465 lines
20 KiB
TypeScript
465 lines
20 KiB
TypeScript
"use client";
|
|
|
|
import {
|
|
Camera,
|
|
ChevronRight,
|
|
Globe,
|
|
Link2,
|
|
Mail,
|
|
MapPin,
|
|
Phone,
|
|
Settings,
|
|
User,
|
|
X,
|
|
} from "lucide-react";
|
|
import { useState } from "react";
|
|
|
|
import {
|
|
FileUpload,
|
|
FileUploadDropzone,
|
|
FileUploadItem,
|
|
FileUploadItemDelete,
|
|
FileUploadItemPreview,
|
|
FileUploadList,
|
|
FileUploadTrigger,
|
|
} from "@/components/diceui/file-upload";
|
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Input } from "@/components/ui/input";
|
|
import { Label } from "@/components/ui/label";
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
} from "@/components/ui/select";
|
|
import { Separator } from "@/components/ui/separator";
|
|
import { Textarea } from "@/components/ui/textarea";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
interface ProfileData {
|
|
name: string;
|
|
username: string;
|
|
email: string;
|
|
avatar?: string;
|
|
bio?: string;
|
|
phone?: string;
|
|
location?: string;
|
|
website?: string;
|
|
twitter?: string;
|
|
linkedin?: string;
|
|
github?: string;
|
|
timezone?: string;
|
|
language?: string;
|
|
}
|
|
|
|
interface SettingsProfile4Props {
|
|
defaultValues?: Partial<ProfileData>;
|
|
className?: string;
|
|
}
|
|
|
|
const sections = [
|
|
{ id: "personal", label: "اطلاعات پایه", icon: User },
|
|
{ id: "contact", label: "اطلاعات تماس", icon: Mail },
|
|
{ id: "social", label: "لینکهای حرفهای", icon: Link2 },
|
|
{ id: "preferences", label: "ترجیحات حساب", icon: Settings },
|
|
];
|
|
|
|
const SettingsProfile4 = ({
|
|
defaultValues = {
|
|
name: "الهام میرزایی",
|
|
username: "elah.mirzaei",
|
|
email: "alex.morgan@email.com",
|
|
avatar:
|
|
"/block-media/shadcnblocks/block/avatar/avatar8.jpg",
|
|
bio: "مدیر موفقیت مشتری با تمرکز روی ماندگاری حساب و رشد گسترش. علاقهمند به آنبوردینگ و سنجش سلامت مشتری.",
|
|
phone: "+98 912 345 6789",
|
|
location: "تهران، ایران",
|
|
website: "https://alexmorgan.design",
|
|
twitter: "alexmorgan",
|
|
linkedin: "alexmorgan",
|
|
github: "alexmorgan",
|
|
timezone: "America/Los_Angeles",
|
|
language: "en",
|
|
},
|
|
className,
|
|
}: SettingsProfile4Props) => {
|
|
const [activeSection, setActiveSection] = useState("personal");
|
|
const [avatarFiles, setAvatarFiles] = useState<File[]>([]);
|
|
|
|
const initials = defaultValues.name
|
|
?.split(" ")
|
|
.map((n) => n[0])
|
|
.join("")
|
|
.toUpperCase();
|
|
|
|
const avatarPreview =
|
|
avatarFiles.length > 0
|
|
? URL.createObjectURL(avatarFiles[0])
|
|
: defaultValues.avatar;
|
|
|
|
return (
|
|
<section dir="rtl" lang="fa" className={cn("w-full py-32", className)}>
|
|
<div className="w-full px-4 sm:px-6 lg:px-8">
|
|
<div className="flex w-full flex-col gap-8">
|
|
{/* Header */}
|
|
<div className="mb-6">
|
|
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
|
<span>تنظیمات حساب</span>
|
|
<ChevronRight className="size-4 rtl:rotate-180" />
|
|
<span className="text-foreground">ویرایش پروفایل</span>
|
|
</div>
|
|
<h1 className="mt-2 text-xl font-semibold">ویرایش پروفایل</h1>
|
|
<p className="text-muted-foreground">
|
|
اطلاعات پروفایل و ترجیحات حساب خود را مدیریت کنید
|
|
</p>
|
|
</div>
|
|
|
|
<div className="flex flex-col gap-8 lg:flex-row">
|
|
{/* Sidebar Navigation */}
|
|
<aside className="lg:w-56 lg:shrink-0">
|
|
<nav className="space-y-1">
|
|
{sections.map((section) => {
|
|
const Icon = section.icon;
|
|
return (
|
|
<button
|
|
key={section.id}
|
|
onClick={() => setActiveSection(section.id)}
|
|
className={cn(
|
|
"flex w-full items-center gap-3 rounded-lg px-3 py-2 text-start text-sm transition-colors",
|
|
activeSection === section.id
|
|
? "bg-primary text-primary-foreground"
|
|
: "text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
)}
|
|
>
|
|
<Icon className="size-4" />
|
|
{section.label}
|
|
</button>
|
|
);
|
|
})}
|
|
</nav>
|
|
</aside>
|
|
|
|
{/* Main Content */}
|
|
<main className="min-w-0 flex-1">
|
|
<div className="rounded-xl border bg-card shadow-sm">
|
|
{/* Personal Info Section */}
|
|
{activeSection === "personal" && (
|
|
<div className="p-6">
|
|
<h2 className="text-lg font-semibold">اطلاعات شخصی</h2>
|
|
<p className="text-sm text-muted-foreground">
|
|
عکس و مشخصات پایه پروفایل را بهروز کنید
|
|
</p>
|
|
|
|
<div className="mt-6 space-y-6">
|
|
{/* Avatar */}
|
|
<FileUpload
|
|
value={avatarFiles}
|
|
onValueChange={setAvatarFiles}
|
|
accept="image/*"
|
|
maxFiles={1}
|
|
maxSize={2 * 1024 * 1024}
|
|
>
|
|
<div className="flex flex-col gap-4 sm:flex-row sm:items-start">
|
|
<Avatar className="size-24 shrink-0">
|
|
<AvatarImage
|
|
src={avatarPreview}
|
|
alt={`آواتار ${defaultValues.name}`}
|
|
className="object-cover"
|
|
/>
|
|
<AvatarFallback className="text-xl">
|
|
{initials}
|
|
</AvatarFallback>
|
|
</Avatar>
|
|
<div className="flex-1 space-y-3">
|
|
<FileUploadDropzone className="flex flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed p-6 text-center transition-colors hover:border-primary/50 hover:bg-muted/50">
|
|
<div className="flex size-10 items-center justify-center rounded-full bg-muted">
|
|
<Camera className="size-5 text-muted-foreground" />
|
|
</div>
|
|
<div className="space-y-1">
|
|
<p className="text-sm font-medium">
|
|
<FileUploadTrigger asChild>
|
|
<Button variant="link" className="h-auto p-0">
|
|
برای بارگذاری کلیک کنید
|
|
</Button>
|
|
</FileUploadTrigger>{" "}
|
|
یا فایل را اینجا رها کنید
|
|
</p>
|
|
<p className="text-xs text-muted-foreground">
|
|
JPG، PNG یا WEBP (حداکثر ۲ مگابایت)
|
|
</p>
|
|
</div>
|
|
</FileUploadDropzone>
|
|
{avatarFiles.length > 0 && (
|
|
<FileUploadList>
|
|
{avatarFiles.map((file, index) => (
|
|
<FileUploadItem
|
|
key={index}
|
|
value={file}
|
|
className="flex items-center gap-3 rounded-lg border bg-muted/30 p-3"
|
|
>
|
|
<FileUploadItemPreview className="size-10 shrink-0 rounded-md" />
|
|
<div className="min-w-0 flex-1">
|
|
<p className="truncate text-sm font-medium">
|
|
{file.name}
|
|
</p>
|
|
<p className="text-xs text-muted-foreground">
|
|
{(file.size / 1024).toLocaleString("fa-IR", {
|
|
maximumFractionDigits: 1,
|
|
})}{" "}
|
|
کیلوبایت
|
|
</p>
|
|
</div>
|
|
<FileUploadItemDelete asChild>
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
className="size-8 shrink-0"
|
|
>
|
|
<X className="size-4" />
|
|
</Button>
|
|
</FileUploadItemDelete>
|
|
</FileUploadItem>
|
|
))}
|
|
</FileUploadList>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</FileUpload>
|
|
|
|
<Separator />
|
|
|
|
<div className="grid gap-6 sm:grid-cols-2">
|
|
<div className="space-y-2">
|
|
<Label htmlFor="name">نام و نام خانوادگی</Label>
|
|
<Input id="name" defaultValue={defaultValues.name} />
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label htmlFor="username">نام کاربری</Label>
|
|
<div className="flex">
|
|
<span className="inline-flex items-center rounded-s-md border border-e-0 bg-muted px-3 text-sm text-muted-foreground">
|
|
@
|
|
</span>
|
|
<Input
|
|
id="username"
|
|
className="rounded-s-none"
|
|
defaultValue={defaultValues.username}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="bio">معرفی کوتاه</Label>
|
|
<Textarea
|
|
id="bio"
|
|
rows={4}
|
|
defaultValue={defaultValues.bio}
|
|
placeholder="نقش و تمرکز کاری خود را بنویسید"
|
|
/>
|
|
<p className="text-xs text-muted-foreground">
|
|
در پروفایل فضای کاری نمایش داده میشود
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Contact Section */}
|
|
{activeSection === "contact" && (
|
|
<div className="p-6">
|
|
<h2 className="text-lg font-semibold">اطلاعات تماس</h2>
|
|
<p className="text-sm text-muted-foreground">
|
|
راههای تماس شما در فضای کاری چگونه باشد؟
|
|
</p>
|
|
|
|
<div className="mt-6 space-y-6">
|
|
<div className="space-y-2">
|
|
<Label htmlFor="email">ایمیل کاری</Label>
|
|
<div className="relative">
|
|
<Mail className="absolute top-1/2 start-3 size-4 -translate-y-1/2 text-muted-foreground" />
|
|
<Input
|
|
id="email"
|
|
type="email"
|
|
className="ps-10"
|
|
defaultValue={defaultValues.email}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="phone">شماره موبایل</Label>
|
|
<div className="relative">
|
|
<Phone className="absolute top-1/2 start-3 size-4 -translate-y-1/2 text-muted-foreground" />
|
|
<Input
|
|
id="phone"
|
|
type="tel"
|
|
className="ps-10"
|
|
defaultValue={defaultValues.phone}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="location">موقعیت مکانی</Label>
|
|
<div className="relative">
|
|
<MapPin className="absolute top-1/2 start-3 size-4 -translate-y-1/2 text-muted-foreground" />
|
|
<Input
|
|
id="location"
|
|
className="ps-10"
|
|
defaultValue={defaultValues.location}
|
|
placeholder="شهر، کشور"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="website">وبسایت</Label>
|
|
<div className="relative">
|
|
<Globe className="absolute top-1/2 start-3 size-4 -translate-y-1/2 text-muted-foreground" />
|
|
<Input
|
|
id="website"
|
|
type="url"
|
|
className="ps-10"
|
|
defaultValue={defaultValues.website}
|
|
placeholder="https://yourwebsite.com"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Social Links Section */}
|
|
{activeSection === "social" && (
|
|
<div className="p-6">
|
|
<h2 className="text-lg font-semibold">لینکهای حرفهای</h2>
|
|
<p className="text-sm text-muted-foreground">
|
|
پروفایلهای حرفهای خود را لینک کنید
|
|
</p>
|
|
|
|
<div className="mt-6 space-y-6">
|
|
<div className="space-y-2">
|
|
<Label htmlFor="twitter">X / توییتر</Label>
|
|
<div className="flex">
|
|
<span className="inline-flex items-center rounded-s-md border border-e-0 bg-muted px-3 text-sm text-muted-foreground">
|
|
x.com/
|
|
</span>
|
|
<Input
|
|
id="twitter"
|
|
className="rounded-s-none"
|
|
defaultValue={defaultValues.twitter}
|
|
placeholder="نام کاربری"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="linkedin">لینکدین</Label>
|
|
<div className="flex">
|
|
<span className="inline-flex items-center rounded-s-md border border-e-0 bg-muted px-3 text-sm text-muted-foreground">
|
|
linkedin.com/in/
|
|
</span>
|
|
<Input
|
|
id="linkedin"
|
|
className="rounded-s-none"
|
|
defaultValue={defaultValues.linkedin}
|
|
placeholder="نام کاربری"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="github">گیتهاب</Label>
|
|
<div className="flex">
|
|
<span className="inline-flex items-center rounded-s-md border border-e-0 bg-muted px-3 text-sm text-muted-foreground">
|
|
github.com/
|
|
</span>
|
|
<Input
|
|
id="github"
|
|
className="rounded-s-none"
|
|
defaultValue={defaultValues.github}
|
|
placeholder="نام کاربری"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Preferences Section */}
|
|
{activeSection === "preferences" && (
|
|
<div className="p-6">
|
|
<h2 className="text-lg font-semibold">ترجیحات حساب</h2>
|
|
<p className="text-sm text-muted-foreground">
|
|
زبان رابط و منطقه زمانی را شخصیسازی کنید
|
|
</p>
|
|
|
|
<div className="mt-6 space-y-6">
|
|
<div className="space-y-2">
|
|
<Label htmlFor="language">زبان رابط</Label>
|
|
<Select defaultValue={defaultValues.language}>
|
|
<SelectTrigger id="language">
|
|
<SelectValue placeholder="انتخاب زبان رابط" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="fa">فارسی</SelectItem>
|
|
<SelectItem value="en">انگلیسی</SelectItem>
|
|
<SelectItem value="es">اسپانیایی</SelectItem>
|
|
<SelectItem value="fr">فرانسوی</SelectItem>
|
|
<SelectItem value="de">آلمانی</SelectItem>
|
|
<SelectItem value="ja">ژاپنی</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="timezone">منطقه زمانی</Label>
|
|
<Select defaultValue={defaultValues.timezone}>
|
|
<SelectTrigger id="timezone">
|
|
<SelectValue placeholder="انتخاب منطقه زمانی" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="America/New_York">
|
|
وقت شرقی آمریکا (ET)
|
|
</SelectItem>
|
|
<SelectItem value="America/Chicago">
|
|
وقت مرکزی آمریکا (CT)
|
|
</SelectItem>
|
|
<SelectItem value="America/Denver">
|
|
وقت کوهستانی آمریکا (MT)
|
|
</SelectItem>
|
|
<SelectItem value="America/Los_Angeles">
|
|
وقت اقیانوس آرام (PT)
|
|
</SelectItem>
|
|
<SelectItem value="Europe/London">وقت گرینویچ (GMT)</SelectItem>
|
|
<SelectItem value="Europe/Paris">
|
|
وقت اروپای مرکزی (CET)
|
|
</SelectItem>
|
|
<SelectItem value="Asia/Tehran">
|
|
وقت ایران (IRST)
|
|
</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Footer with actions */}
|
|
<div className="flex items-center justify-end gap-3 border-t px-6 py-4">
|
|
<Button variant="outline">انصراف</Button>
|
|
<Button>ذخیره تغییرات</Button>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export { SettingsProfile4 };
|