Updated to using managed types instead of
hard coded ones.
This commit is contained in:
165
components/user-scope-modal.tsx
Normal file
165
components/user-scope-modal.tsx
Normal file
@@ -0,0 +1,165 @@
|
||||
"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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user