Track, rate, and remember every wine you love.
Winectory is a personal wine journal web app. Log wines you've tried, rate them, write tasting notes, upload bottle photos, and build your own curated cellar — all stored locally in your browser.
- Track — Log wines with name, type, region, country, vintage year, tasting notes, and a photo
- Rate — Interactive 5-star rating on every card and in the add/edit modal
- Favorite — Star any wine to mark it as a favorite; filter your cellar to favorites only
- Search — Live search across wine name, type, region, and country
- Stats bar — At-a-glance totals: wines logged, average rating, favorites, and countries
- Add / Edit / Delete — Full CRUD via a modal dialog
- Persistent storage — All data is saved to
localStorage; your cellar survives page refreshes - Demo data — Three sample wines are seeded on first load so the app isn't empty
| Layer | Choice |
|---|---|
| Framework | Next.js 16 (App Router) |
| Language | TypeScript |
| Styling | Global CSS with CSS custom properties |
| State | React Context API + localStorage |
| Fonts | Cormorant Garamond · Montserrat (Google Fonts) |
winectory/
├── package.json
├── next.config.js
├── tsconfig.json
└── src/
├── app/
│ ├── layout.tsx # Root layout — metadata, providers, global CSS
│ ├── globals.css # All styles (design tokens, components, animations)
│ ├── page.tsx # / — Landing page
│ ├── auth/
│ │ └── page.tsx # /auth — Login & Sign-up
│ └── cellar/
│ └── page.tsx # /cellar — Main wine journal
├── components/
│ ├── Providers.tsx # Composes all context providers
│ ├── Toast.tsx # Toast notification context + component
│ ├── WineCard.tsx # Individual wine card (rating, fav, edit, delete)
│ ├── WineModal.tsx # Add / Edit modal form
│ ├── StarRating.tsx # Reusable interactive star rating
│ └── StatsBar.tsx # Aggregate stats across the cellar
├── context/
│ ├── AuthContext.tsx # Login / logout state
│ └── WineContext.tsx # Wines CRUD + localStorage persistence
└── lib/
├── types.ts # Wine, WineFormData, WineType interfaces
└── utils.ts # flagFor(), TYPE_CLASS map, demo seed data
- Node.js v18 or later
- npm, yarn, or pnpm
# 1. clone the project
git clone https://github.com/RemiHenry/Winectory.git
cd winectory
# 2. Install dependencies
npm install
# 3. Start the development server
npm run devOpen http://localhost:3000 in your browser.
npm run build
npm startThe public-facing home page. Introduces the three core features (Track, Favorite, Discover) and links to the auth page.
A single page that toggles between Log In and Sign Up modes. Credentials are not validated against a backend — any email/password pair grants access. Upon success the user is redirected to /cellar.
The main authenticated view. Contains:
- Stats bar — total wines, average rating, favorites count, countries represented
- Toolbar — Add Wine button, favorites filter toggle, live search input
- Wine grid — Responsive card grid; each card shows the bottle image (or a placeholder), name, country flag, star rating, type badge, region, vintage, and tasting notes
- Add / Edit modal — Form to create or update a wine entry
interface Wine {
id: string; // Date.now() string
name: string;
type: "Red" | "White" | "Rosé" | "Sparkling" | "Other";
region: string; // e.g. "Beaujolais"
country: string; // e.g. "France"
year: string; // Vintage year
notes: string; // Tasting notes
rating: number; // 0 – 5
img: string | null; // Base64 data URL from file upload
favorite: boolean;
added: number; // Unix timestamp
}All wines are stored as a JSON array under the key winectory_wines in localStorage.
Edit src/lib/utils.ts and add entries to the COUNTRY_FLAGS object:
export const COUNTRY_FLAGS: Record<string, string> = {
france: "🇫🇷",
// add more here…
};All colours are CSS custom properties defined at the top of src/app/globals.css:
:root {
--crimson-bright: #c0392b;
--gold: #c9a84c;
--bg: #0a0a0a;
/* … */
}- No real authentication — the auth flow is purely client-side. Do not use this as-is for a production app with sensitive data.
- localStorage only — data does not sync across devices or browsers.
- Images stored as base64 — large photos will increase
localStorageusage significantly. Consider an object-storage service (e.g. AWS S3, Cloudinary) for a production build.
MIT — free to use, modify, and distribute.