106 lines
3.6 KiB
TypeScript
106 lines
3.6 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { toast } from 'react-toastify';
|
|
import { CustomDropdown, CustomConfirmationModal } from '../../components/custom';
|
|
import { useAuth } from '../../context/AuthContext';
|
|
import { languages } from '../../i18n/config';
|
|
import type { SupportedLanguage } from '../../i18n/config';
|
|
import { Globe } from 'lucide-react';
|
|
|
|
const SettingsPage: React.FC = () => {
|
|
const { t, i18n } = useTranslation('common');
|
|
const { user, updateLanguage } = useAuth();
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [selectedLanguage] = useState<SupportedLanguage>(
|
|
(i18n.language as SupportedLanguage) || 'en'
|
|
);
|
|
const [pendingLanguage, setPendingLanguage] = useState<SupportedLanguage | null>(null);
|
|
const [showConfirmation, setShowConfirmation] = useState(false);
|
|
|
|
const handleLanguageChange = (newLanguage: SupportedLanguage) => {
|
|
if (newLanguage === selectedLanguage) return;
|
|
|
|
setPendingLanguage(newLanguage);
|
|
setShowConfirmation(true);
|
|
};
|
|
|
|
const handleConfirmLanguageChange = async () => {
|
|
if (!pendingLanguage) return;
|
|
|
|
setIsLoading(true);
|
|
setShowConfirmation(false);
|
|
|
|
try {
|
|
localStorage.setItem('preferred_language', pendingLanguage);
|
|
|
|
if (user) {
|
|
await updateLanguage(pendingLanguage);
|
|
}
|
|
|
|
window.location.reload();
|
|
} catch (error) {
|
|
console.error('Failed to update language:', error);
|
|
toast.error(t('messages.error'));
|
|
setIsLoading(false);
|
|
setPendingLanguage(null);
|
|
}
|
|
};
|
|
|
|
const handleCancelLanguageChange = () => {
|
|
setPendingLanguage(null);
|
|
setShowConfirmation(false);
|
|
};
|
|
|
|
return (
|
|
<div className="max-w-4xl mx-auto">
|
|
{/* Page Header */}
|
|
<div className="flex flex-col gap-1 mb-6">
|
|
<h1 className="text-2xl font-bold text-(--text-primary)">
|
|
{t('settings.title')}
|
|
</h1>
|
|
<p className="text-sm text-[var(--text-secondary)]">Manage your account settings and application preferences.</p>
|
|
</div>
|
|
|
|
{/* Language Settings Section */}
|
|
<div className="bg-(--card-bg) rounded-lg border border-(--card-border) p-6">
|
|
<div className="flex items-center gap-3 mb-4">
|
|
<Globe className="w-5 h-5 text-(--primary)" />
|
|
<h2 className="text-lg font-semibold text-(--text-primary)">
|
|
{t('settings.language.title')}
|
|
</h2>
|
|
</div>
|
|
|
|
<p className="text-sm text-(--text-secondary) mb-6">
|
|
{t('settings.language.description')}
|
|
</p>
|
|
|
|
<div className="max-w-md">
|
|
<CustomDropdown
|
|
label={t('settings.language.selectLabel') || "Select Language"}
|
|
options={(Object.keys(languages) as SupportedLanguage[]).map(lang => ({
|
|
label: languages[lang].name,
|
|
value: lang
|
|
}))}
|
|
value={selectedLanguage}
|
|
onChange={(e) => handleLanguageChange(e.target.value as SupportedLanguage)}
|
|
disabled={isLoading}
|
|
leftIcon={<Globe size={18} />}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Confirmation Modal */}
|
|
<CustomConfirmationModal
|
|
isOpen={showConfirmation}
|
|
onClose={handleCancelLanguageChange}
|
|
onConfirm={handleConfirmLanguageChange}
|
|
title={t('settings.language.confirmTitle') || 'Change Language?'}
|
|
description={t('settings.language.confirmMessage') || 'The page will reload to apply the new language settings. Continue?'}
|
|
confirmText={t('actions.confirm')}
|
|
cancelText={t('actions.cancel')}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default SettingsPage; |