mirror of
https://github.com/i701/sarlink-portal.git
synced 2025-07-15 17:15:50 +00:00
feat: implement user verification and rejection functionality with improved error handling ✨
This commit is contained in:
14
app/(dashboard)/users/[userId]/update/page.tsx
Normal file
14
app/(dashboard)/users/[userId]/update/page.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
export default async function UserUpdate({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{
|
||||
userId: string;
|
||||
}>;
|
||||
}) {
|
||||
const { userId } = await params;
|
||||
|
||||
return (
|
||||
<div>UserUpdate: {userId}</div>
|
||||
)
|
||||
}
|
@ -1,3 +1,14 @@
|
||||
import Image from "next/image";
|
||||
import { redirect } from "next/navigation";
|
||||
import { getProfileById } from "@/actions/user-actions";
|
||||
import ClientErrorMessage from "@/components/client-error-message";
|
||||
import InputReadOnly from "@/components/input-read-only";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import UserRejectDialog from "@/components/user/user-reject-dialog";
|
||||
import { UserVerifyDialog } from "@/components/user/user-verify-dialog";
|
||||
import { getNationalPerson } from "@/lib/person";
|
||||
import { tryCatch } from "@/utils/tryCatch";
|
||||
|
||||
export default async function VerifyUserPage({
|
||||
params,
|
||||
}: {
|
||||
@ -6,164 +17,168 @@ export default async function VerifyUserPage({
|
||||
}>;
|
||||
}) {
|
||||
const userId = (await params).userId;
|
||||
console.log("userId", userId);
|
||||
// const dbUser = await prisma.user.findUnique({
|
||||
// where: {
|
||||
// id: userId,
|
||||
// },
|
||||
// include: {
|
||||
// island: {
|
||||
// include: {
|
||||
// atoll: true
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
const [error, dbUser] = await tryCatch(getProfileById(userId));
|
||||
|
||||
// const nationalData = await getNationalPerson({ idCard: dbUser?.id_card ?? "" })
|
||||
const [nationalDataEror, nationalData] = await tryCatch(getNationalPerson({ idCard: dbUser?.id_card ?? "" }))
|
||||
if (nationalDataEror) {
|
||||
console.warn("Error fetching national data:", nationalDataEror);
|
||||
}
|
||||
if (error) {
|
||||
if (error.message === "UNAUTHORIZED") {
|
||||
redirect("/auth/signin");
|
||||
} else {
|
||||
return <ClientErrorMessage message={error.message} />;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
// return (
|
||||
// <div>
|
||||
// <div className="flex items-center justify-between text-gray-500 text-2xl font-bold title-bg py-4 px-2 mb-4">
|
||||
// <h3 className="text-sarLinkOrange text-2xl">Verify user</h3>
|
||||
// return <pre>{JSON.stringify(nationalData, null, 2)}</pre>
|
||||
const fullName = `${dbUser?.first_name} ${dbUser?.last_name}`;
|
||||
const nationalDob = nationalData?.dob?.split("T")[0];
|
||||
const dbUserDob = new Date(dbUser?.dob).toISOString().split("T")[0];
|
||||
|
||||
// <div className="flex gap-2">
|
||||
// {dbUser && !dbUser?.verified && <UserVerifyDialog user={dbUser} />}
|
||||
// {dbUser && !dbUser?.verified && <UserRejectDialog user={dbUser} />}
|
||||
// {dbUser?.verified && (
|
||||
// <Badge variant={"secondary"} className="bg-lime-500">
|
||||
// Verified
|
||||
// </Badge>
|
||||
// )}
|
||||
// </div>
|
||||
// </div>
|
||||
// <div className="grid grid-cols-1 md:grid-cols-2 gap-4 items-start justify-start">
|
||||
// <div id="database-information">
|
||||
// <h4 className="p-2 rounded font-semibold">Database Information</h4>
|
||||
// <div className="shadow p-2 rounded-lg title-bg space-y-1 my-2 grid grid-cols-1 md:grid-cols-2 gap-2">
|
||||
// <InputReadOnly
|
||||
// showCheck
|
||||
// checkTrue={dbUser?.id_card === nationalData.nic}
|
||||
// labelClassName="text-sarLinkOrange"
|
||||
// label="ID Card"
|
||||
// value={dbUser?.id_card ?? ""}
|
||||
// />
|
||||
// <InputReadOnly
|
||||
// showCheck
|
||||
// checkTrue={dbUser?.name === nationalData.name_en}
|
||||
// labelClassName="text-sarLinkOrange"
|
||||
// label="Name"
|
||||
// value={dbUser?.name ?? ""}
|
||||
// />
|
||||
// <InputReadOnly
|
||||
// showCheck
|
||||
// checkTrue={dbUser?.address === nationalData.house_name_en}
|
||||
// labelClassName="text-sarLinkOrange"
|
||||
// label="House Name"
|
||||
// value={dbUser?.address ?? ""}
|
||||
// />
|
||||
// <InputReadOnly
|
||||
// showCheck
|
||||
// checkTrue={dbUser?.island?.name === nationalData.island_name_en}
|
||||
// labelClassName="text-sarLinkOrange"
|
||||
// label="Island"
|
||||
// value={dbUser?.island?.name ?? ""}
|
||||
// />
|
||||
// <InputReadOnly
|
||||
// showCheck
|
||||
// checkTrue={dbUser?.island?.atoll.name === nationalData.atoll_en}
|
||||
// labelClassName="text-sarLinkOrange"
|
||||
// label="Atoll"
|
||||
// value={dbUser?.island?.atoll.name ?? ""}
|
||||
// />
|
||||
return (
|
||||
<div>
|
||||
<div className="flex items-center justify-between text-gray-500 text-2xl font-bold title-bg py-4 px-2 mb-4">
|
||||
<h3 className="text-sarLinkOrange text-2xl">Verify user</h3>
|
||||
|
||||
// <InputReadOnly
|
||||
// showCheck
|
||||
// checkTrue={
|
||||
// new Date(dbUser?.dob ?? "") === new Date(nationalData.dob)
|
||||
// }
|
||||
// labelClassName="text-sarLinkOrange"
|
||||
// label="DOB"
|
||||
// value={new Date(dbUser?.dob ?? "").toLocaleDateString("en-US", {
|
||||
// month: "short",
|
||||
// day: "2-digit",
|
||||
// year: "numeric",
|
||||
// })}
|
||||
// />
|
||||
// <InputReadOnly
|
||||
// showCheck
|
||||
// checkTrue={dbUser?.phoneNumber === nationalData.primary_contact}
|
||||
// labelClassName="text-sarLinkOrange"
|
||||
// label="Phone Number"
|
||||
// value={dbUser?.phoneNumber ?? ""}
|
||||
// />
|
||||
// </div>
|
||||
// </div>
|
||||
// <div id="national-information">
|
||||
// <h4 className="p-2 rounded font-semibold">National Information</h4>
|
||||
// <div className="shadow p-2 rounded-md title-bg space-y-1 my-2 grid grid-cols-1 md:grid-cols-2 gap-2">
|
||||
// <InputReadOnly
|
||||
// showCheck={false}
|
||||
// labelClassName="text-green-500"
|
||||
// label="ID Card"
|
||||
// value={nationalData?.nic ?? ""}
|
||||
// />
|
||||
// <InputReadOnly
|
||||
// showCheck={false}
|
||||
// labelClassName="text-green-500"
|
||||
// label="Name"
|
||||
// value={nationalData?.name_en ?? ""}
|
||||
// />
|
||||
// <InputReadOnly
|
||||
// showCheck={false}
|
||||
// labelClassName="text-green-500"
|
||||
// label="House Name"
|
||||
// value={nationalData?.house_name_en ?? ""}
|
||||
// />
|
||||
// <InputReadOnly
|
||||
// showCheck={false}
|
||||
// labelClassName="text-green-500"
|
||||
// label="Island"
|
||||
// value={nationalData?.island_name_en ?? ""}
|
||||
// />
|
||||
// <InputReadOnly
|
||||
// showCheck={false}
|
||||
// labelClassName="text-green-500"
|
||||
// label="Atoll"
|
||||
// value={nationalData?.atoll_en ?? ""}
|
||||
// />
|
||||
// <InputReadOnly
|
||||
// showCheck={false}
|
||||
// labelClassName="text-green-500"
|
||||
// label="DOB"
|
||||
// value={new Date(nationalData?.dob ?? "").toLocaleDateString(
|
||||
// "en-US",
|
||||
// {
|
||||
// month: "short",
|
||||
// day: "2-digit",
|
||||
// year: "numeric",
|
||||
// },
|
||||
// )}
|
||||
// />
|
||||
// <InputReadOnly
|
||||
// showCheck={false}
|
||||
// labelClassName="text-green-500"
|
||||
// label="Phone Number"
|
||||
// value={nationalData?.primary_contact ?? ""}
|
||||
// />
|
||||
// <div className="flex flex-col col-span-2 items-center justify-center">
|
||||
// <Image
|
||||
// src={nationalData.image_url || "https://i.pravatar.cc/300"}
|
||||
// height={100}
|
||||
// width={100}
|
||||
// className="object-fit aspect-square rounded-full"
|
||||
// alt="id photo"
|
||||
// />
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// );
|
||||
<div className="flex gap-2">
|
||||
{dbUser && !dbUser?.verified && <UserVerifyDialog user={dbUser} />}
|
||||
{dbUser && !dbUser?.verified && <UserRejectDialog user={dbUser} />}
|
||||
{dbUser?.verified && (
|
||||
<Badge variant={"secondary"} className="bg-lime-500">
|
||||
Verified
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 items-start justify-start">
|
||||
<div id="database-information">
|
||||
<h4 className="p-2 rounded font-semibold">Database Information</h4>
|
||||
<div className="shadow p-2 rounded-lg title-bg space-y-1 my-2 grid grid-cols-1 md:grid-cols-2 gap-2">
|
||||
<InputReadOnly
|
||||
showCheck
|
||||
checkTrue={dbUser?.id_card === nationalData?.nic}
|
||||
labelClassName="text-sarLinkOrange"
|
||||
label="ID Card"
|
||||
value={dbUser?.id_card ?? ""}
|
||||
/>
|
||||
<InputReadOnly
|
||||
showCheck
|
||||
checkTrue={fullName === nationalData?.name_en}
|
||||
labelClassName="text-sarLinkOrange"
|
||||
label="Name"
|
||||
value={fullName}
|
||||
/>
|
||||
<InputReadOnly
|
||||
showCheck
|
||||
checkTrue={dbUser?.address === nationalData?.house_name_en}
|
||||
labelClassName="text-sarLinkOrange"
|
||||
label="House Name"
|
||||
value={dbUser?.address ?? ""}
|
||||
/>
|
||||
<InputReadOnly
|
||||
showCheck
|
||||
checkTrue={dbUser?.island?.name === nationalData?.island_name_en}
|
||||
labelClassName="text-sarLinkOrange"
|
||||
label="Island"
|
||||
value={dbUser?.island?.name ?? ""}
|
||||
/>
|
||||
<InputReadOnly
|
||||
showCheck
|
||||
checkTrue={dbUser?.atoll.name === nationalData?.atoll_en}
|
||||
labelClassName="text-sarLinkOrange"
|
||||
label="Atoll"
|
||||
value={dbUser?.island?.name ?? ""}
|
||||
/>
|
||||
|
||||
<InputReadOnly
|
||||
showCheck
|
||||
checkTrue={
|
||||
dbUserDob === nationalDob
|
||||
}
|
||||
labelClassName="text-sarLinkOrange"
|
||||
label="DOB"
|
||||
value={new Date(dbUser?.dob ?? "").toLocaleDateString("en-US", {
|
||||
month: "short",
|
||||
day: "2-digit",
|
||||
year: "numeric",
|
||||
})}
|
||||
/>
|
||||
<InputReadOnly
|
||||
showCheck
|
||||
checkTrue={dbUser?.mobile === nationalData?.primary_contact}
|
||||
labelClassName="text-sarLinkOrange"
|
||||
label="Phone Number"
|
||||
value={dbUser?.mobile ?? ""}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{(
|
||||
<div id="national-information">
|
||||
<h4 className="p-2 rounded font-semibold">National Information</h4>
|
||||
<div className="shadow p-2 rounded-lg title-bg space-y-1 my-2 grid grid-cols-1 md:grid-cols-2 gap-2">
|
||||
<InputReadOnly
|
||||
showCheck={false}
|
||||
labelClassName="text-green-500"
|
||||
label="ID Card"
|
||||
value={nationalData?.nic ?? ""}
|
||||
/>
|
||||
<InputReadOnly
|
||||
showCheck={false}
|
||||
labelClassName="text-green-500"
|
||||
label="Name"
|
||||
value={nationalData?.name_en ?? ""}
|
||||
/>
|
||||
<InputReadOnly
|
||||
showCheck={false}
|
||||
labelClassName="text-green-500"
|
||||
label="House Name"
|
||||
value={nationalData?.house_name_en ?? ""}
|
||||
/>
|
||||
<InputReadOnly
|
||||
showCheck={false}
|
||||
labelClassName="text-green-500"
|
||||
label="Island"
|
||||
value={nationalData?.island_name_en ?? ""}
|
||||
/>
|
||||
<InputReadOnly
|
||||
showCheck={false}
|
||||
labelClassName="text-green-500"
|
||||
label="Atoll"
|
||||
value={nationalData?.atoll_en ?? ""}
|
||||
/>
|
||||
<InputReadOnly
|
||||
showCheck={false}
|
||||
labelClassName="text-green-500"
|
||||
label="DOB"
|
||||
value={new Date(nationalData?.dob ?? "").toLocaleDateString(
|
||||
"en-US",
|
||||
{
|
||||
month: "short",
|
||||
day: "2-digit",
|
||||
year: "numeric",
|
||||
},
|
||||
)}
|
||||
/>
|
||||
<InputReadOnly
|
||||
showCheck={false}
|
||||
labelClassName="text-green-500"
|
||||
label="Phone Number"
|
||||
value={nationalData?.primary_contact ?? ""}
|
||||
/>
|
||||
<div className="flex flex-col col-span-2 items-center justify-center">
|
||||
<Image
|
||||
src={nationalData?.image_url || "https://i.pravatar.cc/300"}
|
||||
height={100}
|
||||
width={100}
|
||||
className="object-fit aspect-square rounded-full"
|
||||
alt="id photo"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user