diff --git a/src/Images/burger.jpg b/src/Images/burger.jpg new file mode 100644 index 0000000..e507c94 Binary files /dev/null and b/src/Images/burger.jpg differ diff --git a/src/Images/chicken.jpg b/src/Images/chicken.jpg new file mode 100644 index 0000000..8b21eb9 Binary files /dev/null and b/src/Images/chicken.jpg differ diff --git a/src/Images/paneerBriyani.jpg b/src/Images/paneerBriyani.jpg new file mode 100644 index 0000000..4a87dda Binary files /dev/null and b/src/Images/paneerBriyani.jpg differ diff --git a/src/Images/pasta.jpg b/src/Images/pasta.jpg new file mode 100644 index 0000000..53f0d03 Binary files /dev/null and b/src/Images/pasta.jpg differ diff --git a/src/Images/salad.jpeg b/src/Images/salad.jpeg new file mode 100644 index 0000000..0c98f38 Binary files /dev/null and b/src/Images/salad.jpeg differ diff --git a/src/pages/Recipes.jsx b/src/pages/Recipes.jsx index 9b352c1..f39e7aa 100644 --- a/src/pages/Recipes.jsx +++ b/src/pages/Recipes.jsx @@ -17,74 +17,143 @@ * - [ ] Offline caching of last search * - [ ] Extract service + hook (useMealsSearch) */ -import { useEffect, useState } from 'react'; -import Loading from '../components/Loading.jsx'; -import ErrorMessage from '../components/ErrorMessage.jsx'; -import Card from '../components/Card.jsx'; -import HeroSection from '../components/HeroSection'; -import Food from '../Images/Food.jpg'; +import React, { useState } from "react"; -export default function Recipes() { - const [ingredient, setIngredient] = useState('chicken'); - const [meals, setMeals] = useState([]); - const [randomMeal, setRandomMeal] = useState(null); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); - useEffect(() => { search(); }, []); - async function search() { - try { - setLoading(true); setError(null); - const res = await fetch(`https://www.themealdb.com/api/json/v1/1/filter.php?i=${encodeURIComponent(ingredient)}`); - if (!res.ok) throw new Error('Failed to fetch'); - const json = await res.json(); - setMeals(json.meals || []); - } catch (e) { setError(e); } finally { setLoading(false); } - } +export default function App() { + const [query, setQuery] = useState(""); + const [loadedImages, setLoadedImages] = useState({}); + const [isDark, setIsDark] = useState(false); - async function random() { - try { - setLoading(true); setError(null); - const res = await fetch('https://www.themealdb.com/api/json/v1/1/random.php'); - if (!res.ok) throw new Error('Failed to fetch'); - const json = await res.json(); - setRandomMeal(json.meals?.[0] || null); - } catch (e) { setError(e); } finally { setLoading(false); } - } + const dishes = [ + { + id: 1, + name: "Cheesy Burger", + category: "Fast Food", + area: "American", + desc: "Juicy, cheesy and delicious.", + img: "/src/images/burger.jpg", + }, + { + id: 2, + name: "Creamy Pasta", + category: "Main Course", + area: "Italian", + desc: "Rich and flavorful with herbs.", + img: "/src/images/pasta.jpg", + }, + { + id: 3, + name: "Fresh Salad", + category: "Healthy", + area: "Mediterranean", + desc: "Crisp greens with a tangy dressing.", + img: "/src/images/salad.jpeg", + }, + ]; + + const randomRecipe = [{ + id: 1, + name: "Chicken Tikka Masala", + category: "Main Course", + area: "Indian", + desc: "Aromatic curry with tender chicken pieces.", + img: "/src/images/chicken.jpg", + }, + { + id: 2, + name: "paneer Briyani", + category: "Main Course", + area: "Indian", + desc: "Paneer biryani is a fragrant dish made with spiced paneer and basmati rice..", + img: "/src/images/paneerBriyani.jpg", + }, + ]; + + + const filteredDishes = dishes.filter((dish) => + dish.name.toLowerCase().includes(query.toLowerCase()) + ); + + const filterRandomRecipe = randomRecipe.filter((randomDish) => + randomDish.name.toLowerCase().includes(query.toLowerCase()) + ); return ( -
- - Delicious Made Simple - - } - subtitle="Wholesome recipes with heart, made easy for every home cook" - /> -

Recipe Finder

-
{ e.preventDefault(); search(); }} className="inline-form"> - setIngredient(e.target.value)} placeholder="Ingredient" /> - - -
- {loading && } - - {randomMeal && ( - Source}> - - {/* TODO: Show instructions modal */} - - )} -
- {meals.map(m => ( - - - - ))} -
+
+ {/* Header */} +
+

