feat: actions page for mobiles
This commit is contained in:
15
src/app/actions/components/Action/Action.module.css
Normal file
15
src/app/actions/components/Action/Action.module.css
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
.link {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: var(--mantine-radius-lg);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
@mixin light {
|
||||||
|
color: var(--mantine-color-gray-7);
|
||||||
|
}
|
||||||
|
@mixin dark {
|
||||||
|
color: var(--mantine-color-dark-0);
|
||||||
|
}
|
||||||
|
}
|
||||||
36
src/app/actions/components/Action/Action.tsx
Normal file
36
src/app/actions/components/Action/Action.tsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { FC } from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { Button, Stack, Text } from "@mantine/core";
|
||||||
|
import ThemeIcon from "@/components/ui/ThemeIcon/ThemeIcon";
|
||||||
|
import LinkData from "@/types/LinkData";
|
||||||
|
import styles from "./Action.module.css";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
linkData: LinkData;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Action: FC<Props> = ({ linkData }) => {
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
href={linkData.href}
|
||||||
|
className={styles.link}>
|
||||||
|
<Button
|
||||||
|
w={"100%"}
|
||||||
|
h={"100px"}
|
||||||
|
variant={"default"}>
|
||||||
|
<Stack
|
||||||
|
px={"xs"}
|
||||||
|
w={"100%"}
|
||||||
|
align={"center"}
|
||||||
|
gap={"xs"}>
|
||||||
|
<ThemeIcon size={"sm"}>
|
||||||
|
<linkData.icon />
|
||||||
|
</ThemeIcon>
|
||||||
|
<Text>{linkData.label}</Text>
|
||||||
|
</Stack>
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Action;
|
||||||
48
src/app/actions/components/PageBody/PageBody.tsx
Normal file
48
src/app/actions/components/PageBody/PageBody.tsx
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useMemo } from "react";
|
||||||
|
import { SimpleGrid, Stack } from "@mantine/core";
|
||||||
|
import Action from "@/app/actions/components/Action/Action";
|
||||||
|
import mobileButtonsData from "@/app/actions/data/mobileButtonsData";
|
||||||
|
import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext";
|
||||||
|
import PageBlock from "@/components/layout/PageBlock/PageBlock";
|
||||||
|
import ProjectSelect from "@/components/selects/ProjectSelect/ProjectSelect";
|
||||||
|
|
||||||
|
const PageBody = () => {
|
||||||
|
const { selectedProject, setSelectedProjectId, projects, modulesSet } =
|
||||||
|
useProjectsContext();
|
||||||
|
|
||||||
|
const filteredMobileButtonsData = useMemo(
|
||||||
|
() =>
|
||||||
|
mobileButtonsData.filter(
|
||||||
|
link => !link.moduleName || modulesSet.has(link.moduleName)
|
||||||
|
),
|
||||||
|
[modulesSet]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageBlock fullScreenMobile>
|
||||||
|
<Stack p={"xs"}>
|
||||||
|
<ProjectSelect
|
||||||
|
onChange={project =>
|
||||||
|
setSelectedProjectId(project?.id ?? null)
|
||||||
|
}
|
||||||
|
value={selectedProject}
|
||||||
|
data={projects}
|
||||||
|
/>
|
||||||
|
<SimpleGrid
|
||||||
|
type={"container"}
|
||||||
|
cols={2}>
|
||||||
|
{filteredMobileButtonsData.map((data, index) => (
|
||||||
|
<Action
|
||||||
|
linkData={data}
|
||||||
|
key={index}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</SimpleGrid>
|
||||||
|
</Stack>
|
||||||
|
</PageBlock>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PageBody;
|
||||||
26
src/app/actions/data/mobileButtonsData.tsx
Normal file
26
src/app/actions/data/mobileButtonsData.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { IconColumns, IconFileBarcode, IconUsers } from "@tabler/icons-react";
|
||||||
|
import { ModuleNames } from "@/modules/modules";
|
||||||
|
import LinkData from "@/types/LinkData";
|
||||||
|
|
||||||
|
const mobileButtonsData: LinkData[] = [
|
||||||
|
{
|
||||||
|
icon: IconUsers,
|
||||||
|
label: "Клиенты",
|
||||||
|
href: "/clients",
|
||||||
|
moduleName: ModuleNames.CLIENTS,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: IconColumns,
|
||||||
|
label: "Услуги",
|
||||||
|
href: "/services",
|
||||||
|
moduleName: ModuleNames.FULFILLMENT_BASE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: IconFileBarcode,
|
||||||
|
label: "Шаблоны штрихкодов",
|
||||||
|
href: "/barcode-templates",
|
||||||
|
moduleName: ModuleNames.FULFILLMENT_BASE,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default mobileButtonsData;
|
||||||
19
src/app/actions/page.tsx
Normal file
19
src/app/actions/page.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { Suspense } from "react";
|
||||||
|
import { Center, Loader } from "@mantine/core";
|
||||||
|
import PageContainer from "@/components/layout/PageContainer/PageContainer";
|
||||||
|
import PageBody from "./components/PageBody/PageBody";
|
||||||
|
|
||||||
|
export default async function ActionsPage() {
|
||||||
|
return (
|
||||||
|
<Suspense
|
||||||
|
fallback={
|
||||||
|
<Center h="50vh">
|
||||||
|
<Loader size="lg" />
|
||||||
|
</Center>
|
||||||
|
}>
|
||||||
|
<PageContainer>
|
||||||
|
<PageBody />
|
||||||
|
</PageContainer>
|
||||||
|
</Suspense>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,10 +1,10 @@
|
|||||||
import {
|
import {
|
||||||
IconCalendarWeekFilled,
|
IconCalendarWeekFilled,
|
||||||
IconCircleDotted,
|
IconLayoutGrid,
|
||||||
IconLayoutKanban,
|
IconLayoutKanban,
|
||||||
IconTable,
|
IconTable,
|
||||||
} from "@tabler/icons-react";
|
} from "@tabler/icons-react";
|
||||||
import LinkData from "@/components/layout/Navbar/types/LinkData";
|
import LinkData from "@/types/LinkData";
|
||||||
|
|
||||||
const buttonsData: LinkData[] = [
|
const buttonsData: LinkData[] = [
|
||||||
{
|
{
|
||||||
@ -23,9 +23,9 @@ const buttonsData: LinkData[] = [
|
|||||||
href: "/deals?view=schedule",
|
href: "/deals?view=schedule",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: IconCircleDotted,
|
icon: IconLayoutGrid,
|
||||||
label: "Label 3",
|
label: "Действия",
|
||||||
href: "/hihihaha",
|
href: "/actions",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +0,0 @@
|
|||||||
import { IconPlus } from "@tabler/icons-react";
|
|
||||||
|
|
||||||
type LinkData = {
|
|
||||||
icon: typeof IconPlus;
|
|
||||||
label: string;
|
|
||||||
href: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default LinkData;
|
|
||||||
@ -5,10 +5,12 @@ import { usePathname, useRouter } from "next/navigation";
|
|||||||
import { Group, Stack, Text } from "@mantine/core";
|
import { Group, Stack, Text } from "@mantine/core";
|
||||||
import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext";
|
import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext";
|
||||||
import ThemeIcon from "@/components/ui/ThemeIcon/ThemeIcon";
|
import ThemeIcon from "@/components/ui/ThemeIcon/ThemeIcon";
|
||||||
|
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||||
import linksData from "../data/linksData";
|
import linksData from "../data/linksData";
|
||||||
import NavbarClickable from "./NavbarClickable";
|
import NavbarClickable from "./NavbarClickable";
|
||||||
|
|
||||||
const NavbarLinks = () => {
|
const NavbarLinks = () => {
|
||||||
|
const isMobile = useIsMobile();
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { modulesSet, selectedProject } = useProjectsContext();
|
const { modulesSet, selectedProject } = useProjectsContext();
|
||||||
@ -21,7 +23,7 @@ const NavbarLinks = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (pathname !== "/deals") router.push("/deals");
|
if (!isMobile && pathname !== "/deals") router.push("/deals");
|
||||||
}, [selectedProject]);
|
}, [selectedProject]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -4,8 +4,8 @@ import {
|
|||||||
IconLayoutKanban,
|
IconLayoutKanban,
|
||||||
IconUsers,
|
IconUsers,
|
||||||
} from "@tabler/icons-react";
|
} from "@tabler/icons-react";
|
||||||
import LinkData from "@/components/layout/Navbar/types/LinkData";
|
|
||||||
import { ModuleNames } from "@/modules/modules";
|
import { ModuleNames } from "@/modules/modules";
|
||||||
|
import LinkData from "@/types/LinkData";
|
||||||
|
|
||||||
const linksData: LinkData[] = [
|
const linksData: LinkData[] = [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -51,11 +51,11 @@ const ClientDataForm: FC = () => {
|
|||||||
flex={1}
|
flex={1}
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
disabled
|
|
||||||
placeholder={"Наименование компании"}
|
placeholder={"Наименование компании"}
|
||||||
label={"Наименование компании"}
|
label={"Наименование компании"}
|
||||||
{...form.getInputProps("companyName")}
|
{...form.getInputProps("companyName")}
|
||||||
flex={1}
|
flex={1}
|
||||||
|
disabled={isEditorDisabled}
|
||||||
/>
|
/>
|
||||||
</FormFlexRow>
|
</FormFlexRow>
|
||||||
<FormFlexRow>
|
<FormFlexRow>
|
||||||
|
|||||||
Reference in New Issue
Block a user