feat(userAccount): enhance user profile handling with avatar upload and additional user data
This commit is contained in:
@@ -37,7 +37,7 @@ function Head({ user }) {
|
||||
</div>
|
||||
<div className="flex flex-col gap-[8px] items-start justify-start">
|
||||
<p className="text-[#3B3B3B] text-nowrap text-[16px] font-medium">
|
||||
{user.total_transactions}{" "}
|
||||
{Number(user?.total_transactions || 0).toLocaleString("fa-IR")}{" "}
|
||||
<span className="text-[12px]">تومان</span>
|
||||
</p>
|
||||
<h1 className="text-[#616161] text-nowrap text-[14px] font-normal">
|
||||
@@ -51,7 +51,7 @@ function Head({ user }) {
|
||||
</div>
|
||||
<div className="flex flex-col gap-[8px] items-start justify-start">
|
||||
<p className="text-[#3B3B3B] text-nowrap text-[16px] font-medium">
|
||||
{user.number_of_turns}
|
||||
{Number(user?.number_of_turns || 0).toLocaleString("fa-IR")}
|
||||
</p>
|
||||
<p className="text-[#616161] text-nowrap text-[14px] font-normal">
|
||||
تعداد نوبت های شما
|
||||
|
||||
@@ -25,7 +25,7 @@ function Form({ insurance, errors, changeData, information }) {
|
||||
name="work_phone"
|
||||
isTransparent={true}
|
||||
changeData={changeData}
|
||||
data={parsedUserInfo?.username}
|
||||
data={parsedUserInfo?.mobile_number ?? parsedUserInfo?.username}
|
||||
/>
|
||||
</Content>
|
||||
<Content
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import Image from "next/image";
|
||||
import { toast } from "react-toastify";
|
||||
import Form from "./form";
|
||||
import { request } from "@/services/response";
|
||||
import ButtonSendData from "./ButtonSendData";
|
||||
import { changeDateType, getParsedUserInfo } from "@/helper";
|
||||
import { changeDateType, getParsedUserInfo, imageUrl } from "@/helper";
|
||||
import { disease } from "./form/disease";
|
||||
import LoadingComponent from "@/app/component/LoadingComponent";
|
||||
|
||||
@@ -11,6 +13,26 @@ function Information({ information, setInformation }) {
|
||||
const [insurance, setInsurance] = useState();
|
||||
const [errors, setErrors] = useState({});
|
||||
const [loadingInfo, setLoadingInfo] = useState(true);
|
||||
const [avatarUploading, setAvatarUploading] = useState(false);
|
||||
|
||||
const handleAvatarChange = async (e) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (!file) return;
|
||||
setAvatarUploading(true);
|
||||
try {
|
||||
const res = await request.uploadUserAvatar(file);
|
||||
const url = res?.data?.avatar || res?.data?.url;
|
||||
if (url) {
|
||||
setInformation((prev) => ({ ...(prev || {}), avatar: url }));
|
||||
toast.success("عکس پروفایل بهروزرسانی شد");
|
||||
}
|
||||
} catch {
|
||||
toast.error("خطا در آپلود عکس");
|
||||
} finally {
|
||||
setAvatarUploading(false);
|
||||
e.target.value = "";
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const parsedUserInfo = getParsedUserInfo();
|
||||
@@ -101,6 +123,25 @@ function Information({ information, setInformation }) {
|
||||
return (
|
||||
<LoadingComponent loading={loadingInfo}>
|
||||
<div className="opacity-page">
|
||||
<div className="flex items-center gap-[16px] mb-[24px]">
|
||||
<Image
|
||||
src={imageUrl(information?.avatar, "/assets/images/profile-user.png")}
|
||||
alt="avatar"
|
||||
width={72}
|
||||
height={72}
|
||||
className="w-[72px] h-[72px] rounded-full object-cover border border-[#EFEFEF]"
|
||||
/>
|
||||
<label className="cursor-pointer text-[#5559CE] text-[14px] font-medium">
|
||||
{avatarUploading ? "در حال آپلود..." : "تغییر عکس"}
|
||||
<input
|
||||
type="file"
|
||||
accept="image/*"
|
||||
hidden
|
||||
disabled={avatarUploading}
|
||||
onChange={handleAvatarChange}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<Form
|
||||
errors={errors}
|
||||
insurance={insurance}
|
||||
|
||||
@@ -38,11 +38,16 @@ function Turns({ user, setIsTurnsDetails, loading }) {
|
||||
const items = response?.data?.data;
|
||||
|
||||
if (Array.isArray(items)) {
|
||||
setAppointments(items);
|
||||
// API برمیگرداند doctor_name/doctor_uuid (تخت)؛ کامپوننتها doctor.name (تودرتو) میخواهند.
|
||||
const normalized = items.map((a) => ({
|
||||
...a,
|
||||
doctor: { uuid: a.doctor_uuid, name: a.doctor_name, specialties: [] },
|
||||
}));
|
||||
setAppointments(normalized);
|
||||
} else {
|
||||
setAppointments([]);
|
||||
}
|
||||
setTotalPages(1);
|
||||
setTotalPages(response?.meta?.totalPages || 1);
|
||||
} catch (error) {
|
||||
console.error("Error fetching appointments:", error);
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user