Context
Replace the current colored-initial placeholder (PlaceAvatar) with real user-selectable icons. Backend support tracked in PlaceBrain/contracts#1, PlaceBrain/places#1, PlaceBrain/gateway#2. This issue is the frontend half.
Design decisions (from earlier discussion)
- Curated Lucide icon preset (~24 keys): `home`, `building`, `warehouse`, `factory`, `tent`, `tree-pine`, `wrench`, `server`, `store`, `school`, `church`, `hotel`, `hospital`, `landmark`, `mountain`, `ship`, `plane`, `train`, `trees`, `sun`, `moon`, `flame`, `snowflake`, `leaf`. Kept in `src/entities/place/model/icons.ts`.
- Palette of ~8 color keys matching the existing `--color-avatar-N-bg` / `--color-avatar-N-fg` variables in `src/app/styles/variables.css`. Stored as palette key, not hex — see contracts#1 rationale.
- Fallback to the existing `PlaceAvatar` (colored initial) when `icon` is null on the place.
Changes
- Extend `src/entities/place/model/types.ts` with optional `icon: string | null` and `icon_color: string | null`.
- Update `useCreatePlace` / `useUpdatePlace` payloads in `src/entities/place/api/place.api.ts`.
- New `src/entities/place/ui/PlaceIcon.vue` — renders the Lucide icon if set; otherwise falls back to ``. Props: `place`, `size` (sm | md | lg, matching `PlaceAvatar`).
- Replace `` usages in the sidebar (`src/widgets/sidebar/ui/SidebarPlacesList.vue`) and wherever the avatar is shown — keep `PlaceAvatar` as the fallback internal to `PlaceIcon`.
- New `src/features/place-icon-picker/PlaceIconPicker.vue`: grid of icons (+ a 'no icon' option) + palette swatches + preview via ``.
- Embed the picker in `CreatePlaceModal` and `EditPlaceModal`.
- All icons in the picker and in rendered rows must have `shrink-0` so flex layout does not squish them in narrow containers (see `frontend/CLAUDE.md`).
Acceptance
- User can pick, change, or clear an icon on a place.
- Sidebar, place detail header, and `PlaceCardGrid` all show the chosen icon.
- Light and dark themes render icon colors through CSS variables, no hardcoded Tailwind palette classes.
- `npx vue-tsc -b`, lint, format clean.
Related
Context
Replace the current colored-initial placeholder (
PlaceAvatar) with real user-selectable icons. Backend support tracked in PlaceBrain/contracts#1, PlaceBrain/places#1, PlaceBrain/gateway#2. This issue is the frontend half.Design decisions (from earlier discussion)
Changes
Acceptance
Related