feat: styles for deal drawer
This commit is contained in:
@ -1,6 +0,0 @@
|
|||||||
.container {
|
|
||||||
width: min-content;
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 6px;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
import { FC, PropsWithChildren } from "react";
|
|
||||||
import { ActionIcon, Box } from "@mantine/core";
|
|
||||||
import style from "./ToolPanelAction.module.css";
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
onClick: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const ToolPanelAction: FC<PropsWithChildren<Props>> = ({
|
|
||||||
onClick,
|
|
||||||
children,
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<Box>
|
|
||||||
<ActionIcon
|
|
||||||
variant={"default"}
|
|
||||||
onClick={onClick}
|
|
||||||
radius="lg"
|
|
||||||
className={style.container}>
|
|
||||||
{children}
|
|
||||||
</ActionIcon>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ToolPanelAction;
|
|
||||||
@ -4,12 +4,12 @@ import { FC } from "react";
|
|||||||
import { IconEdit, IconFilter, IconPlus } from "@tabler/icons-react";
|
import { IconEdit, IconFilter, IconPlus } from "@tabler/icons-react";
|
||||||
import { Flex, Group, Indicator } from "@mantine/core";
|
import { Flex, Group, Indicator } from "@mantine/core";
|
||||||
import { modals } from "@mantine/modals";
|
import { modals } from "@mantine/modals";
|
||||||
import ToolPanelAction from "@/app/deals/components/desktop/ToolPanelAction/ToolPanelAction";
|
|
||||||
import ViewSelector from "@/app/deals/components/desktop/ViewSelector/ViewSelector";
|
import ViewSelector from "@/app/deals/components/desktop/ViewSelector/ViewSelector";
|
||||||
import { useDealsContext } from "@/app/deals/contexts/DealsContext";
|
import { useDealsContext } from "@/app/deals/contexts/DealsContext";
|
||||||
import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext";
|
import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext";
|
||||||
import { DealsFiltersForm } from "@/app/deals/hooks/useDealsFilters";
|
import { DealsFiltersForm } from "@/app/deals/hooks/useDealsFilters";
|
||||||
import ProjectSelect from "@/components/selects/ProjectSelect/ProjectSelect";
|
import ProjectSelect from "@/components/selects/ProjectSelect/ProjectSelect";
|
||||||
|
import ActionIconWithTip from "@/components/ui/ActionIconWithTip/ActionIconWithTip";
|
||||||
import { useDrawersContext } from "@/drawers/DrawersContext";
|
import { useDrawersContext } from "@/drawers/DrawersContext";
|
||||||
import useIsMobile from "@/hooks/utils/useIsMobile";
|
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||||
|
|
||||||
@ -89,16 +89,16 @@ const TopToolPanel: FC<Props> = ({ view, setView }) => {
|
|||||||
disabled={!isChangedFilters}
|
disabled={!isChangedFilters}
|
||||||
offset={3}
|
offset={3}
|
||||||
size={8}>
|
size={8}>
|
||||||
<ToolPanelAction onClick={onFiltersClick}>
|
<ActionIconWithTip onClick={onFiltersClick}>
|
||||||
<IconFilter />
|
<IconFilter />
|
||||||
</ToolPanelAction>
|
</ActionIconWithTip>
|
||||||
</Indicator>
|
</Indicator>
|
||||||
<ToolPanelAction onClick={onEditClick}>
|
<ActionIconWithTip onClick={onEditClick}>
|
||||||
<IconEdit />
|
<IconEdit />
|
||||||
</ToolPanelAction>
|
</ActionIconWithTip>
|
||||||
<ToolPanelAction onClick={onCreateClick}>
|
<ActionIconWithTip onClick={onCreateClick}>
|
||||||
<IconPlus />
|
<IconPlus />
|
||||||
</ToolPanelAction>
|
</ActionIconWithTip>
|
||||||
<ProjectSelect
|
<ProjectSelect
|
||||||
data={projects}
|
data={projects}
|
||||||
value={selectedProject}
|
value={selectedProject}
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
|
|
||||||
.tab {
|
.tab {
|
||||||
|
@media (max-width: 48em) {
|
||||||
border-bottom-width: 3px;
|
border-bottom-width: 3px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-board {
|
.header-board {
|
||||||
|
|||||||
@ -25,7 +25,7 @@ const DealEditorDrawer: FC<DrawerProps<Props>> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Drawer
|
<Drawer
|
||||||
size={isMobile ? "100%" : "60%"}
|
size={isMobile ? "100%" : "80%"}
|
||||||
position={"right"}
|
position={"right"}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
removeScrollProps={{ allowPinchZoom: true }}
|
removeScrollProps={{ allowPinchZoom: true }}
|
||||||
@ -37,7 +37,8 @@ const DealEditorDrawer: FC<DrawerProps<Props>> = ({
|
|||||||
body: {
|
body: {
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
padding: 0,
|
padding: isMobile ? 0 : "var(--mantine-spacing-xs)",
|
||||||
|
height: "100vh",
|
||||||
},
|
},
|
||||||
header: {
|
header: {
|
||||||
paddingBlock: 0,
|
paddingBlock: 0,
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { IconEdit } from "@tabler/icons-react";
|
|||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import { Box, Tabs } from "@mantine/core";
|
import { Box, Tabs } from "@mantine/core";
|
||||||
import GeneralTab from "@/app/deals/drawers/DealEditorDrawer/tabs/GeneralTab/GeneralTab";
|
import GeneralTab from "@/app/deals/drawers/DealEditorDrawer/tabs/GeneralTab/GeneralTab";
|
||||||
|
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||||
import { DealSchema, ProjectSchema } from "@/lib/client";
|
import { DealSchema, ProjectSchema } from "@/lib/client";
|
||||||
import { MODULES } from "@/modules/modules";
|
import { MODULES } from "@/modules/modules";
|
||||||
import styles from "../DealEditorDrawer.module.css";
|
import styles from "../DealEditorDrawer.module.css";
|
||||||
@ -15,6 +16,8 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const DealEditorBody: FC<Props> = props => {
|
const DealEditorBody: FC<Props> = props => {
|
||||||
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
const getTabPanel = (value: string, component: ReactNode): ReactNode => (
|
const getTabPanel = (value: string, component: ReactNode): ReactNode => (
|
||||||
<Tabs.Panel
|
<Tabs.Panel
|
||||||
key={value}
|
key={value}
|
||||||
@ -53,6 +56,8 @@ const DealEditorBody: FC<Props> = props => {
|
|||||||
return (
|
return (
|
||||||
<Tabs
|
<Tabs
|
||||||
defaultValue="general"
|
defaultValue="general"
|
||||||
|
orientation={isMobile ? "horizontal" : "vertical"}
|
||||||
|
h={"100%"}
|
||||||
classNames={{ tab: styles.tab }}>
|
classNames={{ tab: styles.tab }}>
|
||||||
<Tabs.List>
|
<Tabs.List>
|
||||||
<Tabs.Tab
|
<Tabs.Tab
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import React, { FC } from "react";
|
import React, { FC } from "react";
|
||||||
import { Stack, Text, TextInput } from "@mantine/core";
|
import { Flex, Stack, TextInput } from "@mantine/core";
|
||||||
import { useForm } from "@mantine/form";
|
import { useForm } from "@mantine/form";
|
||||||
import Footer from "@/app/deals/drawers/DealEditorDrawer/tabs/GeneralTab/components/Footer";
|
import Footer from "@/app/deals/drawers/DealEditorDrawer/tabs/GeneralTab/components/Footer";
|
||||||
import BoardSelect from "@/components/selects/BoardSelect/BoardSelect";
|
import BoardSelect from "@/components/selects/BoardSelect/BoardSelect";
|
||||||
@ -40,13 +40,26 @@ const GeneralTab: FC<Props> = ({ value, onDelete, onChange }) => {
|
|||||||
return (
|
return (
|
||||||
<form onSubmit={form.onSubmit(onSubmit)}>
|
<form onSubmit={form.onSubmit(onSubmit)}>
|
||||||
<Stack p={"md"}>
|
<Stack p={"md"}>
|
||||||
|
<Flex
|
||||||
|
gap={"md"}
|
||||||
|
w={"100%"}
|
||||||
|
direction={{ base: "column", sm: "row" }}>
|
||||||
<TextInput
|
<TextInput
|
||||||
label={"Название"}
|
label={"Название"}
|
||||||
{...form.getInputProps("name")}
|
{...form.getInputProps("name")}
|
||||||
|
flex={1}
|
||||||
/>
|
/>
|
||||||
<Text>
|
<TextInput
|
||||||
Создано: {utcDateTimeToLocalString(value.createdAt)}
|
label={"Дата создания"}
|
||||||
</Text>
|
value={utcDateTimeToLocalString(value.createdAt)}
|
||||||
|
readOnly
|
||||||
|
flex={1}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
<Flex
|
||||||
|
gap={"md"}
|
||||||
|
w={"100%"}
|
||||||
|
direction={{ base: "column", sm: "row" }}>
|
||||||
<BoardSelect
|
<BoardSelect
|
||||||
label={"Доска"}
|
label={"Доска"}
|
||||||
{...form.getInputProps("board")}
|
{...form.getInputProps("board")}
|
||||||
@ -55,12 +68,15 @@ const GeneralTab: FC<Props> = ({ value, onDelete, onChange }) => {
|
|||||||
form.setFieldValue("status", undefined);
|
form.setFieldValue("status", undefined);
|
||||||
}}
|
}}
|
||||||
projectId={value.board.projectId}
|
projectId={value.board.projectId}
|
||||||
|
flex={1}
|
||||||
/>
|
/>
|
||||||
<StatusSelect
|
<StatusSelect
|
||||||
label={"Статус"}
|
label={"Статус"}
|
||||||
{...form.getInputProps("status")}
|
{...form.getInputProps("status")}
|
||||||
boardId={form.values.board?.id}
|
boardId={form.values.board?.id}
|
||||||
|
flex={1}
|
||||||
/>
|
/>
|
||||||
|
</Flex>
|
||||||
<Footer
|
<Footer
|
||||||
form={form}
|
form={form}
|
||||||
onDelete={() => onDelete(value)}
|
onDelete={() => onDelete(value)}
|
||||||
|
|||||||
@ -0,0 +1,5 @@
|
|||||||
|
.container {
|
||||||
|
cursor: pointer;
|
||||||
|
min-height: calc(var(--mantine-spacing-md) + var(--mantine-spacing-lg));
|
||||||
|
min-width: calc(var(--mantine-spacing-md) + var(--mantine-spacing-lg));
|
||||||
|
}
|
||||||
34
src/components/ui/ActionIconWithTip/ActionIconWithTip.tsx
Normal file
34
src/components/ui/ActionIconWithTip/ActionIconWithTip.tsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { FC, PropsWithChildren } from "react";
|
||||||
|
import {
|
||||||
|
ActionIcon,
|
||||||
|
ActionIconProps,
|
||||||
|
PolymorphicComponentProps,
|
||||||
|
Tooltip,
|
||||||
|
} from "@mantine/core";
|
||||||
|
import style from "./ActionIconWithTip.module.css";
|
||||||
|
|
||||||
|
type Props = PolymorphicComponentProps<"button", ActionIconProps> & {
|
||||||
|
tipLabel?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ActionIconWithTip: FC<PropsWithChildren<Props>> = ({
|
||||||
|
children,
|
||||||
|
tipLabel,
|
||||||
|
...props
|
||||||
|
}) => (
|
||||||
|
<Tooltip
|
||||||
|
label={tipLabel}
|
||||||
|
hidden={!tipLabel}
|
||||||
|
h={"max-content"}
|
||||||
|
w={"max-content"}>
|
||||||
|
<ActionIcon
|
||||||
|
variant={"default"}
|
||||||
|
radius={"lg"}
|
||||||
|
className={style.container}
|
||||||
|
{...props}>
|
||||||
|
{children}
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default ActionIconWithTip;
|
||||||
11
src/components/ui/BaseTable/BaseTable.module.css
Normal file
11
src/components/ui/BaseTable/BaseTable.module.css
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
.table-border {
|
||||||
|
border-width: 1px;
|
||||||
|
border-radius: var(--mantine-radius-lg);
|
||||||
|
@mixin light {
|
||||||
|
border-color: var(--mantine-color-gray-4);
|
||||||
|
}
|
||||||
|
@mixin dark {
|
||||||
|
border-color: var(--mantine-color-dark-4);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,14 +1,18 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import classNames from "classnames";
|
||||||
import { DataTable, DataTableProps } from "mantine-datatable";
|
import { DataTable, DataTableProps } from "mantine-datatable";
|
||||||
|
import styles from "./BaseTable.module.css";
|
||||||
|
|
||||||
function BaseTable<T>(props: DataTableProps<T>) {
|
function BaseTable<T>(props: DataTableProps<T>) {
|
||||||
return (
|
return (
|
||||||
<DataTable
|
<DataTable
|
||||||
withTableBorder
|
|
||||||
withRowBorders
|
withRowBorders
|
||||||
striped={false}
|
striped={false}
|
||||||
verticalAlign={"center"}
|
verticalAlign={"center"}
|
||||||
backgroundColor={"transparent"}
|
backgroundColor={"transparent"}
|
||||||
|
className={classNames(
|
||||||
|
props.withTableBorder && styles["table-border"]
|
||||||
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,16 +1,9 @@
|
|||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { IconTrash } from "@tabler/icons-react";
|
import { IconTrash } from "@tabler/icons-react";
|
||||||
import { isNumber } from "lodash";
|
import { isNumber } from "lodash";
|
||||||
import {
|
import { Divider, Group, NumberInput, Stack, Text } from "@mantine/core";
|
||||||
ActionIcon,
|
|
||||||
Divider,
|
|
||||||
Group,
|
|
||||||
NumberInput,
|
|
||||||
Stack,
|
|
||||||
Text,
|
|
||||||
Tooltip,
|
|
||||||
} from "@mantine/core";
|
|
||||||
import { useDebouncedCallback } from "@mantine/hooks";
|
import { useDebouncedCallback } from "@mantine/hooks";
|
||||||
|
import ActionIconWithTip from "@/components/ui/ActionIconWithTip/ActionIconWithTip";
|
||||||
import { DealServiceSchema } from "@/lib/client";
|
import { DealServiceSchema } from "@/lib/client";
|
||||||
import LockCheckbox from "@/modules/dealModules/dealEditorTabs/FulfillmentBaseTab/components/LockCheckbox/LockCheckbox";
|
import LockCheckbox from "@/modules/dealModules/dealEditorTabs/FulfillmentBaseTab/components/LockCheckbox/LockCheckbox";
|
||||||
|
|
||||||
@ -51,19 +44,15 @@ const DealServiceRow: FC<Props> = ({ value, onChange, onDelete }) => {
|
|||||||
<Divider />
|
<Divider />
|
||||||
<Text>{value.service.name}</Text>
|
<Text>{value.service.name}</Text>
|
||||||
<Group>
|
<Group>
|
||||||
<Tooltip
|
<ActionIconWithTip
|
||||||
onClick={() => onDelete(value)}
|
onClick={() => onDelete(value)}
|
||||||
label="Удалить услугу">
|
tipLabel={"Удалить услугу"}>
|
||||||
<ActionIcon variant={"default"}>
|
|
||||||
<IconTrash />
|
<IconTrash />
|
||||||
</ActionIcon>
|
</ActionIconWithTip>
|
||||||
</Tooltip>
|
|
||||||
{/*<Tooltip label="Сотрудники">*/}
|
{/*<Tooltip label="Сотрудники">*/}
|
||||||
{/* <ActionIcon*/}
|
{/*<ActionIcon onClick={() => onEmployeeClick(service)}>*/}
|
||||||
{/* onClick={() => onEmployeeClick(service)}*/}
|
|
||||||
{/* variant={"default"}>*/}
|
|
||||||
{/* <IconUsersGroup />*/}
|
{/* <IconUsersGroup />*/}
|
||||||
{/* </ActionIcon>*/}
|
{/*</ActionIcon>*/}
|
||||||
{/*</Tooltip>*/}
|
{/*</Tooltip>*/}
|
||||||
<NumberInput
|
<NumberInput
|
||||||
flex={1}
|
flex={1}
|
||||||
|
|||||||
@ -13,6 +13,7 @@ const FulfillmentBaseTabBody = () => {
|
|||||||
gap={"xs"}>
|
gap={"xs"}>
|
||||||
<ScrollArea
|
<ScrollArea
|
||||||
offsetScrollbars={"y"}
|
offsetScrollbars={"y"}
|
||||||
|
flex={4}
|
||||||
mah={"91vh"}>
|
mah={"91vh"}>
|
||||||
<Stack>
|
<Stack>
|
||||||
{dealProductsList.dealProducts.map((dealProduct, index) => (
|
{dealProductsList.dealProducts.map((dealProduct, index) => (
|
||||||
@ -23,7 +24,7 @@ const FulfillmentBaseTabBody = () => {
|
|||||||
))}
|
))}
|
||||||
</Stack>
|
</Stack>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
<Stack>
|
<Stack flex={2}>
|
||||||
<DealServicesTable />
|
<DealServicesTable />
|
||||||
<ProductsActions />
|
<ProductsActions />
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { IconLock, IconLockOpen } from "@tabler/icons-react";
|
import { IconLock, IconLockOpen } from "@tabler/icons-react";
|
||||||
import { ActionIcon, CheckboxProps, Tooltip } from "@mantine/core";
|
import { CheckboxProps } from "@mantine/core";
|
||||||
|
import ActionIconWithTip from "@/components/ui/ActionIconWithTip/ActionIconWithTip";
|
||||||
|
|
||||||
type RestProps = {
|
type RestProps = {
|
||||||
value: boolean;
|
value: boolean;
|
||||||
@ -15,13 +16,11 @@ const LockCheckbox: FC<Props> = props => {
|
|||||||
const handleChange = () => props.onChange(!props.value);
|
const handleChange = () => props.onChange(!props.value);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip label={props.label}>
|
<ActionIconWithTip
|
||||||
<ActionIcon
|
|
||||||
onClick={handleChange}
|
onClick={handleChange}
|
||||||
variant={props.variant}>
|
variant={props.variant}>
|
||||||
{getIcon()}
|
{getIcon()}
|
||||||
</ActionIcon>
|
</ActionIconWithTip>
|
||||||
</Tooltip>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,6 @@
|
|||||||
.container {
|
.container {
|
||||||
display: flex;
|
border: dashed 1px var(--mantine-color-default-border);
|
||||||
border: dashed var(--item-border-size) var(--mantine-color-default-border);
|
border-radius: var(--mantine-radius-lg);
|
||||||
border-radius: var(--item-border-radius);
|
|
||||||
gap: rem(20);
|
|
||||||
padding: rem(10);
|
|
||||||
margin-bottom: rem(10);
|
|
||||||
flex: 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.image-container {
|
.image-container {
|
||||||
@ -14,23 +9,3 @@
|
|||||||
max-width: rem(250);
|
max-width: rem(250);
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.services-container {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: rem(10);
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.data-container {
|
|
||||||
max-width: rem(250);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: rem(10);
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attributes-container {
|
|
||||||
overflow-wrap: break-word;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { isNumber } from "lodash";
|
import { isNumber } from "lodash";
|
||||||
import {
|
import {
|
||||||
Box,
|
Flex,
|
||||||
Card,
|
|
||||||
Image,
|
Image,
|
||||||
NumberInput,
|
NumberInput,
|
||||||
rem,
|
rem,
|
||||||
@ -23,6 +22,7 @@ import ProductViewActions from "@/modules/dealModules/dealEditorTabs/Fulfillment
|
|||||||
import { useFulfillmentBaseContext } from "@/modules/dealModules/dealEditorTabs/FulfillmentBaseTab/contexts/FulfillmentBaseContext";
|
import { useFulfillmentBaseContext } from "@/modules/dealModules/dealEditorTabs/FulfillmentBaseTab/contexts/FulfillmentBaseContext";
|
||||||
import { ServiceType } from "@/modules/dealModules/dealEditorTabs/FulfillmentBaseTab/types/service";
|
import { ServiceType } from "@/modules/dealModules/dealEditorTabs/FulfillmentBaseTab/types/service";
|
||||||
import ProductServicesTable from "./components/ProductServicesTable";
|
import ProductServicesTable from "./components/ProductServicesTable";
|
||||||
|
import styles from "./ProductView.module.css";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
dealProduct: DealProductSchema;
|
dealProduct: DealProductSchema;
|
||||||
@ -99,23 +99,29 @@ const ProductView: FC<Props> = ({ dealProduct }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Flex
|
||||||
|
align={"start"}
|
||||||
|
direction={"row"}
|
||||||
p={"sm"}
|
p={"sm"}
|
||||||
style={{ display: "flex", flexDirection: "row" }}>
|
className={styles.container}
|
||||||
<Stack gap={"sm"}>
|
gap={"sm"}>
|
||||||
|
<Stack
|
||||||
|
flex={2}
|
||||||
|
gap={"sm"}>
|
||||||
|
{!dealProduct.product && (
|
||||||
<Image
|
<Image
|
||||||
flex={1}
|
flex={1}
|
||||||
radius={rem(10)}
|
radius={rem(10)}
|
||||||
fit={"cover"}
|
fit={"cover"}
|
||||||
// src={dealProduct.product.imageUrl}
|
// src={dealProduct.product.imageUrl}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<Title order={3}>{dealProduct.product.name}</Title>
|
<Title order={3}>{dealProduct.product.name}</Title>
|
||||||
<ProductFieldsList product={dealProduct.product} />
|
<ProductFieldsList product={dealProduct.product} />
|
||||||
{/*<Text>*/}
|
{/*<Text>*/}
|
||||||
{/* Штрихкоды:*/}
|
{/* Штрихкоды:*/}
|
||||||
{/*{value.product.barcodes.join(", ")}*/}
|
{/*{value.product.barcodes.join(", ")}*/}
|
||||||
{/*</Text>*/}
|
{/*</Text>*/}
|
||||||
<Box />
|
|
||||||
<NumberInput
|
<NumberInput
|
||||||
mt={rem(10)}
|
mt={rem(10)}
|
||||||
suffix={" шт."}
|
suffix={" шт."}
|
||||||
@ -126,22 +132,17 @@ const ProductView: FC<Props> = ({ dealProduct }) => {
|
|||||||
placeholder={"Введите количество товара"}
|
placeholder={"Введите количество товара"}
|
||||||
/>
|
/>
|
||||||
<Textarea
|
<Textarea
|
||||||
mih={rem(140)}
|
|
||||||
styles={{
|
|
||||||
wrapper: { height: "90%" },
|
|
||||||
input: { height: "90%" },
|
|
||||||
}}
|
|
||||||
my={rem(10)}
|
|
||||||
defaultValue={dealProduct.comment}
|
defaultValue={dealProduct.comment}
|
||||||
onChange={event =>
|
onChange={event =>
|
||||||
debouncedOnChange({
|
debouncedOnChange({
|
||||||
comment: event.currentTarget.value,
|
comment: event.currentTarget.value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
rows={4}
|
||||||
placeholder={"Комментарий"}
|
placeholder={"Комментарий"}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack>
|
<Stack flex={5}>
|
||||||
<ProductServicesTable
|
<ProductServicesTable
|
||||||
dealProduct={dealProduct}
|
dealProduct={dealProduct}
|
||||||
onDuplicateServices={() => onDuplicateServices(dealProduct)}
|
onDuplicateServices={() => onDuplicateServices(dealProduct)}
|
||||||
@ -149,7 +150,7 @@ const ProductView: FC<Props> = ({ dealProduct }) => {
|
|||||||
/>
|
/>
|
||||||
<ProductViewActions dealProduct={dealProduct} />
|
<ProductViewActions dealProduct={dealProduct} />
|
||||||
</Stack>
|
</Stack>
|
||||||
</Card>
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { IconMoodSad } from "@tabler/icons-react";
|
import { IconCopy, IconMoodSad } from "@tabler/icons-react";
|
||||||
import { Button, Flex, Group, Stack, Text } from "@mantine/core";
|
import { Button, Flex, Group, Stack, Text } from "@mantine/core";
|
||||||
import { modals } from "@mantine/modals";
|
import { modals } from "@mantine/modals";
|
||||||
|
import ActionIconWithTip from "@/components/ui/ActionIconWithTip/ActionIconWithTip";
|
||||||
import BaseTable from "@/components/ui/BaseTable/BaseTable";
|
import BaseTable from "@/components/ui/BaseTable/BaseTable";
|
||||||
import { DealProductSchema, ProductServiceSchema } from "@/lib/client";
|
import { DealProductSchema, ProductServiceSchema } from "@/lib/client";
|
||||||
import useProductServicesTableColumns from "@/modules/dealModules/dealEditorTabs/FulfillmentBaseTab/components/ProductView/hooks/useProductServicesTableColumns";
|
import useProductServicesTableColumns from "@/modules/dealModules/dealEditorTabs/FulfillmentBaseTab/components/ProductView/hooks/useProductServicesTableColumns";
|
||||||
@ -113,6 +114,7 @@ const ProductServicesTable: FC<Props> = ({
|
|||||||
columns={columns}
|
columns={columns}
|
||||||
groups={undefined}
|
groups={undefined}
|
||||||
idAccessor={"serviceId"}
|
idAccessor={"serviceId"}
|
||||||
|
withTableBorder
|
||||||
style={{
|
style={{
|
||||||
height: isEmptyTable ? "8rem" : "auto",
|
height: isEmptyTable ? "8rem" : "auto",
|
||||||
}}
|
}}
|
||||||
@ -128,17 +130,21 @@ const ProductServicesTable: FC<Props> = ({
|
|||||||
<Flex
|
<Flex
|
||||||
justify={"flex-end"}
|
justify={"flex-end"}
|
||||||
gap={"xs"}
|
gap={"xs"}
|
||||||
pt={isEmptyTable ? 0 : "xs"}>
|
pt={"xs"}>
|
||||||
|
{onDuplicateServices && (
|
||||||
|
<ActionIconWithTip
|
||||||
|
tipLabel={"Продублировать услуги"}
|
||||||
|
onClick={onDuplicateServices}>
|
||||||
|
<IconCopy />
|
||||||
|
</ActionIconWithTip>
|
||||||
|
)}
|
||||||
|
{onKitAdd && (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => onKitAdd && onKitAdd()}
|
onClick={onKitAdd}
|
||||||
variant={"default"}>
|
variant={"default"}>
|
||||||
Добавить набор услуг
|
Добавить набор услуг
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
)}
|
||||||
onClick={() => onDuplicateServices && onDuplicateServices()}
|
|
||||||
variant={"default"}>
|
|
||||||
Продублировать услуги
|
|
||||||
</Button>
|
|
||||||
<Button
|
<Button
|
||||||
onClick={onCreateClick}
|
onClick={onCreateClick}
|
||||||
variant={"default"}>
|
variant={"default"}>
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { IconEdit, IconTrash } from "@tabler/icons-react";
|
import { IconEdit, IconTrash } from "@tabler/icons-react";
|
||||||
import { ActionIcon, Flex, rem, Tooltip } from "@mantine/core";
|
import { Flex } from "@mantine/core";
|
||||||
import { modals } from "@mantine/modals";
|
import { modals } from "@mantine/modals";
|
||||||
|
import ActionIconWithTip from "@/components/ui/ActionIconWithTip/ActionIconWithTip";
|
||||||
import { DealProductSchema } from "@/lib/client";
|
import { DealProductSchema } from "@/lib/client";
|
||||||
import { useFulfillmentBaseContext } from "@/modules/dealModules/dealEditorTabs/FulfillmentBaseTab/contexts/FulfillmentBaseContext";
|
import { useFulfillmentBaseContext } from "@/modules/dealModules/dealEditorTabs/FulfillmentBaseTab/contexts/FulfillmentBaseContext";
|
||||||
|
|
||||||
@ -35,7 +36,7 @@ const ProductViewActions: FC<Props> = ({ dealProduct }) => {
|
|||||||
<Flex
|
<Flex
|
||||||
mt={"auto"}
|
mt={"auto"}
|
||||||
ml={"auto"}
|
ml={"auto"}
|
||||||
gap={rem(10)}>
|
gap={"sm"}>
|
||||||
{/*<Tooltip*/}
|
{/*<Tooltip*/}
|
||||||
{/* onClick={onPrintBarcodeClick}*/}
|
{/* onClick={onPrintBarcodeClick}*/}
|
||||||
{/* label="Печать штрихкода">*/}
|
{/* label="Печать штрихкода">*/}
|
||||||
@ -43,20 +44,16 @@ const ProductViewActions: FC<Props> = ({ dealProduct }) => {
|
|||||||
{/* <IconBarcode />*/}
|
{/* <IconBarcode />*/}
|
||||||
{/* </ActionIcon>*/}
|
{/* </ActionIcon>*/}
|
||||||
{/*</Tooltip>*/}
|
{/*</Tooltip>*/}
|
||||||
<Tooltip
|
<ActionIconWithTip
|
||||||
onClick={onProductEditClick}
|
onClick={onProductEditClick}
|
||||||
label="Редактировать товар">
|
tipLabel="Редактировать товар">
|
||||||
<ActionIcon variant={"default"}>
|
|
||||||
<IconEdit />
|
<IconEdit />
|
||||||
</ActionIcon>
|
</ActionIconWithTip>
|
||||||
</Tooltip>
|
<ActionIconWithTip
|
||||||
<Tooltip
|
|
||||||
onClick={() => dealProductsCrud.onDelete(dealProduct)}
|
onClick={() => dealProductsCrud.onDelete(dealProduct)}
|
||||||
label="Удалить товар">
|
tipLabel="Удалить товар">
|
||||||
<ActionIcon variant={"default"}>
|
|
||||||
<IconTrash />
|
<IconTrash />
|
||||||
</ActionIcon>
|
</ActionIconWithTip>
|
||||||
</Tooltip>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { IconEdit, IconTrash } from "@tabler/icons-react";
|
import { IconEdit, IconTrash } from "@tabler/icons-react";
|
||||||
import { DataTableColumn } from "mantine-datatable";
|
import { DataTableColumn } from "mantine-datatable";
|
||||||
import { ActionIcon, Box, Flex, Text, Tooltip } from "@mantine/core";
|
import { Box, Flex, Text } from "@mantine/core";
|
||||||
|
import ActionIconWithTip from "@/components/ui/ActionIconWithTip/ActionIconWithTip";
|
||||||
import { ProductServiceSchema } from "@/lib/client";
|
import { ProductServiceSchema } from "@/lib/client";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -31,21 +32,20 @@ const useProductServicesTableColumns = ({
|
|||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
width: "0%",
|
width: "0%",
|
||||||
render: dealProductService => (
|
render: dealProductService => (
|
||||||
<Flex gap="md">
|
<Flex
|
||||||
<Tooltip label="Удалить">
|
gap="md"
|
||||||
<ActionIcon
|
px={"sm"}
|
||||||
onClick={() => onDelete(dealProductService)}
|
my={"sm"}>
|
||||||
variant={"default"}>
|
<ActionIconWithTip
|
||||||
|
tipLabel={"Удалить услугу"}
|
||||||
|
onClick={() => onDelete(dealProductService)}>
|
||||||
<IconTrash />
|
<IconTrash />
|
||||||
</ActionIcon>
|
</ActionIconWithTip>
|
||||||
</Tooltip>
|
<ActionIconWithTip
|
||||||
<Tooltip label="Редактировать">
|
tipLabel="Редактировать"
|
||||||
<ActionIcon
|
onClick={() => onChange(dealProductService)}>
|
||||||
onClick={() => onChange(dealProductService)}
|
|
||||||
variant={"default"}>
|
|
||||||
<IconEdit />
|
<IconEdit />
|
||||||
</ActionIcon>
|
</ActionIconWithTip>
|
||||||
</Tooltip>
|
|
||||||
{/*<Tooltip label="Сотрудники">*/}
|
{/*<Tooltip label="Сотрудники">*/}
|
||||||
{/* <ActionIcon*/}
|
{/* <ActionIcon*/}
|
||||||
{/* onClick={() =>*/}
|
{/* onClick={() =>*/}
|
||||||
@ -66,7 +66,7 @@ const useProductServicesTableColumns = ({
|
|||||||
accessor: "price",
|
accessor: "price",
|
||||||
title: "Цена",
|
title: "Цена",
|
||||||
footer: data.length > 0 && (
|
footer: data.length > 0 && (
|
||||||
<Box h={"100%"}>
|
<Box my={"sm"}>
|
||||||
<Text fw={700}>
|
<Text fw={700}>
|
||||||
Итог: {totalPrice.toLocaleString("ru")}₽
|
Итог: {totalPrice.toLocaleString("ru")}₽
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@ -14,7 +14,7 @@ export const myColor: MantineColorsTuple = [
|
|||||||
"#00718c",
|
"#00718c",
|
||||||
];
|
];
|
||||||
|
|
||||||
const radius = "md";
|
const radius = "lg";
|
||||||
|
|
||||||
const font = Roboto({
|
const font = Roboto({
|
||||||
subsets: ["latin"],
|
subsets: ["latin"],
|
||||||
|
|||||||
Reference in New Issue
Block a user