feat: select view buttons

This commit is contained in:
2025-08-28 11:00:41 +04:00
parent e9b8cdb010
commit 4323695069
14 changed files with 220 additions and 22 deletions

View File

@ -0,0 +1,28 @@
"use client";
import { Group } from "@mantine/core";
import ViewSelector from "@/app/deals/components/desktop/ViewSelector/ViewSelector";
import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext";
import ProjectSelect from "@/components/selects/ProjectSelect/ProjectSelect";
import useIsMobile from "@/hooks/utils/useIsMobile";
const TopToolPanel = () => {
const { projects, setSelectedProjectId, selectedProject } =
useProjectsContext();
const isMobile = useIsMobile();
if (isMobile) return;
return (
<Group justify={"space-between"}>
<ViewSelector />
<ProjectSelect
data={projects}
value={selectedProject}
onChange={value => value && setSelectedProjectId(value.id)}
/>
</Group>
);
};
export default TopToolPanel;

View File

@ -0,0 +1,9 @@
.container {
width: 100%;
border-radius: var(--mantine-radius-xl);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
padding: var(--mantine-spacing-xs);
}

View File

@ -0,0 +1,34 @@
"use client";
import { FC, PropsWithChildren } from "react";
import { Button } from "@mantine/core";
import { useViewContext, View } from "@/app/deals/contexts/ViewContext";
import SmallPageBlock from "@/components/layout/SmallPageBlock/SmallPageBlock";
import style from "./ViewSelectButton.module.css";
type Props = {
viewName: View;
};
const ViewSelectButton: FC<PropsWithChildren<Props>> = ({
viewName,
children,
}) => {
const { view, setView } = useViewContext();
return (
<SmallPageBlock
active={view === viewName}
style={{ borderRadius: "var(--mantine-radius-xl)" }}>
<Button
unstyled
onClick={() => setView(viewName)}
radius="xl"
className={style.container}>
{children}
</Button>
</SmallPageBlock>
);
};
export default ViewSelectButton;

View File

@ -0,0 +1,25 @@
import {
IconCalendarWeekFilled,
IconLayoutDashboard,
IconMenu2,
} from "@tabler/icons-react";
import { Group } from "@mantine/core";
import ViewSelectButton from "@/app/deals/components/desktop/ViewSelectButton/ViewSelectButton";
const ViewSelector = () => {
return (
<Group>
<ViewSelectButton viewName={"board"}>
<IconLayoutDashboard />
</ViewSelectButton>
<ViewSelectButton viewName={"table"}>
<IconMenu2 />
</ViewSelectButton>
<ViewSelectButton viewName={"schedule"}>
<IconCalendarWeekFilled />
</ViewSelectButton>
</Group>
);
};
export default ViewSelector;

View File

@ -1,6 +1,6 @@
.container {
@media (min-width: 48em) {
max-width: calc(100vw - 450px);
max-width: calc(100vw - 210px - var(--mantine-spacing-md));
}
@media (max-width: 48em) {
max-width: 100vw;

View File

@ -0,0 +1,28 @@
"use client";
import { Space } from "@mantine/core";
import MainBlockHeader from "@/app/deals/components/mobile/MainBlockHeader/MainBlockHeader";
import Funnel from "@/app/deals/components/shared/Funnel/Funnel";
import { DealsContextProvider } from "@/app/deals/contexts/DealsContext";
import { useViewContext } from "@/app/deals/contexts/ViewContext";
const PageBody = () => {
const { view } = useViewContext();
if (view === "board")
return (
<>
<MainBlockHeader />
<Space h={"md"} />
<DealsContextProvider>
<Funnel />
</DealsContextProvider>
</>
);
if (view === "table") return <>-</>;
return <>-</>;
};
export default PageBody;

View File

@ -1,6 +1,6 @@
.container {
height: calc(100vh - 150px);
height: calc(100vh - 210px);
@media (max-width: 48em) {
width: 80vw;
height: calc(100vh - 215px);

View File

@ -0,0 +1,23 @@
"use client";
import { useState } from "react";
import makeContext from "@/lib/contextFactory/contextFactory";
export type View = "board" | "table" | "schedule";
type ViewContextState = {
view: View;
setView: (view: View) => void;
};
const useViewContextState = (): ViewContextState => {
const [view, setView] = useState<View>("board");
return {
view,
setView,
};
};
export const [ViewContextProvider, useViewContext] =
makeContext<ViewContextState>(useViewContextState, "View");

View File

@ -3,12 +3,11 @@ import {
HydrationBoundary,
QueryClient,
} from "@tanstack/react-query";
import { Space } from "@mantine/core";
import Funnel from "@/app/deals/components/shared/Funnel/Funnel";
import Header from "@/app/deals/components/shared/Header/Header";
import PageBody from "@/app/deals/components/shared/PageBody/PageBody";
import { BoardsContextProvider } from "@/app/deals/contexts/BoardsContext";
import { ProjectsContextProvider } from "@/app/deals/contexts/ProjectsContext";
import { StatusesContextProvider } from "@/app/deals/contexts/StatusesContext";
import { ViewContextProvider } from "@/app/deals/contexts/ViewContext";
import PageBlock from "@/components/layout/PageBlock/PageBlock";
import PageContainer from "@/components/layout/PageContainer/PageContainer";
import {
@ -16,7 +15,7 @@ import {
getProjectsOptions,
} from "@/lib/client/@tanstack/react-query.gen";
import { combineProviders } from "@/utils/combineProviders";
import { DealsContextProvider } from "./contexts/DealsContext";
import TopToolPanel from "./components/desktop/TopToolPanel/TopToolPanel";
async function prefetchData() {
const queryClient = new QueryClient();
@ -39,18 +38,16 @@ export default async function DealsPage() {
[HydrationBoundary, { state: dehydrate(queryClient) }],
[ProjectsContextProvider],
[BoardsContextProvider],
[StatusesContextProvider]
[StatusesContextProvider],
[ViewContextProvider]
);
return (
<Providers>
<PageContainer>
<PageBlock className={"mobile-margin-height"}>
<Header />
<Space h={"md"} />
<DealsContextProvider>
<Funnel />
</DealsContextProvider>
<TopToolPanel />
<PageBlock>
<PageBody />
</PageBlock>
</PageContainer>
</Providers>