mirror of
https://github.com/i701/sarlink-portal.git
synced 2025-07-06 17:41:40 +00:00
feat: enhance payment retrieval with flexible query parameters and add dynamic filters to payments page ✨
Some checks failed
Build and Push Docker Images / Build and Push Docker Images (push) Failing after 2m18s
Some checks failed
Build and Push Docker Images / Build and Push Docker Images (push) Failing after 2m18s
This commit is contained in:
@ -90,10 +90,19 @@ export async function getPayment({ id }: { id: string }) {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getPayments() {
|
type GetPaymentProps = {
|
||||||
|
[key: string]: string | number | undefined; // Allow additional properties for flexibility
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function getPayments(params: GetPaymentProps) {
|
||||||
|
// Build query string from all defined params
|
||||||
|
const query = Object.entries(params)
|
||||||
|
.filter(([_, value]) => value !== undefined && value !== "")
|
||||||
|
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)
|
||||||
|
.join("&");
|
||||||
const session = await getServerSession(authOptions);
|
const session = await getServerSession(authOptions);
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`${process.env.SARLINK_API_BASE_URL}/api/billing/payment/`,
|
`${process.env.SARLINK_API_BASE_URL}/api/billing/payment/?${query}`,
|
||||||
{
|
{
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { Suspense } from "react";
|
import { Suspense } from "react";
|
||||||
|
import DynamicFilter from "@/components/generic-filter";
|
||||||
import { PaymentsTable } from "@/components/payments-table";
|
import { PaymentsTable } from "@/components/payments-table";
|
||||||
import Search from "@/components/search";
|
import Search from "@/components/search";
|
||||||
|
|
||||||
@ -8,8 +9,6 @@ export default async function Payments({
|
|||||||
searchParams: Promise<{
|
searchParams: Promise<{
|
||||||
query: string;
|
query: string;
|
||||||
page: number;
|
page: number;
|
||||||
sortBy: string;
|
|
||||||
status: string;
|
|
||||||
}>;
|
}>;
|
||||||
}) {
|
}) {
|
||||||
const query = (await searchParams)?.query || "";
|
const query = (await searchParams)?.query || "";
|
||||||
@ -23,7 +22,37 @@ export default async function Payments({
|
|||||||
id="user-filters"
|
id="user-filters"
|
||||||
className=" pb-4 gap-4 flex sm:flex-row flex-col items-start justify-start"
|
className=" pb-4 gap-4 flex sm:flex-row flex-col items-start justify-start"
|
||||||
>
|
>
|
||||||
<Search />
|
<DynamicFilter
|
||||||
|
inputs={[
|
||||||
|
{
|
||||||
|
label: "Payment",
|
||||||
|
name: "paid",
|
||||||
|
type: "radio-group",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: "All",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Paid",
|
||||||
|
value: "true",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Unpaid",
|
||||||
|
value: "false",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Number of months",
|
||||||
|
name: "number_of_months",
|
||||||
|
type: "dual-range-slider",
|
||||||
|
min: 1,
|
||||||
|
max: 12,
|
||||||
|
step: 1,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>{" "}
|
||||||
</div>
|
</div>
|
||||||
<Suspense key={query} fallback={"loading...."}>
|
<Suspense key={query} fallback={"loading...."}>
|
||||||
<PaymentsTable searchParams={searchParams} />
|
<PaymentsTable searchParams={searchParams} />
|
||||||
|
@ -22,7 +22,6 @@ export async function DevicesTable({
|
|||||||
searchParams,
|
searchParams,
|
||||||
parentalControl,
|
parentalControl,
|
||||||
additionalFilters = {},
|
additionalFilters = {},
|
||||||
|
|
||||||
}: {
|
}: {
|
||||||
searchParams: Promise<{
|
searchParams: Promise<{
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
|
@ -24,13 +24,17 @@ export async function PaymentsTable({
|
|||||||
searchParams,
|
searchParams,
|
||||||
}: {
|
}: {
|
||||||
searchParams: Promise<{
|
searchParams: Promise<{
|
||||||
query: string;
|
[key: string]: unknown;
|
||||||
page: number;
|
|
||||||
sortBy: string;
|
|
||||||
}>;
|
}>;
|
||||||
}) {
|
}) {
|
||||||
const query = (await searchParams)?.query || "";
|
const resolvedParams = await searchParams;
|
||||||
const [error, payments] = await tryCatch(getPayments());
|
const apiParams: Record<string, string | number | undefined> = {};
|
||||||
|
for (const [key, value] of Object.entries(resolvedParams)) {
|
||||||
|
if (value !== undefined && value !== "") {
|
||||||
|
apiParams[key] = typeof value === "number" ? value : String(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const [error, payments] = await tryCatch(getPayments(apiParams));
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
if (error.message.includes("Unauthorized")) {
|
if (error.message.includes("Unauthorized")) {
|
||||||
@ -134,18 +138,17 @@ export async function PaymentsTable({
|
|||||||
</TableBody>
|
</TableBody>
|
||||||
<TableFooter>
|
<TableFooter>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell colSpan={2}>
|
|
||||||
{query.length > 0 && (
|
<TableCell colSpan={3} className="text-muted-foreground">
|
||||||
<p className="text-sm text-muted-foreground">
|
{meta?.total === 1 ? (
|
||||||
Showing {payments?.data?.length} payments for "
|
<p className="text-center">
|
||||||
{query}
|
Total {meta?.total} payment.
|
||||||
"
|
|
||||||
</p>
|
</p>
|
||||||
)}
|
) : (
|
||||||
</TableCell>
|
<p className="text-center">
|
||||||
<TableCell className="text-muted-foreground">
|
Total {meta?.total} payments.
|
||||||
{meta.total} payments
|
</p>
|
||||||
</TableCell>
|
)} </TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableFooter>
|
</TableFooter>
|
||||||
</Table>
|
</Table>
|
||||||
|
Reference in New Issue
Block a user