Files
mamad-app/components/user-scope-modal.tsx
2026-01-16 17:48:46 +02:00

166 lines
5.0 KiB
TypeScript

"use client"
import { useEffect, useState } from "react"
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { Button } from "@/components/ui/button"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
interface ManagedTypeOption {
id?: number
name: string
managed: boolean
parentId?: number | null
}
interface UserScopeModalUser {
national_id: string
name: string
field?: string
department?: string
team?: string
}
interface UserScopeModalProps {
isOpen: boolean
onClose: () => void
user: UserScopeModalUser | null
fields: ManagedTypeOption[]
departments: ManagedTypeOption[]
teams: ManagedTypeOption[]
onSave: (payload: { userId: string; field: string; department: string; team: string }) => Promise<void>
isSaving: boolean
}
export function UserScopeModal({
isOpen,
onClose,
user,
fields,
departments,
teams,
onSave,
isSaving,
}: UserScopeModalProps) {
const [field, setField] = useState("")
const [department, setDepartment] = useState("")
const [team, setTeam] = useState("")
useEffect(() => {
if (user && isOpen) {
setField(user.field || "")
setDepartment(user.department || "")
setTeam(user.team || "")
}
}, [user, isOpen])
const selectedFieldId = fields.find((item) => item.name === field)?.id
const availableDepartments = selectedFieldId
? departments.filter((item) => item.parentId === selectedFieldId)
: departments
const selectedDepartmentId = departments.find((item) => item.name === department)?.id
const availableTeams = selectedDepartmentId
? teams.filter((item) => item.parentId === selectedDepartmentId)
: teams
useEffect(() => {
if (field && availableDepartments.length > 0) {
const hasDepartment = availableDepartments.some((item) => item.name === department)
if (!hasDepartment) {
setDepartment("")
setTeam("")
}
}
}, [field, availableDepartments, department])
useEffect(() => {
if (department && availableTeams.length > 0) {
const hasTeam = availableTeams.some((item) => item.name === team)
if (!hasTeam) {
setTeam("")
}
}
}, [department, availableTeams, team])
if (!user) return null
const handleSave = async () => {
if (!field || !department || !team) return
await onSave({ userId: user.national_id, field, department, team })
}
return (
<Dialog open={isOpen} onOpenChange={onClose}>
<DialogContent className="max-w-md" dir="rtl">
<DialogHeader className="text-center" dir="rtl">
<DialogTitle className="text-center" dir="rtl">
Update assignment for {user.name}
</DialogTitle>
<DialogDescription className="text-center" dir="rtl">
Choose the field, department, and team for this user.
</DialogDescription>
</DialogHeader>
<div className="space-y-4">
<div className="space-y-2">
<Select value={field} onValueChange={setField}>
<SelectTrigger dir="rtl">
<SelectValue placeholder="Select field" />
</SelectTrigger>
<SelectContent dir="rtl">
{fields.map((item) => (
<SelectItem key={item.name} value={item.name}>
{item.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Select value={department} onValueChange={setDepartment}>
<SelectTrigger dir="rtl">
<SelectValue placeholder="Select department" />
</SelectTrigger>
<SelectContent dir="rtl">
{availableDepartments.map((item) => (
<SelectItem key={item.name} value={item.name}>
{item.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Select value={team} onValueChange={setTeam}>
<SelectTrigger dir="rtl">
<SelectValue placeholder="Select team" />
</SelectTrigger>
<SelectContent dir="rtl">
{availableTeams.map((item) => (
<SelectItem key={item.name} value={item.name}>
{item.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="flex gap-2">
<Button variant="outline" onClick={onClose} className="w-full">
Cancel
</Button>
<Button
onClick={handleSave}
className="w-full"
disabled={isSaving || !field || !department || !team}
>
{isSaving ? "Saving..." : "Save"}
</Button>
</div>
</div>
</DialogContent>
</Dialog>
)
}