Implement store

This commit is contained in:
2025-05-09 11:17:58 +02:00
parent eb13123d86
commit 149d8f01b7
4 changed files with 124 additions and 3 deletions

View File

@@ -1,6 +1,11 @@
import LoadFilePage from "./pages/LoadFilePage/LoadFilePage"; import LoadFilePage from "./pages/LoadFilePage/LoadFilePage";
import { AppStoreProvider } from "./store/AppStore";
export default function App() { export default function App() {
return (<LoadFilePage />); return (
<AppStoreProvider>
<LoadFilePage />
</AppStoreProvider>
);
} }

View File

@@ -1,8 +1,10 @@
import { useCallback, useEffect, useState } from 'react'; import { useCallback, useEffect, useState } from 'react';
import LoadFileForm from './LoadFileForm'; import LoadFileForm from './LoadFileForm';
import { fetchConfig, loadTransactions } from '../../services/api.service'; import { fetchConfig, loadTransactions } from '../../services/api.service';
import { useStore } from '../../store/AppStore';
export default function LoadFilePage() { export default function LoadFilePage() {
const { dispatch } = useStore();
const [profiles, setProfiles] = useState<string[]>([]); const [profiles, setProfiles] = useState<string[]>([]);
const [servers, setServers] = useState<string[]>([]); const [servers, setServers] = useState<string[]>([]);
@@ -16,6 +18,11 @@ export default function LoadFilePage() {
setServers(config.servers); setServers(config.servers);
setDefaultProfile(config.defaultProfile); setDefaultProfile(config.defaultProfile);
setDefaultServer(config.defaultServer); setDefaultServer(config.defaultServer);
dispatch({
type: 'UPDATE_CONFIG',
payload: config
});
}, [setProfiles, setServers, setDefaultProfile, setDefaultServer]); }, [setProfiles, setServers, setDefaultProfile, setDefaultServer]);
useEffect(() => { useEffect(() => {
@@ -24,14 +31,22 @@ export default function LoadFilePage() {
const handleSubmit = useCallback(async (csvFile: File, profile: string, server: string) => { const handleSubmit = useCallback(async (csvFile: File, profile: string, server: string) => {
const data = await loadTransactions(csvFile, profile, server); const data = await loadTransactions(csvFile, profile, server);
console.log(data);
dispatch({
type: 'UPDATE_DATA',
payload: {
profile,
server,
...data
}
});
}, []); }, []);
return ( return (
<div className="columns mt-6"> <div className="columns mt-6">
<div className="column is-6 is-offset-3"> <div className="column is-6 is-offset-3">
<div className="box"> <div className="box">
<h2 className="title is-4 has-text-centered">Import Transactions</h2> <h2 className="title is-4 has-text-centered">Import Transactions</h2>
<LoadFileForm <LoadFileForm
profiles={profiles} profiles={profiles}
servers={servers} servers={servers}

View File

@@ -0,0 +1,64 @@
import type { State, Action, StoreContext } from "../types/store";
import { createContext, useContext, useMemo, useReducer } from "react";
export type AppStoreProviderProps = {
children: React.ReactNode;
}
export type UseStoreReturnType = StoreContext & {
};
function reducer(state: State, action: Action): State {
switch(action.type) {
case 'UPDATE_CONFIG':
return {
...state,
availableProfiles: action.payload.profiles,
availableServers: action.payload.servers,
defaultProfile: action.payload.defaultProfile,
defaultServer: action.payload.defaultServer,
};
case 'UPDATE_DATA':
return {
...state,
profile: action.payload.profile,
server: action.payload.server,
transactions: action.payload.transactions,
skipped: action.payload.skipped,
};
}
}
const initialState: State = {
availableProfiles: [],
availableServers: [],
transactions: [],
skipped: [],
};
const AppContext = createContext<StoreContext>({
state: initialState,
dispatch: () => {}
});
export function AppStoreProvider({ children }: AppStoreProviderProps) {
const [state, dispatch] = useReducer(reducer, initialState);
const context = useMemo(() => ({ state, dispatch }), [state, dispatch]);
return (
<AppContext.Provider value={context}>
{children}
</AppContext.Provider>
);
}
export function useStore(): UseStoreReturnType {
const { state, dispatch } = useContext(AppContext);
return {
state,
dispatch,
}
}

37
web/src/types/store.ts Normal file
View File

@@ -0,0 +1,37 @@
import type { Transaction } from "./api";
export type State = {
availableProfiles: string[];
availableServers: string[];
defaultProfile?: string;
defaultServer?: string;
profile?: string;
server?: string;
transactions: Transaction[];
skipped: string[];
};
export type Action =
| {
type: 'UPDATE_CONFIG',
payload: {
profiles: string[],
servers: string[],
defaultProfile?: string,
defaultServer?: string,
}
}
| {
type: 'UPDATE_DATA',
payload: {
profile: string;
server: string;
transactions: Transaction[];
skipped: string[];
}
}
export type StoreContext = {
state: State,
dispatch: React.Dispatch<Action>
};