basic functionnalities

This commit is contained in:
grimhilt 2023-07-30 19:14:14 +02:00
parent f820f0142b
commit 0461ef6f93
9 changed files with 260 additions and 0 deletions

View File

@ -0,0 +1,24 @@
import { Route, Routes } from 'react-router-dom';
import NotFound from '../pages/errors/404';
import Home from '../pages/home';
import Planning from '../pages/planning';
import Playlists from '../pages/playlists';
import Playlist from '../pages/playlist';
import Files from '../pages/files';
import Authentication from '../pages/auth';
const AppRouter = () => {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/planning" element={<Planning />} />
<Route path="/playlists" element={<Playlists />} />
<Route path="/files" element={<Files />} />
<Route path="/playlist/:id" element={<Playlist />} />
<Route path="/auth" element={<Authentication />} />
<Route path="*" element={<NotFound />} />
</Routes>
);
};
export default AppRouter;

16
src/components/layout.jsx Normal file
View File

@ -0,0 +1,16 @@
import { AppShell } from '@mantine/core';
import HeaderSearch from './header';
import AppRouter from './app-router';
import { BrowserRouter } from 'react-router-dom';
const Layout = () => {
return (
<BrowserRouter>
<AppShell mx="md" header={<HeaderSearch />}>
<AppRouter />
</AppShell>
</BrowserRouter>
);
};
export default Layout;

View File

@ -0,0 +1,32 @@
import { Switch, Group, useMantineTheme, createStyles } from '@mantine/core';
import { IconSun, IconMoonStars } from '@tabler/icons-react';
import { useColorSchemeToggle } from '../tools/color-scheme-toggle'
const useStyles = createStyles((theme) => ({
group: {
[theme.fn.smallerThan('xs')]: {
display: 'none',
},
},
}));
const SwitchToggle = () => {
const { classes } = useStyles();
const [ colorScheme, toggleColorScheme ] = useColorSchemeToggle();
const theme = useMantineTheme()
return (
<Group position="center" my={30} className={classes.group}>
<Switch
checked={colorScheme === 'dark'}
onChange={toggleColorScheme}
size="lg"
onLabel={<IconSun color={theme.white} size="1.25rem" stroke={1.5} />}
offLabel={<IconMoonStars color={theme.colors.gray[6]} size="1.25rem" stroke={1.5} />}
/>
</Group>
);
};
export default SwitchToggle;

67
src/pages/auth.jsx Normal file
View File

@ -0,0 +1,67 @@
import { TextInput, PasswordInput, Checkbox, Anchor, Paper, Title, Container, Group, Button } from '@mantine/core';
import { isNotEmpty, useForm } from '@mantine/form';
import { useAuth } from '../tools/auth-provider';
import { useNavigate } from 'react-router-dom';
import { useEffect } from 'react';
const Authentication = () => {
const { setRole } = useAuth();
const navigate = useNavigate();
const form = useForm({
initialValues: {
name: '',
password: '',
remember: false,
},
validate: {
name: isNotEmpty('Name is required'),
password: isNotEmpty('Password is required'),
},
});
useEffect(() => {
localStorage.setItem('role', form.values.name);
}, [form.values.name]);
const handleLogin = (e) => {
e.preventDefault();
if (form.validate().hasErrors) return;
setRole(form.values.name);
navigate('/');
};
return (
<Container size={420} my={40}>
<Title
align="center"
sx={(theme) => ({ fontFamily: `Greycliff CF, ${theme.fontFamily}`, fontWeight: 900 })}
>
Connect to signage
</Title>
<Paper withBorder shadow="md" p={30} mt={30} radius="md">
<form onSubmit={handleLogin}>
<TextInput label="Name" placeholder="Your name" {...form.getInputProps('name')} withAsterisk />
<PasswordInput
label="Password"
placeholder="Your password"
mt="md"
{...form.getInputProps('password')}
withAsterisk
/>
<Group position="apart" mt="lg">
<Checkbox label="Remember me" />
<Anchor size="sm" href="https://www.youtube.com/watch?v=dQw4w9WgXcQ&pp=ygUJcmljayByb2xs">
Forgot password(s)?
</Anchor>
</Group>
<Button fullWidth mt="xl" type="submit">
Sign in
</Button>
</form>
</Paper>
</Container>
);
};
export default Authentication;

