189 lines
5.6 KiB
TypeScript
189 lines
5.6 KiB
TypeScript
"use client";
|
|
|
|
import { Camera, Check, Pencil, X } from "lucide-react";
|
|
import { useState } from "react";
|
|
|
|
import { FileUpload, FileUploadTrigger } from "@/components/diceui/file-upload";
|
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Card, CardContent } from "@/components/ui/card";
|
|
import { Input } from "@/components/ui/input";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
interface ProfileData {
|
|
name: string;
|
|
email: string;
|
|
avatar?: string;
|
|
role?: string;
|
|
location?: string;
|
|
}
|
|
|
|
interface SettingsProfile7Props {
|
|
defaultValues?: Partial<ProfileData>;
|
|
className?: string;
|
|
}
|
|
|
|
const SettingsProfile7 = ({
|
|
defaultValues = {
|
|
name: "الهام میرزایی",
|
|
email: "alex.morgan@email.com",
|
|
avatar:
|
|
"/block-media/shadcnblocks/block/avatar/avatar8.jpg",
|
|
role: "مدیر موفقیت مشتری",
|
|
location: "تهران، ایران",
|
|
},
|
|
className,
|
|
}: SettingsProfile7Props) => {
|
|
const [editingField, setEditingField] = useState<string | null>(null);
|
|
const [formData, setFormData] = useState(defaultValues);
|
|
const [tempValue, setTempValue] = useState("");
|
|
const [avatarFiles, setAvatarFiles] = useState<File[]>([]);
|
|
|
|
const avatarPreview =
|
|
avatarFiles.length > 0
|
|
? URL.createObjectURL(avatarFiles[0])
|
|
: formData.avatar;
|
|
|
|
const startEdit = (field: string, currentValue: string) => {
|
|
setEditingField(field);
|
|
setTempValue(currentValue);
|
|
};
|
|
|
|
const saveEdit = (field: keyof ProfileData) => {
|
|
setFormData((prev) => ({ ...prev, [field]: tempValue }));
|
|
setEditingField(null);
|
|
};
|
|
|
|
const cancelEdit = () => {
|
|
setEditingField(null);
|
|
setTempValue("");
|
|
};
|
|
|
|
const initials = formData.name
|
|
?.split(" ")
|
|
.map((n) => n[0])
|
|
.join("")
|
|
.toUpperCase();
|
|
|
|
const EditableField = ({
|
|
field,
|
|
label,
|
|
value,
|
|
}: {
|
|
field: keyof ProfileData;
|
|
label: string;
|
|
value?: string;
|
|
}) => {
|
|
const isEditing = editingField === field;
|
|
|
|
return (
|
|
<div className="group flex items-center justify-between py-2">
|
|
<div className="min-w-0 flex-1">
|
|
<p className="text-xs text-muted-foreground">{label}</p>
|
|
{isEditing ? (
|
|
<div className="mt-1 flex items-center gap-2">
|
|
<Input
|
|
value={tempValue}
|
|
onChange={(e) => setTempValue(e.target.value)}
|
|
className="h-8"
|
|
autoFocus
|
|
onKeyDown={(e) => {
|
|
if (e.key === "Enter") saveEdit(field);
|
|
if (e.key === "Escape") cancelEdit();
|
|
}}
|
|
/>
|
|
<Button
|
|
size="icon"
|
|
variant="ghost"
|
|
className="size-8 shrink-0"
|
|
onClick={() => saveEdit(field)}
|
|
>
|
|
<Check className="size-4 text-green-600" />
|
|
</Button>
|
|
<Button
|
|
size="icon"
|
|
variant="ghost"
|
|
className="size-8 shrink-0"
|
|
onClick={cancelEdit}
|
|
>
|
|
<X className="size-4 text-muted-foreground" />
|
|
</Button>
|
|
</div>
|
|
) : (
|
|
<p className="truncate text-sm font-medium">
|
|
{value || <span className="text-muted-foreground">ثبت نشده</span>}
|
|
</p>
|
|
)}
|
|
</div>
|
|
{!isEditing && (
|
|
<Button
|
|
size="icon"
|
|
variant="ghost"
|
|
className="size-8 shrink-0 opacity-0 transition-opacity group-hover:opacity-100"
|
|
onClick={() => startEdit(field, value || "")}
|
|
>
|
|
<Pencil className="size-3.5" />
|
|
</Button>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
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)}>
|
|
<CardContent className="p-4">
|
|
<div className="flex gap-4">
|
|
{/* Avatar */}
|
|
<FileUpload
|
|
value={avatarFiles}
|
|
onValueChange={setAvatarFiles}
|
|
accept="image/*"
|
|
maxFiles={1}
|
|
maxSize={2 * 1024 * 1024}
|
|
>
|
|
<div className="relative shrink-0">
|
|
<Avatar className="size-16">
|
|
<AvatarImage
|
|
src={avatarPreview}
|
|
alt={
|
|
formData.name ? `آواتار ${formData.name}` : "عکس پروفایل"
|
|
}
|
|
className="object-cover"
|
|
/>
|
|
<AvatarFallback>{initials}</AvatarFallback>
|
|
</Avatar>
|
|
<FileUploadTrigger asChild>
|
|
<Button
|
|
size="icon"
|
|
variant="secondary"
|
|
className="absolute -end-1 -bottom-1 size-6 rounded-full shadow-sm"
|
|
>
|
|
<Camera className="size-3" />
|
|
</Button>
|
|
</FileUploadTrigger>
|
|
</div>
|
|
</FileUpload>
|
|
|
|
{/* Editable Fields */}
|
|
<div className="min-w-0 flex-1 divide-y">
|
|
<EditableField field="name" label="نام و نام خانوادگی" value={formData.name} />
|
|
<EditableField field="role" label="سمت شغلی" value={formData.role} />
|
|
<EditableField field="email" label="ایمیل کاری" value={formData.email} />
|
|
<EditableField
|
|
field="location"
|
|
label="موقعیت مکانی"
|
|
value={formData.location}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export { SettingsProfile7 };
|