Files
mamad-app/components/user-scope-modal.tsx
2026-01-16 23:44:13 +02:00

195 lines
6.2 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"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>
)
}