Files
reui-blocks/blocks/settings-profile1.tsx

200 lines
6.7 KiB
TypeScript

"use client";
import { Camera, X } from "lucide-react";
import { useState } from "react";
import {
FileUpload,
FileUploadItem,
FileUploadItemDelete,
FileUploadList,
FileUploadTrigger,
} from "@/components/diceui/file-upload";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { cn } from "@/lib/utils";
interface ProfileFormData {
name: string;
email: string;
username: string;
avatar?: string;
bio?: string;
}
interface SettingsProfile1Props {
defaultValues?: Partial<ProfileFormData>;
onSave?: (data: ProfileFormData) => void;
className?: string;
}
const SettingsProfile1 = ({
defaultValues = {
name: "الهام میرزایی",
email: "alex.morgan@email.com",
username: "elah.mirzaei",
avatar:
"/block-media/shadcnblocks/block/avatar/avatar8.jpg",
bio: "مدیر موفقیت مشتری با تمرکز روی افزایش ماندگاری و گسترش حساب‌های سازمانی. در تیم‌های SaaS روی قیف آنبوردینگ و NPS کار می‌کنم.",
},
className,
}: SettingsProfile1Props) => {
const [avatarFiles, setAvatarFiles] = useState<File[]>([]);
const initials = defaultValues.name
?.split(" ")
.map((n) => n[0])
.join("")
.toUpperCase();
// Get preview URL from uploaded file or use default avatar
const avatarPreview =
avatarFiles.length > 0
? URL.createObjectURL(avatarFiles[0])
: defaultValues.avatar;
return (
<section dir="rtl" lang="fa" className="w-full py-32">
<div className="w-full px-4 sm:px-6 lg:px-8">
<Card className={cn("w-full", className)}>
<CardHeader>
<CardTitle>پروفایل کاربری</CardTitle>
<CardDescription>
نام، ایمیل و عکس پروفایل خود را در فضای کاری به‌روز نگه دارید.
</CardDescription>
</CardHeader>
<CardContent className="space-y-6">
{/* Avatar Upload */}
<FileUpload
value={avatarFiles}
onValueChange={setAvatarFiles}
accept="image/*"
maxFiles={1}
maxSize={2 * 1024 * 1024}
>
<div className="flex items-center gap-4">
<FileUploadTrigger asChild>
<button
type="button"
className="group relative size-20 shrink-0 cursor-pointer rounded-full focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:outline-none"
>
<Avatar className="size-20">
<AvatarImage
src={avatarPreview}
alt={`آواتار ${defaultValues.name}`}
className="object-cover"
/>
<AvatarFallback className="text-xl font-semibold">
{initials}
</AvatarFallback>
</Avatar>
<div className="absolute inset-0 flex items-center justify-center rounded-full bg-black/50 opacity-0 transition-opacity group-hover:opacity-100">
<Camera className="size-6 text-white" />
</div>
</button>
</FileUploadTrigger>
<div className="space-y-1">
<p className="text-sm font-medium">عکس پروفایل</p>
<p className="text-xs text-muted-foreground">
برای تغییر عکس، روی آواتار کلیک کنید
</p>
<p className="text-xs text-muted-foreground">
JPG، PNG یا WEBP — حداکثر ۲ مگابایت.
</p>
</div>
</div>
{avatarFiles.length > 0 && (
<FileUploadList className="mt-3">
{avatarFiles.map((file, index) => (
<FileUploadItem
key={index}
value={file}
className="rounded-lg border bg-muted/30 p-2"
>
<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">
<X className="size-4" />
</Button>
</FileUploadItemDelete>
</FileUploadItem>
))}
</FileUploadList>
)}
</FileUpload>
<div className="grid gap-4 sm:grid-cols-2">
<div className="space-y-2">
<Label htmlFor="name">نام و نام خانوادگی</Label>
<Input
id="name"
placeholder="مثال: سارا محمدی"
defaultValue={defaultValues.name}
/>
</div>
<div className="space-y-2">
<Label htmlFor="username">نام کاربری</Label>
<Input
id="username"
placeholder="sarah.m"
defaultValue={defaultValues.username}
/>
</div>
</div>
<div className="space-y-2">
<Label htmlFor="email">ایمیل کاری</Label>
<Input
id="email"
type="email"
placeholder="you@company.com"
defaultValue={defaultValues.email}
/>
</div>
<div className="space-y-2">
<Label htmlFor="bio">معرفی کوتاه</Label>
<Textarea
id="bio"
placeholder="نقش و تمرکز کاری خود را بنویسید"
rows={4}
defaultValue={defaultValues.bio}
/>
<p className="text-xs text-muted-foreground">
حداکثر ۱۶۰ کاراکتر؛ در پروفایل عمومی نمایش داده می‌شود.
</p>
</div>
</CardContent>
<CardFooter className="flex justify-end gap-2">
<Button variant="outline">انصراف</Button>
<Button>ذخیره تغییرات</Button>
</CardFooter>
</Card>
</div>
</section>
);
};
export { SettingsProfile1 };