Style recipe list

This commit is contained in:
Anika Raemer 2025-09-13 08:41:07 +02:00
parent 568606213d
commit a50497426b
3 changed files with 45 additions and 34 deletions

View file

@ -8,22 +8,6 @@
@apply p-4 flex;
}
.sidebar {
@apply min-w-[16rem] bg-gray-50 p-4 w-1/3 border-r pr-4;
}
.sidebar-title {
@apply text-blue-900 font-bold mb-2;
}
.sidebar-link {
@apply block bg-white rounded-xl shadow-md overflow-hidden hover:shadow-lg transition w-full px-4 py-2 hover:bg-blue-100
}
.sidebar-item-text {
@apply font-semibold text-blue-400;
}
.content-title{
@apply text-3xl font-black mb-8 text-blue-400;
}

View file

@ -3,18 +3,38 @@ import { Link } from "react-router-dom"
type RecipeListItemProps = {
title: string
targetPath: string
imageUrl?: string
}
/**
* List item for the recipe list. Selecting an item navigates to the recipe
*/
export default function RecipeListItem({ title, targetPath: path}: RecipeListItemProps) {
export default function RecipeListItem({ title, targetPath, imageUrl }: RecipeListItemProps) {
return (
<Link
to={path}
className="sidebar-link"
to={targetPath}
className="h-60 w-60 block rounded-xl overflow-hidden shadow-md hover:shadow-lg transition-shadow bg-white dark:bg-gray-800"
>
<h2 className="sidebar-item-text">{title}</h2>
{/* Optional recipe image */}
{imageUrl ? (
<img
src={imageUrl}
alt={title}
className="w-full h-40 object-cover"
/>
)
: <div className="bg-gray-300 w-full h-40 flex justify-center items-center">
<label className="font-black text-gray-500" >no image</label>
</div>
}
{/* Card content */}
<div className="p-4">
<h2 className="text-lg font-semibold text-blue-400 dark:text-gray-100">
{title}
</h2>
</div>
</Link>
)
}

View file

@ -14,7 +14,7 @@ export default function RecipeListPage() {
useEffect(() => {
const loadRecipeList = async () => {
try {
// Fetch recipe data when editing an existing one
// Fetch recipe list
console.log("loading recipe list")
const data = await fetchRecipeList()
setRecipeList(data)
@ -26,19 +26,26 @@ export default function RecipeListPage() {
}, [])
if(!recipeList) { return <div>Unable to load recipes1</div>}
// @todo find a better representation than an oldfashioned sidebar
return (
<div className="sidebar">
<h1 className="sidebar-title">Recipes</h1>
<div className="flex flex-col gap-2">
{recipeList.map((recipe) => (
<RecipeListItem
key={recipe.id}
title = {recipe.title}
targetPath={'recipe/'+recipe.id}
/>
))}
/*Contaier spanning entire screen used to center content horizontally */
<div className="w-screen min-h-screen flex justify-center">
{/* Container defining the maximum width of the content */}
<div className="bg-gray-100 w-full min-h-screen max-w-5xl shadow-xl p-8">
{/* Header - remains in position when scrolling */}
<div className="sticky bg-gray-100 top-0 left-0 right-0 mb-4">
<h1 className="content-title text-blue-900">Recipes</h1>
<label>{recipeList.length} Recipes</label>
</div>
{/*Content - List of recipe cards */}
<div className="grid gap-6 grid-cols-[repeat(auto-fit,minmax(220px,1fr))]">
{recipeList.map((recipe) => (
<RecipeListItem
key={recipe.id}
title = {recipe.title}
targetPath={'recipe/'+recipe.id}
/>
))}
</div>
</div>
</div>
)