feat(userAccount): improve user profile handling with avatar upload and dynamic display name
This commit is contained in:
@@ -1,25 +1,84 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { getParsedUserInfo, imageUrl } from "@/helper";
|
||||
import { request } from "@/services/response";
|
||||
import { toast } from "react-toastify";
|
||||
import Image from "next/image";
|
||||
|
||||
function Head() {
|
||||
const [userInfo, setUserInfo] = useState(null);
|
||||
const [avatar, setAvatar] = useState("");
|
||||
const [uploading, setUploading] = useState(false);
|
||||
const fileRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
setUserInfo(getParsedUserInfo());
|
||||
const parsed = getParsedUserInfo();
|
||||
setUserInfo(parsed);
|
||||
if (parsed?.uuid) {
|
||||
request
|
||||
.getUserProfile(parsed.uuid)
|
||||
.then((res) => {
|
||||
const profile = res?.data?.data ?? res?.data;
|
||||
if (profile?.avatar) setAvatar(profile.avatar);
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleAvatarChange = async (e) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (!file) return;
|
||||
setUploading(true);
|
||||
try {
|
||||
const res = await request.uploadUserAvatar(file);
|
||||
const url = res?.data?.avatar || res?.data?.url;
|
||||
if (url) {
|
||||
setAvatar(url);
|
||||
toast.success("عکس پروفایل بهروزرسانی شد");
|
||||
}
|
||||
} catch {
|
||||
toast.error("خطا در آپلود عکس");
|
||||
} finally {
|
||||
setUploading(false);
|
||||
if (fileRef.current) fileRef.current.value = "";
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full flex flex-row md:flex-col items-center justify-center md:justify-start gap-[12px] md:gap-[4px]">
|
||||
<Image
|
||||
className="rounded-full border-[3px] border-solid border-[#F8F8FF] shadow-[0px_1px_25.6px_0px_rgba(85,_89,_205,_0.20)]"
|
||||
src={imageUrl(userInfo?.picture?.[0]?.url)}
|
||||
alt="profile"
|
||||
height={73}
|
||||
width={73}
|
||||
/>
|
||||
<div className="relative">
|
||||
{avatar ? (
|
||||
<Image
|
||||
className="rounded-full border-[3px] border-solid border-[#F8F8FF] shadow-[0px_1px_25.6px_0px_rgba(85,_89,_205,_0.20)] object-cover w-[73px] h-[73px]"
|
||||
src={imageUrl(avatar)}
|
||||
alt="profile"
|
||||
height={73}
|
||||
width={73}
|
||||
/>
|
||||
) : (
|
||||
<div className="w-[73px] h-[73px] rounded-full border-[3px] border-solid border-[#F8F8FF] shadow-[0px_1px_25.6px_0px_rgba(85,_89,_205,_0.20)] bg-[#5559CE] text-[#FFF] flex items-center justify-center text-[28px] font-bold select-none">
|
||||
{userInfo?.realName?.trim()?.[0] ?? "؟"}
|
||||
</div>
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => fileRef.current?.click()}
|
||||
disabled={uploading}
|
||||
title="تغییر عکس"
|
||||
className="absolute bottom-0 left-0 bg-[#5559CE] text-white rounded-full w-[24px] h-[24px] flex items-center justify-center text-[12px] shadow-md disabled:opacity-60"
|
||||
>
|
||||
{uploading ? "…" : "✎"}
|
||||
</button>
|
||||
<input
|
||||
ref={fileRef}
|
||||
type="file"
|
||||
accept="image/*"
|
||||
hidden
|
||||
disabled={uploading}
|
||||
onChange={handleAvatarChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col items-start md:items-center justify-center gap-[8px] md:gap-[4px]">
|
||||
<p className="text-[#3B3B3B] text-[14px] font-bold">
|
||||
{userInfo?.realName}
|
||||
|
||||
Reference in New Issue
Block a user