Add favorite indicators to recipe cards and improve favorites UI
All checks were successful
CI / update (push) Successful in 17s
All checks were successful
CI / update (push) Successful in 17s
- Add heart emoji indicators to recipe cards (top-left positioning) - Show favorites across all recipe list pages (season, category, icon, tag) - Create favorites utility functions for server-side data merging - Convert client-side load files to server-side for session access - Redesign favorite button with emoji hearts (🖤/❤️) and bottom-right positioning - Fix randomizer array mutation issue causing card display glitches - Implement consistent favorite indicators with drop shadows for visibility 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,13 +1,22 @@
|
||||
import type { PageServerLoad } from "./$types";
|
||||
import { getUserFavorites, addFavoriteStatusToRecipes } from "$lib/server/favorites";
|
||||
|
||||
export async function load({ fetch }) {
|
||||
export async function load({ fetch, locals }) {
|
||||
let current_month = new Date().getMonth() + 1
|
||||
const res_season = await fetch(`/api/rezepte/items/in_season/` + current_month);
|
||||
const res_all_brief = await fetch(`/api/rezepte/items/all_brief`);
|
||||
const item_season = await res_season.json();
|
||||
const item_all_brief = await res_all_brief.json();
|
||||
|
||||
// Get user favorites and session
|
||||
const [userFavorites, session] = await Promise.all([
|
||||
getUserFavorites(fetch, locals),
|
||||
locals.auth()
|
||||
]);
|
||||
|
||||
return {
|
||||
season: item_season,
|
||||
all_brief: item_all_brief,
|
||||
season: addFavoriteStatusToRecipes(item_season, userFavorites),
|
||||
all_brief: addFavoriteStatusToRecipes(item_all_brief, userFavorites),
|
||||
session
|
||||
};
|
||||
};
|
||||
|
@@ -36,14 +36,14 @@ h1{
|
||||
|
||||
<MediaScroller title="In Saison">
|
||||
{#each data.season as recipe}
|
||||
<Card {recipe} {current_month} loading_strat={"eager"} do_margin_right={true}></Card>
|
||||
<Card {recipe} {current_month} loading_strat={"eager"} do_margin_right={true} isFavorite={recipe.isFavorite} showFavoriteIndicator={!!data.session?.user}></Card>
|
||||
{/each}
|
||||
</MediaScroller>
|
||||
|
||||
{#each categories as category}
|
||||
<MediaScroller title={category}>
|
||||
{#each data.all_brief.filter(recipe => recipe.category == category) as recipe}
|
||||
<Card {recipe} {current_month} do_margin_right={true}></Card>
|
||||
<Card {recipe} {current_month} do_margin_right={true} isFavorite={recipe.isFavorite} showFavoriteIndicator={!!data.session?.user}></Card>
|
||||
{/each}
|
||||
</MediaScroller>
|
||||
{/each}
|
||||
|
@@ -310,13 +310,11 @@ h4{
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<div class="tags center">
|
||||
<FavoriteButton
|
||||
recipeId={data.short_name}
|
||||
isFavorite={data.isFavorite || false}
|
||||
isLoggedIn={!!data.session?.user}
|
||||
/>
|
||||
</div>
|
||||
<FavoriteButton
|
||||
recipeId={data.short_name}
|
||||
isFavorite={data.isFavorite || false}
|
||||
isLoggedIn={!!data.session?.user}
|
||||
/>
|
||||
|
||||
{#if data.note}
|
||||
<RecipeNote note={data.note}></RecipeNote>
|
||||
|
19
src/routes/rezepte/category/[category]/+page.server.ts
Normal file
19
src/routes/rezepte/category/[category]/+page.server.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { PageServerLoad } from "./$types";
|
||||
import { getUserFavorites, addFavoriteStatusToRecipes } from "$lib/server/favorites";
|
||||
|
||||
export const load: PageServerLoad = async ({ fetch, locals, params }) => {
|
||||
const res = await fetch(`/api/rezepte/items/category/${params.category}`);
|
||||
const items = await res.json();
|
||||
|
||||
// Get user favorites and session
|
||||
const [userFavorites, session] = await Promise.all([
|
||||
getUserFavorites(fetch, locals),
|
||||
locals.auth()
|
||||
]);
|
||||
|
||||
return {
|
||||
category: params.category,
|
||||
recipes: addFavoriteStatusToRecipes(items, userFavorites),
|
||||
session
|
||||
};
|
||||
};
|
@@ -18,7 +18,7 @@
|
||||
<section>
|
||||
<Recipes>
|
||||
{#each rand_array(data.recipes) as recipe}
|
||||
<Card {recipe} {current_month}></Card>
|
||||
<Card {recipe} {current_month} isFavorite={recipe.isFavorite} showFavoriteIndicator={!!data.session?.user}></Card>
|
||||
{/each}
|
||||
</Recipes>
|
||||
</section>
|
||||
|
@@ -1,10 +0,0 @@
|
||||
import type { PageLoad } from "./$types";
|
||||
|
||||
export async function load({ fetch, params }) {
|
||||
const res = await fetch(`/api/rezepte/items/category/${params.category}`);
|
||||
const items = await res.json();
|
||||
return {
|
||||
category: params.category,
|
||||
recipes: items
|
||||
}
|
||||
};
|
@@ -47,7 +47,7 @@ h1{
|
||||
{:else if data.favorites.length > 0}
|
||||
<Recipes>
|
||||
{#each data.favorites as recipe}
|
||||
<Card {recipe} {current_month}></Card>
|
||||
<Card {recipe} {current_month} isFavorite={true} showFavoriteIndicator={true}></Card>
|
||||
{/each}
|
||||
</Recipes>
|
||||
{:else}
|
||||
|
22
src/routes/rezepte/icon/[icon]/+page.server.ts
Normal file
22
src/routes/rezepte/icon/[icon]/+page.server.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import type { PageServerLoad } from "./$types";
|
||||
import { getUserFavorites, addFavoriteStatusToRecipes } from "$lib/server/favorites";
|
||||
|
||||
export const load: PageServerLoad = async ({ fetch, locals, params }) => {
|
||||
const res_season = await fetch(`/api/rezepte/items/icon/` + params.icon);
|
||||
const res_icons = await fetch(`/api/rezepte/items/icon`);
|
||||
const icons = await res_icons.json();
|
||||
const item_season = await res_season.json();
|
||||
|
||||
// Get user favorites and session
|
||||
const [userFavorites, session] = await Promise.all([
|
||||
getUserFavorites(fetch, locals),
|
||||
locals.auth()
|
||||
]);
|
||||
|
||||
return {
|
||||
icons: icons,
|
||||
icon: params.icon,
|
||||
season: addFavoriteStatusToRecipes(item_season, userFavorites),
|
||||
session
|
||||
};
|
||||
};
|
@@ -11,7 +11,7 @@
|
||||
<IconLayout icons={data.icons} active_icon={data.icon} >
|
||||
<Recipes slot=recipes>
|
||||
{#each rand_array(data.season) as recipe}
|
||||
<Card {recipe} icon_override=true></Card>
|
||||
<Card {recipe} icon_override=true isFavorite={recipe.isFavorite} showFavoriteIndicator={!!data.session?.user}></Card>
|
||||
{/each}
|
||||
</Recipes>
|
||||
</IconLayout>
|
||||
|
@@ -1,13 +0,0 @@
|
||||
import type { PageLoad } from "./$types";
|
||||
|
||||
export async function load({ fetch, params }) {
|
||||
const res_season = await fetch(`/api/rezepte/items/icon/` + params.icon);
|
||||
const res_icons = await fetch(`/api/rezepte/items/icon`);
|
||||
const icons = await res_icons.json();
|
||||
const item_season = await res_season.json();
|
||||
return {
|
||||
icons: icons,
|
||||
icon: params.icon,
|
||||
season: item_season,
|
||||
};
|
||||
};
|
19
src/routes/rezepte/season/+page.server.ts
Normal file
19
src/routes/rezepte/season/+page.server.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { PageServerLoad } from "./$types";
|
||||
import { getUserFavorites, addFavoriteStatusToRecipes } from "$lib/server/favorites";
|
||||
|
||||
export const load: PageServerLoad = async ({ fetch, locals }) => {
|
||||
let current_month = new Date().getMonth() + 1
|
||||
const res_season = await fetch(`/api/rezepte/items/in_season/` + current_month);
|
||||
const item_season = await res_season.json();
|
||||
|
||||
// Get user favorites and session
|
||||
const [userFavorites, session] = await Promise.all([
|
||||
getUserFavorites(fetch, locals),
|
||||
locals.auth()
|
||||
]);
|
||||
|
||||
return {
|
||||
season: addFavoriteStatusToRecipes(item_season, userFavorites),
|
||||
session
|
||||
};
|
||||
};
|
@@ -14,7 +14,7 @@
|
||||
<SeasonLayout active_index={current_month-1}>
|
||||
<Recipes slot=recipes>
|
||||
{#each rand_array(data.season) as recipe}
|
||||
<Card {recipe} {current_month}></Card>
|
||||
<Card {recipe} {current_month} isFavorite={recipe.isFavorite} showFavoriteIndicator={!!data.session?.user}></Card>
|
||||
{/each}
|
||||
</Recipes>
|
||||
</SeasonLayout>
|
||||
|
@@ -1,10 +0,0 @@
|
||||
import type { PageLoad } from "./$types";
|
||||
|
||||
export async function load({ fetch }) {
|
||||
let current_month = new Date().getMonth() + 1
|
||||
const res_season = await fetch(`/api/rezepte/items/in_season/` + current_month);
|
||||
const item_season = await res_season.json();
|
||||
return {
|
||||
season: item_season,
|
||||
};
|
||||
};
|
19
src/routes/rezepte/season/[month]/+page.server.ts
Normal file
19
src/routes/rezepte/season/[month]/+page.server.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { PageServerLoad } from "./$types";
|
||||
import { getUserFavorites, addFavoriteStatusToRecipes } from "$lib/server/favorites";
|
||||
|
||||
export const load: PageServerLoad = async ({ fetch, locals, params }) => {
|
||||
const res_season = await fetch(`/api/rezepte/items/in_season/` + params.month);
|
||||
const item_season = await res_season.json();
|
||||
|
||||
// Get user favorites and session
|
||||
const [userFavorites, session] = await Promise.all([
|
||||
getUserFavorites(fetch, locals),
|
||||
locals.auth()
|
||||
]);
|
||||
|
||||
return {
|
||||
month: params.month,
|
||||
season: addFavoriteStatusToRecipes(item_season, userFavorites),
|
||||
session
|
||||
};
|
||||
};
|
@@ -12,7 +12,7 @@
|
||||
<SeasonLayout active_index={data.month -1}>
|
||||
<Recipes slot=recipes>
|
||||
{#each rand_array(data.season) as recipe}
|
||||
<Card {recipe} icon_override=true></Card>
|
||||
<Card {recipe} icon_override=true isFavorite={recipe.isFavorite} showFavoriteIndicator={!!data.session?.user}></Card>
|
||||
{/each}
|
||||
</Recipes>
|
||||
</SeasonLayout>
|
||||
|
@@ -1,12 +0,0 @@
|
||||
import type { PageLoad } from "./$types";
|
||||
|
||||
export async function load({ fetch, params }) {
|
||||
const res_season = await fetch(`/api/rezepte/items/in_season/` + params.month);
|
||||
const res_all_brief = await fetch(`/api/rezepte/items/all_brief`);
|
||||
const item_season = await res_season.json();
|
||||
const item_all_brief = await res_all_brief.json();
|
||||
return {
|
||||
month: params.month,
|
||||
season: item_season,
|
||||
};
|
||||
};
|
19
src/routes/rezepte/tag/[tag]/+page.server.ts
Normal file
19
src/routes/rezepte/tag/[tag]/+page.server.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { PageServerLoad } from "./$types";
|
||||
import { getUserFavorites, addFavoriteStatusToRecipes } from "$lib/server/favorites";
|
||||
|
||||
export const load: PageServerLoad = async ({ fetch, locals, params }) => {
|
||||
const res_tag = await fetch(`/api/rezepte/items/tag/${params.tag}`);
|
||||
const items_tag = await res_tag.json();
|
||||
|
||||
// Get user favorites and session
|
||||
const [userFavorites, session] = await Promise.all([
|
||||
getUserFavorites(fetch, locals),
|
||||
locals.auth()
|
||||
]);
|
||||
|
||||
return {
|
||||
tag: params.tag,
|
||||
recipes: addFavoriteStatusToRecipes(items_tag, userFavorites),
|
||||
session
|
||||
};
|
||||
};
|
@@ -18,7 +18,7 @@
|
||||
<section>
|
||||
<Recipes>
|
||||
{#each rand_array(data.recipes) as recipe}
|
||||
<Card {recipe} {current_month}></Card>
|
||||
<Card {recipe} {current_month} isFavorite={recipe.isFavorite} showFavoriteIndicator={!!data.session?.user}></Card>
|
||||
{/each}
|
||||
</Recipes>
|
||||
</section>
|
||||
|
@@ -1,10 +0,0 @@
|
||||
import type { PageLoad } from "./$types";
|
||||
|
||||
export async function load({ fetch, params }) {
|
||||
const res_tag = await fetch(`/api/rezepte/items/tag/${params.tag}`);
|
||||
const items_tag = await res_tag.json();
|
||||
return {
|
||||
tag: params.tag,
|
||||
recipes: items_tag
|
||||
}
|
||||
};
|
Reference in New Issue
Block a user