MIF_E31221222/sigap-website/app/_components/admin/settings/setting-dialog.tsx

192 lines
5.4 KiB
TypeScript

"use client";
import * as React from "react";
import { cn } from "@/lib/utils";
import {
Dialog,
DialogContent,
DialogTrigger,
} from "@/app/_components/ui/dialog";
import { ScrollArea } from "@/app/_components/ui/scroll-area";
import { Separator } from "@/app/_components/ui/separator";
import {
Avatar,
AvatarFallback,
AvatarImage,
} from "@/app/_components/ui/avatar";
import {
IconBell,
IconFingerprint,
IconLock,
IconPlugConnected,
IconSettings,
IconUser,
IconUsers,
IconWorld,
} from "@tabler/icons-react";
import type { User } from "@/src/models/users/users.model";
import { ProfileSettings } from "./profile-settings";
import { DialogTitle } from "@radix-ui/react-dialog";
interface SettingsDialogProps {
user: User | null;
trigger: React.ReactNode;
defaultTab?: string;
open?: boolean;
onOpenChange?: (open: boolean) => void;
}
interface SettingsTab {
id: string;
icon: typeof IconUser;
title: string;
content: React.ReactNode;
}
interface SettingsSection {
title: string;
tabs: SettingsTab[];
}
export function SettingsDialog({
user,
trigger,
defaultTab = "account",
open,
onOpenChange,
}: SettingsDialogProps) {
const [selectedTab, setSelectedTab] = React.useState(defaultTab);
// Get user display name
const preferredName = user?.profile?.first_name || "";
const userEmail = user?.email || "";
const displayName = preferredName || userEmail?.split("@")[0] || "User";
const userAvatar = user?.profile?.avatar || "";
const sections: SettingsSection[] = [
{
title: "Account",
tabs: [
{
id: "account",
icon: IconUser,
title: "My Account",
content: <ProfileSettings user={user} />,
},
{
id: "preferences",
icon: IconSettings,
title: "Preferences",
content: <div>Preferences content</div>,
},
{
id: "notifications",
icon: IconBell,
title: "Notifications",
content: <div>Notifications content</div>,
},
{
id: "connections",
icon: IconPlugConnected,
title: "Connections",
content: <div>Connections content</div>,
},
],
},
{
title: "Workspace",
tabs: [
{
id: "general",
icon: IconWorld,
title: "General",
content: <div>General content</div>,
},
{
id: "members",
icon: IconUsers,
title: "Members",
content: <div>Members content</div>,
},
{
id: "security",
icon: IconLock,
title: "Security",
content: <div>Security content</div>,
},
{
id: "identity",
icon: IconFingerprint,
title: "Identity",
content: <div>Identity content</div>,
},
],
},
];
const currentTab = sections
.flatMap((section) => section.tabs)
.find((tab) => tab.id === selectedTab);
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogTitle></DialogTitle>
<DialogTrigger asChild>{trigger}</DialogTrigger>
<DialogContent className="max-w-[1200px] gap-0 p-0">
<div className="grid h-[600px] grid-cols-[250px,1fr]">
{/* Sidebar */}
<div className="border-r bg-muted/50">
<ScrollArea className="h-[600px]">
<div className="p-2">
<div className="flex items-center gap-2 px-3 py-2">
<Avatar className="h-8 w-8">
<AvatarImage src={userAvatar} alt={displayName} />
<AvatarFallback>
{displayName[0].toUpperCase()}
</AvatarFallback>
</Avatar>
<span className="text-sm font-medium">{displayName}</span>
</div>
{sections.map((section, index) => (
<div key={section.title} className="py-2">
<div className="px-3 py-2">
<h3 className="text-sm font-medium text-muted-foreground">
{section.title}
</h3>
</div>
<div className="space-y-1">
{section.tabs.map((tab) => (
<button
key={tab.id}
onClick={() => setSelectedTab(tab.id)}
className={cn(
"flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm font-medium",
tab.id === selectedTab
? "bg-accent text-accent-foreground"
: "text-muted-foreground hover:bg-accent hover:text-accent-foreground"
)}
>
<tab.icon className="h-4 w-4" />
{tab.title}
</button>
))}
</div>
{index < sections.length - 1 && (
<Separator className="mx-3 my-2" />
)}
</div>
))}
</div>
</ScrollArea>
</div>
{/* Content */}
<div className="flex flex-col">
<div className="flex-1">{currentTab?.content}</div>
</div>
</div>
</DialogContent>
</Dialog>
);
}