css and adding cancel button to editor

This commit is contained in:
Anika Raemer 2025-09-07 09:43:55 +02:00
parent f1711831f7
commit 0eec7cf58e
5 changed files with 102 additions and 71 deletions

View file

@ -4,55 +4,76 @@
/* Custom recipe app styles */ /* Custom recipe app styles */
@layer components{ @layer components{
.app-container { .app-container {
@apply p-4 flex; @apply p-4 flex;
} }
.sidebar { .sidebar {
@apply min-w-[16rem] bg-gray-50 p-4 w-1/3 border-r pr-4; @apply min-w-[16rem] bg-gray-50 p-4 w-1/3 border-r pr-4;
} }
.sidebar-title { .sidebar-title {
@apply text-blue-900 font-bold mb-2; @apply text-blue-900 font-bold mb-2;
} }
.sidebar-link { .sidebar-link {
@apply block bg-white rounded-xl shadow-md overflow-hidden hover:shadow-lg transition @apply block bg-white rounded-xl shadow-md overflow-hidden hover:shadow-lg transition
} }
.sidebar-item-text { .sidebar-item-text {
@apply font-semibold text-blue-400 @apply font-semibold text-blue-400;
} }
.content-title{ .content-title{
@apply text-xl font-black mb-16 text-blue-300 @apply text-3xl font-black mb-8 text-blue-400;
} }
.main-view { .main-view {
@apply w-2/3 pl-4; @apply w-2/3 pl-4;
} }
.recipe-title { .recipe-image {
@apply text-2xl font-bold; @apply my-4 w-64;
} }
.recipe-image { .section-heading {
@apply my-4 w-64; @apply text-xl font-bold mb-2;
} }
.section-heading { .subsection-heading {
@apply text-2xl font-bold; @apply font-semibold mb-2;
} }
.primary-button { /* buttons */
@apply bg-blue-300 px-4 py-2 shadow-md rounded-lg hover:bg-blue-400 text-gray-600 .primary-button {
} @apply bg-blue-300 px-4 py-2 shadow-md rounded-lg hover:bg-blue-400 text-gray-600
}
.default-button{ .default-button{
@apply bg-gray-300 px-4 py-2 shadow-md rounded-lg hover:bg-gray-400 text-gray-600 @apply bg-gray-300 px-4 py-2 shadow-md rounded-lg hover:bg-gray-400 text-gray-600
} }
.input-field { .dark-button{
@apply border p-2 w-full mb-2; @apply bg-gray-600 text-white rounded px-4 py-2
} }
/* input field */
.input-field {
@apply border p-2 w-full mb-2 rounded;
}
.text-area {
@apply border p-2 w-full mb-2 rounded;
}
/* groups */
.button-group{
@apply flex gap-4 mt-4;
}
/* lists */
.default-list-item {
@apply list-disc pl-6 mb-6
}
} }

View file

