add linting and some lazy loading

This commit is contained in:
2026-04-04 18:43:54 +02:00
parent c14864aa29
commit 4c989928f1
7 changed files with 705 additions and 49 deletions
+16 -37
View File
@@ -2,20 +2,20 @@ import * as React from "react";
import "./App.css";
import {Faro} from "@grafana/faro-web-sdk";
import {createBrowserRouter, LoaderFunctionArgs, Navigate, Outlet, redirect, RouterProvider} from "react-router-dom";
import CreateCharacter from "./first-edition/pages/CreateCharacter";
import CharacterList, {CharacterListItemDto} from "./shared/pages/CharacterList";
import ErrorBoundary from "./shared/ErrorBoundary";
import Header from "./shared/Header";
import Footer from "./shared/Footer";
import CreateCharacter2E from "./second-edition/pages/CreateCharacter2E";
import store, {AppDispatch, RootState} from './store'
import { Provider } from "react-redux"
import { useSelector, useDispatch } from 'react-redux'
import {load, setUser, unsetUser, userSelector} from './shared/domain-models/userSlice'
import {fetchCurrentUser, userSelector} from './shared/domain-models/userSlice'
import {setCharacter} from "./second-edition/domain-models/characterSlice";
import {getJson, getText} from "./shared/api/http";
import {getJson} from "./shared/api/http";
import {KarakterInputs} from "./first-edition/domain-models/karakter";
import {Karakter2E} from "./second-edition/domain-models/karakter2E";
const CreateCharacter = React.lazy(() => import("./first-edition/pages/CreateCharacter"))
const CreateCharacter2E = React.lazy(() => import("./second-edition/pages/CreateCharacter2E"))
const FaroContext = React.createContext<Faro | undefined>(undefined)
@@ -43,49 +43,28 @@ function IndexRedirect() {
function CreateCharacter1ERoute() {
const faro = React.useContext(FaroContext)
return <CreateCharacter faro={faro} />
return (
<React.Suspense fallback={<div className="p-3">Betoltes...</div>}>
{faro ? <CreateCharacter faro={faro} /> : <CreateCharacter />}
</React.Suspense>
)
}
function CreateCharacter2ERoute() {
const faro = React.useContext(FaroContext)
return <CreateCharacter2E faro={faro} />
return (
<React.Suspense fallback={<div className="p-3">Betoltes...</div>}>
{faro ? <CreateCharacter2E faro={faro} /> : <CreateCharacter2E />}
</React.Suspense>
)
}
function UserBootstrap() {
const dispatch = useDispatch.withTypes<AppDispatch>()()
const fetchedUser = useSelector.withTypes<RootState>()(userSelector)
React.useEffect(() => {
if (fetchedUser.state !== "not-started") {
return;
}
let isCancelled = false;
dispatch(load())
getText("/api/User/me")
.then(userNameResponse => {
if (isCancelled) {
return;
}
if (userNameResponse && userNameResponse.length > 0) {
dispatch(setUser(userNameResponse))
} else {
dispatch(unsetUser())
}
})
.catch(() => {
if (isCancelled) {
return;
}
dispatch(unsetUser())
})
return () => {
isCancelled = true;
}
}, [dispatch, fetchedUser.state])
void dispatch(fetchCurrentUser())
}, [dispatch])
return null;
}
+38 -7
View File
@@ -1,18 +1,35 @@
import { createSlice } from '@reduxjs/toolkit'
import {createAsyncThunk, createSlice} from '@reduxjs/toolkit'
import {getText} from '../api/http'
type LoadingState = "not-started" | "loading" | "finished"
export interface UserState {
state: LoadingState,
email: string | null,
}
export const fetchCurrentUser = createAsyncThunk<string | null, void, { state: { user: UserState } }>(
'user/fetchCurrentUser',
async () => {
try {
const userNameResponse = await getText('/api/User/me')
return userNameResponse.length > 0 ? userNameResponse : null
} catch {
return null
}
},
{
condition: (_, {getState}) => getState().user.state === 'not-started',
}
)
export const userSlice = createSlice({
name: 'user',
initialState: {
state: "not-started" as LoadingState,
email: null as string | null,
},
} as UserState,
reducers: {
load: (state) => {
state.state = "loading"
return state
},
setUser: (state, action: {payload: string}) => {
state.state = "finished"
state.email = action.payload
@@ -24,10 +41,24 @@ export const userSlice = createSlice({
return state
}
},
extraReducers: builder => {
builder
.addCase(fetchCurrentUser.pending, (state) => {
state.state = 'loading'
})
.addCase(fetchCurrentUser.fulfilled, (state, action) => {
state.state = 'finished'
state.email = action.payload
})
.addCase(fetchCurrentUser.rejected, (state) => {
state.state = 'finished'
state.email = null
})
},
})
// Action creators are generated for each case reducer function
export const { load, setUser, unsetUser } = userSlice.actions
export const { setUser, unsetUser } = userSlice.actions
export const userSelector = userSlice.selectSlice