feat(admin-users): Add user edit dialog with form validation and update functionality
This commit is contained in:
parent
7b0b5099fe
commit
64ba7cfc31
|
|
@ -4,20 +4,76 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
|||
import { Button } from "@/components/ui/button"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
||||
import { ArrowLeft, Edit, Key } from "lucide-react"
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Label } from "@/components/ui/label"
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select"
|
||||
import { ArrowLeft, Edit, Key, Loader2 } from "lucide-react"
|
||||
import { userService } from "@/services"
|
||||
import { format } from "date-fns"
|
||||
import { useState } from "react"
|
||||
import { toast } from "sonner"
|
||||
|
||||
export default function UserDetailsPage() {
|
||||
const { id } = useParams()
|
||||
const navigate = useNavigate()
|
||||
const [isEditDialogOpen, setIsEditDialogOpen] = useState(false)
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
const [editForm, setEditForm] = useState({
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
email: '',
|
||||
role: '',
|
||||
isActive: true,
|
||||
})
|
||||
|
||||
const { data: user, isLoading } = useQuery({
|
||||
const { data: user, isLoading, refetch } = useQuery({
|
||||
queryKey: ['admin', 'users', id],
|
||||
queryFn: () => userService.getUser(id!),
|
||||
enabled: !!id,
|
||||
})
|
||||
|
||||
const handleEditClick = () => {
|
||||
if (user) {
|
||||
setEditForm({
|
||||
firstName: user.firstName || '',
|
||||
lastName: user.lastName || '',
|
||||
email: user.email,
|
||||
role: user.role,
|
||||
isActive: user.isActive,
|
||||
})
|
||||
setIsEditDialogOpen(true)
|
||||
}
|
||||
}
|
||||
|
||||
const handleSaveEdit = async () => {
|
||||
try {
|
||||
setIsSubmitting(true)
|
||||
await userService.updateUser(id!, editForm)
|
||||
toast.success("User updated successfully")
|
||||
setIsEditDialogOpen(false)
|
||||
refetch()
|
||||
} catch (error) {
|
||||
toast.error("Failed to update user")
|
||||
console.error('Update error:', error)
|
||||
} finally {
|
||||
setIsSubmitting(false)
|
||||
}
|
||||
}
|
||||
|
||||
if (isLoading) {
|
||||
return <div className="text-center py-8">Loading user details...</div>
|
||||
}
|
||||
|
|
@ -50,7 +106,7 @@ export default function UserDetailsPage() {
|
|||
<div className="flex items-center justify-between">
|
||||
<CardTitle>User Information</CardTitle>
|
||||
<div className="flex gap-2">
|
||||
<Button variant="outline" size="sm">
|
||||
<Button variant="outline" size="sm" onClick={handleEditClick}>
|
||||
<Edit className="w-4 h-4 mr-2" />
|
||||
Edit
|
||||
</Button>
|
||||
|
|
@ -133,6 +189,82 @@ export default function UserDetailsPage() {
|
|||
</div>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
|
||||
<Dialog open={isEditDialogOpen} onOpenChange={setIsEditDialogOpen}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Edit User</DialogTitle>
|
||||
<DialogDescription>
|
||||
Update user information and settings
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4 py-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="firstName">First Name</Label>
|
||||
<Input
|
||||
id="firstName"
|
||||
value={editForm.firstName}
|
||||
onChange={(e) => setEditForm({ ...editForm, firstName: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="lastName">Last Name</Label>
|
||||
<Input
|
||||
id="lastName"
|
||||
value={editForm.lastName}
|
||||
onChange={(e) => setEditForm({ ...editForm, lastName: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="email">Email</Label>
|
||||
<Input
|
||||
id="email"
|
||||
type="email"
|
||||
value={editForm.email}
|
||||
onChange={(e) => setEditForm({ ...editForm, email: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="role">Role</Label>
|
||||
<Select value={editForm.role} onValueChange={(value) => setEditForm({ ...editForm, role: value })}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select role" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="ADMIN">Admin</SelectItem>
|
||||
<SelectItem value="EMPLOYEE">Employee</SelectItem>
|
||||
<SelectItem value="CLIENT">Client</SelectItem>
|
||||
<SelectItem value="MEMBER">Member</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="status">Status</Label>
|
||||
<Select
|
||||
value={editForm.isActive ? 'active' : 'inactive'}
|
||||
onValueChange={(value) => setEditForm({ ...editForm, isActive: value === 'active' })}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select status" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="active">Active</SelectItem>
|
||||
<SelectItem value="inactive">Inactive</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button variant="outline" onClick={() => setIsEditDialogOpen(false)} disabled={isSubmitting}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button onClick={handleSaveEdit} disabled={isSubmitting}>
|
||||
{isSubmitting && <Loader2 className="w-4 h-4 mr-2 animate-spin" />}
|
||||
Save Changes
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user