Compare commits

..

No commits in common. "a10f3e37c2d5dd33cbb53a7e51c835251d7955bf" and "a50497426b0471f19ff8ba459ce4ba6712f2db60" have entirely different histories.

5 changed files with 27 additions and 64 deletions

View file

@ -2,7 +2,6 @@ import { BrowserRouter as Router, Routes, Route } from "react-router-dom"
import RecipeDetailPage from "./components/recipes/RecipeDetailPage" import RecipeDetailPage from "./components/recipes/RecipeDetailPage"
import RecipeEditPage from "./components/recipes/RecipeEditPage" import RecipeEditPage from "./components/recipes/RecipeEditPage"
import RecipeListPage from "./components/recipes/RecipeListPage" import RecipeListPage from "./components/recipes/RecipeListPage"
import { getRecipeAddUrlDefinition, getRecipeDetailsUrlDefinition, getRecipeEditUrlDefinition, getRootUrlDefinition } from "./routes"
import "./App.css" import "./App.css"
@ -15,16 +14,13 @@ function App() {
<Router> <Router>
<Routes> <Routes>
{/* Home page: list of recipes */} {/* Home page: list of recipes */}
<Route path= {getRootUrlDefinition()} element={<RecipeListPage />} /> <Route path="/" element={<RecipeListPage />} />
{/* Detail page: shows one recipe */} {/* Detail page: shows one recipe */}
<Route path={getRecipeDetailsUrlDefinition()} element={<RecipeDetailPage />} /> <Route path="/recipe/:id" element={<RecipeDetailPage />} />
{/* Edit page: form to edit a recipe */} {/* Edit page: form to edit a recipe */}
<Route path={getRecipeEditUrlDefinition()} element={<RecipeEditPage />} /> <Route path="/recipe/:id/edit" element={<RecipeEditPage />} />
{/* Add page: form to add a recipe */}
<Route path={getRecipeAddUrlDefinition()} element={<RecipeEditPage />} />
</Routes> </Routes>
</Router> </Router>
) )

View file

@ -2,7 +2,6 @@ import { useParams, Link } from "react-router-dom"
import type { Recipe } from "../../types/recipe" import type { Recipe } from "../../types/recipe"
import { useEffect, useState } from "react" import { useEffect, useState } from "react"
import { fetchRecipe } from "../../api/recipePoint" import { fetchRecipe } from "../../api/recipePoint"
import { getRecipeEditUrl, getRecipeListUrl } from "../../routes"
/** /**
@ -124,13 +123,13 @@ export default function RecipeDetailPage() {
{/* Action buttons */} {/* Action buttons */}
<div className="button-group"> <div className="button-group">
<Link <Link
to={ getRecipeEditUrl(recipe.id) } to={`/recipe/${recipe.id}/edit`}
className="primary-button" className="primary-button"
> >
Bearbeiten Bearbeiten
</Link> </Link>
<Link <Link
to={getRecipeListUrl()} to="/"
className="default-button" className="default-button"
> >
Zurueck Zurueck

View file

