| import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit'; | |
| import { authAPI } from '../services/api'; | |
| interface User { | |
| id: string; | |
| email: string; | |
| subscription: string; | |
| role: string; | |
| videosGenerated?: number; | |
| } | |
| interface AuthState { | |
| user: User | null; | |
| token: string | null; | |
| loading: boolean; | |
| error: string | null; | |
| } | |
| const savedToken = localStorage.getItem('director_token'); | |
| const savedUser = localStorage.getItem('director_user'); | |
| const initialState: AuthState = { | |
| user: savedUser ? JSON.parse(savedUser) : null, | |
| token: savedToken || null, | |
| loading: false, | |
| error: null, | |
| }; | |
| export const registerUser = createAsyncThunk( | |
| 'auth/register', | |
| async ({ email, password }: { email: string; password: string }, { rejectWithValue }) => { | |
| try { | |
| const response = await authAPI.register(email, password); | |
| return response.data; | |
| } catch (error: any) { | |
| return rejectWithValue(error.response?.data?.error || 'Registration failed.'); | |
| } | |
| } | |
| ); | |
| export const loginUser = createAsyncThunk( | |
| 'auth/login', | |
| async ({ email, password }: { email: string; password: string }, { rejectWithValue }) => { | |
| try { | |
| const response = await authAPI.login(email, password); | |
| return response.data; | |
| } catch (error: any) { | |
| return rejectWithValue(error.response?.data?.error || 'Login failed.'); | |
| } | |
| } | |
| ); | |
| const authSlice = createSlice({ | |
| name: 'auth', | |
| initialState, | |
| reducers: { | |
| logout(state) { | |
| state.user = null; | |
| state.token = null; | |
| state.error = null; | |
| localStorage.removeItem('director_token'); | |
| localStorage.removeItem('director_user'); | |
| }, | |
| clearError(state) { | |
| state.error = null; | |
| }, | |
| }, | |
| extraReducers: (builder) => { | |
| builder | |
| .addCase(registerUser.pending, (state) => { | |
| state.loading = true; | |
| state.error = null; | |
| }) | |
| .addCase(registerUser.fulfilled, (state, action: PayloadAction<any>) => { | |
| state.loading = false; | |
| state.user = action.payload.user; | |
| state.token = action.payload.token; | |
| localStorage.setItem('director_token', action.payload.token); | |
| localStorage.setItem('director_user', JSON.stringify(action.payload.user)); | |
| }) | |
| .addCase(registerUser.rejected, (state, action) => { | |
| state.loading = false; | |
| state.error = action.payload as string; | |
| }) | |
| .addCase(loginUser.pending, (state) => { | |
| state.loading = true; | |
| state.error = null; | |
| }) | |
| .addCase(loginUser.fulfilled, (state, action: PayloadAction<any>) => { | |
| state.loading = false; | |
| state.user = action.payload.user; | |
| state.token = action.payload.token; | |
| localStorage.setItem('director_token', action.payload.token); | |
| localStorage.setItem('director_user', JSON.stringify(action.payload.user)); | |
| }) | |
| .addCase(loginUser.rejected, (state, action) => { | |
| state.loading = false; | |
| state.error = action.payload as string; | |
| }); | |
| }, | |
| }); | |
| export const { logout, clearError } = authSlice.actions; | |
| export default authSlice.reducer; | |