195 lines
6.2 KiB
TypeScript
195 lines
6.2 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
|
||
role?: 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("")
|
||
const noDepartmentValue = "__no_department__"
|
||
const noTeamValue = "__no_team__"
|
||
|
||
useEffect(() => {
|
||
if (user && isOpen) {
|
||
setField(user.field || "")
|
||
if (user.role === "field_admin") {
|
||
setDepartment(user.department || noDepartmentValue)
|
||
} else {
|
||
setDepartment(user.department || "")
|
||
}
|
||
setTeam(user.team || noTeamValue)
|
||
}
|
||
}, [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 && department !== noDepartmentValue
|
||
? teams.filter((item) => item.parentId === selectedDepartmentId)
|
||
: []
|
||
|
||
useEffect(() => {
|
||
if (field && availableDepartments.length > 0) {
|
||
const hasDepartment = availableDepartments.some((item) => item.name === department)
|
||
if (!hasDepartment) {
|
||
setDepartment(user?.role === "field_admin" ? noDepartmentValue : "")
|
||
setTeam(noTeamValue)
|
||
}
|
||
}
|
||
}, [field, availableDepartments, department])
|
||
|
||
useEffect(() => {
|
||
if (department === noDepartmentValue) {
|
||
setTeam(noTeamValue)
|
||
return
|
||
}
|
||
if (department && availableTeams.length > 0) {
|
||
const hasTeam = availableTeams.some((item) => item.name === team)
|
||
if (!hasTeam) {
|
||
setTeam(noTeamValue)
|
||
}
|
||
}
|
||
}, [department, availableTeams, team])
|
||
|
||
if (!user) return null
|
||
|
||
const handleSave = async () => {
|
||
if (!field) return
|
||
const normalizedDepartment = department === noDepartmentValue ? "" : department
|
||
const normalizedTeam = team === noTeamValue ? "" : team
|
||
const scopedDepartment = user.role === "field_admin" ? "" : normalizedDepartment
|
||
const scopedTeam = user.role === "field_admin" ? "" : normalizedTeam
|
||
|
||
if (user.role !== "field_admin" && !scopedDepartment) return
|
||
if ((user.role === "team_admin" || user.role === "user") && !scopedTeam) return
|
||
|
||
await onSave({ userId: user.national_id, field, department: scopedDepartment, team: scopedTeam })
|
||
}
|
||
|
||
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">
|
||
שיוך מחדש למשתמש {user.name}
|
||
</DialogTitle>
|
||
<DialogDescription className="text-center" dir="rtl">
|
||
יש לבחור תחום, מסגרת וצוות.
|
||
</DialogDescription>
|
||
</DialogHeader>
|
||
|
||
<div className="space-y-4">
|
||
<div className="space-y-2">
|
||
<Select value={field} onValueChange={setField}>
|
||
<SelectTrigger dir="rtl">
|
||
<SelectValue placeholder="??? ????" />
|
||
</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="??? ?????" />
|
||
</SelectTrigger>
|
||
<SelectContent dir="rtl">
|
||
{availableDepartments.map((item) => (
|
||
<SelectItem key={item.name} value={item.name}>
|
||
{item.name}
|
||
</SelectItem>
|
||
))}
|
||
{user.role === "field_admin" && (
|
||
<SelectItem value={noDepartmentValue}>??? ?????</SelectItem>
|
||
)}
|
||
</SelectContent>
|
||
</Select>
|
||
</div>
|
||
|
||
<div className="space-y-2">
|
||
<Select value={team} onValueChange={setTeam}>
|
||
<SelectTrigger dir="rtl">
|
||
<SelectValue placeholder="??? ????" />
|
||
</SelectTrigger>
|
||
<SelectContent dir="rtl">
|
||
{availableTeams.map((item) => (
|
||
<SelectItem key={item.name} value={item.name}>
|
||
{item.name}
|
||
</SelectItem>
|
||
))}
|
||
<SelectItem value={noTeamValue}>ללא צוות</SelectItem>
|
||
</SelectContent>
|
||
</Select>
|
||
</div>
|
||
|
||
<div className="flex gap-2">
|
||
<Button variant="outline" onClick={onClose} className="w-full">
|
||
ביטול
|
||
</Button>
|
||
<Button
|
||
onClick={handleSave}
|
||
className="w-full"
|
||
disabled={
|
||
isSaving ||
|
||
!field ||
|
||
(user.role !== "field_admin" && !department) ||
|
||
((user.role === "team_admin" || user.role === "user") && !team)
|
||
}
|
||
>
|
||
{isSaving ? "שומר..." : "שמירה"}
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
</DialogContent>
|
||
</Dialog>
|
||
)
|
||
}
|