@ -3,7 +3,6 @@ import { useEffect, useState } from "react"
import type { Recipe } from "../../types/recipe" import type { Recipe } from "../../types/recipe"
import RecipeEditor from "./RecipeEditor" import RecipeEditor from "./RecipeEditor"
import { fetchRecipe, createRecipe, updateRecipe } from "../../api/recipePoint" import { fetchRecipe, createRecipe, updateRecipe } from "../../api/recipePoint"
import { getRecipeDetailUrl, getRecipeListUrl, getRootUrl } from "../../routes"
export default function RecipeEditPage() { export default function RecipeEditPage() {
// Extract recipe ID from route params // Extract recipe ID from route params
@ -63,10 +62,10 @@ export default function RecipeEditPage() {
const navigateBack = () => { const navigateBack = () => {
if(recipe && recipe.id){ if(recipe && recipe.id){
console.log("navigating to recipe with id", recipe.id) console.log("navigating to recipe with id", recipe.id)
navigate(getRecipeDetailUrl(recipe.id)) // go back to detail view navigate("/recipe/" + recipe.id) // go back to detail view
} else { } else {
console.log("navigating back to list as no recipe was selected") console.log("navigating back to list as no recipe was selected")
navigate(getRecipeListUrl()) // no recipe -> go back to list navigate("/") // no recipe -> go back to list
} }
} }
// error handling -> if there is no recipe, we cannot open edit view // error handling -> if there is no recipe, we cannot open edit view

View file

@ -2,8 +2,6 @@ import { useEffect, useState } from "react"
import RecipeListItem from "./RecipeListItem" import RecipeListItem from "./RecipeListItem"
import type { Recipe } from "../../types/recipe" import type { Recipe } from "../../types/recipe"
import { fetchRecipeList } from "../../api/recipePoint" import { fetchRecipeList } from "../../api/recipePoint"
import { useNavigate } from "react-router-dom"
import { getRecipeAddUrl, getRecipeAddUrlDefinition, getRecipeDetailUrl } from "../../routes"
/** /**
* Displays a list of recipes in a sidebar layout. * Displays a list of recipes in a sidebar layout.
@ -11,7 +9,6 @@ import { getRecipeAddUrl, getRecipeAddUrlDefinition, getRecipeDetailUrl } from "
*/ */
export default function RecipeListPage() { export default function RecipeListPage() {
const navigate = useNavigate()
const [recipeList, setRecipeList] = useState<Recipe[]|null>(null) const [recipeList, setRecipeList] = useState<Recipe[]|null>(null)
// load recipes once on render // load recipes once on render
useEffect(() => { useEffect(() => {
@ -28,37 +25,24 @@ export default function RecipeListPage() {
loadRecipeList() loadRecipeList()
}, []) }, [])
const handleAdd = () => { if(!recipeList) { return <div>Unable to load recipes1</div>}
navigate(getRecipeAddUrl())
}
if(!recipeList) { return <div>Unable to load recipes!</div>}
return ( return (
/*Contaier spanning entire screen used to center content horizontally */ /*Contaier spanning entire screen used to center content horizontally */
<div className="w-screen min-h-screen flex justify-center"> <div className="w-screen min-h-screen flex justify-center">
{/* Container defining the maximum width of the content */} {/* 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"> <div className="bg-gray-100 w-full min-h-screen max-w-5xl shadow-xl p-8">
{/* Header - remains in position when scrolling */} {/* Header - remains in position when scrolling */}
<div className="sticky bg-gray-100 top-0 left-0 right-0 pb-4 border-b-2 border-gray-300"> <div className="sticky bg-gray-100 top-0 left-0 right-0 mb-4">
<h1 className="content-title text-blue-900">Recipes</h1> <h1 className="content-title text-blue-900">Recipes</h1>
<div className="flex columns-4 content-stretch gap-2 items-center"> <label>{recipeList.length} Recipes</label>
<label className="text-gray-500 w-2/3">{recipeList.length} Recipes</label>
<input className="input-field"
placeholder="Search"
></input>
<button className="primary-button"
onClick={handleAdd}
>
Add recipe
</button>
</div>
</div> </div>
{/*Content - List of recipe cards */} {/*Content - List of recipe cards */}
<div className="grid pt-4 gap-6 grid-cols-[repeat(auto-fit,minmax(220px,1fr))]"> <div className="grid gap-6 grid-cols-[repeat(auto-fit,minmax(220px,1fr))]">
{recipeList.map((recipe) => ( {recipeList.map((recipe) => (
<RecipeListItem <RecipeListItem
key={recipe.id} key={recipe.id}
title = {recipe.title} title = {recipe.title}
targetPath={getRecipeDetailUrl(recipe.id)} targetPath={'recipe/'+recipe.id}
/> />
))} ))}
</div> </div>

View file

@ -1,15 +0,0 @@
/**
* Routes for all pages
*/
// Route definitions using :id as placeholder for the id
export function getRootUrlDefinition() : string { return getRootUrl()}
export function getRecipeDetailsUrlDefinition() : string {return getRecipeDetailUrl(":id")}
export function getRecipeEditUrlDefinition() : string {return getRecipeEditUrl(":id")}
export function getRecipeAddUrlDefinition() : string {return getRecipeAddUrl()}
// URLs including id
export function getRootUrl () : string { return "/"}
export function getRecipeListUrl() : string {return getRootUrl()}
export function getRecipeDetailUrl(id: string) : string {return "/recipe/" + id}
export function getRecipeEditUrl(id: string) : string {return "/recipe/" + id + "/edit"}
export function getRecipeAddUrl() : string {return "/new-recipe"}