Skip to content

AhoyLemon/booz

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

327 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

kinda.fun

Last Deploy Live Site

Open Issues Closed Issues          Open PRs Closed PRs Commit Activity License: CC BY 4.0 Docs

A multi-tenant bar inventory and cocktail app built with Nuxt 3, supporting multiple bars with tenant-specific data from Cockpit CMS.

Features

  • Inventory Management: Track bottles with size, state, and images per tenant
  • Recipe Discovery: Find cocktails from your custom cocktails or The Cocktail DB
  • Smart Matching: See which drinks you can make with your current inventory
  • Non-Alcoholic Support: Includes mocktails, beer, and wine
  • Live Data: Fetches fresh data directly from Cockpit CMS API
  • Multi-Tenant Support: Host multiple bars with separate inventories and drinks using path-based routing

Made with

Vite Vue.js TypeScript Bun Sass Pug Vitest Prettier Cockpit JSON GitHub Pages

Multi-Tenant URLs

Once deployed, your tenants will be accessible at:

  • https://booz.bar/ (Home Page)
  • https://booz.bar/about - About Page
  • https://booz.bar/foo - Home page for a tenant named "foo"
  • https://booz.bar/foo/available - Available drinks for "foo" (follow similar structure for drinks, bottles, essentials, et al)

How It Works

The deployed site fetches data directly from your Cockpit CMS API at runtime. This means:

  • Visitors see fresh, up-to-date inventory and drink data
  • No need to rebuild/redeploy when data changes in Cockpit CMS
  • Updates to your CMS are immediately reflected on the live site
  • Each tenant fetches from their configured Cockpit collections

Data Structure

All TypeScript interfaces and types are defined in types/index.ts. This file contains comprehensive type definitions for:

  • Tenant Configuration - Multi-tenant setup and routing
  • Bar Data - Complete bar inventory structure
  • Bottles - Spirit inventory with detailed metadata
  • Drinks - Cocktail recipes with ingredients and instructions
  • Beer/Wine - Non-spirit bottle inventory
  • Bitters - Cocktail bitters and flavor profiles
  • Essentials - Bar essentials and mixers
  • Search Types - Omnisearch and drink search interfaces

The root data structure for each tenant is a BarData object containing arrays of bottles, drinks, beers, wines, bitters, and essentials.

For detailed field descriptions and comments, see the type definitions in types/index.ts.

Architecture

Multi-Tenant Routing

The app uses Nuxt's dynamic routing with a [tenant] parameter:

  • All pages are under /pages/[tenant]/
  • Middleware (middleware/tenant.global.ts) handles:
    • Non-tenant routes (home, about)
    • Redirecting root paths to default tenant
    • Validating tenant slugs
    • Showing error pages for unknown tenants

Data Fetching

All composables accept an optional tenant parameter:

const { fetchBottles, fetchDrinks } = useCockpitAPI(tenantSlug);
const { loadInventory } = useCocktails(tenantSlug);
const { loadBeerWine } = useBeerWine(tenantSlug);

State Management

Each tenant has isolated state using tenant-prefixed keys:

const inventory = useState(`${tenantSlug}_inventory`, () => []);

Testing

# With Bun
bun test

# Or with npm
npm test

Code Formatting

# With Bun
bun run format

# Or with npm
npm run format

Further Documentation

  • The docs folder
  • Tenant Configuration: See utils/tenants.ts for adding/modifying tenants
  • API Configuration: See utils/cockpitConfig.ts for Cockpit CMS settings
  • Copilot Instructions: See .github/copilot-instructions.md for AI development guidelines

License

CC-BY-4.0 - Creative Commons Attribution 4.0 International License

About

A custom created headless inventory and drink manager

Topics

Resources

License

Stars

Watchers

Forks

Contributors