chore: migrate to TypeScript
- Convert all .js files to .tsx/.ts - Add types for data structures (MuseumRecord, Metrics, etc.) - Add type declarations for react-chartjs-2 - Configure tsconfig with relaxed strictness for gradual adoption - All components now use TypeScript
This commit is contained in:
@@ -1,15 +1,34 @@
|
||||
import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
|
||||
import React, { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react';
|
||||
import en from '../locales/en.json';
|
||||
import ar from '../locales/ar.json';
|
||||
|
||||
const translations = { en, ar };
|
||||
type LanguageCode = 'en' | 'ar';
|
||||
type Direction = 'ltr' | 'rtl';
|
||||
|
||||
const LanguageContext = createContext();
|
||||
interface Translations {
|
||||
[key: string]: string | Translations;
|
||||
}
|
||||
|
||||
export function LanguageProvider({ children }) {
|
||||
const [lang, setLang] = useState(() => {
|
||||
const translations: Record<LanguageCode, Translations> = { en, ar };
|
||||
|
||||
interface LanguageContextType {
|
||||
lang: LanguageCode;
|
||||
dir: Direction;
|
||||
t: (key: string, fallback?: string) => string;
|
||||
switchLanguage: () => void;
|
||||
setLanguage: (lang: LanguageCode) => void;
|
||||
}
|
||||
|
||||
const LanguageContext = createContext<LanguageContextType | null>(null);
|
||||
|
||||
interface LanguageProviderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export function LanguageProvider({ children }: LanguageProviderProps) {
|
||||
const [lang, setLang] = useState<LanguageCode>(() => {
|
||||
// Check localStorage first, then browser preference
|
||||
const saved = localStorage.getItem('hihala-lang');
|
||||
const saved = localStorage.getItem('hihala-lang') as LanguageCode | null;
|
||||
if (saved && translations[saved]) return saved;
|
||||
|
||||
// Check browser language
|
||||
@@ -18,7 +37,7 @@ export function LanguageProvider({ children }) {
|
||||
return 'en';
|
||||
});
|
||||
|
||||
const dir = lang === 'ar' ? 'rtl' : 'ltr';
|
||||
const dir: Direction = lang === 'ar' ? 'rtl' : 'ltr';
|
||||
|
||||
// Apply direction to document
|
||||
useEffect(() => {
|
||||
@@ -28,9 +47,9 @@ export function LanguageProvider({ children }) {
|
||||
}, [lang, dir]);
|
||||
|
||||
// Translation function with dot notation support
|
||||
const t = useCallback((key, fallback) => {
|
||||
const t = useCallback((key: string, fallback?: string): string => {
|
||||
const keys = key.split('.');
|
||||
let value = translations[lang];
|
||||
let value: Translations | string = translations[lang];
|
||||
|
||||
for (const k of keys) {
|
||||
if (value && typeof value === 'object' && k in value) {
|
||||
@@ -58,7 +77,7 @@ export function LanguageProvider({ children }) {
|
||||
}, []);
|
||||
|
||||
// Set specific language
|
||||
const setLanguage = useCallback((newLang) => {
|
||||
const setLanguage = useCallback((newLang: LanguageCode) => {
|
||||
if (translations[newLang]) {
|
||||
setLang(newLang);
|
||||
}
|
||||
@@ -71,7 +90,7 @@ export function LanguageProvider({ children }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function useLanguage() {
|
||||
export function useLanguage(): LanguageContextType {
|
||||
const context = useContext(LanguageContext);
|
||||
if (!context) {
|
||||
throw new Error('useLanguage must be used within a LanguageProvider');
|
||||
Reference in New Issue
Block a user