muller-reporting-sys/app/shift-manager/create-shift/page.tsx
2025-11-12 22:21:35 +03:00

184 lines
6.9 KiB
TypeScript

"use client"
import { useState, useEffect } from "react"
import { useRouter } from "next/navigation"
export default function CreateShiftPage() {
const router = useRouter()
const [loading, setLoading] = useState(false)
const [managerTeam, setManagerTeam] = useState<any>(null)
const [workers, setWorkers] = useState<any[]>([])
const [machines, setMachines] = useState<any[]>([])
const [formData, setFormData] = useState({
name: "AM",
shiftDate: new Date().toISOString().split('T')[0],
teamId: "",
operators: Array(7).fill(""),
level2Id: "",
engineerId: ""
})
useEffect(() => {
// Fetch manager's team
fetch(`/api/shift-manager/my-team`)
.then(r => r.json())
.then(team => {
if (team && !team.error) {
setManagerTeam(team)
setFormData(prev => ({ ...prev, teamId: team.id }))
// Fetch workers for this team only
fetch(`/api/workers?teamId=${team.id}`)
.then(r => r.json())
.then(setWorkers)
}
})
.catch(err => console.error("Error fetching team:", err))
fetch('/api/machines').then(r => r.json()).then(data => {
// Sort machines by name (T1, T2, T3, etc.)
const sortedMachines = data.sort((a: any, b: any) => {
const numA = parseInt(a.name.replace('T', ''))
const numB = parseInt(b.name.replace('T', ''))
return numA - numB
})
setMachines(sortedMachines)
})
}, [])
// Get available operators for a specific machine index
const getAvailableOperators = (currentIndex: number) => {
const selectedOperatorIds = formData.operators.filter((id, idx) => id && idx !== currentIndex)
return workers.filter((w: any) =>
w.jobPosition === "Blow Moulder Level 1" &&
!selectedOperatorIds.includes(w.id)
)
}
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
setLoading(true)
const response = await fetch('/api/shifts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData)
})
if (response.ok) {
router.push('/shift-manager/shifts')
}
setLoading(false)
}
return (
<div className="min-h-screen bg-gray-50 p-8">
<div className="max-w-4xl mx-auto">
<h1 className="text-3xl font-bold text-gray-800 mb-6">Create New Shift</h1>
<form onSubmit={handleSubmit} className="bg-white p-6 rounded-xl shadow-sm border border-gray-200 space-y-6">
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium mb-2">Shift Type</label>
<select
value={formData.name}
onChange={(e) => setFormData({...formData, name: e.target.value})}
className="w-full px-4 py-2 border rounded-lg"
required
>
<option value="AM">AM (7:00 AM - 7:00 PM)</option>
<option value="PM">PM (7:00 PM - 7:00 AM)</option>
</select>
</div>
<div>
<label className="block text-sm font-medium mb-2">Date</label>
<input
type="date"
value={formData.shiftDate}
onChange={(e) => setFormData({...formData, shiftDate: e.target.value})}
className="w-full px-4 py-2 border rounded-lg"
required
/>
</div>
</div>
<div>
<label className="block text-sm font-medium mb-2">Team</label>
<input
type="text"
value={managerTeam?.name || "Loading..."}
className="w-full px-4 py-2 border rounded-lg bg-gray-100 cursor-not-allowed"
disabled
readOnly
/>
<p className="text-sm text-gray-500 mt-1">You can only create shifts for your assigned team</p>
</div>
<div>
<h3 className="font-semibold mb-3">Assign Operators to Machines</h3>
<p className="text-sm text-gray-600 mb-3">
Assign one operator to each machine. Once selected, an operator won't appear in other dropdowns.
</p>
<div className="space-y-3">
{machines.slice(0, 7).map((machine: any, index: number) => {
const availableOps = getAvailableOperators(index)
const currentOperator = formData.operators[index]
return (
<div key={machine.id} className="flex items-center gap-4">
<span className="w-20 font-medium text-gray-700">{machine.name}</span>
<select
value={currentOperator}
onChange={(e) => {
const ops = [...formData.operators]
ops[index] = e.target.value
setFormData({...formData, operators: ops})
}}
className="flex-1 px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500"
required
>
<option value="">Select Operator</option>
{/* Show currently selected operator even if not in available list */}
{currentOperator && !availableOps.find((w: any) => w.id === currentOperator) && (() => {
const selectedWorker = workers.find((w: any) => w.id === currentOperator)
return selectedWorker ? (
<option value={currentOperator}>
{selectedWorker.firstName} {selectedWorker.surname}
</option>
) : null
})()}
{/* Show available operators */}
{availableOps.map((worker: any) => (
<option key={worker.id} value={worker.id}>
{worker.firstName} {worker.surname} ({worker.empNo})
</option>
))}
</select>
{currentOperator && (
<span className="text-green-600 text-sm"></span>
)}
</div>
)
})}
</div>
{formData.operators.filter(op => op).length > 0 && (
<p className="text-sm text-gray-600 mt-3">
{formData.operators.filter(op => op).length} of 7 operators assigned
</p>
)}
</div>
<button
type="submit"
disabled={loading}
className="w-full bg-blue-600 text-white py-3 rounded-lg font-medium hover:bg-blue-700 transition-colors disabled:opacity-50"
>
{loading ? "Creating..." : "Create Shift"}
</button>
</form>
</div>
</div>
)
}