From ee01558ca1bc6c7b8dd0dc29ca1f8bee04bf24c0 Mon Sep 17 00:00:00 2001 From: adelethorberg-sudo Date: Tue, 20 Oct 2026 13:45:19 +0200 Subject: [PATCH] feature/lag-siden-find-wine-by-food --- backend/src/index.ts | 94 +++++-- client/src/App.tsx | 3 + client/src/assets/food/cheese.jpg | Bin 0 -> 8018 bytes client/src/assets/food/dessert.jpg | Bin 0 -> 8164 bytes client/src/assets/food/fish.jpg | Bin 0 -> 8726 bytes client/src/assets/food/meat.jpg | Bin 0 -> 8846 bytes client/src/assets/food/pasta.jpg | Bin 0 -> 9654 bytes client/src/assets/food/poultry.jpg | Bin 0 -> 9157 bytes client/src/assets/food/snacks.jpg | Bin 0 -> 7837 bytes client/src/assets/food/spicy.jpg | Bin 0 -> 10005 bytes client/src/assets/food/vegetarian.jpg | Bin 0 -> 10163 bytes client/src/components/FindWineByFood.css | 342 +++++++++++++++++++++++ client/src/components/FindWineByFood.tsx | 227 +++++++++++++++ client/src/components/FoodWineCard.tsx | 151 ++++++++++ client/src/components/SiteHeader.tsx | 3 + client/src/data/food.ts | 91 ++++++ client/src/graphql/queries.ts | 56 ++++ client/src/index.css | 10 + client/src/types/wine.ts | 14 + 19 files changed, 970 insertions(+), 21 deletions(-) create mode 100644 client/src/assets/food/cheese.jpg create mode 100644 client/src/assets/food/dessert.jpg create mode 100644 client/src/assets/food/fish.jpg create mode 100644 client/src/assets/food/meat.jpg create mode 100644 client/src/assets/food/pasta.jpg create mode 100644 client/src/assets/food/poultry.jpg create mode 100644 client/src/assets/food/snacks.jpg create mode 100644 client/src/assets/food/spicy.jpg create mode 100644 client/src/assets/food/vegetarian.jpg create mode 100644 client/src/components/FindWineByFood.css create mode 100644 client/src/components/FindWineByFood.tsx create mode 100644 client/src/components/FoodWineCard.tsx create mode 100644 client/src/data/food.ts diff --git a/backend/src/index.ts b/backend/src/index.ts index b59e5f8..a06f4b6 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -26,6 +26,11 @@ function readPaging(args: { limit?: number; offset?: number }) { // Flere enn ca. 300 prikker blir uleselig og tungt å tegne. const TASTE_MAP_MAX = 300; +// Find wine by food: viner med minst så mange vurderinger kommer først. +// Ellers havner ukjente viner med én vurdering øverst, fordi de tilfeldigvis +// passer til flest retter i kategorien. +const FOOD_POPULAR_MIN = 50; + /** * ORDER BY for hver sortering i vinkatalogen. * Klienten sender bare navnet (enum WineSort), og SQL-en hentes herfra, @@ -223,6 +228,30 @@ const typeDefs = `#graphql type FoodCategory { name: String! wineCount: Int! + # Rettene i kategorien, verdier fra Harmonize, f.eks. ["Beef", "Lamb"] + foods: [String!]! + } + + # En vin på Find wine by food, med rettene i den valgte kategorien som + # vinen passer til ifølge Harmonize + type FoodWine { + id: ID! + name: String! + type: String! + abv: Float + body: String + acidity: String + winery: String! + region: String! + country: String! + avgRating: Float + ratingCount: Int! + matchedFoods: [String!]! + } + + type FoodWinePage { + items: [FoodWine!]! + totalCount: Int! } # Sortering i vinkatalogen @@ -304,11 +333,15 @@ const typeDefs = `#graphql foodCategories: [FoodCategory!]! + # Viner som passer til en matkategori. food snevrer inn til én rett i + # kategorien. De som passer til flest retter i kategorien kommer først, + # deretter de flest har vurdert. winesByFoodCategory( category: String! + food: String limit: Int = 20 offset: Int = 0 - ): WinePage! + ): FoodWinePage! # Viner til smakskartet. Bare viner med både fylde og syre kommer med. tasteMap(filter: TasteFilter, limit: Int = 100): WinePage! @@ -468,7 +501,10 @@ const resolvers = { foodCategories: async () => { const result = await pool.query( ` - SELECT f.category AS name, count(DISTINCT wf.wine_id)::int AS "wineCount" + SELECT + f.category AS name, + count(DISTINCT wf.wine_id)::int AS "wineCount", + array_agg(DISTINCT f.name ORDER BY f.name) AS foods FROM foods f JOIN wine_foods wf ON wf.food_id = f.id WHERE f.category IS NOT NULL @@ -481,46 +517,62 @@ const resolvers = { winesByFoodCategory: async ( _: unknown, - args: { category: string; limit?: number; offset?: number }, + args: { + category: string; + food?: string | null; + limit?: number; + offset?: number; + }, ) => { const { limit, offset } = readPaging(args); - const inCategory = ` - EXISTS ( - SELECT 1 - FROM wine_foods wf - JOIN foods f ON f.id = wf.food_id - WHERE wf.wine_id = w.id AND f.category = $1 - )`; + + // Én rad per vin, med rettene i kategorien vinen passer til. + // Med food må vinen passe til akkurat den retten, men listen viser + // fortsatt alle rettene i kategorien den passer til. + const matches = ` + SELECT wf.wine_id, array_agg(f.name ORDER BY f.name) AS foods + FROM wine_foods wf + JOIN foods f ON f.id = wf.food_id + WHERE f.category = $1 + GROUP BY wf.wine_id + HAVING $2::text IS NULL OR bool_or(f.name = $2::text)`; + const params = [args.category, args.food || null]; const winesResult = await pool.query( ` + WITH matches AS (${matches}) SELECT w.id, w.name, w.type, - w.abv, + w.abv::float AS abv, w.body, w.acidity, wi.name AS winery, r.name AS region, c.name AS country, - w.avg_rating AS "avgRating", - w.rating_count AS "ratingCount" - FROM wines w + w.avg_rating::float AS "avgRating", + w.rating_count AS "ratingCount", + m.foods AS "matchedFoods" + FROM matches m + JOIN wines w ON w.id = m.wine_id JOIN wineries wi ON w.winery_id = wi.id JOIN regions r ON w.region_id = r.id JOIN countries c ON w.country_code = c.code - WHERE ${inCategory} - ORDER BY w.name, w.id - LIMIT $2 - OFFSET $3 + ORDER BY + w.rating_count >= $3 DESC, + cardinality(m.foods) DESC, + w.rating_count DESC, + w.id + LIMIT $4 + OFFSET $5 `, - [args.category, limit, offset], + [...params, FOOD_POPULAR_MIN, limit, offset], ); const countResult = await pool.query( - `SELECT count(*)::int AS count FROM wines w WHERE ${inCategory}`, - [args.category], + `WITH matches AS (${matches}) SELECT count(*)::int AS count FROM matches`, + params, ); return { diff --git a/client/src/App.tsx b/client/src/App.tsx index 1249a83..be3fa02 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -2,6 +2,7 @@ import { Link, Route, Routes, useParams } from 'react-router'; import SiteHeader from './components/SiteHeader'; import ExploreByTaste from './components/ExploreByTaste'; import WineCatalog from './components/WineCatalog'; +import FindWineByFood from './components/FindWineByFood'; /** * NB: Temporary placeholder. The detail page is not built yet. @@ -24,6 +25,7 @@ function WineDetailsPlaceholder() { * * SiteHeader is shown on every page. Routes picks the page from the URL: * - / Explore by taste (front page) + * - /food Find wine by food * - /wines the wine catalog * - /wines/:id detail page (placeholder for now) * @@ -45,6 +47,7 @@ export default function App() { } /> + } /> } /> diff --git a/client/src/assets/food/cheese.jpg b/client/src/assets/food/cheese.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b681eb1cebdc9f1e2b40d21e29b48ae941747f39 GIT binary patch literal 8018 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 literal 0 HcmV?d00001 diff --git a/client/src/assets/food/dessert.jpg b/client/src/assets/food/dessert.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a42c4fe328fd509370c083312e54ef7ee604f4a7 GIT binary patch literal 8164 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 CmrR!c literal 0 HcmV?d00001 diff --git a/client/src/assets/food/meat.jpg b/client/src/assets/food/meat.jpg new file mode 100644 index 0000000000000000000000000000000000000000..752e0a810219e15a9e96e50bdae00f0619ca8fe4 GIT binary patch literal 8846 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 literal 0 HcmV?d00001 diff --git a/client/src/assets/food/pasta.jpg b/client/src/assets/food/pasta.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4d6e1104b93aed6d96c720b1919a18270c97c613 GIT binary patch literal 9654 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 QQy>Qmn#P?MB#WN=4+~o&ZU6uP literal 0 HcmV?d00001 diff --git a/client/src/assets/food/poultry.jpg b/client/src/assets/food/poultry.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2618c0497e8b08421c0aeff56407599267b48b60 GIT binary patch literal 9157 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 Uq9^^f1*H#Pu@=Oz65r1M2S}<800000 literal 0 HcmV?d00001 diff --git a/client/src/components/FindWineByFood.css b/client/src/components/FindWineByFood.css new file mode 100644 index 0000000..31409d5 --- /dev/null +++ b/client/src/components/FindWineByFood.css @@ -0,0 +1,342 @@ +/* + * Find wine by food. + * Colours come from the variables in index.css. + */ + +/* ---------- Hero ---------- */ + +.food-hero { + background: + radial-gradient(circle at 82% 50%, rgb(123 30 43 / 0.12), transparent 45%), + linear-gradient(90deg, var(--color-bg) 35%, var(--color-panel)); + border-bottom: 1px solid var(--color-border); +} + +.food-hero-inner { + max-width: 78rem; + margin: 0 auto; + padding: 3rem 1rem; +} + +.food-eyebrow { + margin: 0 0 0.4rem; + font-size: 0.75rem; + letter-spacing: 0.15em; + text-transform: uppercase; + color: var(--color-muted); +} + +.food-hero h1 { + margin: 0 0 0.5rem; + font-family: var(--font-display); + font-weight: 400; + font-size: clamp(2rem, 5vw, 3rem); + line-height: 1.1; + color: var(--color-text); +} + +.food-hero p:last-child { + margin: 0; + max-width: 28rem; + font-size: 1.1rem; + color: var(--color-muted); +} + +/* ---------- Page ---------- */ + +main.food-page { + max-width: 78rem; + display: grid; + gap: 2rem; + padding: 1.75rem 1rem 3rem; +} + +.food-page h2 { + margin: 0 0 1rem; + font-family: var(--font-display); + font-weight: 400; + font-size: 1.6rem; +} + +.food-note { + margin: 0; + font-size: 0.9rem; + color: var(--color-muted); +} + +/* ---------- Category cards ---------- */ + +.food-categories { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr)); + gap: 0.75rem; + margin: 0; + padding: 0; + list-style: none; +} + +.food-category { + width: 100%; + height: 100%; + display: grid; + justify-items: center; + gap: 0.15rem; + padding: 0.5rem 0.5rem 0.75rem; + border: 1px solid var(--color-border); + border-radius: 0.75rem; + background: var(--color-surface); + color: var(--color-text); + font: inherit; + cursor: pointer; + transition: + border-color 0.15s, + background 0.15s; +} + +.food-category:hover { + border-color: var(--color-muted); +} + +.food-category[aria-pressed='true'] { + border-color: var(--color-accent); + background: var(--color-panel); + box-shadow: inset 0 0 0 1px var(--color-accent); +} + +/* Photo tile at the top of the card */ +.food-category-image { + width: 100%; + height: 5.25rem; + margin-bottom: 0.35rem; + border-radius: 0.5rem; + object-fit: cover; +} + +/* Same height as the photos, so the names line up */ +.food-category-emoji { + display: grid; + place-items: center; + height: 5.25rem; + margin-bottom: 0.35rem; + font-size: 2.8rem; +} + +.food-category-name { + font-weight: 600; +} + +/* ---------- Dish chips ---------- */ + +.food-dishes { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.5rem; + margin-top: 1rem; +} + +.food-dishes-label { + margin-right: 0.25rem; + font-size: 0.85rem; + font-weight: 600; +} + +.food-dishes button { + padding: 0.35rem 0.85rem; + border: 1px solid var(--color-border); + border-radius: 999px; + background: var(--color-surface); + color: var(--color-text); + font: inherit; + font-size: 0.88rem; + cursor: pointer; +} + +.food-dishes button:hover { + border-color: var(--color-muted); +} + +.food-dishes button[aria-pressed='true'] { + border-color: var(--color-accent); + background: var(--color-accent); + color: var(--color-accent-ink); +} + +/* ---------- Results ---------- */ + +.food-results { + display: grid; + gap: 1rem; +} + +.food-results-head { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + align-items: baseline; + gap: 0.25rem 1rem; +} + +.food-results-head h2 { + margin: 0; + scroll-margin-top: 1rem; +} + +.food-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr)); + gap: 1rem; + margin: 0; + padding: 0; + list-style: none; +} + +.food-card { + height: 100%; + display: grid; + grid-template-columns: 4.5rem minmax(0, 1fr); + gap: 1rem; + padding: 1.1rem; + border: 1px solid var(--color-border); + border-radius: 0.75rem; + background: var(--color-surface); +} + +.food-bottle { + width: 100%; + height: auto; + max-height: 10rem; + align-self: center; +} + +.food-card-body { + display: grid; + align-content: start; + gap: 0.5rem; +} + +.food-card h3 { + margin: 0; + font-family: var(--font-display); + font-weight: 400; + font-size: 1.25rem; + line-height: 1.2; +} + +.food-card h3 a { + color: var(--color-text); + text-decoration: none; +} + +.food-card h3 a:hover { + color: var(--color-accent); + text-decoration: underline; +} + +.food-winery { + margin: -0.35rem 0 0; + font-size: 0.9rem; + color: var(--color-muted); +} + +/* "Pairs with" chip, in place of the "% match" chip in the sketch */ +.food-match { + justify-self: start; + margin: 0; + padding: 0.2rem 0.65rem; + border-radius: 999px; + background: var(--color-panel); + color: var(--color-accent); + font-size: 0.8rem; + font-weight: 600; +} + +.food-meta { + display: flex; + flex-wrap: wrap; + gap: 0.2rem 0.9rem; + margin: 0; + padding: 0; + list-style: none; + font-size: 0.82rem; + color: var(--color-muted); +} + +.food-meta li { + display: inline-flex; + align-items: center; + gap: 0.3rem; +} + +.food-meta svg { + width: 0.9rem; + height: 0.9rem; + color: var(--color-accent); +} + +.food-star { + color: var(--color-star); +} + +.food-bars { + display: grid; + gap: 0.35rem; + margin-top: 0.25rem; +} + +.food-bar-row { + display: grid; + grid-template-columns: 4.25rem 1fr; + align-items: center; + gap: 0.6rem; + font-size: 0.82rem; +} + +.food-bar { + height: 0.45rem; + overflow: hidden; + border-radius: 999px; + background: var(--color-sunk); +} + +.food-bar i { + display: block; + height: 100%; + border-radius: 999px; + background: var(--color-accent); +} + +/* ---------- Why this pairing works ---------- */ + +.food-why { + display: flex; + gap: 1.25rem; + align-items: flex-start; + padding: 1.25rem 1.5rem; + border-radius: 0.75rem; + background: var(--color-panel); +} + +.food-why svg { + flex: none; + width: 2.25rem; + height: 2.25rem; + color: var(--color-accent); +} + +.food-why h2 { + margin: 0 0 0.25rem; + font-size: 1.25rem; +} + +.food-why p { + margin: 0; + max-width: 50rem; + color: var(--color-muted); +} + +@media (prefers-reduced-motion: reduce) { + .food-category { + transition: none; + } +} diff --git a/client/src/components/FindWineByFood.tsx b/client/src/components/FindWineByFood.tsx new file mode 100644 index 0000000..53b0d11 --- /dev/null +++ b/client/src/components/FindWineByFood.tsx @@ -0,0 +1,227 @@ +import { useSearchParams } from 'react-router'; +import { useQuery } from '@apollo/client/react'; +import FoodWineCard from './FoodWineCard'; +import Pagination from './Pagination'; +import { + FOOD_CATEGORIES_QUERY, + WINES_BY_FOOD_QUERY, + type FoodCategoriesData, + type WinesByFoodData, +} from '../graphql/queries'; +import { + DEFAULT_FOOD_CATEGORY, + FOOD_CATEGORY_INFO, + FOOD_PAGE_SIZE, + foodCategoryOrder, +} from '../data/food'; +import './FindWineByFood.css'; + +/** + * Find wine by food. + * + * The user picks a food category (e.g. Meat), and can narrow it down to one + * dish (e.g. Beef). We show the wines that pair with it according to the + * Harmonize column in X-Wines, and explain why the pairing works. + * + * On purpose there are no wine filters or sorting here: the user chooses by + * food only. The backend decides the order: well-known wines (at least 50 + * ratings) that pair with the most dishes in the category come first. + * + * The choices live in the URL (?category=Meat&food=Beef&page=2), so the back + * button works and a search can be shared as a link. + */ +export default function FindWineByFood() { + const [params, setParams] = useSearchParams(); + const category = params.get('category') ?? DEFAULT_FOOD_CATEGORY; + const food = params.get('food'); + const page = Math.max(1, Number(params.get('page')) || 1); + + const categoriesQuery = useQuery(FOOD_CATEGORIES_QUERY); + const { data, previousData, loading, error } = useQuery( + WINES_BY_FOOD_QUERY, + { + variables: { + category, + food, + limit: FOOD_PAGE_SIZE, + offset: (page - 1) * FOOD_PAGE_SIZE, + }, + }, + ); + + const categories = [...(categoriesQuery.data?.foodCategories ?? [])].sort( + (a, b) => + foodCategoryOrder(a.name) - foodCategoryOrder(b.name) || + a.name.localeCompare(b.name), + ); + const current = categories.find((c) => c.name === category); + const info = FOOD_CATEGORY_INFO[category]; + const label = info?.label ?? category; + + // Keep showing the previous wines while new ones load, so the list + // doesn't flash empty on every click + const shown = (data ?? previousData)?.winesByFoodCategory; + const wines = shown?.items ?? []; + const totalPages = shown ? Math.ceil(shown.totalCount / FOOD_PAGE_SIZE) : 0; + + /** Changes the URL. A new category or dish starts at page 1. */ + function choose(next: { category?: string; food?: string | null }) { + const p = new URLSearchParams(); + p.set('category', next.category ?? category); + const nextFood = next.category ? null : (next.food ?? null); + if (nextFood) p.set('food', nextFood); + setParams(p); + } + + function goToPage(n: number) { + const p = new URLSearchParams(params); + p.set('page', String(n)); + setParams(p); + document + .getElementById('food-results-heading') + ?.scrollIntoView({ block: 'start' }); + } + + return ( + <> +
+
+

Explore

+

Find wine by food

+

+ Choose what you’re eating and discover wines that make it even + better. +

+
+
+ +
+
+

Choose a food category

+ {categoriesQuery.error && ( +

Could not load the food categories.

+ )} +
    + {categories.map((c) => { + const cInfo = FOOD_CATEGORY_INFO[c.name]; + return ( +
  • + +
  • + ); + })} +
+ + {current && current.foods.length > 1 && ( +
+ + + {current.foods.map((f) => ( + + ))} +
+ )} +
+ +
+
+

Best matches for {food ?? label}

+ {/* role="status" announces the new count when the choice changes */} +

+ {!shown + ? 'Loading wines …' + : `${shown.totalCount.toLocaleString('en')} ${shown.totalCount === 1 ? 'wine' : 'wines'} pair with ${food ?? label.toLowerCase()}`} +

+
+ + {error && ( +

Could not load wines. Please try again later.

+ )} + {shown && wines.length === 0 && ( +

No wines pair with this food yet.

+ )} + +
    + {wines.map((w) => ( +
  • + +
  • + ))} +
+ + +
+ + {info && ( + + )} +
+ + ); +} diff --git a/client/src/components/FoodWineCard.tsx b/client/src/components/FoodWineCard.tsx new file mode 100644 index 0000000..225e1a9 --- /dev/null +++ b/client/src/components/FoodWineCard.tsx @@ -0,0 +1,151 @@ +import { Link } from 'react-router'; +import type { FoodWine } from '../types/wine'; +import { ACIDITY_LEVELS, BODY_LEVELS, wineTypeColor } from '../data/taste'; + +/** + * A wine bottle in the colour of the wine type. Decorative only. + * X-Wines has no pictures of the wines, so we draw one. + */ +function Bottle({ type }: { type: string }) { + return ( + + ); +} + +/** One row with label and bar, e.g. "Body ████░". The exact value is read by screen readers and shown on hover. */ +function Bar(props: { label: string; share: number; value: string }) { + return ( +
+ {props.label} +
+ +
+
+ ); +} + +/** + * A card on Find wine by food: the wine, where it is from, which dishes in + * the chosen category it pairs with, and its taste. + * + * Display only, like WineList: it gets the wine as a prop. + */ +export default function FoodWineCard({ wine }: { wine: FoodWine }) { + return ( +
+ + +
+

+ {/* + NB: The detail page (/wines/:id) is not built yet. Until then this + link opens a placeholder page, see App.tsx. + */} + {wine.name} +

+

{wine.winery}

+ +

+ Pairs with + {wine.matchedFoods.join(', ')} +

+ +
    +
  • + + {wine.region}, {wine.country} +
  • +
  • + + {wine.type} wine +
  • +
  • + + {wine.avgRating != null + ? `${wine.avgRating.toFixed(1)} (${wine.ratingCount.toLocaleString('en')} ratings)` + : 'No ratings yet'} +
  • +
+ +
+ {wine.body && ( + + )} + {wine.acidity && ( + + )} + {wine.abv != null && ( + + )} +
+
+
+ ); +} diff --git a/client/src/components/SiteHeader.tsx b/client/src/components/SiteHeader.tsx index a348fda..18bb0eb 100644 --- a/client/src/components/SiteHeader.tsx +++ b/client/src/components/SiteHeader.tsx @@ -39,6 +39,9 @@ export default function SiteHeader() {
  • Wines
  • +
  • + Food pairing +
  • diff --git a/client/src/data/food.ts b/client/src/data/food.ts new file mode 100644 index 0000000..e79e3d7 --- /dev/null +++ b/client/src/data/food.ts @@ -0,0 +1,91 @@ +import pastaImage from '../assets/food/pasta.jpg'; +import meatImage from '../assets/food/meat.jpg'; +import fishImage from '../assets/food/fish.jpg'; +import poultryImage from '../assets/food/poultry.jpg'; +import cheeseImage from '../assets/food/cheese.jpg'; +import vegetarianImage from '../assets/food/vegetarian.jpg'; +import spicyImage from '../assets/food/spicy.jpg'; +import snacksImage from '../assets/food/snacks.jpg'; +import dessertImage from '../assets/food/dessert.jpg'; + +/** + * Constants for Find wine by food. + * In their own file (not in a component file) so that React Fast Refresh + * keeps working, the same reason as graphql/queries.ts. + */ + +/** How many wines are shown per page. Three columns, three rows. */ +export const FOOD_PAGE_SIZE = 9; + +/** The category that is selected when the page opens. */ +export const DEFAULT_FOOD_CATEGORY = 'Pasta, pizza & stews'; + +type FoodCategoryInfo = { + /** Short name on the category card */ + label: string; + /** Photo on the card (AI-generated in Canva, on a light background) */ + image: string; + /** Text in the "Why this pairing works" box */ + why: string; +}; + +/** + * Display text for each category. The names (keys) must match + * foods.category in the database, see backend/db/seeds/food_categories.sql. + * The order here is the order of the cards. Categories from the backend + * that are not listed here come last, with their database name as label + * and a plate emoji instead of a photo. + */ +export const FOOD_CATEGORY_INFO: Record = { + 'Pasta, pizza & stews': { + label: 'Pasta & pizza', + image: pastaImage, + why: 'Tomato sauces, cheese and slow-cooked stews are rich and savoury. Wines with bright acidity and moderate tannins cut through the richness and match the acidity of the tomatoes, so every bite feels balanced.', + }, + Meat: { + label: 'Meat', + image: meatImage, + why: 'Red meat is full of fat and protein, which soften the tannins in red wine. A full-bodied wine stands up to grilled and roasted flavours, while the tannins clean the palate between bites.', + }, + 'Fish & seafood': { + label: 'Fish & seafood', + image: fishImage, + why: 'Fish and shellfish are delicate and often served with lemon. Light, fresh wines with good acidity lift the flavours without overpowering them, while heavy tannins can make fish taste metallic.', + }, + Poultry: { + label: 'Poultry', + image: poultryImage, + why: 'Chicken and other poultry are mild and work with many styles. Medium-bodied whites and lighter reds follow the sauce and seasoning without hiding the meat.', + }, + Cheese: { + label: 'Cheese', + image: cheeseImage, + why: 'Cheese is salty and creamy. Acidity cuts through the fat, and sweet or fortified wines balance the salt in strong and blue cheeses. Fresh goat cheese loves crisp whites.', + }, + Vegetarian: { + label: 'Vegetarian', + image: vegetarianImage, + why: 'Vegetables, salads and mushrooms are lighter and often earthy or green. Fresh, aromatic wines match green flavours, and soft reds go well with mushrooms.', + }, + 'Spicy food': { + label: 'Spicy food', + image: spicyImage, + why: 'Heat from chili is made stronger by alcohol and tannins. Wines with a little sweetness, lower alcohol and plenty of fruit cool the burn and balance the spices.', + }, + 'Snacks & starters': { + label: 'Snacks & starters', + image: snacksImage, + why: 'Starters, cured meat and salty snacks need a wine that refreshes. Sparkling and light, crisp wines clean the palate and wake up the appetite before the meal.', + }, + Dessert: { + label: 'Dessert', + image: dessertImage, + why: 'The wine should be at least as sweet as the dessert, or it will taste sour and thin. Sweet and fortified wines match cake, fruit and chocolate.', + }, +}; + +/** Sort key for a category: its place in FOOD_CATEGORY_INFO, unknown last. */ +export function foodCategoryOrder(name: string): number { + const index = Object.keys(FOOD_CATEGORY_INFO).indexOf(name); + return index === -1 ? Infinity : index; +} diff --git a/client/src/graphql/queries.ts b/client/src/graphql/queries.ts index ea42253..6f0ffff 100644 --- a/client/src/graphql/queries.ts +++ b/client/src/graphql/queries.ts @@ -1,6 +1,8 @@ import { gql } from '@apollo/client'; import type { CatalogFilter, + FoodCategory, + FoodWine, TasteWine, WineListItem, WineSort, @@ -179,3 +181,57 @@ export const WINE_GRAPES_QUERY = gql` export type WineGrapesData = { wine: { id: string; grapes: string[]; vintages: number[] } | null; }; + +/** The food categories on Find wine by food, with their dishes. */ +export const FOOD_CATEGORIES_QUERY = gql` + query FoodCategories { + foodCategories { + name + foods + } + } +`; + +export type FoodCategoriesData = { + foodCategories: FoodCategory[]; +}; + +/** + * One page of wines that pair with a food category. + * food narrows it down to one dish in the category (null = all dishes). + */ +export const WINES_BY_FOOD_QUERY = gql` + query WinesByFood( + $category: String! + $food: String + $offset: Int + $limit: Int + ) { + winesByFoodCategory( + category: $category + food: $food + offset: $offset + limit: $limit + ) { + totalCount + items { + id + name + type + winery + region + country + avgRating + ratingCount + abv + body + acidity + matchedFoods + } + } + } +`; + +export type WinesByFoodData = { + winesByFoodCategory: { totalCount: number; items: FoodWine[] }; +}; diff --git a/client/src/index.css b/client/src/index.css index 27e139c..7e3afda 100644 --- a/client/src/index.css +++ b/client/src/index.css @@ -72,3 +72,13 @@ h1 { outline: 3px solid var(--color-accent); outline-offset: 2px; } + +/* Text only for screen readers, hidden on screen */ +.sr-only { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; +} diff --git a/client/src/types/wine.ts b/client/src/types/wine.ts index 95c8dbb..277a49c 100644 --- a/client/src/types/wine.ts +++ b/client/src/types/wine.ts @@ -77,3 +77,17 @@ export type TasteFilter = { /** Only wines with at least 100 ratings */ popularOnly: boolean; }; + +/** A food category on Find wine by food, e.g. 'Meat' with its dishes. */ +export type FoodCategory = { + name: string; + /** The dishes in the category, from Harmonize in X-Wines */ + foods: string[]; +}; + +/** A wine on Find wine by food. */ +export type FoodWine = WineListItem & { + ratingCount: number; + /** The dishes in the chosen category that the wine pairs with */ + matchedFoods: string[]; +};