Compare commits
No commits in common. "fdaf4cff1fa8770e91f3a7fbe7f9bf1297077040" and "91439cbcfa24abcd1f8261ac5e73374f539272de" have entirely different histories.
fdaf4cff1f
...
91439cbcfa
6 changed files with 23 additions and 51 deletions
|
@ -1,7 +1,6 @@
|
||||||
import { type RecipeSmall } from "../types/Recipe"
|
import { type RecipeSmall } from "../types/Recipe"
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import StarRating from '../components/StarRating.tsx'
|
import StarRating from '../components/StarRating.tsx'
|
||||||
import TimeDisplay from "../components/TimeDisplay.tsx"
|
|
||||||
|
|
||||||
function CookbookRecipeTile({ recipe }: { recipe: RecipeSmall }) {
|
function CookbookRecipeTile({ recipe }: { recipe: RecipeSmall }) {
|
||||||
|
|
||||||
|
@ -14,7 +13,7 @@ function CookbookRecipeTile({ recipe }: { recipe: RecipeSmall }) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
⏰ <TimeDisplay minutes={recipe.prep_minutes + recipe.cook_minutes} />
|
⏰ {recipe.prep_minutes + recipe.cook_minutes} min
|
||||||
<StarRating rating={recipe.stars} onRatingChange={() => { }} />
|
<StarRating rating={recipe.stars} onRatingChange={() => { }} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,7 +10,7 @@ const DemoModal = ({ isOpen, onClose, closeModal }: DemoModalProps) => {
|
||||||
if (!isOpen) return null;
|
if (!isOpen) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`z-50 modal-overlay fixed top-0 left-0 w-full h-full bg-black bg-opacity-50 flex justify-center items-center`} onClick={onClose}>
|
<div className="modal-overlay fixed top-0 left-0 w-full h-full bg-black bg-opacity-50 flex justify-center items-center" onClick={onClose}>
|
||||||
<div className="modal-content bg-amber-200 p-12 rounded-md shadow-md" onClick={(e) => e.stopPropagation()}>
|
<div className="modal-content bg-amber-200 p-12 rounded-md shadow-md" onClick={(e) => e.stopPropagation()}>
|
||||||
<div className="modal-msg">
|
<div className="modal-msg">
|
||||||
<p>Thanks for checking out my app! Database write operations are disabled in demo mode.</p>
|
<p>Thanks for checking out my app! Database write operations are disabled in demo mode.</p>
|
||||||
|
|
|
@ -10,7 +10,7 @@ const Modal = ({ isOpen, onClose, message, confirmAction, cancelAction }: ModalP
|
||||||
if (!isOpen) return null;
|
if (!isOpen) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`z-50 modal-overlay fixed top-0 left-0 w-full h-full bg-black bg-opacity-50 flex justify-center items-center`} onClick={onClose}>
|
<div className="modal-overlay fixed top-0 left-0 w-full h-full bg-black bg-opacity-50 flex justify-center items-center" onClick={onClose}>
|
||||||
<div className="modal-content bg-amber-200 p-12 rounded-md shadow-md" onClick={(e) => e.stopPropagation()}>
|
<div className="modal-content bg-amber-200 p-12 rounded-md shadow-md" onClick={(e) => e.stopPropagation()}>
|
||||||
<div className="modal-msg">
|
<div className="modal-msg">
|
||||||
<span aria-labelledby="message">{message}</span>
|
<span aria-labelledby="message">{message}</span>
|
||||||
|
|
|
@ -35,9 +35,9 @@ const RecipeBookTabs = () => {
|
||||||
|
|
||||||
|
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{ id: '/', label: 'Cookbook', icon: '📚' },
|
{ id: '/', label: 'All Recipes', icon: '📚' },
|
||||||
{ id: `/recipe/${lastViewedRecipeId}`, label: 'Recipe', icon: '🥗' },
|
{ id: `/recipe/${lastViewedRecipeId}`, label: 'Recipe', icon: '🥗' },
|
||||||
{ id: '/add-recipe', label: 'Add', icon: '➕' },
|
{ id: '/add-recipe', label: 'Add Recipe', icon: '➕' },
|
||||||
{ id: '/about', label: 'About', icon: '🍽️' },
|
{ id: '/about', label: 'About', icon: '🍽️' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ const RecipeBookTabs = () => {
|
||||||
key={tab.id}
|
key={tab.id}
|
||||||
to={tab.id}
|
to={tab.id}
|
||||||
className={`
|
className={`
|
||||||
relative px-3 py-2 md:px-6 md:py-3 rounded-t-lg font-bold text-sm transform text-amber-800
|
relative px-6 py-3 rounded-t-lg font-bold text-sm transform text-amber-800
|
||||||
${isActive
|
${isActive
|
||||||
? 'bg-amber-100 scale-105 z-10 border-t-2 border-amber-200'
|
? 'bg-amber-100 scale-105 z-10 border-t-2 border-amber-200'
|
||||||
: 'bg-amber-200 hover:bg-amber-100 hover:text-amber-700 hover:scale-102 shadow-sm'
|
: 'bg-amber-200 hover:bg-amber-100 hover:text-amber-700 hover:scale-102 shadow-sm'
|
||||||
|
@ -64,23 +64,21 @@ const RecipeBookTabs = () => {
|
||||||
${isActive ? '' : ''}
|
${isActive ? '' : ''}
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center space-x-2">
|
||||||
<span className={`text-lg pr-2 ${window.innerWidth <= 640 ? 'hidden' : ''}`}>{tab.icon}</span>
|
<span className="text-lg">{tab.icon}</span>
|
||||||
<span>{tab.label}</span>
|
<span>{tab.label}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{
|
{isActive && (
|
||||||
isActive && (
|
<>
|
||||||
<>
|
<div className={`absolute -left-2 bottom-0 w-2 h-2 bg-white ${location.pathname === '/' ? 'hidden' : ''}`}>
|
||||||
<div className={`absolute -left-2 bottom-0 w-2 h-2 bg-white ${location.pathname === '/' ? 'hidden' : ''}`}>
|
<div className="absolute top-0 left-0 w-2 h-2 bg-amber-200 rounded-br-lg"></div>
|
||||||
<div className="absolute top-0 left-0 w-2 h-2 bg-amber-200 rounded-br-lg"></div>
|
</div>
|
||||||
</div>
|
<div className={`absolute -right-2 bottom-0 w-2 h-2 bg-white ${location.pathname === '/about' ? 'hidden' : ''}`}>
|
||||||
<div className={`absolute -right-2 bottom-0 w-2 h-2 bg-white ${location.pathname === '/about' ? 'hidden' : ''}`}>
|
<div className="absolute top-0 right-0 w-2 h-2 bg-amber-200 rounded-bl-lg"></div>
|
||||||
<div className="absolute top-0 right-0 w-2 h-2 bg-amber-200 rounded-bl-lg"></div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
</>
|
)}
|
||||||
)
|
|
||||||
}
|
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
interface TimeDisplayProps {
|
|
||||||
minutes: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TimeDisplay = ({ minutes }: TimeDisplayProps) => {
|
|
||||||
let displayText: string;
|
|
||||||
|
|
||||||
if (minutes < 60) {
|
|
||||||
displayText = `${minutes} min`;
|
|
||||||
} else {
|
|
||||||
const hours = Math.floor(minutes / 60);
|
|
||||||
const remainingMinutes = minutes % 60;
|
|
||||||
if (hours > 0 && remainingMinutes > 0) {
|
|
||||||
displayText = `${hours} hr${hours !== 1 ? 's' : ''} ${remainingMinutes} min`;
|
|
||||||
} else if (hours > 0) {
|
|
||||||
displayText = `${hours} hr${hours !== 1 ? 's' : ''}`;
|
|
||||||
} else {
|
|
||||||
displayText = `${remainingMinutes} min`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return <>{displayText}</>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default TimeDisplay;
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { useParams, useNavigate, Link } from "react-router-dom";
|
import { useParams, useNavigate, Link } from "react-router-dom";
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { getRecipeById, deleteRecipe, setDBStars } from "../services/frontendApi.js";
|
import { getRecipeById, deleteRecipe } from "../services/frontendApi.js";
|
||||||
import { type Recipe, type Ingredient } from "../types/Recipe"
|
import { type Recipe, type Ingredient } from "../types/Recipe"
|
||||||
|
import StarRating from "../components/StarRating.tsx"
|
||||||
|
import { setDBStars } from "../services/frontendApi.js";
|
||||||
import Modal from '../components/Modal.tsx'
|
import Modal from '../components/Modal.tsx'
|
||||||
import DemoModal from '../components/DemoModal.tsx'
|
import DemoModal from '../components/DemoModal.tsx'
|
||||||
import StarRating from "../components/StarRating.tsx"
|
|
||||||
import TimeDisplay from '../components/TimeDisplay.tsx'
|
|
||||||
|
|
||||||
function RecipePage() {
|
function RecipePage() {
|
||||||
const [recipe, setRecipe] = useState<Recipe>({
|
const [recipe, setRecipe] = useState<Recipe>({
|
||||||
|
@ -100,13 +100,13 @@ function RecipePage() {
|
||||||
) : (
|
) : (
|
||||||
|
|
||||||
<div className="recipe-card relative">
|
<div className="recipe-card relative">
|
||||||
<button onClick={openModal} className="ar-button bg-amber-500 text-white py-1 px-2 rounded hover:bg-amber-600 m-2 absolute top-0 right-0">
|
<button onClick={openModal} className="ar-button bg-gray-200 text-white py-1 px-2 rounded hover:bg-gray-300 m-2 absolute top-0 right-0">
|
||||||
🗑️
|
🗑️
|
||||||
</button>
|
</button>
|
||||||
<div className="border-b-2 border-amber-300 pb-4 mb-6">
|
<div className="border-b-2 border-amber-300 pb-4 mb-6">
|
||||||
<h3 className="text-2xl lg:text-3xl font-bold text-amber-900 mb-2">{recipe.details.name}</h3>
|
<h3 className="text-2xl lg:text-3xl font-bold text-amber-900 mb-2">{recipe.details.name}</h3>
|
||||||
<p className="text-amber-700 italic text-lg">{recipe.details.cuisine}</p>
|
<p className="text-amber-700 italic text-lg">{recipe.details.cuisine}</p>
|
||||||
<p>prep: <TimeDisplay minutes={recipe.details.prep_minutes ?? 0} /> | cook: <TimeDisplay minutes={recipe.details.cook_minutes ?? 0} /></p>
|
<p>prep: {recipe.details.prep_minutes} min | cook: {recipe.details.cook_minutes} min</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid lg:grid-cols-2 gap-6 mb-6">
|
<div className="grid lg:grid-cols-2 gap-6 mb-6">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue