updated left menu and page template
This commit is contained in:
parent
dd4a8f333d
commit
da95b629ac
|
|
@ -1,11 +1,10 @@
|
|||
import React from 'react';
|
||||
import { DataType, Pagination } from './schema';
|
||||
import { getTranslation, LanguageKey } from './language';
|
||||
import { ActionButtonsComponent } from './ActionButtonsComponent';
|
||||
import { SortingComponent } from './SortingComponent';
|
||||
import { PaginationToolsComponent } from './PaginationToolsComponent';
|
||||
|
||||
|
||||
import React from "react";
|
||||
import { DataType } from "./schema";
|
||||
import { getTranslation, LanguageKey } from "./language";
|
||||
import { ActionButtonsComponent } from "./ActionButtonsComponent";
|
||||
import { SortingComponent } from "./SortingComponent";
|
||||
import { PaginationToolsComponent } from "./PaginationToolsComponent";
|
||||
import { PagePagination } from "@/components/validations/list/paginations";
|
||||
|
||||
interface DataCardProps {
|
||||
item: DataType;
|
||||
|
|
@ -18,7 +17,7 @@ export function DataCard({
|
|||
item,
|
||||
onView,
|
||||
onUpdate,
|
||||
lang = 'en'
|
||||
lang = "en",
|
||||
}: DataCardProps) {
|
||||
const t = getTranslation(lang);
|
||||
|
||||
|
|
@ -29,11 +28,18 @@ export function DataCard({
|
|||
<h3 className="text-lg font-semibold">{item.title}</h3>
|
||||
<p className="text-gray-600 mt-1">{item.description}</p>
|
||||
<div className="mt-2 flex items-center">
|
||||
<span className={`px-2 py-1 rounded text-xs ${item.status === 'active' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}`}>
|
||||
<span
|
||||
className={`px-2 py-1 rounded text-xs ${
|
||||
item.status === "active"
|
||||
? "bg-green-100 text-green-800"
|
||||
: "bg-gray-100 text-gray-800"
|
||||
}`}
|
||||
>
|
||||
{item.status}
|
||||
</span>
|
||||
<span className="text-xs text-gray-500 ml-2">
|
||||
{t.formLabels.createdAt}: {new Date(item.createdAt).toLocaleDateString()}
|
||||
{t.formLabels.createdAt}:{" "}
|
||||
{new Date(item.createdAt).toLocaleDateString()}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -58,10 +64,10 @@ export function DataCard({
|
|||
|
||||
interface ListInfoComponentProps {
|
||||
data: DataType[];
|
||||
pagination: Pagination;
|
||||
pagination: PagePagination;
|
||||
loading: boolean;
|
||||
error: Error | null;
|
||||
updatePagination: (updates: Partial<Pagination>) => void;
|
||||
updatePagination: (updates: Partial<PagePagination>) => void;
|
||||
onCreateClick: () => void;
|
||||
onViewClick: (item: DataType) => void;
|
||||
onUpdateClick: (item: DataType) => void;
|
||||
|
|
@ -77,7 +83,7 @@ export function ListInfoComponent({
|
|||
onCreateClick,
|
||||
onViewClick,
|
||||
onUpdateClick,
|
||||
lang = 'en'
|
||||
lang = "en",
|
||||
}: ListInfoComponentProps) {
|
||||
const t = getTranslation(lang);
|
||||
|
||||
|
|
@ -91,10 +97,7 @@ export function ListInfoComponent({
|
|||
|
||||
return (
|
||||
<>
|
||||
<ActionButtonsComponent
|
||||
onCreateClick={onCreateClick}
|
||||
lang={lang}
|
||||
/>
|
||||
<ActionButtonsComponent onCreateClick={onCreateClick} lang={lang} />
|
||||
|
||||
<SortingComponent
|
||||
pagination={pagination}
|
||||
|
|
@ -114,7 +117,7 @@ export function ListInfoComponent({
|
|||
</div>
|
||||
) : (
|
||||
<div className="grid gap-4">
|
||||
{data.map(item => (
|
||||
{data.map((item) => (
|
||||
<DataCard
|
||||
key={item.id}
|
||||
item={item}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
import React from 'react';
|
||||
import { Pagination } from './schema';
|
||||
import { getTranslation, LanguageKey } from './language';
|
||||
import React from "react";
|
||||
import { getTranslation, LanguageKey } from "./language";
|
||||
import { PagePagination } from "@/components/validations/list/paginations";
|
||||
|
||||
interface PaginationToolsComponentProps {
|
||||
pagination: Pagination;
|
||||
updatePagination: (updates: Partial<Pagination>) => void;
|
||||
pagination: PagePagination;
|
||||
updatePagination: (updates: Partial<PagePagination>) => void;
|
||||
lang?: LanguageKey;
|
||||
}
|
||||
|
||||
export function PaginationToolsComponent({
|
||||
pagination,
|
||||
updatePagination,
|
||||
lang = 'en'
|
||||
lang = "en",
|
||||
}: PaginationToolsComponentProps) {
|
||||
const t = getTranslation(lang);
|
||||
|
||||
|
|
@ -53,23 +53,32 @@ export function PaginationToolsComponent({
|
|||
|
||||
{/* Items per page selector */}
|
||||
<div className="flex items-center space-x-2">
|
||||
<label htmlFor="page-size" className="text-sm font-medium">{t.itemsPerPage}</label>
|
||||
<label htmlFor="page-size" className="text-sm font-medium">
|
||||
{t.itemsPerPage}
|
||||
</label>
|
||||
<select
|
||||
id="page-size"
|
||||
value={pagination.size}
|
||||
onChange={handleSizeChange}
|
||||
className="border rounded px-2 py-1"
|
||||
>
|
||||
{[5, 10, 20, 50].map(size => (
|
||||
<option key={size} value={size}>{size}</option>
|
||||
{[5, 10, 20, 50].map((size) => (
|
||||
<option key={size} value={size}>
|
||||
{size}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Pagination stats */}
|
||||
<div className="text-sm text-gray-600">
|
||||
<div>{t.showing} {pagination.pageCount} {t.of} {pagination.totalCount} {t.items}</div>
|
||||
<div>{t.total}: {pagination.allCount} {t.items}</div>
|
||||
<div>
|
||||
{t.showing} {pagination.pageCount} {t.of} {pagination.totalCount}{" "}
|
||||
{t.items}
|
||||
</div>
|
||||
<div>
|
||||
{t.total}: {pagination.allCount} {t.items}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,18 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { DataSchema } from './schema';
|
||||
import { getTranslation, LanguageKey } from './language';
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { DataSchema } from "./schema";
|
||||
import { getTranslation, LanguageKey } from "./language";
|
||||
|
||||
interface SearchComponentProps {
|
||||
onSearch: (query: Record<string, string>) => void;
|
||||
lang?: LanguageKey;
|
||||
}
|
||||
|
||||
export function SearchComponent({ onSearch, lang = 'en' }: SearchComponentProps) {
|
||||
export function SearchComponent({
|
||||
onSearch,
|
||||
lang = "en",
|
||||
}: SearchComponentProps) {
|
||||
const t = getTranslation(lang);
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const [searchValue, setSearchValue] = useState("");
|
||||
const [activeFields, setActiveFields] = useState<string[]>([]);
|
||||
const [searchQuery, setSearchQuery] = useState<Record<string, string>>({});
|
||||
|
||||
|
|
@ -22,7 +25,7 @@ export function SearchComponent({ onSearch, lang = 'en' }: SearchComponentProps)
|
|||
|
||||
// Only add fields if we have a search value
|
||||
if (searchValue) {
|
||||
activeFields.forEach(field => {
|
||||
activeFields.forEach((field) => {
|
||||
newQuery[field] = searchValue;
|
||||
});
|
||||
}
|
||||
|
|
@ -57,7 +60,7 @@ export function SearchComponent({ onSearch, lang = 'en' }: SearchComponentProps)
|
|||
}
|
||||
|
||||
const newQuery: Record<string, string> = {};
|
||||
activeFields.forEach(field => {
|
||||
activeFields.forEach((field) => {
|
||||
newQuery[field] = value;
|
||||
});
|
||||
|
||||
|
|
@ -66,9 +69,9 @@ export function SearchComponent({ onSearch, lang = 'en' }: SearchComponentProps)
|
|||
};
|
||||
|
||||
const toggleField = (field: string) => {
|
||||
setActiveFields(prev => {
|
||||
setActiveFields((prev) => {
|
||||
if (prev.includes(field)) {
|
||||
return prev.filter(f => f !== field);
|
||||
return prev.filter((f) => f !== field);
|
||||
} else {
|
||||
return [...prev, field];
|
||||
}
|
||||
|
|
@ -79,29 +82,31 @@ export function SearchComponent({ onSearch, lang = 'en' }: SearchComponentProps)
|
|||
<div className="bg-white p-4 rounded-lg shadow mb-4">
|
||||
<div className="mb-3">
|
||||
<label htmlFor="search" className="block text-sm font-medium mb-1">
|
||||
{t.search || 'Search'}
|
||||
{t.search || "Search"}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="search"
|
||||
value={searchValue}
|
||||
onChange={handleSearchChange}
|
||||
placeholder={t.searchPlaceholder || 'Enter search term...'}
|
||||
placeholder={t.searchPlaceholder || "Enter search term..."}
|
||||
className="w-full p-2 border rounded focus:ring-blue-500 focus:border-blue-500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="text-sm font-medium mb-1">{t.searchFields || 'Search in fields'}:</div>
|
||||
<div className="text-sm font-medium mb-1">
|
||||
{t.searchFields || "Search in fields"}:
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{Object.keys(DataSchema.shape).map(field => (
|
||||
{Object.keys(DataSchema.shape).map((field) => (
|
||||
<button
|
||||
key={field}
|
||||
onClick={() => toggleField(field)}
|
||||
className={`px-3 py-1 text-sm rounded ${
|
||||
activeFields.includes(field)
|
||||
? 'bg-blue-500 text-white'
|
||||
: 'bg-gray-200 text-gray-700'
|
||||
? "bg-blue-500 text-white"
|
||||
: "bg-gray-200 text-gray-700"
|
||||
}`}
|
||||
>
|
||||
{field}
|
||||
|
|
@ -112,10 +117,15 @@ export function SearchComponent({ onSearch, lang = 'en' }: SearchComponentProps)
|
|||
|
||||
{Object.keys(searchQuery).length > 0 && (
|
||||
<div className="mt-3 p-2 bg-gray-100 rounded">
|
||||
<div className="text-sm font-medium mb-1">{t.activeSearch || 'Active search'}:</div>
|
||||
<div className="text-sm font-medium mb-1">
|
||||
{t.activeSearch || "Active search"}:
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{Object.entries(searchQuery).map(([field, value]) => (
|
||||
<div key={field} className="bg-blue-100 text-blue-800 px-2 py-1 rounded text-sm">
|
||||
<div
|
||||
key={field}
|
||||
className="bg-blue-100 text-blue-800 px-2 py-1 rounded text-sm"
|
||||
>
|
||||
{field}: {value}
|
||||
<button
|
||||
onClick={() => toggleField(field)}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
import React from 'react';
|
||||
import { Pagination, DataSchema } from './schema';
|
||||
import { getTranslation, LanguageKey } from './language';
|
||||
import React from "react";
|
||||
import { DataSchema } from "./schema";
|
||||
import { getTranslation, LanguageKey } from "./language";
|
||||
import { PagePagination } from "@/components/validations/list/paginations";
|
||||
|
||||
interface SortingComponentProps {
|
||||
pagination: Pagination;
|
||||
updatePagination: (updates: Partial<Pagination>) => void;
|
||||
pagination: PagePagination;
|
||||
updatePagination: (updates: Partial<PagePagination>) => void;
|
||||
lang?: LanguageKey;
|
||||
}
|
||||
|
||||
export function SortingComponent({
|
||||
pagination,
|
||||
updatePagination,
|
||||
lang = 'en'
|
||||
lang = "en",
|
||||
}: SortingComponentProps) {
|
||||
const t = getTranslation(lang);
|
||||
|
||||
|
|
@ -26,10 +27,10 @@ export function SortingComponent({
|
|||
if (fieldIndex === -1) {
|
||||
// Field is not being sorted yet - add it with 'asc' direction
|
||||
newOrderFields.push(field);
|
||||
newOrderTypes.push('asc');
|
||||
} else if (pagination.orderTypes[fieldIndex] === 'asc') {
|
||||
newOrderTypes.push("asc");
|
||||
} else if (pagination.orderTypes[fieldIndex] === "asc") {
|
||||
// Field is being sorted ascending - change to descending
|
||||
newOrderTypes[fieldIndex] = 'desc';
|
||||
newOrderTypes[fieldIndex] = "desc";
|
||||
} else {
|
||||
// Field is being sorted descending - remove it from sorting
|
||||
newOrderFields.splice(fieldIndex, 1);
|
||||
|
|
@ -48,22 +49,26 @@ export function SortingComponent({
|
|||
<div className="flex items-center space-x-2">
|
||||
<label className="text-sm font-medium">{t.sortBy}</label>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{Object.keys(DataSchema.shape).map(field => {
|
||||
{Object.keys(DataSchema.shape).map((field) => {
|
||||
// Find if this field is in the orderFields array
|
||||
const fieldIndex = pagination.orderFields.indexOf(field);
|
||||
const isActive = fieldIndex !== -1;
|
||||
const direction = isActive ? pagination.orderTypes[fieldIndex] : null;
|
||||
const direction = isActive
|
||||
? pagination.orderTypes[fieldIndex]
|
||||
: null;
|
||||
|
||||
return (
|
||||
<button
|
||||
key={field}
|
||||
onClick={() => handleSortChange(field)}
|
||||
className={`px-3 py-1 rounded ${isActive ? 'bg-blue-500 text-white' : 'bg-gray-200'}`}
|
||||
className={`px-3 py-1 rounded ${
|
||||
isActive ? "bg-blue-500 text-white" : "bg-gray-200"
|
||||
}`}
|
||||
>
|
||||
{field}
|
||||
{isActive && (
|
||||
<span className="ml-1">
|
||||
{direction === 'asc' ? '↑' : '↓'}
|
||||
{direction === "asc" ? "↑" : "↓"}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -1,22 +1,10 @@
|
|||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { DataType, Pagination, fetchData, DataSchema } from './schema';
|
||||
|
||||
// Define request parameters interface
|
||||
interface RequestParams {
|
||||
page: number;
|
||||
size: number;
|
||||
orderFields: string[];
|
||||
orderTypes: string[];
|
||||
query: Record<string, string>;
|
||||
}
|
||||
|
||||
// Define response metadata interface
|
||||
interface ResponseMetadata {
|
||||
totalCount: number;
|
||||
allCount: number;
|
||||
totalPages: number;
|
||||
pageCount: number;
|
||||
}
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import { DataType, fetchData, DataSchema } from "./schema";
|
||||
import {
|
||||
PagePagination,
|
||||
RequestParams,
|
||||
ResponseMetadata,
|
||||
} from "@/components/validations/list/paginations";
|
||||
|
||||
// Custom hook for pagination and data fetching
|
||||
export function usePaginatedData() {
|
||||
|
|
@ -26,8 +14,8 @@ export function usePaginatedData() {
|
|||
const [requestParams, setRequestParams] = useState<RequestParams>({
|
||||
page: 1,
|
||||
size: 10,
|
||||
orderFields: ['createdAt'],
|
||||
orderTypes: ['desc'],
|
||||
orderFields: ["createdAt"],
|
||||
orderTypes: ["desc"],
|
||||
query: {},
|
||||
});
|
||||
|
||||
|
|
@ -54,14 +42,16 @@ export function usePaginatedData() {
|
|||
});
|
||||
|
||||
// Validate data with Zod
|
||||
const validatedData = result.data.map(item => {
|
||||
const validatedData = result.data
|
||||
.map((item) => {
|
||||
try {
|
||||
return DataSchema.parse(item);
|
||||
} catch (err) {
|
||||
console.error('Validation error for item:', item, err);
|
||||
console.error("Validation error for item:", item, err);
|
||||
return null;
|
||||
}
|
||||
}).filter(Boolean) as DataType[];
|
||||
})
|
||||
.filter(Boolean) as DataType[];
|
||||
|
||||
setData(validatedData);
|
||||
|
||||
|
|
@ -75,11 +65,17 @@ export function usePaginatedData() {
|
|||
|
||||
setError(null);
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err : new Error('Unknown error'));
|
||||
setError(err instanceof Error ? err : new Error("Unknown error"));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [requestParams.page, requestParams.size, requestParams.orderFields, requestParams.orderTypes, requestParams.query]);
|
||||
}, [
|
||||
requestParams.page,
|
||||
requestParams.size,
|
||||
requestParams.orderFields,
|
||||
requestParams.orderTypes,
|
||||
requestParams.query,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => {
|
||||
|
|
@ -90,7 +86,7 @@ export function usePaginatedData() {
|
|||
}, [fetchDataFromApi]);
|
||||
|
||||
const updatePagination = (updates: Partial<RequestParams>) => {
|
||||
setRequestParams(prev => ({
|
||||
setRequestParams((prev) => ({
|
||||
...prev,
|
||||
...updates,
|
||||
}));
|
||||
|
|
@ -98,7 +94,7 @@ export function usePaginatedData() {
|
|||
|
||||
// Create a combined refetch object that includes the setQuery function
|
||||
const setQuery = (query: Record<string, string>) => {
|
||||
setRequestParams(prev => ({
|
||||
setRequestParams((prev) => ({
|
||||
...prev,
|
||||
query,
|
||||
}));
|
||||
|
|
@ -107,7 +103,7 @@ export function usePaginatedData() {
|
|||
const refetch = Object.assign(fetchDataFromApi, { setQuery });
|
||||
|
||||
// Combine request params and response metadata for backward compatibility
|
||||
const pagination: Pagination = {
|
||||
const pagination: PagePagination = {
|
||||
...requestParams,
|
||||
...responseMetadata,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,55 +1,55 @@
|
|||
// Language dictionary for the template component
|
||||
const language = {
|
||||
en: {
|
||||
title: 'Data Management',
|
||||
create: 'Create New',
|
||||
view: 'View Item',
|
||||
update: 'Update Item',
|
||||
createNew: 'Create New Item',
|
||||
back: 'Back',
|
||||
cancel: 'Cancel',
|
||||
submit: 'Submit',
|
||||
noItemsFound: 'No items found',
|
||||
previous: 'Previous',
|
||||
next: 'Next',
|
||||
page: 'Page',
|
||||
of: 'of',
|
||||
itemsPerPage: 'Items per page:',
|
||||
sortBy: 'Sort by:',
|
||||
loading: 'Loading...',
|
||||
error: 'Error loading data:',
|
||||
showing: 'Showing',
|
||||
items: 'items',
|
||||
total: 'Total',
|
||||
title: "Data Management",
|
||||
create: "Create New",
|
||||
view: "View Item",
|
||||
update: "Update Item",
|
||||
createNew: "Create New Item",
|
||||
back: "Back",
|
||||
cancel: "Cancel",
|
||||
submit: "Submit",
|
||||
noItemsFound: "No items found",
|
||||
previous: "Previous",
|
||||
next: "Next",
|
||||
page: "Page",
|
||||
of: "of",
|
||||
itemsPerPage: "Items per page:",
|
||||
sortBy: "Sort by:",
|
||||
loading: "Loading...",
|
||||
error: "Error loading data:",
|
||||
showing: "Showing",
|
||||
items: "items",
|
||||
total: "Total",
|
||||
// Search related translations
|
||||
search: 'Search',
|
||||
searchPlaceholder: 'Enter search term...',
|
||||
searchFields: 'Search in fields',
|
||||
activeSearch: 'Active search',
|
||||
clearSearch: 'Clear',
|
||||
search: "Search",
|
||||
searchPlaceholder: "Enter search term...",
|
||||
searchFields: "Search in fields",
|
||||
activeSearch: "Active search",
|
||||
clearSearch: "Clear",
|
||||
formLabels: {
|
||||
title: 'Title',
|
||||
description: 'Description',
|
||||
status: 'Status',
|
||||
createdAt: 'Created'
|
||||
title: "Title",
|
||||
description: "Description",
|
||||
status: "Status",
|
||||
createdAt: "Created",
|
||||
},
|
||||
status: {
|
||||
active: 'Active',
|
||||
inactive: 'Inactive'
|
||||
active: "Active",
|
||||
inactive: "Inactive",
|
||||
},
|
||||
buttons: {
|
||||
view: 'View',
|
||||
update: 'Update',
|
||||
create: 'Create',
|
||||
save: 'Save'
|
||||
}
|
||||
view: "View",
|
||||
update: "Update",
|
||||
create: "Create",
|
||||
save: "Save",
|
||||
},
|
||||
},
|
||||
// Add more languages as needed
|
||||
};
|
||||
|
||||
export type LanguageKey = keyof typeof language;
|
||||
|
||||
export const getTranslation = (lang: LanguageKey = 'en') => {
|
||||
export const getTranslation = (lang: LanguageKey = "en") => {
|
||||
return language[lang] || language.en;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import { z } from "zod";
|
||||
|
||||
import { PagePagination } from "@/components/validations/list/paginations";
|
||||
|
||||
// Define the data schema using Zod
|
||||
export const DataSchema = z.object({
|
||||
id: z.string(),
|
||||
|
|
@ -12,19 +14,6 @@ export const DataSchema = z.object({
|
|||
|
||||
export type DataType = z.infer<typeof DataSchema>;
|
||||
|
||||
// Define pagination interface
|
||||
export interface Pagination {
|
||||
page: number;
|
||||
size: number;
|
||||
totalCount: number;
|
||||
allCount: number;
|
||||
totalPages: number;
|
||||
orderFields: string[];
|
||||
orderTypes: string[];
|
||||
pageCount: number;
|
||||
query: Record<string, string>;
|
||||
}
|
||||
|
||||
// Mock API function (replace with your actual API call)
|
||||
export const fetchData = async ({
|
||||
page = 1,
|
||||
|
|
@ -49,7 +38,7 @@ export const fetchData = async ({
|
|||
});
|
||||
|
||||
// Simulated API response
|
||||
return new Promise<{ data: DataType[]; pagination: Pagination }>(
|
||||
return new Promise<{ data: DataType[]; pagination: PagePagination }>(
|
||||
(resolve) => {
|
||||
setTimeout(() => {
|
||||
// Generate mock data
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
// Define pagination interface
|
||||
export interface PagePagination {
|
||||
page: number;
|
||||
size: number;
|
||||
totalCount: number;
|
||||
allCount: number;
|
||||
totalPages: number;
|
||||
orderFields: string[];
|
||||
orderTypes: string[];
|
||||
pageCount: number;
|
||||
query: Record<string, string>;
|
||||
}
|
||||
|
||||
|
||||
// Define request parameters interface
|
||||
export interface RequestParams {
|
||||
page: number;
|
||||
size: number;
|
||||
orderFields: string[];
|
||||
orderTypes: string[];
|
||||
query: Record<string, string>;
|
||||
}
|
||||
|
||||
// Define response metadata interface
|
||||
export interface ResponseMetadata {
|
||||
totalCount: number;
|
||||
allCount: number;
|
||||
totalPages: number;
|
||||
pageCount: number;
|
||||
}
|
||||
Loading…
Reference in New Issue