feat: select view buttons
This commit is contained in:
@ -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;
|
||||||
@ -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);
|
||||||
|
}
|
||||||
@ -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;
|
||||||
@ -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;
|
||||||
@ -1,6 +1,6 @@
|
|||||||
.container {
|
.container {
|
||||||
@media (min-width: 48em) {
|
@media (min-width: 48em) {
|
||||||
max-width: calc(100vw - 450px);
|
max-width: calc(100vw - 210px - var(--mantine-spacing-md));
|
||||||
}
|
}
|
||||||
@media (max-width: 48em) {
|
@media (max-width: 48em) {
|
||||||
max-width: 100vw;
|
max-width: 100vw;
|
||||||
|
|||||||
28
src/app/deals/components/shared/PageBody/PageBody.tsx
Normal file
28
src/app/deals/components/shared/PageBody/PageBody.tsx
Normal 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;
|
||||||
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
.container {
|
.container {
|
||||||
height: calc(100vh - 150px);
|
height: calc(100vh - 210px);
|
||||||
@media (max-width: 48em) {
|
@media (max-width: 48em) {
|
||||||
width: 80vw;
|
width: 80vw;
|
||||||
height: calc(100vh - 215px);
|
height: calc(100vh - 215px);
|
||||||
|
|||||||
23
src/app/deals/contexts/ViewContext.tsx
Normal file
23
src/app/deals/contexts/ViewContext.tsx
Normal 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");
|
||||||
@ -3,12 +3,11 @@ import {
|
|||||||
HydrationBoundary,
|
HydrationBoundary,
|
||||||
QueryClient,
|
QueryClient,
|
||||||
} from "@tanstack/react-query";
|
} from "@tanstack/react-query";
|
||||||
import { Space } from "@mantine/core";
|
import PageBody from "@/app/deals/components/shared/PageBody/PageBody";
|
||||||
import Funnel from "@/app/deals/components/shared/Funnel/Funnel";
|
|
||||||
import Header from "@/app/deals/components/shared/Header/Header";
|
|
||||||
import { BoardsContextProvider } from "@/app/deals/contexts/BoardsContext";
|
import { BoardsContextProvider } from "@/app/deals/contexts/BoardsContext";
|
||||||
import { ProjectsContextProvider } from "@/app/deals/contexts/ProjectsContext";
|
import { ProjectsContextProvider } from "@/app/deals/contexts/ProjectsContext";
|
||||||
import { StatusesContextProvider } from "@/app/deals/contexts/StatusesContext";
|
import { StatusesContextProvider } from "@/app/deals/contexts/StatusesContext";
|
||||||
|
import { ViewContextProvider } from "@/app/deals/contexts/ViewContext";
|
||||||
import PageBlock from "@/components/layout/PageBlock/PageBlock";
|
import PageBlock from "@/components/layout/PageBlock/PageBlock";
|
||||||
import PageContainer from "@/components/layout/PageContainer/PageContainer";
|
import PageContainer from "@/components/layout/PageContainer/PageContainer";
|
||||||
import {
|
import {
|
||||||
@ -16,7 +15,7 @@ import {
|
|||||||
getProjectsOptions,
|
getProjectsOptions,
|
||||||
} from "@/lib/client/@tanstack/react-query.gen";
|
} from "@/lib/client/@tanstack/react-query.gen";
|
||||||
import { combineProviders } from "@/utils/combineProviders";
|
import { combineProviders } from "@/utils/combineProviders";
|
||||||
import { DealsContextProvider } from "./contexts/DealsContext";
|
import TopToolPanel from "./components/desktop/TopToolPanel/TopToolPanel";
|
||||||
|
|
||||||
async function prefetchData() {
|
async function prefetchData() {
|
||||||
const queryClient = new QueryClient();
|
const queryClient = new QueryClient();
|
||||||
@ -39,18 +38,16 @@ export default async function DealsPage() {
|
|||||||
[HydrationBoundary, { state: dehydrate(queryClient) }],
|
[HydrationBoundary, { state: dehydrate(queryClient) }],
|
||||||
[ProjectsContextProvider],
|
[ProjectsContextProvider],
|
||||||
[BoardsContextProvider],
|
[BoardsContextProvider],
|
||||||
[StatusesContextProvider]
|
[StatusesContextProvider],
|
||||||
|
[ViewContextProvider]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Providers>
|
<Providers>
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
<PageBlock className={"mobile-margin-height"}>
|
<TopToolPanel />
|
||||||
<Header />
|
<PageBlock>
|
||||||
<Space h={"md"} />
|
<PageBody />
|
||||||
<DealsContextProvider>
|
|
||||||
<Funnel />
|
|
||||||
</DealsContextProvider>
|
|
||||||
</PageBlock>
|
</PageBlock>
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
</Providers>
|
</Providers>
|
||||||
|
|||||||
@ -18,13 +18,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-margin-height {
|
|
||||||
height: var(--page-height);
|
|
||||||
@media (min-width: 48em) {
|
|
||||||
margin: var(--mantine-spacing-md);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.container-full-height {
|
.container-full-height {
|
||||||
min-height: var(--page-height);
|
min-height: var(--page-height);
|
||||||
height: var(--page-height);
|
height: var(--page-height);
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|
||||||
@media (min-width: 48em) {
|
@media (min-width: 48em) {
|
||||||
gap: rem(10);
|
gap: var(--mantine-spacing-md);
|
||||||
|
padding: var(--mantine-spacing-md);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/components/layout/SmallPageBlock/SmallPageBlock.tsx
Normal file
24
src/components/layout/SmallPageBlock/SmallPageBlock.tsx
Normal file
@ -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<Props> = ({ children, style, active = false }) => {
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
className={classNames(
|
||||||
|
styles.container,
|
||||||
|
active && styles["container-active"]
|
||||||
|
)}
|
||||||
|
style={style}>
|
||||||
|
{children}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default SmallPageBlock;
|
||||||
@ -37,7 +37,10 @@ const EnterNameModal = ({
|
|||||||
<Flex
|
<Flex
|
||||||
gap={rem(10)}
|
gap={rem(10)}
|
||||||
direction={"column"}>
|
direction={"column"}>
|
||||||
<TextInput {...form.getInputProps("name")} />
|
<TextInput
|
||||||
|
{...form.getInputProps("name")}
|
||||||
|
data-autofocus
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
variant={"default"}
|
variant={"default"}
|
||||||
type={"submit"}>
|
type={"submit"}>
|
||||||
|
|||||||
Reference in New Issue
Block a user