feat: language selector on user creation, pass to welcome email
Some checks failed
Deploy / deploy (push) Failing after 9s
Some checks failed
Deploy / deploy (push) Failing after 9s
Adds preferred_language field to Users, language picker (EN/AR) in create/edit user form, persists to NocoDB, and passes it to the welcome notification so new users receive emails in their language. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -570,6 +570,7 @@
|
||||
"users.passwordMismatch": "كلمات المرور غير متطابقة",
|
||||
"users.passwordRequired": "كلمة المرور مطلوبة للمستخدمين الجدد",
|
||||
"users.saveFailed": "فشل في حفظ المستخدم",
|
||||
"users.preferredLanguage": "اللغة المفضلة",
|
||||
"users.deleteFailed": "فشل في حذف المستخدم",
|
||||
|
||||
"settings.saveFailed": "فشل في الحفظ",
|
||||
|
||||
@@ -570,6 +570,7 @@
|
||||
"users.passwordMismatch": "Passwords do not match",
|
||||
"users.passwordRequired": "Password is required for new users",
|
||||
"users.saveFailed": "Failed to save user",
|
||||
"users.preferredLanguage": "Preferred Language",
|
||||
"users.deleteFailed": "Failed to delete user",
|
||||
|
||||
"settings.saveFailed": "Failed to save",
|
||||
|
||||
@@ -14,7 +14,7 @@ const ROLES = [
|
||||
]
|
||||
|
||||
const EMPTY_FORM = {
|
||||
name: '', email: '', password: '', role: 'contributor', avatar: '',
|
||||
name: '', email: '', password: '', role: 'contributor', avatar: '', preferred_language: 'en',
|
||||
}
|
||||
|
||||
function RoleBadge({ role }) {
|
||||
@@ -66,6 +66,7 @@ export default function Users() {
|
||||
email: form.email,
|
||||
role: form.role,
|
||||
avatar: form.avatar || null,
|
||||
preferred_language: form.preferred_language || 'en',
|
||||
}
|
||||
if (form.password) data.password = form.password
|
||||
|
||||
@@ -97,6 +98,7 @@ export default function Users() {
|
||||
password: '',
|
||||
role: user.role || 'contributor',
|
||||
avatar: user.avatar || '',
|
||||
preferred_language: user.preferred_language || 'en',
|
||||
})
|
||||
setConfirmPassword('')
|
||||
setPasswordError('')
|
||||
@@ -312,6 +314,27 @@ export default function Users() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-text-primary mb-1">{t('users.preferredLanguage')}</label>
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
{[{ value: 'en', label: 'English', flag: '🇬🇧' }, { value: 'ar', label: 'العربية', flag: '🇸🇦' }].map(l => (
|
||||
<button
|
||||
key={l.value}
|
||||
type="button"
|
||||
onClick={() => setForm(f => ({ ...f, preferred_language: l.value }))}
|
||||
className={`p-2.5 rounded-lg border-2 text-center transition-all ${
|
||||
form.preferred_language === l.value
|
||||
? 'border-brand-primary bg-brand-primary/5'
|
||||
: 'border-border hover:border-brand-primary/30'
|
||||
}`}
|
||||
>
|
||||
<span className="text-lg">{l.flag}</span>
|
||||
<span className="text-xs font-medium text-text-primary ms-1.5">{l.label}</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-end gap-3 pt-4 border-t border-border">
|
||||
<button
|
||||
onClick={() => { setShowModal(false); setEditingUser(null) }}
|
||||
|
||||
Reference in New Issue
Block a user