Style recipe list
This commit is contained in:
parent
568606213d
commit
a50497426b
3 changed files with 45 additions and 34 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,20 +26,27 @@ 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>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue