feat: navbar and footer
This commit is contained in:
@ -44,14 +44,15 @@ const Board: FC<Props> = ({ board }) => {
|
|||||||
{board.name}
|
{board.name}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
{!isMobile && (
|
||||||
<BoardMenu
|
<BoardMenu
|
||||||
isHovered={
|
isHovered={
|
||||||
!isMobile &&
|
selectedBoard?.id === board.id || isHovered
|
||||||
(selectedBoard?.id === board.id || isHovered)
|
|
||||||
}
|
}
|
||||||
board={board}
|
board={board}
|
||||||
startEditing={startEditing}
|
startEditing={startEditing}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
modalTitle={"Редактирование доски"}
|
modalTitle={"Редактирование доски"}
|
||||||
|
|||||||
@ -11,15 +11,14 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const BoardMenu: FC<Props> = ({ board, startEditing, isHovered = true }) => {
|
const BoardMenu: FC<Props> = ({ board, startEditing, isHovered = true }) => {
|
||||||
const { selectedBoard, onDeleteBoard } = useBoardsContext();
|
const { onDeleteBoard } = useBoardsContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu>
|
<Menu>
|
||||||
<Menu.Target>
|
<Menu.Target>
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
opacity:
|
opacity: isHovered ? 1 : 0,
|
||||||
isHovered || selectedBoard?.id === board.id ? 1 : 0,
|
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
}}
|
}}
|
||||||
onClick={e => e.stopPropagation()}>
|
onClick={e => e.stopPropagation()}>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
.container {
|
.container {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
height: calc(100vh - 150px);
|
height: 100%;
|
||||||
|
|
||||||
@media (max-width: 48em) {
|
@media (max-width: 48em) {
|
||||||
width: 80vw;
|
width: 80vw;
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import Boards from "@/app/deals/components/shared/Boards/Boards";
|
|||||||
import { useBoardsContext } from "@/app/deals/contexts/BoardsContext";
|
import { useBoardsContext } from "@/app/deals/contexts/BoardsContext";
|
||||||
import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext";
|
import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext";
|
||||||
import ProjectSelect from "@/components/selects/ProjectSelect/ProjectSelect";
|
import ProjectSelect from "@/components/selects/ProjectSelect/ProjectSelect";
|
||||||
import { ColorSchemeToggle } from "@/components/ui/ColorSchemeToggle/ColorSchemeToggle";
|
|
||||||
import useIsMobile from "@/hooks/useIsMobile";
|
import useIsMobile from "@/hooks/useIsMobile";
|
||||||
|
|
||||||
const Header = () => {
|
const Header = () => {
|
||||||
@ -26,15 +25,12 @@ const Header = () => {
|
|||||||
justify={"end"}
|
justify={"end"}
|
||||||
wrap={"nowrap"}
|
wrap={"nowrap"}
|
||||||
pr={"md"}>
|
pr={"md"}>
|
||||||
<Group wrap={"nowrap"}>
|
|
||||||
<ColorSchemeToggle />
|
|
||||||
<ProjectSelect
|
<ProjectSelect
|
||||||
data={projects}
|
data={projects}
|
||||||
value={selectedProject}
|
value={selectedProject}
|
||||||
onChange={value => value && setSelectedProject(value)}
|
onChange={value => value && setSelectedProject(value)}
|
||||||
/>
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
|
|
||||||
.container {
|
.container {
|
||||||
height: calc(100vh - 150px);
|
|
||||||
|
|
||||||
@media (max-width: 48em) {
|
@media (max-width: 48em) {
|
||||||
width: 80vw;
|
width: 80vw;
|
||||||
|
height: calc(100vh - 200px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11,6 +10,10 @@
|
|||||||
border-radius: var(--mantine-spacing-md);
|
border-radius: var(--mantine-spacing-md);
|
||||||
gap: 0;
|
gap: 0;
|
||||||
|
|
||||||
|
@media (max-width: 48em) {
|
||||||
|
max-height: calc(100vh - 200px);
|
||||||
|
}
|
||||||
|
|
||||||
@mixin light {
|
@mixin light {
|
||||||
background-color: var(--color-light-aqua);
|
background-color: var(--color-light-aqua);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,7 @@ const StatusColumnWrapper = ({ renderHeader, children }: Props) => {
|
|||||||
scrollbarSize={10}
|
scrollbarSize={10}
|
||||||
type={"always"}
|
type={"always"}
|
||||||
scrollbars={"y"}>
|
scrollbars={"y"}>
|
||||||
<Stack mah={"calc(100vh - 220px)"}>{children}</Stack>
|
<Stack mah={"calc(100vh - 250px)"}>{children}</Stack>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -15,7 +15,7 @@ export default function DealsPage() {
|
|||||||
<ProjectsContextProvider>
|
<ProjectsContextProvider>
|
||||||
<BoardsContextProvider>
|
<BoardsContextProvider>
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
<PageBlock className={"mobile-padding-height"}>
|
<PageBlock className={"mobile-margin-height"}>
|
||||||
<Header />
|
<Header />
|
||||||
<StatusesContextProvider>
|
<StatusesContextProvider>
|
||||||
<DealsContextProvider>
|
<DealsContextProvider>
|
||||||
|
|||||||
@ -12,6 +12,8 @@
|
|||||||
--light-thick-shadow: 4px 4px 10px darkgray;
|
--light-thick-shadow: 4px 4px 10px darkgray;
|
||||||
--dark-shadow: 1px 1px 10px 1px var(--mantine-color-dark-6);
|
--dark-shadow: 1px 1px 10px 1px var(--mantine-color-dark-6);
|
||||||
--dark-thick-shadow: 5px 5px 10px 1px var(--mantine-color-dark-6);
|
--dark-thick-shadow: 5px 5px 10px 1px var(--mantine-color-dark-6);
|
||||||
|
/* Heights */
|
||||||
|
--page-height: calc(100vh - (var(--mantine-spacing-md) * 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import "swiper/css/pagination";
|
|||||||
import "swiper/css/scrollbar";
|
import "swiper/css/scrollbar";
|
||||||
import { ReactNode } from "react";
|
import { ReactNode } from "react";
|
||||||
import {
|
import {
|
||||||
|
AppShell,
|
||||||
ColorSchemeScript,
|
ColorSchemeScript,
|
||||||
mantineHtmlProps,
|
mantineHtmlProps,
|
||||||
MantineProvider,
|
MantineProvider,
|
||||||
@ -13,6 +14,11 @@ import { theme } from "@/theme";
|
|||||||
import "@/app/global.css";
|
import "@/app/global.css";
|
||||||
import { ModalsProvider } from "@mantine/modals";
|
import { ModalsProvider } from "@mantine/modals";
|
||||||
import { Notifications } from "@mantine/notifications";
|
import { Notifications } from "@mantine/notifications";
|
||||||
|
import AppShellFooterWrapper from "@/components/layout/AppShellWrappers/AppShellFooterWrapper";
|
||||||
|
import AppShellMainWrapper from "@/components/layout/AppShellWrappers/AppShellMainWrapper";
|
||||||
|
import AppShellNavbarWrapper from "@/components/layout/AppShellWrappers/AppShellNavbarWrapper";
|
||||||
|
import Footer from "@/components/layout/Footer/Footer";
|
||||||
|
import Navbar from "@/components/layout/Navbar/Navbar";
|
||||||
import { modals } from "@/modals/modals";
|
import { modals } from "@/modals/modals";
|
||||||
import { ReactQueryProvider } from "@/providers/ReactQueryProvider";
|
import { ReactQueryProvider } from "@/providers/ReactQueryProvider";
|
||||||
import ReduxProvider from "@/providers/ReduxProvider";
|
import ReduxProvider from "@/providers/ReduxProvider";
|
||||||
@ -58,7 +64,27 @@ export default function RootLayout({ children }: Props) {
|
|||||||
<ModalsProvider
|
<ModalsProvider
|
||||||
labels={{ confirm: "Да", cancel: "Нет" }}
|
labels={{ confirm: "Да", cancel: "Нет" }}
|
||||||
modals={modals}>
|
modals={modals}>
|
||||||
|
<AppShell
|
||||||
|
layout={"alt"}
|
||||||
|
withBorder={false}
|
||||||
|
navbar={{
|
||||||
|
width: 160,
|
||||||
|
breakpoint: "sm",
|
||||||
|
collapsed: {
|
||||||
|
desktop: false,
|
||||||
|
mobile: true,
|
||||||
|
},
|
||||||
|
}}>
|
||||||
|
<AppShellNavbarWrapper>
|
||||||
|
<Navbar />
|
||||||
|
</AppShellNavbarWrapper>
|
||||||
|
<AppShellMainWrapper>
|
||||||
{children}
|
{children}
|
||||||
|
</AppShellMainWrapper>
|
||||||
|
<AppShellFooterWrapper>
|
||||||
|
<Footer />
|
||||||
|
</AppShellFooterWrapper>
|
||||||
|
</AppShell>
|
||||||
</ModalsProvider>
|
</ModalsProvider>
|
||||||
</ReduxProvider>
|
</ReduxProvider>
|
||||||
<Notifications position="bottom-right" />
|
<Notifications position="bottom-right" />
|
||||||
|
|||||||
@ -0,0 +1,14 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { FC, ReactNode } from "react";
|
||||||
|
import { AppShell } from "@mantine/core";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
children: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
const AppShellFooterWrapper: FC<Props> = ({ children }) => {
|
||||||
|
return <AppShell.Footer hiddenFrom={"sm"}>{children}</AppShell.Footer>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AppShellFooterWrapper;
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { FC, ReactNode } from "react";
|
||||||
|
import { AppShell } from "@mantine/core";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
children: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
const AppShellMainWrapper: FC<Props> = ({ children }) => {
|
||||||
|
return <AppShell.Main>{children}</AppShell.Main>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AppShellMainWrapper;
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { FC, ReactNode } from "react";
|
||||||
|
import { AppShell } from "@mantine/core";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
children: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
const AppShellNavbarWrapper: FC<Props> = ({ children }) => {
|
||||||
|
return <AppShell.Navbar>{children}</AppShell.Navbar>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AppShellNavbarWrapper;
|
||||||
32
src/components/layout/Footer/Footer.module.css
Normal file
32
src/components/layout/Footer/Footer.module.css
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
.container {
|
||||||
|
@mixin light {
|
||||||
|
border-top: solid gray 2px;
|
||||||
|
}
|
||||||
|
@mixin dark {
|
||||||
|
border-top: solid var(--mantine-color-dark-7) 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.link {
|
||||||
|
width: 100%;
|
||||||
|
height: rem(50px);
|
||||||
|
border-radius: var(--mantine-radius-md);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-active] {
|
||||||
|
&,
|
||||||
|
&:hover {
|
||||||
|
color: var(--mantine-color-blue-light-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
31
src/components/layout/Footer/Footer.tsx
Normal file
31
src/components/layout/Footer/Footer.tsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { IconCircleDotted, IconLayoutKanban } from "@tabler/icons-react";
|
||||||
|
import FooterButtons from "@/components/layout/Footer/FooterButtons";
|
||||||
|
|
||||||
|
const buttonsData = [
|
||||||
|
{
|
||||||
|
icon: IconLayoutKanban,
|
||||||
|
label: "Сделки",
|
||||||
|
href: "/deals",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: IconCircleDotted,
|
||||||
|
label: "Label 1",
|
||||||
|
href: "/oiiai",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: IconCircleDotted,
|
||||||
|
label: "Label 2",
|
||||||
|
href: "/opaopa",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: IconCircleDotted,
|
||||||
|
label: "Label 3",
|
||||||
|
href: "/hihihaha",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const Footer = () => {
|
||||||
|
return <FooterButtons buttonsData={buttonsData} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Footer;
|
||||||
39
src/components/layout/Footer/FooterButtons.tsx
Normal file
39
src/components/layout/Footer/FooterButtons.tsx
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { IconPlus } from "@tabler/icons-react";
|
||||||
|
import { Group, Stack, Text } from "@mantine/core";
|
||||||
|
import FooterClickable from "@/components/layout/Footer/FooterClickable";
|
||||||
|
import styles from "./Footer.module.css";
|
||||||
|
|
||||||
|
type LinkData = {
|
||||||
|
icon: typeof IconPlus;
|
||||||
|
label: string;
|
||||||
|
href: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
buttonsData: LinkData[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const FooterButtons = ({ buttonsData }: Props) => {
|
||||||
|
return (
|
||||||
|
<Group
|
||||||
|
className={styles.container}
|
||||||
|
p={"xs"}
|
||||||
|
wrap={"nowrap"}
|
||||||
|
justify={"space-between"}>
|
||||||
|
{buttonsData.map(data => (
|
||||||
|
<FooterClickable
|
||||||
|
href={data.href}
|
||||||
|
key={data.label}>
|
||||||
|
<Stack
|
||||||
|
gap={0}
|
||||||
|
align={"center"}>
|
||||||
|
<data.icon />
|
||||||
|
<Text>{data.label}</Text>
|
||||||
|
</Stack>
|
||||||
|
</FooterClickable>
|
||||||
|
))}
|
||||||
|
</Group>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FooterButtons;
|
||||||
29
src/components/layout/Footer/FooterClickable.tsx
Normal file
29
src/components/layout/Footer/FooterClickable.tsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { ReactNode } from "react";
|
||||||
|
import { usePathname, useRouter } from "next/navigation";
|
||||||
|
import { UnstyledButton } from "@mantine/core";
|
||||||
|
import styles from "./Footer.module.css";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
href: string;
|
||||||
|
children: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
const FooterClickable = ({ children, href }: Props) => {
|
||||||
|
const pathname = usePathname();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const onClick = () => router.push(href);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<UnstyledButton
|
||||||
|
onClick={onClick}
|
||||||
|
className={styles.link}
|
||||||
|
data-active={pathname === href || undefined}>
|
||||||
|
{children}
|
||||||
|
</UnstyledButton>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FooterClickable;
|
||||||
38
src/components/layout/Navbar/Navbar.module.css
Normal file
38
src/components/layout/Navbar/Navbar.module.css
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
.link {
|
||||||
|
width: 100%;
|
||||||
|
height: rem(50px);
|
||||||
|
border-radius: var(--mantine-radius-md);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
@mixin light {
|
||||||
|
background-color: var(--mantine-color-gray-1);
|
||||||
|
}
|
||||||
|
@mixin dark {
|
||||||
|
background-color: var(--mantine-color-dark-5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-active] {
|
||||||
|
&,
|
||||||
|
&:hover {
|
||||||
|
@mixin light {
|
||||||
|
background-color: var(--color-light-aqua);
|
||||||
|
}
|
||||||
|
@mixin dark {
|
||||||
|
background-color: var(--mantine-color-dark-6);
|
||||||
|
}
|
||||||
|
color: var(--mantine-color-blue-light-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
46
src/components/layout/Navbar/Navbar.tsx
Normal file
46
src/components/layout/Navbar/Navbar.tsx
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import { IconCircleDotted, IconLayoutKanban } from "@tabler/icons-react";
|
||||||
|
import { Flex } from "@mantine/core";
|
||||||
|
import PageBlock from "@/components/layout/PageBlock/PageBlock";
|
||||||
|
import { ColorSchemeToggle } from "@/components/ui/ColorSchemeToggle/ColorSchemeToggle";
|
||||||
|
import Logo from "@/components/ui/Logo/Logo";
|
||||||
|
import NavbarLinks from "./NavbarLinks";
|
||||||
|
|
||||||
|
const linksData = [
|
||||||
|
{
|
||||||
|
icon: IconLayoutKanban,
|
||||||
|
label: "Сделки",
|
||||||
|
href: "/deals",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: IconCircleDotted,
|
||||||
|
label: "Назад",
|
||||||
|
href: "/oiiai",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const Navbar = () => {
|
||||||
|
return (
|
||||||
|
<PageBlock
|
||||||
|
style={{
|
||||||
|
marginBlock: "var(--mantine-spacing-md)",
|
||||||
|
marginLeft: "var(--mantine-spacing-md)",
|
||||||
|
}}
|
||||||
|
fullHeight>
|
||||||
|
<Flex
|
||||||
|
direction={"column"}
|
||||||
|
h={"100%"}>
|
||||||
|
<Logo title={"Fulfillment & Delivery"} />
|
||||||
|
<Flex
|
||||||
|
mx={"xs"}
|
||||||
|
direction={"column"}
|
||||||
|
justify={"space-between"}
|
||||||
|
h={"100%"}>
|
||||||
|
<NavbarLinks linksData={linksData} />
|
||||||
|
<ColorSchemeToggle />
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</PageBlock>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Navbar;
|
||||||
30
src/components/layout/Navbar/NavbarClickable.tsx
Normal file
30
src/components/layout/Navbar/NavbarClickable.tsx
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { ReactNode } from "react";
|
||||||
|
import { usePathname, useRouter } from "next/navigation";
|
||||||
|
import { UnstyledButton } from "@mantine/core";
|
||||||
|
import styles from "./Navbar.module.css";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
href: string;
|
||||||
|
children: ReactNode;
|
||||||
|
active?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const NavbarClickable = ({ children, href, active = false }: Props) => {
|
||||||
|
const pathname = usePathname();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const onClick = () => router.push(href);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<UnstyledButton
|
||||||
|
onClick={onClick}
|
||||||
|
className={styles.link}
|
||||||
|
data-active={active || pathname === href || undefined}>
|
||||||
|
{children}
|
||||||
|
</UnstyledButton>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default NavbarClickable;
|
||||||
36
src/components/layout/Navbar/NavbarLinks.tsx
Normal file
36
src/components/layout/Navbar/NavbarLinks.tsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { IconPlus } from "@tabler/icons-react";
|
||||||
|
import { Stack, Tooltip } from "@mantine/core";
|
||||||
|
import NavbarClickable from "./NavbarClickable";
|
||||||
|
|
||||||
|
type LinkData = {
|
||||||
|
icon: typeof IconPlus;
|
||||||
|
label: string;
|
||||||
|
href: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
linksData: LinkData[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const NavbarLinks = ({ linksData }: Props) => {
|
||||||
|
return (
|
||||||
|
<Stack gap={"xs"}>
|
||||||
|
{linksData.map((linkData, index) => (
|
||||||
|
<Tooltip
|
||||||
|
key={index}
|
||||||
|
display={!linkData.label ? "none" : "flex"}
|
||||||
|
label={linkData.label}
|
||||||
|
position="right"
|
||||||
|
transitionProps={{ duration: 0 }}>
|
||||||
|
<NavbarClickable
|
||||||
|
href={linkData.href}
|
||||||
|
key={linkData.label}>
|
||||||
|
<linkData.icon />
|
||||||
|
</NavbarClickable>
|
||||||
|
</Tooltip>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default NavbarLinks;
|
||||||
@ -10,24 +10,29 @@
|
|||||||
padding: var(--mantine-spacing-md);
|
padding: var(--mantine-spacing-md);
|
||||||
|
|
||||||
@mixin dark {
|
@mixin dark {
|
||||||
box-shadow: var(--dark-thick-shadow);
|
box-shadow: var(--dark-shadow);
|
||||||
}
|
}
|
||||||
@mixin light {
|
@mixin light {
|
||||||
box-shadow: var(--light-thick-shadow);
|
box-shadow: var(--light-shadow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-padding-height {
|
.mobile-margin-height {
|
||||||
height: 100vh;
|
height: var(--page-height);
|
||||||
|
@media (min-width: 48em) {
|
||||||
|
margin: var(--mantine-spacing-md);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.container-full-height {
|
.container-full-height {
|
||||||
min-height: calc(100vh - (var(--mantine-spacing-md) * 2));
|
min-height: var(--page-height);
|
||||||
|
height: var(--page-height);
|
||||||
|
max-height: var(--page-height);
|
||||||
}
|
}
|
||||||
|
|
||||||
.container-full-height-fixed {
|
.container-full-height-fixed {
|
||||||
height: calc(100vh - (var(--mantine-spacing-md) * 2));
|
height: var(--page-height);
|
||||||
}
|
}
|
||||||
|
|
||||||
.container-no-border-radius {
|
.container-no-border-radius {
|
||||||
|
|||||||
@ -1,8 +1,29 @@
|
|||||||
.container {
|
.container {
|
||||||
|
width: 100%;
|
||||||
|
height: rem(50px);
|
||||||
|
border-radius: var(--mantine-radius-md);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
@mixin light {
|
||||||
|
color: var(--mantine-color-gray-7);
|
||||||
|
}
|
||||||
@mixin dark {
|
@mixin dark {
|
||||||
background-color: var(--mantine-color-dark-7);
|
color: var(--mantine-color-dark-0);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
@mixin light {
|
||||||
|
background-color: var(--mantine-color-gray-1);
|
||||||
|
}
|
||||||
|
@mixin dark {
|
||||||
|
background-color: var(--mantine-color-dark-6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
width: rem(18px);
|
width: rem(18px);
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
import { IconMoon, IconSun } from "@tabler/icons-react";
|
import { IconMoon, IconSun } from "@tabler/icons-react";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import {
|
import {
|
||||||
ActionIcon,
|
Button,
|
||||||
useComputedColorScheme,
|
useComputedColorScheme,
|
||||||
useMantineColorScheme,
|
useMantineColorScheme,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
@ -20,12 +20,12 @@ export function ColorSchemeToggle() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ActionIcon
|
<Button
|
||||||
|
unstyled
|
||||||
onClick={toggleColorScheme}
|
onClick={toggleColorScheme}
|
||||||
variant="default"
|
|
||||||
size="xl"
|
size="xl"
|
||||||
radius="lg"
|
radius="lg"
|
||||||
aria-label="Toggle color scheme"
|
aria-label="Сменить тему"
|
||||||
className={style.container}>
|
className={style.container}>
|
||||||
<IconSun
|
<IconSun
|
||||||
className={classNames(style.icon, style.light)}
|
className={classNames(style.icon, style.light)}
|
||||||
@ -35,6 +35,6 @@ export function ColorSchemeToggle() {
|
|||||||
className={classNames(style.icon, style.dark)}
|
className={classNames(style.icon, style.dark)}
|
||||||
stroke={1.5}
|
stroke={1.5}
|
||||||
/>
|
/>
|
||||||
</ActionIcon>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
38
src/components/ui/Logo/Logo.tsx
Normal file
38
src/components/ui/Logo/Logo.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { Center, Image, Stack, Text, Title } from "@mantine/core";
|
||||||
|
import { myColor } from "@/theme";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
title?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Logo = ({ title }: Props) => {
|
||||||
|
return (
|
||||||
|
<Stack
|
||||||
|
align="center"
|
||||||
|
gap={0}>
|
||||||
|
<Image
|
||||||
|
src="/favicon.svg"
|
||||||
|
alt="LogiDex Logo"
|
||||||
|
w={70}
|
||||||
|
/>
|
||||||
|
<Title
|
||||||
|
ta={"center"}
|
||||||
|
order={4}
|
||||||
|
mt={"xs"}>
|
||||||
|
LogiDex
|
||||||
|
</Title>
|
||||||
|
{title && (
|
||||||
|
<Center>
|
||||||
|
<Text
|
||||||
|
fz={"xs"}
|
||||||
|
mb={"lg"}
|
||||||
|
style={{ color: myColor[6], textAlign: "center" }}>
|
||||||
|
{title}
|
||||||
|
</Text>
|
||||||
|
</Center>
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Logo;
|
||||||
Reference in New Issue
Block a user