Store Components
Store components enable bookstore owners to manage inventory, process sales, and showcase their businesses.
InventoryItemTile
A list tile displaying inventory item details with stock status indicators.
Usage
InventoryItemTile(
item: inventoryItem,
onTap: () => navigateToDetail(item.id),
)
Props
| Property | Type | Required | Description |
|---|---|---|---|
item | InventoryItem | Yes | Inventory item with book, price, quantity, condition |
onTap | VoidCallback | Yes | Callback when tile is tapped |
Anatomy
Leading
- Thumbnail: 50x70px book cover
- Fallback: Gray surface with book icon
Title
- Book title (2-line max with ellipsis)
- Style:
AppTypography.bookTitle
Subtitle
- Authors: Comma-separated, 1-line max
- Price: Dollar format with 2 decimals, bold
- Stock Badge: Colored badge with quantity or "Out of stock"
- Condition Badge: Shows condition if not new
Trailing
- Chevron right icon
Stock Status Logic
final isLowStock = item.quantity < 3;
final isOutOfStock = item.quantity == 0;
Status Colors
- Out of Stock: Error container color (red theme)
- Low Stock: Orange background at 0.2 alpha, orange text
- In Stock: Primary container color
Condition Labels
Enum mapping via BookCondition:
new: "New"like_new: "Like New"good: "Good"fair: "Fair"
Condition Badge (only shown if not new):
- Tertiary container background
- Small badge (12px font)
- Displayed next to stock badge
Styling
- Padding: 16px horizontal, 6px vertical
- Border radius: 12px
- Elevation: 2
- Background: White
Features
- Stock Indicators: Visual warnings for low/out-of-stock items
- Condition Display: Clearly shows used book condition
- Tappable: Opens inventory detail page
InventoryCard
For grid layouts, inventory items can use a card format similar to BookCard.
Implementation Pattern
Card(
child: Column(
children: [
// Book cover
Expanded(child: CoverImage()),
// Details
Padding(
child: Column(
children: [
Text(item.book.title),
Text('\$${item.priceInDollars}'),
StockBadge(quantity: item.quantity),
],
),
),
],
),
)
POSPanel
The Point of Sale panel is implemented in POSPage for in-store transactions.
Usage Location
/Users/terryheath/Documents/bookwish_monorepo/app/lib/ui/pages/shop/pos_page.dart
Features
- Barcode Scanning: Add items via ISBN scanner
- Cart Management: Add/remove items from transaction
- Payment Processing: Cash and card payments via Square
- Receipt Generation: Email receipts to customers
- Discount Application: Apply percentage or fixed discounts
- Tax Calculation: Automatic tax calculation based on store settings
Key Components
Item Search
- ISBN barcode scanner integration
- Manual ISBN entry
- Inventory item lookup
Cart Display
- List of items with quantities
- Running subtotal
- Tax calculation
- Total display
Checkout Actions
- Process payment button
- Clear cart button
- Apply discount button
Integration
- Uses
Squarepayment integration - Connects to store's Square account
- Records transaction in order history
StoreHeader (Web)
Header component for store websites (Next.js).
Usage
<StoreHeader store={store} />
Props
| Property | Type | Required | Description |
|---|---|---|---|
store | Store | Yes | Store data with name, logo, slug, colors |
Anatomy
Logo Section
- Store logo (40x40px, rounded) or initial letter fallback
- Store name in serif font (text-xl, bold)
- Clickable to return to store home
Navigation
- Browse Books link
- Read With Us link (programs)
- "Powered by BookWish" link
Styling
- Position: Sticky top-0, z-10
- Background: White with 95% opacity, backdrop blur
- Border: Bottom border
- Container: Max width 6xl (1152px), centered
- Padding: 4 units (16px) all
Dynamic Branding
Uses CSS custom properties:
style={{
"--dynamic-primary": store.primaryColor || "#1a1a1a",
}}
Features
- Sticky Header: Remains visible while scrolling
- Responsive: Adapts to mobile/desktop
- Brand Colors: Applies store's primary color
StoreFooter (Web)
Footer component for store websites (Next.js).
Usage
<StoreFooter store={store} />
Props
| Property | Type | Required | Description |
|---|---|---|---|
store | Store | Yes | Store data with address, hours, phone |
Anatomy
Store Info Column
- Store name heading
- Full address (if available)
- Phone number (if available)
Hours Column (if store.hours exists)
- Day-by-day hours display
- Formatted as key-value pairs
Links Column
- Get the BookWish App
- Terms of Service
- Privacy Policy
Bottom Bar
- Copyright notice
- "Powered by BookWish" link
Styling
- Background: Dark gray (gray-900)
- Text Color: Light gray (gray-400)
- Headings: White
- Grid: 3 columns on desktop, stacked on mobile
- Padding: 12 units (48px) vertical, 4 units horizontal
- Top Margin: 16 units (64px)
Features
- Responsive Grid: Adapts to screen size
- Optional Sections: Only shows hours if available
- Brand Links: Links back to main BookWish app
StoreProgramCard (Web)
Program cards for clubs and challenges on store websites.
ClubCard
Displays book club information with current reading.
Anatomy
- Cover Image: 80x80px rounded, or icon fallback
- Club Name: Semibold heading
- Description: 2-line clamp
- Member Count: Small text with person icon
- Current Book Section (if available):
- "Currently Reading" label
- Book cover thumbnail (40x56px)
- Book title and authors
- Join Button: "Join in App" CTA
ChallengeCard
Displays reading challenge information with status.
Anatomy
- Challenge Name: Semibold heading
- Status Badge: Active/Upcoming/Ended with color coding
- Book Count: Small text
- Description: 2-line clamp
- Date Range: Start and end dates
- Participant Count: Small text
- Join Button: "Join in App" CTA
Status Logic
const isActive = now >= startDate && now <= endDate;
const isUpcoming = now < startDate;
Status Colors
- Active: Green background, green text
- Upcoming: Amber background, dark text
- Ended: Gray background, gray text
Styling
- Card: White background, border, rounded-xl
- Padding: 5 units (20px)
- Hover: Shadow-md on hover
- Border: Subtle parchment color (#E0D7C8)
App Integration
Both cards link to BookWish app:
const appLink = `${config.mainAppUrl}/club/${club.id}`;
const appLink = `${config.mainAppUrl}/challenge/${challenge.id}`;
InventoryTable
Used in inventory management page for tabular display.
Implementation
Grid/list view of InventoryItemTile components in InventoryPage.
Columns (Conceptual)
- Book thumbnail
- Title/Author
- Price
- Quantity
- Condition
- Actions
Features
- Sorting: By title, price, quantity
- Filtering: By condition, stock status
- Bulk Actions: Select multiple items
- Quick Edit: Inline quantity updates
Location
/Users/terryheath/Documents/bookwish_monorepo/app/lib/ui/pages/shop/inventory_page.dart
StoreSetup Components
Store setup flow components for onboarding.
StoreSetupPage
Located at: /Users/terryheath/Documents/bookwish_monorepo/app/lib/ui/pages/shop/store_setup_page.dart
Setup Steps
- Store name and description
- Address information
- Hours of operation
- Payment integration (Square)
- Website customization
HoursEditor
Component for editing store hours.
Located at: /Users/terryheath/Documents/bookwish_monorepo/app/lib/ui/components/hours_editor.dart
Features
- Day Selection: Toggle each day of week
- Time Range: Start and end time pickers
- Closed Days: Mark days as closed
- Copy Hours: Copy to multiple days
StoreChip
Small chip component for displaying store information.
Located at: /Users/terryheath/Documents/bookwish_monorepo/app/lib/ui/components/store_chip.dart
Usage
Display store name with icon in search results or references.
Common Patterns
Price Formatting
// Flutter
final priceInDollars = priceCents / 100;
'\$${priceInDollars.toStringAsFixed(2)}'
// TypeScript (Web)
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
}).format(cents / 100)
Stock Status Colors
Consistent color scheme:
- Error/Out of Stock: Red/error container
- Warning/Low Stock: Orange/amber
- Success/In Stock: Green/primary container
Condition Display
Only show condition badge when condition !== 'new'
Navigation Patterns
Mobile App
- Tap inventory item → Detail page
- Detail page → Edit mode
- POS page → Process transaction
Web
- Book card → Book detail page
- Store header → Store pages
- CTA buttons → Open BookWish app
Typography
Flutter Components
- Book Title:
AppTypography.bookTitle - Price:
AppTypography.cardLabelwith bold weight - Badge Text: 12px font size
- Metadata:
AppTypography.caption
Web Components
- Headings: Semibold, various sizes
- Body: Default sans-serif
- Store Name: Serif font for branding
- Labels: Uppercase tracking for small text
Color Palette
Flutter
- Primary:
AppColors.inkBlue - Success:
AppColors.forestGreen - Warning:
Colors.orange - Error:
AppColors.error/AppColors.coralSpine - Surface:
Colors.white - Background:
AppColors.parchment
Web
- Primary: Store-specific via
--store-primaryCSS variable - Dark:
#233548(ink blue) - Accent:
#FFC857(amber) - Background: White
- Border:
#E0D7C8(parchment) - Footer:
gray-900