From 39e84723b1a94d6bdad4dde8640c1c579d0c8192 Mon Sep 17 00:00:00 2001 From: i701 Date: Sat, 20 Sep 2025 14:40:10 +0500 Subject: [PATCH] =?UTF-8?q?refactor:=20remove=20table=20captions=20from=20?= =?UTF-8?q?all=20tables=20=F0=9F=94=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devices/device-table-skeleton.tsx | 134 +++-- components/admin/admin-devices-table.tsx | 304 +++++------ components/admin/admin-topup-table.tsx | 246 +++++---- components/admin/user-payments-table.tsx | 304 +++++------ components/devices-table.tsx | 210 ++++--- components/payments-table.tsx | 516 +++++++++--------- components/topups-table.tsx | 386 +++++++------ components/user-table.tsx | 257 ++++----- components/wallet-transactions-table.tsx | 436 ++++++++------- 9 files changed, 1380 insertions(+), 1413 deletions(-) diff --git a/app/(dashboard)/devices/device-table-skeleton.tsx b/app/(dashboard)/devices/device-table-skeleton.tsx index 033426f..bebafde 100644 --- a/app/(dashboard)/devices/device-table-skeleton.tsx +++ b/app/(dashboard)/devices/device-table-skeleton.tsx @@ -1,78 +1,76 @@ import { Skeleton } from "@/components/ui/skeleton"; import { - Table, - TableBody, - TableCaption, - TableCell, - TableFooter, - TableHead, - TableHeader, - TableRow, + Table, + TableBody, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, } from "@/components/ui/table"; import { cn } from "@/lib/utils"; export default function DevicesTableSkeleton() { - return ( - <> -
- - Table of all devices. - - - Device Name - MAC Address - # - - - - {Array.from({ length: 10 }).map((_, i) => ( - - - - - - - - - - - - ))} - - - - - - - - - - - -
-
-
- {Array.from({ length: 10 }).map((_, i) => ( - - ))} -
- - ); + return ( + <> +
+ + + + Device Name + MAC Address + # + + + + {Array.from({ length: 10 }).map((_, i) => ( + + + + + + + + + + + + ))} + + + + + + + + + + + +
+
+
+ {Array.from({ length: 10 }).map((_, i) => ( + + ))} +
+ + ); } function DeviceCardSkeleton() { - return ( -
-
- - - - -
-
- ); + return ( +
+
+ + + + +
+
+ ); } diff --git a/components/admin/admin-devices-table.tsx b/components/admin/admin-devices-table.tsx index d8eacb5..818380a 100644 --- a/components/admin/admin-devices-table.tsx +++ b/components/admin/admin-devices-table.tsx @@ -4,14 +4,13 @@ import { redirect } from "next/navigation"; import { getServerSession } from "next-auth"; import { authOptions } from "@/app/auth"; import { - Table, - TableBody, - TableCaption, - TableCell, - TableFooter, - TableHead, - TableHeader, - TableRow, + Table, + TableBody, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, } from "@/components/ui/table"; import { cn } from "@/lib/utils"; import { getDevices } from "@/queries/devices"; @@ -21,156 +20,155 @@ import ClientErrorMessage from "../client-error-message"; import Pagination from "../pagination"; export async function AdminDevicesTable({ - searchParams, + searchParams, }: { - searchParams: Promise<{ - [key: string]: unknown; - }>; + searchParams: Promise<{ + [key: string]: unknown; + }>; }) { - const resolvedParams = await searchParams; - const session = await getServerSession(authOptions); - const isAdmin = session?.user?.is_admin; + const resolvedParams = await searchParams; + const session = await getServerSession(authOptions); + const isAdmin = session?.user?.is_admin; - const page = Number.parseInt(resolvedParams.page as string) || 1; - const limit = 10; - const offset = (page - 1) * limit; + const page = Number.parseInt(resolvedParams.page as string) || 1; + const limit = 10; + const offset = (page - 1) * limit; - // Build params object for getDevices - const apiParams: Record = {}; - for (const [key, value] of Object.entries(resolvedParams)) { - if (value !== undefined && value !== "") { - apiParams[key] = typeof value === "number" ? value : String(value); - } - } - apiParams.limit = limit; - apiParams.offset = offset; + // Build params object for getDevices + const apiParams: Record = {}; + for (const [key, value] of Object.entries(resolvedParams)) { + if (value !== undefined && value !== "") { + apiParams[key] = typeof value === "number" ? value : String(value); + } + } + apiParams.limit = limit; + apiParams.offset = offset; - const [error, devices] = await tryCatch(getDevices(apiParams, true)); - if (error) { - if (error.message === "UNAUTHORIZED") { - redirect("/auth/signin"); - } else { - return ; - } - } - const { meta, data } = devices; - return ( -
- {data?.length === 0 ? ( -
-

No devices.

-
- ) : ( - <> -
- - Table of all devices. - - - Device Name - User - MAC Address - Vendor - # - - - - {data?.map((device) => ( - - -
- - {device.name} - - {device.is_active ? ( -
- Active until{" "} - - {new Date( - device.expiry_date || "", - ).toLocaleDateString("en-US", { - month: "short", - day: "2-digit", - year: "numeric", - })} - -
- ) : ( -

- Device Inactive -

- )} - {device.has_a_pending_payment && ( - - - Payment Pending{" "} - - - - )} + const [error, devices] = await tryCatch(getDevices(apiParams, true)); + if (error) { + if (error.message === "UNAUTHORIZED") { + redirect("/auth/signin"); + } else { + return ; + } + } + const { meta, data } = devices; + return ( +
+ {data?.length === 0 ? ( +
+

No devices.

+
+ ) : ( + <> +
+
+ + + Device Name + User + MAC Address + Vendor + # + + + + {data?.map((device) => ( + + +
+ + {device.name} + + {device.is_active ? ( +
+ Active until{" "} + + {new Date( + device.expiry_date || "", + ).toLocaleDateString("en-US", { + month: "short", + day: "2-digit", + year: "numeric", + })} + +
+ ) : ( +

+ Device Inactive +

+ )} + {device.has_a_pending_payment && ( + + + Payment Pending{" "} + + + + )} - {device.blocked_by === "ADMIN" && device.blocked && ( -
- Comment -

- {device?.reason_for_blocking} -

-
- )} -
-
- -
- {device?.user?.name} - - {device?.user?.id_card} - -
-
- {device.mac} - - {device?.vendor} - - - {!device.has_a_pending_payment && ( - - )} - -
- ))} -
- - - - {meta?.total === 1 ? ( -

Total {meta?.total} device.

- ) : ( -

- Total {meta?.total} devices. -

- )} -
-
-
-
-
+ {device.blocked_by === "ADMIN" && device.blocked && ( +
+ Comment +

+ {device?.reason_for_blocking} +

+
+ )} +
+ + +
+ {device?.user?.name} + + {device?.user?.id_card} + +
+
+ {device.mac} + + {device?.vendor} + + + {!device.has_a_pending_payment && ( + + )} + + + ))} + + + + + {meta?.total === 1 ? ( +

Total {meta?.total} device.

+ ) : ( +

+ Total {meta?.total} devices. +

+ )} +
+
+
+ + - - - )} - - ); + + + )} + + ); } diff --git a/components/admin/admin-topup-table.tsx b/components/admin/admin-topup-table.tsx index 4c1700a..1e98d91 100644 --- a/components/admin/admin-topup-table.tsx +++ b/components/admin/admin-topup-table.tsx @@ -2,14 +2,13 @@ import Link from "next/link"; import { redirect } from "next/navigation"; import { getTopups } from "@/actions/payment"; import { - Table, - TableBody, - TableCaption, - TableCell, - TableFooter, - TableHead, - TableHeader, - TableRow, + Table, + TableBody, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, } from "@/components/ui/table"; import { tryCatch } from "@/utils/tryCatch"; import Pagination from "../pagination"; @@ -17,123 +16,122 @@ import { Badge } from "../ui/badge"; import { Button } from "../ui/button"; export async function AdminTopupsTable({ - searchParams, + searchParams, }: { - searchParams: Promise<{ - [key: string]: unknown; - }>; + searchParams: Promise<{ + [key: string]: unknown; + }>; }) { - const resolvedParams = await searchParams; - const page = Number.parseInt(resolvedParams.page as string) || 1; - const limit = 10; - const offset = (page - 1) * limit; - // Build params object - const apiParams: Record = {}; - for (const [key, value] of Object.entries(resolvedParams)) { - if (value !== undefined && value !== "") { - apiParams[key] = typeof value === "number" ? value : String(value); - } - } - apiParams.limit = limit; - apiParams.offset = offset; - const [error, topups] = await tryCatch(getTopups(apiParams, true)); + const resolvedParams = await searchParams; + const page = Number.parseInt(resolvedParams.page as string) || 1; + const limit = 10; + const offset = (page - 1) * limit; + // Build params object + const apiParams: Record = {}; + for (const [key, value] of Object.entries(resolvedParams)) { + if (value !== undefined && value !== "") { + apiParams[key] = typeof value === "number" ? value : String(value); + } + } + apiParams.limit = limit; + apiParams.offset = offset; + const [error, topups] = await tryCatch(getTopups(apiParams, true)); - if (error) { - if (error.message.includes("Unauthorized")) { - redirect("/auth/signin"); - } else { - return
{JSON.stringify(error, null, 2)}
; - } - } - const { data, meta } = topups; - return ( -
- {data?.length === 0 ? ( -
-

No topups yet.

-
- ) : ( - <> -
- - Table of all topups. - - - User - Status - Amount - Action - - - - {topups?.data?.map((topup) => ( - - -
- {topup?.user?.name} - - {topup?.user?.id_card} - -
-
- - - {topup.paid ? ( - - {topup.status} - - ) : topup.is_expired ? ( - Expired - ) : ( - {topup.status} - )} - - - - - {topup.amount.toFixed(2)} - - MVR - - -
-
- - - -
-
-
-
- ))} -
- - - - {meta?.total === 1 ? ( -

Total {meta?.total} topup.

- ) : ( -

Total {meta?.total} topups.

- )} -
-
-
-
-
- - - )} -
- ); + if (error) { + if (error.message.includes("Unauthorized")) { + redirect("/auth/signin"); + } else { + return
{JSON.stringify(error, null, 2)}
; + } + } + const { data, meta } = topups; + return ( +
+ {data?.length === 0 ? ( +
+

No topups yet.

+
+ ) : ( + <> +
+ + + + User + Status + Amount + Action + + + + {topups?.data?.map((topup) => ( + + +
+ {topup?.user?.name} + + {topup?.user?.id_card} + +
+
+ + + {topup.paid ? ( + + {topup.status} + + ) : topup.is_expired ? ( + Expired + ) : ( + {topup.status} + )} + + + + + {topup.amount.toFixed(2)} + + MVR + + +
+
+ + + +
+
+
+
+ ))} +
+ + + + {meta?.total === 1 ? ( +

Total {meta?.total} topup.

+ ) : ( +

Total {meta?.total} topups.

+ )} +
+
+
+
+
+ + + )} +
+ ); } diff --git a/components/admin/user-payments-table.tsx b/components/admin/user-payments-table.tsx index 59483ff..6734712 100644 --- a/components/admin/user-payments-table.tsx +++ b/components/admin/user-payments-table.tsx @@ -5,170 +5,168 @@ import Pagination from "@/components/pagination"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { - Table, - TableBody, - TableCaption, - TableCell, - TableFooter, - TableHead, - TableHeader, - TableRow, + Table, + TableBody, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, } from "@/components/ui/table"; import { tryCatch } from "@/utils/tryCatch"; import ClientErrorMessage from "../client-error-message"; export async function UsersPaymentsTable({ - searchParams, + searchParams, }: { - searchParams: Promise<{ - [key: string]: unknown; - }>; + searchParams: Promise<{ + [key: string]: unknown; + }>; }) { - const resolvedParams = await searchParams; + const resolvedParams = await searchParams; - const page = Number.parseInt(resolvedParams.page as string) || 1; - const limit = 10; - const offset = (page - 1) * limit; + const page = Number.parseInt(resolvedParams.page as string) || 1; + const limit = 10; + const offset = (page - 1) * limit; - // Build params object for getDevices - const apiParams: Record = {}; - for (const [key, value] of Object.entries(resolvedParams)) { - if (value !== undefined && value !== "") { - apiParams[key] = typeof value === "number" ? value : String(value); - } - } - apiParams.limit = limit; - apiParams.offset = offset; + // Build params object for getDevices + const apiParams: Record = {}; + for (const [key, value] of Object.entries(resolvedParams)) { + if (value !== undefined && value !== "") { + apiParams[key] = typeof value === "number" ? value : String(value); + } + } + apiParams.limit = limit; + apiParams.offset = offset; - const [error, payments] = await tryCatch(getPayments(apiParams, true)); - if (error) { - if (error.message === "UNAUTHORIZED") { - redirect("/auth/signin"); - } else { - return ; - } - } - const { meta, data } = payments; + const [error, payments] = await tryCatch(getPayments(apiParams, true)); + if (error) { + if (error.message === "UNAUTHORIZED") { + redirect("/auth/signin"); + } else { + return ; + } + } + const { meta, data } = payments; - // return
{JSON.stringify(payments, null, 2)}
; - return ( -
- {data.length === 0 ? ( -
-

No user payments yet.

-
- ) : ( - <> - - Table of all users. - - - Devices paid - User - Amount - Duration - Payment Status - Payment Method - MIB Reference - Paid At - Action - - - - {data.map((payment) => ( - - -
    - {payment.devices.map((device) => ( -
  1. - {device.name} -
  2. - ))} -
-
- - {/* {payment.user.id_card} */} -
- {payment?.user?.name} - - {payment?.user?.id_card} - -
{" "} -
- {payment.amount} MVR - {payment.number_of_months} Months + // return
{JSON.stringify(payments, null, 2)}
; + return ( +
+ {data.length === 0 ? ( +
+

No user payments yet.

+
+ ) : ( + <> +
+ + + Devices paid + User + Amount + Duration + Payment Status + Payment Method + MIB Reference + Paid At + Action + + + + {data.map((payment) => ( + + +
    + {payment.devices.map((device) => ( +
  1. + {device.name} +
  2. + ))} +
+
+ + {/* {payment.user.id_card} */} +
+ {payment?.user?.name} + + {payment?.user?.id_card} + +
{" "} +
+ {payment.amount} MVR + {payment.number_of_months} Months - - {payment.status === "PENDING" ? ( - - {payment.status} - - ) : payment.status === "PAID" ? ( - - {payment.status} - - ) : ( - - {payment.status} - - )} - - {payment.method} - {payment.mib_reference} - - {new Date(payment.paid_at ?? "").toLocaleDateString( - "en-US", - { - month: "short", - day: "2-digit", - year: "numeric", - minute: "2-digit", - hour: "2-digit", - }, - )} - + + {payment.status === "PENDING" ? ( + + {payment.status} + + ) : payment.status === "PAID" ? ( + + {payment.status} + + ) : ( + + {payment.status} + + )} + + {payment.method} + {payment.mib_reference} + + {new Date(payment.paid_at ?? "").toLocaleDateString( + "en-US", + { + month: "short", + day: "2-digit", + year: "numeric", + minute: "2-digit", + hour: "2-digit", + }, + )} + - - - - - -
- ))} -
- - - - {meta?.total === 1 ? ( -

Total {meta?.total} payment.

- ) : ( -

Total {meta?.total} payments.

- )}{" "} -
-
-
-
- - - )} -
- ); + + + + + + + ))} + + + + + {meta?.total === 1 ? ( +

Total {meta?.total} payment.

+ ) : ( +

Total {meta?.total} payments.

+ )}{" "} +
+
+
+ + + + )} + + ); } diff --git a/components/devices-table.tsx b/components/devices-table.tsx index dd713ca..1ce45f1 100644 --- a/components/devices-table.tsx +++ b/components/devices-table.tsx @@ -2,14 +2,13 @@ import { redirect } from "next/navigation"; import { getServerSession } from "next-auth"; import { authOptions } from "@/app/auth"; import { - Table, - TableBody, - TableCaption, - TableCell, - TableFooter, - TableHead, - TableHeader, - TableRow, + Table, + TableBody, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, } from "@/components/ui/table"; import { getDevices } from "@/queries/devices"; import { tryCatch } from "@/utils/tryCatch"; @@ -19,107 +18,106 @@ import DeviceCard from "./device-card"; import Pagination from "./pagination"; export async function DevicesTable({ - searchParams, - parentalControl, - additionalFilters = {}, + searchParams, + parentalControl, + additionalFilters = {}, }: { - searchParams: Promise<{ - [key: string]: unknown; - }>; - parentalControl?: boolean; - additionalFilters?: Record; + searchParams: Promise<{ + [key: string]: unknown; + }>; + parentalControl?: boolean; + additionalFilters?: Record; }) { - const resolvedParams = await searchParams; - const session = await getServerSession(authOptions); - const isAdmin = session?.user?.is_admin; + const resolvedParams = await searchParams; + const session = await getServerSession(authOptions); + const isAdmin = session?.user?.is_admin; - const page = Number.parseInt(resolvedParams.page as string) || 1; - const limit = 10; - const offset = (page - 1) * limit; + const page = Number.parseInt(resolvedParams.page as string) || 1; + const limit = 10; + const offset = (page - 1) * limit; - // Build params object for getDevices - const apiParams: Record = {}; - for (const [key, value] of Object.entries(resolvedParams)) { - if (value !== undefined && value !== "") { - apiParams[key] = typeof value === "number" ? value : String(value); - } - } + // Build params object for getDevices + const apiParams: Record = {}; + for (const [key, value] of Object.entries(resolvedParams)) { + if (value !== undefined && value !== "") { + apiParams[key] = typeof value === "number" ? value : String(value); + } + } - for (const [key, value] of Object.entries(additionalFilters)) { - if (value !== undefined && value !== "") { - apiParams[key] = typeof value === "number" ? value : String(value); - } - } - apiParams.limit = limit; - apiParams.offset = offset; - const [error, devices] = await tryCatch(getDevices(apiParams)); - if (error) { - if (error.message === "UNAUTHORIZED") { - redirect("/auth/signin"); - } else { - return ; - } - } - const { meta, data } = devices; - return ( -
- {data?.length === 0 ? ( -
-

{parentalControl ? "No active devices" : "No devices."}

-
- ) : ( - <> -
- - Table of all devices. - - - Device Name - MAC Address - Vendor - # - - - - {data?.map((device) => ( - - ))} - - - - - {meta?.total === 1 ? ( -

Total {meta?.total} device.

- ) : ( -

- Total {meta?.total} devices. -

- )} -
-
-
-
-
-
- {data?.map((device) => ( - - ))} -
- - - )} -
- ); + for (const [key, value] of Object.entries(additionalFilters)) { + if (value !== undefined && value !== "") { + apiParams[key] = typeof value === "number" ? value : String(value); + } + } + apiParams.limit = limit; + apiParams.offset = offset; + const [error, devices] = await tryCatch(getDevices(apiParams)); + if (error) { + if (error.message === "UNAUTHORIZED") { + redirect("/auth/signin"); + } else { + return ; + } + } + const { meta, data } = devices; + return ( +
+ {data?.length === 0 ? ( +
+

{parentalControl ? "No active devices" : "No devices."}

+
+ ) : ( + <> +
+ + + + Device Name + MAC Address + Vendor + # + + + + {data?.map((device) => ( + + ))} + + + + + {meta?.total === 1 ? ( +

Total {meta?.total} device.

+ ) : ( +

+ Total {meta?.total} devices. +

+ )} +
+
+
+
+
+
+ {data?.map((device) => ( + + ))} +
+ + + )} +
+ ); } diff --git a/components/payments-table.tsx b/components/payments-table.tsx index 97ffb21..179ce62 100644 --- a/components/payments-table.tsx +++ b/components/payments-table.tsx @@ -3,14 +3,13 @@ import Link from "next/link"; import { redirect } from "next/navigation"; import { getPayments } from "@/actions/payment"; import { - Table, - TableBody, - TableCaption, - TableCell, - TableFooter, - TableHead, - TableHeader, - TableRow, + Table, + TableBody, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, } from "@/components/ui/table"; import type { Payment } from "@/lib/backend-types"; import { cn } from "@/lib/utils"; @@ -21,266 +20,265 @@ import { Button } from "./ui/button"; import { Separator } from "./ui/separator"; export async function PaymentsTable({ - searchParams, + searchParams, }: { - searchParams: Promise<{ - [key: string]: unknown; - }>; + searchParams: Promise<{ + [key: string]: unknown; + }>; }) { - const resolvedParams = await searchParams; - const page = Number.parseInt(resolvedParams.page as string) || 1; - const limit = 10; - const offset = (page - 1) * limit; - const apiParams: Record = {}; - for (const [key, value] of Object.entries(resolvedParams)) { - if (value !== undefined && value !== "") { - apiParams[key] = typeof value === "number" ? value : String(value); - } - } - apiParams.limit = limit; - apiParams.offset = offset; - const [error, payments] = await tryCatch(getPayments(apiParams)); + const resolvedParams = await searchParams; + const page = Number.parseInt(resolvedParams.page as string) || 1; + const limit = 10; + const offset = (page - 1) * limit; + const apiParams: Record = {}; + for (const [key, value] of Object.entries(resolvedParams)) { + if (value !== undefined && value !== "") { + apiParams[key] = typeof value === "number" ? value : String(value); + } + } + apiParams.limit = limit; + apiParams.offset = offset; + const [error, payments] = await tryCatch(getPayments(apiParams)); - if (error) { - if (error.message.includes("Unauthorized")) { - redirect("/auth/signin"); - } else { - return
{JSON.stringify(error, null, 2)}
; - } - } - const { data, meta } = payments; - return ( -
- {data?.length === 0 ? ( -
-

No Payments.

-
- ) : ( - <> -
- - Table of all devices. - - - Details - Duration - Status - Amount - - - - {payments?.data?.map((payment) => ( - - -
-
- - - {new Date(payment.created_at).toLocaleDateString( - "en-US", - { - month: "short", - day: "2-digit", - year: "numeric", - minute: "2-digit", - hour: "2-digit", - timeZone: "Indian/Maldives", // Force consistent timezone - }, - )} - -
+ if (error) { + if (error.message.includes("Unauthorized")) { + redirect("/auth/signin"); + } else { + return
{JSON.stringify(error, null, 2)}
; + } + } + const { data, meta } = payments; + return ( +
+ {data?.length === 0 ? ( +
+

No Payments.

+
+ ) : ( + <> +
+
+ + + Details + Duration + Status + Amount + + + + {payments?.data?.map((payment) => ( + + +
+
+ + + {new Date(payment.created_at).toLocaleDateString( + "en-US", + { + month: "short", + day: "2-digit", + year: "numeric", + minute: "2-digit", + hour: "2-digit", + timeZone: "Indian/Maldives", // Force consistent timezone + }, + )} + +
-
- - - -
-
-

Devices

-
    - {payment.devices.map((device) => ( -
  1. - {device.name} -
  2. - ))} -
-
-
-
+
+ + + +
+
+

Devices

+
    + {payment.devices.map((device) => ( +
  1. + {device.name} +
  2. + ))} +
+
+ + - - {payment.number_of_months} Months - - - - {payment.paid ? ( - - {payment.status} - - ) : payment.is_expired ? ( - Expired - ) : ( - {payment.status} - )} - - - - - {payment.amount.toFixed(2)} - - MVR - -
- ))} -
- - - - {meta?.total === 1 ? ( -

- Total {meta?.total} payment. -

- ) : ( -

- Total {meta?.total} payments. -

- )}{" "} -
-
-
-
- -
-
- {data.map((payment) => ( - - ))} -
- - )} -
- ); + + {payment.number_of_months} Months + + + + {payment.paid ? ( + + {payment.status} + + ) : payment.is_expired ? ( + Expired + ) : ( + {payment.status} + )} + + + + + {payment.amount.toFixed(2)} + + MVR + + + ))} + + + + + {meta?.total === 1 ? ( +

+ Total {meta?.total} payment. +

+ ) : ( +

+ Total {meta?.total} payments. +

+ )}{" "} +
+
+
+ + + +
+ {data.map((payment) => ( + + ))} +
+ + )} + + ); } export function MobilePaymentDetails({ - payment, - isAdmin = false, + payment, + isAdmin = false, }: { - payment: Payment; - isAdmin?: boolean; + payment: Payment; + isAdmin?: boolean; }) { - return ( -
-
- - - {new Date(payment.created_at).toLocaleDateString("en-US", { - month: "short", - day: "2-digit", - year: "numeric", - minute: "2-digit", - hour: "2-digit", - timeZone: "Indian/Maldives", // Force consistent timezone - })} - -
+ return ( +
+
+ + + {new Date(payment.created_at).toLocaleDateString("en-US", { + month: "short", + day: "2-digit", + year: "numeric", + minute: "2-digit", + hour: "2-digit", + timeZone: "Indian/Maldives", // Force consistent timezone + })} + +
-
- - - -
-
-

Devices

-
    - {payment.devices.map((device) => ( -
  1. - {device.name} -
  2. - ))} -
-
- -

Duration

- - {payment.number_of_months} Months - - -

Amount

-
- - {payment.amount.toFixed(2)} MVR - - - {payment.paid ? ( - - {payment.status} - - ) : payment.is_expired ? ( - Expired - ) : ( - {payment.status} - )} - - {isAdmin && ( -
- {payment?.user?.name} - - {payment?.user?.id_card} - -
- )} -
-
-
-
- ); +
+ + + +
+
+

Devices

+
    + {payment.devices.map((device) => ( +
  1. + {device.name} +
  2. + ))} +
+
+ +

Duration

+ + {payment.number_of_months} Months + + +

Amount

+
+ + {payment.amount.toFixed(2)} MVR + + + {payment.paid ? ( + + {payment.status} + + ) : payment.is_expired ? ( + Expired + ) : ( + {payment.status} + )} + + {isAdmin && ( +
+ {payment?.user?.name} + + {payment?.user?.id_card} + +
+ )} +
+
+
+
+ ); } diff --git a/components/topups-table.tsx b/components/topups-table.tsx index 2fe07a7..96dd834 100644 --- a/components/topups-table.tsx +++ b/components/topups-table.tsx @@ -3,14 +3,13 @@ import Link from "next/link"; import { redirect } from "next/navigation"; import { getTopups } from "@/actions/payment"; import { - Table, - TableBody, - TableCaption, - TableCell, - TableFooter, - TableHead, - TableHeader, - TableRow, + Table, + TableBody, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, } from "@/components/ui/table"; import type { Topup } from "@/lib/backend-types"; import { cn } from "@/lib/utils"; @@ -20,200 +19,199 @@ import { Badge } from "./ui/badge"; import { Button } from "./ui/button"; export async function TopupsTable({ - searchParams, + searchParams, }: { - searchParams: Promise<{ - [key: string]: unknown; - }>; + searchParams: Promise<{ + [key: string]: unknown; + }>; }) { - const resolvedParams = await searchParams; - const page = Number.parseInt(resolvedParams.page as string) || 1; - const limit = 10; - const offset = (page - 1) * limit; - // Build params object - const apiParams: Record = {}; - for (const [key, value] of Object.entries(resolvedParams)) { - if (value !== undefined && value !== "") { - apiParams[key] = typeof value === "number" ? value : String(value); - } - } - apiParams.limit = limit; - apiParams.offset = offset; - const [error, topups] = await tryCatch(getTopups(apiParams)); + const resolvedParams = await searchParams; + const page = Number.parseInt(resolvedParams.page as string) || 1; + const limit = 10; + const offset = (page - 1) * limit; + // Build params object + const apiParams: Record = {}; + for (const [key, value] of Object.entries(resolvedParams)) { + if (value !== undefined && value !== "") { + apiParams[key] = typeof value === "number" ? value : String(value); + } + } + apiParams.limit = limit; + apiParams.offset = offset; + const [error, topups] = await tryCatch(getTopups(apiParams)); - if (error) { - if (error.message.includes("Unauthorized")) { - redirect("/auth/signin"); - } else { - return
{JSON.stringify(error, null, 2)}
; - } - } - const { data, meta } = topups; - return ( -
- {data?.length === 0 ? ( -
-

No topups.

-
- ) : ( - <> -
- - Table of all topups. - - - Details - Status - Amount - - - - {topups?.data?.map((topup) => ( - - -
-
- - - {new Date(topup.created_at).toLocaleDateString( - "en-US", - { - month: "short", - day: "2-digit", - year: "numeric", - minute: "2-digit", - hour: "2-digit", - }, - )} - -
+ if (error) { + if (error.message.includes("Unauthorized")) { + redirect("/auth/signin"); + } else { + return
{JSON.stringify(error, null, 2)}
; + } + } + const { data, meta } = topups; + return ( +
+ {data?.length === 0 ? ( +
+

No topups.

+
+ ) : ( + <> +
+
+ + + Details + Status + Amount + + + + {topups?.data?.map((topup) => ( + + +
+
+ + + {new Date(topup.created_at).toLocaleDateString( + "en-US", + { + month: "short", + day: "2-digit", + year: "numeric", + minute: "2-digit", + hour: "2-digit", + }, + )} + +
-
- - - -
-
-
+
+ + + +
+ + - - - {topup.paid ? ( - - {topup.status} - - ) : topup.is_expired ? ( - Expired - ) : ( - {topup.status} - )} - - - - - {topup.amount.toFixed(2)} - - MVR - -
- ))} -
- - - - {meta?.total === 1 ? ( -

Total {meta?.total} topup.

- ) : ( -

Total {meta?.total} topups.

- )} -
-
-
-
-
-
- {data.map((topup) => ( - - ))} -
- - - )} -
- ); + + + {topup.paid ? ( + + {topup.status} + + ) : topup.is_expired ? ( + Expired + ) : ( + {topup.status} + )} + + + + + {topup.amount.toFixed(2)} + + MVR + + + ))} + + + + + {meta?.total === 1 ? ( +

Total {meta?.total} topup.

+ ) : ( +

Total {meta?.total} topups.

+ )} +
+
+
+ + +
+ {data.map((topup) => ( + + ))} +
+ + + )} + + ); } function MobileTopupDetails({ topup }: { topup: Topup }) { - return ( -
-
- - - {new Date(topup.created_at).toLocaleDateString("en-US", { - month: "short", - day: "2-digit", - year: "numeric", - })} - -
+ return ( +
+
+ + + {new Date(topup.created_at).toLocaleDateString("en-US", { + month: "short", + day: "2-digit", + year: "numeric", + })} + +
-
- - - -
+
+ + + +
-
-
-

Amount

- - {topup.amount.toFixed(2)} MVR - -
- - {topup.paid ? ( - - {topup.status} - - ) : topup.is_expired ? ( - Expired - ) : ( - {topup.status} - )} - -
-
- ); +
+
+

Amount

+ + {topup.amount.toFixed(2)} MVR + +
+ + {topup.paid ? ( + + {topup.status} + + ) : topup.is_expired ? ( + Expired + ) : ( + {topup.status} + )} + +
+
+ ); } diff --git a/components/user-table.tsx b/components/user-table.tsx index a70e872..a46af6d 100644 --- a/components/user-table.tsx +++ b/components/user-table.tsx @@ -1,18 +1,3 @@ -// import { -// Table, -// TableBody, -// TableCaption, -// TableCell, -// TableFooter, -// TableHead, -// TableHeader, -// TableRow, -// } from "@/components/ui/table"; -// import Link from "next/link"; -// import Pagination from "./pagination"; -// import { Badge } from "./ui/badge"; -// import { Button } from "./ui/button"; - import Link from "next/link"; import { redirect } from "next/navigation"; import { getUsers } from "@/queries/users"; @@ -22,136 +7,134 @@ import Pagination from "./pagination"; import { Badge } from "./ui/badge"; import { Button } from "./ui/button"; import { - Table, - TableBody, - TableCaption, - TableCell, - TableFooter, - TableHead, - TableHeader, - TableRow, + Table, + TableBody, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, } from "./ui/table"; export async function UsersTable({ - searchParams, + searchParams, }: { - searchParams: Promise<{ - [key: string]: unknown; - }>; + searchParams: Promise<{ + [key: string]: unknown; + }>; }) { - const resolvedParams = await searchParams; + const resolvedParams = await searchParams; - const page = Number.parseInt(resolvedParams.page as string) || 1; - const limit = 10; - const offset = (page - 1) * limit; - const apiParams: Record = {}; - for (const [key, value] of Object.entries(resolvedParams)) { - if (value !== undefined && value !== "") { - apiParams[key] = typeof value === "number" ? value : String(value); - } - } + const page = Number.parseInt(resolvedParams.page as string) || 1; + const limit = 10; + const offset = (page - 1) * limit; + const apiParams: Record = {}; + for (const [key, value] of Object.entries(resolvedParams)) { + if (value !== undefined && value !== "") { + apiParams[key] = typeof value === "number" ? value : String(value); + } + } - apiParams.limit = limit; - apiParams.offset = offset; - const [error, users] = await tryCatch(getUsers(apiParams)); - if (error) { - if (error.message === "UNAUTHORIZED") { - redirect("/auth/signin"); - } - return ; - } - const { meta, data } = users; + apiParams.limit = limit; + apiParams.offset = offset; + const [error, users] = await tryCatch(getUsers(apiParams)); + if (error) { + if (error.message === "UNAUTHORIZED") { + redirect("/auth/signin"); + } + return ; + } + const { meta, data } = users; - // return null; - return ( -
- {users?.data.length === 0 ? ( -
-

No Users yet.

-
- ) : ( - <> - - Table of all users. - - - Name - ID Card - Atoll - Island - House Name - Status - Dob - Phone Number - Action - - - - {data.map((user) => ( - - - {user.first_name} {user.last_name} - - {user.id_card} - {user.atoll?.name} - {user.island?.name} - {user.address} + // return null; + return ( +
+ {users?.data.length === 0 ? ( +
+

No Users yet.

+
+ ) : ( + <> +
+ + + Name + ID Card + Atoll + Island + House Name + Status + Dob + Phone Number + Action + + + + {data.map((user) => ( + + + {user.first_name} {user.last_name} + + {user.id_card} + {user.atoll?.name} + {user.island?.name} + {user.address} - - {user.verified ? ( - - Verified - - ) : ( - - Unverified - - )} - - - {new Date(user.dob ?? "").toLocaleDateString("en-US", { - month: "short", - day: "2-digit", - year: "numeric", - })} - + + {user.verified ? ( + + Verified + + ) : ( + + Unverified + + )} + + + {new Date(user.dob ?? "").toLocaleDateString("en-US", { + month: "short", + day: "2-digit", + year: "numeric", + })} + - {user.mobile} - - - - - - - ))} - - - - - {meta?.total === 1 ? ( -

Total {meta?.total} user.

- ) : ( -

Total {meta?.total} users.

- )} -
-
-
-
- - - )} -
- ); + {user.mobile} + + + + + + + ))} + + + + + {meta?.total === 1 ? ( +

Total {meta?.total} user.

+ ) : ( +

Total {meta?.total} users.

+ )} +
+
+
+ + + + )} + + ); } diff --git a/components/wallet-transactions-table.tsx b/components/wallet-transactions-table.tsx index 4620661..91b676c 100644 --- a/components/wallet-transactions-table.tsx +++ b/components/wallet-transactions-table.tsx @@ -2,14 +2,13 @@ import { Calendar } from "lucide-react"; import Link from "next/link"; import { redirect } from "next/navigation"; import { - Table, - TableBody, - TableCaption, - TableCell, - TableFooter, - TableHead, - TableHeader, - TableRow, + Table, + TableBody, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, } from "@/components/ui/table"; import type { WalletTransaction } from "@/lib/backend-types"; import { cn } from "@/lib/utils"; @@ -20,224 +19,223 @@ import { Badge } from "./ui/badge"; import { Button } from "./ui/button"; export async function WalletTransactionsTable({ - searchParams, + searchParams, }: { - searchParams: Promise<{ - [key: string]: unknown; - }>; + searchParams: Promise<{ + [key: string]: unknown; + }>; }) { - const resolvedParams = await searchParams; - const page = Number.parseInt(resolvedParams.page as string) || 1; - const limit = 10; - const offset = (page - 1) * limit; - // Build params object - const apiParams: Record = {}; - for (const [key, value] of Object.entries(resolvedParams)) { - if (value !== undefined && value !== "") { - apiParams[key] = typeof value === "number" ? value : String(value); - } - } - apiParams.limit = limit; - apiParams.offset = offset; - const [error, transactions] = await tryCatch( - getWaleltTransactions(apiParams), - ); + const resolvedParams = await searchParams; + const page = Number.parseInt(resolvedParams.page as string) || 1; + const limit = 10; + const offset = (page - 1) * limit; + // Build params object + const apiParams: Record = {}; + for (const [key, value] of Object.entries(resolvedParams)) { + if (value !== undefined && value !== "") { + apiParams[key] = typeof value === "number" ? value : String(value); + } + } + apiParams.limit = limit; + apiParams.offset = offset; + const [error, transactions] = await tryCatch( + getWaleltTransactions(apiParams), + ); - if (error) { - if (error.message.includes("Unauthorized")) { - redirect("/auth/signin"); - } else { - return
{JSON.stringify(error, null, 2)}
; - } - } - const { data, meta } = transactions; - const totalDebit = data.reduce( - (acc, trx) => acc + (trx.transaction_type === "DEBIT" ? trx.amount : 0), - 0, - ); - const totalCredit = data.reduce( - (acc, trx) => acc + (trx.transaction_type === "TOPUP" ? trx.amount : 0), - 0, - ); - return ( -
- {data?.length === 0 ? ( -
-

No transactions yet.

-
- ) : ( -
-
-
-
Total Debit
-

{totalDebit.toFixed(2)} MVR

-
-
-
Total Credit
-

{totalCredit.toFixed(2)} MVR

-
-
-
- - Table of all transactions. - - - Description - Amount - Transaction Type - View Details - Created at - - - - {transactions?.data?.map((trx) => ( - - - - {trx.description} - - - {trx.amount.toFixed(2)} MVR + if (error) { + if (error.message.includes("Unauthorized")) { + redirect("/auth/signin"); + } else { + return
{JSON.stringify(error, null, 2)}
; + } + } + const { data, meta } = transactions; + const totalDebit = data.reduce( + (acc, trx) => acc + (trx.transaction_type === "DEBIT" ? trx.amount : 0), + 0, + ); + const totalCredit = data.reduce( + (acc, trx) => acc + (trx.transaction_type === "TOPUP" ? trx.amount : 0), + 0, + ); + return ( +
+ {data?.length === 0 ? ( +
+

No transactions yet.

+
+ ) : ( +
+
+
+
Total Debit
+

{totalDebit.toFixed(2)} MVR

+
+
+
Total Credit
+

{totalCredit.toFixed(2)} MVR

+
+
+
+
+ + + Description + Amount + Transaction Type + View Details + Created at + + + + {transactions?.data?.map((trx) => ( + + + + {trx.description} + + + {trx.amount.toFixed(2)} MVR - - - {trx.transaction_type === "TOPUP" ? ( - - {trx.transaction_type} - - ) : ( - - {trx.transaction_type} - - )} - - + + + {trx.transaction_type === "TOPUP" ? ( + + {trx.transaction_type} + + ) : ( + + {trx.transaction_type} + + )} + + - - - {new Date(trx.created_at).toLocaleDateString("en-US", { - month: "short", - day: "2-digit", - year: "numeric", - minute: "2-digit", - hour: "2-digit", - })} - - - - - - - ))} - - - - - {meta?.total === 1 ? ( -

- Total {meta?.total} transaction. -

- ) : ( -

- Total {meta?.total} transactions. -

- )} -
-
-
-
-
-
- {data.map((trx) => ( - - ))} -
- -
- )} -
- ); + + + {new Date(trx.created_at).toLocaleDateString("en-US", { + month: "short", + day: "2-digit", + year: "numeric", + minute: "2-digit", + hour: "2-digit", + })} + + + + + + + ))} + + + + + {meta?.total === 1 ? ( +

+ Total {meta?.total} transaction. +

+ ) : ( +

+ Total {meta?.total} transactions. +

+ )} +
+
+
+ + +
+ {data.map((trx) => ( + + ))} +
+ + + )} + + ); } function MobileTransactionDetails({ trx }: { trx: WalletTransaction }) { - return ( -
-
-
- - - {new Date(trx.created_at).toLocaleDateString("en-US", { - month: "short", - day: "2-digit", - year: "numeric", - minute: "2-digit", - hour: "2-digit", - })} - -
-

{trx.description}

-
+ return ( +
+
+
+ + + {new Date(trx.created_at).toLocaleDateString("en-US", { + month: "short", + day: "2-digit", + year: "numeric", + minute: "2-digit", + hour: "2-digit", + })} + +
+

{trx.description}

+
-
-
-

Amount

- - {trx.amount.toFixed(2)} MVR - -
- - {trx.transaction_type === "TOPUP" ? ( - - {trx.transaction_type} - - ) : ( - - {trx.transaction_type} - - )} - -
-
- - - -
-
- ); +
+
+

Amount

+ + {trx.amount.toFixed(2)} MVR + +
+ + {trx.transaction_type === "TOPUP" ? ( + + {trx.transaction_type} + + ) : ( + + {trx.transaction_type} + + )} + +
+
+ + + +
+
+ ); }