shelf edits
This commit is contained in:
parent
f97b49cbdf
commit
f48dd1ef7c
@ -1,21 +1,57 @@
|
|||||||
// components/RackDetails.tsx
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {StockRack, StockPosition} from '@/types';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
import { faTrash, faPlus } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import { StockRack, StockPosition } from '@/types';
|
||||||
|
|
||||||
interface RackDetailsProps {
|
interface RackDetailsProps {
|
||||||
rack: StockRack | null;
|
rack: StockRack | null;
|
||||||
onPositionClick: (posId: number) => void;
|
onPositionClick: (posId: number) => void;
|
||||||
|
onAddShelf: (rackId: number) => void;
|
||||||
|
onDeleteShelf: (shelfId: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function RackModalDetails({rack, onPositionClick}: RackDetailsProps) {
|
export default function RackModalDetails({
|
||||||
|
rack,
|
||||||
|
onPositionClick,
|
||||||
|
onAddShelf,
|
||||||
|
onDeleteShelf
|
||||||
|
}: RackDetailsProps) {
|
||||||
|
if (!rack) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="overflow-auto p-4">
|
<div className="overflow-auto p-4">
|
||||||
|
{/* Add shelf button */}
|
||||||
|
<div className="flex justify-end mb-2">
|
||||||
|
<button
|
||||||
|
className="btn btn-sm btn-outline flex items-center space-x-1"
|
||||||
|
onClick={() => onAddShelf(rack.rack_id)}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faPlus} />
|
||||||
|
<span>Add Shelf</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col space-y-4">
|
<div className="flex flex-col space-y-4">
|
||||||
{rack.shelves?.map((shelf) => (
|
{rack.shelves?.map((shelf) => (
|
||||||
<div key={shelf.shelf_symbol} className="flex items-start space-x-4 flex-col">
|
<div
|
||||||
{/* Shelf label */}
|
key={shelf.shelf_id}
|
||||||
<div className="font-bold">Shelf {shelf.shelf_symbol}</div>
|
className="flex flex-col space-y-2 border p-3 rounded-lg"
|
||||||
|
>
|
||||||
|
<div className="flex justify-between items-center">
|
||||||
|
<div className="font-bold">
|
||||||
|
Shelf {shelf.shelf_symbol} — {shelf.shelf_name}
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
className="btn btn-xs btn-error p-1"
|
||||||
|
onClick={() => {
|
||||||
|
if (confirm(`Delete shelf ${shelf.shelf_symbol}?`)) {
|
||||||
|
onDeleteShelf(shelf.shelf_id);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faTrash} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Positions container */}
|
{/* Positions container */}
|
||||||
<div className="flex space-x-4 border border-white dark:border-gray-700 h-max min-h-40 w-full">
|
<div className="flex space-x-4 border border-white dark:border-gray-700 h-max min-h-40 w-full">
|
||||||
@ -26,13 +62,11 @@ export default function RackModalDetails({rack, onPositionClick}: RackDetailsPro
|
|||||||
className="border rounded-lg p-3 w-full cursor-pointer"
|
className="border rounded-lg p-3 w-full cursor-pointer"
|
||||||
onClick={() => onPositionClick(position.position_id)}
|
onClick={() => onPositionClick(position.position_id)}
|
||||||
>
|
>
|
||||||
{/* Position label */}
|
<div className="font-semibold mb-2">
|
||||||
<div className="font-semibold mb-2">Pos {position.position_symbol}</div>
|
Pos {position.position_symbol}
|
||||||
|
</div>
|
||||||
{/* Sections grid */}
|
|
||||||
<div className="grid grid-cols-1 gap-2">
|
<div className="grid grid-cols-1 gap-2">
|
||||||
{position.sections.map((section) => (
|
{position.sections.map((section) => (
|
||||||
|
|
||||||
<div
|
<div
|
||||||
key={section.section_symbol}
|
key={section.section_symbol}
|
||||||
className="border rounded p-1 text-center bg-primary font-bold cursor-pointer"
|
className="border rounded p-1 text-center bg-primary font-bold cursor-pointer"
|
||||||
@ -48,8 +82,9 @@ export default function RackModalDetails({rack, onPositionClick}: RackDetailsPro
|
|||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<div className="border rounded-lg p-3 w-full flex items-center justify-center">No
|
<div className="border rounded-lg p-3 w-full flex items-center justify-center">
|
||||||
positions</div>
|
No positions
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -421,6 +421,52 @@ export default function FloorPlan() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ➊ add a new shelf
|
||||||
|
const handleAddShelf = async (rackId: number) => {
|
||||||
|
// compute next symbol & name from current editModal.item_obj
|
||||||
|
const rack = editModal.item_obj as StockRack;
|
||||||
|
const next = rack.shelves ? rack.shelves.length + 1 : 1;
|
||||||
|
const symbol = String(next);
|
||||||
|
const name = `Shelf ${symbol}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await axios.post(
|
||||||
|
'/api/stock-shelves',
|
||||||
|
{ rack_id: rackId, shelf_symbol: symbol, shelf_name: name },
|
||||||
|
{ withCredentials: true }
|
||||||
|
);
|
||||||
|
// refresh just that rack
|
||||||
|
const { data: freshRack } = await axios.get<StockRack>(
|
||||||
|
`/api/stock-racks/${rackId}`,
|
||||||
|
{ withCredentials: true }
|
||||||
|
);
|
||||||
|
setEditModal(m => ({ ...m, item_obj: freshRack }));
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
alert('Could not add shelf.');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ➋ delete a shelf
|
||||||
|
const handleDeleteShelf = async (shelfId: number) => {
|
||||||
|
try {
|
||||||
|
await axios.delete(`/api/stock-shelves/${shelfId}`, {
|
||||||
|
withCredentials: true
|
||||||
|
});
|
||||||
|
// after delete, re-fetch rack
|
||||||
|
const rack = editModal.item_obj as StockRack;
|
||||||
|
const { data: freshRack } = await axios.get<StockRack>(
|
||||||
|
`/api/stock-racks/${rack.rack_id}`,
|
||||||
|
{ withCredentials: true }
|
||||||
|
);
|
||||||
|
setEditModal(m => ({ ...m, item_obj: freshRack }));
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
alert('Could not delete shelf.');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout title="Floor Plan">
|
<AppLayout title="Floor Plan">
|
||||||
<div className="p-6 flex flex-col items-center space-y-4">
|
<div className="p-6 flex flex-col items-center space-y-4">
|
||||||
@ -520,7 +566,7 @@ export default function FloorPlan() {
|
|||||||
{editModal.type === 'rack' && (
|
{editModal.type === 'rack' && (
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<h4 className="font-bold mb-2">Shelves & Sections</h4>
|
<h4 className="font-bold mb-2">Shelves & Sections</h4>
|
||||||
<RackModalDetails rack={editModal.item_obj} onPositionClick={handleOpenSections} />
|
<RackModalDetails rack={editModal.item_obj} onPositionClick={handleOpenSections} onAddShelf={handleAddShelf} onDeleteShelf={handleDeleteShelf} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="modal-action">
|
<div className="modal-action">
|
||||||
|
Loading…
Reference in New Issue
Block a user