TKK_E32231405/app/dashboard/kelola-jadwal/InstantScheduleModal.tsx

137 lines
6.6 KiB
TypeScript

'use client'
import { useState, useActionState, useEffect, useRef } from 'react'
import { X, Calendar, Clock, Loader2, Sparkles, AlertCircle } from 'lucide-react'
import { generateInstantSchedule } from './action-jadwal'
import { showSwal } from '@/lib/swal'
interface Props {
isOpen: boolean
onClose: () => void
adminName: string
}
export function InstantScheduleModal({ isOpen, onClose, adminName }: Props) {
const [state, formAction, isPending] = useActionState(generateInstantSchedule, null)
const processedStateRef = useRef<any>(null)
useEffect(() => {
// Detect NEW result from action
if (state && state !== processedStateRef.current) {
// 1. Immediately close the modal so it doesn't block the alert or persist
onClose()
// 2. Show the alert after closing the modal
if (state.success) {
showSwal.success('Berhasil!', `${state.message} Silakan gunakan tombol "Cetak Semua Jadwal" untuk mengunduh seluruh laporan PDF.`)
} else {
showSwal.error('Gagal!', state.message)
}
// 3. Mark this specific state object as processed
processedStateRef.current = state
}
}, [state, onClose])
// Reset processed state when modal is opened for a fresh experience
useEffect(() => {
if (isOpen) {
processedStateRef.current = null
}
}, [isOpen])
if (!isOpen) return null
const tomorrow = new Date()
tomorrow.setDate(tomorrow.getDate() + 1)
const minDate = tomorrow.toISOString().split('T')[0]
return (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/40 backdrop-blur-sm">
<div className="bg-white w-full max-w-md rounded-2xl border-2 border-black shadow-[6px_6px_0px_0px_rgba(0,0,0,1)] overflow-hidden animate-in zoom-in duration-200">
<div className="p-5 bg-red-500 border-b-2 border-black flex justify-between items-center text-white">
<div className="flex items-center gap-3">
<div className="p-1.5 bg-white/20 rounded-lg backdrop-blur-sm">
<Sparkles className="w-4 h-4 text-white" />
</div>
<h3 className="text-base font-black uppercase tracking-tight">Penjadwalan Instan</h3>
</div>
<button onClick={onClose} className="p-1.5 hover:bg-white/10 rounded-full transition-all">
<X className="w-5 h-5" />
</button>
</div>
<form action={formAction} className="p-6 flex flex-col gap-5">
<input type="hidden" name="edited_by" value={adminName} />
<input type="hidden" name="jam_mulai" value="08:00" />
<input type="hidden" name="jam_selesai" value="11:00" />
<div className="p-3 bg-blue-50 border border-blue-200 rounded-xl flex gap-x-2">
<AlertCircle className="w-4 h-4 text-blue-600 flex-shrink-0" />
<div className="flex flex-col gap-1">
<p className="text-[10px] text-blue-800 leading-relaxed font-bold uppercase tracking-tight">
Penjadwalan harus dilakukan minimal 1 hari sebelumnya.
</p>
<p className="text-[10px] text-blue-800 leading-relaxed font-bold uppercase tracking-tight">
Sesi tetap: 08:00 - 11:00 WIB (Selingan 1 Jam).
</p>
</div>
</div>
{/* Tanggal */}
<div className="flex flex-col gap-2">
<label className="text-[9px] font-black uppercase tracking-widest text-gray-400 flex items-center gap-2">
<Calendar className="w-3.5 h-3.5" /> Pilih Tanggal Pelaksanaan
</label>
<input
type="date"
name="tanggal"
required
min={minDate}
defaultValue={minDate}
className="w-full p-3 border-2 border-black rounded-xl font-bold focus:outline-none focus:ring-4 focus:ring-red-500/10 transition-all text-sm"
/>
</div>
<div className="p-4 bg-gray-50 border-2 border-dashed border-gray-200 rounded-xl">
<label className="text-[9px] font-black uppercase tracking-widest text-gray-400 flex items-center gap-2 mb-2">
<Clock className="w-3.5 h-3.5" /> Waktu Sesi (Otomatis)
</label>
<div className="flex items-center gap-3">
<div className="px-3 py-1.5 bg-black text-white text-sm font-black rounded-lg">
08:00
</div>
<div className="h-0.5 w-4 bg-gray-300"></div>
<div className="px-3 py-1.5 bg-black text-white text-sm font-black rounded-lg">
11:00
</div>
<span className="text-[10px] font-black text-gray-400 uppercase tracking-widest ml-auto">Fixed Slot</span>
</div>
</div>
<div className="pt-2">
<button
type="submit"
disabled={isPending}
className="w-full py-4 bg-black text-white font-black text-xs uppercase tracking-widest rounded-xl hover:bg-gray-800 transition-all shadow-[4px_4px_0px_0px_rgba(0,0,0,0.3)] hover:shadow-none hover:translate-x-[2px] hover:translate-y-[2px] flex items-center justify-center gap-2 disabled:opacity-50"
>
{isPending ? (
<>
<Loader2 className="w-5 h-5 animate-spin" />
Menghitung...
</>
) : (
<>
<Sparkles className="w-5 h-5" />
Buat Jadwal Sekarang
</>
)}
</button>
</div>
</form>
</div>
</div>
)
}