117 lines
2.9 KiB
JavaScript
117 lines
2.9 KiB
JavaScript
import React, { createContext, useContext, useReducer, useEffect } from 'react';
|
|
import { storage } from '../lib/storage';
|
|
|
|
const AppContext = createContext();
|
|
|
|
const initialState = {
|
|
currentUser: null, // will hold user object if logged in
|
|
users: [], // array of registered users
|
|
weekNumber: 1, // current learning week
|
|
isLoading: true
|
|
};
|
|
|
|
function appReducer(state, action) {
|
|
switch (action.type) {
|
|
case 'INIT_APP':
|
|
return {
|
|
...state,
|
|
users: action.payload.users,
|
|
weekNumber: action.payload.weekNumber,
|
|
isLoading: false
|
|
};
|
|
case 'LOGIN':
|
|
return {
|
|
...state,
|
|
currentUser: action.payload
|
|
};
|
|
case 'LOGOUT':
|
|
return {
|
|
...state,
|
|
currentUser: null
|
|
};
|
|
case 'REGISTER_USER':
|
|
return {
|
|
...state,
|
|
users: [...state.users, action.payload]
|
|
};
|
|
case 'ADVANCE_WEEK':
|
|
return {
|
|
...state,
|
|
weekNumber: state.weekNumber + 1
|
|
};
|
|
default:
|
|
return state;
|
|
}
|
|
}
|
|
|
|
export function AppProvider({ children }) {
|
|
const [state, dispatch] = useReducer(appReducer, initialState);
|
|
|
|
// Initialize app state from storage
|
|
useEffect(() => {
|
|
const loadState = () => {
|
|
let users = storage.get('users:registry');
|
|
|
|
// Seed first admin if no users exist
|
|
if (!users || users.length === 0) {
|
|
const initialAdmin = {
|
|
id: 'u_1',
|
|
name: 'Admin',
|
|
role: 'admin',
|
|
pin: '0000',
|
|
registeredAt: new Date().toISOString()
|
|
};
|
|
users = [initialAdmin];
|
|
storage.set('users:registry', users);
|
|
|
|
// Also seed initial empty leaderboard
|
|
storage.set('leaderboard:current', []);
|
|
}
|
|
|
|
const storedWeek = storage.get('admin:current_week') || 1;
|
|
|
|
// Automatically login if we saved session (optional, simpler to require login per session)
|
|
const sessionUserId = sessionStorage.getItem('respellion_session');
|
|
if (sessionUserId) {
|
|
const user = users.find(u => u.id === sessionUserId);
|
|
if (user) {
|
|
dispatch({ type: 'LOGIN', payload: user });
|
|
}
|
|
}
|
|
|
|
dispatch({
|
|
type: 'INIT_APP',
|
|
payload: { users, weekNumber: storedWeek }
|
|
});
|
|
};
|
|
|
|
loadState();
|
|
}, []);
|
|
|
|
// Expose dispatch actions as convenient methods
|
|
const login = (userId, pin) => {
|
|
const user = state.users.find(u => u.id === userId && u.pin === pin);
|
|
if (user) {
|
|
sessionStorage.setItem('respellion_session', user.id);
|
|
dispatch({ type: 'LOGIN', payload: user });
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
const logout = () => {
|
|
sessionStorage.removeItem('respellion_session');
|
|
dispatch({ type: 'LOGOUT' });
|
|
};
|
|
|
|
return (
|
|
<AppContext.Provider value={{ state, dispatch, login, logout }}>
|
|
{children}
|
|
</AppContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useApp() {
|
|
return useContext(AppContext);
|
|
}
|