@ -24,31 +24,31 @@ export function IngredientListEditor({ ingredients, onChange }: IngredientListEd
return ( return (
<div> <div>
<h3 className="font-semibold mb-2">Ingredients</h3> <h3 className="subsection-heading">Ingredients</h3>
{ingredients.map((ing, index) => ( {ingredients.map((ing, index) => (
<div key={index} className="flex gap-2 mb-2 items-center"> <div key={index} className="flex gap-2 mb-2 items-center">
<input <input
type="number" type="number"
className="border p-2 w-20" className="input-field"
placeholder="Amount" placeholder="Amount"
value={ing.amount} value={ing.amount}
onChange={e => handleUpdate(index, "amount", e.target.value)} onChange={e => handleUpdate(index, "amount", e.target.value)}
/> />
<input <input
className="border p-2 w-20" className="input-field w-20"
placeholder="Unit" placeholder="Unit"
value={ing.unit ?? ""} value={ing.unit ?? ""}
onChange={e => handleUpdate(index, "unit", e.target.value)} onChange={e => handleUpdate(index, "unit", e.target.value)}
/> />
<input <input
className="border p-2 flex-1" className="input-field"
placeholder="Name" placeholder="Name"
value={ing.name} value={ing.name}
onChange={e => handleUpdate(index, "name", e.target.value)} onChange={e => handleUpdate(index, "name", e.target.value)}
/> />
<button <button
type="button" type="button"
className="p-2 bg-red-500 text-white rounded" className="dark-button"
onClick={() => handleRemove(index)} onClick={() => handleRemove(index)}
> >
@ -57,7 +57,7 @@ export function IngredientListEditor({ ingredients, onChange }: IngredientListEd
))} ))}
<button <button
type="button" type="button"
className="p-2 bg-green-500 text-white rounded" className="primary-button"
onClick={handleAdd} onClick={handleAdd}
> >
Add Ingredient Add Ingredient

View file

@ -28,8 +28,8 @@ export default function RecipeDetailView() {
)} )}
{/* Ingredients */} {/* Ingredients */}
<h2 className="section-heading">Ingredients</h2> <h2 className="section-heading">Zutaten</h2>
<ul className="list-disc pl-6"> <ul className="default-list-item">
{recipe.ingredients.map((ing, i) => ( {recipe.ingredients.map((ing, i) => (
<li key={i}> <li key={i}>
{ing.amount} {ing.unit ?? ""} {ing.name} {ing.amount} {ing.unit ?? ""} {ing.name}
@ -38,22 +38,22 @@ export default function RecipeDetailView() {
</ul> </ul>
{/* Instructions */} {/* Instructions */}
<h2 className="section-heading">Instructions</h2> <h2 className="section-heading">Zubereitung</h2>
<p className="mb-6">{recipe.instructions}</p> <p className="mb-6">{recipe.instructions}</p>
{/* Action buttons */} {/* Action buttons */}
<div className="flex gap-8"> <div className="button-group">
<Link <Link
to={`/recipe/${recipe.id}/edit`} to={`/recipe/${recipe.id}/edit`}
className="primary-button" className="primary-button"
> >
Edit Bearbeiten
</Link> </Link>
<Link <Link
to="/" to="/"
className="default-button" className="default-button"
> >
Back Zurueck
</Link> </Link>
</div> </div>

View file

@ -1,4 +1,5 @@
import { useState } from "react" import { useState } from "react"
import { Link } from "react-router-dom" // @todo replace cancel link with button and onCancel handler
import type { Recipe } from "../types/recipe" import type { Recipe } from "../types/recipe"
import type { Ingredient } from "../types/ingredient" import type { Ingredient } from "../types/ingredient"
import {IngredientListEditor} from "./IngredientListEditor" import {IngredientListEditor} from "./IngredientListEditor"
@ -21,14 +22,14 @@ export default function RecipeEditor({ recipe, onSave }: RecipeEditorProps) {
if (!recipe) return <div>Oops, there's no recipe in RecipeEditor...</div> if (!recipe) return <div>Oops, there's no recipe in RecipeEditor...</div>
return ( return (
<div className="p-4 gap-10"> <div className="p-4 gap-10">
<h2 className="section-heading"> <h2 className="content-title">
{recipe.id ? "Edit Recipe" : "New Recipe"} {recipe.id ? "Edit Recipe" : "New Recipe"}
</h2> </h2>
{/* Title */} {/* Title */}
<h3>Title</h3> <h3 className="subsection-heading">Title</h3>
<input <input
className="border p-2 w-full mb-2" className="input-field"
placeholder="Title" placeholder="Title"
value={draft.title} value={draft.title}
onChange={e => setDraft({ ...draft, title: e.target.value })} onChange={e => setDraft({ ...draft, title: e.target.value })}
@ -40,22 +41,30 @@ export default function RecipeEditor({ recipe, onSave }: RecipeEditorProps) {
onChange={updateIngredients} onChange={updateIngredients}
/> />
<h3>Instructions</h3> <h3 className="subsection-heading">Instructions</h3>
{/* Instructions */} {/* Instructions */}
<textarea <textarea
className="border p-2 w-full mb-2" className="text-area"
placeholder="Instructions" placeholder="Instructions"
value={draft.instructions} value={draft.instructions}
onChange={e => setDraft({ ...draft, instructions: e.target.value })} onChange={e => setDraft({ ...draft, instructions: e.target.value })}
/> />
{/* Save Button */} <div className="button-group">
<button {/* Save Button */}
className="p-2 bg-green-500 text-white rounded" <button
onClick={() => onSave(draft)} className="primary-button"
> onClick={() => onSave(draft)}
💾 Save >
</button> Save
</button>
<Link
to={`/recipe/${recipe.id}`}
className="default-button"
>
Cancel
</Link>
</div>
</div> </div>
) )
} }

View file

@ -16,6 +16,14 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}
/*a { /*a {
font-weight: 500; font-weight: 500;
color: #646cff; color: #646cff;
@ -23,14 +31,6 @@
} }
a:hover { a:hover {
color : #8e8f9c; color : #8e8f9c;
}*/
body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
} }
h1 { h1 {
@ -69,3 +69,4 @@ button:focus-visible {
background-color: #f9f9f9; background-color: #f9f9f9;
} }
} }
*/