Skip to content

Commit

Permalink
FEATURE: Recipe For The Day Suggestion section
Browse files Browse the repository at this point in the history
Fixes #328
  • Loading branch information
sanchitc05 committed Nov 3, 2024
1 parent acb0156 commit cb96be2
Show file tree
Hide file tree
Showing 3,644 changed files with 133,667 additions and 0 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
55 changes: 55 additions & 0 deletions backend/Controllers/RecipeController.js
Original file line number Diff line number Diff line change
Expand Up @@ -647,3 +647,58 @@ const RecipeController = {
};

export default RecipeController;

export const getRecipeOfTheDay = async (req, res) => {
try {
const today = new Date();
today.setHours(0, 0, 0, 0);

let recipeOfTheDay = await Recipe.findOne({
featured: true,
lastFeatured: { $gte: today }
});

if (!recipeOfTheDay) {
await Recipe.updateMany(
{ featured: true },
{ featured: false, lastFeatured: null }
);

const lastWeek = new Date(today);
lastWeek.setDate(lastWeek.getDate() - 7);

const eligibleRecipes = await Recipe.find({
$or: [
{ lastFeatured: null },
{ lastFeatured: { $lt: lastWeek } }
]
});

if (eligibleRecipes.length > 0) {
const randomIndex = Math.floor(Math.random() * eligibleRecipes.length);
recipeOfTheDay = eligibleRecipes[randomIndex];
} else {
const count = await Recipe.countDocuments();
const random = Math.floor(Math.random() * count);
recipeOfTheDay = await Recipe.findOne().skip(random);
}

recipeOfTheDay.featured = true;
recipeOfTheDay.lastFeatured = today;
await recipeOfTheDay.save();
}

res.status(200).json({
success: true,
recipe: recipeOfTheDay
});

} catch (error) {
console.error('Error in getRecipeOfTheDay:', error);
res.status(500).json({
success: false,
message: "Error fetching Recipe of the Day",
error: error.message
});
}
};
8 changes: 8 additions & 0 deletions backend/models/Recipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ const recipeSchema = new mongoose.Schema({
type: {
type: [String],
required: true
},
featured: {
type: Boolean,
default: false
},
lastFeatured: {
type: Date,
default: null
}
});

Expand Down
2 changes: 2 additions & 0 deletions backend/routes/web.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,5 @@ router.delete(

router.patch("/recipe/share/:recipeId", authenticateToken, RecipeController.updateShareCount);
export default router;

router.get('/recipe-of-the-day', getRecipeOfTheDay);
59 changes: 59 additions & 0 deletions frontend/src/Components/RecipeOfTheDay.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { useNavigate } from 'react-router-dom';

const RecipeOfTheDay = () => {
const [recipe, setRecipe] = useState(null);
const [loading, setLoading] = useState(true);
const navigate = useNavigate();
const backendURL = import.meta.env.VITE_BACKEND_URL;

useEffect(() => {
const fetchRecipeOfTheDay = async () => {
try {
const response = await axios.get(`${backendURL}/api/recipe-of-the-day`);
if (response.data.success) {
setRecipe(response.data.recipe);
} else {
console.error('Failed to fetch recipe:', response.data.message);
}
} catch (error) {
console.error('Error fetching Recipe of the Day:', error);
} finally {
setLoading(false);
}
};

fetchRecipeOfTheDay();
}, [backendURL]);

if (loading) {
return <div className="text-center">Loading Recipe of the Day...</div>;
}

if (!recipe) {
return <div className="text-center">No Recipe of the Day available.</div>;
}

return (
<div className="bg-white shadow-lg rounded-lg overflow-hidden">
<img
src={recipe.image}
alt={recipe.name}
className="w-full h-64 object-cover"
/>
<div className="p-6">
<h2 className="text-2xl font-bold text-red-700 mb-2">{recipe.name}</h2>
<p className="text-gray-600 mb-4">{recipe.description}</p>
<button
onClick={() => navigate(`/recipe/${recipe._id}`, { state: { dish: recipe } })}
className="bg-red-700 text-white px-4 py-2 rounded hover:bg-red-600 transition-colors"
>
View Recipe
</button>
</div>
</div>
);
};

export default RecipeOfTheDay;
9 changes: 9 additions & 0 deletions frontend/src/Pages/Landing.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useNavigate } from "react-router-dom";
import axios from "axios";
import RecipeCardSkeleton from "./RecipeSkeleton.jsx";
import Testimonial from "../Components/Testimonial.jsx";
import RecipeOfTheDay from '../Components/RecipeOfTheDay.jsx';

const Landing = () => {
const navigator = useNavigate();
Expand Down Expand Up @@ -187,6 +188,14 @@ const Landing = () => {
)}
</section>

{/* -------------------------- Recipe of the Day Section ---------------------- */}
<section id="RecipeOfTheDay" className="py-4 my-20 mx-8">
<h1 className="text-center font-semibold text-4xl text-red-700 my-4 font-[Merriweather]">
Recipe of the Day
</h1>
<RecipeOfTheDay />
</section>

{/* -------------------------- About Section ---------------------- */}
<section
className="text-gray-600 body-font overflow-hidden py-4 my-20 mx-8"
Expand Down
1 change: 1 addition & 0 deletions node_modules/.bin/conc

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions node_modules/.bin/concurrently

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions node_modules/.bin/tree-kill

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit cb96be2

Please sign in to comment.