diff --git a/lib/ResponseDefinitions.php b/lib/ResponseDefinitions.php index 1d5c43f..534f39d 100644 --- a/lib/ResponseDefinitions.php +++ b/lib/ResponseDefinitions.php @@ -59,7 +59,7 @@ namespace OCA\Pantry; * updatedAt: int, * } * - * @psalm-type PantryCategoryIcon = 'tag'|'food'|'fruit'|'vegetable'|'bakery'|'dairy'|'meat'|'fish'|'snacks'|'cookie'|'drinks'|'coffee'|'frozen'|'household'|'pets'|'baby'|'home'|'leaf'|'pizza' + * @psalm-type PantryCategoryIcon = 'tag'|'food'|'fruit'|'vegetable'|'bakery'|'dairy'|'meat'|'fish'|'snacks'|'cookie'|'drinks'|'coffee'|'frozen'|'household'|'pets'|'baby'|'home'|'leaf'|'pizza'|'clipboard-check'|'clipboard-list'|'format-list-checks'|'cart'|'basket'|'star'|'heart'|'calendar'|'bell'|'flag'|'bookmark'|'pin'|'map-marker'|'briefcase'|'wrench'|'silverware'|'gift'|'book'|'school'|'palette'|'camera'|'music'|'gamepad'|'run'|'dumbbell'|'pill'|'paw'|'flower'|'tree'|'broom'|'lightbulb'|'package'|'car'|'bike'|'beach' * * @psalm-type PantryCategoryColor = '#ef4444'|'#f97316'|'#eab308'|'#22c55e'|'#14b8a6'|'#0ea5e9'|'#6366f1'|'#a855f7'|'#ec4899'|'#78716c' * diff --git a/lib/Service/ConstantsService.php b/lib/Service/ConstantsService.php index 094c0c8..290e38c 100644 --- a/lib/Service/ConstantsService.php +++ b/lib/Service/ConstantsService.php @@ -34,6 +34,42 @@ class ConstantsService { 'home', 'leaf', 'pizza', + // Shared with the checklist icon picker. + 'clipboard-check', + 'clipboard-list', + 'format-list-checks', + 'cart', + 'basket', + 'star', + 'heart', + 'calendar', + 'bell', + 'flag', + 'bookmark', + 'pin', + 'map-marker', + 'briefcase', + 'wrench', + 'silverware', + 'gift', + 'book', + 'school', + 'palette', + 'camera', + 'music', + 'gamepad', + 'run', + 'dumbbell', + 'pill', + 'paw', + 'flower', + 'tree', + 'broom', + 'lightbulb', + 'package', + 'car', + 'bike', + 'beach', ]; /** Default category color palette, mirrored in the frontend. */ diff --git a/openapi.json b/openapi.json index cc1d3bb..e4d50d9 100644 --- a/openapi.json +++ b/openapi.json @@ -100,7 +100,42 @@ "baby", "home", "leaf", - "pizza" + "pizza", + "clipboard-check", + "clipboard-list", + "format-list-checks", + "cart", + "basket", + "star", + "heart", + "calendar", + "bell", + "flag", + "bookmark", + "pin", + "map-marker", + "briefcase", + "wrench", + "silverware", + "gift", + "book", + "school", + "palette", + "camera", + "music", + "gamepad", + "run", + "dumbbell", + "pill", + "paw", + "flower", + "tree", + "broom", + "lightbulb", + "package", + "car", + "bike", + "beach" ] }, "ChecklistIcon": { diff --git a/src/components/CategoryPicker/categoryIcons.test.ts b/src/components/CategoryPicker/categoryIcons.test.ts index d541e69..7262be4 100644 --- a/src/components/CategoryPicker/categoryIcons.test.ts +++ b/src/components/CategoryPicker/categoryIcons.test.ts @@ -19,6 +19,40 @@ vi.mock('@icons/Baby.vue', () => ({ default: { name: 'BabyIcon' } })) vi.mock('@icons/Home.vue', () => ({ default: { name: 'HomeIcon' } })) vi.mock('@icons/Leaf.vue', () => ({ default: { name: 'LeafIcon' } })) vi.mock('@icons/Pizza.vue', () => ({ default: { name: 'PizzaIcon' } })) +vi.mock('@icons/ClipboardCheck.vue', () => ({ default: { name: 'ClipboardCheckIcon' } })) +vi.mock('@icons/ClipboardList.vue', () => ({ default: { name: 'ClipboardListIcon' } })) +vi.mock('@icons/FormatListChecks.vue', () => ({ default: { name: 'FormatListChecksIcon' } })) +vi.mock('@icons/Cart.vue', () => ({ default: { name: 'CartIcon' } })) +vi.mock('@icons/Basket.vue', () => ({ default: { name: 'BasketIcon' } })) +vi.mock('@icons/Star.vue', () => ({ default: { name: 'StarIcon' } })) +vi.mock('@icons/Heart.vue', () => ({ default: { name: 'HeartIcon' } })) +vi.mock('@icons/Calendar.vue', () => ({ default: { name: 'CalendarIcon' } })) +vi.mock('@icons/Bell.vue', () => ({ default: { name: 'BellIcon' } })) +vi.mock('@icons/Flag.vue', () => ({ default: { name: 'FlagIcon' } })) +vi.mock('@icons/Bookmark.vue', () => ({ default: { name: 'BookmarkIcon' } })) +vi.mock('@icons/Pin.vue', () => ({ default: { name: 'PinIcon' } })) +vi.mock('@icons/MapMarker.vue', () => ({ default: { name: 'MapMarkerIcon' } })) +vi.mock('@icons/Briefcase.vue', () => ({ default: { name: 'BriefcaseIcon' } })) +vi.mock('@icons/Wrench.vue', () => ({ default: { name: 'WrenchIcon' } })) +vi.mock('@icons/Silverware.vue', () => ({ default: { name: 'SilverwareIcon' } })) +vi.mock('@icons/Gift.vue', () => ({ default: { name: 'GiftIcon' } })) +vi.mock('@icons/Book.vue', () => ({ default: { name: 'BookIcon' } })) +vi.mock('@icons/School.vue', () => ({ default: { name: 'SchoolIcon' } })) +vi.mock('@icons/Palette.vue', () => ({ default: { name: 'PaletteIcon' } })) +vi.mock('@icons/Camera.vue', () => ({ default: { name: 'CameraIcon' } })) +vi.mock('@icons/Music.vue', () => ({ default: { name: 'MusicIcon' } })) +vi.mock('@icons/Gamepad.vue', () => ({ default: { name: 'GamepadIcon' } })) +vi.mock('@icons/Run.vue', () => ({ default: { name: 'RunIcon' } })) +vi.mock('@icons/Dumbbell.vue', () => ({ default: { name: 'DumbbellIcon' } })) +vi.mock('@icons/Pill.vue', () => ({ default: { name: 'PillIcon' } })) +vi.mock('@icons/Paw.vue', () => ({ default: { name: 'PawIcon' } })) +vi.mock('@icons/Flower.vue', () => ({ default: { name: 'FlowerIcon' } })) +vi.mock('@icons/Tree.vue', () => ({ default: { name: 'TreeIcon' } })) +vi.mock('@icons/Lightbulb.vue', () => ({ default: { name: 'LightbulbIcon' } })) +vi.mock('@icons/Package.vue', () => ({ default: { name: 'PackageIcon' } })) +vi.mock('@icons/Car.vue', () => ({ default: { name: 'CarIcon' } })) +vi.mock('@icons/Bike.vue', () => ({ default: { name: 'BikeIcon' } })) +vi.mock('@icons/Beach.vue', () => ({ default: { name: 'BeachIcon' } })) import { CATEGORY_COLORS, @@ -28,8 +62,8 @@ import { } from './categoryIcons' describe('CATEGORY_ICONS', () => { - it('has 19 entries', () => { - expect(CATEGORY_ICONS).toHaveLength(19) + it('has 54 entries', () => { + expect(CATEGORY_ICONS).toHaveLength(54) }) it('each entry has key, label, and component', () => { diff --git a/src/components/CategoryPicker/categoryIcons.ts b/src/components/CategoryPicker/categoryIcons.ts index a910063..5e88129 100644 --- a/src/components/CategoryPicker/categoryIcons.ts +++ b/src/components/CategoryPicker/categoryIcons.ts @@ -21,6 +21,44 @@ import BabyIcon from '@icons/Baby.vue' import HomeIcon from '@icons/Home.vue' import LeafIcon from '@icons/Leaf.vue' import PizzaIcon from '@icons/Pizza.vue' +// Shared with the checklist icon picker — these cover general-purpose use cases +// (shopping, reminders, travel, hobbies, etc.) and make categories flexible +// beyond the food-centric default set above. +import ClipboardCheckIcon from '@icons/ClipboardCheck.vue' +import ClipboardListIcon from '@icons/ClipboardList.vue' +import FormatListChecksIcon from '@icons/FormatListChecks.vue' +import CartIcon from '@icons/Cart.vue' +import BasketIcon from '@icons/Basket.vue' +import StarIcon from '@icons/Star.vue' +import HeartIcon from '@icons/Heart.vue' +import CalendarIcon from '@icons/Calendar.vue' +import BellIcon from '@icons/Bell.vue' +import FlagIcon from '@icons/Flag.vue' +import BookmarkIcon from '@icons/Bookmark.vue' +import PinIcon from '@icons/Pin.vue' +import MapMarkerIcon from '@icons/MapMarker.vue' +import BriefcaseIcon from '@icons/Briefcase.vue' +import WrenchIcon from '@icons/Wrench.vue' +import SilverwareIcon from '@icons/Silverware.vue' +import GiftIcon from '@icons/Gift.vue' +import BookIcon from '@icons/Book.vue' +import SchoolIcon from '@icons/School.vue' +import PaletteIcon from '@icons/Palette.vue' +import CameraIcon from '@icons/Camera.vue' +import MusicIcon from '@icons/Music.vue' +import GamepadIcon from '@icons/Gamepad.vue' +import RunIcon from '@icons/Run.vue' +import DumbbellIcon from '@icons/Dumbbell.vue' +import PillIcon from '@icons/Pill.vue' +import PawIcon from '@icons/Paw.vue' +import FlowerIcon from '@icons/Flower.vue' +import TreeIcon from '@icons/Tree.vue' +import BroomIcon from '@icons/Broom.vue' +import LightbulbIcon from '@icons/Lightbulb.vue' +import PackageIcon from '@icons/Package.vue' +import CarIcon from '@icons/Car.vue' +import BikeIcon from '@icons/Bike.vue' +import BeachIcon from '@icons/Beach.vue' export interface CategoryIconOption { key: string @@ -51,6 +89,41 @@ export const CATEGORY_ICONS: CategoryIconOption[] = [ { key: 'home', label: 'Home', component: HomeIcon }, { key: 'leaf', label: 'Leaf', component: LeafIcon }, { key: 'pizza', label: 'Pizza', component: PizzaIcon }, + { key: 'clipboard-check', label: 'Checklist', component: ClipboardCheckIcon }, + { key: 'clipboard-list', label: 'List', component: ClipboardListIcon }, + { key: 'format-list-checks', label: 'Tasks', component: FormatListChecksIcon }, + { key: 'cart', label: 'Shopping', component: CartIcon }, + { key: 'basket', label: 'Basket', component: BasketIcon }, + { key: 'star', label: 'Favorites', component: StarIcon }, + { key: 'heart', label: 'Wishlist', component: HeartIcon }, + { key: 'calendar', label: 'Calendar', component: CalendarIcon }, + { key: 'bell', label: 'Reminders', component: BellIcon }, + { key: 'flag', label: 'Goals', component: FlagIcon }, + { key: 'bookmark', label: 'Saved', component: BookmarkIcon }, + { key: 'pin', label: 'Pinned', component: PinIcon }, + { key: 'map-marker', label: 'Places', component: MapMarkerIcon }, + { key: 'briefcase', label: 'Work', component: BriefcaseIcon }, + { key: 'wrench', label: 'Repairs', component: WrenchIcon }, + { key: 'silverware', label: 'Meals', component: SilverwareIcon }, + { key: 'gift', label: 'Gifts', component: GiftIcon }, + { key: 'book', label: 'Reading', component: BookIcon }, + { key: 'school', label: 'School', component: SchoolIcon }, + { key: 'palette', label: 'Creative', component: PaletteIcon }, + { key: 'camera', label: 'Photos', component: CameraIcon }, + { key: 'music', label: 'Music', component: MusicIcon }, + { key: 'gamepad', label: 'Games', component: GamepadIcon }, + { key: 'run', label: 'Exercise', component: RunIcon }, + { key: 'dumbbell', label: 'Fitness', component: DumbbellIcon }, + { key: 'pill', label: 'Health', component: PillIcon }, + { key: 'paw', label: 'Pets (paw)', component: PawIcon }, + { key: 'flower', label: 'Garden', component: FlowerIcon }, + { key: 'tree', label: 'Outdoors', component: TreeIcon }, + { key: 'broom', label: 'Cleaning', component: BroomIcon }, + { key: 'lightbulb', label: 'Ideas', component: LightbulbIcon }, + { key: 'package', label: 'Packing', component: PackageIcon }, + { key: 'car', label: 'Travel', component: CarIcon }, + { key: 'bike', label: 'Cycling', component: BikeIcon }, + { key: 'beach', label: 'Vacation', component: BeachIcon }, ] const byKey: Record = Object.fromEntries(