mirror of
https://github.com/SamyRai/turash.git
synced 2025-12-26 23:01:33 +00:00
Some checks failed
CI/CD Pipeline / backend-lint (push) Failing after 31s
CI/CD Pipeline / backend-build (push) Has been skipped
CI/CD Pipeline / frontend-lint (push) Failing after 1m37s
CI/CD Pipeline / frontend-build (push) Has been skipped
CI/CD Pipeline / e2e-test (push) Has been skipped
- Replace all 'any' types with proper TypeScript interfaces - Fix React hooks setState in useEffect issues with lazy initialization - Remove unused variables and imports across all files - Fix React Compiler memoization dependency issues - Add comprehensive i18n translation keys for admin interfaces - Apply consistent prettier formatting throughout codebase - Clean up unused bulk editing functionality - Improve type safety and code quality across frontend Files changed: 39 - ImpactMetrics.tsx: Fixed any types and interfaces - AdminVerificationQueuePage.tsx: Added i18n keys, removed unused vars - LocalizationUIPage.tsx: Fixed memoization, added translations - LocalizationDataPage.tsx: Added type safety and translations - And 35+ other files with various lint fixes
152 lines
5.3 KiB
TypeScript
152 lines
5.3 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { useParams, useNavigate } from 'react-router-dom';
|
|
import { useTranslation } from '@/hooks/useI18n.tsx';
|
|
import { useUser, useUpdateUser, useCreateUser } from '@/hooks/api/useAdminAPI.ts';
|
|
import Button from '@/components/ui/Button.tsx';
|
|
import Input from '@/components/ui/Input.tsx';
|
|
import { Label } from '@/components/ui/Label.tsx';
|
|
import { FormField } from '@/components/ui/FormField.tsx';
|
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card.tsx';
|
|
import { Switch } from '@/components/ui/Switch.tsx';
|
|
import { Combobox } from '@/components/ui/Combobox.tsx';
|
|
import { ArrowLeft, Save } from 'lucide-react';
|
|
import type { CreateUserRequest, UpdateUserRequest } from '@/services/admin-api.ts';
|
|
|
|
const UserEditPage = () => {
|
|
const { t } = useTranslation();
|
|
const { id } = useParams<{ id: string }>();
|
|
const navigate = useNavigate();
|
|
const isNew = id === 'new';
|
|
|
|
const { data: user } = useUser(isNew ? null : id);
|
|
const { mutate: updateUser, isPending: isUpdating } = useUpdateUser();
|
|
const { mutate: createUser, isPending: isCreating } = useCreateUser();
|
|
|
|
const [formData, setFormData] = useState<CreateUserRequest | UpdateUserRequest>(() => ({
|
|
name: user?.name ?? '',
|
|
email: user?.email ?? '',
|
|
password: '',
|
|
role: user?.role ?? 'user',
|
|
}));
|
|
const [isActive, setIsActive] = useState(() => user?.isActive ?? true);
|
|
|
|
const handleSubmit = (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
|
|
if (isNew) {
|
|
createUser(formData as CreateUserRequest, {
|
|
onSuccess: (newUser) => {
|
|
navigate(`/admin/users/${newUser.id}/edit`);
|
|
},
|
|
});
|
|
} else if (id) {
|
|
updateUser(
|
|
{
|
|
id,
|
|
request: {
|
|
...formData,
|
|
isActive,
|
|
} as UpdateUserRequest,
|
|
},
|
|
{
|
|
onSuccess: () => {
|
|
// Show success message
|
|
},
|
|
}
|
|
);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<Button variant="ghost" onClick={() => navigate('/admin/users')}>
|
|
<ArrowLeft className="h-4 w-4 mr-2" />
|
|
{t('adminPage.users.backToList')}
|
|
</Button>
|
|
|
|
<form onSubmit={handleSubmit}>
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>
|
|
{isNew ? t('adminPage.users.newUser') : t('adminPage.users.editUser')}
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="space-y-6">
|
|
<FormField>
|
|
<Label>{t('adminPage.users.name')}</Label>
|
|
<Input
|
|
value={formData.name}
|
|
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
|
required
|
|
/>
|
|
</FormField>
|
|
|
|
<FormField>
|
|
<Label>{t('adminPage.users.email')}</Label>
|
|
<Input
|
|
type="email"
|
|
value={formData.email}
|
|
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
|
|
required
|
|
disabled={!isNew}
|
|
/>
|
|
</FormField>
|
|
|
|
{isNew && (
|
|
<FormField>
|
|
<Label>{t('adminPage.users.password')}</Label>
|
|
<Input
|
|
type="password"
|
|
value={(formData as CreateUserRequest).password || ''}
|
|
onChange={(e) =>
|
|
setFormData({ ...formData, password: e.target.value } as CreateUserRequest)
|
|
}
|
|
required={isNew}
|
|
minLength={8}
|
|
/>
|
|
<p className="text-sm text-muted-foreground">{t('adminPage.users.passwordHint')}</p>
|
|
</FormField>
|
|
)}
|
|
|
|
<FormField>
|
|
<Label>{t('adminPage.users.role')}</Label>
|
|
<Combobox
|
|
value={formData.role}
|
|
onChange={(value) => setFormData({ ...formData, role: value })}
|
|
options={[
|
|
{ value: 'user', label: t('adminPage.users.user') },
|
|
{ value: 'admin', label: t('adminPage.users.admin') },
|
|
{ value: 'content_manager', label: t('adminPage.users.contentManager') },
|
|
{ value: 'viewer', label: t('adminPage.users.viewer') },
|
|
]}
|
|
/>
|
|
</FormField>
|
|
|
|
{!isNew && (
|
|
<FormField>
|
|
<div className="flex items-center justify-between">
|
|
<Label>{t('adminPage.users.active')}</Label>
|
|
<Switch checked={isActive} onCheckedChange={setIsActive} />
|
|
</div>
|
|
<p className="text-sm text-muted-foreground">{t('adminPage.users.activeHint')}</p>
|
|
</FormField>
|
|
)}
|
|
|
|
<div className="flex justify-end gap-4">
|
|
<Button type="button" variant="outline" onClick={() => navigate('/admin/users')}>
|
|
{t('adminPage.users.cancel')}
|
|
</Button>
|
|
<Button type="submit" disabled={isUpdating || isCreating}>
|
|
<Save className="h-4 w-4 mr-2" />
|
|
{isUpdating || isCreating ? t('adminPage.users.saving') : t('adminPage.users.save')}
|
|
</Button>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</form>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default UserEditPage;
|