diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..9560d5b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,24 @@ +# Changelog + +All notable changes to Epicure are documented here. This file is mirrored in-app at `/changelog` (and in the admin dashboard) via `apps/web/lib/changelog.ts` — update both together. + +## 0.2.0 — 2026-07-12 + +### Added +- **Batch cooking**: generate a single "mega recipe" covering several meals at once — merged shopping list, steps tagged per dish (including steps that advance several dishes at once), and per-dish storage/reheat guidance. Available from the recipe list's Generate dialog and from the meal planner. +- **Leftover expiry reminders**: mark a batch-cook dish as cooked, track its fridge life, see it surfaced on the Pantry page, and get a daily reminder before it goes bad. +- **"Cooked it" photo reviews**: attach a photo and written review when rating a recipe. +- **Pantry-expiry recipe suggestions**: the Pantry page now surfaces recipes that use up ingredients about to expire. +- **Trending collections**: star public collections; browse trending and recently-added ones under Collections → Discover. +- **Add to collection from the recipe list**: select recipes and add them to a new or existing collection without leaving the page. +- List and compact view modes for the recipe list, alongside the existing grid view. + +### Fixed +- Recipe version-comparison diff was unreadable and partially untranslated. +- Print/export pages always render light, regardless of the app's dark/light setting. +- Presigned photo-upload URLs were signed against an internal-only address in production, breaking uploads. +- Several recipe-list and recipe-form UI issues: filter menu closing on every click, tag filter not accepting keystrokes, inconsistent card badge styling, missing tooltips, a floating save button on long recipe forms. + +## 0.1.0 — earlier + +Initial feature set: recipes (create, edit, AI-generate, import from URL/photo), meal planning, shopping lists, pantry tracking, collections, social features (follow, comment, rate, notifications), nutrition tracking, admin dashboard, and account/billing basics. diff --git a/apps/web/app/(app)/changelog/page.tsx b/apps/web/app/(app)/changelog/page.tsx new file mode 100644 index 0000000..87f76e2 --- /dev/null +++ b/apps/web/app/(app)/changelog/page.tsx @@ -0,0 +1,19 @@ +import type { Metadata } from "next"; +import { ChangelogList } from "@/components/shared/changelog-list"; +import { APP_VERSION } from "@/lib/changelog"; + +export const metadata: Metadata = {}; + +export default function ChangelogPage() { + return ( +
+
+

Changelog

+

Currently running v{APP_VERSION}.

+
+
+ +
+
+ ); +} diff --git a/apps/web/app/admin/changelog/page.tsx b/apps/web/app/admin/changelog/page.tsx new file mode 100644 index 0000000..65e248c --- /dev/null +++ b/apps/web/app/admin/changelog/page.tsx @@ -0,0 +1,17 @@ +import type { Metadata } from "next"; +import { ChangelogList } from "@/components/shared/changelog-list"; +import { APP_VERSION } from "@/lib/changelog"; + +export const metadata: Metadata = {}; + +export default function AdminChangelogPage() { + return ( +
+
+

Changelog

+

Currently running v{APP_VERSION}. Edit apps/web/lib/changelog.ts to update.

+
+ +
+ ); +} diff --git a/apps/web/app/admin/layout.tsx b/apps/web/app/admin/layout.tsx index 3176231..319a3f0 100644 --- a/apps/web/app/admin/layout.tsx +++ b/apps/web/app/admin/layout.tsx @@ -3,7 +3,7 @@ import { headers } from "next/headers"; import { auth } from "@/lib/auth/server"; import { db, users, eq } from "@epicure/db"; import Link from "next/link"; -import { Shield, Users, BookOpen, Settings, BarChart3, ClipboardList, HardDrive, Bot, ArrowLeft, Gauge, Mail, Flag } from "lucide-react"; +import { Shield, Users, BookOpen, Settings, BarChart3, ClipboardList, HardDrive, Bot, ArrowLeft, Gauge, Mail, Flag, History } from "lucide-react"; import { cn } from "@/lib/utils"; const adminNav = [ @@ -17,6 +17,7 @@ const adminNav = [ { href: "/admin/storage", label: "Storage", icon: HardDrive }, { href: "/admin/ai-config", label: "AI Config", icon: Bot }, { href: "/admin/settings", label: "Settings", icon: Settings }, + { href: "/admin/changelog", label: "Changelog", icon: History }, ]; export default async function AdminLayout({ children }: { children: React.ReactNode }) { diff --git a/apps/web/app/admin/page.tsx b/apps/web/app/admin/page.tsx index 0dc3147..1939c08 100644 --- a/apps/web/app/admin/page.tsx +++ b/apps/web/app/admin/page.tsx @@ -1,9 +1,11 @@ import type { Metadata } from "next"; +import Link from "next/link"; import { db } from "@epicure/db"; import { users, recipes, userUsage, recipePhotos } from "@epicure/db"; import { count, eq, sql } from "@epicure/db"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; -import { Users, BookOpen, Sparkles, Image } from "lucide-react"; +import { Users, BookOpen, Sparkles, Image, History } from "lucide-react"; +import { APP_VERSION, CHANGELOG } from "@/lib/changelog"; export const metadata: Metadata = {}; @@ -46,6 +48,22 @@ export default async function AdminPage() { ))} + + + + Version + + + +
v{APP_VERSION}
+

