2026-01-07 15:41:36 +01:00

134 lines
3.4 KiB
TypeScript

"use server";
import { cookies } from "next/headers";
import {
AUTH_COOKIE_NAME,
BE_BASE_URL,
REVALIDATE_SECONDS,
HEALTH_CACHE_TAG,
} from "./constants";
import {
type IDashboardData,
type IFetchHealthDataParams,
type IHealthData,
type IReviewTransactionsData,
type ITransactionsOverviewData,
} from "./types";
/**
* Fetch both health and overview data concurrently
* This is optimized for initial page load
* Always includes overview data with the provided date range
*/
export async function fetchDashboardDataService({
dateStart,
dateEnd,
}: IFetchHealthDataParams): Promise<IDashboardData> {
const cookieStore = await cookies();
const token = cookieStore.get(AUTH_COOKIE_NAME)?.value;
if (!token) {
throw new Error("Missing auth token");
}
const queryParts: string[] = [];
// Add date filter if provided
if (dateStart && dateEnd) {
queryParts.push(
`Modified=BETWEEN/${encodeURIComponent(dateStart)}/${encodeURIComponent(dateEnd)}`
);
} else if (dateStart) {
queryParts.push(`Modified=>/${encodeURIComponent(dateStart)}`);
} else if (dateEnd) {
queryParts.push(`Modified=</${encodeURIComponent(dateEnd)}`);
}
const queryString = queryParts.join("&");
const fetchConfig = {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
next: {
revalidate: REVALIDATE_SECONDS,
tags: [HEALTH_CACHE_TAG],
},
};
// Fetch all three endpoints concurrently
const [healthResponse, overviewResponse, reviewResponse] = await Promise.all([
fetch(
`${BE_BASE_URL}/api/v1/transactions/health${
queryString ? `?${queryString}` : ""
}`,
fetchConfig
),
fetch(
`${BE_BASE_URL}/api/v1/transactions/overview${
queryString ? `?${queryString}` : ""
}`,
fetchConfig
),
fetch(
`${BE_BASE_URL}/api/v1/transactions?limit=1000&page=1${
queryString ? `&${queryString}` : ""
}&Status==/review`,
fetchConfig
),
]);
// Handle health data response
if (!healthResponse.ok) {
const errorData = await healthResponse
.json()
.catch(() => ({ message: "Failed to fetch health data" }));
throw new Error(errorData?.message || "Failed to fetch health data");
}
const healthData = (await healthResponse.json()) as IHealthData;
// Handle overview data response
let overviewData: ITransactionsOverviewData = {
success: false,
successful_count: 0,
waiting_count: 0,
failed_count: 0,
cancelled_count: 0,
};
if (!overviewResponse.ok) {
// Don't fail the whole request if overview fails, just log it
console.error("Failed to fetch transactions overview");
} else {
overviewData = (await overviewResponse.json()) as ITransactionsOverviewData;
}
// Handle review transactions response
let reviewTransactions: IReviewTransactionsData = {
success: false,
transactions: [],
total: 0,
};
if (!reviewResponse.ok) {
// Don't fail the whole request if review transactions fail, just log it
console.error("Failed to fetch review transactions");
} else {
const reviewData = (await reviewResponse.json()) as IReviewTransactionsData;
reviewTransactions = {
success: reviewData.success ?? true,
transactions: reviewData.transactions || [],
total: reviewData.total || 0,
};
}
return {
healthData,
overviewData,
reviewTransactions,
};
}