diff --git a/actions/user-actions.ts b/actions/user-actions.ts index a986604..7138fb9 100644 --- a/actions/user-actions.ts +++ b/actions/user-actions.ts @@ -1,16 +1,20 @@ "use server"; +import { revalidatePath } from "next/cache"; +import { redirect } from "next/navigation"; import { getServerSession } from "next-auth"; import { authOptions } from "@/app/auth"; +import type { RejectUserFormState } from "@/components/user/user-reject-dialog"; +import type { ApiError } from "@/lib/backend-types"; import type { User, UserProfile } from "@/lib/types/user"; import { handleApiResponse } from "@/utils/tryCatch"; -export async function VerifyUser(userId: string) { +export async function VerifyUser(_userId: string) { // const user = await prisma.user.findUnique({ // where: { // id: userId, // }, - // include: { + // include: {Rejectuser // atoll: true, // island: true, // }, @@ -87,3 +91,41 @@ export async function getProfileById(userId: string) { return handleApiResponse(response, "getProfilebyId"); } +export async function rejectUser( + _prevState: RejectUserFormState, + formData: FormData +): Promise { + const userId = formData.get("userId") as string; + const rejection_details = formData.get("rejection_details") as string; + const session = await getServerSession(authOptions); + const response = await fetch( + `${process.env.SARLINK_API_BASE_URL}/api/auth/users/${userId}/reject/`, + { + method: "DELETE", + headers: { + "Content-Type": "application/json", + Authorization: `Token ${session?.apiToken}`, + }, + body: JSON.stringify({ rejection_details: rejection_details }), + }, + ); + + if (!response.ok) { + const errorData = await response.json(); + throw new Error(errorData.message || errorData.detail || "Failed to reject user"); + } + + // Handle 204 No Content response (successful deletion) + if (response.status === 204) { + revalidatePath("/users"); + redirect("/users"); + } + + revalidatePath("/users"); + const error = await response.json() + return { + message: (error as ApiError).message || (error as ApiError).detail || "An unexpected error occurred.", + fieldErrors: {}, + payload: formData + }; +} diff --git a/app/(dashboard)/users/[userId]/update/page.tsx b/app/(dashboard)/users/[userId]/update/page.tsx new file mode 100644 index 0000000..14328a7 --- /dev/null +++ b/app/(dashboard)/users/[userId]/update/page.tsx @@ -0,0 +1,14 @@ + +export default async function UserUpdate({ + params, +}: { + params: Promise<{ + userId: string; + }>; +}) { + const { userId } = await params; + + return ( +
UserUpdate: {userId}
+ ) +} diff --git a/app/(dashboard)/users/[userId]/verify/page.tsx b/app/(dashboard)/users/[userId]/verify/page.tsx index 5d71178..cfad444 100644 --- a/app/(dashboard)/users/[userId]/verify/page.tsx +++ b/app/(dashboard)/users/[userId]/verify/page.tsx @@ -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 ; + } + } - return null; - // return ( - //
- //
- //

Verify user

+ // return
{JSON.stringify(nationalData, null, 2)}
+ 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]; - //
- // {dbUser && !dbUser?.verified && } - // {dbUser && !dbUser?.verified && } - // {dbUser?.verified && ( - // - // Verified - // - // )} - //
- //
- //
- //
- //

Database Information

- //
- // - // - // - // - // + return ( +
+
+

Verify user

- // - // - //
- //
- //
- //

National Information

- //
- // - // - // - // - // - // - // - //
- // id photo - //
- //
- //
- //
- //
- // ); +
+ {dbUser && !dbUser?.verified && } + {dbUser && !dbUser?.verified && } + {dbUser?.verified && ( + + Verified + + )} +
+
+
+
+

Database Information

+
+ + + + + + + + +
+
+ {( +
+

National Information

+
+ + + + + + + +
+ id photo +
+
+
+ )} +
+
+ ); } diff --git a/components/input-read-only.tsx b/components/input-read-only.tsx index 851b795..9ef8358 100644 --- a/components/input-read-only.tsx +++ b/components/input-read-only.tsx @@ -1,5 +1,5 @@ -import { cn } from '@/lib/utils'; import { CheckCheck, X } from 'lucide-react'; +import { cn } from '@/lib/utils'; export default function InputReadOnly({ label, value, labelClassName, className, showCheck = true, checkTrue = false }: { label: string; @@ -10,7 +10,7 @@ export default function InputReadOnly({ label, value, labelClassName, className, checkTrue?: boolean }) { return ( -
+