+ Released {CHANGELOG[0]?.date} ·{" "} + + View changelog + +

+
+
); } diff --git a/apps/web/components/layout/nav.tsx b/apps/web/components/layout/nav.tsx index f085419..a5b813a 100644 --- a/apps/web/components/layout/nav.tsx +++ b/apps/web/components/layout/nav.tsx @@ -3,7 +3,7 @@ import Link from "next/link"; import { usePathname, useRouter } from "next/navigation"; import { useTheme } from "next-themes"; -import { BookOpen, Calendar, Package, ChefHat, User, Rss, FolderOpen, ShoppingCart, Shield, Search, Compass, Menu, Sun, Moon, Monitor, Apple } from "lucide-react"; +import { BookOpen, Calendar, Package, ChefHat, User, Rss, FolderOpen, ShoppingCart, Shield, Search, Compass, Menu, Sun, Moon, Monitor, Apple, History } from "lucide-react"; import { cn } from "@/lib/utils"; import { Button, buttonVariants } from "@/components/ui/button"; import { @@ -131,6 +131,12 @@ export function Nav() { {t("settings")} + + + + {t("changelog")} + +
+ {CHANGELOG.map((entry, i) => ( +
+
+ v{entry.version} + {entry.date} +
+ + {entry.notes &&

{entry.notes}

} + + {entry.added && entry.added.length > 0 && ( +
+

Added

+
    + {entry.added.map((line, j) =>
  • {line}
  • )} +
+
+ )} + + {entry.fixed && entry.fixed.length > 0 && ( +
+

Fixed

+
    + {entry.fixed.map((line, j) =>
  • {line}
  • )} +
+
+ )} + + {i < CHANGELOG.length - 1 && } +
+ ))} +
+ ); +} diff --git a/apps/web/lib/changelog.ts b/apps/web/lib/changelog.ts new file mode 100644 index 0000000..b49a5df --- /dev/null +++ b/apps/web/lib/changelog.ts @@ -0,0 +1,37 @@ +// Mirrors CHANGELOG.md at the repo root — update both together. +export const APP_VERSION = "0.2.0"; + +export type ChangelogEntry = { + version: string; + date: string; + added?: string[]; + fixed?: string[]; + notes?: string; +}; + +export const CHANGELOG: ChangelogEntry[] = [ + { + version: "0.2.0", + date: "2026-07-12", + added: [ + "Batch cooking: generate a single \"mega recipe\" covering several meals at once — merged shopping list, steps tagged per dish, and per-dish storage/reheat guidance.", + "Leftover expiry reminders: mark a batch-cook dish as cooked, track its fridge life, and get a reminder before it goes bad.", + "\"Cooked it\" photo reviews: attach a photo and written review when rating a recipe.", + "Pantry-expiry recipe suggestions on the Pantry page.", + "Trending collections: star public collections, browse trending/recent under Collections → Discover.", + "Add to collection directly from the recipe list.", + "List and compact view modes for the recipe list.", + ], + fixed: [ + "Recipe version-comparison diff was unreadable and partially untranslated.", + "Print/export pages now always render light, regardless of app theme.", + "Presigned photo-upload URLs were signed against an internal-only address in production.", + "Recipe list/form UI issues: filter menu closing on every click, tag filter not accepting keystrokes, inconsistent badge styling, missing tooltips, floating save button on long forms.", + ], + }, + { + version: "0.1.0", + date: "earlier", + notes: "Initial feature set: recipes, meal planning, shopping lists, pantry tracking, collections, social features, nutrition tracking, admin dashboard, account/billing basics.", + }, +]; diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index b76aed3..fe4dd67 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -11,6 +11,7 @@ "pantry": "Pantry", "shopping": "Shopping", "settings": "Settings", + "changelog": "Changelog", "admin": "Admin", "signOut": "Sign out", "apiKeys": "API keys", diff --git a/apps/web/messages/fr.json b/apps/web/messages/fr.json index 73e0b0d..3f68aab 100644 --- a/apps/web/messages/fr.json +++ b/apps/web/messages/fr.json @@ -11,6 +11,7 @@ "pantry": "Garde-manger", "shopping": "Courses", "settings": "Paramètres", + "changelog": "Journal des modifications", "admin": "Admin", "signOut": "Se déconnecter", "apiKeys": "Clés API", diff --git a/apps/web/package.json b/apps/web/package.json index 4156f75..79553bd 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "@epicure/web", - "version": "0.1.0", + "version": "0.2.0", "private": true, "scripts": { "dev": "next dev", diff --git a/package.json b/package.json index 9d4e57c..03f7922 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "epicure", - "version": "0.0.0", + "version": "0.2.0", "private": true, "scripts": { "dev": "pnpm --filter web dev",