Begin consumption of API
This commit is contained in:
parent
b40ae7d701
commit
1b62b890b9
617
exam/dist/assets/index-Bv9g1hLV.js
vendored
Normal file
617
exam/dist/assets/index-Bv9g1hLV.js
vendored
Normal file
File diff suppressed because one or more lines are too long
509
exam/dist/assets/index-CCI8Q-vE.js
vendored
509
exam/dist/assets/index-CCI8Q-vE.js
vendored
File diff suppressed because one or more lines are too long
2
exam/dist/index.html
vendored
2
exam/dist/index.html
vendored
@ -5,7 +5,7 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/phpCourse/exam/dist/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + React + TS</title>
|
||||
<script type="module" crossorigin src="/phpCourse/exam/dist/assets/index-CCI8Q-vE.js"></script>
|
||||
<script type="module" crossorigin src="/phpCourse/exam/dist/assets/index-Bv9g1hLV.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
1
exam/react/.nvmrc
Normal file
1
exam/react/.nvmrc
Normal file
@ -0,0 +1 @@
|
||||
v18
|
||||
@ -13,12 +13,18 @@
|
||||
"@emotion/react": "^11.13.0",
|
||||
"@emotion/styled": "^11.13.0",
|
||||
"@mui/material": "^5.16.4",
|
||||
"@tanstack/react-query": "^5.51.11",
|
||||
"@tanstack/react-router": "^1.45.8",
|
||||
"@types/node": "^20.14.12",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
"react-dom": "^18.3.1",
|
||||
"zustand": "^4.5.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@redux-devtools/extension": "^3.3.0",
|
||||
"@tanstack/eslint-plugin-query": "^5.51.12",
|
||||
"@tanstack/router-devtools": "^1.45.8",
|
||||
"@tanstack/react-query-devtools": "^5.51.11",
|
||||
"@tanstack/router-plugin": "^1.45.8",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
|
||||
209
exam/react/pnpm-lock.yaml
generated
209
exam/react/pnpm-lock.yaml
generated
@ -17,22 +17,40 @@ importers:
|
||||
'@mui/material':
|
||||
specifier: ^5.16.4
|
||||
version: 5.16.4(@emotion/react@11.13.0(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.0(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@tanstack/react-query':
|
||||
specifier: ^5.51.11
|
||||
version: 5.51.11(react@18.3.1)
|
||||
'@tanstack/react-query-devtools':
|
||||
specifier: ^5.51.11
|
||||
version: 5.51.11(@tanstack/react-query@5.51.11(react@18.3.1))(react@18.3.1)
|
||||
'@tanstack/react-router':
|
||||
specifier: ^1.45.8
|
||||
version: 1.45.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@types/node':
|
||||
specifier: ^20.14.12
|
||||
version: 20.14.12
|
||||
react:
|
||||
specifier: ^18.3.1
|
||||
version: 18.3.1
|
||||
react-dom:
|
||||
specifier: ^18.3.1
|
||||
version: 18.3.1(react@18.3.1)
|
||||
zustand:
|
||||
specifier: ^4.5.4
|
||||
version: 4.5.4(@types/react@18.3.3)(react@18.3.1)
|
||||
devDependencies:
|
||||
'@redux-devtools/extension':
|
||||
specifier: ^3.3.0
|
||||
version: 3.3.0(redux@5.0.1)
|
||||
'@tanstack/eslint-plugin-query':
|
||||
specifier: ^5.51.12
|
||||
version: 5.51.12(eslint@8.57.0)(typescript@5.5.3)
|
||||
'@tanstack/router-devtools':
|
||||
specifier: ^1.45.8
|
||||
version: 1.45.8(@tanstack/react-router@1.45.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(csstype@3.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@tanstack/router-plugin':
|
||||
specifier: ^1.45.8
|
||||
version: 1.45.8(vite@5.3.4)
|
||||
version: 1.45.8(vite@5.3.4(@types/node@20.14.12))
|
||||
'@types/react':
|
||||
specifier: ^18.3.3
|
||||
version: 18.3.3
|
||||
@ -47,7 +65,7 @@ importers:
|
||||
version: 7.16.1(eslint@8.57.0)(typescript@5.5.3)
|
||||
'@vitejs/plugin-react':
|
||||
specifier: ^4.3.1
|
||||
version: 4.3.1(vite@5.3.4)
|
||||
version: 4.3.1(vite@5.3.4(@types/node@20.14.12))
|
||||
eslint:
|
||||
specifier: ^8.57.0
|
||||
version: 8.57.0
|
||||
@ -68,7 +86,7 @@ importers:
|
||||
version: 5.5.3
|
||||
vite:
|
||||
specifier: ^5.3.4
|
||||
version: 5.3.4
|
||||
version: 5.3.4(@types/node@20.14.12)
|
||||
|
||||
packages:
|
||||
|
||||
@ -528,6 +546,11 @@ packages:
|
||||
'@popperjs/core@2.11.8':
|
||||
resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
|
||||
|
||||
'@redux-devtools/extension@3.3.0':
|
||||
resolution: {integrity: sha512-X34S/rC8S/M1BIrkYD1mJ5f8vlH0BDqxXrs96cvxSBo4FhMdbhU+GUGsmNYov1xjSyLMHgo8NYrUG8bNX7525g==}
|
||||
peerDependencies:
|
||||
redux: ^3.1.0 || ^4.0.0 || ^5.0.0
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.18.1':
|
||||
resolution: {integrity: sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==}
|
||||
cpu: [arm]
|
||||
@ -608,10 +631,32 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@tanstack/eslint-plugin-query@5.51.12':
|
||||
resolution: {integrity: sha512-vzUXXIVzDP2c6wVSJ+1imPGaKQ2ILuWnta64FJc/JnQ5WunfO17bQJSk6uKDbzTQG/YKgPYBMG3C9qFA4b7Ayg==}
|
||||
peerDependencies:
|
||||
eslint: ^8 || ^9
|
||||
|
||||
'@tanstack/history@1.45.3':
|
||||
resolution: {integrity: sha512-n4XXInV9irIq0obRvINIkESkGk280Q+xkIIbswmM0z9nAu2wsIRZNvlmPrtYh6bgNWtItOWWoihFUjLTW8g6Jg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
'@tanstack/query-core@5.51.9':
|
||||
resolution: {integrity: sha512-HsAwaY5J19MD18ykZDS3aVVh+bAt0i7m6uQlFC2b77DLV9djo+xEN7MWQAQQTR8IM+7r/zbozTQ7P0xr0bHuew==}
|
||||
|
||||
'@tanstack/query-devtools@5.51.9':
|
||||
resolution: {integrity: sha512-FQqJynaEDuwQxoFLP3/i10HQwNYh4wxgs0NeSoL24BLWvpUdstgHqUm2zgwRov8Tmh5kjndPIWaXenwl0D47EA==}
|
||||
|
||||
'@tanstack/react-query-devtools@5.51.11':
|
||||
resolution: {integrity: sha512-8nQRbhdtvl/J9bO+bk/kPQesCOtDgk+oI4AmZJDnkf5OfKTJL3J4tTe+fhuXph7KP4DUOS+ge9o9TGt0OgWFHw==}
|
||||
peerDependencies:
|
||||
'@tanstack/react-query': ^5.51.11
|
||||
react: ^18 || ^19
|
||||
|
||||
'@tanstack/react-query@5.51.11':
|
||||
resolution: {integrity: sha512-4Kq2x0XpDlpvSnaLG+8pHNH60zEc3mBvb3B2tOMDjcPCi/o+Du3p/9qpPLwJOTliVxxPJAP27fuIhLrsRdCr7A==}
|
||||
peerDependencies:
|
||||
react: ^18.0.0
|
||||
|
||||
'@tanstack/react-router@1.45.8':
|
||||
resolution: {integrity: sha512-hLJOKDK5lGHteoMjpF6COQrlhsl4C6GyBCzmSJHFcoh26GBa7tv/94li0H1a3deJpzMNpSvmSXrQDpxj9h9bNA==}
|
||||
engines: {node: '>=12'}
|
||||
@ -670,6 +715,9 @@ packages:
|
||||
'@types/estree@1.0.5':
|
||||
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
|
||||
|
||||
'@types/node@20.14.12':
|
||||
resolution: {integrity: sha512-r7wNXakLeSsGT0H1AU863vS2wa5wBOK4bWMjZz2wj+8nBx+m5PeIn0k8AloSLpRuiwdRQZwarZqHE4FNArPuJQ==}
|
||||
|
||||
'@types/parse-json@4.0.2':
|
||||
resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==}
|
||||
|
||||
@ -710,6 +758,10 @@ packages:
|
||||
resolution: {integrity: sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==}
|
||||
engines: {node: ^18.18.0 || >=20.0.0}
|
||||
|
||||
'@typescript-eslint/scope-manager@8.0.0-alpha.30':
|
||||
resolution: {integrity: sha512-FGW/iPWGyPFamAVZ60oCAthMqQrqafUGebF8UKuq/ha+e9SVG6YhJoRzurlQXOVf8dHfOhJ0ADMXyFnMc53clg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/type-utils@7.16.1':
|
||||
resolution: {integrity: sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==}
|
||||
engines: {node: ^18.18.0 || >=20.0.0}
|
||||
@ -724,6 +776,10 @@ packages:
|
||||
resolution: {integrity: sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==}
|
||||
engines: {node: ^18.18.0 || >=20.0.0}
|
||||
|
||||
'@typescript-eslint/types@8.0.0-alpha.30':
|
||||
resolution: {integrity: sha512-4WzLlw27SO9pK9UFj/Hu7WGo8WveT0SEiIpFVsV2WwtQmLps6kouwtVCB8GJPZKJyurhZhcqCoQVQFmpv441Vg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/typescript-estree@7.16.1':
|
||||
resolution: {integrity: sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==}
|
||||
engines: {node: ^18.18.0 || >=20.0.0}
|
||||
@ -733,16 +789,35 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.0.0-alpha.30':
|
||||
resolution: {integrity: sha512-WSXbc9ZcXI+7yC+6q95u77i8FXz6HOLsw3ST+vMUlFy1lFbXyFL/3e6HDKQCm2Clt0krnoCPiTGvIn+GkYPn4Q==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '*'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/utils@7.16.1':
|
||||
resolution: {integrity: sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==}
|
||||
engines: {node: ^18.18.0 || >=20.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.56.0
|
||||
|
||||
'@typescript-eslint/utils@8.0.0-alpha.30':
|
||||
resolution: {integrity: sha512-rfhqfLqFyXhHNDwMnHiVGxl/Z2q/3guQ1jLlGQ0hi9Rb7inmwz42crM+NnLPR+2vEnwyw1P/g7fnQgQ3qvFx4g==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
|
||||
'@typescript-eslint/visitor-keys@7.16.1':
|
||||
resolution: {integrity: sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==}
|
||||
engines: {node: ^18.18.0 || >=20.0.0}
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.0.0-alpha.30':
|
||||
resolution: {integrity: sha512-XZuNurZxBqmr6ZIRIwWFq7j5RZd6ZlkId/HZEWyfciK+CWoyOxSF9Pv2VXH9Rlu2ZG2PfbhLz2Veszl4Pfn7yA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@ungap/structured-clone@1.2.0':
|
||||
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
|
||||
|
||||
@ -1067,6 +1142,9 @@ packages:
|
||||
resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
|
||||
engines: {node: '>= 4'}
|
||||
|
||||
immutable@4.3.7:
|
||||
resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==}
|
||||
|
||||
import-fresh@3.3.0:
|
||||
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
|
||||
engines: {node: '>=6'}
|
||||
@ -1316,6 +1394,9 @@ packages:
|
||||
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
|
||||
engines: {node: '>=8.10.0'}
|
||||
|
||||
redux@5.0.1:
|
||||
resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==}
|
||||
|
||||
regenerator-runtime@0.14.1:
|
||||
resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
|
||||
|
||||
@ -1435,6 +1516,9 @@ packages:
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
undici-types@5.26.5:
|
||||
resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
|
||||
|
||||
unplugin@1.11.0:
|
||||
resolution: {integrity: sha512-3r7VWZ/webh0SGgJScpWl2/MRCZK5d3ZYFcNaeci/GQ7Teop7zf0Nl2pUuz7G21BwPd9pcUPOC5KmJ2L3WgC5g==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
@ -1448,6 +1532,11 @@ packages:
|
||||
uri-js@4.4.1:
|
||||
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
||||
|
||||
use-sync-external-store@1.2.0:
|
||||
resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
|
||||
use-sync-external-store@1.2.2:
|
||||
resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==}
|
||||
peerDependencies:
|
||||
@ -1514,6 +1603,21 @@ packages:
|
||||
zod@3.23.8:
|
||||
resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==}
|
||||
|
||||
zustand@4.5.4:
|
||||
resolution: {integrity: sha512-/BPMyLKJPtFEvVL0E9E9BTUM63MNyhPGlvxk1XjrfWTUlV+BR8jufjsovHzrtR6YNcBEcL7cMHovL1n9xHawEg==}
|
||||
engines: {node: '>=12.7.0'}
|
||||
peerDependencies:
|
||||
'@types/react': '>=16.8'
|
||||
immer: '>=9.0.6'
|
||||
react: '>=16.8'
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
immer:
|
||||
optional: true
|
||||
react:
|
||||
optional: true
|
||||
|
||||
snapshots:
|
||||
|
||||
'@ampproject/remapping@2.3.0':
|
||||
@ -1972,6 +2076,12 @@ snapshots:
|
||||
|
||||
'@popperjs/core@2.11.8': {}
|
||||
|
||||
'@redux-devtools/extension@3.3.0(redux@5.0.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.8
|
||||
immutable: 4.3.7
|
||||
redux: 5.0.1
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.18.1':
|
||||
optional: true
|
||||
|
||||
@ -2020,8 +2130,31 @@ snapshots:
|
||||
'@rollup/rollup-win32-x64-msvc@4.18.1':
|
||||
optional: true
|
||||
|
||||
'@tanstack/eslint-plugin-query@5.51.12(eslint@8.57.0)(typescript@5.5.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/utils': 8.0.0-alpha.30(eslint@8.57.0)(typescript@5.5.3)
|
||||
eslint: 8.57.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
'@tanstack/history@1.45.3': {}
|
||||
|
||||
'@tanstack/query-core@5.51.9': {}
|
||||
|
||||
'@tanstack/query-devtools@5.51.9': {}
|
||||
|
||||
'@tanstack/react-query-devtools@5.51.11(@tanstack/react-query@5.51.11(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@tanstack/query-devtools': 5.51.9
|
||||
'@tanstack/react-query': 5.51.11(react@18.3.1)
|
||||
react: 18.3.1
|
||||
|
||||
'@tanstack/react-query@5.51.11(react@18.3.1)':
|
||||
dependencies:
|
||||
'@tanstack/query-core': 5.51.9
|
||||
react: 18.3.1
|
||||
|
||||
'@tanstack/react-router@1.45.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@tanstack/history': 1.45.3
|
||||
@ -2053,7 +2186,7 @@ snapshots:
|
||||
prettier: 3.3.3
|
||||
zod: 3.23.8
|
||||
|
||||
'@tanstack/router-plugin@1.45.8(vite@5.3.4)':
|
||||
'@tanstack/router-plugin@1.45.8(vite@5.3.4(@types/node@20.14.12))':
|
||||
dependencies:
|
||||
'@babel/core': 7.24.9
|
||||
'@babel/generator': 7.24.10
|
||||
@ -2073,7 +2206,7 @@ snapshots:
|
||||
unplugin: 1.11.0
|
||||
zod: 3.23.8
|
||||
optionalDependencies:
|
||||
vite: 5.3.4
|
||||
vite: 5.3.4(@types/node@20.14.12)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@ -2102,6 +2235,10 @@ snapshots:
|
||||
|
||||
'@types/estree@1.0.5': {}
|
||||
|
||||
'@types/node@20.14.12':
|
||||
dependencies:
|
||||
undici-types: 5.26.5
|
||||
|
||||
'@types/parse-json@4.0.2': {}
|
||||
|
||||
'@types/prop-types@15.7.12': {}
|
||||
@ -2155,6 +2292,11 @@ snapshots:
|
||||
'@typescript-eslint/types': 7.16.1
|
||||
'@typescript-eslint/visitor-keys': 7.16.1
|
||||
|
||||
'@typescript-eslint/scope-manager@8.0.0-alpha.30':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.0.0-alpha.30
|
||||
'@typescript-eslint/visitor-keys': 8.0.0-alpha.30
|
||||
|
||||
'@typescript-eslint/type-utils@7.16.1(eslint@8.57.0)(typescript@5.5.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.3)
|
||||
@ -2169,6 +2311,8 @@ snapshots:
|
||||
|
||||
'@typescript-eslint/types@7.16.1': {}
|
||||
|
||||
'@typescript-eslint/types@8.0.0-alpha.30': {}
|
||||
|
||||
'@typescript-eslint/typescript-estree@7.16.1(typescript@5.5.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 7.16.1
|
||||
@ -2184,6 +2328,21 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.0.0-alpha.30(typescript@5.5.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.0.0-alpha.30
|
||||
'@typescript-eslint/visitor-keys': 8.0.0-alpha.30
|
||||
debug: 4.3.5
|
||||
globby: 11.1.0
|
||||
is-glob: 4.0.3
|
||||
minimatch: 9.0.5
|
||||
semver: 7.6.3
|
||||
ts-api-utils: 1.3.0(typescript@5.5.3)
|
||||
optionalDependencies:
|
||||
typescript: 5.5.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/utils@7.16.1(eslint@8.57.0)(typescript@5.5.3)':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
|
||||
@ -2195,21 +2354,37 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
'@typescript-eslint/utils@8.0.0-alpha.30(eslint@8.57.0)(typescript@5.5.3)':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
|
||||
'@typescript-eslint/scope-manager': 8.0.0-alpha.30
|
||||
'@typescript-eslint/types': 8.0.0-alpha.30
|
||||
'@typescript-eslint/typescript-estree': 8.0.0-alpha.30(typescript@5.5.3)
|
||||
eslint: 8.57.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
'@typescript-eslint/visitor-keys@7.16.1':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 7.16.1
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.0.0-alpha.30':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.0.0-alpha.30
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
'@ungap/structured-clone@1.2.0': {}
|
||||
|
||||
'@vitejs/plugin-react@4.3.1(vite@5.3.4)':
|
||||
'@vitejs/plugin-react@4.3.1(vite@5.3.4(@types/node@20.14.12))':
|
||||
dependencies:
|
||||
'@babel/core': 7.24.9
|
||||
'@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.24.9)
|
||||
'@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.24.9)
|
||||
'@types/babel__core': 7.20.5
|
||||
react-refresh: 0.14.2
|
||||
vite: 5.3.4
|
||||
vite: 5.3.4(@types/node@20.14.12)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@ -2582,6 +2757,8 @@ snapshots:
|
||||
|
||||
ignore@5.3.1: {}
|
||||
|
||||
immutable@4.3.7: {}
|
||||
|
||||
import-fresh@3.3.0:
|
||||
dependencies:
|
||||
parent-module: 1.0.1
|
||||
@ -2788,6 +2965,8 @@ snapshots:
|
||||
dependencies:
|
||||
picomatch: 2.3.1
|
||||
|
||||
redux@5.0.1: {}
|
||||
|
||||
regenerator-runtime@0.14.1: {}
|
||||
|
||||
resolve-from@4.0.0: {}
|
||||
@ -2892,6 +3071,8 @@ snapshots:
|
||||
|
||||
typescript@5.5.3: {}
|
||||
|
||||
undici-types@5.26.5: {}
|
||||
|
||||
unplugin@1.11.0:
|
||||
dependencies:
|
||||
acorn: 8.12.1
|
||||
@ -2909,16 +3090,21 @@ snapshots:
|
||||
dependencies:
|
||||
punycode: 2.3.1
|
||||
|
||||
use-sync-external-store@1.2.0(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
|
||||
use-sync-external-store@1.2.2(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
|
||||
vite@5.3.4:
|
||||
vite@5.3.4(@types/node@20.14.12):
|
||||
dependencies:
|
||||
esbuild: 0.21.5
|
||||
postcss: 8.4.39
|
||||
rollup: 4.18.1
|
||||
optionalDependencies:
|
||||
'@types/node': 20.14.12
|
||||
fsevents: 2.3.3
|
||||
|
||||
webpack-sources@3.2.3: {}
|
||||
@ -2940,3 +3126,10 @@ snapshots:
|
||||
yocto-queue@0.1.0: {}
|
||||
|
||||
zod@3.23.8: {}
|
||||
|
||||
zustand@4.5.4(@types/react@18.3.3)(react@18.3.1):
|
||||
dependencies:
|
||||
use-sync-external-store: 1.2.0(react@18.3.1)
|
||||
optionalDependencies:
|
||||
'@types/react': 18.3.3
|
||||
react: 18.3.1
|
||||
|
||||
61
exam/react/src/api/Api.ts
Normal file
61
exam/react/src/api/Api.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import { User } from '../types/User';
|
||||
|
||||
const BASE = 'https://khofmann.userpage.fu-berlin.de/phpCourse/exam/api/';
|
||||
|
||||
let instance: ApiImpl;
|
||||
|
||||
class ApiImpl {
|
||||
private token: string = '';
|
||||
|
||||
constructor() {
|
||||
if (instance) {
|
||||
throw new Error('New instance cannot be created!!');
|
||||
}
|
||||
|
||||
instance = this;
|
||||
}
|
||||
|
||||
public logIn = async (email: string, password: string): Promise<User> => {
|
||||
const { user, token } = await (await this.post('login', { email, password })).json();
|
||||
this.token = token;
|
||||
|
||||
return user;
|
||||
};
|
||||
|
||||
public logOut = async (): Promise<boolean> => {
|
||||
return await (await this.postAuth('logout')).json();
|
||||
};
|
||||
|
||||
private post = async (
|
||||
endpoint: string,
|
||||
body: Record<string, unknown> | undefined = undefined,
|
||||
headers: HeadersInit | undefined = undefined
|
||||
) => {
|
||||
const response = await fetch(`${BASE}${endpoint}`, {
|
||||
mode: 'cors',
|
||||
method: 'post',
|
||||
headers,
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
if (response.ok) return response;
|
||||
throw await response.json();
|
||||
};
|
||||
|
||||
private postAuth = async (
|
||||
endpoint: string,
|
||||
body: Record<string, unknown> | undefined = undefined,
|
||||
headers: HeadersInit | undefined = undefined
|
||||
) => {
|
||||
const response = await fetch(`${BASE}${endpoint}`, {
|
||||
mode: 'cors',
|
||||
method: 'post',
|
||||
headers: { token: this.token, ...headers },
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
if (response.ok) return response;
|
||||
throw await response.json();
|
||||
};
|
||||
}
|
||||
|
||||
const Api = new ApiImpl();
|
||||
export default Api;
|
||||
@ -1,12 +1,27 @@
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { RouterProvider, createRouter } from '@tanstack/react-router';
|
||||
import { StrictMode } from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
|
||||
// Import the generated route tree
|
||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
||||
import { routeTree } from './routeTree.gen';
|
||||
|
||||
// Query Client
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
// Create a new router instance
|
||||
const router = createRouter({ routeTree });
|
||||
const router = createRouter({
|
||||
routeTree,
|
||||
context: {
|
||||
queryClient,
|
||||
},
|
||||
defaultPreload: 'intent',
|
||||
// Since we're using React Query, we don't want loader calls to ever be stale
|
||||
// This will ensure that the loader is always called when the route is preloaded or visited
|
||||
defaultPreloadStaleTime: 0,
|
||||
basepath: process.env.NODE_ENV === 'development' ? 'phpCourse/exam/dist' : '/phpCourse/exam',
|
||||
});
|
||||
|
||||
// Register the router instance for type safety
|
||||
declare module '@tanstack/react-router' {
|
||||
@ -21,7 +36,10 @@ if (!rootElement.innerHTML) {
|
||||
const root = ReactDOM.createRoot(rootElement);
|
||||
root.render(
|
||||
<StrictMode>
|
||||
<RouterProvider router={router} />
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<RouterProvider router={router} />
|
||||
<ReactQueryDevtools initialIsOpen={false} />
|
||||
</QueryClientProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
}
|
||||
|
||||
@ -11,18 +11,32 @@
|
||||
// Import Routes
|
||||
|
||||
import { Route as rootRoute } from './routes/__root'
|
||||
import { Route as IndexImport } from './routes/index'
|
||||
|
||||
// Create/Update Routes
|
||||
|
||||
const IndexRoute = IndexImport.update({
|
||||
path: '/',
|
||||
getParentRoute: () => rootRoute,
|
||||
} as any)
|
||||
|
||||
// Populate the FileRoutesByPath interface
|
||||
|
||||
declare module '@tanstack/react-router' {
|
||||
interface FileRoutesByPath {}
|
||||
interface FileRoutesByPath {
|
||||
'/': {
|
||||
id: '/'
|
||||
path: '/'
|
||||
fullPath: '/'
|
||||
preLoaderRoute: typeof IndexImport
|
||||
parentRoute: typeof rootRoute
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create and export the route tree
|
||||
|
||||
export const routeTree = rootRoute.addChildren({})
|
||||
export const routeTree = rootRoute.addChildren({ IndexRoute })
|
||||
|
||||
/* prettier-ignore-end */
|
||||
|
||||
@ -31,7 +45,12 @@ export const routeTree = rootRoute.addChildren({})
|
||||
"routes": {
|
||||
"__root__": {
|
||||
"filePath": "__root.tsx",
|
||||
"children": []
|
||||
"children": [
|
||||
"/"
|
||||
]
|
||||
},
|
||||
"/": {
|
||||
"filePath": "index.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,19 @@
|
||||
import { createRootRoute, Outlet } from '@tanstack/react-router';
|
||||
import { QueryClient } from '@tanstack/react-query';
|
||||
import { createRootRouteWithContext, Link, Outlet } from '@tanstack/react-router';
|
||||
import { TanStackRouterDevtools } from '@tanstack/router-devtools';
|
||||
|
||||
export const Route = createRootRoute({
|
||||
export const Route = createRootRouteWithContext<{ queryClient: QueryClient }>()({
|
||||
component: () => (
|
||||
<>
|
||||
<Link
|
||||
to="/"
|
||||
activeProps={{
|
||||
className: 'font-bold',
|
||||
}}
|
||||
activeOptions={{ exact: true }}
|
||||
>
|
||||
Home
|
||||
</Link>
|
||||
<Outlet />
|
||||
<TanStackRouterDevtools />
|
||||
</>
|
||||
|
||||
40
exam/react/src/routes/index.tsx
Normal file
40
exam/react/src/routes/index.tsx
Normal file
@ -0,0 +1,40 @@
|
||||
import { Button } from '@mui/material';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
import Api from '../api/Api';
|
||||
import useGuestBookStore from '../store/store';
|
||||
|
||||
export const Route = createFileRoute('/')({
|
||||
component: Home,
|
||||
});
|
||||
|
||||
function Home() {
|
||||
const setUser = useGuestBookStore((state) => state.setUser);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
onClick={async () => {
|
||||
try {
|
||||
setUser(await Api.logIn('max@moritz.net', 'max'));
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}}
|
||||
>
|
||||
Log In
|
||||
</Button>
|
||||
<Button
|
||||
onClick={async () => {
|
||||
try {
|
||||
await Api.logOut();
|
||||
setUser(undefined);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}}
|
||||
>
|
||||
Log Out
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
18
exam/react/src/store/store.ts
Normal file
18
exam/react/src/store/store.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import type {} from '@redux-devtools/extension'; // required for devtools typing
|
||||
import { create } from 'zustand';
|
||||
import { devtools } from 'zustand/middleware';
|
||||
import { User } from '../types/User';
|
||||
|
||||
interface GuestBookState {
|
||||
user: User | undefined;
|
||||
setUser: (user: User | undefined) => void;
|
||||
}
|
||||
|
||||
const useGuestBookStore = create<GuestBookState>()(
|
||||
devtools((set) => ({
|
||||
user: undefined,
|
||||
setUser: (user: User | undefined) => set(() => ({ user })),
|
||||
}))
|
||||
);
|
||||
|
||||
export default useGuestBookStore;
|
||||
6
exam/react/src/types/Responses.ts
Normal file
6
exam/react/src/types/Responses.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { User } from './User';
|
||||
|
||||
export interface LoginResponse {
|
||||
token: string;
|
||||
user: User;
|
||||
}
|
||||
5
exam/react/src/types/Timestamp.ts
Normal file
5
exam/react/src/types/Timestamp.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export interface Timestamp {
|
||||
date: string;
|
||||
timezone_type: number;
|
||||
timezone: string;
|
||||
}
|
||||
12
exam/react/src/types/User.ts
Normal file
12
exam/react/src/types/User.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { Timestamp } from './Timestamp';
|
||||
|
||||
export interface User {
|
||||
id: number;
|
||||
username: string;
|
||||
status: number;
|
||||
email: string;
|
||||
image: string;
|
||||
isAdmin: boolean;
|
||||
memberSince: Timestamp;
|
||||
postCount: number;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user