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

@ -0,0 +1,43 @@
"use client";
import React, { FC } from "react";
import { Drawer, rem } from "@mantine/core";
import StatusesDrawerBody from "@/app/deals/drawers/StatusesMobileEditorDrawer/components/StatusesDrawerBody";
import { StatusesMobileContextProvider } from "@/app/deals/drawers/StatusesMobileEditorDrawer/contexts/BoardStatusesContext";
import { DrawerProps } from "@/drawers/types";
import { BoardSchema } from "@/lib/client";
type Props = {
board: BoardSchema;
};
const StatusesMobileEditorDrawer: FC<DrawerProps<Props>> = ({
opened,
onClose,
props: { board },
}) => {
return (
<Drawer
size={"100%"}
position={"right"}
onClose={onClose}
removeScrollProps={{ allowPinchZoom: true }}
withCloseButton={false}
opened={opened}
trapFocus={false}
styles={{
body: {
height: "100%",
display: "flex",
flexDirection: "column",
gap: rem(10),
},
}}>
<StatusesMobileContextProvider board={board}>
<StatusesDrawerBody onClose={onClose} />
</StatusesMobileContextProvider>
</Drawer>
);
};
export default StatusesMobileEditorDrawer;

View File

@ -0,0 +1,33 @@
import { FC } from "react";
import { IconPlus } from "@tabler/icons-react";
import { Box, Group, Text } from "@mantine/core";
import { modals } from "@mantine/modals";
import { useStatusesMobileContext } from "@/app/deals/drawers/StatusesMobileEditorDrawer/contexts/BoardStatusesContext";
const CreateStatusButton: FC = () => {
const { statusesCrud } = useStatusesMobileContext();
const onStartCreating = () => {
modals.openContextModal({
modal: "enterNameModal",
title: "Создание колонки",
withCloseButton: true,
innerProps: {
onChange: values => statusesCrud.onCreate(values.name),
},
});
};
return (
<Group
ml={"xs"}
onClick={onStartCreating}>
<IconPlus />
<Box mt={5}>
<Text>Создать колонку</Text>
</Box>
</Group>
);
};
export default CreateStatusButton;

View File

@ -0,0 +1,33 @@
import React, { FC } from "react";
import { Stack } from "@mantine/core";
import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext";
import CreateProjectButton from "@/app/deals/drawers/ProjectsMobileEditorDrawer/components/CreateProjectButton";
import ProjectMobile from "@/app/deals/drawers/ProjectsMobileEditorDrawer/components/ProjectMobile";
import { ProjectSchema } from "@/lib/client";
type Props = {
onSelect: (project: ProjectSchema | null) => void;
onClose: () => void;
};
const ProjectsDrawerBody: FC<Props> = ({ onSelect, onClose }) => {
const { projects } = useProjectsContext();
return (
<>
<Stack gap={0}>
{projects.map((project, index) => (
<ProjectMobile
key={index}
project={project}
onSelect={onSelect}
closeDrawer={onClose}
/>
))}
</Stack>
<CreateProjectButton />
</>
);
};
export default ProjectsDrawerBody;

View File

@ -0,0 +1,49 @@
import React, { FC } from "react";
import { Box, Group, Text } from "@mantine/core";
import { modals } from "@mantine/modals";
import StatusMenu from "@/app/deals/components/shared/StatusMenu/StatusMenu";
import { useStatusesMobileContext } from "@/app/deals/drawers/StatusesMobileEditorDrawer/contexts/BoardStatusesContext";
import { BoardSchema, StatusSchema } from "@/lib/client";
type Props = {
status: StatusSchema;
board: BoardSchema;
};
const StatusMobile: FC<Props> = ({ status, board }) => {
const { statusesCrud } = useStatusesMobileContext();
const startEditing = () => {
modals.openContextModal({
modal: "enterNameModal",
title: "Редактирование статуса",
withCloseButton: true,
innerProps: {
onChange: values => statusesCrud.onUpdate(status.id, values),
value: status,
},
});
};
return (
<Group
w={"100%"}
pr={"md"}
py={"xs"}
justify={"space-between"}
wrap={"nowrap"}>
<Box>
<Text>{status.name}</Text>
</Box>
<StatusMenu
status={status}
board={board}
onDeleteStatus={statusesCrud.onDelete}
handleEdit={startEditing}
withChangeOrderButton={false}
/>
</Group>
);
};
export default StatusMobile;

View File

@ -0,0 +1,68 @@
import React, { FC, ReactNode } from "react";
import { IconChevronLeft, IconGripVertical } from "@tabler/icons-react";
import { Box, Center, Divider, Group, Text } from "@mantine/core";
import CreateStatusButton from "@/app/deals/drawers/StatusesMobileEditorDrawer/components/CreateStatusButton";
import StatusMobile from "@/app/deals/drawers/StatusesMobileEditorDrawer/components/StatusMobile";
import { useStatusesMobileContext } from "@/app/deals/drawers/StatusesMobileEditorDrawer/contexts/BoardStatusesContext";
import SortableDnd from "@/components/dnd/SortableDnd";
import { StatusSchema } from "@/lib/client";
type Props = {
onClose: () => void;
};
const StatusesDrawerBody: FC<Props> = ({ onClose }) => {
const { statusesCrud, board, statuses } = useStatusesMobileContext();
const renderDraggable = () => (
<Box p={"xs"}>
<IconGripVertical />
</Box>
);
const renderStatus = (
status: StatusSchema,
renderDraggable?: (item: StatusSchema) => ReactNode
) => {
return (
<Group wrap={"nowrap"}>
{renderDraggable && renderDraggable(status)}
<StatusMobile
status={status}
board={board}
/>
</Group>
);
};
const onDragEnd = (itemId: number, newLexorank: string) =>
statusesCrud.onUpdate(itemId, { lexorank: newLexorank });
return (
<>
<Group justify={"space-between"}>
<Box
onClick={onClose}
p={"xs"}>
<IconChevronLeft />
</Box>
<Center>
<Text>{board.name}</Text>
</Center>
<Box p={"lg"} />
</Group>
<Divider />
<SortableDnd
initialItems={statuses}
onDragEnd={onDragEnd}
renderItem={renderStatus}
renderDraggable={renderDraggable}
dragHandleStyle={{ width: "auto" }}
vertical
/>
<CreateStatusButton />
</>
);
};
export default StatusesDrawerBody;

View File

@ -0,0 +1,51 @@
"use client";
import { StatusesCrud, useStatusesCrud } from "@/hooks/cruds/useStatusesCrud";
import useStatusesList from "@/hooks/lists/useStatusesList";
import { BoardSchema, StatusSchema } from "@/lib/client";
import makeContext from "@/lib/contextFactory/contextFactory";
type BoardStatusesContextState = {
board: BoardSchema;
statuses: StatusSchema[];
setStatuses: (statuses: StatusSchema[]) => void;
refetchStatuses: () => void;
statusesCrud: StatusesCrud;
};
type Props = {
board: BoardSchema;
};
const useBoardStatusesContextState = ({
board,
}: Props): BoardStatusesContextState => {
const {
statuses,
setStatuses,
refetch: refetchStatuses,
queryKey,
} = useStatusesList({
boardId: board.id,
});
const statusesCrud = useStatusesCrud({
statuses,
boardId: board.id,
queryKey,
});
return {
board,
statuses,
setStatuses,
refetchStatuses,
statusesCrud,
};
};
export const [StatusesMobileContextProvider, useStatusesMobileContext] =
makeContext<BoardStatusesContextState, Props>(
useBoardStatusesContextState,
"BoardStatuses"
);

View File

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