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:
fahed
2026-02-04 13:45:50 +03:00
parent e98bebd60b
commit 868f46fc6e
18 changed files with 484 additions and 121 deletions

View File

@@ -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');