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) => (
- -
- {device.name}
-
- ))}
-
-
-
- {/* {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) => (
+ -
+ {device.name}
+
+ ))}
+
+
+
+ {/* {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) => (
- -
- {device.name}
-
- ))}
-
-
-
-
+
+
+
+
+
+
+
Devices
+
+ {payment.devices.map((device) => (
+ -
+ {device.name}
+
+ ))}
+
+
+
+
-
- {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) => (
- -
- {device.name}
-
- ))}
-
-
-
-
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) => (
+ -
+ {device.name}
+
+ ))}
+
+
+
+
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}
+
+ )}
+
+
+
+
+
+
+
+
+ );
}