176 lines
5.3 KiB
TypeScript
176 lines
5.3 KiB
TypeScript
"use client";
|
|
|
|
import { memo, useMemo } from "react";
|
|
import Image from "next/image";
|
|
import { useRouter } from "next/navigation";
|
|
|
|
import icons from "@/constant/images/icons";
|
|
import { PATH } from "@/constant/config";
|
|
import { QUERY_KEY } from "@/constant/config/enum";
|
|
|
|
import { useQuery } from "@tanstack/react-query";
|
|
import { httpRequest } from "@/services";
|
|
|
|
import Moment from "react-moment";
|
|
import {
|
|
Cake,
|
|
Phone,
|
|
MapPin,
|
|
Mail,
|
|
SquareUser,
|
|
ShieldUser,
|
|
} from "lucide-react";
|
|
|
|
import userServices from "@/services/userServices";
|
|
import CustomButton from "@/components/customs/custom-button";
|
|
import profileServices, { ProfileResponse } from "@/services/profileServices";
|
|
import { useSelector } from "react-redux";
|
|
import { RootState } from "@/redux/store";
|
|
|
|
function MainPageProfile() {
|
|
const router = useRouter();
|
|
const { infoUser } = useSelector((state: RootState) => state.user);
|
|
|
|
const profileQuery = useQuery<any>({
|
|
queryKey: [QUERY_KEY.table_list_profile],
|
|
queryFn: async () => {
|
|
const res = await httpRequest<any>({
|
|
showMessageFailed: true,
|
|
http: profileServices.getProfile(), // Đảm bảo endpoint trỏ về /api/v1/UserProfile/list
|
|
});
|
|
|
|
// Trả về đúng object chứa items theo cấu trúc của API
|
|
return (
|
|
res || {
|
|
items: [],
|
|
page: 1,
|
|
pageSize: 10,
|
|
total: 0,
|
|
totalPages: 0,
|
|
}
|
|
);
|
|
},
|
|
});
|
|
|
|
// Tìm kiếm thông tin profile của user hiện tại đang đăng nhập bằng useMemo
|
|
// eslint-disable-next-line react-hooks/preserve-manual-memoization
|
|
const currentUserProfile = useMemo(() => {
|
|
const listItems = profileQuery.data?.items || [];
|
|
if (!infoUser?.userId) return null;
|
|
|
|
// So khớp accountId của API trả về với userId trong Redux (infoUser)
|
|
return (
|
|
listItems.find((item: any) => item.accountId === infoUser.userId) || null
|
|
);
|
|
}, [profileQuery.data, infoUser?.userId]);
|
|
|
|
return (
|
|
<div className="flex flex-col p-6 bg-white/80 rounded-2xl">
|
|
{/* HEADER */}
|
|
<div className="flex items-center justify-between w-full">
|
|
<h2 className="text-xl font-semibold">Thông tin tài khoản</h2>
|
|
|
|
<div className="flex gap-2.5">
|
|
<CustomButton
|
|
variant="midnightBlue"
|
|
size="md"
|
|
rounded="full"
|
|
fullWidth={false}
|
|
href={PATH.UPDATEPROFILE}
|
|
>
|
|
Chỉnh sửa
|
|
</CustomButton>
|
|
</div>
|
|
</div>
|
|
|
|
{/* AVATAR */}
|
|
<div className="flex gap-4 mt-6 mb-4">
|
|
<Image
|
|
src={
|
|
currentUserProfile?.avatarUrl
|
|
? `${process.env.NEXT_PUBLIC_IMAGE}${currentUserProfile.avatarUrl}`
|
|
: icons.avatar
|
|
}
|
|
alt="avatar"
|
|
width={120}
|
|
height={120}
|
|
className="object-cover rounded-lg "
|
|
/>
|
|
</div>
|
|
|
|
{/* MAIN */}
|
|
<div className="flex gap-4 mt-6 flex-col md:flex-row">
|
|
{/* BASIC INFO */}
|
|
<div className="flex flex-col border border-gray-200 bg-gray-50 rounded-xl w-full md:w-1/2 p-5 text-gray-600">
|
|
<div className="text-xl font-semibold mb-2 text-gray-800">
|
|
Thông tin cơ bản
|
|
</div>
|
|
|
|
<div className="flex flex-col gap-3">
|
|
{/* NAME */}
|
|
<div className="grid grid-cols-[180px_1fr] items-center font-semibold">
|
|
<p className="flex gap-2">
|
|
<SquareUser size={24} />
|
|
Họ và tên
|
|
</p>
|
|
<span className="text-gray-900">
|
|
{currentUserProfile?.fullName || "---"}
|
|
</span>
|
|
</div>
|
|
|
|
{/* DOB */}
|
|
<div className="grid grid-cols-[180px_1fr] items-center font-semibold">
|
|
<p className="flex gap-2">
|
|
<Cake size={24} />
|
|
Ngày sinh
|
|
</p>
|
|
<span className="text-gray-900">
|
|
{currentUserProfile?.birthDate ? (
|
|
<Moment format="DD/MM/YYYY">
|
|
{currentUserProfile.birthDate}
|
|
</Moment>
|
|
) : (
|
|
"---"
|
|
)}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* CONTACT */}
|
|
<div className="flex flex-col border border-gray-200 bg-gray-50 rounded-xl w-full md:w-1/2 p-5 text-gray-600">
|
|
<div className="text-xl font-semibold mb-2 text-gray-800">
|
|
Liên hệ
|
|
</div>
|
|
|
|
<div className="flex flex-col gap-3">
|
|
{/* EMAIL */}
|
|
<div className="grid grid-cols-[180px_1fr] items-center font-semibold">
|
|
<p className="flex gap-2">
|
|
<Mail size={24} />
|
|
Email
|
|
</p>
|
|
<span className="text-gray-900">
|
|
{currentUserProfile?.email || "---"}
|
|
</span>
|
|
</div>
|
|
|
|
{/* PHONE */}
|
|
<div className="grid grid-cols-[180px_1fr] items-center font-semibold">
|
|
<p className="flex gap-2">
|
|
<Phone size={24} />
|
|
Số điện thoại
|
|
</p>
|
|
<span className="text-gray-900">
|
|
{currentUserProfile?.phone || "---"}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default memo(MainPageProfile);
|