diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 4dcb439..7fb53a1 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -16,5 +16,6 @@ module.exports = { 'warn', { allowConstantExport: true }, ], + 'react/prop-types': 'off', }, -} +}; diff --git a/index.html b/index.html index 0c589ec..5fbf71e 100644 --- a/index.html +++ b/index.html @@ -1,10 +1,10 @@ - + - Vite + React + BDC Shoe Dashboard
diff --git a/package-lock.json b/package-lock.json index b23a001..9540ca3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@mantine/core": "^6.0.18", "@mantine/form": "^6.0.18", "@mantine/hooks": "^6.0.18", + "@tabler/icons-react": "^2.30.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.14.2" @@ -1286,6 +1287,31 @@ "node": ">=14" } }, + "node_modules/@tabler/icons": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-2.30.0.tgz", + "integrity": "sha512-tvtmkI4ALjKThVVORh++sB9JnkFY7eGInKxNy+Df7WVQiF7T85tlvGADzlgX4Ic+CK5MIUzZ0jhOlQ/RRlgXpg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + } + }, + "node_modules/@tabler/icons-react": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/@tabler/icons-react/-/icons-react-2.30.0.tgz", + "integrity": "sha512-aYggXusHW133L4KujJkVf4GIIrjg7tIRHgNf/n37mnoHqMjwNP+PjmVdrBM1Z8Ywx9PKFRlrwM0eUMDcG+I4HA==", + "dependencies": { + "@tabler/icons": "2.30.0", + "prop-types": "^15.7.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + }, + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", @@ -3093,7 +3119,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -3366,7 +3391,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", diff --git a/package.json b/package.json index 78ed3ed..05316bc 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@mantine/core": "^6.0.18", "@mantine/form": "^6.0.18", "@mantine/hooks": "^6.0.18", + "@tabler/icons-react": "^2.30.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.14.2" diff --git a/src/assets/images/shoe-example.jpg b/src/assets/images/shoe-example.jpg new file mode 100644 index 0000000..679b12b Binary files /dev/null and b/src/assets/images/shoe-example.jpg differ diff --git a/src/components/header.jsx b/src/components/header.jsx new file mode 100644 index 0000000..3dc6407 --- /dev/null +++ b/src/components/header.jsx @@ -0,0 +1,15 @@ +import { Header, Title, MediaQuery, Flex } from '@mantine/core'; +import { IconMenu2 } from '@tabler/icons-react'; + +export function HeaderMain({ onToggle }) { + return ( +
+ + + onToggle()} /> + + Dasboard + +
+ ); +} diff --git a/src/components/navbar/index.jsx b/src/components/navbar/index.jsx new file mode 100644 index 0000000..784a62e --- /dev/null +++ b/src/components/navbar/index.jsx @@ -0,0 +1,77 @@ +import { NavLink } from 'react-router-dom'; +import { Navbar, Group, Title, Flex, MediaQuery } from '@mantine/core'; +import { + IconDashboard, + IconShoe, + IconCategory, + IconLogout, + IconX, +} from '@tabler/icons-react'; + +import { useStyles } from './style'; + +const links = [ + { link: '/', label: 'Dashboard', icon: IconDashboard }, + { link: '/shoe', label: 'Shoes', icon: IconShoe }, + { link: '/category', label: 'Category', icon: IconCategory }, +]; + +export default function NavbarMain({ status, onToggle }) { + const { classes, cx } = useStyles(); + + return ( + + ); +} diff --git a/src/components/navbar/style.js b/src/components/navbar/style.js new file mode 100644 index 0000000..3b33481 --- /dev/null +++ b/src/components/navbar/style.js @@ -0,0 +1,57 @@ +import { createStyles, getStylesRef, rem } from '@mantine/core'; + +export const useStyles = createStyles((theme) => ({ + header: { + paddingBottom: theme.spacing.md, + marginBottom: `calc(${theme.spacing.md} * 1.5)`, + borderBottom: `${rem(1)} solid ${theme.colors.gray[2]}`, + }, + + footer: { + paddingTop: theme.spacing.md, + marginTop: theme.spacing.md, + borderTop: `${rem(1)} solid ${theme.colors.gray[2]}`, + }, + + link: { + ...theme.fn.focusStyles(), + display: 'flex', + alignItems: 'center', + textDecoration: 'none', + fontSize: theme.fontSizes.sm, + color: theme.colors.gray[7], + padding: `${theme.spacing.xs} ${theme.spacing.sm}`, + borderRadius: theme.radius.sm, + fontWeight: 500, + + '&:hover': { + backgroundColor: theme.colors.gray[0], + color: theme.black, + + [`& .${getStylesRef('icon')}`]: { + color: theme.black, + }, + }, + }, + + linkIcon: { + ref: getStylesRef('icon'), + color: theme.colors.gray[6], + marginRight: theme.spacing.sm, + }, + + linkActive: { + '&, &:hover': { + backgroundColor: theme.fn.variant({ + variant: 'light', + color: theme.primaryColor, + }).background, + color: theme.fn.variant({ variant: 'light', color: theme.primaryColor }) + .color, + [`& .${getStylesRef('icon')}`]: { + color: theme.fn.variant({ variant: 'light', color: theme.primaryColor }) + .color, + }, + }, + }, +})); diff --git a/src/layouts/main.jsx b/src/layouts/main.jsx index 8459bd3..cb9c0fe 100644 --- a/src/layouts/main.jsx +++ b/src/layouts/main.jsx @@ -1,5 +1,35 @@ -import { Outlet } from "react-router-dom"; +import { useState } from 'react'; +import { Outlet, useNavigation } from 'react-router-dom'; +import { AppShell, Container, LoadingOverlay } from '@mantine/core'; + +import NavbarMain from '../components/navbar'; +import { HeaderMain } from '../components/header'; export default function LayoutMain() { - return ; + const navigation = useNavigation(); + + const [opened, setOpened] = useState(false); + + return ( + <> + + + setOpened(!opened)} /> + } + header={ setOpened(!opened)} />} + > + + + + + + ); } diff --git a/src/pages/category/create.jsx b/src/pages/category/create.jsx new file mode 100644 index 0000000..8221c11 --- /dev/null +++ b/src/pages/category/create.jsx @@ -0,0 +1,37 @@ +import { Link } from 'react-router-dom'; +import { Button, Flex, Group, TextInput, Title } from '@mantine/core'; +import { IconArrowBack } from '@tabler/icons-react'; + +export default function PageCategoryCreate() { + return ( + <> + + + Add Category + + + + + +
+ + + + + + + + ); +} diff --git a/src/pages/category/edit.jsx b/src/pages/category/edit.jsx new file mode 100644 index 0000000..e546165 --- /dev/null +++ b/src/pages/category/edit.jsx @@ -0,0 +1,37 @@ +import { Link } from 'react-router-dom'; +import { Button, Flex, Group, TextInput, Title } from '@mantine/core'; +import { IconArrowBack } from '@tabler/icons-react'; + +export default function PageCategoryEdit() { + return ( + <> + + + Edit Category + + + + + +
+ + + + + + + + ); +} diff --git a/src/pages/category/list.jsx b/src/pages/category/list.jsx new file mode 100644 index 0000000..e9463db --- /dev/null +++ b/src/pages/category/list.jsx @@ -0,0 +1,59 @@ +import { Link } from 'react-router-dom'; +import { ActionIcon, Button, Flex, Table, Title } from '@mantine/core'; +import { IconPencil, IconPlus, IconTrash } from '@tabler/icons-react'; + +const elements = [ + { name: 'Sport' }, + { name: 'Casual' }, + { name: 'School' }, + { name: 'Adventure' }, +]; + +export default function PageCategoryList() { + return ( + <> + + + Category List + + + + + + + + + + + + + + + {elements.map((element) => ( + + + + + ))} + +
NameAction
{element.name} + + + + + + + + + +
+ + ); +} diff --git a/src/pages/home.jsx b/src/pages/home.jsx index f98b49e..61c4461 100644 --- a/src/pages/home.jsx +++ b/src/pages/home.jsx @@ -1,3 +1,5 @@ -export default function Home() { - return

Home Page

; +import { Title } from '@mantine/core'; + +export default function PageHome() { + return Welcome to BDC Shoe 👋; } diff --git a/src/pages/shoe/create.jsx b/src/pages/shoe/create.jsx index 2b8c162..35a02db 100644 --- a/src/pages/shoe/create.jsx +++ b/src/pages/shoe/create.jsx @@ -1,7 +1,109 @@ -export default function ShoeCreate() { +import { Link, Form, redirect } from 'react-router-dom'; +import { + Button, + Flex, + Group, + NumberInput, + Radio, + TextInput, + Textarea, + Title, +} from '@mantine/core'; +import { IconArrowBack } from '@tabler/icons-react'; + +export async function action({ request }) { + const formData = await request.formData(); + const payload = Object.fromEntries(formData); + await fetch('http://localhost:3000/shoe', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(payload), + }); + + return redirect('/shoe'); +} + +export default function PageShoeCreate() { return ( -
-

Create Page

-
+ <> + + + Add Shoe + + + + + +
+ + + + + + + + +