- Unify API: lib/api.ts uses /api/v1, inbox uses /api/inbox (rewrites) - Remove localhost refs: openapi, inbox page - Add rewrites: /api/inbox|tmc -> inbox-server, /api/v1 -> FastAPI - Add stub routes: knowledge/insights, recommendations, search, log-error - Transfer from PAPA: prompts (inspection, tmc), scripts, supabase, data/tmc-requests - Fix inbox-server: ORDER BY created_at, package.json - Remove redundant app/api/inbox/files route (rewrites handle it) - knowledge/ in gitignore (large PDFs) Co-authored-by: Cursor <cursoragent@cursor.com>
148 lines
3.3 KiB
TypeScript
148 lines
3.3 KiB
TypeScript
/**
|
||
* Хук для работы с URL параметрами (фильтры, сортировка, пагинация)
|
||
*/
|
||
'use client';
|
||
|
||
import { useRouter, useSearchParams } from 'next/navigation';
|
||
import { useCallback, useMemo } from 'react';
|
||
|
||
export interface FilterParams {
|
||
search?: string;
|
||
status?: string[];
|
||
organization?: string;
|
||
type?: string;
|
||
dateFrom?: string;
|
||
dateTo?: string;
|
||
sortBy?: string;
|
||
sortOrder?: 'asc' | 'desc';
|
||
page?: number;
|
||
limit?: number;
|
||
}
|
||
|
||
export function useUrlParams() {
|
||
const router = useRouter();
|
||
const searchParams = useSearchParams();
|
||
|
||
const params = useMemo(() => {
|
||
const params: FilterParams = {};
|
||
|
||
const search = searchParams.get('search');
|
||
if (search) {
|
||
params.search = search;
|
||
}
|
||
|
||
const status = searchParams.get('status');
|
||
if (status) {
|
||
params.status = status.split(',');
|
||
}
|
||
|
||
const organization = searchParams.get('organization');
|
||
if (organization) {
|
||
params.organization = organization;
|
||
}
|
||
|
||
const type = searchParams.get('type');
|
||
if (type) {
|
||
params.type = type;
|
||
}
|
||
|
||
const dateFrom = searchParams.get('dateFrom');
|
||
if (dateFrom) {
|
||
params.dateFrom = dateFrom;
|
||
}
|
||
|
||
const dateTo = searchParams.get('dateTo');
|
||
if (dateTo) {
|
||
params.dateTo = dateTo;
|
||
}
|
||
|
||
const sortBy = searchParams.get('sortBy');
|
||
if (sortBy) {
|
||
params.sortBy = sortBy;
|
||
}
|
||
|
||
const sortOrder = searchParams.get('sortOrder') as 'asc' | 'desc' | null;
|
||
if (sortOrder) {
|
||
params.sortOrder = sortOrder;
|
||
}
|
||
|
||
const page = searchParams.get('page');
|
||
if (page) {
|
||
params.page = parseInt(page, 10);
|
||
}
|
||
|
||
const limit = searchParams.get('limit');
|
||
if (limit) {
|
||
params.limit = parseInt(limit, 10);
|
||
}
|
||
|
||
return params;
|
||
}, [searchParams]);
|
||
|
||
const updateParams = useCallback(
|
||
(updates: Partial<FilterParams>, replace: boolean = false) => {
|
||
const newParams = new URLSearchParams(searchParams.toString());
|
||
|
||
Object.entries(updates).forEach(([key, value]) => {
|
||
if (value === undefined || value === null || value === '') {
|
||
newParams.delete(key);
|
||
} else if (Array.isArray(value)) {
|
||
if (value.length > 0) {
|
||
newParams.set(key, value.join(','));
|
||
} else {
|
||
newParams.delete(key);
|
||
}
|
||
} else {
|
||
newParams.set(key, String(value));
|
||
}
|
||
});
|
||
|
||
const method = replace ? router.replace : router.push;
|
||
method(`?${newParams.toString()}`);
|
||
},
|
||
[router, searchParams]
|
||
);
|
||
|
||
const setSearch = useCallback(
|
||
(search: string) => {
|
||
updateParams({ search, page: 1 });
|
||
},
|
||
[updateParams]
|
||
);
|
||
|
||
const setFilters = useCallback(
|
||
(filters: Partial<FilterParams>) => {
|
||
updateParams({ ...filters, page: 1 });
|
||
},
|
||
[updateParams]
|
||
);
|
||
|
||
const setSort = useCallback(
|
||
(sortBy: string, sortOrder: 'asc' | 'desc' = 'asc') => {
|
||
updateParams({ sortBy, sortOrder });
|
||
},
|
||
[updateParams]
|
||
);
|
||
|
||
const setPage = useCallback(
|
||
(page: number) => {
|
||
updateParams({ page });
|
||
},
|
||
[updateParams]
|
||
);
|
||
|
||
const clearFilters = useCallback(() => {
|
||
router.replace('?');
|
||
}, [router]);
|
||
|
||
return {
|
||
params,
|
||
updateParams,
|
||
setSearch,
|
||
setFilters,
|
||
setSort,
|
||
setPage,
|
||
clearFilters,
|
||
};
|
||
}
|