TypeScript 97.5%
SQL 1.4%
Python 0.8%
1import Link from "next/link";2import { BadgeCheck, MailWarning } from "lucide-react";3import { getWorkspace } from "@/lib/session";4import { formatDate, titleCase } from "@/lib/format";5import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";6import { Badge } from "@/components/ui/badge";7import { Alert } from "@/components/ui/alert";8import { ThemeToggle } from "@/components/ui/theme";9import { ResendVerificationButton } from "@/components/dashboard/resend-verification";10import { ProfileNameForm } from "@/components/dashboard/settings/profile-form";11import { ChangeEmailDialog } from "@/components/dashboard/settings/change-email-dialog";12import { OrganizationForm } from "@/components/dashboard/settings/organization-form";13import { DeleteAccountDialog } from "@/components/dashboard/settings/delete-account-dialog";1415export const dynamic = "force-dynamic";1617export default async function SettingsProfilePage({ searchParams }: { searchParams: Promise<{ "email-changed"?: string }> }) {18 const sp = await searchParams;19 const ws = await getWorkspace();20 const canEditOrg = ["owner", "admin", "billing"].includes(ws.role);2122 return (23 <div className="grid gap-6">24 {sp["email-changed"] === "1" ? <Alert variant="success" title="Email address updated">Your new address is now your login. If it is not verified yet, use the button below.</Alert> : null}2526 <Card>27 <CardHeader>28 <CardTitle>Profile</CardTitle>29 <CardDescription>How you appear across Fetcha. Member since {formatDate(ws.user.createdAt, { timeStyle: undefined })}.</CardDescription>30 </CardHeader>31 <CardContent className="grid gap-6">32 <ProfileNameForm name={ws.user.name} />33 <div className="grid gap-2 border-t border-border pt-5">34 <div className="text-[13px] font-medium">Email</div>35 <div className="flex flex-wrap items-center gap-3">36 <span className="font-mono text-[13.5px]">{ws.user.email}</span>37 {ws.user.emailVerified ? (38 <Badge variant="success">39 <BadgeCheck className="size-3" /> Verified40 </Badge>41 ) : (42 <Badge variant="warning">43 <MailWarning className="size-3" /> Unverified44 </Badge>45 )}46 <div className="ml-auto flex items-center gap-2">47 {!ws.user.emailVerified ? <ResendVerificationButton email={ws.user.email} size="sm" /> : null}48 <ChangeEmailDialog currentEmail={ws.user.email} />49 </div>50 </div>51 <p className="text-xs text-fg-subtle">{ws.user.emailVerified ? "Security notices and receipts go to this address." : "Verify your address to unlock production API access."}</p>52 </div>53 </CardContent>54 </Card>5556 <Card>57 <CardHeader>58 <div className="flex items-center justify-between gap-3">59 <CardTitle>Organization</CardTitle>60 <div className="flex items-center gap-2">61 <Badge variant="outline">{titleCase(ws.role)}</Badge>62 <Badge variant="accent">{titleCase(ws.organization.plan)} plan</Badge>63 </div>64 </div>65 <CardDescription>66 Organization-wide spending limits apply on top of per-project limits. Manage your plan in{" "}67 <Link href="/dashboard/billing" className="text-fg underline-offset-4 hover:underline">68 Billing69 </Link>70 . Teams and invitations are not available yet.71 </CardDescription>72 </CardHeader>73 <CardContent>74 <OrganizationForm name={ws.organization.name} softLimitUsd={ws.organization.softLimitUsd} hardLimitUsd={ws.organization.hardLimitUsd} canEdit={canEditOrg} />75 </CardContent>76 </Card>7778 <Card>79 <CardHeader>80 <CardTitle>Appearance</CardTitle>81 <CardDescription>Theme preference is stored in this browser.</CardDescription>82 </CardHeader>83 <CardContent className="flex items-center justify-between gap-4">84 <p className="text-[13px] text-fg-muted">Light, dark, or follow your system.</p>85 <ThemeToggle className="border border-border" />86 </CardContent>87 </Card>8889 <Card className="border-danger/30">90 <CardHeader>91 <CardTitle className="text-danger">Danger zone</CardTitle>92 <CardDescription>Deleting your account removes your organization, projects, keys and request history. Requires your password and an email confirmation.</CardDescription>93 </CardHeader>94 <CardContent>95 <DeleteAccountDialog email={ws.user.email} />96 </CardContent>97 </Card>98 </div>99 );100}101