mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-12 12:25:22 +00:00
* sign up copy nits * first pass at new onboarding page * wip join onboard logic * refactor auth provider fetch logic * add member approval and invite link flag logic * update join request flow and remove jit logic * onboard guard * nits, onboard role check, invite link enabled check * fix bg color issue in onboarding page * refactor onboard UI * ui nits and more onboarding resource cards * revamp auth docs * change member approval default behavior and updated docs * merge prisma migrations * add id to resource card * feedback * feedback * feedback and fixed build * settings drop down UI nit * ui nits * handle join when max capacity case * add news data for member toggle * refactor for public access case * add iap bridge to onboard logic * fetch member approval req and invite link enabled flag on server * ui nits * fix invite link enable toggle snapping issue * ui nits * styling and ui nits, pass in invite id from server * add mcp resource in onboard step * get invite link in server * fix build issue * refactor docs on config * minor doc nit
177 lines
7.2 KiB
TypeScript
177 lines
7.2 KiB
TypeScript
'use client';
|
|
|
|
import {
|
|
CodeIcon,
|
|
Laptop,
|
|
LogIn,
|
|
LogOut,
|
|
Moon,
|
|
Settings,
|
|
Sun
|
|
} from "lucide-react"
|
|
import { Button } from "@/components/ui/button"
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuGroup,
|
|
DropdownMenuItem,
|
|
DropdownMenuPortal,
|
|
DropdownMenuRadioGroup,
|
|
DropdownMenuRadioItem,
|
|
DropdownMenuSeparator,
|
|
DropdownMenuSub,
|
|
DropdownMenuSubContent,
|
|
DropdownMenuSubTrigger,
|
|
DropdownMenuTrigger,
|
|
} from "@/components/ui/dropdown-menu"
|
|
import { useTheme } from "next-themes"
|
|
import { useMemo } from "react"
|
|
import { KeymapType } from "@/lib/types"
|
|
import { cn } from "@/lib/utils"
|
|
import { useKeymapType } from "@/hooks/useKeymapType"
|
|
import { useSession } from "next-auth/react";
|
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
|
import { signOut } from "next-auth/react"
|
|
import { env } from "@/env.mjs";
|
|
import posthog from "posthog-js";
|
|
import { useDomain } from "@/hooks/useDomain";
|
|
|
|
interface SettingsDropdownProps {
|
|
menuButtonClassName?: string;
|
|
}
|
|
|
|
export const SettingsDropdown = ({
|
|
menuButtonClassName,
|
|
}: SettingsDropdownProps) => {
|
|
|
|
const { theme: _theme, setTheme } = useTheme();
|
|
const [keymapType, setKeymapType] = useKeymapType();
|
|
const { data: session, update } = useSession();
|
|
const domain = useDomain();
|
|
|
|
const theme = useMemo(() => {
|
|
return _theme ?? "light";
|
|
}, [_theme]);
|
|
|
|
const ThemeIcon = useMemo(() => {
|
|
switch (theme) {
|
|
case "light":
|
|
return <Sun className="h-4 w-4 mr-2" />;
|
|
case "dark":
|
|
return <Moon className="h-4 w-4 mr-2" />;
|
|
case "system":
|
|
return <Laptop className="h-4 w-4 mr-2" />;
|
|
default:
|
|
return <Laptop className="h-4 w-4 mr-2" />;
|
|
}
|
|
}, [theme]);
|
|
|
|
return (
|
|
// Was hitting a bug with invite code login where the first time the user signs in, the settingsDropdown doesn't have a valid session. To fix this
|
|
// we can simply update the session everytime the settingsDropdown is opened. This isn't a super frequent operation and updating the session is low cost,
|
|
// so this is a simple solution to the problem.
|
|
<DropdownMenu onOpenChange={(isOpen) => {
|
|
if (isOpen) {
|
|
update();
|
|
}
|
|
}}>
|
|
<DropdownMenuTrigger asChild>
|
|
<Button variant="outline" size="icon" className={cn(menuButtonClassName)}>
|
|
<Settings className="h-4 w-4" />
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent className="w-64">
|
|
{session?.user ? (
|
|
<DropdownMenuGroup>
|
|
<div className="flex flex-row items-start gap-3 p-2">
|
|
<Avatar className="flex-shrink-0">
|
|
<AvatarImage
|
|
src={session.user.image ?? ""}
|
|
/>
|
|
<AvatarFallback>
|
|
{session.user.name && session.user.name.length > 0 ? session.user.name[0] : 'U'}
|
|
</AvatarFallback>
|
|
</Avatar>
|
|
<p className="text-sm font-medium break-all flex-1 leading-relaxed">{session.user.email ?? "User"}</p>
|
|
</div>
|
|
<DropdownMenuItem
|
|
onClick={() => {
|
|
signOut({
|
|
redirectTo: "/login",
|
|
}).then(() => {
|
|
posthog.reset();
|
|
})
|
|
}}
|
|
>
|
|
<LogOut className="mr-2 h-4 w-4" />
|
|
<span>Log out</span>
|
|
</DropdownMenuItem>
|
|
</DropdownMenuGroup>
|
|
) : (
|
|
<DropdownMenuItem
|
|
onClick={() => {
|
|
window.location.href = "/login";
|
|
}}
|
|
>
|
|
<LogIn className="mr-2 h-4 w-4" />
|
|
<span>Sign in</span>
|
|
</DropdownMenuItem>
|
|
)}
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuGroup>
|
|
<DropdownMenuSub>
|
|
<DropdownMenuSubTrigger>
|
|
{ThemeIcon}
|
|
<span>Theme</span>
|
|
</DropdownMenuSubTrigger>
|
|
<DropdownMenuPortal>
|
|
<DropdownMenuSubContent>
|
|
<DropdownMenuRadioGroup value={theme} onValueChange={setTheme}>
|
|
<DropdownMenuRadioItem value="light">
|
|
Light
|
|
</DropdownMenuRadioItem>
|
|
<DropdownMenuRadioItem value="dark">
|
|
Dark
|
|
</DropdownMenuRadioItem>
|
|
<DropdownMenuRadioItem value="system">
|
|
System
|
|
</DropdownMenuRadioItem>
|
|
</DropdownMenuRadioGroup>
|
|
</DropdownMenuSubContent>
|
|
</DropdownMenuPortal>
|
|
</DropdownMenuSub>
|
|
<DropdownMenuSub>
|
|
<DropdownMenuSubTrigger>
|
|
<CodeIcon className="h-4 w-4 mr-2" />
|
|
<span>Code navigation</span>
|
|
</DropdownMenuSubTrigger>
|
|
<DropdownMenuPortal>
|
|
<DropdownMenuSubContent>
|
|
<DropdownMenuRadioGroup value={keymapType} onValueChange={(value) => setKeymapType(value as KeymapType)}>
|
|
<DropdownMenuRadioItem value="default">
|
|
Default
|
|
</DropdownMenuRadioItem>
|
|
<DropdownMenuRadioItem value="vim">
|
|
Vim
|
|
</DropdownMenuRadioItem>
|
|
</DropdownMenuRadioGroup>
|
|
</DropdownMenuSubContent>
|
|
</DropdownMenuPortal>
|
|
</DropdownMenuSub>
|
|
{session?.user && (
|
|
<DropdownMenuItem asChild>
|
|
<a href={`/${domain}/settings`}>
|
|
<Settings className="h-4 w-4 mr-2" />
|
|
<span>Settings</span>
|
|
</a>
|
|
</DropdownMenuItem>
|
|
)}
|
|
</DropdownMenuGroup>
|
|
<DropdownMenuSeparator />
|
|
<div className="px-2 py-1 text-sm text-muted-foreground">
|
|
version: {env.NEXT_PUBLIC_SOURCEBOT_VERSION}
|
|
</div>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
)
|
|
}
|