diff --git a/frontend/app/src/App.css b/frontend/app/src/App.css index 8ec3c9b..0c92e88 100644 --- a/frontend/app/src/App.css +++ b/frontend/app/src/App.css @@ -18,6 +18,11 @@ cursor: pointer; } +.link { + color: unset; + text-decoration: none; +} + .lot { border-top: 1px solid lightgrey; display: flex; diff --git a/frontend/app/src/App.js b/frontend/app/src/App.js index 48c2f05..e5955f7 100644 --- a/frontend/app/src/App.js +++ b/frontend/app/src/App.js @@ -1,31 +1,25 @@ import { ThemeProvider } from '@mui/material'; -import { createTheme } from '@mui/material/styles'; -import { frFR } from '@mui/material/locale'; import { LocalizationProvider } from "@mui/x-date-pickers" import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs' -import { ReactKeycloakProvider } from '@react-keycloak/web' import Keycloak from 'keycloak-js' +import { ReactKeycloakProvider } from '@react-keycloak/web' import { CookiesProvider } from 'react-cookie'; +import { RouterProvider } from "react-router-dom"; -import { createBrowserRouter, RouterProvider } from "react-router-dom"; -import CustomerLayout from './layouts/customer/CustomerLayout.tsx'; -import CustomerOrderView from './layouts/customer/PaymentLayout.tsx' +import { RouterFactory } from './layouts/RouterFactory.tsx'; import './App.css'; -import PaymentLayout from './layouts/customer/PaymentLayout.tsx'; -import Dashboard from './domains/dashboard/views/Dashboard.tsx'; -import ProductionController from './domains/production/ProductionController.tsx'; -import SaleController from './domains/sale/SaleController.tsx'; -import CustomerController from './domains/customer/CustomerController.tsx'; -import ProducerController from './domains/producer/ProducerController.tsx'; +import { ThemeFactory } from './layouts/ThemeFactory.ts'; function App() { const keycloakClient = new Keycloak(window.location.origin + '/config/keycloak.json') + const routerFactory = new RouterFactory() + const themeFactory = new ThemeFactory() const keycloakInitOptions = { checkLoginIframe: false, @@ -33,85 +27,12 @@ function App() { silentCheckSsoRedirectUri: window.location.origin + '/silent-check-sso.html' } - const theme = createTheme({ - palette: { - //mode: 'dark', - primary: { - main: '#556b2f', - } - }, - typography: { - h1: { - fontFamily: 'Acme', - }, - h2: { - fontFamily: 'Acme', - }, - h3: { - fontFamily: 'Acme', - }, - h4: { - fontFamily: 'Acme', - }, - h5: { - fontFamily: 'Acme', - }, - h6: { - fontFamily: 'Acme', - }, - subtitle1: { - fontWeight: 'bold' - } - } - }, frFR); - - const router = createBrowserRouter([ - { - path: "/", - element: getLayoutWrapper(), - }, - { - path: "/dashboard", - element: - }, - { - path: "/productions", - element: - }, - { - path: "/sales", - element: - }, - { - path: "/customers", - element: - }, - { - path: "/account", - element: - }, - { - path: "/orders/:orderId/payment", - element: - } - ]); - - function getLayoutWrapper(mainContent) { - if(process.env.REACT_APP_MODE === 'CUSTOMER') { - return - } - if(process.env.REACT_APP_MODE === 'PRODUCER') { - return - } - return
Configuration du mode client ou producteur absent ou non reconnu
- } - return ( - + - + diff --git a/frontend/app/src/domains/customer/CustomerController.tsx b/frontend/app/src/domains/customer/CustomerController.tsx index d617e82..2e800a3 100644 --- a/frontend/app/src/domains/customer/CustomerController.tsx +++ b/frontend/app/src/domains/customer/CustomerController.tsx @@ -20,7 +20,7 @@ export default function CustomerController() { producerService.loadProducer(setProducer) }) - return {getContent()} + return <>{getContent()} function getContent() { if(producer) { diff --git a/frontend/app/src/domains/dashboard/views/Dashboard.tsx b/frontend/app/src/domains/dashboard/views/Dashboard.tsx index 8206d63..70e008b 100644 --- a/frontend/app/src/domains/dashboard/views/Dashboard.tsx +++ b/frontend/app/src/domains/dashboard/views/Dashboard.tsx @@ -7,7 +7,7 @@ import DashboardProductions from '../components/DashboardProductions.tsx' import DashboardSales from '../components/DashboardSales.tsx' function Dashboard() { - return + return <> Tableau de bord
@@ -15,7 +15,7 @@ function Dashboard() {
-
+ } export default Dashboard \ No newline at end of file diff --git a/frontend/app/src/domains/producer/ProducerController.tsx b/frontend/app/src/domains/producer/ProducerController.tsx index 3d07ebc..cbdd469 100644 --- a/frontend/app/src/domains/producer/ProducerController.tsx +++ b/frontend/app/src/domains/producer/ProducerController.tsx @@ -29,10 +29,10 @@ function ProducerController() { }) }) - return + return <> Gestion du compte {displayStripeAccount()} - + function loadStripeAccount(producerId: number) { apiInvoker.callApiAuthenticatedly( diff --git a/frontend/app/src/domains/production/ProductionController.tsx b/frontend/app/src/domains/production/ProductionController.tsx index bc4f8a1..d64e93c 100644 --- a/frontend/app/src/domains/production/ProductionController.tsx +++ b/frontend/app/src/domains/production/ProductionController.tsx @@ -15,7 +15,7 @@ export default function ProductionController({producer: producer}) { const [currentAction, setCurrentAction] = useState(PRODUCTIONS_LIST) const [context, setContext] = useState(undefined) - return {getContent()} + return <>{getContent()} function getContent() { switch (currentAction) { diff --git a/frontend/app/src/domains/sale/SaleController.tsx b/frontend/app/src/domains/sale/SaleController.tsx index 8c429b7..64a3d27 100644 --- a/frontend/app/src/domains/sale/SaleController.tsx +++ b/frontend/app/src/domains/sale/SaleController.tsx @@ -32,7 +32,7 @@ export default function SaleController() { producerService.loadProducer(setProducer) }) - return {getCurrentView()} + return <>{getCurrentView()} function getCurrentView() { if(producer) { diff --git a/frontend/app/src/layouts/ErrorLayout.tsx b/frontend/app/src/layouts/ErrorLayout.tsx new file mode 100644 index 0000000..49dc26e --- /dev/null +++ b/frontend/app/src/layouts/ErrorLayout.tsx @@ -0,0 +1,6 @@ +import { Typography } from "@mui/material"; +import React from "react"; + +export function ErrorLayout({message: message}) { + return {message} +} diff --git a/frontend/app/src/layouts/RouterFactory.tsx b/frontend/app/src/layouts/RouterFactory.tsx new file mode 100644 index 0000000..3bd4936 --- /dev/null +++ b/frontend/app/src/layouts/RouterFactory.tsx @@ -0,0 +1,26 @@ +import { createBrowserRouter } from "react-router-dom" +import { CustomerRouterFactory } from "./customer/CustomerRouterFactory.tsx" +import { ProducerRouterFactory } from "./producer/ProducerRouterFactory.tsx" +import React from "react" +import { ErrorLayout } from "./ErrorLayout.tsx" + +export class RouterFactory { + + producerRouterFactory: ProducerRouterFactory = new ProducerRouterFactory() + customerRouterFactory: CustomerRouterFactory = new CustomerRouterFactory() + + getRouter() { + if(process.env.REACT_APP_MODE === 'CUSTOMER') { + return this.customerRouterFactory.getRouter() + } + if(process.env.REACT_APP_MODE === 'PRODUCER') { + return this.producerRouterFactory.getRouter() + } + return createBrowserRouter([ + { + path: "/", + element: + } + ]) + } +} \ No newline at end of file diff --git a/frontend/app/src/layouts/ThemeFactory.ts b/frontend/app/src/layouts/ThemeFactory.ts new file mode 100644 index 0000000..0d0bd93 --- /dev/null +++ b/frontend/app/src/layouts/ThemeFactory.ts @@ -0,0 +1,38 @@ +import { createTheme } from "@mui/material"; +import { frFR } from '@mui/material/locale'; + +export class ThemeFactory { + createTheme() { + return createTheme({ + palette: { + //mode: 'dark', + primary: { + main: '#556b2f', + } + }, + typography: { + h1: { + fontFamily: 'Acme', + }, + h2: { + fontFamily: 'Acme', + }, + h3: { + fontFamily: 'Acme', + }, + h4: { + fontFamily: 'Acme', + }, + h5: { + fontFamily: 'Acme', + }, + h6: { + fontFamily: 'Acme', + }, + subtitle1: { + fontWeight: 'bold' + } + } + }, frFR); + } +} \ No newline at end of file diff --git a/frontend/app/src/layouts/customer/CustomerLayout.tsx b/frontend/app/src/layouts/customer/CustomerLayout.tsx index 8e12aed..047c84a 100644 --- a/frontend/app/src/layouts/customer/CustomerLayout.tsx +++ b/frontend/app/src/layouts/customer/CustomerLayout.tsx @@ -17,6 +17,7 @@ import CustomerCreationForm from '../../domains/customer/views/CustomerCreationF import Welcome from '../../domains/welcome/Welcome.tsx' import { Login, Logout } from '@mui/icons-material' import NotAuthorizedForProducers from '../../authentication/views/NotAuthorizedForProducers.tsx' +import { Outlet, useNavigate } from 'react-router-dom' export default function CustomerLayout() { @@ -33,6 +34,7 @@ export default function CustomerLayout() { const [context, setContext] = useState(undefined) const [cookies, setCookie, removeCookie] = useCookies(['pendingOrder']); const [customer, setCustomer] = useState(undefined) + const navigate = useNavigate() useEffect(() => { if (initialized) { @@ -65,7 +67,7 @@ export default function CustomerLayout() { setCustomer(customer) } } - +/* function displayMainContent() { if(authenticationService.isAuthenticated() && customer && !customer.id) { return setCustomer(newCustomer)}> @@ -79,10 +81,11 @@ export default function CustomerLayout() { } } - + */ function createOrder(sale: Sale) { setContext(sale) - setMainContent(ORDER_CREATION) + /*setMainContent(ORDER_CREATION)*/ + navigate('/order/creation') } function displayAuthenticationButton(): React.ReactNode { @@ -115,7 +118,7 @@ export default function CustomerLayout() { {displayAuthenticationButton()} - {displayMainContent()} + ) } diff --git a/frontend/app/src/layouts/customer/CustomerRouterFactory.tsx b/frontend/app/src/layouts/customer/CustomerRouterFactory.tsx new file mode 100644 index 0000000..083571b --- /dev/null +++ b/frontend/app/src/layouts/customer/CustomerRouterFactory.tsx @@ -0,0 +1,38 @@ +import React from "react"; + +import { createBrowserRouter } from "react-router-dom"; + +import PaymentLayout from "./PaymentLayout.tsx"; +import CustomerLayout from "./CustomerLayout.tsx"; +import CustomerOrderForm from "../../domains/sale/views/CustomerOrderForm.tsx"; +import NotAuthorizedForProducers from "../../authentication/views/NotAuthorizedForProducers.tsx"; +import Welcome from "../../domains/welcome/Welcome.tsx"; + +export class CustomerRouterFactory { + getRouter() { + return createBrowserRouter([ + { + path: "/", + element: , + children: [ + { + path: "/welcome", + element: + }, + { + path: "/order/creation", + element: + }, + { + path: "/orders/:orderId/payment", + element: + } + ] + }, + { + path: "/unauthorized", + element: + } + ]) + } +} \ No newline at end of file diff --git a/frontend/app/src/layouts/producer/AnonymousLayout.tsx b/frontend/app/src/layouts/producer/AnonymousLayout.tsx index 366b595..917b16f 100644 --- a/frontend/app/src/layouts/producer/AnonymousLayout.tsx +++ b/frontend/app/src/layouts/producer/AnonymousLayout.tsx @@ -1,6 +1,7 @@ import { styled } from '@mui/material/styles'; import { AppBar, Box, Typography, CssBaseline, Toolbar, Grid, Paper, Button } from "@mui/material"; import { useKeycloak } from '@react-keycloak/web' +import React from 'react'; function AnonymousLayout() { diff --git a/frontend/app/src/layouts/producer/AuthenticatedLayout.tsx b/frontend/app/src/layouts/producer/AuthenticatedLayout.tsx index ae34aad..4184e01 100644 --- a/frontend/app/src/layouts/producer/AuthenticatedLayout.tsx +++ b/frontend/app/src/layouts/producer/AuthenticatedLayout.tsx @@ -8,13 +8,14 @@ import {Close, Logout, Menu} from '@mui/icons-material' import { ApiInvoker } from '../../api/ApiInvoker.ts' import Producer from 'viandeendirect_eu/dist/model/Producer.js'; -import SideMenu from './SideMenu.js' +import SideMenu from './SideMenu.jsx' import { AuthenticationService } from '../../authentication/service/AuthenticationService.ts'; import NotAuthorizedForCustomers from '../../authentication/views/NotAuthorizedForCustomers.tsx'; import { ProducerService } from '../../domains/commons/service/ProducerService.ts'; +import { Outlet } from 'react-router-dom'; -function AuthenticatedLayout(props) { +export default function AuthenticatedLayout(props) { const { keycloak, initialized } = useKeycloak() const [sideMenuOpen, setSideMenuOpen] = useState(false) const [producer, setProducer] = useState() @@ -87,10 +88,8 @@ function AuthenticatedLayout(props) { sx={{ flexGrow: 1, p: 3 }} width={'100%'}> - {props.children} + ) } - -export default AuthenticatedLayout \ No newline at end of file diff --git a/frontend/app/src/layouts/producer/ProducerRouterFactory.tsx b/frontend/app/src/layouts/producer/ProducerRouterFactory.tsx new file mode 100644 index 0000000..74ebf6f --- /dev/null +++ b/frontend/app/src/layouts/producer/ProducerRouterFactory.tsx @@ -0,0 +1,58 @@ +import React from "react"; +import { createBrowserRouter, Navigate } from "react-router-dom"; + +import AuthenticatedLayout from "./AuthenticatedLayout.tsx"; +import ProductionController from "../../domains/production/ProductionController.tsx"; +import CustomerController from "../../domains/customer/CustomerController.tsx"; +import ProducerController from "../../domains/producer/ProducerController.tsx"; +import SaleController from "../../domains/sale/SaleController.tsx"; +import Dashboard from "../../domains/dashboard/views/Dashboard.tsx"; +import AnonymousLayout from "./AnonymousLayout.tsx"; +import NotAuthorizedForCustomers from "../../authentication/views/NotAuthorizedForCustomers.tsx"; + +export class ProducerRouterFactory { + getRouter() { + return createBrowserRouter([ + { + path: "/", + element: , + children: [ + { + index: true, + element: + }, + { + path: "/dashboard", + element: + }, + { + path: "/productions", + element: + }, + { + path: "/sales", + element: + }, + { + path: "/customers", + element: + }, + { + path: "/account", + element: + }, + ] + }, + { + path: "/authentication", + element: + }, + { + path: "/unauthorized", + element: + } + ]) + + } + +} \ No newline at end of file diff --git a/frontend/app/src/layouts/producer/SideMenu.js b/frontend/app/src/layouts/producer/SideMenu.js deleted file mode 100644 index 5874d42..0000000 --- a/frontend/app/src/layouts/producer/SideMenu.js +++ /dev/null @@ -1,95 +0,0 @@ -import Box from '@mui/material/Box' -import Drawer from '@mui/material/Drawer' -import List from '@mui/material/List'; -import ListItem from '@mui/material/ListItem'; -import ListItemButton from '@mui/material/ListItemButton'; -import ListItemText from '@mui/material/ListItemText'; -import Toolbar from '@mui/material/Toolbar'; - -function SideMenu({width, open, onClose}) { - - function sideMenuContent() { - return ( - - - - - { - onClose() - setTimeout(() => window.open('./dashboard', '_self'), 200) - }}> - - - - - { - onClose() - setTimeout(() => window.open('./productions', '_self'), 200) - }}> - - - - - { - onClose() - setTimeout(() => window.open('./sales', '_self'), 200) - }}> - - - - - { - onClose() - setTimeout(() => window.open('./customers', '_self'), 200) - }}> - - - - - { - onClose() - setTimeout(() => window.open('./account', '_self'), 200) - }}> - - - - - - ) - } - - return ( - - - {sideMenuContent()} - - - {sideMenuContent()} - - - ) -} - -export default SideMenu \ No newline at end of file diff --git a/frontend/app/src/layouts/producer/SideMenu.jsx b/frontend/app/src/layouts/producer/SideMenu.jsx new file mode 100644 index 0000000..d6ae1ae --- /dev/null +++ b/frontend/app/src/layouts/producer/SideMenu.jsx @@ -0,0 +1,91 @@ +import Box from '@mui/material/Box' +import Drawer from '@mui/material/Drawer' +import List from '@mui/material/List'; +import ListItem from '@mui/material/ListItem'; +import ListItemButton from '@mui/material/ListItemButton'; +import ListItemText from '@mui/material/ListItemText'; +import Toolbar from '@mui/material/Toolbar'; +import { Link } from 'react-router-dom'; + +function SideMenu({width, open, onClose}) { + + function sideMenuContent() { + return ( + + + + onClose()} className={'link'}> + + + + + + + onClose()} className={'link'}> + + + + + + + onClose()} className={'link'}> + + + + + + + onClose()} className={'link'}> + + + + + + + onClose()} className={'link'}> + + + + + + + + + ) + } + + return ( + + + {sideMenuContent()} + + + {sideMenuContent()} + + + ) +} + +export default SideMenu \ No newline at end of file