From 734daf9a5c682fd1002f7c7a4464b668a01e214d Mon Sep 17 00:00:00 2001 From: Nils Knappmeier Date: Sun, 4 Feb 2024 16:47:37 +0100 Subject: [PATCH] add welcome page --- package.json | 3 +- src/App.tsx | 55 +++++++------------------ src/assets/styles/styles-include.scss | 16 ++++++++ src/assets/styles/styles.scss | 17 +------- src/components/logo/Logo.module.scss | 5 +++ src/components/logo/Logo.tsx | 7 ++++ src/index.tsx | 25 +++++------- src/layout/DefaultLayout.tsx | 37 ++++++++++------- src/pages/chooser/index.tsx | 46 +++++++++++++++++++++ src/pages/index.module.scss | 58 +++++++++++++++++++++++++++ src/pages/index.tsx | 53 ++++++++++++++++++++++++ src/{ => router}/types/assets.d.ts | 0 src/{ => router}/types/vtest.d.ts | 0 yarn.lock | 39 ++++++++---------- 14 files changed, 251 insertions(+), 110 deletions(-) create mode 100644 src/assets/styles/styles-include.scss create mode 100644 src/components/logo/Logo.module.scss create mode 100644 src/components/logo/Logo.tsx create mode 100644 src/pages/chooser/index.tsx create mode 100644 src/pages/index.module.scss create mode 100644 src/pages/index.tsx rename src/{ => router}/types/assets.d.ts (100%) rename src/{ => router}/types/vtest.d.ts (100%) diff --git a/package.json b/package.json index 989bd6b..6d5c41a 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,6 @@ "@types/node": "^20.11.7", "@types/react": "^18.2.48", "@types/react-dom": "^18.2.18", - "@types/react-router": "^5.1.20", "bootstrap": "5.3.2", "handtrackjs": "^0.1.5", "i18next": "^23.7.20", @@ -21,7 +20,7 @@ "react-bootstrap-icons": "^1.10.3", "react-dom": "^18.2.0", "react-i18next": "^14.0.1", - "react-router": "^6.21.3", + "react-router-dom": "^6.22.0", "typescript": "^5.3.3", "web-vitals": "^3.5.2" }, diff --git a/src/App.tsx b/src/App.tsx index 2141778..c2bc0d4 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,47 +1,20 @@ -import React, { useState } from "react"; +import React from "react"; +import { RouterProvider, createHashRouter } from "react-router-dom"; import "src/assets/styles/styles.scss"; -import { DefaultLayout } from "./layout/DefaultLayout"; -import { Reader } from "./components/Reader/Reader"; -import { CreateExamButton } from "./components/ExamTableChooser/CreateExamButton"; -import { NoTechniquesChosen } from "./components/Reader/NoTechniquesChosen"; -import css from "./components/Reader/Reader.module.scss"; -import { ShowExamTable } from "./components/ShowExamTable/ShowExamTable"; -import { Button } from "react-bootstrap"; -import { Printer } from "react-bootstrap-icons"; -import { TechniqueList } from "./model/TechniqueList"; + +export const router = createHashRouter([ + { + path: "/", + lazy: () => import("src/pages"), + }, + { + path: "/chooser", + lazy: () => import("src/pages/chooser"), + }, +]); function App(): JSX.Element { - const [techniques, setTechniques] = useState(new TechniqueList()); - const [currentTechniqueIndex, setCurrentTechniqueIndex] = useState(-1); - return ( - 0 && ( - <> - - - - ) - } - > -
- {techniques.length === 0 ? ( - - ) : ( - <> -
- -
-
- -
- - )} -
-
- ); + return ; } export default App; diff --git a/src/assets/styles/styles-include.scss b/src/assets/styles/styles-include.scss new file mode 100644 index 0000000..0a91094 --- /dev/null +++ b/src/assets/styles/styles-include.scss @@ -0,0 +1,16 @@ +@import "bootstrap/scss/functions"; +@import "bootstrap/scss/variables"; +@import "bootstrap/scss/mixins"; + +$primary: #55aa77; +$info: #66bb33; +$theme-colors: ( + "primary": $primary, + "secondary": $secondary, + "success": $success, + "info": $info, + "warning": $warning, + "danger": $danger, + "light": $light, + "dark": $dark, +); diff --git a/src/assets/styles/styles.scss b/src/assets/styles/styles.scss index 43b17ad..cdcffe2 100644 --- a/src/assets/styles/styles.scss +++ b/src/assets/styles/styles.scss @@ -1,19 +1,4 @@ -@import "bootstrap/scss/functions"; -@import "bootstrap/scss/variables"; - -$primary: #55aa77; -$info: #66bb33; -$theme-colors: ( - "primary": $primary, - "secondary": $secondary, - "success": $success, - "info": $info, - "warning": $warning, - "danger": $danger, - "light": $light, - "dark": $dark, -); - +@import "./styles-include.scss"; @import "bootstrap"; $hightlighTechniqueBg: change-color($primary, $alpha: 0.3); diff --git a/src/components/logo/Logo.module.scss b/src/components/logo/Logo.module.scss new file mode 100644 index 0000000..566c99c --- /dev/null +++ b/src/components/logo/Logo.module.scss @@ -0,0 +1,5 @@ + +.logo { + width: 10rem; + height: 10rem; +} \ No newline at end of file diff --git a/src/components/logo/Logo.tsx b/src/components/logo/Logo.tsx new file mode 100644 index 0000000..950c634 --- /dev/null +++ b/src/components/logo/Logo.tsx @@ -0,0 +1,7 @@ +import React from "react"; +import css from "./Logo.module.scss"; +import logo from "src/assets/logo.svg"; + +export const Logo: React.FC<{ className?: string }> = ({ className = "" }) => { + return Logo; +}; diff --git a/src/index.tsx b/src/index.tsx index 393797e..d1ddbbd 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,5 +1,5 @@ import React from "react"; -import ReactDOM from "react-dom"; +import { createRoot } from "react-dom/client"; import "./index.css"; import App from "./App"; import reportWebVitals from "./reportWebVitals"; @@ -7,20 +7,17 @@ import { initI18Next } from "./i18n/i18n"; import i18n from "i18next"; import { initCurrentDojo } from "./exam-tables"; -async function initialize() { - await initI18Next(); - await initCurrentDojo(); -} +await initI18Next(); +document.title = i18n.t("app.title"); -initialize().then(() => { - document.title = i18n.t("app.title"); - ReactDOM.render( - - - , - document.getElementById("root") - ); -}); +await initCurrentDojo(); + +const root = createRoot(document.getElementById("root")!); +root.render( + + + , +); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) diff --git a/src/layout/DefaultLayout.tsx b/src/layout/DefaultLayout.tsx index fcac2a0..a1f70d4 100644 --- a/src/layout/DefaultLayout.tsx +++ b/src/layout/DefaultLayout.tsx @@ -5,7 +5,11 @@ import logo from "src/assets/logo.svg"; import { Square } from "react-bootstrap-icons"; import { Impress } from "src/components/Impress/Imress"; -export const DefaultLayout: React.FC<{ navbuttons: ReactNode; children: ReactNode }> = ({ children, navbuttons }) => { +export const DefaultLayout: React.FC<{ hideNavbar?: boolean; navbuttons?: ReactNode; children: ReactNode }> = ({ + children, + navbuttons, + hideNavbar = false, +}) => { const { t } = useTranslation(); return ( @@ -16,18 +20,20 @@ export const DefaultLayout: React.FC<{ navbuttons: ReactNode; children: ReactNod
{document.location.origin}
- - - - {t("app.title")} {t("app.title")} - - - -
{navbuttons}
- © Nils Knappmeier (2021) -
-
-
+ {!hideNavbar && ( + + + + {t("app.title")} {t("app.title")} + + + +
{navbuttons}
+ © Nils Knappmeier (2021) +
+
+
+ )} {children} @@ -38,8 +44,9 @@ export const DefaultLayout: React.FC<{ navbuttons: ReactNode; children: ReactNod Prüfungsprogramm {" "} - der Aikido-Föderation Deutschland. Ich übernehme keine - Garantie für die Richtigkeit und Aktualität der Daten. Fehler könnt ihr mir gerne über{" "} + der Aikido-Föderation Deutschland und des{" "} + Aikido-Dojo Darmnstadt Ich übernehme keine Garantie für die + Richtigkeit und Aktualität der Daten. Fehler könnt ihr mir gerne über{" "} Github-Issues oder per Mail schicken (siehe{" "} Github-Profil)

diff --git a/src/pages/chooser/index.tsx b/src/pages/chooser/index.tsx new file mode 100644 index 0000000..0875d69 --- /dev/null +++ b/src/pages/chooser/index.tsx @@ -0,0 +1,46 @@ +import { useState } from "react"; +import { Button } from "react-bootstrap"; +import { Printer } from "react-bootstrap-icons"; +import { CreateExamButton } from "src/components/ExamTableChooser/CreateExamButton"; +import { NoTechniquesChosen } from "src/components/Reader/NoTechniquesChosen"; +import { Reader } from "src/components/Reader/Reader"; +import { ShowExamTable } from "src/components/ShowExamTable/ShowExamTable"; +import { DefaultLayout } from "src/layout/DefaultLayout"; +import { TechniqueList } from "src/model/TechniqueList"; +import css from "src/components/Reader/Reader.module.scss"; + +export const Component: React.FC = () => { + const [techniques, setTechniques] = useState(new TechniqueList()); + const [currentTechniqueIndex, setCurrentTechniqueIndex] = useState(-1); + + return ( + 0 && ( + <> + + + + ) + } + > +
+ {techniques.length === 0 ? ( + + ) : ( + <> +
+ +
+
+ +
+ + )} +
+
+ ); +}; diff --git a/src/pages/index.module.scss b/src/pages/index.module.scss new file mode 100644 index 0000000..61c9671 --- /dev/null +++ b/src/pages/index.module.scss @@ -0,0 +1,58 @@ +@import "src/assets/styles/styles-include.scss"; + +.homepage { + margin-top: 3rem; + margin-left: auto; + margin-right: auto; + max-width: 100vh; + @include media-breakpoint-up(lg) { + max-width: 800px; + } +} + +.subheader { + text-align: center; + font-size: 1.5rem; +} +.header { + text-align: center; +} + +.logo { + text-align: center; + margin: 1rem; +} + +.teaser { + // inline style in component + // --columns: ...; + display: grid; + gap: 1rem; + grid-template-columns: 1fr; + @include media-breakpoint-up(lg) { + grid-template-columns: repeat(var(--columns), 1fr); + } +} + +.action { + text-align: center; + margin: 2rem; +} +.actionButton { + border: 2px solid lighten($warning, 30%); + padding: 0.5rem; + color: darken($warning, 30%); + background-color: lighten($warning, 40%); + font-weight: bold; + text-decoration: none; + transition: background-color 0.2s ease-in-out; + &:hover { + background-color: lighten($warning, 10%); + } +} + +.teaserItem { + background-color: lighten($primary, 40%); + padding: 1rem; + min-height: 200px; +} \ No newline at end of file diff --git a/src/pages/index.tsx b/src/pages/index.tsx new file mode 100644 index 0000000..c89142d --- /dev/null +++ b/src/pages/index.tsx @@ -0,0 +1,53 @@ +import React from "react"; +import { Link } from "react-router-dom"; +import { Logo } from "src/components/logo/Logo"; +import css from "./index.module.scss"; +import { DefaultLayout } from "src/layout/DefaultLayout"; + +function cssVar(name: string, value: string | number): React.CSSProperties { + return { + [name]: value, + } as React.CSSProperties; +} + +export const Component = () => { + return ( + +
+

Besser vorbereitet auf deine

+

Aikido-Prüfung

+ +
+ +
+
+
+ + Gleich anfangen + +
+
+
+

+ Im Training üben wir Techniken und Prinzipien. Die Techniken werden in der Prüfung abgefragt. Dabei muss + es manchmal schnell gehen. Du musst sofort wissen, welche Technik du machst. Das kann man üben: +

+
+
+

Prüfungslisten erzeugen

+

+ Mit Aikido-Prüfung kannst du dir zufällige Listen aus deinen Prüfungen erzeugen. Damit kannst du + dich beim freien Training abfragen lassen. +

+
+
+

Vorlesen lassen

+

+ Aikido-Prüfung kann die Techniken vorlesen, die ausgewählt hast. Du musst nur auf "Play" drücken. +

+
+
+
+
+ ); +}; diff --git a/src/types/assets.d.ts b/src/router/types/assets.d.ts similarity index 100% rename from src/types/assets.d.ts rename to src/router/types/assets.d.ts diff --git a/src/types/vtest.d.ts b/src/router/types/vtest.d.ts similarity index 100% rename from src/types/vtest.d.ts rename to src/router/types/vtest.d.ts diff --git a/yarn.lock b/yarn.lock index bab97be..78c3402 100644 --- a/yarn.lock +++ b/yarn.lock @@ -528,10 +528,10 @@ dependencies: "@swc/helpers" "^0.5.0" -"@remix-run/router@1.14.2": - version "1.14.2" - resolved "https://registry.npmjs.org/@remix-run/router/-/router-1.14.2.tgz" - integrity sha512-ACXpdMM9hmKZww21yEqWwiLws/UPLhNKvimN8RrYSqPSvB3ov7sLvAcfvaxePeLvccTQKGdkDIhLYApZVDFuKg== +"@remix-run/router@1.15.0": + version "1.15.0" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.15.0.tgz#461a952c2872dd82c8b2e9b74c4dfaff569123e2" + integrity sha512-HOil5aFtme37dVQTB6M34G95kPM3MMuqSmIRVCC52eKV+Y/tGSqw9P3rWhlAx6A+mz+MoX+XxsGsNJbaI5qCgQ== "@restart/hooks@^0.4.9": version "0.4.15" @@ -828,11 +828,6 @@ "@types/qs" "*" "@types/serve-static" "*" -"@types/history@^4.7.11": - version "4.7.11" - resolved "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz" - integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA== - "@types/http-errors@*": version "2.0.4" resolved "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz" @@ -912,14 +907,6 @@ dependencies: "@types/react" "*" -"@types/react-router@^5.1.20": - version "5.1.20" - resolved "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz" - integrity sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q== - dependencies: - "@types/history" "^4.7.11" - "@types/react" "*" - "@types/react-transition-group@^4.4.6": version "4.4.10" resolved "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz" @@ -4360,12 +4347,20 @@ react-refresh@^0.14.0: resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz" integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ== -react-router@^6.21.3: - version "6.21.3" - resolved "https://registry.npmjs.org/react-router/-/react-router-6.21.3.tgz" - integrity sha512-a0H638ZXULv1OdkmiK6s6itNhoy33ywxmUFT/xtSoVyf9VnC7n7+VT4LjVzdIHSaF5TIh9ylUgxMXksHTgGrKg== +react-router-dom@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.22.0.tgz#177c8bd27146decbb991eafb5df159f7a9f70035" + integrity sha512-z2w+M4tH5wlcLmH3BMMOMdrtrJ9T3oJJNsAlBJbwk+8Syxd5WFJ7J5dxMEW0/GEXD1BBis4uXRrNIz3mORr0ag== + dependencies: + "@remix-run/router" "1.15.0" + react-router "6.22.0" + +react-router@6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.22.0.tgz#a22b44851a79dafc6b944cb418db3e80622b9be1" + integrity sha512-q2yemJeg6gw/YixRlRnVx6IRJWZD6fonnfZhN1JIOhV2iJCPeRNSH3V1ISwHf+JWcESzLC3BOLD1T07tmO5dmg== dependencies: - "@remix-run/router" "1.14.2" + "@remix-run/router" "1.15.0" react-transition-group@^4.4.5: version "4.4.5"