import { useState, useEffect, useCallback } from 'react'; import { api } from '../api.js'; import { isInspectionExpirySoon } from '../utils/carUtils.js'; import styles from './CarManagement.module.css'; export default function CarManagement({ reloadKey = 0 }) { const [cars, setCars] = useState([]); const [reservations, setReservations] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [newCarName, setNewCarName] = useState(''); const [newCarDesc, setNewCarDesc] = useState(''); const [newCarExpiry, setNewCarExpiry] = useState(''); const [newCarEtc, setNewCarEtc] = useState(false); const [newCarTire, setNewCarTire] = useState('ノーマル'); const [editingId, setEditingId] = useState(null); const [editName, setEditName] = useState(''); const [editDesc, setEditDesc] = useState(''); const [editExpiry, setEditExpiry] = useState(''); const [editEtc, setEditEtc] = useState(false); const [editTire, setEditTire] = useState('ノーマル'); const [submitting, setSubmitting] = useState(false); const loadCars = useCallback(async () => { try { setLoading(true); const [carsData, resData] = await Promise.all([api.getCars(), api.getReservations()]); setCars(carsData); setReservations(resData); setError(null); } catch (e) { setError(e.message); } finally { setLoading(false); } }, []); useEffect(() => { loadCars(); }, [loadCars, reloadKey]); const handleAdd = async (e) => { e.preventDefault(); if (!newCarName.trim()) return; try { setSubmitting(true); await api.createCar({ name: newCarName.trim(), description: newCarDesc.trim(), inspection_expiry: newCarExpiry, has_etc: newCarEtc, tire_type: newCarTire, }); setNewCarName(''); setNewCarDesc(''); setNewCarExpiry(''); setNewCarEtc(false); setNewCarTire('ノーマル'); await loadCars(); } catch (e) { setError(e.message); } finally { setSubmitting(false); } }; const handleDelete = async (id, name) => { const carReservations = reservations.filter((r) => r.car_id === id); const message = carReservations.length > 0 ? `「${name}」を削除しますか?\n⚠ この代車には ${carReservations.length} 件の予約があります。削除するとこれらの予約もすべて削除されます。` : `「${name}」を削除しますか?\n関連する予約もすべて削除されます。`; if (!confirm(message)) return; try { await api.deleteCar(id); await loadCars(); } catch (e) { setError(e.message); } }; const startEdit = (car) => { setEditingId(car.id); setEditName(car.name); setEditDesc(car.description || ''); setEditExpiry(car.inspection_expiry || ''); setEditEtc(!!car.has_etc); setEditTire(car.tire_type || 'ノーマル'); }; const cancelEdit = () => { setEditingId(null); setEditName(''); setEditDesc(''); setEditExpiry(''); setEditEtc(false); setEditTire('ノーマル'); }; const handleUpdate = async (id) => { if (!editName.trim()) return; try { setSubmitting(true); await api.updateCar(id, { name: editName.trim(), description: editDesc.trim(), inspection_expiry: editExpiry, has_etc: editEtc, tire_type: editTire, }); cancelEdit(); await loadCars(); } catch (e) { setError(e.message); } finally { setSubmitting(false); } }; return (

代車管理

代車を追加

setNewCarName(e.target.value)} required /> setNewCarDesc(e.target.value)} />
{loading &&

読み込み中...

} {error &&

エラー: {error}

} {!loading && !error && (
{cars.length === 0 && ( )} {cars.map((car) => ( {editingId === car.id ? ( <> ) : ( <> )} ))}
ID 車名 備考 車検満了日 ETC タイヤ 操作
代車がありません
{car.id} setEditName(e.target.value)} /> setEditDesc(e.target.value)} /> setEditExpiry(e.target.value)} /> {car.name} {car.description || '-'} {car.inspection_expiry ? isInspectionExpirySoon(car.inspection_expiry) ? ⚠️ {car.inspection_expiry} : car.inspection_expiry : '-'} {car.has_etc ? '🛣️ あり' : 'なし'} {car.tire_type === 'スタットレス' ? '❄️ スタットレス' : 'ノーマル'}
)}
); }