mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-12 12:25:22 +00:00
hide member page if not owner
This commit is contained in:
parent
dbd8ef7fdb
commit
63d3123fa7
5 changed files with 27 additions and 48 deletions
|
|
@ -1,5 +1,10 @@
|
||||||
import { getOrgFromDomain } from "@/data/org";
|
import { getOrgFromDomain } from "@/data/org";
|
||||||
import { OrganizationAccessSettings } from "@/app/components/organizationAccessSettings";
|
import { OrganizationAccessSettings } from "@/app/components/organizationAccessSettings";
|
||||||
|
import { isServiceError } from "@/lib/utils";
|
||||||
|
import { ServiceErrorException } from "@/lib/serviceError";
|
||||||
|
import { getMe } from "@/actions";
|
||||||
|
import { OrgRole } from "@sourcebot/db";
|
||||||
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
interface AccessPageProps {
|
interface AccessPageProps {
|
||||||
params: {
|
params: {
|
||||||
|
|
@ -13,6 +18,20 @@ export default async function AccessPage({ params: { domain } }: AccessPageProps
|
||||||
throw new Error("Organization not found");
|
throw new Error("Organization not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const me = await getMe();
|
||||||
|
if (isServiceError(me)) {
|
||||||
|
throw new ServiceErrorException(me);
|
||||||
|
}
|
||||||
|
|
||||||
|
const userRoleInOrg = me.memberships.find((membership) => membership.id === org.id)?.role;
|
||||||
|
if (!userRoleInOrg) {
|
||||||
|
throw new Error("User role not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userRoleInOrg !== OrgRole.OWNER) {
|
||||||
|
redirect(`/${domain}/settings`);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-6">
|
<div className="flex flex-col gap-6">
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
|
|
@ -70,11 +70,11 @@ export default async function SettingsLayout({
|
||||||
href: `/${domain}/settings/access`,
|
href: `/${domain}/settings/access`,
|
||||||
}
|
}
|
||||||
] : []),
|
] : []),
|
||||||
{
|
...(userRoleInOrg === OrgRole.OWNER ? [{
|
||||||
title: (
|
title: (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
Members
|
Members
|
||||||
{userRoleInOrg === OrgRole.OWNER && numJoinRequests !== undefined && numJoinRequests > 0 && (
|
{numJoinRequests !== undefined && numJoinRequests > 0 && (
|
||||||
<span className="inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-primary px-1.5 text-xs font-medium text-primary-foreground">
|
<span className="inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-primary px-1.5 text-xs font-medium text-primary-foreground">
|
||||||
{numJoinRequests}
|
{numJoinRequests}
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -82,7 +82,7 @@ export default async function SettingsLayout({
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
href: `/${domain}/settings/members`,
|
href: `/${domain}/settings/members`,
|
||||||
},
|
}] : []),
|
||||||
{
|
{
|
||||||
title: "Secrets",
|
title: "Secrets",
|
||||||
href: `/${domain}/settings/secrets`,
|
href: `/${domain}/settings/secrets`,
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import { ServiceErrorException } from "@/lib/serviceError";
|
||||||
import { getSeats, SOURCEBOT_UNLIMITED_SEATS } from "@sourcebot/shared";
|
import { getSeats, SOURCEBOT_UNLIMITED_SEATS } from "@sourcebot/shared";
|
||||||
import { RequestsList } from "./components/requestsList";
|
import { RequestsList } from "./components/requestsList";
|
||||||
import { OrgRole } from "@prisma/client";
|
import { OrgRole } from "@prisma/client";
|
||||||
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
interface MembersSettingsPageProps {
|
interface MembersSettingsPageProps {
|
||||||
params: {
|
params: {
|
||||||
|
|
@ -38,6 +39,10 @@ export default async function MembersSettingsPage({ params: { domain }, searchPa
|
||||||
throw new Error("User role not found");
|
throw new Error("User role not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (userRoleInOrg !== OrgRole.OWNER) {
|
||||||
|
redirect(`/${domain}/settings`);
|
||||||
|
}
|
||||||
|
|
||||||
const members = await getOrgMembers(domain);
|
const members = await getOrgMembers(domain);
|
||||||
if (isServiceError(members)) {
|
if (isServiceError(members)) {
|
||||||
throw new ServiceErrorException(members);
|
throw new ServiceErrorException(members);
|
||||||
|
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
"use client"
|
|
||||||
|
|
||||||
import { ExternalLink } from "lucide-react"
|
|
||||||
import Link from "next/link"
|
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button"
|
|
||||||
import { Card, CardContent } from "@/components/ui/card"
|
|
||||||
import useCaptureEvent from "@/hooks/useCaptureEvent"
|
|
||||||
|
|
||||||
export default function DemoCard() {
|
|
||||||
const captureEvent = useCaptureEvent();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Card className="mb-6 w-full border bg-card text-card-foreground">
|
|
||||||
<CardContent className="p-4">
|
|
||||||
<div className="flex flex-col space-y-4">
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<div className="space-y-1">
|
|
||||||
<h3 className="text-sm font-medium">New to Sourcebot?</h3>
|
|
||||||
<p className="text-xs text-muted-foreground">Try our public demo before creating an account</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Button asChild variant="outline" size="sm" className="h-8 text-xs">
|
|
||||||
<Link
|
|
||||||
href="https://demo.sourcebot.dev"
|
|
||||||
target="_blank"
|
|
||||||
className="flex items-center gap-1.5"
|
|
||||||
onClick={() => captureEvent('wa_demo_card_click', {})}
|
|
||||||
>
|
|
||||||
Try demo
|
|
||||||
<ExternalLink className="h-3.5 w-3.5" />
|
|
||||||
</Link>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
@ -5,7 +5,6 @@ import { Card } from "@/components/ui/card";
|
||||||
import { SourcebotLogo } from "@/app/components/sourcebotLogo";
|
import { SourcebotLogo } from "@/app/components/sourcebotLogo";
|
||||||
import { AuthMethodSelector } from "@/app/components/authMethodSelector";
|
import { AuthMethodSelector } from "@/app/components/authMethodSelector";
|
||||||
import useCaptureEvent from "@/hooks/useCaptureEvent";
|
import useCaptureEvent from "@/hooks/useCaptureEvent";
|
||||||
import DemoCard from "@/app/login/components/demoCard";
|
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { env } from "@/env.mjs";
|
import { env } from "@/env.mjs";
|
||||||
import type { AuthProvider } from "@/lib/authProviders";
|
import type { AuthProvider } from "@/lib/authProviders";
|
||||||
|
|
@ -72,11 +71,6 @@ export const LoginForm = ({ callbackUrl, error, providers, context }: LoginFormP
|
||||||
{context === "login" ? "Sign in to your account" : "Create a new account"}
|
{context === "login" ? "Sign in to your account" : "Create a new account"}
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
{env.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT !== undefined && (
|
|
||||||
<div className="w-full sm:w-[500px] max-w-[500px]">
|
|
||||||
<DemoCard />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<Card className="flex flex-col items-center border p-6 sm:p-12 rounded-lg gap-4 sm:gap-6 w-full sm:w-[500px] max-w-[500px] bg-background">
|
<Card className="flex flex-col items-center border p-6 sm:p-12 rounded-lg gap-4 sm:gap-6 w-full sm:w-[500px] max-w-[500px] bg-background">
|
||||||
{error && (
|
{error && (
|
||||||
<div className="text-sm text-destructive text-center text-wrap border p-2 rounded-md border-destructive">
|
<div className="text-sm text-destructive text-center text-wrap border p-2 rounded-md border-destructive">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue