mirror of
https://github.com/johndoe6345789/workforce-pay-bill-p.git
synced 2026-04-24 13:24:57 +00:00
Generated by Spark: When I set Language to french, it doesnt work. I think Redux can help with this.
This commit is contained in:
@@ -3,6 +3,7 @@ import { useNotifications } from '@/hooks/use-notifications'
|
||||
import { useAppData } from '@/hooks/use-app-data'
|
||||
import { useAppActions } from '@/hooks/use-app-actions'
|
||||
import { useViewPreload } from '@/hooks/use-view-preload'
|
||||
import { useLocaleInit } from '@/hooks/use-locale-init'
|
||||
import { Sidebar } from '@/components/navigation'
|
||||
import { NotificationCenter } from '@/components/NotificationCenter'
|
||||
import { ViewRouter } from '@/components/ViewRouter'
|
||||
@@ -26,6 +27,7 @@ function App() {
|
||||
|
||||
useSampleData()
|
||||
useViewPreload()
|
||||
useLocaleInit()
|
||||
|
||||
const { notifications, addNotification, markAsRead, markAllAsRead, deleteNotification, unreadCount } = useNotifications()
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ export { useSortableData } from './use-sortable-data'
|
||||
export { useFilterableData } from './use-filterable-data'
|
||||
export { useFormatter } from './use-formatter'
|
||||
export { useTemplateManager } from './use-template-manager'
|
||||
export { useLocaleInit } from './use-locale-init'
|
||||
|
||||
export { useFetch } from './use-fetch'
|
||||
export { useLocalStorageState } from './use-local-storage-state'
|
||||
@@ -145,4 +146,3 @@ export type { UseAsyncActionResult } from './use-async-action'
|
||||
export type { UseMutationOptions, UseMutationResult } from './use-mutation'
|
||||
export type { UseFavoritesOptions, UseFavoritesResult } from './use-favorites'
|
||||
export type { UseClipboardResult } from './use-clipboard-copy'
|
||||
|
||||
|
||||
18
src/hooks/use-locale-init.ts
Normal file
18
src/hooks/use-locale-init.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { useEffect } from 'react'
|
||||
import { useKV } from '@github/spark/hooks'
|
||||
import { useAppDispatch, useAppSelector } from '@/store/hooks'
|
||||
import { setLocale } from '@/store/slices/uiSlice'
|
||||
|
||||
type Locale = 'en' | 'es' | 'fr'
|
||||
|
||||
export function useLocaleInit() {
|
||||
const dispatch = useAppDispatch()
|
||||
const reduxLocale = useAppSelector(state => state.ui.locale)
|
||||
const [kvLocale] = useKV<Locale>('app-locale', 'en')
|
||||
|
||||
useEffect(() => {
|
||||
if (kvLocale && kvLocale !== reduxLocale) {
|
||||
dispatch(setLocale(kvLocale))
|
||||
}
|
||||
}, [kvLocale, reduxLocale, dispatch])
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
import { useKV } from '@github/spark/hooks'
|
||||
import { useState, useEffect, useCallback } from 'react'
|
||||
import { useAppSelector, useAppDispatch } from '@/store/hooks'
|
||||
import { setLocale as setReduxLocale } from '@/store/slices/uiSlice'
|
||||
|
||||
type Translations = Record<string, any>
|
||||
type Locale = 'en' | 'es' | 'fr'
|
||||
@@ -8,11 +10,21 @@ const AVAILABLE_LOCALES: Locale[] = ['en', 'es', 'fr']
|
||||
const DEFAULT_LOCALE: Locale = 'en'
|
||||
|
||||
export function useTranslation() {
|
||||
const [locale, setLocale] = useKV<Locale>('app-locale', DEFAULT_LOCALE)
|
||||
const dispatch = useAppDispatch()
|
||||
const reduxLocale = useAppSelector(state => state.ui.locale)
|
||||
const [kvLocale, setKVLocale] = useKV<Locale>('app-locale', DEFAULT_LOCALE)
|
||||
const [translations, setTranslations] = useState<Translations>({})
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
const [error, setError] = useState<Error | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (kvLocale && kvLocale !== reduxLocale) {
|
||||
dispatch(setReduxLocale(kvLocale))
|
||||
}
|
||||
}, [kvLocale, reduxLocale, dispatch])
|
||||
|
||||
const locale = reduxLocale
|
||||
|
||||
useEffect(() => {
|
||||
const loadTranslations = async () => {
|
||||
try {
|
||||
@@ -68,9 +80,10 @@ export function useTranslation() {
|
||||
|
||||
const changeLocale = useCallback((newLocale: Locale) => {
|
||||
if (AVAILABLE_LOCALES.includes(newLocale)) {
|
||||
setLocale(newLocale)
|
||||
dispatch(setReduxLocale(newLocale))
|
||||
setKVLocale(newLocale)
|
||||
}
|
||||
}, [setLocale])
|
||||
}, [dispatch, setKVLocale])
|
||||
|
||||
return {
|
||||
t,
|
||||
@@ -83,16 +96,18 @@ export function useTranslation() {
|
||||
}
|
||||
|
||||
export function useLocale() {
|
||||
const [locale] = useKV<Locale>('app-locale', DEFAULT_LOCALE)
|
||||
const locale = useAppSelector(state => state.ui.locale)
|
||||
return locale
|
||||
}
|
||||
|
||||
export function useChangeLocale() {
|
||||
const [, setLocale] = useKV<Locale>('app-locale', DEFAULT_LOCALE)
|
||||
const dispatch = useAppDispatch()
|
||||
const [, setKVLocale] = useKV<Locale>('app-locale', DEFAULT_LOCALE)
|
||||
|
||||
return useCallback((newLocale: Locale) => {
|
||||
if (AVAILABLE_LOCALES.includes(newLocale)) {
|
||||
setLocale(newLocale)
|
||||
dispatch(setReduxLocale(newLocale))
|
||||
setKVLocale(newLocale)
|
||||
}
|
||||
}, [setLocale])
|
||||
}, [dispatch, setKVLocale])
|
||||
}
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
||||
|
||||
type View = 'dashboard' | 'timesheets' | 'billing' | 'payroll' | 'compliance' | 'expenses' | 'roadmap' | 'reports' | 'currency' | 'email-templates' | 'invoice-templates' | 'qr-scanner' | 'missing-timesheets' | 'purchase-orders' | 'onboarding' | 'audit-trail' | 'notification-rules' | 'batch-import' | 'rate-templates' | 'custom-reports' | 'holiday-pay' | 'contract-validation' | 'shift-patterns' | 'query-guide' | 'component-showcase' | 'business-logic-demo' | 'data-admin' | 'translation-demo' | 'profile'
|
||||
type View = 'dashboard' | 'timesheets' | 'billing' | 'payroll' | 'compliance' | 'expenses' | 'roadmap' | 'reports' | 'currency' | 'email-templates' | 'invoice-templates' | 'qr-scanner' | 'missing-timesheets' | 'purchase-orders' | 'onboarding' | 'audit-trail' | 'notification-rules' | 'batch-import' | 'rate-templates' | 'custom-reports' | 'holiday-pay' | 'contract-validation' | 'shift-patterns' | 'query-guide' | 'component-showcase' | 'business-logic-demo' | 'data-admin' | 'translation-demo' | 'profile' | 'roles-permissions'
|
||||
|
||||
type Locale = 'en' | 'es' | 'fr'
|
||||
|
||||
interface UIState {
|
||||
currentView: View
|
||||
searchQuery: string
|
||||
sidebarCollapsed: boolean
|
||||
locale: Locale
|
||||
}
|
||||
|
||||
const initialState: UIState = {
|
||||
currentView: 'dashboard',
|
||||
searchQuery: '',
|
||||
sidebarCollapsed: false,
|
||||
locale: 'en',
|
||||
}
|
||||
|
||||
const uiSlice = createSlice({
|
||||
@@ -27,8 +31,11 @@ const uiSlice = createSlice({
|
||||
toggleSidebar: (state) => {
|
||||
state.sidebarCollapsed = !state.sidebarCollapsed
|
||||
},
|
||||
setLocale: (state, action: PayloadAction<Locale>) => {
|
||||
state.locale = action.payload
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const { setCurrentView, setSearchQuery, toggleSidebar } = uiSlice.actions
|
||||
export const { setCurrentView, setSearchQuery, toggleSidebar, setLocale } = uiSlice.actions
|
||||
export default uiSlice.reducer
|
||||
|
||||
Reference in New Issue
Block a user