-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
404 lines (355 loc) · 18 KB
/
Copy pathscript.js
File metadata and controls
404 lines (355 loc) · 18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
// Recipe Database - WITH REAL IMAGES (18 recipes)
const recipes = [
// ================= ITALIAN CUISINE =================
{
id: 1,
name: "Spaghetti Carbonara",
cuisine: "italian",
emoji: "🍝",
image: "images/carbonara.jpg",
prepTime: "20 min",
ingredients: ["200g spaghetti", "3 large eggs", "100g Pecorino Romano", "150g guanciale/pancetta", "Black pepper", "Salt"],
steps: ["Boil salted water and cook spaghetti al dente (9-11 minutes)", "Whisk eggs with grated cheese and 1 tsp black pepper", "Fry guanciale in a cold pan until crispy (6-8 minutes)", "Reserve 1 cup pasta water, then drain spaghetti", "Add hot pasta to skillet with guanciale, toss well", "Remove from heat, pour egg mixture and toss vigorously", "Add pasta water for creaminess, serve immediately"]
},
{
id: 2,
name: "Margherita Pizza",
cuisine: "italian",
emoji: "🍕",
image: "images/pizza.jpg",
prepTime: "15 min",
ingredients: ["Pizza dough", "Tomato sauce", "Fresh mozzarella", "Fresh basil", "Olive oil", "Sea salt"],
steps: ["Preheat oven to 260°C (500°F)", "Stretch dough into 30cm round", "Spread tomato sauce, leaving 1.5cm border", "Add torn mozzarella pieces", "Bake 10-12 minutes until golden", "Top with fresh basil and olive oil"]
},
{
id: 3,
name: "Mushroom Risotto",
cuisine: "italian",
emoji: "🍚",
image: "images/risotto.jpg",
prepTime: "35 min",
ingredients: ["Arborio rice", "Mixed mushrooms", "Onion", "Garlic", "Butter", "White wine", "Parmesan cheese", "Vegetable broth"],
steps: ["Sauté mushrooms until golden (8 min), set aside", "Cook onion and garlic in butter", "Toast rice for 2 min, add wine", "Add broth gradually while stirring (18-20 min)", "Stir in mushrooms, butter, Parmesan", "Rest 2 minutes before serving"]
},
// ================= INDIAN CUISINE =================
{
id: 4,
name: "Chicken Curry",
cuisine: "indian",
emoji: "🍛",
image: "images/curry.jpg",
prepTime: "40 min",
ingredients: ["700g chicken thighs", "2 onions", "3 tomatoes", "2 tsp ginger-garlic paste", "1 tsp turmeric", "1.5 tsp chili powder", "2 tsp coriander powder", "1 tsp garam masala", "Fresh cilantro"],
steps: ["Fry onions until golden brown (8-10 min)", "Add ginger-garlic paste, cook 1 min", "Add spices and tomato puree, cook until oil separates", "Add chicken and sear for 5 min", "Add water, cover and simmer 20 min", "Finish with garam masala and cilantro"]
},
{
id: 5,
name: "Chicken Biryani",
cuisine: "indian",
emoji: "🍚",
image: "images/biryani.jpg",
prepTime: "75 min",
ingredients: ["500g basmati rice", "600g chicken", "1 cup fried onions", "1/2 cup yogurt", "2 tbsp biryani masala", "Whole spices", "Saffron", "4 tbsp ghee"],
steps: ["Marinate chicken in yogurt and spices (30 min)", "Par-boil rice with whole spices (6-7 min)", "Layer rice and chicken in heavy pot", "Add saffron milk and ghee", "Cover tightly, cook on low heat (dum) 30 min", "Rest 10 min before serving"]
},
{
id: 6,
name: "Butter Chicken",
cuisine: "indian",
emoji: "🍗",
image: "images/butterchicken.jpg",
prepTime: "50 min",
ingredients: ["500g boneless chicken", "3 tbsp butter", "1 onion", "400g tomato puree", "1/2 cup cream", "1 tsp garam masala", "1 tsp kasuri methi", "Ginger-garlic paste"],
steps: ["Grill chicken until charred (8-10 min), set aside", "Melt butter, sauté onion and ginger-garlic", "Add tomato puree, simmer 10 min then blend smooth", "Add cream, garam masala, kasuri methi", "Add chicken, simmer 2-3 minutes", "Finish with butter, serve with naan"]
},
// ================= MEXICAN CUISINE =================
{
id: 7,
name: "Beef Tacos",
cuisine: "mexican",
emoji: "🌮",
image: "images/tacos.jpg",
prepTime: "20 min",
ingredients: ["500g ground beef", "8 tortillas", "1 onion", "1/2 cup cilantro", "Shredded cheese", "Salsa", "Taco seasoning"],
steps: ["Brown ground beef (6-8 min), drain excess fat", "Add taco seasoning and 1/2 cup water", "Simmer 5 minutes until thickened", "Warm tortillas on dry skillet", "Assemble tacos with beef, onion, cilantro, cheese", "Serve with lime wedges"]
},
{
id: 8,
name: "Burrito",
cuisine: "mexican",
emoji: "🌯",
image: "images/burrito.jpg",
prepTime: "15 min",
ingredients: ["2 large flour tortillas", "1 cup Mexican rice", "1 can black beans", "150g shredded cheese", "4 tbsp sour cream", "1/2 cup salsa", "1 avocado"],
steps: ["Heat beans with 2 tbsp water, mash slightly", "Warm tortillas until pliable", "Spread sour cream in center", "Layer rice, beans, cheese, salsa, avocado", "Fold sides then roll tightly", "Toast seam-side down 1-2 min, cut in half"]
},
{
id: 9,
name: "Quesadilla",
cuisine: "mexican",
emoji: "🧀",
image: "images/quesadilla.jpg",
prepTime: "10 min",
ingredients: ["2 flour tortillas", "180g Oaxaca cheese", "1 tbsp butter", "Salsa", "Guacamole"],
steps: ["Spread cheese evenly over one tortilla", "Top with second tortilla", "Melt butter in skillet over medium heat", "Cook 2-3 minutes until golden", "Carefully flip, cook 2 more minutes", "Cut into wedges, serve with salsa/guacamole"]
},
// ================= JAPANESE CUISINE =================
{
id: 10,
name: "Sushi Rolls",
cuisine: "japanese",
emoji: "🍣",
image: "images/sushi.jpg",
prepTime: "40 min",
ingredients: ["2 cups sushi rice", "2 sheets nori", "Cucumber strips", "Avocado", "Crab or salmon", "Rice vinegar", "Sugar", "Salt"],
steps: ["Cook and season sushi rice with vinegar mixture", "Place nori on bamboo mat (shiny side down)", "Spread rice evenly, leave 1cm top edge", "Arrange fillings in a line", "Roll tightly using mat, wet edge to seal", "Slice with wet knife into 6-8 pieces"]
},
{
id: 11,
name: "Shoyu Ramen",
cuisine: "japanese",
emoji: "🍜",
image: "images/ramen.jpg",
prepTime: "25 min",
ingredients: ["200g fresh ramen noodles", "1L chicken broth", "3 tbsp soy sauce", "1 tbsp mirin", "1 tsp sesame oil", "Soft-boiled egg", "Green onions", "Nori"],
steps: ["Heat broth with soy sauce, mirin, sesame oil", "Cook ramen noodles 2-3 minutes, drain", "Divide noodles into two deep bowls", "Pour hot broth over noodles", "Arrange toppings: egg, protein, nori, green onions", "Serve immediately with chopsticks"]
},
{
id: 12,
name: "Shrimp Tempura",
cuisine: "japanese",
emoji: "🍤",
image: "images/tempura.jpg",
prepTime: "30 min",
ingredients: ["12 large prawns", "1 cup ice-cold water", "1 egg yolk", "1 cup cake flour", "Oil for frying", "Dipping sauce"],
steps: ["Butterfly shrimp on belly to keep straight", "Make ice-cold batter: mix water, egg yolk, flour quickly", "Heat oil to 170°C (340°F)", "Dust shrimp with flour, dip in batter", "Fry 2-3 minutes until pale golden", "Drain on wire rack, serve with tentsuyu sauce"]
},
// ================= EAST AFRICAN CUISINE =================
{
id: 13,
name: "Beef Pilau",
cuisine: "eastafrican",
emoji: "🍛",
image: "images/pilau.jpg",
prepTime: "50 min",
ingredients: ["2 cups basmati rice", "500g beef stew meat", "1 large onion", "2 tbsp pilau masala", "3 cups beef broth", "4 tbsp oil", "1 tsp garlic-ginger paste", "Fresh coriander"],
steps: ["Brown beef pieces for 8 min, remove and set aside", "Fry onion until golden (7 min)", "Add garlic-ginger and pilau masala, stir 1 min", "Add rice and toast for 2 min", "Return beef, add broth, bring to boil", "Cover and cook 20 min, fluff with fork"]
},
{
id: 14,
name: "Ugali & Sukuma Wiki",
cuisine: "eastafrican",
emoji: "🍽️",
image: "images/ugali.jpg",
prepTime: "25 min",
ingredients: ["2 cups maize meal", "4 cups water", "1 tsp salt", "500g collard greens", "1 onion", "2 tomatoes", "2 tbsp oil"],
steps: ["For Ugali: Boil water and salt, slowly add maize meal while stirring", "Cook until thick and pulling away from pot (5-7 min)", "Mould into a dome shape", "For Sukuma: Sauté onions, add tomatoes until mushy", "Add greens, salt, pepper, cook 5-7 minutes", "Serve ugali slices with sukuma wiki"]
},
{
id: 15,
name: "Nyama Choma",
cuisine: "eastafrican",
emoji: "🍖",
image: "images/nyamachoma.jpg",
prepTime: "60 min",
ingredients: ["1.2kg goat or beef ribs", "Coarse sea salt", "Black pepper", "Lemon wedges", "Kachumbari (onion, tomato, cilantro)"],
steps: ["Season meat generously with salt and pepper", "Let rest at room temperature 30 minutes", "Prepare charcoal grill until medium-hot", "Grill meat over direct heat, turning every 5-8 minutes", "Cook until charred outside (internal temp 70°C)", "Rest 10 minutes, slice, serve with kachumbari"]
},
// ================= CHINESE CUISINE =================
{
id: 16,
name: "Egg Fried Rice",
cuisine: "chinese",
emoji: "🍚",
image: "images/friedrice.jpg",
prepTime: "10 min",
ingredients: ["3 cups day-old jasmine rice", "3 large eggs", "1/2 cup peas & carrots", "3 green onions", "3 tbsp soy sauce", "1 tsp sesame oil", "2 tbsp vegetable oil"],
steps: ["Heat wok on high, add 1 tbsp oil, scramble eggs, remove", "Add 1 tbsp oil, stir-fry peas and carrots 1 min", "Add rice, break clumps with spatula", "Add soy sauce, sesame oil, stir-fry 2-3 min", "Return eggs to wok, add green onions", "Toss to combine, serve hot"]
},
{
id: 17,
name: "Sweet & Sour Chicken",
cuisine: "chinese",
emoji: "🍗",
image: "images/sweetchicken.jpg",
prepTime: "30 min",
ingredients: ["600g chicken breast", "1/2 cup cornstarch", "2 eggs", "1/2 cup ketchup", "1/4 cup rice vinegar", "1/3 cup brown sugar", "2 tbsp soy sauce", "1/2 cup pineapple juice", "Bell pepper, onion, pineapple"],
steps: ["Coat chicken in cornstarch, then dip in beaten eggs", "Deep-fry at 180°C until golden (3-4 min)", "Combine sauce ingredients, simmer until thickened", "Stir-fry bell pepper and onion 2 min", "Add sauce, pineapple, fried chicken, toss to coat", "Serve immediately with steamed rice"]
},
{
id: 18,
name: "Chow Mein",
cuisine: "chinese",
emoji: "🍜",
image: "images/chowmein.jpg",
prepTime: "20 min",
ingredients: ["300g fresh egg noodles", "250g chicken thigh", "1 carrot julienned", "1/2 cabbage shredded", "2 spring onions", "3 tbsp oyster sauce", "2 tbsp soy sauce", "1 tsp dark soy", "1 tsp sugar"],
steps: ["Boil noodles 2-3 min, drain and rinse with cold water", "Stir-fry chicken in hot wok until cooked (3 min), remove", "Add carrot and cabbage, stir-fry 2 min", "Add noodles and chicken back to wok", "Pour sauce over, toss vigorously 2 min", "Garnish with spring onions, serve hot"]
}
];
// App State
let favorites = JSON.parse(localStorage.getItem('favorites')) || [];
let currentFilter = 'all';
let currentSearch = '';
let currentNav = 'home';
// DOM Elements
const recipesGrid = document.getElementById('recipesGrid');
const searchInput = document.getElementById('searchInput');
const cuisineFilter = document.getElementById('cuisineFilter');
const recipeCountSpan = document.getElementById('recipeCount');
const modal = document.getElementById('recipeModal');
const modalBody = document.getElementById('modalBody');
const closeModal = document.querySelector('.close-modal');
const navItems = document.querySelectorAll('#navigation ul li');
// Helper: Get Cuisine Display Name
function getCuisineName(cuisine) {
const names = {
italian: '🇮🇹 Italian',
indian: '🇮🇳 Indian',
mexican: '🇲🇽 Mexican',
japanese: '🇯🇵 Japanese',
eastafrican: '🇰🇪 East African',
chinese: '🇨🇳 Chinese'
};
return names[cuisine] || cuisine;
}
// Filter Recipes based on search, cuisine, and nav
function getFilteredRecipes() {
let filtered = [...recipes];
// Filter by cuisine
if (currentFilter !== 'all') {
filtered = filtered.filter(r => r.cuisine === currentFilter);
}
// Filter by search (name or ingredients)
if (currentSearch) {
const searchLower = currentSearch.toLowerCase();
filtered = filtered.filter(r =>
r.name.toLowerCase().includes(searchLower) ||
r.ingredients.some(ing => ing.toLowerCase().includes(searchLower))
);
}
// Filter by favorites view
if (currentNav === 'favorites') {
filtered = filtered.filter(r => favorites.includes(r.id));
}
return filtered;
}
// Toggle Favorite
function toggleFavorite(recipeId, event) {
if (event) event.stopPropagation();
if (favorites.includes(recipeId)) {
favorites = favorites.filter(id => id !== recipeId);
} else {
favorites.push(recipeId);
}
localStorage.setItem('favorites', JSON.stringify(favorites));
renderRecipes();
}
// Open Modal with Full Recipe and Image
function openModal(recipe) {
const isFavorited = favorites.includes(recipe.id);
modalBody.innerHTML = `
<div class="modal-body-content">
<div style="position: relative;">
<img src="${recipe.image}" alt="${recipe.name}" style="width: 100%; height: 250px; object-fit: cover; border-radius: 1rem; margin-bottom: 1rem;" onerror="this.style.display='none'; this.insertAdjacentHTML('afterend', '<div style=\\'font-size: 4rem; text-align: center; padding: 2rem;\\'>${recipe.emoji}</div>')">
</div>
<h2>${recipe.name}</h2>
<div class="modal-cuisine">${getCuisineName(recipe.cuisine)} • ⏱️ ${recipe.prepTime}</div>
<div class="modal-ingredients">
<h3>📝 Ingredients</h3>
<ul>
${recipe.ingredients.map(ing => `<li>${ing}</li>`).join('')}
</ul>
</div>
<div class="modal-steps">
<h3>👩🍳 Step-by-Step Instructions</h3>
<ol>
${recipe.steps.map(step => `<li>${step}</li>`).join('')}
</ol>
</div>
<button class="modal-favorite" data-id="${recipe.id}">
${isFavorited ? '❤️ Remove from Favorites' : '🤍 Save to Favorites'}
</button>
</div>
`;
modal.style.display = 'block';
// Add favorite button listener in modal
const modalFavBtn = modalBody.querySelector('.modal-favorite');
if (modalFavBtn) {
modalFavBtn.addEventListener('click', (e) => {
toggleFavorite(recipe.id, e);
openModal(recipe);
renderRecipes();
});
}
}
// Render Recipes Grid with Images
function renderRecipes() {
const filtered = getFilteredRecipes();
recipeCountSpan.textContent = filtered.length;
if (filtered.length === 0) {
recipesGrid.innerHTML = '<div class="no-results">🍽️ No recipes found. Try adjusting your search or filter!</div>';
return;
}
recipesGrid.innerHTML = filtered.map(recipe => `
<div class="recipe-card" data-id="${recipe.id}">
<div class="favorite-btn ${favorites.includes(recipe.id) ? 'favorited' : ''}" data-id="${recipe.id}">
${favorites.includes(recipe.id) ? '❤️' : '🤍'}
</div>
<div class="recipe-card-image">
<img src="${recipe.image}" alt="${recipe.name}" onerror="this.parentElement.innerHTML='<div class=\\'emoji-fallback\\'>${recipe.emoji}</div>'">
</div>
<div class="recipe-card-content">
<h3>${recipe.name}</h3>
<div class="cuisine-badge">${getCuisineName(recipe.cuisine)} • ${recipe.prepTime}</div>
<div class="preview-ingredients">
📌 ${recipe.ingredients.slice(0, 3).join(', ')}${recipe.ingredients.length > 3 ? '...' : ''}
</div>
</div>
</div>
`).join('');
// Add event listeners to cards and favorite buttons
document.querySelectorAll('.recipe-card').forEach(card => {
const recipeId = parseInt(card.dataset.id);
const recipe = recipes.find(r => r.id === recipeId);
card.addEventListener('click', (e) => {
if (!e.target.closest('.favorite-btn')) {
openModal(recipe);
}
});
const favBtn = card.querySelector('.favorite-btn');
if (favBtn) {
favBtn.addEventListener('click', (e) => {
toggleFavorite(recipeId, e);
});
}
});
}
// Event Listeners
searchInput.addEventListener('input', (e) => {
currentSearch = e.target.value;
renderRecipes();
});
cuisineFilter.addEventListener('change', (e) => {
currentFilter = e.target.value;
renderRecipes();
});
closeModal.addEventListener('click', () => {
modal.style.display = 'none';
});
window.addEventListener('click', (e) => {
if (e.target === modal) {
modal.style.display = 'none';
}
});
navItems.forEach(item => {
item.addEventListener('click', () => {
const navValue = item.dataset.nav;
currentNav = navValue;
navItems.forEach(nav => nav.classList.remove('active'));
item.classList.add('active');
renderRecipes();
});
});
// Initial Render
renderRecipes();