refactor: drawers refactored

This commit is contained in:
2025-09-06 11:09:42 +04:00
parent 67780b5251
commit d76dc82cb8
44 changed files with 239 additions and 227 deletions

View File

@ -3,7 +3,6 @@ import { IconMoodSad } from "@tabler/icons-react";
import { Group, Pagination, Stack, Text } from "@mantine/core"; import { Group, Pagination, Stack, Text } from "@mantine/core";
import useDealsTableColumns from "@/app/deals/components/desktop/DealsTable/useDealsTableColumns"; import useDealsTableColumns from "@/app/deals/components/desktop/DealsTable/useDealsTableColumns";
import { useDealsContext } from "@/app/deals/contexts/DealsContext"; import { useDealsContext } from "@/app/deals/contexts/DealsContext";
import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext";
import BaseTable from "@/components/ui/BaseTable/BaseTable"; import BaseTable from "@/components/ui/BaseTable/BaseTable";
import { useDrawersContext } from "@/drawers/DrawersContext"; import { useDrawersContext } from "@/drawers/DrawersContext";
import { DealSchema } from "@/lib/client"; import { DealSchema } from "@/lib/client";
@ -11,18 +10,16 @@ import { DealSchema } from "@/lib/client";
const DealsTable: FC = () => { const DealsTable: FC = () => {
const { deals, paginationInfo, page, setPage, sortingForm, dealsCrud } = const { deals, paginationInfo, page, setPage, sortingForm, dealsCrud } =
useDealsContext(); useDealsContext();
const { selectedProject } = useProjectsContext();
const { openDrawer } = useDrawersContext(); const { openDrawer } = useDrawersContext();
const onEditClick = useCallback( const onEditClick = useCallback(
(deal: DealSchema) => { (deal: DealSchema) => {
if (!selectedProject) return;
openDrawer({ openDrawer({
key: "dealEditorDrawer", key: "dealEditorDrawer",
props: { props: {
deal, value: deal,
dealsCrud, onChange: deal => dealsCrud.onUpdate(deal.id, deal),
project: selectedProject, onDelete: dealsCrud.onDelete,
}, },
}); });
}, },

View File

@ -44,8 +44,12 @@ const TopToolPanel: FC<Props> = ({ view, setView }) => {
if (!selectedProject) return; if (!selectedProject) return;
openDrawer({ openDrawer({
key: "selectedProjectEditorDrawer", key: "projectEditorDrawer",
props: { project: selectedProject, projectsCrud }, props: {
value: selectedProject,
onChange: value => projectsCrud.onUpdate(value.id, value),
onDelete: projectsCrud.onDelete,
},
}); });
}; };

View File

@ -22,9 +22,9 @@ const MainBlockHeader = () => {
const openProjectsEditorDrawer = () => { const openProjectsEditorDrawer = () => {
openDrawer({ openDrawer({
key: "projectsEditorDrawer", key: "projectsMobileEditorDrawer",
props: { props: {
setSelectedProjectId: selectProjectId, onSelect: project => selectProjectId(project?.id ?? null),
}, },
}); });
}; };
@ -32,7 +32,7 @@ const MainBlockHeader = () => {
const openBoardsEditorDrawer = () => { const openBoardsEditorDrawer = () => {
if (!selectedProject) return; if (!selectedProject) return;
openDrawer({ openDrawer({
key: "projectBoardsEditorDrawer", key: "boardsMobileEditorDrawer",
props: { props: {
project: selectedProject, project: selectedProject,
}, },

View File

@ -1,6 +1,5 @@
import { Box, Card, Group, Pill, Stack, Text } from "@mantine/core"; import { Box, Card, Group, Pill, Stack, Text } from "@mantine/core";
import { useDealsContext } from "@/app/deals/contexts/DealsContext"; import { useDealsContext } from "@/app/deals/contexts/DealsContext";
import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext";
import { useDrawersContext } from "@/drawers/DrawersContext"; import { useDrawersContext } from "@/drawers/DrawersContext";
import { DealSchema } from "@/lib/client"; import { DealSchema } from "@/lib/client";
import styles from "./DealCard.module.css"; import styles from "./DealCard.module.css";
@ -10,15 +9,17 @@ type Props = {
}; };
const DealCard = ({ deal }: Props) => { const DealCard = ({ deal }: Props) => {
const { selectedProject } = useProjectsContext();
const { dealsCrud } = useDealsContext(); const { dealsCrud } = useDealsContext();
const { openDrawer } = useDrawersContext(); const { openDrawer } = useDrawersContext();
const onClick = () => { const onClick = () => {
if (!selectedProject) return;
openDrawer({ openDrawer({
key: "dealEditorDrawer", key: "dealEditorDrawer",
props: { project: selectedProject, deal, dealsCrud }, props: {
value: deal,
onChange: deal => dealsCrud.onUpdate(deal.id, deal),
onDelete: dealsCrud.onDelete,
},
}); });
}; };

View File

@ -69,7 +69,7 @@ const StatusMenu: FC<Props> = ({
e.stopPropagation(); e.stopPropagation();
if (!board) return; if (!board) return;
openDrawer({ openDrawer({
key: "boardStatusesEditorDrawer", key: "statusesMobileEditorDrawer",
props: { props: {
board, board,
}, },

View File

@ -1,3 +0,0 @@
import BoardStatusesEditorDrawer from "@/app/deals/drawers/BoardStatusesEditorDrawer/BoardStatusesEditorDrawer";
export default BoardStatusesEditorDrawer;

View File

@ -2,8 +2,8 @@
import React, { FC } from "react"; import React, { FC } from "react";
import { Drawer, rem } from "@mantine/core"; import { Drawer, rem } from "@mantine/core";
import BoardsDrawerBody from "@/app/deals/drawers/ProjectBoardsEditorDrawer/components/BoardsDrawerBody"; import BoardsDrawerBody from "@/app/deals/drawers/BoardsMobileEditorDrawer/components/BoardsDrawerBody";
import { ProjectBoardsContextProvider } from "@/app/deals/drawers/ProjectBoardsEditorDrawer/contexts/ProjectBoardsContext"; import { BoardsMobileContextProvider } from "@/app/deals/drawers/BoardsMobileEditorDrawer/contexts/BoardsMobileContext";
import { DrawerProps } from "@/drawers/types"; import { DrawerProps } from "@/drawers/types";
import { ProjectSchema } from "@/lib/client"; import { ProjectSchema } from "@/lib/client";
@ -11,7 +11,7 @@ type Props = {
project: ProjectSchema; project: ProjectSchema;
}; };
const ProjectBoardsEditorDrawer: FC<DrawerProps<Props>> = ({ const BoardsMobileEditorDrawer: FC<DrawerProps<Props>> = ({
onClose, onClose,
opened, opened,
props: { project }, props: { project },
@ -33,11 +33,11 @@ const ProjectBoardsEditorDrawer: FC<DrawerProps<Props>> = ({
gap: rem(10), gap: rem(10),
}, },
}}> }}>
<ProjectBoardsContextProvider project={project}> <BoardsMobileContextProvider project={project}>
<BoardsDrawerBody onClose={onClose} /> <BoardsDrawerBody onClose={onClose} />
</ProjectBoardsContextProvider> </BoardsMobileContextProvider>
</Drawer> </Drawer>
); );
}; };
export default ProjectBoardsEditorDrawer; export default BoardsMobileEditorDrawer;

View File

@ -2,7 +2,7 @@ import React, { FC } from "react";
import { Box, Group, Text } from "@mantine/core"; import { Box, Group, Text } from "@mantine/core";
import { modals } from "@mantine/modals"; import { modals } from "@mantine/modals";
import BoardMenu from "@/app/deals/components/shared/BoardMenu/BoardMenu"; import BoardMenu from "@/app/deals/components/shared/BoardMenu/BoardMenu";
import { useProjectBoardsContext } from "@/app/deals/drawers/ProjectBoardsEditorDrawer/contexts/ProjectBoardsContext"; import { useBoardsMobileContext } from "@/app/deals/drawers/BoardsMobileEditorDrawer/contexts/BoardsMobileContext";
import { BoardSchema } from "@/lib/client"; import { BoardSchema } from "@/lib/client";
type Props = { type Props = {
@ -10,7 +10,7 @@ type Props = {
}; };
const BoardMobile: FC<Props> = ({ board }) => { const BoardMobile: FC<Props> = ({ board }) => {
const { boardsCrud } = useProjectBoardsContext(); const { boardsCrud } = useBoardsMobileContext();
const startEditing = () => { const startEditing = () => {
modals.openContextModal({ modals.openContextModal({

View File

@ -1,9 +1,9 @@
import React, { FC, ReactNode } from "react"; import React, { FC, ReactNode } from "react";
import { IconChevronLeft, IconGripVertical } from "@tabler/icons-react"; import { IconChevronLeft, IconGripVertical } from "@tabler/icons-react";
import { Box, Center, Divider, Group, Text } from "@mantine/core"; import { Box, Center, Divider, Group, Text } from "@mantine/core";
import BoardMobile from "@/app/deals/drawers/ProjectBoardsEditorDrawer/components/BoardMobile"; import BoardMobile from "@/app/deals/drawers/BoardsMobileEditorDrawer/components/BoardMobile";
import CreateBoardButton from "@/app/deals/drawers/ProjectBoardsEditorDrawer/components/CreateBoardButton"; import CreateBoardButton from "@/app/deals/drawers/BoardsMobileEditorDrawer/components/CreateBoardButton";
import { useProjectBoardsContext } from "@/app/deals/drawers/ProjectBoardsEditorDrawer/contexts/ProjectBoardsContext"; import { useBoardsMobileContext } from "@/app/deals/drawers/BoardsMobileEditorDrawer/contexts/BoardsMobileContext";
import SortableDnd from "@/components/dnd/SortableDnd"; import SortableDnd from "@/components/dnd/SortableDnd";
import { BoardSchema } from "@/lib/client"; import { BoardSchema } from "@/lib/client";
@ -12,7 +12,7 @@ type Props = {
}; };
const BoardsDrawerBody: FC<Props> = ({ onClose }) => { const BoardsDrawerBody: FC<Props> = ({ onClose }) => {
const { boards, boardsCrud, project } = useProjectBoardsContext(); const { boards, boardsCrud, project } = useBoardsMobileContext();
const renderDraggable = () => ( const renderDraggable = () => (
<Box p={"xs"}> <Box p={"xs"}>

View File

@ -40,7 +40,7 @@ const useProjectBoardsContextState = ({ project }: Props) => {
}; };
}; };
export const [ProjectBoardsContextProvider, useProjectBoardsContext] = export const [BoardsMobileContextProvider, useBoardsMobileContext] =
makeContext<ProjectBoardsContextState, Props>( makeContext<ProjectBoardsContextState, Props>(
useProjectBoardsContextState, useProjectBoardsContextState,
"ProjectBoards" "ProjectBoards"

View File

@ -0,0 +1,3 @@
import BoardsMobileEditorDrawer from "@/app/deals/drawers/BoardsMobileEditorDrawer/BoardsMobileEditorDrawer";
export default BoardsMobileEditorDrawer;

View File

@ -5,14 +5,13 @@ import { Drawer } from "@mantine/core";
import DealEditorBody from "@/app/deals/drawers/DealEditorDrawer/components/DealEditorBody"; import DealEditorBody from "@/app/deals/drawers/DealEditorDrawer/components/DealEditorBody";
import Header from "@/app/deals/drawers/DealEditorDrawer/components/Header"; import Header from "@/app/deals/drawers/DealEditorDrawer/components/Header";
import { DrawerProps } from "@/drawers/types"; import { DrawerProps } from "@/drawers/types";
import { DealsCrud } from "@/hooks/cruds/useDealsCrud";
import useIsMobile from "@/hooks/utils/useIsMobile"; import useIsMobile from "@/hooks/utils/useIsMobile";
import { DealSchema, ProjectSchema } from "@/lib/client"; import { DealSchema } from "@/lib/client";
type Props = { type Props = {
project: ProjectSchema; value: DealSchema;
deal: DealSchema; onChange: (deal: DealSchema) => void;
dealsCrud: DealsCrud; onDelete: (deal: DealSchema, onSuccess: () => void) => void;
}; };
const DealEditorDrawer: FC<DrawerProps<Props>> = ({ const DealEditorDrawer: FC<DrawerProps<Props>> = ({
@ -21,7 +20,7 @@ const DealEditorDrawer: FC<DrawerProps<Props>> = ({
props, props,
}) => { }) => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const [deal, setDeal] = useState(props.deal); const [deal, setDeal] = useState(props.value);
return ( return (
<Drawer <Drawer
@ -44,10 +43,12 @@ const DealEditorDrawer: FC<DrawerProps<Props>> = ({
}, },
}}> }}>
<DealEditorBody <DealEditorBody
{...props} value={deal}
deal={deal} onChange={deal => {
setDeal={setDeal} setDeal(deal);
onClose={onClose} props.onChange(deal);
}}
onDelete={value => props.onDelete(value, onClose)}
/> />
</Drawer> </Drawer>
); );

View File

@ -2,16 +2,13 @@ import React, { FC } from "react";
import { IconCircleDotted, IconEdit } from "@tabler/icons-react"; import { IconCircleDotted, IconEdit } from "@tabler/icons-react";
import { Tabs, Text } from "@mantine/core"; import { Tabs, Text } from "@mantine/core";
import GeneralTab from "@/app/deals/drawers/DealEditorDrawer/tabs/GeneralTab/GeneralTab"; import GeneralTab from "@/app/deals/drawers/DealEditorDrawer/tabs/GeneralTab/GeneralTab";
import { DealsCrud } from "@/hooks/cruds/useDealsCrud"; import { DealSchema } from "@/lib/client";
import { DealSchema, ProjectSchema } from "@/lib/client";
import styles from "../DealEditorDrawer.module.css"; import styles from "../DealEditorDrawer.module.css";
type Props = { type Props = {
project: ProjectSchema; value: DealSchema;
dealsCrud: DealsCrud; onChange: (deal: DealSchema) => void;
deal: DealSchema; onDelete: (deal: DealSchema) => void;
setDeal: React.Dispatch<React.SetStateAction<DealSchema>>;
onClose: () => void;
}; };
const DealEditorBody: FC<Props> = props => { const DealEditorBody: FC<Props> = props => {

View File

@ -1,3 +1,3 @@
import ProjectsEditorDrawer from "@/app/deals/drawers/ProjectsEditorDrawer/ProjectsEditorDrawer"; import ProjectsMobileEditorDrawer from "@/app/deals/drawers/ProjectsEditorDrawer/ProjectsMobileEditorDrawer";
export default ProjectsEditorDrawer; export default ProjectsMobileEditorDrawer;

View File

@ -2,10 +2,11 @@ import { FC } from "react";
import { isEqual } from "lodash"; import { isEqual } from "lodash";
import { Button, Group } from "@mantine/core"; import { Button, Group } from "@mantine/core";
import { UseFormReturnType } from "@mantine/form"; import { UseFormReturnType } from "@mantine/form";
import { DealForm } from "@/app/deals/drawers/DealEditorDrawer/tabs/GeneralTab/GeneralTab";
import { DealSchema } from "@/lib/client"; import { DealSchema } from "@/lib/client";
type Props = { type Props = {
form: UseFormReturnType<Partial<DealSchema>>; form: UseFormReturnType<DealForm>;
initialValues: Partial<DealSchema>; initialValues: Partial<DealSchema>;
onDelete: () => void; onDelete: () => void;
}; };

View File

@ -4,27 +4,23 @@ import { useForm } from "@mantine/form";
import Footer from "@/app/deals/drawers/DealEditorDrawer/tabs/GeneralTab/Footer"; import Footer from "@/app/deals/drawers/DealEditorDrawer/tabs/GeneralTab/Footer";
import BoardSelect from "@/components/selects/BoardSelect/BoardSelect"; import BoardSelect from "@/components/selects/BoardSelect/BoardSelect";
import StatusSelect from "@/components/selects/StatusSelect/StatusSelect"; import StatusSelect from "@/components/selects/StatusSelect/StatusSelect";
import { DealsCrud } from "@/hooks/cruds/useDealsCrud"; import { BoardSchema, DealSchema, StatusSchema } from "@/lib/client";
import { DealSchema, ProjectSchema } from "@/lib/client";
import { utcDateTimeToLocalString } from "@/utils/datetime"; import { utcDateTimeToLocalString } from "@/utils/datetime";
type Props = { type Props = {
project: ProjectSchema; value: DealSchema;
dealsCrud: DealsCrud; onChange: (deal: DealSchema) => void;
deal: DealSchema; onDelete: (deal: DealSchema) => void;
setDeal: React.Dispatch<React.SetStateAction<DealSchema>>;
onClose: () => void;
}; };
const GeneralTab: FC<Props> = ({ export type DealForm = Omit<DealSchema, "board" | "status"> & {
project, board?: BoardSchema | undefined;
deal, status?: StatusSchema | undefined;
setDeal, };
dealsCrud,
onClose, const GeneralTab: FC<Props> = ({ value, onDelete, onChange }) => {
}) => { const form = useForm<DealForm>({
const form = useForm<Partial<DealSchema>>({ initialValues: value,
initialValues: deal,
validate: { validate: {
name: value => !value && "Введите название", name: value => !value && "Введите название",
board: value => !value && "Выберите доску", board: value => !value && "Выберите доску",
@ -32,20 +28,13 @@ const GeneralTab: FC<Props> = ({
}, },
}); });
const onSubmit = (values: Partial<DealSchema>) => { const onSubmit = (values: DealForm) => {
dealsCrud.onUpdate(deal.id, { form.setInitialValues(values);
onChange({
...values, ...values,
boardId: values.board?.id, board: values.board!,
statusId: values.status?.id, status: values.status!,
}); });
setDeal(prev => ({
...prev,
...values,
}));
};
const onDelete = () => {
dealsCrud.onDelete(deal, onClose);
}; };
return ( return (
@ -55,7 +44,9 @@ const GeneralTab: FC<Props> = ({
label={"Название"} label={"Название"}
{...form.getInputProps("name")} {...form.getInputProps("name")}
/> />
<Text>Создано: {utcDateTimeToLocalString(deal.createdAt)}</Text> <Text>
Создано: {utcDateTimeToLocalString(value.createdAt)}
</Text>
<BoardSelect <BoardSelect
label={"Доска"} label={"Доска"}
{...form.getInputProps("board")} {...form.getInputProps("board")}
@ -63,7 +54,7 @@ const GeneralTab: FC<Props> = ({
form.setFieldValue("board", board ?? undefined); form.setFieldValue("board", board ?? undefined);
form.setFieldValue("status", undefined); form.setFieldValue("status", undefined);
}} }}
projectId={project?.id} projectId={value.board.projectId}
/> />
<StatusSelect <StatusSelect
label={"Статус"} label={"Статус"}
@ -72,8 +63,8 @@ const GeneralTab: FC<Props> = ({
/> />
<Footer <Footer
form={form} form={form}
initialValues={deal} initialValues={value}
onDelete={onDelete} onDelete={() => onDelete(value)}
/> />
</Stack> </Stack>
</form> </form>

View File

@ -1,3 +0,0 @@
import ProjectBoardsEditorDrawer from "@/app/deals/drawers/ProjectBoardsEditorDrawer/ProjectBoardsEditorDrawer";
export default ProjectBoardsEditorDrawer;

View File

@ -1,24 +1,25 @@
"use client"; "use client";
import React, { FC } from "react"; import React, { FC, useState } from "react";
import { Drawer } from "@mantine/core"; import { Drawer } from "@mantine/core";
import ProjectEditorBody from "@/app/deals/drawers/SelectedProjectEditorDrawer/components/ProjectEditorBody"; import ProjectEditorBody from "@/app/deals/drawers/ProjectEditorDrawer/components/ProjectEditorBody";
import { DrawerProps } from "@/drawers/types"; import { DrawerProps } from "@/drawers/types";
import { ProjectsCrud } from "@/hooks/cruds/useProjectsCrud";
import useIsMobile from "@/hooks/utils/useIsMobile"; import useIsMobile from "@/hooks/utils/useIsMobile";
import { ProjectSchema } from "@/lib/client"; import { ProjectSchema } from "@/lib/client";
type Props = { type Props = {
project: ProjectSchema; value: ProjectSchema;
projectsCrud: ProjectsCrud; onChange: (value: ProjectSchema) => void;
onDelete: (value: ProjectSchema, onSuccess: () => void) => void;
}; };
const SelectedProjectEditorDrawer: FC<DrawerProps<Props>> = ({ const ProjectEditorDrawer: FC<DrawerProps<Props>> = ({
opened, opened,
onClose, onClose,
props, props,
}) => { }) => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const [project, setProject] = useState(props.value);
return ( return (
<Drawer <Drawer
@ -38,11 +39,15 @@ const SelectedProjectEditorDrawer: FC<DrawerProps<Props>> = ({
}, },
}}> }}>
<ProjectEditorBody <ProjectEditorBody
{...props} value={project}
onClose={onClose} onChange={project => {
setProject(project);
props.onChange(project);
}}
onDelete={value => props.onDelete(value, onClose)}
/> />
</Drawer> </Drawer>
); );
}; };
export default SelectedProjectEditorDrawer; export default ProjectEditorDrawer;

View File

@ -1,18 +1,17 @@
import { FC } from "react"; import { FC } from "react";
import { IconEdit } from "@tabler/icons-react"; import { IconEdit } from "@tabler/icons-react";
import { Tabs } from "@mantine/core"; import { Tabs } from "@mantine/core";
import GeneralTab from "@/app/deals/drawers/SelectedProjectEditorDrawer/components/GeneralTab"; import GeneralTab from "@/app/deals/drawers/ProjectEditorDrawer/tabs/GeneralTab/GeneralTab";
import { ProjectsCrud } from "@/hooks/cruds/useProjectsCrud";
import { ProjectSchema } from "@/lib/client"; import { ProjectSchema } from "@/lib/client";
import styles from "../SelectedProjectEditorDrawer.module.css"; import styles from "../ProjectEditorDrawer.module.css";
type Props = { type Props = {
projectsCrud: ProjectsCrud; value: ProjectSchema;
project: ProjectSchema; onChange: (value: ProjectSchema) => void;
onClose: () => void; onDelete: (value: ProjectSchema) => void;
}; };
const ProjectEditorBody: FC<Props> = ({ projectsCrud, project, onClose }) => { const ProjectEditorBody: FC<Props> = props => {
return ( return (
<Tabs <Tabs
defaultValue="general" defaultValue="general"
@ -25,11 +24,7 @@ const ProjectEditorBody: FC<Props> = ({ projectsCrud, project, onClose }) => {
</Tabs.Tab> </Tabs.Tab>
</Tabs.List> </Tabs.List>
<Tabs.Panel value="general"> <Tabs.Panel value="general">
<GeneralTab <GeneralTab {...props} />
projectsCrud={projectsCrud}
project={project}
onClose={onClose}
/>
</Tabs.Panel> </Tabs.Panel>
</Tabs> </Tabs>
); );

View File

@ -0,0 +1,3 @@
import ProjectEditorDrawer from "@/app/deals/drawers/ProjectEditorDrawer/ProjectEditorDrawer";
export default ProjectEditorDrawer;

View File

@ -0,0 +1,43 @@
import { FC } from "react";
import { isEqual } from "lodash";
import { Button, Group } from "@mantine/core";
import { UseFormReturnType } from "@mantine/form";
import { ProjectSchema } from "@/lib/client";
type Props = {
form: UseFormReturnType<ProjectSchema>;
initialValues: Partial<ProjectSchema>;
onDelete: () => void;
};
const Footer: FC<Props> = ({ form, initialValues, onDelete }) => {
return (
<Group
justify={"space-between"}
wrap={"nowrap"}>
<Group wrap={"nowrap"}>
<Button
type={"submit"}
disabled={isEqual(form.values, initialValues)}
variant={"filled"}>
Сохранить
</Button>
<Button
type={"reset"}
onClick={() => form.reset()}
disabled={isEqual(form.values, initialValues)}
variant={"default"}>
Отменить
</Button>
</Group>
<Button
onClick={onDelete}
color={"red"}
variant={"outline"}>
Удалить
</Button>
</Group>
);
};
export default Footer;

View File

@ -0,0 +1,43 @@
import { FC } from "react";
import { Stack, TextInput } from "@mantine/core";
import { useForm } from "@mantine/form";
import Footer from "@/app/deals/drawers/ProjectEditorDrawer/tabs/GeneralTab/Footer";
import { ProjectSchema } from "@/lib/client";
type Props = {
value: ProjectSchema;
onChange: (value: ProjectSchema) => void;
onDelete: (value: ProjectSchema) => void;
};
const GeneralTab: FC<Props> = ({ value, onChange, onDelete }) => {
const form = useForm<ProjectSchema>({
initialValues: value,
validate: {
name: value => !value && "Введите название",
},
});
const onSubmit = (values: ProjectSchema) => {
onChange(values);
form.setInitialValues(values);
};
return (
<form onSubmit={form.onSubmit(onSubmit)}>
<Stack p={"md"}>
<TextInput
label={"Название"}
{...form.getInputProps("name")}
/>
<Footer
form={form}
initialValues={value}
onDelete={() => onDelete(value)}
/>
</Stack>
</form>
);
};
export default GeneralTab;

View File

@ -1,3 +0,0 @@
import ProjectsEditorDrawer from "@/app/deals/drawers/ProjectsEditorDrawer/ProjectsEditorDrawer";
export default ProjectsEditorDrawer;

View File

@ -3,17 +3,18 @@
import React, { FC } from "react"; import React, { FC } from "react";
import { Center, Divider, Drawer, rem, Text } from "@mantine/core"; import { Center, Divider, Drawer, rem, Text } from "@mantine/core";
import { ProjectsContextProvider } from "@/app/deals/contexts/ProjectsContext"; import { ProjectsContextProvider } from "@/app/deals/contexts/ProjectsContext";
import ProjectsDrawerBody from "@/app/deals/drawers/BoardStatusesEditorDrawer/components/ProjectsDrawerBody"; import ProjectsDrawerBody from "@/app/deals/drawers/StatusesMobileEditorDrawer/components/ProjectsDrawerBody";
import { DrawerProps } from "@/drawers/types"; import { DrawerProps } from "@/drawers/types";
import { ProjectSchema } from "@/lib/client";
type Props = { type Props = {
setSelectedProjectId: (projectId: number | null) => void; onSelect: (project: ProjectSchema | null) => void;
}; };
const ProjectsEditorDrawer: FC<DrawerProps<Props>> = ({ const ProjectsMobileEditorDrawer: FC<DrawerProps<Props>> = ({
opened, opened,
onClose, onClose,
props: { setSelectedProjectId }, props: { onSelect },
}) => { }) => {
return ( return (
<Drawer <Drawer
@ -38,7 +39,7 @@ const ProjectsEditorDrawer: FC<DrawerProps<Props>> = ({
<Divider /> <Divider />
<ProjectsContextProvider> <ProjectsContextProvider>
<ProjectsDrawerBody <ProjectsDrawerBody
setSelectedProjectId={setSelectedProjectId} onSelect={onSelect}
onClose={onClose} onClose={onClose}
/> />
</ProjectsContextProvider> </ProjectsContextProvider>
@ -46,4 +47,4 @@ const ProjectsEditorDrawer: FC<DrawerProps<Props>> = ({
); );
}; };
export default ProjectsEditorDrawer; export default ProjectsMobileEditorDrawer;

View File

@ -2,21 +2,17 @@ import React, { FC } from "react";
import { Box, Group, Text } from "@mantine/core"; import { Box, Group, Text } from "@mantine/core";
import { modals } from "@mantine/modals"; import { modals } from "@mantine/modals";
import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext"; import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext";
import ProjectMenu from "@/app/deals/drawers/ProjectsEditorDrawer/components/ProjectMenu"; import ProjectMenu from "@/app/deals/drawers/ProjectsMobileEditorDrawer/components/ProjectMenu";
import { ProjectSchema } from "@/lib/client"; import { ProjectSchema } from "@/lib/client";
import styles from "./../ProjectsEditorDrawer.module.css"; import styles from "./../ProjectsEditorDrawer.module.css";
type Props = { type Props = {
project: ProjectSchema; project: ProjectSchema;
setSelectedProjectId: (projectId: number | null) => void; onSelect: (project: ProjectSchema | null) => void;
closeDrawer: () => void; closeDrawer: () => void;
}; };
const ProjectMobile: FC<Props> = ({ const ProjectMobile: FC<Props> = ({ project, onSelect, closeDrawer }) => {
project,
setSelectedProjectId,
closeDrawer,
}) => {
const { projectsCrud } = useProjectsContext(); const { projectsCrud } = useProjectsContext();
const startEditing = () => { const startEditing = () => {
@ -32,7 +28,7 @@ const ProjectMobile: FC<Props> = ({
}; };
const onClick = () => { const onClick = () => {
setSelectedProjectId(project.id); onSelect(project);
closeDrawer(); closeDrawer();
}; };

View File

@ -0,0 +1,3 @@
import ProjectsMobileEditorDrawer from "./ProjectsMobileEditorDrawer";
export default ProjectsMobileEditorDrawer;

View File

@ -1,70 +0,0 @@
import { FC, useState } from "react";
import { isEqual } from "lodash";
import { Button, Group, Stack, TextInput } from "@mantine/core";
import { useForm } from "@mantine/form";
import { ProjectsCrud } from "@/hooks/cruds/useProjectsCrud";
import { ProjectSchema } from "@/lib/client";
type Props = {
projectsCrud: ProjectsCrud;
project: ProjectSchema;
onClose: () => void;
};
const GeneralTab: FC<Props> = ({ project, projectsCrud, onClose }) => {
const [initialValues, setInitialValues] = useState(project);
const form = useForm<ProjectSchema>({
initialValues,
validate: {
name: value => !value && "Введите название",
},
});
const onSubmit = (values: ProjectSchema) => {
projectsCrud.onUpdate(project.id, values);
setInitialValues(values);
};
const onDelete = () => {
projectsCrud.onDelete(project, onClose);
};
return (
<form onSubmit={form.onSubmit(onSubmit)}>
<Stack p={"md"}>
<TextInput
label={"Название"}
{...form.getInputProps("name")}
/>
<Group
justify={"space-between"}
wrap={"nowrap"}>
<Group wrap={"nowrap"}>
<Button
type={"submit"}
disabled={isEqual(form.values, initialValues)}
variant={"filled"}>
Сохранить
</Button>
<Button
type={"reset"}
onClick={() => form.reset()}
disabled={isEqual(form.values, initialValues)}
variant={"default"}>
Отменить
</Button>
</Group>
<Button
onClick={onDelete}
color={"red"}
variant={"outline"}>
Удалить
</Button>
</Group>
</Stack>
</form>
);
};
export default GeneralTab;

View File

@ -1,3 +0,0 @@
import SelectedProjectEditorDrawer from "@/app/deals/drawers/SelectedProjectEditorDrawer/SelectedProjectEditorDrawer";
export default SelectedProjectEditorDrawer;

View File

@ -2,8 +2,8 @@
import React, { FC } from "react"; import React, { FC } from "react";
import { Drawer, rem } from "@mantine/core"; import { Drawer, rem } from "@mantine/core";
import StatusesDrawerBody from "@/app/deals/drawers/BoardStatusesEditorDrawer/components/StatusesDrawerBody"; import StatusesDrawerBody from "@/app/deals/drawers/StatusesMobileEditorDrawer/components/StatusesDrawerBody";
import { BoardStatusesContextProvider } from "@/app/deals/drawers/BoardStatusesEditorDrawer/contexts/BoardStatusesContext"; import { StatusesMobileContextProvider } from "@/app/deals/drawers/StatusesMobileEditorDrawer/contexts/BoardStatusesContext";
import { DrawerProps } from "@/drawers/types"; import { DrawerProps } from "@/drawers/types";
import { BoardSchema } from "@/lib/client"; import { BoardSchema } from "@/lib/client";
@ -11,7 +11,7 @@ type Props = {
board: BoardSchema; board: BoardSchema;
}; };
const BoardStatusesEditorDrawer: FC<DrawerProps<Props>> = ({ const StatusesMobileEditorDrawer: FC<DrawerProps<Props>> = ({
opened, opened,
onClose, onClose,
props: { board }, props: { board },
@ -33,11 +33,11 @@ const BoardStatusesEditorDrawer: FC<DrawerProps<Props>> = ({
gap: rem(10), gap: rem(10),
}, },
}}> }}>
<BoardStatusesContextProvider board={board}> <StatusesMobileContextProvider board={board}>
<StatusesDrawerBody onClose={onClose} /> <StatusesDrawerBody onClose={onClose} />
</BoardStatusesContextProvider> </StatusesMobileContextProvider>
</Drawer> </Drawer>
); );
}; };
export default BoardStatusesEditorDrawer; export default StatusesMobileEditorDrawer;

View File

@ -2,10 +2,10 @@ import { FC } from "react";
import { IconPlus } from "@tabler/icons-react"; import { IconPlus } from "@tabler/icons-react";
import { Box, Group, Text } from "@mantine/core"; import { Box, Group, Text } from "@mantine/core";
import { modals } from "@mantine/modals"; import { modals } from "@mantine/modals";
import { useBoardStatusesContext } from "@/app/deals/drawers/BoardStatusesEditorDrawer/contexts/BoardStatusesContext"; import { useStatusesMobileContext } from "@/app/deals/drawers/StatusesMobileEditorDrawer/contexts/BoardStatusesContext";
const CreateStatusButton: FC = () => { const CreateStatusButton: FC = () => {
const { statusesCrud } = useBoardStatusesContext(); const { statusesCrud } = useStatusesMobileContext();
const onStartCreating = () => { const onStartCreating = () => {
modals.openContextModal({ modals.openContextModal({

View File

@ -1,15 +1,16 @@
import React, { FC } from "react"; import React, { FC } from "react";
import { Stack } from "@mantine/core"; import { Stack } from "@mantine/core";
import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext"; import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext";
import CreateProjectButton from "@/app/deals/drawers/ProjectsEditorDrawer/components/CreateProjectButton"; import CreateProjectButton from "@/app/deals/drawers/ProjectsMobileEditorDrawer/components/CreateProjectButton";
import ProjectMobile from "@/app/deals/drawers/ProjectsEditorDrawer/components/ProjectMobile"; import ProjectMobile from "@/app/deals/drawers/ProjectsMobileEditorDrawer/components/ProjectMobile";
import { ProjectSchema } from "@/lib/client";
type Props = { type Props = {
setSelectedProjectId: (projectId: number | null) => void; onSelect: (project: ProjectSchema | null) => void;
onClose: () => void; onClose: () => void;
}; };
const ProjectsDrawerBody: FC<Props> = ({ setSelectedProjectId, onClose }) => { const ProjectsDrawerBody: FC<Props> = ({ onSelect, onClose }) => {
const { projects } = useProjectsContext(); const { projects } = useProjectsContext();
return ( return (
@ -19,7 +20,7 @@ const ProjectsDrawerBody: FC<Props> = ({ setSelectedProjectId, onClose }) => {
<ProjectMobile <ProjectMobile
key={index} key={index}
project={project} project={project}
setSelectedProjectId={setSelectedProjectId} onSelect={onSelect}
closeDrawer={onClose} closeDrawer={onClose}
/> />
))} ))}

View File

@ -2,7 +2,7 @@ import React, { FC } from "react";
import { Box, Group, Text } from "@mantine/core"; import { Box, Group, Text } from "@mantine/core";
import { modals } from "@mantine/modals"; import { modals } from "@mantine/modals";
import StatusMenu from "@/app/deals/components/shared/StatusMenu/StatusMenu"; import StatusMenu from "@/app/deals/components/shared/StatusMenu/StatusMenu";
import { useBoardStatusesContext } from "@/app/deals/drawers/BoardStatusesEditorDrawer/contexts/BoardStatusesContext"; import { useStatusesMobileContext } from "@/app/deals/drawers/StatusesMobileEditorDrawer/contexts/BoardStatusesContext";
import { BoardSchema, StatusSchema } from "@/lib/client"; import { BoardSchema, StatusSchema } from "@/lib/client";
type Props = { type Props = {
@ -11,7 +11,7 @@ type Props = {
}; };
const StatusMobile: FC<Props> = ({ status, board }) => { const StatusMobile: FC<Props> = ({ status, board }) => {
const { statusesCrud } = useBoardStatusesContext(); const { statusesCrud } = useStatusesMobileContext();
const startEditing = () => { const startEditing = () => {
modals.openContextModal({ modals.openContextModal({

View File

@ -1,9 +1,9 @@
import React, { FC, ReactNode } from "react"; import React, { FC, ReactNode } from "react";
import { IconChevronLeft, IconGripVertical } from "@tabler/icons-react"; import { IconChevronLeft, IconGripVertical } from "@tabler/icons-react";
import { Box, Center, Divider, Group, Text } from "@mantine/core"; import { Box, Center, Divider, Group, Text } from "@mantine/core";
import CreateStatusButton from "@/app/deals/drawers/BoardStatusesEditorDrawer/components/CreateStatusButton"; import CreateStatusButton from "@/app/deals/drawers/StatusesMobileEditorDrawer/components/CreateStatusButton";
import StatusMobile from "@/app/deals/drawers/BoardStatusesEditorDrawer/components/StatusMobile"; import StatusMobile from "@/app/deals/drawers/StatusesMobileEditorDrawer/components/StatusMobile";
import { useBoardStatusesContext } from "@/app/deals/drawers/BoardStatusesEditorDrawer/contexts/BoardStatusesContext"; import { useStatusesMobileContext } from "@/app/deals/drawers/StatusesMobileEditorDrawer/contexts/BoardStatusesContext";
import SortableDnd from "@/components/dnd/SortableDnd"; import SortableDnd from "@/components/dnd/SortableDnd";
import { StatusSchema } from "@/lib/client"; import { StatusSchema } from "@/lib/client";
@ -12,7 +12,7 @@ type Props = {
}; };
const StatusesDrawerBody: FC<Props> = ({ onClose }) => { const StatusesDrawerBody: FC<Props> = ({ onClose }) => {
const { statusesCrud, board, statuses } = useBoardStatusesContext(); const { statusesCrud, board, statuses } = useStatusesMobileContext();
const renderDraggable = () => ( const renderDraggable = () => (
<Box p={"xs"}> <Box p={"xs"}>

View File

@ -44,7 +44,7 @@ const useBoardStatusesContextState = ({
}; };
}; };
export const [BoardStatusesContextProvider, useBoardStatusesContext] = export const [StatusesMobileContextProvider, useStatusesMobileContext] =
makeContext<BoardStatusesContextState, Props>( makeContext<BoardStatusesContextState, Props>(
useBoardStatusesContextState, useBoardStatusesContextState,
"BoardStatuses" "BoardStatuses"

View File

@ -0,0 +1,3 @@
import StatusesMobileEditorDrawer from "@/app/deals/drawers/StatusesMobileEditorDrawer/StatusesMobileEditorDrawer";
export default StatusesMobileEditorDrawer;

View File

@ -49,7 +49,7 @@ const InPlaceInputDesktop: FC<Props> = ({
}; };
const onCancelCreating = () => { const onCancelCreating = () => {
setLocalValue(localValue); setLocalValue("");
setIsWriting(false); setIsWriting(false);
}; };
@ -58,6 +58,7 @@ const InPlaceInputDesktop: FC<Props> = ({
if (val) { if (val) {
onChange(val); onChange(val);
} }
setLocalValue("");
setIsWriting(false); setIsWriting(false);
}; };

View File

@ -1,15 +1,15 @@
import BoardStatusesEditorDrawer from "@/app/deals/drawers/BoardStatusesEditorDrawer"; import BoardsMobileEditorDrawer from "@/app/deals/drawers/BoardsMobileEditorDrawer";
import StatusesMobileEditorDrawer from "../app/deals/drawers/StatusesMobileEditorDrawer";
import DealEditorDrawer from "@/app/deals/drawers/DealEditorDrawer/DealEditorDrawer"; import DealEditorDrawer from "@/app/deals/drawers/DealEditorDrawer/DealEditorDrawer";
import ProjectBoardsEditorDrawer from "@/app/deals/drawers/ProjectBoardsEditorDrawer"; import ProjectEditorDrawer from "@/app/deals/drawers/ProjectEditorDrawer";
import ProjectsEditorDrawer from "@/app/deals/drawers/ProjectsEditorDrawer"; import ProjectsMobileEditorDrawer from "@/app/deals/drawers/ProjectsMobileEditorDrawer";
import SelectedProjectEditorDrawer from "@/app/deals/drawers/SelectedProjectEditorDrawer";
const drawerRegistry = { const drawerRegistry = {
projectsEditorDrawer: ProjectsEditorDrawer, projectsMobileEditorDrawer: ProjectsMobileEditorDrawer,
boardStatusesEditorDrawer: BoardStatusesEditorDrawer, statusesMobileEditorDrawer: StatusesMobileEditorDrawer,
projectBoardsEditorDrawer: ProjectBoardsEditorDrawer, boardsMobileEditorDrawer: BoardsMobileEditorDrawer,
dealEditorDrawer: DealEditorDrawer, dealEditorDrawer: DealEditorDrawer,
selectedProjectEditorDrawer: SelectedProjectEditorDrawer, projectEditorDrawer: ProjectEditorDrawer,
}; };
export default drawerRegistry; export default drawerRegistry;

View File

@ -16,6 +16,10 @@ export type BoardSchema = {
* Lexorank * Lexorank
*/ */
lexorank: string; lexorank: string;
/**
* Projectid
*/
projectId: number;
}; };
/** /**

View File

@ -9,6 +9,7 @@ export const zBoardSchema = z.object({
id: z.int(), id: z.int(),
name: z.string(), name: z.string(),
lexorank: z.string(), lexorank: z.string(),
projectId: z.int(),
}); });
/** /**