diff --git a/package.json b/package.json index 2b27f39..9ff7447 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@dnd-kit/modifiers": "^9.0.0", "@dnd-kit/sortable": "^10.0.0", "@mantine/core": "8.1.2", + "@mantine/dates": "^8.2.7", "@mantine/form": "^8.1.3", "@mantine/hooks": "8.1.2", "@mantine/modals": "^8.2.1", @@ -27,10 +28,12 @@ "classnames": "^2.5.1", "date-fns": "^4.1.0", "date-fns-tz": "^3.2.0", + "dayjs": "^1.11.15", "framer-motion": "^12.23.7", "i18n-iso-countries": "^7.14.0", "lexorank": "^1.0.5", "libphonenumber-js": "^1.12.10", + "mantine-react-table": "^2.0.0-beta.9", "next": "15.3.3", "react": "19.1.0", "react-dom": "19.1.0", diff --git a/src/app/deals/components/desktop/DealsTable/DealsTable.tsx b/src/app/deals/components/desktop/DealsTable/DealsTable.tsx new file mode 100644 index 0000000..35ccc6f --- /dev/null +++ b/src/app/deals/components/desktop/DealsTable/DealsTable.tsx @@ -0,0 +1,74 @@ +import { IconEdit } from "@tabler/icons-react"; +import { MRT_TableOptions } from "mantine-react-table"; +import { ActionIcon, Group, Pagination, Stack, Tooltip } from "@mantine/core"; +import useDealsTableColumns from "@/app/deals/components/desktop/DealsTable/useDealsTableColumns"; +import { useDealsContext } from "@/app/deals/contexts/DealsContext"; +import BaseTable from "@/components/ui/BaseTable/BaseTable"; +import { useDrawersContext } from "@/drawers/DrawersContext"; +import { DealSchema } from "@/lib/client"; + +const DealsTable = () => { + const { deals, paginationInfo, page, setPage, dealsCrud } = + useDealsContext(); + const { openDrawer } = useDrawersContext(); + const columns = useDealsTableColumns(); + const defaultSorting = [{ id: "createdAt", desc: false }]; + + const onEditDeal = (deal: DealSchema) => { + openDrawer({ + key: "dealEditorDrawer", + props: { + deal, + dealsCrud, + }, + }); + }; + + return ( + + ( + + onEditDeal(row.original)} + variant={"default"}> + + + + ), + } as MRT_TableOptions + } + /> + + + + + ); +}; + +export default DealsTable; diff --git a/src/app/deals/components/desktop/DealsTable/useDealsTableColumns.tsx b/src/app/deals/components/desktop/DealsTable/useDealsTableColumns.tsx new file mode 100644 index 0000000..45a1858 --- /dev/null +++ b/src/app/deals/components/desktop/DealsTable/useDealsTableColumns.tsx @@ -0,0 +1,33 @@ +import { useMemo } from "react"; +import { MRT_ColumnDef } from "mantine-react-table"; +import { DealSchema } from "@/lib/client"; + +const useDealsTableColumns = () => { + return useMemo[]>( + () => [ + { + accessorKey: "id", + header: "Номер", + size: 20, + }, + { + accessorKey: "name", + header: "Название", + enableSorting: false, + }, + { + header: "Дата создания", + accessorKey: "createdAt", + Cell: ({ row }) => + new Date(row.original.createdAt).toLocaleString("ru-RU"), + enableSorting: true, + sortingFn: (rowA, rowB) => + new Date(rowB.original.createdAt).getTime() - + new Date(rowA.original.createdAt).getTime(), + }, + ], + [] + ); +}; + +export default useDealsTableColumns; diff --git a/src/app/deals/components/shared/Header/Header.tsx b/src/app/deals/components/mobile/MainBlockHeader/MainBlockHeader.tsx similarity index 53% rename from src/app/deals/components/shared/Header/Header.tsx rename to src/app/deals/components/mobile/MainBlockHeader/MainBlockHeader.tsx index 55b3e8c..5fee885 100644 --- a/src/app/deals/components/shared/Header/Header.tsx +++ b/src/app/deals/components/mobile/MainBlockHeader/MainBlockHeader.tsx @@ -1,53 +1,20 @@ "use client"; import { IconChevronLeft, IconSettings } from "@tabler/icons-react"; -import { Box, Flex, Group, Stack, Text } from "@mantine/core"; +import { Box, Group, Stack, Text } from "@mantine/core"; import Boards from "@/app/deals/components/shared/Boards/Boards"; import { useBoardsContext } from "@/app/deals/contexts/BoardsContext"; import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext"; -import ProjectSelect from "@/components/selects/ProjectSelect/ProjectSelect"; import { useDrawersContext } from "@/drawers/DrawersContext"; import useIsMobile from "@/hooks/utils/useIsMobile"; -const Header = () => { - const { projects, setSelectedProjectId, refetchProjects, selectedProject } = +const MainBlockHeader = () => { + const { setSelectedProjectId, refetchProjects, selectedProject } = useProjectsContext(); const { refetchBoards } = useBoardsContext(); const { openDrawer } = useDrawersContext(); const isMobile = useIsMobile(); - const spacer = ( - - ); - - const getDesktopHeader = () => { - return ( - - - {spacer} - - - value && setSelectedProjectId(value.id) - } - style={{ minWidth: 200 }} - /> - - - ); - }; - const selectProjectId = async (projectId: number | null) => { await refetchProjects(); setSelectedProjectId(projectId); @@ -73,9 +40,11 @@ const Header = () => { }); }; - const getMobileHeader = () => { - return ( - <> + return ( + + {isMobile && ( { - - - {spacer} - - - ); - }; - - return ( - - - {isMobile ? getMobileHeader() : getDesktopHeader()} - - + align={"end"}> + + + + ); }; -export default Header; +export default MainBlockHeader; diff --git a/src/app/deals/components/shared/PageBody/PageBody.tsx b/src/app/deals/components/shared/PageBody/PageBody.tsx index 5d7274e..872b948 100644 --- a/src/app/deals/components/shared/PageBody/PageBody.tsx +++ b/src/app/deals/components/shared/PageBody/PageBody.tsx @@ -1,26 +1,42 @@ "use client"; -import { Space } from "@mantine/core"; +import { Box, Space } from "@mantine/core"; +import DealsTable from "@/app/deals/components/desktop/DealsTable/DealsTable"; import MainBlockHeader from "@/app/deals/components/mobile/MainBlockHeader/MainBlockHeader"; import Funnel from "@/app/deals/components/shared/Funnel/Funnel"; +import { useBoardsContext } from "@/app/deals/contexts/BoardsContext"; import { DealsContextProvider } from "@/app/deals/contexts/DealsContext"; +import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext"; import { useViewContext } from "@/app/deals/contexts/ViewContext"; const PageBody = () => { + const { selectedBoard } = useBoardsContext(); + const { selectedProject } = useProjectsContext(); const { view } = useViewContext(); - if (view === "board") + if (view === "board") { return ( <> - + ); + } - if (view === "table") return <>-; + if (view === "table") { + return ( + + + + + + ); + } return <>-; }; diff --git a/src/app/deals/contexts/DealsContext.tsx b/src/app/deals/contexts/DealsContext.tsx index ae5fde5..5aa29ee 100644 --- a/src/app/deals/contexts/DealsContext.tsx +++ b/src/app/deals/contexts/DealsContext.tsx @@ -1,11 +1,10 @@ "use client"; import React from "react"; -import { useBoardsContext } from "@/app/deals/contexts/BoardsContext"; import { useStatusesContext } from "@/app/deals/contexts/StatusesContext"; import { DealsCrud, useDealsCrud } from "@/hooks/cruds/useDealsCrud"; import useDealsList from "@/hooks/lists/useDealsList"; -import { DealSchema } from "@/lib/client"; +import { DealSchema, PaginationInfoSchema } from "@/lib/client"; import makeContext from "@/lib/contextFactory/contextFactory"; type DealsContextState = { @@ -13,29 +12,42 @@ type DealsContextState = { setDeals: React.Dispatch>; refetchDeals: () => void; dealsCrud: DealsCrud; + paginationInfo: PaginationInfoSchema; + page: number; + setPage: React.Dispatch>; }; -const useDealsContextState = (): DealsContextState => { - const { selectedBoard } = useBoardsContext(); +type Props = { + withPagination?: boolean; + boardId?: number; + projectId?: number; +}; + +const useDealsContextState = ({ + withPagination = false, + boardId, + projectId, +}: Props): DealsContextState => { const { statuses } = useStatusesContext(); - const { - deals, - setDeals, - refetch: refetchDeals, - } = useDealsList({ - boardId: selectedBoard?.id, + const dealsListObjects = useDealsList({ + boardId, + projectId, + withPagination, }); const dealsCrud = useDealsCrud({ - deals, - setDeals, - refetchDeals, - boardId: selectedBoard?.id, + ...dealsListObjects, + boardId, statuses, }); - return { deals, setDeals, refetchDeals, dealsCrud }; + return { + ...dealsListObjects, + dealsCrud, + }; }; -export const [DealsContextProvider, useDealsContext] = - makeContext(useDealsContextState, "Deals"); +export const [DealsContextProvider, useDealsContext] = makeContext< + DealsContextState, + Props +>(useDealsContextState, "Deals"); diff --git a/src/app/layout.tsx b/src/app/layout.tsx index a549e62..12e6be8 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,5 +1,7 @@ import "@mantine/core/styles.css"; import "@mantine/notifications/styles.css"; +import "@mantine/dates/styles.css"; +import "mantine-react-table/styles.css"; import "swiper/css"; import "swiper/css/pagination"; import "swiper/css/scrollbar"; diff --git a/src/components/ui/BaseTable/BaseTable.tsx b/src/components/ui/BaseTable/BaseTable.tsx new file mode 100644 index 0000000..59c95ee --- /dev/null +++ b/src/components/ui/BaseTable/BaseTable.tsx @@ -0,0 +1,59 @@ +import React, { useEffect, useImperativeHandle } from "react"; +import { + MantineReactTable, + MRT_ColumnDef, + MRT_RowData, + MRT_TableInstance, + MRT_TableOptions, + useMantineReactTable, +} from "mantine-react-table"; +import { MRT_Localization_RU } from "mantine-react-table/locales/ru"; + +type Props = { + data: T[]; + onSelectionChange?: (selectedRows: T[]) => void; + columns: MRT_ColumnDef[]; + restProps?: MRT_TableOptions; + striped?: boolean | "odd" | "even"; +}; + +export type BaseTableRef = { + getTable: () => MRT_TableInstance; +}; + +function BaseTableInner( + { data, columns, restProps, onSelectionChange, striped = false }: Props, + ref: React.Ref> +) { + const table = useMantineReactTable({ + localization: MRT_Localization_RU, + enablePagination: false, + data, + columns, + mantineTableProps: { + striped, + highlightOnHover: false, + }, + enableTopToolbar: false, + enableBottomToolbar: false, + enableRowSelection: onSelectionChange !== undefined, + ...restProps, + }); + + useEffect(() => { + if (!onSelectionChange) return; + onSelectionChange( + table.getSelectedRowModel().rows.map(r => r.original) + ); + }, [onSelectionChange, table.getState().rowSelection]); + + useImperativeHandle(ref, () => ({ getTable: () => table })); + + return ; +} + +const BaseTable = React.forwardRef(BaseTableInner) as ( + props: Props & { ref?: React.Ref> } +) => React.ReactElement | null; + +export default BaseTable; diff --git a/src/hooks/lists/useDealsList.ts b/src/hooks/lists/useDealsList.ts index 63c5a87..f6df120 100644 --- a/src/hooks/lists/useDealsList.ts +++ b/src/hooks/lists/useDealsList.ts @@ -1,40 +1,61 @@ import { useEffect, useState } from "react"; import { useQueryClient } from "@tanstack/react-query"; -import { DealSchema } from "@/lib/client"; +import { DealSchema, PaginationInfoSchema } from "@/lib/client"; import { getDealsOptions } from "@/lib/client/@tanstack/react-query.gen"; type Props = { - boardId?: number; + boardId?: number | null; + projectId?: number | null; + withPagination: boolean; }; -const useDealsList = ({ boardId }: Props) => { +const useDealsList = ({ + withPagination, + projectId = null, + boardId = null, +}: Props) => { const [deals, setDeals] = useState([]); - + const [page, setPage] = useState(1); + const [paginationInfo, setPaginationInfo] = useState({ + totalPages: 1, + totalItems: 1, + }); + const itemsPerPage = 10; const queryClient = useQueryClient(); - const fetchDeals = () => { - if (!boardId) { - setDeals([]); - return; - } + const refetchDeals = () => { + if (!boardId && !projectId) return; queryClient .fetchQuery({ - ...getDealsOptions({ path: { boardId } }), + ...getDealsOptions({ + query: { + boardId: boardId ?? null, + projectId: projectId ?? null, + page: withPagination ? page : null, + itemsPerPage: withPagination ? itemsPerPage : null, + }, + }), }) .then(data => { setDeals(data.deals); + setPaginationInfo(data.paginationInfo); }) - .catch(err => { - console.error(err); - }); + .catch(err => console.error(err)); }; useEffect(() => { - fetchDeals(); - }, [boardId]); + refetchDeals(); + }, [boardId, withPagination, projectId, page]); - return { deals, setDeals, refetch: fetchDeals }; + return { + deals, + setDeals, + refetchDeals, + page, + setPage, + paginationInfo, + }; }; export default useDealsList; diff --git a/src/lib/client/@tanstack/react-query.gen.ts b/src/lib/client/@tanstack/react-query.gen.ts index 12fb916..a0eee04 100644 --- a/src/lib/client/@tanstack/react-query.gen.ts +++ b/src/lib/client/@tanstack/react-query.gen.ts @@ -1,6 +1,11 @@ // This file is auto-generated by @hey-api/openapi-ts -import { queryOptions, type UseMutationOptions } from "@tanstack/react-query"; +import { + infiniteQueryOptions, + queryOptions, + type InfiniteData, + type UseMutationOptions, +} from "@tanstack/react-query"; import type { AxiosError } from "axios"; import { client as _heyApiClient } from "../client.gen"; import { @@ -49,6 +54,8 @@ import type { DeleteStatusResponse2, GetBoardsData, GetDealsData, + GetDealsError, + GetDealsResponse2, GetProjectsData, GetStatusesData, UpdateBoardData, @@ -224,13 +231,13 @@ export const updateBoardMutation = ( return mutationOptions; }; -export const getDealsQueryKey = (options: Options) => +export const getDealsQueryKey = (options?: Options) => createQueryKey("getDeals", options); /** * Get Deals */ -export const getDealsOptions = (options: Options) => { +export const getDealsOptions = (options?: Options) => { return queryOptions({ queryFn: async ({ queryKey, signal }) => { const { data } = await getDeals({ @@ -245,6 +252,91 @@ export const getDealsOptions = (options: Options) => { }); }; +const createInfiniteParams = < + K extends Pick[0], "body" | "headers" | "path" | "query">, +>( + queryKey: QueryKey, + page: K +) => { + const params = { + ...queryKey[0], + }; + if (page.body) { + params.body = { + ...(queryKey[0].body as any), + ...(page.body as any), + }; + } + if (page.headers) { + params.headers = { + ...queryKey[0].headers, + ...page.headers, + }; + } + if (page.path) { + params.path = { + ...(queryKey[0].path as any), + ...(page.path as any), + }; + } + if (page.query) { + params.query = { + ...(queryKey[0].query as any), + ...(page.query as any), + }; + } + return params as unknown as typeof page; +}; + +export const getDealsInfiniteQueryKey = ( + options?: Options +): QueryKey> => createQueryKey("getDeals", options, true); + +/** + * Get Deals + */ +export const getDealsInfiniteOptions = (options?: Options) => { + return infiniteQueryOptions< + GetDealsResponse2, + AxiosError, + InfiniteData, + QueryKey>, + | number + | null + | Pick< + QueryKey>[0], + "body" | "headers" | "path" | "query" + > + >( + // @ts-ignore + { + queryFn: async ({ pageParam, queryKey, signal }) => { + // @ts-ignore + const page: Pick< + QueryKey>[0], + "body" | "headers" | "path" | "query" + > = + typeof pageParam === "object" + ? pageParam + : { + query: { + page: pageParam, + }, + }; + const params = createInfiniteParams(queryKey, page); + const { data } = await getDeals({ + ...options, + ...params, + signal, + throwOnError: true, + }); + return data; + }, + queryKey: getDealsInfiniteQueryKey(options), + } + ); +}; + export const createDealQueryKey = (options: Options) => createQueryKey("createDeal", options); diff --git a/src/lib/client/sdk.gen.ts b/src/lib/client/sdk.gen.ts index 7f53ca7..52a2516 100644 --- a/src/lib/client/sdk.gen.ts +++ b/src/lib/client/sdk.gen.ts @@ -207,9 +207,9 @@ export const updateBoard = ( * Get Deals */ export const getDeals = ( - options: Options + options?: Options ) => { - return (options.client ?? _heyApiClient).get< + return (options?.client ?? _heyApiClient).get< GetDealsResponses, GetDealsErrors, ThrowOnError @@ -221,7 +221,7 @@ export const getDeals = ( responseValidator: async data => { return await zGetDealsResponse2.parseAsync(data); }, - url: "/deal/{boardId}", + url: "/deal/", ...options, }); }; diff --git a/src/lib/client/types.gen.ts b/src/lib/client/types.gen.ts index c86909e..e1179ae 100644 --- a/src/lib/client/types.gen.ts +++ b/src/lib/client/types.gen.ts @@ -242,6 +242,7 @@ export type GetDealsResponse = { * Deals */ deals: Array; + paginationInfo: PaginationInfoSchema; }; /** @@ -274,6 +275,20 @@ export type HttpValidationError = { detail?: Array; }; +/** + * PaginationInfoSchema + */ +export type PaginationInfoSchema = { + /** + * Totalpages + */ + totalPages: number; + /** + * Totalitems + */ + totalItems: number; +}; + /** * ProjectSchema */ @@ -568,14 +583,26 @@ export type UpdateBoardResponse2 = export type GetDealsData = { body?: never; - path: { + path?: never; + query?: { /** * Boardid */ - boardId: number; + boardId?: number | null; + /** + * Projectid + */ + projectId?: number | null; + /** + * Page + */ + page?: number | null; + /** + * Itemsperpage + */ + itemsPerPage?: number | null; }; - query?: never; - url: "/deal/{boardId}"; + url: "/deal/"; }; export type GetDealsErrors = { diff --git a/src/lib/client/zod.gen.ts b/src/lib/client/zod.gen.ts index 08c8188..2420cc2 100644 --- a/src/lib/client/zod.gen.ts +++ b/src/lib/client/zod.gen.ts @@ -171,11 +171,20 @@ export const zGetBoardsResponse = z.object({ boards: z.array(zBoardSchema), }); +/** + * PaginationInfoSchema + */ +export const zPaginationInfoSchema = z.object({ + totalPages: z.int(), + totalItems: z.int(), +}); + /** * GetDealsResponse */ export const zGetDealsResponse = z.object({ deals: z.array(zDealSchema), + paginationInfo: zPaginationInfoSchema, }); /** @@ -348,10 +357,15 @@ export const zUpdateBoardResponse2 = zUpdateBoardResponse; export const zGetDealsData = z.object({ body: z.optional(z.never()), - path: z.object({ - boardId: z.int(), - }), - query: z.optional(z.never()), + path: z.optional(z.never()), + query: z.optional( + z.object({ + boardId: z.optional(z.union([z.int(), z.null()])), + projectId: z.optional(z.union([z.int(), z.null()])), + page: z.optional(z.union([z.int(), z.null()])), + itemsPerPage: z.optional(z.union([z.int(), z.null()])), + }) + ), }); /** diff --git a/yarn.lock b/yarn.lock index eab10b9..d592082 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2875,6 +2875,21 @@ __metadata: languageName: node linkType: hard +"@mantine/dates@npm:^8.2.7": + version: 8.2.7 + resolution: "@mantine/dates@npm:8.2.7" + dependencies: + clsx: "npm:^2.1.1" + peerDependencies: + "@mantine/core": 8.2.7 + "@mantine/hooks": 8.2.7 + dayjs: ">=1.0.0" + react: ^18.x || ^19.x + react-dom: ^18.x || ^19.x + checksum: 10c0/04490d6282b8e8828600f0f29e7197f4ee3b535529cfdefb7ce09ae22c59a38cae77587e95f3ddda92722d5f950e2b10b0648383f4a193bfcfe90de2dd9a219f + languageName: node + linkType: hard + "@mantine/form@npm:^8.1.3": version: 8.2.1 resolution: "@mantine/form@npm:8.2.1" @@ -3693,6 +3708,15 @@ __metadata: languageName: node linkType: hard +"@tanstack/match-sorter-utils@npm:8.19.4": + version: 8.19.4 + resolution: "@tanstack/match-sorter-utils@npm:8.19.4" + dependencies: + remove-accents: "npm:0.5.0" + checksum: 10c0/935022e3d639f19472131d289f3e1202253ff34301717c337e9bac0eeae6a0bd56450ed8ae2f7eb7ac9dfefa7ceaa7d126d8c5441021968b4a9eabc3ac4f8ba1 + languageName: node + linkType: hard + "@tanstack/query-core@npm:5.83.0": version: 5.83.0 resolution: "@tanstack/query-core@npm:5.83.0" @@ -3711,6 +3735,44 @@ __metadata: languageName: node linkType: hard +"@tanstack/react-table@npm:8.20.5": + version: 8.20.5 + resolution: "@tanstack/react-table@npm:8.20.5" + dependencies: + "@tanstack/table-core": "npm:8.20.5" + peerDependencies: + react: ">=16.8" + react-dom: ">=16.8" + checksum: 10c0/574fa62fc6868a3b1113dbd043323f8b73aeb60555609caa164d5137a14636d4502784a961191afde2ec46f33f8c2bbfc4561d27a701c3d084e899a632dda3c8 + languageName: node + linkType: hard + +"@tanstack/react-virtual@npm:3.11.2": + version: 3.11.2 + resolution: "@tanstack/react-virtual@npm:3.11.2" + dependencies: + "@tanstack/virtual-core": "npm:3.11.2" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: 10c0/de446ce517d0855b3d58e79b6a75a37be40b4529baf0a5c3ffa2662dea80aba03409e06545aea27aa9e3a36fc2a2e3005ecbfce16a4659991d66930ea3bd62d4 + languageName: node + linkType: hard + +"@tanstack/table-core@npm:8.20.5": + version: 8.20.5 + resolution: "@tanstack/table-core@npm:8.20.5" + checksum: 10c0/3c27b5debd61b6bd9bfbb40bfc7c5d5af90873ae1a566b20e3bf2d2f4f2e9a78061c081aacc5259a00e256f8df506ec250eb5472f5c01ff04baf9918b554982b + languageName: node + linkType: hard + +"@tanstack/virtual-core@npm:3.11.2": + version: 3.11.2 + resolution: "@tanstack/virtual-core@npm:3.11.2" + checksum: 10c0/38f1047127c6b1d07fe95becb7a12e66fb7c59d37ec0359e4ab339f837c6b906e1adff026ebd12849ba851d3f118d491014205c6b3c6ed8568cc232a798aeaaf + languageName: node + linkType: hard + "@testing-library/dom@npm:10.4.0, @testing-library/dom@npm:^10.4.0": version: 10.4.0 resolution: "@testing-library/dom@npm:10.4.0" @@ -6108,6 +6170,7 @@ __metadata: "@hey-api/openapi-ts": "npm:^0.80.1" "@ianvs/prettier-plugin-sort-imports": "npm:^4.4.2" "@mantine/core": "npm:8.1.2" + "@mantine/dates": "npm:^8.2.7" "@mantine/form": "npm:^8.1.3" "@mantine/hooks": "npm:8.1.2" "@mantine/modals": "npm:^8.2.1" @@ -6138,6 +6201,7 @@ __metadata: classnames: "npm:^2.5.1" date-fns: "npm:^4.1.0" date-fns-tz: "npm:^3.2.0" + dayjs: "npm:^1.11.15" eslint: "npm:^9.29.0" eslint-config-mantine: "npm:^4.0.3" eslint-plugin-eslint-comments: "npm:^3.2.0" @@ -6149,6 +6213,7 @@ __metadata: jest-environment-jsdom: "npm:^30.0.0" lexorank: "npm:^1.0.5" libphonenumber-js: "npm:^1.12.10" + mantine-react-table: "npm:^2.0.0-beta.9" next: "npm:15.3.3" postcss: "npm:^8.5.6" postcss-preset-mantine: "npm:1.17.0" @@ -6364,6 +6429,13 @@ __metadata: languageName: node linkType: hard +"dayjs@npm:^1.11.15": + version: 1.11.15 + resolution: "dayjs@npm:1.11.15" + checksum: 10c0/bb66cd5419fff017f3950b95fc27643cf4e0ce22a087cef1f67398f18126ed07bf36d6911f33b19029a1621c64090b8ecaef660477de7678287fe8c0f4e68d29 + languageName: node + linkType: hard + "debounce@npm:^1.2.1": version: 1.2.1 resolution: "debounce@npm:1.2.1" @@ -10105,6 +10177,26 @@ __metadata: languageName: node linkType: hard +"mantine-react-table@npm:^2.0.0-beta.9": + version: 2.0.0-beta.9 + resolution: "mantine-react-table@npm:2.0.0-beta.9" + dependencies: + "@tanstack/match-sorter-utils": "npm:8.19.4" + "@tanstack/react-table": "npm:8.20.5" + "@tanstack/react-virtual": "npm:3.11.2" + peerDependencies: + "@mantine/core": ^7.9 + "@mantine/dates": ^7.9 + "@mantine/hooks": ^7.9 + "@tabler/icons-react": ">=2.23.0" + clsx: ">=2" + dayjs: ">=1.11" + react: ">=18.0" + react-dom: ">=18.0" + checksum: 10c0/8a560096d4a6ecc3f0eb16ea171c3d2589125f53152e0ed8ac1853977b6fa35994cf7b4f553b92b9b0333010805f8c0e42f002330408925cbc8050b03528df0b + languageName: node + linkType: hard + "map-or-similar@npm:^1.5.0": version: 1.5.0 resolution: "map-or-similar@npm:1.5.0" @@ -12009,6 +12101,13 @@ __metadata: languageName: node linkType: hard +"remove-accents@npm:0.5.0": + version: 0.5.0 + resolution: "remove-accents@npm:0.5.0" + checksum: 10c0/a75321aa1b53d9abe82637115a492770bfe42bb38ed258be748bf6795871202bc8b4badff22013494a7029f5a241057ad8d3f72adf67884dbe15a9e37e87adc4 + languageName: node + linkType: hard + "renderkid@npm:^3.0.0": version: 3.0.0 resolution: "renderkid@npm:3.0.0"