Better settings ui
This commit is contained in:
@@ -1,71 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { useProfileSettings, useClientSettings } from "@/hooks/use-settings";
|
||||
import { setClientSettings } from "@/lib/clientSettings";
|
||||
import Settings from "./settings";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { CardContent } from "@/components/ui/card";
|
||||
import { PROFILE_SCHEMA, CLIENT_SCHEMA } from "@/types/settings";
|
||||
import { useParams, useRouter, useSearchParams } from "next/navigation";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { ChevronLeftCircle } from "lucide-react";
|
||||
import axios from "axios";
|
||||
import { useEffect } from "react";
|
||||
|
||||
export default function SettingsPage() {
|
||||
const [settings, setSettings] = useClientSettings();
|
||||
const [profileSettings, setProfileSettings] = useProfileSettings();
|
||||
const router = useRouter();
|
||||
const params = useSearchParams();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="ml-2 mt-2"
|
||||
onClick={() => router.back()}
|
||||
>
|
||||
<ChevronLeftCircle />
|
||||
</Button>
|
||||
<Tabs
|
||||
className="mx-auto mt-3"
|
||||
defaultValue={params.get("tab") || "client"}
|
||||
>
|
||||
<TabsList className="mx-auto">
|
||||
<TabsTrigger value="client">Client Settings</TabsTrigger>
|
||||
<TabsTrigger value="profile">Profile Settings</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="client">
|
||||
<Card className="w-xl mx-auto">
|
||||
<CardContent className="flex flex-col gap-3">
|
||||
<Settings
|
||||
settings={settings}
|
||||
setSettings={setSettings}
|
||||
schema={CLIENT_SCHEMA}
|
||||
onSave={() => {
|
||||
setClientSettings(settings);
|
||||
router.refresh();
|
||||
}}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
<TabsContent value="profile">
|
||||
<Card className="w-xl mx-auto">
|
||||
<CardContent className="flex flex-col gap-3">
|
||||
<Settings
|
||||
settings={profileSettings}
|
||||
setSettings={setProfileSettings}
|
||||
schema={PROFILE_SCHEMA}
|
||||
onSave={async () => {
|
||||
await axios.post("/api/profile", profileSettings);
|
||||
}}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -33,6 +33,7 @@ import ProfilePicture from "./ProfilePicture";
|
||||
import auth, { makeAddress } from "@/lib/auth";
|
||||
import { toast } from "sonner";
|
||||
import { StringMap } from "@/types/typeUtils";
|
||||
import SettingsDialog from "./settings/SettingsDialog";
|
||||
|
||||
export default function AppSidebar({
|
||||
children,
|
||||
@@ -195,9 +196,7 @@ export default function AppSidebar({
|
||||
</Dialog>
|
||||
|
||||
<footer className="mt-auto">
|
||||
<Link href="/settings">
|
||||
<SettingsIcon />
|
||||
</Link>
|
||||
<SettingsDialog />
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -271,12 +270,10 @@ function DMItem({
|
||||
<span className="text-xs text-muted-foreground">{status}</span>
|
||||
</div>
|
||||
{settings && (
|
||||
<Button
|
||||
onClick={() => router.push(`/settings?tab=profile`)}
|
||||
className="bg-transparent text-accent-foreground hover:text-accent ml-auto w-7 h-7 p-0 flex items-center justify-center rounded-md"
|
||||
>
|
||||
<SettingsIcon size={16} />
|
||||
</Button>
|
||||
<SettingsDialog
|
||||
className="ml-auto w-7 h-7 p-0 flex items-center justify-center"
|
||||
tab="profile"
|
||||
/>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
|
||||
@@ -25,7 +25,7 @@ export type SettingsSchema = StringMap<
|
||||
"boolean" | "string" | "number" | string[] | RegexSetting
|
||||
>;
|
||||
|
||||
export default function Settings<T>({
|
||||
export default function SettingSchema<T>({
|
||||
settings,
|
||||
setSettings,
|
||||
schema,
|
||||
@@ -73,7 +73,7 @@ export default function Settings<T>({
|
||||
value={(settings as any)[key] || []}
|
||||
onValueChange={(val) => handleChange(key, val)}
|
||||
>
|
||||
<SelectTrigger className="w-[200px]">
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={key} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
@@ -0,0 +1,66 @@
|
||||
"use client";
|
||||
|
||||
import { useClientSettings } from "@/hooks/use-settings";
|
||||
import { setClientSettings } from "@/lib/clientSettings";
|
||||
import SettingSchema from "./SettingSchema";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { CardContent } from "@/components/ui/card";
|
||||
import {
|
||||
PROFILE_SCHEMA,
|
||||
CLIENT_SCHEMA,
|
||||
ProfileSettings,
|
||||
} from "@/types/settings";
|
||||
import { useParams, useRouter, useSearchParams } from "next/navigation";
|
||||
import axios from "axios";
|
||||
|
||||
export default function Settings({
|
||||
tab,
|
||||
profileSettings,
|
||||
setProfileSettings,
|
||||
}: {
|
||||
tab?: string;
|
||||
profileSettings: ProfileSettings;
|
||||
setProfileSettings: React.Dispatch<React.SetStateAction<ProfileSettings>>;
|
||||
}) {
|
||||
const [settings, setSettings] = useClientSettings();
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<Tabs className="mx-auto mt-3" defaultValue={tab || "client"}>
|
||||
<TabsList className="mx-auto">
|
||||
<TabsTrigger value="client">Client Settings</TabsTrigger>
|
||||
<TabsTrigger value="profile">Profile Settings</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="client">
|
||||
<Card className="mx-auto">
|
||||
<CardContent className="flex flex-col gap-3">
|
||||
<SettingSchema
|
||||
settings={settings}
|
||||
setSettings={setSettings}
|
||||
schema={CLIENT_SCHEMA}
|
||||
onSave={() => {
|
||||
setClientSettings(settings);
|
||||
router.refresh();
|
||||
}}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
<TabsContent value="profile">
|
||||
<Card className="mx-auto">
|
||||
<CardContent className="flex flex-col gap-3">
|
||||
<SettingSchema
|
||||
settings={profileSettings}
|
||||
setSettings={setProfileSettings}
|
||||
schema={PROFILE_SCHEMA}
|
||||
onSave={async () => {
|
||||
await axios.post("/api/profile", profileSettings);
|
||||
}}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import { SettingsIcon } from "lucide-react";
|
||||
import { Button } from "../ui/button";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "../ui/dialog";
|
||||
import { cn } from "@/lib/utils";
|
||||
import Settings from "./Settings";
|
||||
import { ProfileSettings } from "@/types/settings";
|
||||
import { useProfileSettings } from "@/hooks/use-settings";
|
||||
|
||||
export default function SettingsDialog({
|
||||
className,
|
||||
tab,
|
||||
}: {
|
||||
className?: string;
|
||||
tab?: string;
|
||||
profile?: ProfileSettings;
|
||||
}) {
|
||||
const [profileSettings, setProfileSettings] = useProfileSettings();
|
||||
|
||||
return (
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button
|
||||
className={cn(
|
||||
"bg-transparent text-accent-foreground hover:text-accent",
|
||||
className
|
||||
)}
|
||||
>
|
||||
<SettingsIcon />
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Settings</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="w-full">
|
||||
<Settings
|
||||
tab={tab}
|
||||
profileSettings={profileSettings}
|
||||
setProfileSettings={setProfileSettings}
|
||||
/>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
import { RegexSetting, SettingsSchema } from "@/app/settings/settings";
|
||||
import {
|
||||
RegexSetting,
|
||||
SettingsSchema,
|
||||
} from "@/components/settings/SettingSchema";
|
||||
|
||||
export interface ClientSettings {
|
||||
theme: "light" | "dark";
|
||||
|
||||
Reference in New Issue
Block a user