diff --git a/compose.yaml b/compose.yaml index 8c836503..c905adc7 100644 --- a/compose.yaml +++ b/compose.yaml @@ -119,7 +119,7 @@ services: POSTGRES_URL: jdbc:postgresql://postgres:5432/test ## Recompiles on source code changes. - ## Do ensure that the two Gradle containers have independent Home directories and Project cache directories. + ## Do ensure that the two Gradle containers have independent Intro directories and Project cache directories. ztor-build-once: extends: service: gradle-base @@ -128,7 +128,7 @@ services: command: ztor:buildFatJar --no-daemon ## Recompiles on source code changes. - ## Do ensure that the two Gradle containers have independent Home directories and Project cache directories. + ## Do ensure that the two Gradle containers have independent Intro directories and Project cache directories. ztor-build: extends: service: gradle-base @@ -137,7 +137,7 @@ services: command: ztor:classes ## Runs Ktor web server and reloads classes if the compiled .class file changes. - ## Do ensure that the two Gradle containers have independent Home directories and Project cache directories. + ## Do ensure that the two Gradle containers have independent Intro directories and Project cache directories. ztor-run: extends: service: ztor-gradle-with-db diff --git a/frontend/src/App.test.tsx b/frontend/src/App.test.tsx index 9053a53d..3287c07b 100644 --- a/frontend/src/App.test.tsx +++ b/frontend/src/App.test.tsx @@ -1,6 +1,6 @@ import {render, screen} from '@testing-library/react' import React from 'react' -import App from './App' +import {App} from './App' test('renders learn react link', () => { render() diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 8a40e3a1..d02333e5 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,54 +1,12 @@ -import 'leaflet/dist/leaflet.css' -import React, {createElement as h, useState} from 'react' -import './App.css' -import {AggregatedAreaData} from './components/aggregated-area-data' -import {AnyLogic} from './components/any-logic' -import {BuurtPicker} from './components/buurt-picker' -import {MainMap} from './components/main-map' -import {PandDataDisplay} from './components/pand-display' -import {useApp} from './services/appState' -import {assertDefined} from './services/util' -import {Buurt} from './services/wijkenbuurten/buurten' -import {ZeroLayout} from "./components/zero-layout" - -function App() { - const appHook = useApp() - const {setGeometry, getPandData, bag2dPanden} = appHook - - const [currentPandId, setCurrentPandId] = useState('') - - const [buurt, setBuurt] = useState() +import React, {FunctionComponent} from 'react' +import {ZeroHeader} from "./components/zero-header"; +import {Outlet} from "react-router-dom"; +export const App: FunctionComponent = () => { return ( - - {/* Three-column layout*/} -
-
- {h(AggregatedAreaData, {appHook: appHook})} - { - setBuurt(buurt) - setGeometry(buurt.geometry) - }}/> -
-
- - -
-
- {currentPandId && getPandData(currentPandId) && - } -
-
-
- ) -} - -export default App + <> + + + + ); +}; diff --git a/frontend/src/admin/admin.tsx b/frontend/src/admin/surveys.tsx similarity index 98% rename from frontend/src/admin/admin.tsx rename to frontend/src/admin/surveys.tsx index 06f65d4c..e693a1bb 100644 --- a/frontend/src/admin/admin.tsx +++ b/frontend/src/admin/surveys.tsx @@ -16,7 +16,7 @@ import {ZeroLayout} from "../components/zero-layout" import {AdminButtonRow} from "./admin-button-row" import {SurveyIncludeInSimulationCheckbox} from "./survey-include-in-simulation-checkbox" -export const Admin: FunctionComponent = () => { +export const Surveys: FunctionComponent = () => { const {loading, surveys, changeSurvey, removeSurvey} = useSurveys() const multipleProjects = surveys.map(survey => survey.zenmoProject) diff --git a/frontend/src/components/home.tsx b/frontend/src/components/intro.tsx similarity index 96% rename from frontend/src/components/home.tsx rename to frontend/src/components/intro.tsx index e3248db8..281d4f6a 100644 --- a/frontend/src/components/home.tsx +++ b/frontend/src/components/intro.tsx @@ -2,7 +2,7 @@ import {FunctionComponent} from "react" import {ZeroLayout} from "./zero-layout" import {Link} from "react-router-dom" -export const Home: FunctionComponent = () => ( +export const Intro: FunctionComponent = () => (

Welkom bij Zenmo Zero

diff --git a/frontend/src/components/zero-header.tsx b/frontend/src/components/zero-header.tsx index 4d92f27f..7b5f1b93 100644 --- a/frontend/src/components/zero-header.tsx +++ b/frontend/src/components/zero-header.tsx @@ -1,16 +1,78 @@ -import React from "react"; +import React, {FunctionComponent, PropsWithChildren, useState} from "react" +import {Button} from "primereact/button"; +import {Sidebar} from "primereact/sidebar"; +import {css} from "@emotion/react"; +import {To, useNavigate} from "react-router-dom"; -export const ZeroHeader = () => ( -

- -   - Zenmo Zero -

-) \ No newline at end of file +const sidebarStyle = css({ + width: '16rem', + backgroundColor: '#f5f5f5', + borderRight: '1px solid #ddd', +}); + +const buttonStyle = css({ + display: 'block', + marginBottom: '3rem', + width: '100%', + + textAlign: 'left', + padding: '0.5em 1em', + border: 'none', + borderBottom: '1px solid #ddd', + color: '#333', + background: '#f5f5f5', + transition: 'background-color 0.2s ease-in-out', + fontWeight: 'normal', + cursor: 'pointer', + '&:hover': { + backgroundColor: '#ebebeb', + color: '#007ad9', + }, +}); + +export const ZeroHeader: FunctionComponent = () => { + const [visible, setVisible] = useState(false); + const navigate = useNavigate(); + + const loadContent = (navidateTo: To) => { + setVisible(false); + navigate(navidateTo) + } + return ( + + ); +}; \ No newline at end of file diff --git a/frontend/src/components/zero-layout.tsx b/frontend/src/components/zero-layout.tsx index 2a136c3e..00391cae 100644 --- a/frontend/src/components/zero-layout.tsx +++ b/frontend/src/components/zero-layout.tsx @@ -29,4 +29,5 @@ export const ZeroLayout: FunctionComponent} {children}
-) \ No newline at end of file +) + diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index b57d66b5..4a42ae42 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -1,106 +1,12 @@ import React from 'react' import ReactDOM from 'react-dom/client' -import { - createBrowserRouter, - RouterProvider, -} from "react-router-dom"; import './index.css' -import {DE_WIEKEN, getProjectConfiguration, HESSENPOORT, ProjectName} from "./components/company-survey-v2/project" -import {Survey, SurveyFromProject} from "./components/company-survey-v2/survey" -import {ThankYou} from './components/thank-you' import reportWebVitals from './reportWebVitals' -import App from "./App"; -import {LoginWidget} from "./user/login"; -import {BedrijvenFormV1} from "./components/bedrijven-form-v1"; -import {Admin} from "./admin/admin"; -import { - fetchSurveyById, - SurveyById, - SurveyByIdLoaderData, - SurveyByIdRouteData, -} from "./components/company-survey-v2/survey-by-id" -import {Home} from "./components/home" -import {ExcelImport} from "./excel-import/excel-import" -import {NewSurveyByProjectName} from "./components/company-survey-v2/new-survey-by-project-name" -import {fetchBuurtcodesByProject} from "./panden-select/fetch-buurtcodes" -import {assertDefined} from "./services/util" - -const router = createBrowserRouter([ - { - path: "/", - element: , - }, - { - path: "/proof-of-concept", - element: , - }, - { - path: "/bedrijven-v1", - element: - }, - { - path: "/new-survey/:projectName", - element: , - loader: async ({params: {projectName}, request}) => { - return getProjectConfiguration(assertDefined(projectName) as ProjectName) - } - }, - { - path: "/bedrijven-hessenpoort", - element: , - loader: async () => getProjectConfiguration(HESSENPOORT.name) - }, - { - path: "/bedrijven-de-wieken", - element: , - loader: async () => getProjectConfiguration(DE_WIEKEN.name) - }, - { - path: "/bedrijven-uitvraag/:surveyId", - element: , - loader: async ({params: {surveyId}, request}): Promise => { - if (!surveyId) { - throw new Error("Survey ID is required") - } - const url = new URL(request.url); - const deeplink = url.searchParams.get("deeplink"); - const secret = url.searchParams.get("secret"); - - const survey = await fetchSurveyById({ - surveyId, - deeplink, - secret, - }) - - const project = await getProjectConfiguration(survey.zenmoProject) - - return { - survey, - project, - } - } - }, - { - path: "/bedankt", - element: , - }, - { - path: "/admin", - element: , - }, - { - path: "/admin/import-excel", - element: - }, - { - path: "/login", - element: - } -]); +import { RouterProvider } from "react-router-dom"; +import { router } from "./router"; const root = ReactDOM.createRoot( - //@ts-ignore - document.getElementById('react-root'), + document.getElementById('react-root') as HTMLElement, ) root.render( diff --git a/frontend/src/router.tsx b/frontend/src/router.tsx new file mode 100644 index 00000000..83c7b99c --- /dev/null +++ b/frontend/src/router.tsx @@ -0,0 +1,93 @@ +import { createBrowserRouter } from "react-router-dom"; + +import {DE_WIEKEN, getProjectConfiguration, HESSENPOORT, ProjectName} from "./components/company-survey-v2/project" +import {SurveyFromProject} from "./components/company-survey-v2/survey" +import {ThankYou} from './components/thank-you' +import {LoginWidget} from "./user/login"; +import {BedrijvenFormV1} from "./components/bedrijven-form-v1"; +import {Surveys} from "./admin/surveys"; +import {fetchSurveyById, SurveyById, SurveyByIdLoaderData} from "./components/company-survey-v2/survey-by-id" +import {Intro} from "./components/intro" +import {ExcelImport} from "./excel-import/excel-import" +import {NewSurveyByProjectName} from "./components/company-survey-v2/new-survey-by-project-name" +import {assertDefined} from "./services/util" +import Simulation from "./simulation"; +import {App} from "./App"; + +export const router = createBrowserRouter([ + { + path: "/", + element: , + children: [ + {path: "", element: }, + {path: "/surveys", element: }, + {path: "/simulation", element: }, + ], + }, + { + path: "/bedrijven-v1", + element: + }, + { + path: "/proof-of-concept", + element: , + }, + { + path: "/new-survey/:projectName", + element: , + loader: async ({params: {projectName}, request}) => { + return getProjectConfiguration(assertDefined(projectName) as ProjectName) + } + }, + { + path: "/bedrijven-hessenpoort", + element: , + loader: async () => getProjectConfiguration(HESSENPOORT.name) + }, + { + path: "/bedrijven-de-wieken", + element: , + loader: async () => getProjectConfiguration(DE_WIEKEN.name) + }, + { + path: "/bedrijven-uitvraag/:surveyId", + element: , + loader: async ({params: {surveyId}, request}): Promise => { + if (!surveyId) { + throw new Error("Survey ID is required") + } + const url = new URL(request.url); + const deeplink = url.searchParams.get("deeplink"); + const secret = url.searchParams.get("secret"); + + const survey = await fetchSurveyById({ + surveyId, + deeplink, + secret, + }) + + const project = await getProjectConfiguration(survey.zenmoProject) + + return { + survey, + project, + } + } + }, + { + path: "/bedankt", + element: , + }, + { + path: "/admin", + element: , + }, + { + path: "/admin/import-excel", + element: + }, + { + path: "/login", + element: + } +]); diff --git a/frontend/src/simulation.tsx b/frontend/src/simulation.tsx new file mode 100644 index 00000000..7bf3e18d --- /dev/null +++ b/frontend/src/simulation.tsx @@ -0,0 +1,54 @@ +import 'leaflet/dist/leaflet.css' +import React, {createElement as h, useState} from 'react' +import './App.css' +import {AggregatedAreaData} from './components/aggregated-area-data' +import {AnyLogic} from './components/any-logic' +import {BuurtPicker} from './components/buurt-picker' +import {MainMap} from './components/main-map' +import {PandDataDisplay} from './components/pand-display' +import {useApp} from './services/appState' +import {assertDefined} from './services/util' +import {Buurt} from './services/wijkenbuurten/buurten' +import {ZeroLayout} from "./components/zero-layout" + +function Simulation() { + const appHook = useApp() + const {setGeometry, getPandData, bag2dPanden} = appHook + + const [currentPandId, setCurrentPandId] = useState('') + + const [buurt, setBuurt] = useState() + + return ( + + {/* Three-column layout*/} +
+
+ {h(AggregatedAreaData, {appHook: appHook})} + { + setBuurt(buurt) + setGeometry(buurt.geometry) + }}/> +
+
+ + +
+
+ {currentPandId && getPandData(currentPandId) && + } +
+
+
+ ) +} + +export default Simulation