🍴 Recipes Dashboard

+
+ + {/* Search Section */} +
+

Find your next favorite recipe

+
+ setQuery(e.target.value)} + className="search-input" + /> + {query && ( + + )} +
+
+ + {/* Random Recipe */} +
+
+ {filterRandomRecipe.map((randomDish) => ( +
+ {randomDish.name} +
+

{randomDish.name}

+

{randomDish.desc}

+

+ {randomDish.category} • {randomDish.area} +

+ +
+
+ ))} + +
+
+ + + {/* Cards */} +
+

Popular Recipes

+
+ {filteredDishes.map((dish) => ( +
+ {!loadedImages[dish.id] &&
} + {dish.name} + setLoadedImages((prev) => ({ ...prev, [dish.id]: true })) + } + /> +

{dish.name}

+

+ {dish.category} • {dish.area} +

+

{dish.desc}

+ +
+ ))} +
+
+ +
); } diff --git a/src/styles.css b/src/styles.css index 8cd7997..c1ba1b5 100644 --- a/src/styles.css +++ b/src/styles.css @@ -48,6 +48,7 @@ main { opacity: 0; transform: translateX(100px); } + to { opacity: 1; transform: translateX(0); @@ -65,6 +66,7 @@ main { opacity: 0; transform: translateX(-30px) translateY(20px); } + to { opacity: 1; transform: translateX(0) translateY(0); @@ -76,6 +78,7 @@ main { opacity: 0; transform: translateY(40px) scale(0.95); } + to { opacity: 1; transform: translateY(0) scale(1); @@ -803,6 +806,7 @@ blockquote { .hero-title { font-size: 2.2rem; } + .hero-subtitle { font-size: 1.2rem; } @@ -812,6 +816,7 @@ blockquote { .hero-title { font-size: 1.8rem; } + .hero-subtitle { font-size: 1rem; } @@ -826,7 +831,11 @@ blockquote { justify-content: center; background-color: rgb(242, 215, 220); transition: all 0.25s ease; - box-shadow: 0 4px 6px rgba(16, 11, 11, 0.1), 0 0 10px rgba(242, 215, 220, 0.4); + + box-shadow: + 0 4px 6px rgba(16, 11, 11, 0.1), + 0 0 10px rgba(242, 215, 220, 0.4); + } .fav-icon:hover { @@ -897,6 +906,7 @@ blockquote { opacity: 0; transform: translateY(-5px); } + to { opacity: 1; transform: translateY(0); @@ -937,6 +947,7 @@ blockquote { from { opacity: 0; } + to { opacity: 1; } @@ -959,6 +970,7 @@ blockquote { opacity: 0; transform: translateY(-20px) scale(0.95); } + to { opacity: 1; transform: translateY(0) scale(1); @@ -1055,4 +1067,303 @@ blockquote { cursor: default; } -/* ...existing code... */ \ No newline at end of file +/* ======================= Recipe Dashboard UI ======================= */ + +/* Header */ +header { + display: flex; + justify-content: center; + align-items: center; + padding: 20px 48px; + background: var(--card); + border-bottom: 1px solid var(--border); + box-shadow: 0 2px 10px var(--shadow); + position: sticky; + top: 0; + z-index: 10; +} + +header h1 { + font-size: 1.6rem; + font-weight: 600; + color: var(--text); +} + +.header-buttons { + display: flex; + gap: 10px; +} + +/* Buttons */ +.btn { + padding: 10px 20px; + border-radius: 10px; + font-size: 0.95rem; + cursor: pointer; + font-weight: 500; + transition: all 0.25s ease; +} + +.btn-primary { + background: var(--primary); + color: #fff; + border: none; +} + +.btn-primary:hover { + background: var(--primary-hover); + transform: translateY(-1px); +} + +.btn-outline { + border: 2px solid var(--primary); + color: var(--primary); + background: transparent; +} + +.btn-outline:hover { + background: var(--surface); +} + +/* ======================= Search Section ======================= */ +.search-section { + text-align: center; + padding: 80px 20px 60px; + max-width: 600px; + margin: 0 auto; +} + +.search-section h2 { + font-size: 2.2rem; + font-weight: 600; + margin-bottom: 25px; + color: var(--text); +} + +.search-box { + position: relative; + width: 100%; +} + +.search-input { + width: 100%; + padding: 14px 18px; + border-radius: 50px; /* pill shape */ + border: 1px solid var(--border); + font-size: 1rem; + background: var(--card); + color: var(--text); + box-shadow: 0 2px 8px var(--shadow); + transition: border 0.3s ease, box-shadow 0.3s ease; +} + +.search-input::placeholder { + color: var(--muted); + font-weight: 500; +} + +.search-input:focus { + outline: none; + border-color: var(--primary); + box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.2); +} + +.clear-btn { + position: absolute; + right: 16px; + top: 50%; + transform: translateY(-50%); + background: none; + border: none; + color: var(--muted); + font-size: 1.2rem; + cursor: pointer; + transition: color 0.2s ease; +} + +.clear-btn:hover { + color: var(--text); +} + +/* ======================= Random Recipe Section ======================= */ +.random-recipe { + padding: 40px 20px; + display: flex; + justify-content: center; + background: var(--surface); + transition: background 0.3s ease; +} + +.random-recipe-card { + display: flex; + gap: 30px; + background: var(--card); + border-radius: 20px; + padding: 20px; + max-width: 900px; + width: 100%; + align-items: center; + box-shadow: 0 6px 20px var(--shadow); + transition: transform 0.3s ease, box-shadow 0.3s ease, background 0.3s ease; +} + +.random-recipe-card:hover { + transform: translateY(-4px); + box-shadow: 0 10px 25px var(--shadow); +} + +.random-recipe-img { + width: 180px; + height: 180px; + border-radius: 20px; + object-fit: cover; + flex-shrink: 0; + border: 2px solid var(--border); + transition: transform 0.3s ease, border 0.3s ease; +} + +.random-recipe-img:hover { + transform: scale(1.05); + border-color: var(--primary); +} + +.random-recipe-info h3 { + font-size: 1.8rem; + font-weight: 700; + margin-bottom: 10px; + color: var(--text); + transition: color 0.3s ease; +} + +.random-recipe-info p { + font-size: 1rem; + margin-bottom: 8px; + color: var(--muted); + transition: color 0.3s ease; +} + +.random-recipe-info .muted { + font-size: 0.95rem; + font-weight: 500; +} + +.random-recipe-info .btn { + margin-top: 12px; +} + +/* Responsive */ +@media (max-width: 768px) { + .random-recipe-card { + flex-direction: column; + text-align: center; + } + + .random-recipe-img { + width: 140px; + height: 140px; + margin-bottom: 15px; + } +} + +/* ======================= Cards Section ======================= */ +.cards-section { + padding: 0 48px 80px; + max-width: 1300px; + margin: 0 auto; +} + +.cards-title { + text-align: center; + font-size: 2rem; + margin-bottom: 40px; + font-weight: 600; + color: var(--text); +} + +.cards-grid { + display: grid; + gap: 30px; + grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); +} + +.card { + background: var(--card); + border-radius: 18px; + box-shadow: 0 3px 10px var(--shadow); + text-align: center; + padding: 24px; + transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease; + border: 1px solid transparent; +} + +.card:hover { + transform: translateY(-4px); + box-shadow: 0 8px 20px var(--shadow); + border-color: var(--border); +} + +.card img { + width: 130px; + height: 130px; + border-radius: 50%; + object-fit: cover; + margin: 10px auto 15px; + display: block; + border: 2px solid var(--border); + transition: border 0.3s ease; +} + +.card h4 { + font-size: 1.2rem; + font-weight: 600; + color: var(--text); + margin-bottom: 6px; +} + +.card p { + margin: 5px 0; + color: var(--muted); + font-size: 0.95rem; +} + +/* Skeleton loader */ +.skeleton { + width: 130px; + height: 130px; + border-radius: 50%; + background: linear-gradient(90deg, #eee, #ddd, #eee); + background-size: 200% 100%; + animation: shimmer 1.5s infinite; + margin: 12px auto; +} + +@keyframes shimmer { + 0% { + background-position: -200% 0; + } + + 100% { + background-position: 200% 0; + } +} + +/* ======================= Footer ======================= */ +footer { + text-align: center; + padding: 30px 20px; + font-size: 0.95rem; + border-top: 1px solid var(--border); + background: var(--card); + color: var(--muted); + transition: background 0.3s ease, color 0.3s ease; +} + +footer a { + color: var(--primary); + text-decoration: none; + transition: color 0.2s ease; +} + +footer a:hover { + color: var(--primary-hover); +}