@pitifulhawk/flash-up
Version:
Interactive project scaffolder for modern web applications
90 lines (80 loc) • 2.57 kB
text/typescript
import { configureStore, createSlice, PayloadAction } from '@reduxjs/toolkit';
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
// Define user interface
interface User {
id: string;
name: string;
email: string;
avatar?: string;
}
// Define the app state interface
interface AppState {
user: User | null;
isAuthenticated: boolean;
theme: 'light' | 'dark';
isLoading: boolean;
}
// Initial state
const initialState: AppState = {
user: null,
isAuthenticated: false,
theme: 'light',
isLoading: false,
};
// Create the app slice
const appSlice = createSlice({
name: 'app',
initialState,
reducers: {
setUser: (state, action: PayloadAction<User | null>) => {
state.user = action.payload;
state.isAuthenticated = !!action.payload;
},
setAuthenticated: (state, action: PayloadAction<boolean>) => {
state.isAuthenticated = action.payload;
},
setTheme: (state, action: PayloadAction<'light' | 'dark'>) => {
state.theme = action.payload;
// Apply theme to document
if (typeof document !== 'undefined') {
document.documentElement.setAttribute('data-theme', action.payload);
}
},
setLoading: (state, action: PayloadAction<boolean>) => {
state.isLoading = action.payload;
},
logout: (state) => {
state.user = null;
state.isAuthenticated = false;
// Clear any stored tokens
if (typeof localStorage !== 'undefined') {
localStorage.removeItem('token');
}
},
},
});
// Export actions
export const { setUser, setAuthenticated, setTheme, setLoading, logout } = appSlice.actions;
// Configure store
export const store = configureStore({
reducer: {
app: appSlice.reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: ['persist/PERSIST'],
},
}),
});
// Export types
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
// Typed hooks
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
// Selector hooks for better performance
export const useUser = () => useAppSelector((state) => state.app.user);
export const useIsAuthenticated = () => useAppSelector((state) => state.app.isAuthenticated);
export const useTheme = () => useAppSelector((state) => state.app.theme);
export const useIsLoading = () => useAppSelector((state) => state.app.isLoading);