fix: preserve AM/PM when dragging reservation; add drag & drop car reordering

Agent-Logs-Url: https://github.com/pdf114514/CarReservation/sessions/c5f8f1a2-8a8b-4951-8442-76ce37d906ae

Co-authored-by: pdf114514 <57948770+pdf114514@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-04-06 07:47:08 +00:00
committed by GitHub
parent 81767e5270
commit 3b49844d0b
3 changed files with 56 additions and 2 deletions

View File

@@ -1,4 +1,4 @@
import { useState, useEffect, useCallback } from 'react'; import { useState, useEffect, useCallback, useRef } from 'react';
import { api } from '../api.js'; import { api } from '../api.js';
import { isInspectionExpirySoon } from '../utils/carUtils.js'; import { isInspectionExpirySoon } from '../utils/carUtils.js';
import styles from './CarManagement.module.css'; import styles from './CarManagement.module.css';
@@ -20,6 +20,8 @@ export default function CarManagement({ reloadKey = 0 }) {
const [editEtc, setEditEtc] = useState(false); const [editEtc, setEditEtc] = useState(false);
const [editTire, setEditTire] = useState('ノーマル'); const [editTire, setEditTire] = useState('ノーマル');
const [submitting, setSubmitting] = useState(false); const [submitting, setSubmitting] = useState(false);
const [dragOverIdx, setDragOverIdx] = useState(null);
const dragSrcIdx = useRef(null);
const loadCars = useCallback(async () => { const loadCars = useCallback(async () => {
try { try {
@@ -130,6 +132,38 @@ export default function CarManagement({ reloadKey = 0 }) {
} }
}; };
const handleDragStart = (index) => {
dragSrcIdx.current = index;
};
const handleDragOver = (e, index) => {
e.preventDefault();
setDragOverIdx(index);
};
const handleDragEnd = () => {
setDragOverIdx(null);
dragSrcIdx.current = null;
};
const handleDrop = async (e, dropIndex) => {
e.preventDefault();
const srcIndex = dragSrcIdx.current;
setDragOverIdx(null);
dragSrcIdx.current = null;
if (srcIndex === null || srcIndex === dropIndex) return;
const newCars = [...cars];
const [moved] = newCars.splice(srcIndex, 1);
newCars.splice(dropIndex, 0, moved);
setCars(newCars);
try {
await api.reorderCars(newCars.map((c) => c.id));
} catch (e) {
setError(e.message);
await loadCars();
}
};
return ( return (
<div className={styles.container}> <div className={styles.container}>
<h2 className={styles.heading}>代車管理</h2> <h2 className={styles.heading}>代車管理</h2>
@@ -217,7 +251,15 @@ export default function CarManagement({ reloadKey = 0 }) {
</tr> </tr>
)} )}
{cars.map((car, carIdx) => ( {cars.map((car, carIdx) => (
<tr key={car.id}> <tr
key={car.id}
draggable
onDragStart={() => handleDragStart(carIdx)}
onDragOver={(e) => handleDragOver(e, carIdx)}
onDragEnd={handleDragEnd}
onDrop={(e) => handleDrop(e, carIdx)}
className={dragOverIdx === carIdx ? styles.dragOver : ''}
>
<td className={styles.idCell}> <td className={styles.idCell}>
<div className={styles.orderBtns}> <div className={styles.orderBtns}>
<button <button

View File

@@ -111,6 +111,16 @@
background: #fafafa; background: #fafafa;
} }
.table tbody tr[draggable] {
cursor: grab;
}
.dragOver {
background: #eff6ff !important;
outline: 2px dashed #1a56db;
outline-offset: -2px;
}
.idCell { .idCell {
color: #9ca3af; color: #9ca3af;
width: 80px; width: 80px;

View File

@@ -224,6 +224,8 @@ export default function ScheduleView({ reloadKey = 0 }) {
end_date: newEndDate, end_date: newEndDate,
customer_name: reservation.customer_name, customer_name: reservation.customer_name,
notes: reservation.notes, notes: reservation.notes,
start_period: reservation.start_period,
end_period: reservation.end_period,
}); });
await loadData(); await loadData();
} catch (err) { } catch (err) {