💄 Passe la navigation de vue à React

This commit is contained in:
Clement Desmidt 2022-03-04 16:35:09 +01:00
parent 844f625298
commit 44e9b5d694
11 changed files with 3622 additions and 81 deletions

48
public/css/app.css vendored
View File

@ -11878,6 +11878,39 @@ select {
--tw-backdrop-saturate: ; --tw-backdrop-saturate: ;
--tw-backdrop-sepia: ; --tw-backdrop-sepia: ;
} }
.container {
width: 100%;
}
@media (min-width: 640px) {
.container {
max-width: 640px;
}
}
@media (min-width: 768px) {
.container {
max-width: 768px;
}
}
@media (min-width: 1024px) {
.container {
max-width: 1024px;
}
}
@media (min-width: 1280px) {
.container {
max-width: 1280px;
}
}
@media (min-width: 1536px) {
.container {
max-width: 1536px;
}
}
.fixed { .fixed {
position: fixed; position: fixed;
} }
@ -11902,6 +11935,9 @@ select {
.z-50 { .z-50 {
z-index: 50; z-index: 50;
} }
.m-0 {
margin: 0px;
}
.mx-auto { .mx-auto {
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
@ -11954,6 +11990,12 @@ select {
.mt-3 { .mt-3 {
margin-top: 0.75rem; margin-top: 0.75rem;
} }
.mb-3 {
margin-bottom: 0.75rem;
}
.mb-0 {
margin-bottom: 0px;
}
.block { .block {
display: block; display: block;
} }
@ -12177,6 +12219,9 @@ select {
.p-2 { .p-2 {
padding: 0.5rem; padding: 0.5rem;
} }
.p-0 {
padding: 0px;
}
.px-4 { .px-4 {
padding-left: 1rem; padding-left: 1rem;
padding-right: 1rem; padding-right: 1rem;
@ -12243,6 +12288,9 @@ select {
.text-center { .text-center {
text-align: center; text-align: center;
} }
.align-baseline {
vertical-align: baseline;
}
.font-sans { .font-sans {
font-family: Nunito, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-family: Nunito, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
} }

3415
public/js/app.js vendored

File diff suppressed because it is too large Load Diff

16
resources/js/app.js vendored
View File

@ -1,7 +1,15 @@
/**
* First we will load all of this project's JavaScript dependencies which
* includes React and other helpers. It's a great starting point while
* building robust, powerful web applications using React + Laravel.
*/
require('./bootstrap'); require('./bootstrap');
import Alpine from 'alpinejs'; /**
* Next, we will create a fresh React component instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/
window.Alpine = Alpine; require('./components/Example');
Alpine.start();

View File

@ -42,8 +42,8 @@ function App() {
const [listPages, setListPages] = React.useState(pages); const [listPages, setListPages] = React.useState(pages);
const [passphrase, setPassphrase] = React.useState(sessionPassphrase); const [passphrase, setPassphrase] = React.useState(sessionPassphrase);
const history = useHistory(); const history = useHistory();
const [user, setUser] = React.useState(false); const [user, setUser] = React.useState(checkPassphrase());
const [error, isError] = React.useState(false); const [error, isError] = React.useState(!checkPassphrase());
const signin = cb => { const signin = cb => {
const isAuthenticated = checkPassphrase(); const isAuthenticated = checkPassphrase();
@ -57,6 +57,7 @@ function App() {
}; };
const signout = cb => { const signout = cb => {
sessionStorage.removeItem("key");
setUser(false); setUser(false);
cb(); cb();
}; };
@ -98,7 +99,7 @@ function App() {
<p> <p>
Bienvenue !{" "} Bienvenue !{" "}
<Button variant="outlined" size="small" sx={{align: "right"}} onClick={() => { <Button variant="outlined" size="small" sx={{align: "right"}} onClick={() => {
signout(() => history.push("/")); signout(() => history.push("/diary/public"));
}}> }}>
Fermer mon carnet à clef Fermer mon carnet à clef
</Button> </Button>

View File

@ -2,8 +2,18 @@ import * as React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import { BrowserRouter as Router} from "react-router-dom"; import { BrowserRouter as Router} from "react-router-dom";
import App from "./App"; import App from "./App";
import BasicMenu from "../user/BasicMenu";
import MobileMenu from "../user/MobileMenu";
const app = document.getElementById('app'); const app = document.getElementById('app');
const menu = document.getElementById("menu");
const mobileMenu = document.getElementById("mobile-menu");
if (menu) {
ReactDOM.render(<BasicMenu nickname={menu.getAttribute("data-user")} />, menu);
}
if (mobileMenu) {
ReactDOM.render(<MobileMenu nickname={mobileMenu.getAttribute("data-user")} />, mobileMenu);
}
if (app) { if (app) {
ReactDOM.render(<AppWrapper/>, app); ReactDOM.render(<AppWrapper/>, app);
} }

View File

@ -42,13 +42,14 @@ export default function PageForm({setListPages, csrf, url, passphrase}) {
if (json.success) { if (json.success) {
HTMLForm.reset(); HTMLForm.reset();
setListPages(previousList => [ setListPages(previousList => [
...previousList,
{ {
id: uuid, id: uuid,
date: json.date, date: json.date,
title: decryptedFormData.get("title"), title: decryptedFormData.get("title"),
content: decryptedFormData.get("text"), content: decryptedFormData.get("text"),
}]); },
...previousList
]);
} }
} }

View File

@ -0,0 +1,47 @@
import * as React from 'react';
import Button from '@mui/material/Button';
import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';
export default function BasicMenu({nickname}) {
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const open = Boolean(anchorEl);
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
function logout() {
const logoutForm: HTMLFormElement = document.getElementById("logout-form") as HTMLFormElement;
logoutForm.submit();
}
return (
<div>
<Button
id="basic-button"
aria-controls={open ? 'basic-menu' : undefined}
aria-haspopup="true"
aria-expanded={open ? 'true' : undefined}
onClick={handleClick}
className={"flex items-center text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300 transition duration-150 ease-in-out"}
>
{nickname}
</Button>
<Menu
id="basic-menu"
anchorEl={anchorEl}
open={open}
onClose={handleClose}
MenuListProps={{
'aria-labelledby': 'basic-button',
}}
>
{/*<MenuItem onClick={handleClose}>My account</MenuItem>*/}
<MenuItem onClick={logout}>Logout</MenuItem>
</Menu>
</div>
);
}

View File

@ -0,0 +1,76 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import SwipeableDrawer from '@mui/material/SwipeableDrawer';
import Button from '@mui/material/Button';
import List from '@mui/material/List';
import Divider from '@mui/material/Divider';
import ListItem from '@mui/material/ListItem';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import InboxIcon from '@mui/icons-material/MoveToInbox';
import MailIcon from '@mui/icons-material/Mail';
export default function MobileMenu({nickname}) {
const [state, setState] = React.useState(false);
const toggleDrawer =
(open: boolean) =>
(event: React.KeyboardEvent | React.MouseEvent) => {
if (
event &&
event.type === 'keydown' &&
((event as React.KeyboardEvent).key === 'Tab' ||
(event as React.KeyboardEvent).key === 'Shift')
) {
return;
}
setState( open );
};
function logout() {
const logoutForm: HTMLFormElement = document.getElementById("logout-form") as HTMLFormElement;
logoutForm.submit();
}
return (
<div>
<Button onClick={toggleDrawer(true)}>
<svg className="h-6 w-6" stroke="currentColor" fill="none" viewBox="0 0 24 24">
<path className="inline-flex" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 6h16M4 12h16M4 18h16" />
</svg>
</Button>
<SwipeableDrawer
anchor={"right"}
open={state}
onClose={toggleDrawer(false)}
onOpen={toggleDrawer(true)}
>
<Box
sx={{ width: 250 }}
role="presentation"
onClick={toggleDrawer(false)}
onKeyDown={toggleDrawer(false)}
>
<List>
<ListItem button key={"user"}>
<ListItemIcon>
<MailIcon />
</ListItemIcon>
<ListItemText primary={nickname} />
</ListItem>
</List>
<Divider />
<List>
<ListItem button key={"user.logout"} onClick={logout}>
<ListItemIcon>
<InboxIcon />
</ListItemIcon>
<ListItemText primary={"Logout"} />
</ListItem>
</List>
</Box>
</SwipeableDrawer>
</div>
);
}

View File

@ -1,4 +1,4 @@
<nav x-data="{ open: false }" class="bg-white border-b border-gray-100"> <nav class="bg-white border-b border-gray-100">
<!-- Primary Navigation Menu --> <!-- Primary Navigation Menu -->
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between h-16"> <div class="flex justify-between h-16">
@ -20,72 +20,21 @@
<!-- Settings Dropdown --> <!-- Settings Dropdown -->
<div class="hidden sm:flex sm:items-center sm:ml-6"> <div class="hidden sm:flex sm:items-center sm:ml-6">
<x-dropdown align="right" width="48"> <div id="menu" data-user="{{ Auth::user()->name }}"></div>
<x-slot name="trigger"> <!-- Authentication -->
<button class="flex items-center text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300 transition duration-150 ease-in-out"> <form method="POST" action="{{ route('logout') }}" style="display: none;" id="logout-form">
<div>{{ Auth::user()->name }}</div> @csrf
<x-dropdown-link :href="route('logout')"
<div class="ml-1"> onclick="event.preventDefault();
<svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"> this.closest('form').submit();">
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" /> {{ __('Log Out') }}
</svg> </x-dropdown-link>
</div> </form>
</button>
</x-slot>
<x-slot name="content">
<!-- Authentication -->
<form method="POST" action="{{ route('logout') }}">
@csrf
<x-dropdown-link :href="route('logout')"
onclick="event.preventDefault();
this.closest('form').submit();">
{{ __('Log Out') }}
</x-dropdown-link>
</form>
</x-slot>
</x-dropdown>
</div> </div>
<!-- Hamburger --> <!-- Hamburger -->
<div class="-mr-2 flex items-center sm:hidden"> <div class="-mr-2 flex items-center sm:hidden">
<button @click="open = ! open" class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 focus:text-gray-500 transition duration-150 ease-in-out"> <div id="mobile-menu" data-user="{{ Auth::user()->name }}"></div>
<svg class="h-6 w-6" stroke="currentColor" fill="none" viewBox="0 0 24 24">
<path :class="{'hidden': open, 'inline-flex': ! open }" class="inline-flex" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
<path :class="{'hidden': ! open, 'inline-flex': open }" class="hidden" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
</div>
</div>
<!-- Responsive Navigation Menu -->
<div :class="{'block': open, 'hidden': ! open}" class="hidden sm:hidden">
<div class="pt-2 pb-3 space-y-1">
<x-responsive-nav-link :href="route('dashboard')" :active="request()->routeIs('dashboard')">
{{ __('Dashboard') }}
</x-responsive-nav-link>
</div>
<!-- Responsive Settings Options -->
<div class="pt-4 pb-1 border-t border-gray-200">
<div class="px-4">
<div class="font-medium text-base text-gray-800">{{ Auth::user()->name }}</div>
<div class="font-medium text-sm text-gray-500">{{ Auth::user()->email }}</div>
</div>
<div class="mt-3 space-y-1">
<!-- Authentication -->
<form method="POST" action="{{ route('logout') }}">
@csrf
<x-responsive-nav-link :href="route('logout')"
onclick="event.preventDefault();
this.closest('form').submit();">
{{ __('Log Out') }}
</x-responsive-nav-link>
</form>
</div> </div>
</div> </div>
</div> </div>

View File

@ -15,7 +15,7 @@
data-post="{{ route('pages.store') }}" data-post="{{ route('pages.store') }}"
data-remove="{{ route('pages.destroy', ['page' => 'replace_me']) }}" data-remove="{{ route('pages.destroy', ['page' => 'replace_me']) }}"
data-csrf="{{ csrf_token() }}" data-csrf="{{ csrf_token() }}"
data-checkword="{{ $checkword }}" data-checkword="{{ $checkword }}"
> >
</div> </div>
</div> </div>

View File

@ -26,7 +26,7 @@ Route::get('/first', [UserController::class, 'first'])->middleware(['auth', 'aut
Route::post('/first', [UserController::class, 'storeFirst'])->middleware(['auth', 'auth.passphrase'])->name('user.storeFirst'); Route::post('/first', [UserController::class, 'storeFirst'])->middleware(['auth', 'auth.passphrase'])->name('user.storeFirst');
Route::get('/dashboard', function () { Route::get('/dashboard', function () {
return view('dashboard'); return redirect(\route('pages.index'));
})->middleware(['auth'])->name('dashboard'); })->middleware(['auth'])->name('dashboard');
require __DIR__.'/auth.php'; require __DIR__.'/auth.php';