css and adding cancel button to editor
This commit is contained in:
parent
f1711831f7
commit
0eec7cf58e
5 changed files with 102 additions and 71 deletions
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue