prod-wag-backend-automate-s.../WebServices/client-frontend/src/components/Pages/people/superusers/hooks.ts

137 lines
3.6 KiB
TypeScript

import { useState, useEffect, useCallback } from "react";
import { PeopleFormData, PeopleSchema, fetchData } from "./schema";
import {
PagePagination,
RequestParams,
ResponseMetadata,
} from "@/components/validations/list/paginations";
// Custom hook for pagination and data fetching
export function usePaginatedData() {
const [data, setData] = useState<PeopleFormData[]>([]);
// Request parameters - these are controlled by the user
const [requestParams, setRequestParams] = useState<RequestParams>({
page: 1,
size: 10,
orderFields: ["createdAt"],
orderTypes: ["desc"],
query: {},
});
// Response metadata - these come from the API
const [responseMetadata, setResponseMetadata] = useState<ResponseMetadata>({
totalCount: 0,
allCount: 0,
totalPages: 0,
pageCount: 0,
});
const [loading, setLoading] = useState(false);
const [error, setError] = useState<Error | null>(null);
const fetchDataFromApi = useCallback(async () => {
setLoading(true);
try {
const result = await fetchData({
page: requestParams.page,
size: requestParams.size,
orderFields: requestParams.orderFields,
orderTypes: requestParams.orderTypes,
query: requestParams.query,
});
// Validate data with Zod
const validatedData = result.data
.map((item: any) => {
try {
return PeopleSchema.parse(item);
} catch (err) {
console.error("Validation error for item:", item, err);
return null;
}
})
.filter(Boolean) as PeopleFormData[];
setData(validatedData);
// Update response metadata from API response
setResponseMetadata({
totalCount: result.pagination.totalCount,
allCount: result.pagination.allCount,
totalPages: result.pagination.totalPages,
pageCount: result.pagination.pageCount,
});
setError(null);
} catch (err) {
setError(err instanceof Error ? err : new Error("Unknown error"));
} finally {
setLoading(false);
}
}, [
requestParams.page,
requestParams.size,
requestParams.orderFields,
requestParams.orderTypes,
requestParams.query,
]);
useEffect(() => {
const timer = setTimeout(() => {
fetchDataFromApi();
}, 300); // Debounce
return () => clearTimeout(timer);
}, [fetchDataFromApi]);
const updatePagination = (updates: Partial<RequestParams>) => {
// Transform query parameters to use __ilike with %value% format
if (updates.query) {
const transformedQuery: Record<string, any> = {};
Object.entries(updates.query).forEach(([key, value]) => {
// Only transform string values that aren't already using a special operator
if (typeof value === 'string' && !key.includes('__')) {
transformedQuery[`${key}__ilike`] = `%${value}%`;
} else {
transformedQuery[key] = value;
}
});
updates.query = transformedQuery;
}
setRequestParams((prev) => ({
...prev,
...updates,
}));
};
// Create a combined refetch object that includes the setQuery function
const setQuery = (query: Record<string, string>) => {
setRequestParams((prev) => ({
...prev,
query,
}));
};
const refetch = Object.assign(fetchDataFromApi, { setQuery });
// Combine request params and response metadata for backward compatibility
const pagination: PagePagination = {
...requestParams,
...responseMetadata,
};
return {
data,
pagination,
loading,
error,
updatePagination,
setQuery,
refetch,
};
}