feat: deals table
This commit is contained in:
@@ -8,6 +8,7 @@ export type DealSummary = {
|
|||||||
name: string;
|
name: string;
|
||||||
clientName: string;
|
clientName: string;
|
||||||
changedAt: string;
|
changedAt: string;
|
||||||
|
createdAt: string;
|
||||||
deadline: string;
|
deadline: string;
|
||||||
status: number;
|
status: number;
|
||||||
totalPrice: number;
|
totalPrice: number;
|
||||||
|
|||||||
@@ -134,10 +134,20 @@ export class DealService {
|
|||||||
* @returns DealSummaryResponse Successful Response
|
* @returns DealSummaryResponse Successful Response
|
||||||
* @throws ApiError
|
* @throws ApiError
|
||||||
*/
|
*/
|
||||||
public static getDealSummaries(): CancelablePromise<DealSummaryResponse> {
|
public static getDealSummaries({
|
||||||
|
full,
|
||||||
|
}: {
|
||||||
|
full: (boolean | null),
|
||||||
|
}): CancelablePromise<DealSummaryResponse> {
|
||||||
return __request(OpenAPI, {
|
return __request(OpenAPI, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: '/deal/summaries',
|
url: '/deal/summaries',
|
||||||
|
query: {
|
||||||
|
'full': full,
|
||||||
|
},
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2,13 +2,15 @@ import {Center, Flex, Image, rem, Stack, Tooltip, UnstyledButton, useMantineColo
|
|||||||
import {
|
import {
|
||||||
IconBarcode,
|
IconBarcode,
|
||||||
IconBox,
|
IconBox,
|
||||||
IconCash, IconDashboard,
|
IconCash,
|
||||||
|
IconDashboard,
|
||||||
IconFileBarcode,
|
IconFileBarcode,
|
||||||
IconHome2,
|
IconHome2,
|
||||||
IconLogout,
|
IconLogout,
|
||||||
IconMan,
|
IconMan,
|
||||||
IconMoon,
|
IconMoon,
|
||||||
IconSun,
|
IconSun,
|
||||||
|
IconTable,
|
||||||
} from '@tabler/icons-react';
|
} from '@tabler/icons-react';
|
||||||
import classes from './Navbar.module.css';
|
import classes from './Navbar.module.css';
|
||||||
import {useAppDispatch} from "../../redux/store.ts";
|
import {useAppDispatch} from "../../redux/store.ts";
|
||||||
@@ -40,16 +42,17 @@ function NavbarLink(props: NavbarLinkProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const mockdata = [
|
const mockdata = [
|
||||||
// {
|
|
||||||
// icon: IconHome2,
|
|
||||||
// label: 'Главная',
|
|
||||||
// href: '/'
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
icon: IconCash,
|
icon: IconCash,
|
||||||
label: 'Сделки',
|
label: 'Сделки',
|
||||||
href: '/leads'
|
href: '/leads'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
icon: IconTable,
|
||||||
|
label: 'Таблица сделок',
|
||||||
|
href: '/deals'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
icon: IconMan,
|
icon: IconMan,
|
||||||
label: 'Клиенты',
|
label: 'Клиенты',
|
||||||
|
|||||||
@@ -26,10 +26,12 @@ type RestProps<T> = {
|
|||||||
filterBy?: (item: SelectObjectType<T>) => boolean;
|
filterBy?: (item: SelectObjectType<T>) => boolean;
|
||||||
};
|
};
|
||||||
const defaultGetLabelFn = <T extends { name: string }>(item: T): string => {
|
const defaultGetLabelFn = <T extends { name: string }>(item: T): string => {
|
||||||
|
|
||||||
return item.name;
|
return item.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultGetValueFn = <T extends { id: number }>(item: T): string => {
|
const defaultGetValueFn = <T extends { id: number }>(item: T): string => {
|
||||||
|
if (!item) return item;
|
||||||
return item.id.toString();
|
return item.id.toString();
|
||||||
}
|
}
|
||||||
export type ObjectSelectProps<T> =
|
export type ObjectSelectProps<T> =
|
||||||
@@ -85,6 +87,7 @@ const ObjectSelect = <T, >(props: ObjectSelectProps<T>) => {
|
|||||||
if (isControlled || !internalValue) return;
|
if (isControlled || !internalValue) return;
|
||||||
props.onChange(internalValue);
|
props.onChange(internalValue);
|
||||||
}, [internalValue]);
|
}, [internalValue]);
|
||||||
|
|
||||||
const restProps = omit(props, ['filterBy', 'groupBy', 'getValueFn', 'getLabelFn']);
|
const restProps = omit(props, ['filterBy', 'groupBy', 'getValueFn', 'getLabelFn']);
|
||||||
return (
|
return (
|
||||||
<Select
|
<Select
|
||||||
|
|||||||
17
src/components/Selects/ClientSelectNew/ClientSelectNew.tsx
Normal file
17
src/components/Selects/ClientSelectNew/ClientSelectNew.tsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import ObjectSelect, {ObjectSelectProps} from "../../ObjectSelect/ObjectSelect.tsx";
|
||||||
|
import {ClientSchema} from "../../../client";
|
||||||
|
import {FC} from "react";
|
||||||
|
import useClientsList from "../../../pages/ClientsPage/hooks/useClientsList.tsx";
|
||||||
|
|
||||||
|
type Props = Omit<ObjectSelectProps<ClientSchema>, 'data'>
|
||||||
|
|
||||||
|
const ClientSelectNew: FC<Props> = (props) => {
|
||||||
|
const {clients} = useClientsList();
|
||||||
|
return (
|
||||||
|
<ObjectSelect
|
||||||
|
data={clients}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default ClientSelectNew;
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import ObjectSelect, {ObjectSelectProps} from "../../../../components/ObjectSelect/ObjectSelect.tsx";
|
||||||
|
import {FC} from "react";
|
||||||
|
import {DealStatuses} from "../../../../shared/enums/DealStatus.ts";
|
||||||
|
|
||||||
|
type DealStatus = {
|
||||||
|
name: string;
|
||||||
|
id: number
|
||||||
|
}
|
||||||
|
type Props = Omit<ObjectSelectProps<DealStatus>, 'data'>;
|
||||||
|
|
||||||
|
const DealStatusSelect: FC<Props> = (props) => {
|
||||||
|
const data: DealStatus[] = DealStatuses;
|
||||||
|
return (
|
||||||
|
<ObjectSelect
|
||||||
|
data={data}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default DealStatusSelect;
|
||||||
49
src/pages/DealsPage/components/DealsTable/DealsTable.tsx
Normal file
49
src/pages/DealsPage/components/DealsTable/DealsTable.tsx
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import {CRUDTableProps} from "../../../../types/CRUDTable.tsx";
|
||||||
|
import {DealService, DealSummary} from "../../../../client";
|
||||||
|
import {FC} from "react";
|
||||||
|
import useDealsTableColumns from "./columns.tsx";
|
||||||
|
import {BaseTable} from "../../../../components/BaseTable/BaseTable.tsx";
|
||||||
|
import {ActionIcon, Flex, Tooltip} from "@mantine/core";
|
||||||
|
import {IconEdit} from "@tabler/icons-react";
|
||||||
|
import {MRT_TableOptions} from "mantine-react-table";
|
||||||
|
import {useDealPageContext} from "../../../LeadsPage/contexts/DealPageContext.tsx";
|
||||||
|
|
||||||
|
type Props = CRUDTableProps<DealSummary>;
|
||||||
|
|
||||||
|
const DealsTable: FC<Props> = ({items}) => {
|
||||||
|
const columns = useDealsTableColumns();
|
||||||
|
const {setSelectedDeal} = useDealPageContext();
|
||||||
|
const onEditClick = (dealSummary: DealSummary) => {
|
||||||
|
DealService.getDealById({dealId: dealSummary.id})
|
||||||
|
.then((deal) => {
|
||||||
|
setSelectedDeal(deal);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<BaseTable
|
||||||
|
data={items}
|
||||||
|
columns={columns}
|
||||||
|
restProps={{
|
||||||
|
enableSorting: true,
|
||||||
|
enableColumnActions: false,
|
||||||
|
enablePagination: true,
|
||||||
|
enableBottomToolbar: true,
|
||||||
|
paginationDisplayMode: "pages",
|
||||||
|
enableRowActions: true,
|
||||||
|
renderRowActions: ({row}) => (
|
||||||
|
<Flex gap="md">
|
||||||
|
<Tooltip label="Редактировать">
|
||||||
|
<ActionIcon
|
||||||
|
onClick={() => onEditClick(row.original)}
|
||||||
|
variant={"default"}>
|
||||||
|
<IconEdit/>
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
</Flex>
|
||||||
|
)
|
||||||
|
} as MRT_TableOptions<DealSummary>}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DealsTable;
|
||||||
50
src/pages/DealsPage/components/DealsTable/columns.tsx
Normal file
50
src/pages/DealsPage/components/DealsTable/columns.tsx
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import {useMemo} from "react";
|
||||||
|
import {MRT_ColumnDef} from "mantine-react-table";
|
||||||
|
import {DealSummary} from "../../../../client";
|
||||||
|
import {ActionIcon, Image} from "@mantine/core";
|
||||||
|
|
||||||
|
const useDealsTableColumns = () => {
|
||||||
|
return useMemo<MRT_ColumnDef<DealSummary>[]>(() => [
|
||||||
|
|
||||||
|
{
|
||||||
|
header: "Маркетплейс",
|
||||||
|
size: 10,
|
||||||
|
Cell: ({row}) => (
|
||||||
|
<ActionIcon variant={"transparent"}>
|
||||||
|
<Image src={row.original.baseMarketplace?.iconUrl || ""}/>
|
||||||
|
</ActionIcon>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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())
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "name",
|
||||||
|
header: "Название",
|
||||||
|
enableSorting: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "clientName",
|
||||||
|
header: "Клиент",
|
||||||
|
enableSorting: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Cell: ({row}) => (new Date(row.original.deadline)).toLocaleString("ru-RU"),
|
||||||
|
accessorKey: "deadline",
|
||||||
|
header: "Дедлайн",
|
||||||
|
sortingFn: (rowA, rowB) => ((new Date(rowB.original.deadline)).getTime() - (new Date(rowA.original.deadline)).getTime())
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: "Общая стоимость",
|
||||||
|
Cell: ({row}) => (row.original.totalPrice).toLocaleString("ru-RU") + '₽',
|
||||||
|
accessorKey:"totalPrice"
|
||||||
|
}
|
||||||
|
], [])
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useDealsTableColumns;
|
||||||
1
src/pages/DealsPage/index.ts
Normal file
1
src/pages/DealsPage/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export {DealsPage} from './ui/DealsPage.tsx';
|
||||||
27
src/pages/DealsPage/ui/DealsPage.module.css
Normal file
27
src/pages/DealsPage/ui/DealsPage.module.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
gap: rem(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.body-container {
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-panel {
|
||||||
|
padding: rem(5);
|
||||||
|
gap: rem(10);
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
display: flex;
|
||||||
|
gap: rem(10);
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-pagination {
|
||||||
|
align-self: flex-end;
|
||||||
|
|
||||||
|
}
|
||||||
89
src/pages/DealsPage/ui/DealsPage.tsx
Normal file
89
src/pages/DealsPage/ui/DealsPage.tsx
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
import {FC, useEffect, useState} from "react";
|
||||||
|
import PageBlock from "../../../components/PageBlock/PageBlock.tsx";
|
||||||
|
import styles from './DealsPage.module.css';
|
||||||
|
import DealStatusSelect from "../components/DealStatusSelect/DealStatusSelect.tsx";
|
||||||
|
import DealsTable from "../components/DealsTable/DealsTable.tsx";
|
||||||
|
import {useDealSummariesFull} from "../../LeadsPage/hooks/useDealSummaries.tsx";
|
||||||
|
import {DealStatusType} from "../../../shared/enums/DealStatus.ts";
|
||||||
|
import {BaseMarketplaceSchema, ClientSchema} from "../../../client";
|
||||||
|
import BaseMarketplaceSelect from "../../../components/Selects/BaseMarketplaceSelect/BaseMarketplaceSelect.tsx";
|
||||||
|
import {useForm} from "@mantine/form";
|
||||||
|
import ClientSelectNew from "../../../components/Selects/ClientSelectNew/ClientSelectNew.tsx";
|
||||||
|
import {DealPageContextProvider} from "../../LeadsPage/contexts/DealPageContext.tsx";
|
||||||
|
import DealEditDrawer from "../../LeadsPage/drawers/DealEditDrawer/DealEditDrawer.tsx";
|
||||||
|
|
||||||
|
type State = {
|
||||||
|
marketplace: BaseMarketplaceSchema | null;
|
||||||
|
dealStatus: DealStatusType | null;
|
||||||
|
client: ClientSchema | null;
|
||||||
|
}
|
||||||
|
export const DealsPage: FC = () => {
|
||||||
|
const {objects} = useDealSummariesFull();
|
||||||
|
const form = useForm<State>({
|
||||||
|
initialValues: {
|
||||||
|
marketplace: null,
|
||||||
|
dealStatus: null,
|
||||||
|
client: null
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const [data, setData] = useState(objects);
|
||||||
|
const applyFilters = () => {
|
||||||
|
let result = objects;
|
||||||
|
if (form.values.marketplace) {
|
||||||
|
result = result.filter(obj => obj.baseMarketplace?.key === form.values.marketplace?.key);
|
||||||
|
}
|
||||||
|
if (form.values.dealStatus) {
|
||||||
|
result = result.filter(obj => obj.status === form.values.dealStatus?.id);
|
||||||
|
}
|
||||||
|
if (form.values.client) {
|
||||||
|
result = result.filter(obj => obj.clientName === form.values.client?.name);
|
||||||
|
|
||||||
|
}
|
||||||
|
setData(result);
|
||||||
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
applyFilters();
|
||||||
|
}, [form.values, objects])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<DealPageContextProvider>
|
||||||
|
<div className={styles['container']}>
|
||||||
|
<PageBlock>
|
||||||
|
<div className={styles['top-panel']}>
|
||||||
|
<DealStatusSelect
|
||||||
|
onClear={() => form.setFieldValue("dealStatus", null)}
|
||||||
|
clearable
|
||||||
|
placeholder={"Выберите статус "}
|
||||||
|
{...form.getInputProps("dealStatus")}
|
||||||
|
/>
|
||||||
|
<BaseMarketplaceSelect
|
||||||
|
onClear={() => form.setFieldValue("marketplace", null)}
|
||||||
|
clearable
|
||||||
|
|
||||||
|
placeholder={"Выберите маркетплейс"}
|
||||||
|
{...form.getInputProps("marketplace")}
|
||||||
|
/>
|
||||||
|
<ClientSelectNew
|
||||||
|
onClear={() => form.setFieldValue("client", null)}
|
||||||
|
clearable
|
||||||
|
searchable
|
||||||
|
placeholder={"Выберите клиента"}
|
||||||
|
{...form.getInputProps("client")}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</PageBlock>
|
||||||
|
<PageBlock>
|
||||||
|
<div className={styles['body-container']}>
|
||||||
|
<div className={styles['table-container']}>
|
||||||
|
<DealsTable items={data}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</PageBlock>
|
||||||
|
</div>
|
||||||
|
<DealEditDrawer
|
||||||
|
/>
|
||||||
|
</DealPageContextProvider>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
import {useQuery} from "@tanstack/react-query";
|
import {useQuery} from "@tanstack/react-query";
|
||||||
import {DealService} from "../../../client";
|
import {DealService} from "../../../client";
|
||||||
|
import ObjectList from "../../../hooks/objectList.tsx";
|
||||||
|
|
||||||
export const useDealSummaries = () => {
|
export const useDealSummaries = () => {
|
||||||
const {data: summariesRaw = [], refetch} = useQuery({
|
const {data: summariesRaw = [], refetch} = useQuery({
|
||||||
queryKey: ['getDealSummaries'],
|
queryKey: ['getDealSummaries'],
|
||||||
queryFn: DealService.getDealSummaries,
|
queryFn: () => DealService.getDealSummaries({full: false}),
|
||||||
select: data => data.summaries || [] // Трансформируем полученные данные
|
select: data => data.summaries || [] // Трансформируем полученные данные
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -12,4 +13,9 @@ export const useDealSummaries = () => {
|
|||||||
// isLoading и isError могут быть использованы для отображения индикаторов загрузки или ошибки
|
// isLoading и isError могут быть использованы для отображения индикаторов загрузки или ошибки
|
||||||
|
|
||||||
return {summariesRaw, refetch};
|
return {summariesRaw, refetch};
|
||||||
}
|
}
|
||||||
|
export const useDealSummariesFull = () => ObjectList({
|
||||||
|
queryFn: () => DealService.getDealSummaries({full: true}),
|
||||||
|
queryKey: "getDealSummariesFull",
|
||||||
|
getObjectsFn: response => response.summaries
|
||||||
|
});
|
||||||
@@ -22,6 +22,7 @@ const ServicesLazyImport = createFileRoute('/services')()
|
|||||||
const ProductsLazyImport = createFileRoute('/products')()
|
const ProductsLazyImport = createFileRoute('/products')()
|
||||||
const LoginLazyImport = createFileRoute('/login')()
|
const LoginLazyImport = createFileRoute('/login')()
|
||||||
const LeadsLazyImport = createFileRoute('/leads')()
|
const LeadsLazyImport = createFileRoute('/leads')()
|
||||||
|
const DealsLazyImport = createFileRoute('/deals')()
|
||||||
const ClientsLazyImport = createFileRoute('/clients')()
|
const ClientsLazyImport = createFileRoute('/clients')()
|
||||||
const BarcodeLazyImport = createFileRoute('/barcode')()
|
const BarcodeLazyImport = createFileRoute('/barcode')()
|
||||||
const AdminLazyImport = createFileRoute('/admin')()
|
const AdminLazyImport = createFileRoute('/admin')()
|
||||||
@@ -54,6 +55,11 @@ const LeadsLazyRoute = LeadsLazyImport.update({
|
|||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => rootRoute,
|
||||||
} as any).lazy(() => import('./routes/leads.lazy').then((d) => d.Route))
|
} as any).lazy(() => import('./routes/leads.lazy').then((d) => d.Route))
|
||||||
|
|
||||||
|
const DealsLazyRoute = DealsLazyImport.update({
|
||||||
|
path: '/deals',
|
||||||
|
getParentRoute: () => rootRoute,
|
||||||
|
} as any).lazy(() => import('./routes/deals.lazy').then((d) => d.Route))
|
||||||
|
|
||||||
const ClientsLazyRoute = ClientsLazyImport.update({
|
const ClientsLazyRoute = ClientsLazyImport.update({
|
||||||
path: '/clients',
|
path: '/clients',
|
||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => rootRoute,
|
||||||
@@ -75,8 +81,8 @@ const IndexLazyRoute = IndexLazyImport.update({
|
|||||||
} as any).lazy(() => import('./routes/index.lazy').then((d) => d.Route))
|
} as any).lazy(() => import('./routes/index.lazy').then((d) => d.Route))
|
||||||
|
|
||||||
const DealsDealIdRoute = DealsDealIdImport.update({
|
const DealsDealIdRoute = DealsDealIdImport.update({
|
||||||
path: '/deals/$dealId',
|
path: '/$dealId',
|
||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => DealsLazyRoute,
|
||||||
} as any)
|
} as any)
|
||||||
|
|
||||||
// Populate the FileRoutesByPath interface
|
// Populate the FileRoutesByPath interface
|
||||||
@@ -111,6 +117,13 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof ClientsLazyImport
|
preLoaderRoute: typeof ClientsLazyImport
|
||||||
parentRoute: typeof rootRoute
|
parentRoute: typeof rootRoute
|
||||||
}
|
}
|
||||||
|
'/deals': {
|
||||||
|
id: '/deals'
|
||||||
|
path: '/deals'
|
||||||
|
fullPath: '/deals'
|
||||||
|
preLoaderRoute: typeof DealsLazyImport
|
||||||
|
parentRoute: typeof rootRoute
|
||||||
|
}
|
||||||
'/leads': {
|
'/leads': {
|
||||||
id: '/leads'
|
id: '/leads'
|
||||||
path: '/leads'
|
path: '/leads'
|
||||||
@@ -148,10 +161,10 @@ declare module '@tanstack/react-router' {
|
|||||||
}
|
}
|
||||||
'/deals/$dealId': {
|
'/deals/$dealId': {
|
||||||
id: '/deals/$dealId'
|
id: '/deals/$dealId'
|
||||||
path: '/deals/$dealId'
|
path: '/$dealId'
|
||||||
fullPath: '/deals/$dealId'
|
fullPath: '/deals/$dealId'
|
||||||
preLoaderRoute: typeof DealsDealIdImport
|
preLoaderRoute: typeof DealsDealIdImport
|
||||||
parentRoute: typeof rootRoute
|
parentRoute: typeof DealsLazyImport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -163,12 +176,12 @@ export const routeTree = rootRoute.addChildren({
|
|||||||
AdminLazyRoute,
|
AdminLazyRoute,
|
||||||
BarcodeLazyRoute,
|
BarcodeLazyRoute,
|
||||||
ClientsLazyRoute,
|
ClientsLazyRoute,
|
||||||
|
DealsLazyRoute: DealsLazyRoute.addChildren({ DealsDealIdRoute }),
|
||||||
LeadsLazyRoute,
|
LeadsLazyRoute,
|
||||||
LoginLazyRoute,
|
LoginLazyRoute,
|
||||||
ProductsLazyRoute,
|
ProductsLazyRoute,
|
||||||
ServicesLazyRoute,
|
ServicesLazyRoute,
|
||||||
TestLazyRoute,
|
TestLazyRoute,
|
||||||
DealsDealIdRoute,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
/* prettier-ignore-end */
|
/* prettier-ignore-end */
|
||||||
@@ -183,12 +196,12 @@ export const routeTree = rootRoute.addChildren({
|
|||||||
"/admin",
|
"/admin",
|
||||||
"/barcode",
|
"/barcode",
|
||||||
"/clients",
|
"/clients",
|
||||||
|
"/deals",
|
||||||
"/leads",
|
"/leads",
|
||||||
"/login",
|
"/login",
|
||||||
"/products",
|
"/products",
|
||||||
"/services",
|
"/services",
|
||||||
"/test",
|
"/test"
|
||||||
"/deals/$dealId"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"/": {
|
"/": {
|
||||||
@@ -203,6 +216,12 @@ export const routeTree = rootRoute.addChildren({
|
|||||||
"/clients": {
|
"/clients": {
|
||||||
"filePath": "clients.lazy.tsx"
|
"filePath": "clients.lazy.tsx"
|
||||||
},
|
},
|
||||||
|
"/deals": {
|
||||||
|
"filePath": "deals.lazy.tsx",
|
||||||
|
"children": [
|
||||||
|
"/deals/$dealId"
|
||||||
|
]
|
||||||
|
},
|
||||||
"/leads": {
|
"/leads": {
|
||||||
"filePath": "leads.lazy.tsx"
|
"filePath": "leads.lazy.tsx"
|
||||||
},
|
},
|
||||||
@@ -219,7 +238,8 @@ export const routeTree = rootRoute.addChildren({
|
|||||||
"filePath": "test.lazy.tsx"
|
"filePath": "test.lazy.tsx"
|
||||||
},
|
},
|
||||||
"/deals/$dealId": {
|
"/deals/$dealId": {
|
||||||
"filePath": "deals.$dealId.tsx"
|
"filePath": "deals.$dealId.tsx",
|
||||||
|
"parent": "/deals"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
6
src/routes/deals.lazy.tsx
Normal file
6
src/routes/deals.lazy.tsx
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import {createLazyFileRoute} from '@tanstack/react-router'
|
||||||
|
import {DealsPage} from "../pages/DealsPage";
|
||||||
|
|
||||||
|
export const Route = createLazyFileRoute('/deals')({
|
||||||
|
component: DealsPage
|
||||||
|
})
|
||||||
@@ -19,4 +19,11 @@ export const DealStatusDictionary = {
|
|||||||
[DealStatus.AWAITING_PAYMENT]: "Ожидает оплаты",
|
[DealStatus.AWAITING_PAYMENT]: "Ожидает оплаты",
|
||||||
[DealStatus.COMPLETED]: "Завершена",
|
[DealStatus.COMPLETED]: "Завершена",
|
||||||
[DealStatus.CANCELLED]: "Отменена",
|
[DealStatus.CANCELLED]: "Отменена",
|
||||||
}
|
}
|
||||||
|
export type DealStatusType = {
|
||||||
|
id: number,
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
export const DealStatuses: DealStatusType[] = Object.entries(DealStatusDictionary).map(([key, value]) => {
|
||||||
|
return {id: parseInt(key), name: value}
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user