first commit
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
# Furniture Optimizer (hackathon project)
|
||||
|
||||
A web tool for venues (events, banquets, conferences) to lay out furniture in a room and, eventually, auto-optimize the layout.
|
||||
|
||||
## Current scope: Phase 1 (UI only)
|
||||
|
||||
The ONLY feature right now is drag-and-drop layout:
|
||||
|
||||
- Left palette with two source tiles: chair and table.
|
||||
- Large rectangular room on the right (fixed 10m x 8m, drawn to scale, 1m = 60px, faint 0.5m grid).
|
||||
- Click (no drag) a palette tile to open a settings menu for that furniture type:
|
||||
- Available: how many of that type the venue has (number stepper, min = number already placed).
|
||||
- Tables only: Seats per table (number stepper, min 1).
|
||||
- Palette tiles show a badge with remaining count (available minus placed).
|
||||
- Drag a tile into the room to create an item. The tile stays in the palette. If remaining is 0, the tile is greyed out and can't be dragged.
|
||||
- Distinguish click from drag with a small movement threshold (about 5px).
|
||||
- Drag existing items to move them. Items are clamped inside the room walls.
|
||||
- No overlap allowed. Invalid position = red outline while dragging; on drop, snap back to last valid position (or cancel the add if new).
|
||||
- Snap to the 0.5m grid on drop.
|
||||
|
||||
Do not build anything beyond this unless asked. Do not design in a way that blocks the roadmap below.
|
||||
|
||||
## Tech stack
|
||||
|
||||
- React + TypeScript, Vite
|
||||
- react-konva (Konva) for the canvas
|
||||
- State: single top-level store (useState/useReducer). Keep it centralized so an optimizer can read and write it later.
|
||||
|
||||
## Data model
|
||||
|
||||
```ts
|
||||
type FurnitureType = "chair" | "table";
|
||||
|
||||
interface FurnitureItem {
|
||||
id: string;
|
||||
type: FurnitureType;
|
||||
x: number; // meters, top-left, room coordinates
|
||||
y: number;
|
||||
width: number; // meters
|
||||
height: number;
|
||||
rotation: number; // degrees, always 0 for now
|
||||
locked: boolean; // always false for now, reserved
|
||||
}
|
||||
|
||||
interface Room { width: number; height: number; } // meters
|
||||
|
||||
// Per-type settings, edited via the palette menu
|
||||
interface FurnitureTypeConfig {
|
||||
type: FurnitureType;
|
||||
available: number; // inventory count
|
||||
seatsPerUnit?: number; // tables only: people who can sit at one
|
||||
}
|
||||
// remaining = available - items.filter(i => i.type === type).length
|
||||
```
|
||||
|
||||
Seats per table is a type-level setting for now (applies to all tables). Per-table overrides come later. Chairs and table seats are independent for now.
|
||||
|
||||
Default sizes: chair 0.5 x 0.5 m, table 1.8 x 0.8 m.
|
||||
|
||||
## Conventions
|
||||
|
||||
- Store everything in meters. Convert to pixels only at render time (one `PX_PER_M` constant).
|
||||
- Collision = axis-aligned bounding boxes. Keep collision and clamping logic in pure functions (no React or Konva imports) so the optimizer can reuse them.
|
||||
- Keep geometry/rules logic separate from rendering components.
|
||||
- Small, typed, readable code. No new dependencies without a good reason.
|
||||
- Keep the UI minimal: light grey app background, room centered in the remaining space.
|
||||
|
||||
## Roadmap (not built yet, don't block)
|
||||
|
||||
Venue-focused features planned for later phases:
|
||||
|
||||
- Furniture inventory: set X amount of each furniture type
|
||||
- Semi-custom furniture: couches, chairs, tables of any size and seating count
|
||||
- Room import
|
||||
- Furniture placement rules
|
||||
- Locking furniture in place
|
||||
- Custom seating limits (per table or global)
|
||||
- Optimizers for: room loading/unloading flow, screen visibility, max comfort, max table access
|
||||
- Optimization approach idea: user-set rule priorities, possibly a neural net with weights and biases to score "optimal placements" (undecided; start with hard constraints like no overlap, then weighted scoring)
|
||||
- Input ideas: phone scanning of a room, manual entry
|
||||
|
||||
## Commands
|
||||
|
||||
```
|
||||
npm install
|
||||
npm run dev # start dev server
|
||||
npm run build # production build
|
||||
npx tsc --noEmit # type check
|
||||
```
|
||||
|
||||
## Working agreement
|
||||
|
||||
- Ask before expanding scope past Phase 1.
|
||||
- After changes, make sure the app builds and type checks.
|
||||
- Hackathon pace: prefer simple and working over clever.
|
||||
Reference in New Issue
Block a user