From a571de6a14a14a85daad3fc4310e8b306f681a97 Mon Sep 17 00:00:00 2001 From: Amirhossein Khalili Date: Fri, 13 Mar 2026 02:23:41 +0800 Subject: [PATCH] feat(profile): improve profile editing UX flow --- src/pages/Profile.tsx | 224 ++++++++++++++++++++++-------------------- 1 file changed, 117 insertions(+), 107 deletions(-) diff --git a/src/pages/Profile.tsx b/src/pages/Profile.tsx index 896923a..a6e68c4 100644 --- a/src/pages/Profile.tsx +++ b/src/pages/Profile.tsx @@ -8,7 +8,7 @@ import { removeProfilePicture } from "../api/users" import { Button } from "../components/ui/button" -import { Camera, Edit2, Trash2, User as UserIcon, UploadCloud } from "lucide-react" +import { Camera, Edit2, Trash2, User as UserIcon, UploadCloud, X, Check } from "lucide-react" import JalaliDatePicker from "../components/ui/JalaliDatePicker" import { toast } from "sonner" import { Modal } from "../components/Modal" @@ -54,8 +54,8 @@ export default function Profile() { } } - // Modals state - const [isEditModalOpen, setIsEditModalOpen] = useState(false) + // Modals & Editing state + const [isEditing, setIsEditing] = useState(false) const [isPicModalOpen, setIsPicModalOpen] = useState(false) const [isSaving, setIsSaving] = useState(false) @@ -89,10 +89,15 @@ export default function Profile() { description: user.description || "", birth_date: user.birth_date || "", }) - setIsEditModalOpen(true) + setIsEditing(true) } } + const handleCancelEdit = () => { + setIsEditing(false) + setFormData({}) + } + const handleSaveProfile = async () => { setIsSaving(true) try { @@ -108,7 +113,7 @@ export default function Profile() { const updatedUser = await updateUserProfile(payload) setUser(prev => prev ? { ...prev, ...updatedUser } : updatedUser) - setIsEditModalOpen(false) + setIsEditing(false) toast.success(t.profile.toasts.successEdit) } catch (error) { toast.error(t.profile.toasts.error) @@ -209,145 +214,150 @@ export default function Profile() {

{user.email || "-"}

- - {/* Details Card */}
-

- {t.profile?.title || 'Personal Information'} -

+ + {/* Header with Title and Edit Button */} +
+

+ {t.profile?.title || 'Personal Information'} +

+ + {!isEditing && ( + + )} +
+ + {/* Row 1: First Name | Last Name */}
{t.profile?.firstName || 'First Name'} -

{user.first_name || "-"}

+ {isEditing ? ( + setFormData({ ...formData, first_name: e.target.value })} + disabled={isSaving} + className="mt-1 w-full rounded-md border border-slate-300 bg-transparent px-3 py-2 text-sm dark:border-slate-700 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500" + /> + ) : ( +

{user.first_name || "-"}

+ )}
+
{t.profile?.lastName || 'Last Name'} -

{user.last_name || "-"}

+ {isEditing ? ( + setFormData({ ...formData, last_name: e.target.value })} + disabled={isSaving} + className="mt-1 w-full rounded-md border border-slate-300 bg-transparent px-3 py-2 text-sm dark:border-slate-700 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500" + /> + ) : ( +

{user.last_name || "-"}

+ )}
+ + {/* Row 2: Mobile | Email */}
{t.profile?.mobileNumber || 'Mobile'} -

+

{toPersianNum(user.mobile)}

+
- {t.profile?.birthDate || 'Birth Date'} -

- {formatDate(user.birth_date)} {user.age ? `(${toPersianNum(user.age)} ${t.profile?.yearsOld})` : ""} -

-
-
- {t.profile?.description || 'Description'} -

{user.description || "-"}

-
- {user.created_at && ( -
- {t.profile?.dateJoined || 'Date Joined'} -

- {formatDate(user.created_at)} -

-
- )} -
-
- - - - {/* Edit Profile Modal */} - {isEditModalOpen && ( - setIsEditModalOpen(false)} - title={t.profile?.title || "Edit Profile"} - maxWidth="max-w-lg" - footer={ - <> - - - - } - > -
- -
-
-
- - setFormData({ ...formData, first_name: e.target.value })} - className="mt-1 w-full rounded-md border border-slate-300 bg-transparent px-3 py-2 text-sm dark:border-slate-700 dark:text-white" - /> -
-
- - setFormData({ ...formData, last_name: e.target.value })} - className="mt-1 w-full rounded-md border border-slate-300 bg-transparent px-3 py-2 text-sm dark:border-slate-700 dark:text-white" - /> -
-
- -
- + {t.profile?.email || 'Email'} + {isEditing ? ( setFormData({ ...formData, email: e.target.value })} - className="mt-1 w-full rounded-md border border-slate-300 bg-transparent px-3 py-2 text-sm dark:border-slate-700 dark:text-white flex-row-reverse" + disabled={isSaving} dir="ltr" + className="mt-1 w-full rounded-md border border-slate-300 bg-transparent px-3 py-2 text-sm dark:border-slate-700 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500" /> -
+ ) : ( +

{user.email || "-"}

+ )} +
- setFormData({ ...formData, birth_date: date })} - disabled={isSaving} - /> + {/* Row 3: Birth Date | Date Joined */} +
+ {isEditing ? ( +
+ setFormData({ ...formData, birth_date: date })} + disabled={isSaving} + /> +
+ ) : ( + <> + {t.profile?.birthDate || 'Birth Date'} +

+ {formatDate(user.birth_date)} {user.age ? `(${toPersianNum(user.age)} ${t.profile?.yearsOld || 'years'})` : ""} +

+ + )} +
-
- +
+ {t.profile?.dateJoined || 'Date Joined'} +

+ {formatDate(user.created_at)} +

+
+ + {/* Row 4: Description (Full Width) */} +
+ {t.profile?.description || 'Description'} + {isEditing ? (