All files / src/store/slices/student StudentThemes.js

100% Statements 42/42
90% Branches 18/20
100% Functions 13/13
100% Lines 42/42

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101      5x   5x 3x 3x 1x   2x       5x 2x 2x 1x   1x       5x 2x 2x 1x   1x       5x                         2x     5x 5x     4x 4x 4x 4x       4x 4x       5x 5x     3x   3x 1x   3x     4x 4x       5x 5x     3x   3x 1x   3x     3x 3x            
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import { StudentThemesAPI } from "@/api/student/StudentThemesAPI";
 
const studentThemesAPI = new StudentThemesAPI();
 
export const _fetchStudentTheme = createAsyncThunk("fetch/studentTheme", async (_, { rejectWithValue }) => {
    try {
        const response = await studentThemesAPI.getCurrentTheme();
        return response;
    } catch (error) {
        return rejectWithValue(error.response?.data || error.message);
    }
});
 
export const _applyStudentTheme = createAsyncThunk("apply/studentTheme", async (themeData, { rejectWithValue }) => {
    try {
        const response = await studentThemesAPI.applyTheme(themeData);
        return { ...response, themeData };
    } catch (error) {
        return rejectWithValue(error.response?.data || error.message);
    }
});
 
export const _updateStudentTheme = createAsyncThunk("update/studentTheme", async (themeUpdate, { rejectWithValue }) => {
    try {
        const response = await studentThemesAPI.updateTheme(themeUpdate);
        return { ...response, themeUpdate };
    } catch (error) {
        return rejectWithValue(error.response?.data || error.message);
    }
});
 
const StudentThemes = createSlice({
    name: "StudentThemes",
    initialState: {
        selectedTheme: null,
        colorMode: null,
        isLoading: false,
        isApplyingTheme: false,
        isUpdatingTheme: false,
        hasErrors: null,
        applyThemeError: null,
        updateThemeError: null,
    },
    extraReducers: (builder) => {
        builder
            // Fetch Theme
            .addCase(_fetchStudentTheme.pending, (state) => {
                state.isLoading = true;
                state.hasErrors = null;
            })
            .addCase(_fetchStudentTheme.fulfilled, (state, action) => {
                state.isLoading = false;
                state.selectedTheme = action.payload.data.theme_details || null;
                state.colorMode = action.payload.data.theme_details?.color_mode || "light";
                state.hasErrors = null;
                // Theme data fetched successfully - will be applied by ThemeContext
            })
            .addCase(_fetchStudentTheme.rejected, (state, action) => {
                state.isLoading = false;
                state.hasErrors = action.payload?.detail || action.error.message;
            })
            // Apply Theme
            .addCase(_applyStudentTheme.pending, (state) => {
                state.isApplyingTheme = true;
                state.applyThemeError = null;
            })
            .addCase(_applyStudentTheme.fulfilled, (state, action) => {
                state.isApplyingTheme = false;
                // Update selected theme if API returns theme details
                if (action.payload.data?.theme_details) {
                    state.selectedTheme = action.payload.data.theme_details;
                }
                state.applyThemeError = null;
            })
            .addCase(_applyStudentTheme.rejected, (state, action) => {
                state.isApplyingTheme = false;
                state.applyThemeError = action.payload?.detail || action.error.message;
            })
            // Update Theme
            .addCase(_updateStudentTheme.pending, (state) => {
                state.isUpdatingTheme = true;
                state.updateThemeError = null;
            })
            .addCase(_updateStudentTheme.fulfilled, (state, action) => {
                state.isUpdatingTheme = false;
                // Update selected theme if API returns theme details
                if (action.payload.data?.theme_details) {
                    state.selectedTheme = action.payload.data.theme_details;
                }
                state.updateThemeError = null;
            })
            .addCase(_updateStudentTheme.rejected, (state, action) => {
                state.isUpdatingTheme = false;
                state.updateThemeError = action.payload?.detail || action.error.message;
            });
    },
});
 
export default StudentThemes;