63
src/pages/errors/404.jsx Normal file
View File

@ -0,0 +1,63 @@
import { createStyles, Title, Text, Button, Container, Group, rem } from '@mantine/core';
import { useNavigate } from 'react-router-dom';
const useStyles = createStyles((theme) => ({
root: {
paddingTop: rem(80),
paddingBottom: rem(80),
},
label: {
textAlign: 'center',
fontWeight: 900,
fontSize: rem(220),
lineHeight: 1,
marginBottom: `calc(${theme.spacing.xl} * 1.5)`,
color: theme.colorScheme === 'dark' ? theme.colors.dark[4] : theme.colors.gray[2],
[theme.fn.smallerThan('sm')]: {
fontSize: rem(120),
},
},
title: {
fontFamily: `Greycliff CF, ${theme.fontFamily}`,
textAlign: 'center',
fontWeight: 900,
fontSize: rem(38),
[theme.fn.smallerThan('sm')]: {
fontSize: rem(32),
},
},
description: {
maxWidth: rem(500),
margin: 'auto',
marginTop: theme.spacing.xl,
marginBottom: `calc(${theme.spacing.xl} * 1.5)`,
},
}));
const NotFound = () => {
const { classes } = useStyles();
const navigate = useNavigate();
return (
<Container className={classes.root}>
<div className={classes.label}>404</div>
<Title className={classes.title}>You have found a secret place.</Title>
<Text color="dimmed" size="lg" align="center" className={classes.description}>
Unfortunately, this is only a 404 page. You may have mistyped the address, or the page has been moved to
another URL.
</Text>
<Group position="center">
<Button variant="subtle" size="md" onClick={() => navigate('/')}>
Take me back to home page
</Button>
</Group>
</Container>
);
};
export default NotFound;

View File

@ -0,0 +1,19 @@
import { createContext, useState, useContext } from 'react';
const AuthContext = createContext();
const AuthProvider = ({ children }) => {
const [role, setRole] = useState(localStorage.getItem('role') ?? 'user');
return <AuthContext.Provider value={{ role, setRole }}>{children}</AuthContext.Provider>;
};
const logout = () => {
localStorage.removeItem('role');
window.location.href = '/auth';
};
const useAuth = () => useContext(AuthContext);
export default AuthContext;
export { AuthProvider, logout, useAuth };

View File

@ -0,0 +1,15 @@
import { useLocalStorage, useColorScheme } from '@mantine/hooks';
const useColorSchemeToggle = function(){
const defaultColorScheme = useColorScheme()
const [colorScheme, setColorScheme] = useLocalStorage({
key: 'mantine-color-scheme',
defaultValue: defaultColorScheme,
getInitialValueInEffect: true,
});
const toggleColorScheme = () =>
setColorScheme((colorScheme === 'dark' ? 'light' : 'dark'));
return [ colorScheme, toggleColorScheme ];
};
export { useColorSchemeToggle };

View File

@ -0,0 +1,8 @@
import { useAuth } from './auth-provider';
const GrantAccess = ({ roles, children }) => {
const { role } = useAuth();
return roles.includes(role) ? children : null;
};
export default GrantAccess;

16
src/tools/timeUtil.js Normal file
View File

@ -0,0 +1,16 @@
export const parseTime = (preparationTime) => {
let res = '';
let hours = Math.floor(preparationTime / 3600);
res += hours > 0 ? `${hours}h` : '';
let min = Math.floor((preparationTime % 3600) / 60);
if (min > 0 && res != '') res += ' ';
res += min > 0 ? `${min}m` : '';
let sec = Math.floor((preparationTime % 3600) % 60);
if (sec > 0 && res != '') res += ' ';
res += sec > 0 ? `${sec}s` : '';
if (res == '') res = '0s';
return res;
};