Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
forbidals
/
student_panel
/
src
/
components
/
store
/
slices
:
languageSlice.ts
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import languagesData from '@/lib/student/languages.json'; // Language interface export interface Language { name: string; code: string; flag: string; isRtl: boolean; } // Language state interface interface LanguageState { // Current selected language code currentLanguage: string; // Current language name for display currentLanguageName: string; // Available languages list languages: Language[]; // Translations object - key-value pairs for translated strings translations: Record<string, string>; // Loading state for translations loading: boolean; // Error state if translation loading fails error: string | null; } // LocalStorage key for language persistence const LANGUAGE_STORAGE_KEY = 'student-language'; // Available languages configuration from JSON const availableLanguages: Language[] = languagesData; // Default language const defaultLanguage: string = availableLanguages[0]?.code || 'en'; // Helper function to load language from localStorage // This should only be called on the client side export const loadLanguageFromLocalStorage = (): string => { if (typeof window !== 'undefined') { try { const saved = localStorage.getItem(LANGUAGE_STORAGE_KEY); const isAvailable = availableLanguages.some((lang) => lang.code === saved); if (saved && isAvailable) { return saved; } } catch { // If there's an error reading from localStorage, use default localStorage.removeItem(LANGUAGE_STORAGE_KEY); } } return defaultLanguage; }; // Helper function to save language to localStorage const saveLanguageToLocalStorage = (lang: string) => { if (typeof window !== 'undefined') { try { localStorage.setItem(LANGUAGE_STORAGE_KEY, lang); } catch (error) { // Silently fail if localStorage is not available console.error('Failed to save language to localStorage:', error); } } }; // Get language name from code const getLanguageName = (code: string): string => { return ( availableLanguages.find((lang) => lang.code === code)?.name || 'English' ); }; // Initial state // Start with default language to prevent hydration mismatch // Language will be rehydrated from localStorage after client mount const initialState: LanguageState = { currentLanguage: defaultLanguage, currentLanguageName: getLanguageName(defaultLanguage), languages: availableLanguages, translations: {}, loading: false, error: null, }; // Create the language slice const languageSlice = createSlice({ name: 'language', initialState, reducers: { // Rehydrate language from localStorage after client mount // This action should be dispatched once after the app mounts on the client // It prevents hydration mismatch by loading persisted state after initial render rehydrateLanguage: (state) => { const savedLanguage = loadLanguageFromLocalStorage(); state.currentLanguage = savedLanguage; state.currentLanguageName = getLanguageName(savedLanguage); }, // Set current language setLanguage: (state, action: PayloadAction<string>) => { state.currentLanguage = action.payload; state.currentLanguageName = getLanguageName(action.payload); state.error = null; // Save language to localStorage for persistence saveLanguageToLocalStorage(action.payload); }, // Set translations object setTranslations: (state, action: PayloadAction<Record<string, string>>) => { state.translations = action.payload; state.loading = false; state.error = null; }, // Set loading state setLoading: (state, action: PayloadAction<boolean>) => { state.loading = action.payload; }, // Set error message setError: (state, action: PayloadAction<string | null>) => { state.error = action.payload; state.loading = false; }, // Clear error clearError: (state) => { state.error = null; }, }, }); // Export types export type LanguageCode = string; export type LanguageName = string; // Export actions export const { rehydrateLanguage, setLanguage, setTranslations, setLoading, setError, clearError, } = languageSlice.actions; // Export reducer export default languageSlice.reducer;