diff --git a/src/app/deals/components/desktop/TopToolPanel/TopToolPanel.tsx b/src/app/deals/components/desktop/TopToolPanel/TopToolPanel.tsx
new file mode 100644
index 0000000..a64d375
--- /dev/null
+++ b/src/app/deals/components/desktop/TopToolPanel/TopToolPanel.tsx
@@ -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 (
+
+
+ value && setSelectedProjectId(value.id)}
+ />
+
+ );
+};
+
+export default TopToolPanel;
diff --git a/src/app/deals/components/desktop/ViewSelectButton/ViewSelectButton.module.css b/src/app/deals/components/desktop/ViewSelectButton/ViewSelectButton.module.css
new file mode 100644
index 0000000..b3ff25b
--- /dev/null
+++ b/src/app/deals/components/desktop/ViewSelectButton/ViewSelectButton.module.css
@@ -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);
+}
diff --git a/src/app/deals/components/desktop/ViewSelectButton/ViewSelectButton.tsx b/src/app/deals/components/desktop/ViewSelectButton/ViewSelectButton.tsx
new file mode 100644
index 0000000..02d9cea
--- /dev/null
+++ b/src/app/deals/components/desktop/ViewSelectButton/ViewSelectButton.tsx
@@ -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> = ({
+ viewName,
+ children,
+}) => {
+ const { view, setView } = useViewContext();
+
+ return (
+
+
+
+ );
+};
+
+export default ViewSelectButton;
diff --git a/src/app/deals/components/desktop/ViewSelector/ViewSelector.tsx b/src/app/deals/components/desktop/ViewSelector/ViewSelector.tsx
new file mode 100644
index 0000000..0029b93
--- /dev/null
+++ b/src/app/deals/components/desktop/ViewSelector/ViewSelector.tsx
@@ -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 (
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default ViewSelector;
diff --git a/src/app/deals/components/shared/Boards/Boards.module.css b/src/app/deals/components/shared/Boards/Boards.module.css
index 70b1827..390a722 100644
--- a/src/app/deals/components/shared/Boards/Boards.module.css
+++ b/src/app/deals/components/shared/Boards/Boards.module.css
@@ -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;
diff --git a/src/app/deals/components/shared/PageBody/PageBody.tsx b/src/app/deals/components/shared/PageBody/PageBody.tsx
new file mode 100644
index 0000000..5d7274e
--- /dev/null
+++ b/src/app/deals/components/shared/PageBody/PageBody.tsx
@@ -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 (
+ <>
+
+
+
+
+
+ >
+ );
+
+ if (view === "table") return <>->;
+
+ return <>->;
+};
+
+export default PageBody;
diff --git a/src/app/deals/components/shared/StatusColumnWrapper/StatusColumnWrapper.module.css b/src/app/deals/components/shared/StatusColumnWrapper/StatusColumnWrapper.module.css
index 0fd6c08..a37f91f 100644
--- a/src/app/deals/components/shared/StatusColumnWrapper/StatusColumnWrapper.module.css
+++ b/src/app/deals/components/shared/StatusColumnWrapper/StatusColumnWrapper.module.css
@@ -1,6 +1,6 @@
.container {
- height: calc(100vh - 150px);
+ height: calc(100vh - 210px);
@media (max-width: 48em) {
width: 80vw;
height: calc(100vh - 215px);
diff --git a/src/app/deals/contexts/ViewContext.tsx b/src/app/deals/contexts/ViewContext.tsx
new file mode 100644
index 0000000..f59cf20
--- /dev/null
+++ b/src/app/deals/contexts/ViewContext.tsx
@@ -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("board");
+
+ return {
+ view,
+ setView,
+ };
+};
+
+export const [ViewContextProvider, useViewContext] =
+ makeContext(useViewContextState, "View");
diff --git a/src/app/deals/page.tsx b/src/app/deals/page.tsx
index fefadd3..dd17a08 100644
--- a/src/app/deals/page.tsx
+++ b/src/app/deals/page.tsx
@@ -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 (
-
-
-
-
-
-
+
+
+
diff --git a/src/components/layout/PageBlock/PageBlock.module.css b/src/components/layout/PageBlock/PageBlock.module.css
index 6aa3a1f..e7e9eda 100644
--- a/src/components/layout/PageBlock/PageBlock.module.css
+++ b/src/components/layout/PageBlock/PageBlock.module.css
@@ -18,13 +18,6 @@
}
}
-.mobile-margin-height {
- height: var(--page-height);
- @media (min-width: 48em) {
- margin: var(--mantine-spacing-md);
- }
-}
-
.container-full-height {
min-height: var(--page-height);
height: var(--page-height);
diff --git a/src/components/layout/PageContainer/PageContainer.module.css b/src/components/layout/PageContainer/PageContainer.module.css
index 0c926b6..5d21c11 100644
--- a/src/components/layout/PageContainer/PageContainer.module.css
+++ b/src/components/layout/PageContainer/PageContainer.module.css
@@ -5,6 +5,7 @@
background-color: transparent;
@media (min-width: 48em) {
- gap: rem(10);
+ gap: var(--mantine-spacing-md);
+ padding: var(--mantine-spacing-md);
}
}
diff --git a/src/components/layout/SmallPageBlock/SmallPageBlock.module.css b/src/components/layout/SmallPageBlock/SmallPageBlock.module.css
new file mode 100644
index 0000000..dd53857
--- /dev/null
+++ b/src/components/layout/SmallPageBlock/SmallPageBlock.module.css
@@ -0,0 +1,33 @@
+
+.container {
+ border-radius: var(--mantine-radius-lg);
+
+ @mixin dark {
+ background-color: var(--mantine-color-dark-7-5);
+ box-shadow: var(--dark-shadow);
+ }
+ @mixin light {
+ background-color: var(--color-light-whitesmoke);
+ box-shadow: var(--light-shadow);
+ }
+}
+
+.container-active {
+ @mixin dark {
+ color: dodgerblue;
+ }
+ @mixin light {
+ background-color: var(--color-light-aqua);
+ box-shadow: var(--light-thick-shadow);
+ }
+}
+
+.container:hover {
+ @mixin dark {
+ box-shadow: var(--dark-thick-shadow);
+ }
+ @mixin light {
+ background-color: var(--color-light-aqua);
+ box-shadow: var(--light-thick-shadow);
+ }
+}
diff --git a/src/components/layout/SmallPageBlock/SmallPageBlock.tsx b/src/components/layout/SmallPageBlock/SmallPageBlock.tsx
new file mode 100644
index 0000000..f0021ea
--- /dev/null
+++ b/src/components/layout/SmallPageBlock/SmallPageBlock.tsx
@@ -0,0 +1,24 @@
+import { CSSProperties, FC, ReactNode } from "react";
+import classNames from "classnames";
+import { Box } from "@mantine/core";
+import styles from "@/components/layout/SmallPageBlock/SmallPageBlock.module.css";
+
+type Props = {
+ children: ReactNode;
+ style?: CSSProperties;
+ active?: boolean;
+};
+
+const SmallPageBlock: FC = ({ children, style, active = false }) => {
+ return (
+
+ {children}
+
+ );
+};
+export default SmallPageBlock;
diff --git a/src/modals/EnterNameModal/EnterNameModal.tsx b/src/modals/EnterNameModal/EnterNameModal.tsx
index f77966b..7a803a8 100644
--- a/src/modals/EnterNameModal/EnterNameModal.tsx
+++ b/src/modals/EnterNameModal/EnterNameModal.tsx
@@ -37,7 +37,10 @@ const EnterNameModal = ({
-
+