mirror of
https://github.com/i701/sarlink-portal.git
synced 2025-06-29 15:47:09 +00:00
Refactor authentication middleware to use native fetch, update dependencies, and enhance error handling. Add new error boundary component for dashboard and improve user verification UI. Update payment handling and device management components for better user experience. Adjust CSS for error backgrounds and refine input read-only components with validation indicators.
Some checks failed
Build and Push Docker Images / Build and Push Docker Images (push) Failing after 3m9s
Some checks failed
Build and Push Docker Images / Build and Push Docker Images (push) Failing after 3m9s
This commit is contained in:
12
app/(dashboard)/devices-to-pay/page.tsx
Normal file
12
app/(dashboard)/devices-to-pay/page.tsx
Normal file
@ -0,0 +1,12 @@
|
||||
import DevicesForPayment from '@/components/devices-for-payment'
|
||||
import prisma from '@/lib/db';
|
||||
import React from 'react'
|
||||
|
||||
export default async function DevicesToPay() {
|
||||
const billFormula = await prisma.billFormula.findFirst();
|
||||
return (
|
||||
<div>
|
||||
<DevicesForPayment billFormula={billFormula ?? undefined} />
|
||||
</div>
|
||||
)
|
||||
}
|
36
app/(dashboard)/error.tsx
Normal file
36
app/(dashboard)/error.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
'use client' // Error boundaries must be Client Components
|
||||
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { TriangleAlert } from "lucide-react";
|
||||
import { useEffect } from 'react'
|
||||
export default function DashboardError({
|
||||
error,
|
||||
reset,
|
||||
}: {
|
||||
error: Error & { digest?: string }
|
||||
reset: () => void
|
||||
}) {
|
||||
useEffect(() => {
|
||||
// Log the error to an error reporting service
|
||||
console.error(error)
|
||||
}, [error])
|
||||
|
||||
return (
|
||||
<div className='error-bg dark:error-bg-dark rounded-lg p-4 h-full flex flex-col gap-4 items-center justify-center'>
|
||||
<div className='bg-white dark:bg-transparent p-6 rounded flex flex-col items-center justify-center gap-4'>
|
||||
<TriangleAlert color='red' />
|
||||
<h2 className='text-red-500 text-xl font-semibold'>Something went wrong!</h2>
|
||||
<Button
|
||||
variant={"destructive"}
|
||||
size={"lg"}
|
||||
onClick={
|
||||
// Attempt to recover by trying to re-render the segment
|
||||
() => reset()
|
||||
}
|
||||
>
|
||||
Try again
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -29,12 +29,15 @@ export default async function VerifyUserPage({
|
||||
})
|
||||
|
||||
const nationalData = await getNationalPerson({ idCard: dbUser?.id_card ?? "" })
|
||||
|
||||
|
||||
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="">
|
||||
<h3 className="text-sarLinkOrange text-2xl">
|
||||
Verify user
|
||||
</h3>
|
||||
|
||||
<div className='flex gap-2'>
|
||||
{dbUser && !dbUser?.verified && <UserVerifyDialog user={dbUser} />}
|
||||
{dbUser && !dbUser?.verified && <UserRejectDialog user={dbUser} />}
|
||||
@ -46,44 +49,43 @@ export default async function VerifyUserPage({
|
||||
<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 labelClassName='text-sarLinkOrange' label="ID Card" value={dbUser?.id_card ?? ""} />
|
||||
<InputReadOnly labelClassName='text-sarLinkOrange' label="Name" value={dbUser?.name ?? ""} />
|
||||
<InputReadOnly labelClassName='text-sarLinkOrange' label="House Name" value={dbUser?.address ?? ""} />
|
||||
<InputReadOnly labelClassName='text-sarLinkOrange' label="Island" value={dbUser?.island?.name ?? ""} />
|
||||
<InputReadOnly labelClassName='text-sarLinkOrange' label="Atoll" value={dbUser?.island?.atoll.name ?? ""} />
|
||||
<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 ?? ""} />
|
||||
|
||||
<InputReadOnly labelClassName='text-sarLinkOrange' label="DOB" value={new Date(dbUser?.dob ?? "").toLocaleDateString("en-US", {
|
||||
<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 labelClassName='text-sarLinkOrange' label="Phone Number" value={dbUser?.phoneNumber ?? ""} />
|
||||
<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 labelClassName='text-green-500' label="ID Card" value={nationalData?.nic ?? ""} />
|
||||
<InputReadOnly labelClassName='text-green-500' label="Name" value={nationalData?.name_en ?? ""} />
|
||||
<InputReadOnly labelClassName='text-green-500' label="House Name" value={nationalData?.house_name_en ?? ""} />
|
||||
<InputReadOnly labelClassName='text-green-500' label="Island" value={nationalData?.island_name_en ?? ""} />
|
||||
<InputReadOnly labelClassName='text-green-500' label="Atoll" value={nationalData?.atoll_en ?? ""} />
|
||||
<InputReadOnly labelClassName='text-green-500' label="DOB" value={new Date(nationalData?.dob ?? "").toLocaleDateString("en-US", {
|
||||
<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 labelClassName='text-green-500' label="Phone Number" value={nationalData?.primary_contact ?? ""} />
|
||||
<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}
|
||||
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>
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { Rejectuser } from "@/actions/user-actions";
|
||||
import Filter from "@/components/filter";
|
||||
import Search from "@/components/search";
|
||||
import { UsersTable } from "@/components/user-table";
|
||||
@ -9,6 +10,7 @@ import {
|
||||
Hourglass,
|
||||
Minus,
|
||||
} from "lucide-react";
|
||||
import { redirect } from "next/navigation";
|
||||
import React, { Suspense } from "react";
|
||||
|
||||
const sortfilterOptions = [
|
||||
@ -36,6 +38,7 @@ export default async function AdminUsers({
|
||||
}) {
|
||||
await AdminAuthGuard();
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="flex justify-between items-center border-[1px] rounded-md border-dashed font-bold title-bg py-4 px-2 mb-4">
|
||||
|
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user