From df557ec667db389867e1fe480ac8aeb440a0f083 Mon Sep 17 00:00:00 2001 From: Mahmoud khairy Date: Sat, 6 Jul 2024 20:15:55 +0300 Subject: [PATCH 1/4] apply react-helmet --- wannameal/package-lock.json | 28 + wannameal/package.json | 1 + wannameal/public/index.html | 2 +- .../src/components/MyRecips/MyRecips.jsx | 147 ++-- .../src/pages/RecipeDetails/RecipeDetails.jsx | 28 +- wannameal/src/pages/addProduct/addProduct.jsx | 709 +++++++++--------- wannameal/src/pages/chatting/chatting.jsx | 9 + wannameal/src/pages/community/comunity.jsx | 11 +- wannameal/src/pages/contact/contact.jsx | 5 + wannameal/src/pages/dashboeard/dashboard.jsx | 5 + wannameal/src/pages/makeMeal/makeMeal.jsx | 14 +- wannameal/src/pages/profile/profile.jsx | 41 +- .../src/redux/slices/recomendedMealsSlice.jsx | 24 +- 13 files changed, 575 insertions(+), 449 deletions(-) diff --git a/wannameal/package-lock.json b/wannameal/package-lock.json index a2c3491..e9c9bf7 100644 --- a/wannameal/package-lock.json +++ b/wannameal/package-lock.json @@ -22,6 +22,7 @@ "jwt-decode": "^4.0.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-helmet": "^6.1.0", "react-i18next": "^14.1.2", "react-icons": "^5.1.0", "react-input-emoji": "^5.9.0", @@ -15582,6 +15583,25 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" + }, + "node_modules/react-helmet": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz", + "integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==", + "dependencies": { + "object-assign": "^4.1.1", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.1.1", + "react-side-effect": "^2.1.0" + }, + "peerDependencies": { + "react": ">=16.3.0" + } + }, "node_modules/react-i18next": { "version": "14.1.2", "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-14.1.2.tgz", @@ -15771,6 +15791,14 @@ } } }, + "node_modules/react-side-effect": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.2.tgz", + "integrity": "sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==", + "peerDependencies": { + "react": "^16.3.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-smooth": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.1.tgz", diff --git a/wannameal/package.json b/wannameal/package.json index 477c39f..fbbcc9e 100644 --- a/wannameal/package.json +++ b/wannameal/package.json @@ -17,6 +17,7 @@ "jwt-decode": "^4.0.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-helmet": "^6.1.0", "react-i18next": "^14.1.2", "react-icons": "^5.1.0", "react-input-emoji": "^5.9.0", diff --git a/wannameal/public/index.html b/wannameal/public/index.html index fa9ffd9..d860711 100644 --- a/wannameal/public/index.html +++ b/wannameal/public/index.html @@ -24,7 +24,7 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - React App + WannaMeal diff --git a/wannameal/src/components/MyRecips/MyRecips.jsx b/wannameal/src/components/MyRecips/MyRecips.jsx index b085764..5da5c83 100644 --- a/wannameal/src/components/MyRecips/MyRecips.jsx +++ b/wannameal/src/components/MyRecips/MyRecips.jsx @@ -1,79 +1,86 @@ -import React from "react"; +import React, { useEffect } from "react"; import style from "./MyRecips.module.css"; import MealCard from "../mealCard/mealCard"; +import { MdSmsFailed } from "react-icons/md"; + import noMeals from "../../assets/nomeals.gif"; -export default function MyRecips() { - const meals = [ - // { - // index: 488, - // name: "النجريسكو", - // time: "غداء", - // ingredients: - // "400 صدور دجاج، مخلية ومقطعة إلى قطع صغيرة الحجم. , الملح والفلفل حسب الذوق. , 2 فص الثوم مفروم. , 80 جم زيت زيتون. , 70 جم دقيق. , 400 مل لبن كامل الدسم. , 400 جم مكرونة بينا. , 100 جم جبنة شيدر مبشورة. , 50 جم جبنة بارميزان مبشورة. ", - // prep: " اطهى المكرونة وفقا للتعليمات على الكيس، ثم صفيها وضعيها جانباً. , فى هذه الأثناء فى حلة صلصة كبيرة، اضيفى زيت الزيتون، والدجاج، الثوم، والملح والفلفل، ثم حمريها على نار متوسطة إلى منخفضة، واطهى الدجاج مع التحريك المستمر، حتى لم يعد لونه وردى اضيفى الدقيق وقلبيه حتى يمتص كل السائل ويصبح كالمعجون الذى يغطى الدجاج. , ببطء اضيفى اللبن مع التحريك المستمر، حتى يكون لديكِ صلصة كريمية خفيفة من البشاميل. , ارفعى الحلة من على النار، اضيفى الجبن الشيدر وقلبيه حتى يتم توزيعه بشكل جيد. , اضيفي المكرونة المطبوخة وقلبيها حتى يتم توزيعها جيداً، صبى الخليط كله فى صينية فرن عميقة، ثم رشى على السطح الجبن البارميزان. , اخبزيها فى الفرن على 210درجة مئوية، حتى يصبح الوجه لونه بنياً ذهبياً، ثم تقدم ساخنة. ", - // img_link: { - // url: "https://res.cloudinary.com/dz5dpvxg7/image/upload/v1718750274/WannaMeal/recommend/ocrxycya2j0ieo9suqg7.jpg", - // id: "WannaMeal/recommend/ocrxycya2j0ieo9suqg7", - // }, - // calories: 1061, - // prep_time: 30, - // no_of_ppl: 4, - // }, - // { - // index: 152, - // name: "الأرز بالزعفران", - // time: "غداء", - // ingredients: - // " 400 جم أرز بسمتي مغسول. , 810 مل مرق دجاج أو مرق خضار. , 150 جم بصل أصفر مفروم ناعمًا. , 1 ملعقة صغيرة زعفران. , 60 مل ماء مغلي. , 2 ملعقة كبيرة زيت زيتون. , 1 ملعقة صغيرة ملح. ", - // prep: " ضعي الزعفران في وعاء صغير، ثم أضيفي الماء المغلي، وقلبي جيدًا، ثم اتركيه جانبًا لمدة خمس دقائق. , سخني الزيت في قدر كبير على نار متوسطة، ثم أضيفي البصل وقلبيه لمدة ثماني إلى عشر دقائق حتى يتكرمل. , أضيفي الأرز وقلبي لمدة دقيقة، ثم أضيفي خليط الزعفران والمرق والملح، وقلبي جيدًا، واتركيه حتى يغلي. , غطي القدر، واتركيه على نار هادئة مدة 30 دقيقة حتى ينضج. , ضعي الأرز في أطباق التقديم، وقدميه ساخنًا مع الدجاج والسلطات. ", - // img_link: { - // url: "https://res.cloudinary.com/dz5dpvxg7/image/upload/v1718750275/WannaMeal/recommend/rqyhl3iqkk5fndudnjmu.jpg", - // id: "WannaMeal/recommend/rqyhl3iqkk5fndudnjmu", - // }, - // calories: 454.99, - // prep_time: 50, - // no_of_ppl: 4, - // }, - // { - // index: 154, - // name: "الكوارع", - // time: "غداء", - // ingredients: - // " 1500 مل من الماء المغلي , 1000 جم كوارع مقطعة , بصلة كبيرة مفرومة ناعمًا , بصلة صغيرة مقطعة مكعبات صغيرة , 200 جم فلفل أخضر حار مفروم , 4 ثمرات طماطم مقشرة، ومفرومة ناعمًا , 6 فصوص ثوم مهروس , 2 ملعقة كبيرة خل أبيض , 4 معلقة كبيرة زيت , 1 ملعقة كبيرة زبدة في درجة حرارة الغرفة , 1 ملعقة كبيرة صلصة طماطم , 3 ورقات لورا , عود قرفة , 5 حبات حبهان , 4 حبات قرنفل , 1 ملعقة صغيرة فلفل أسود حصى , ملح وفلفل أسود ", - // prep: " انقعي الكوارع في ماء وخل وملح وعصير ليمون لمدة ساعة. , صفي الكوارع من الماء، واغسليها جيدًا تحت الماء الجاري مرتين. , على نار متوسطة، ضعي الكوارع والملح والفلفل الأسود، ثم غطيها بالماء، واتركيها حتى تغلي. , صفي الكوارع من الماء، واتركيها جانبًا. , على نار متوسطة، ضعي الزبدة ونصف كمية الزيت، واتركيهما حتى تذوب الزبدة. , أضيفي الكوارع، وقلبيها لمدة 5 دقائق، ثم أضيفي ورق اللورا والقرفة والحبهان والقرنفل والفلفل الحصى، وقلبي لمدة دقيقة. , أضيفي البصل المفروم، وقلبي لمدة دقيقتين، ثم أضيفي الماء، واتركيه حتى تغلي. , غطي القدر، واتركي الكوارع على نار هادئة جدًّا لمدة ساعة حتى تنضج. , على نار متوسطة، سخني الزيت، ثم أضيفي مكعبات البصل الصغيرة، وقلبيها حتى تذبل ويصفر لونها. , أضيفي الثوم والفلفل الحار، وقلبي لمدة دقيقة، ثم أضيفي الطماطم المفرومة وصلصة الطماطم والملح والفلفل الأسود، وقلبي لمدة دقيقة. , اتركي الصلصة على النار حتى تغلي، ثم غطي القرد واتركيها على نار هادئة جدًّا لمدة 10 دقائق. , أضيفي الخل واتركيها لمدة دقيقة، ثم أضيفي الكوارع، وكوبًا من شوربة الكوارع، واتركيها على نار هادئة لمدة 15 دقيقة، ثم قدميها ساخنة. ", - // img_link: { - // url: "https://res.cloudinary.com/dz5dpvxg7/image/upload/v1718750275/WannaMeal/recommend/urvgyfbjd3aak0njsl6u.jpg", - // id: "WannaMeal/recommend/urvgyfbjd3aak0njsl6u", - // }, - // calories: 150, - // prep_time: 105, - // no_of_ppl: 6, - // }, - ]; +import { useDispatch, useSelector } from "react-redux"; +import { + fetchMyRecipes, + fetchSavedMeals, + getMealsError, + getMealsStatus, + getMyRecipes, + getSavedMeals, +} from "../../redux/slices/recomendedMealsSlice"; +import { getDecodedToken } from "../../redux/slices/authSlice"; +import Loading from "../loading/loading"; +import { getLanguage } from "../../redux/slices/language"; +export default function SavedMeals() { + const decodedToken = useSelector(getDecodedToken); + console.log("🚀 ~ SavedMeals ~ decodedToken:", decodedToken); + const mealsError = useSelector(getMealsError); + const mealsStatus = useSelector(getMealsStatus); + const dispatch = useDispatch(); + const language = useSelector(getLanguage); + const myRecips = useSelector(getMyRecipes); + console.log("🚀 ~ SavedMeals ~ myRecips:", myRecips); + + useEffect(() => { + if (decodedToken?.id) { + const fetchMeals = async () => { + await dispatch( + fetchMyRecipes({ userId: decodedToken?.id, lang: language }) + ); + }; + fetchMeals(); + } + }, []); + + if (mealsStatus === "loading") + return ( +
+ +
+ ); + + if (mealsError) + return ( +
+

+ {mealsError} + +

+
+ ); return ( - <> -
- {meals && meals.length > 0 ? ( - meals.map((meal) => { - return ; - }) - ) : ( -
-
- +
+
+
+ {myRecips && myRecips.length > 0 ? ( + myRecips.map((meal) => ( +
+ +
+ )) + ) : ( +
+
+ +
+

+ You haven't published any recipe yet. +

+

+ Post your first recipe and you'll find it here. +

-

- You haven't published any recipe yet. -

-

- Post your first recipe and you'll find it here. -

-
- )} + )} +
- +
); } diff --git a/wannameal/src/pages/RecipeDetails/RecipeDetails.jsx b/wannameal/src/pages/RecipeDetails/RecipeDetails.jsx index 6d3b49d..99db405 100644 --- a/wannameal/src/pages/RecipeDetails/RecipeDetails.jsx +++ b/wannameal/src/pages/RecipeDetails/RecipeDetails.jsx @@ -8,17 +8,17 @@ import { useLocation } from "react-router-dom"; import MealCard from "../../components/mealCard/mealCard"; import CommonMeals from "../../components/commonMeals/commonMeals"; import { useTranslation } from "react-i18next"; +import { Helmet } from "react-helmet"; const RecipeDetails = () => { - const location = useLocation(); const { meal } = location.state || {}; console.log("🚀 ~ RecipeDetails ~ meal:", meal); - const stepsArray = meal?.steps ? meal.steps.split(',') : []; - const ingredientsArray = meal?.steps ? meal.ingredients.split(',') : []; + const stepsArray = meal?.steps ? meal.steps.split(",") : []; + const ingredientsArray = meal?.steps ? meal.ingredients.split(",") : []; console.log(stepsArray); - let x = [1, 2, 35, 459, 88, 113, 87, 2] - const { t } = useTranslation() + let x = [1, 2, 35, 459, 88, 113, 87, 2]; + const { t } = useTranslation(); const { apply, minutes, @@ -26,15 +26,17 @@ const RecipeDetails = () => { people, Ingredients, Directions, - Latest - } = t('View'); + Latest, + } = t("View"); return (
+ + Recipe Detailes + +
-

- {meal.recipeName} -

+

{meal.recipeName}

@@ -110,7 +112,6 @@ const RecipeDetails = () => {
{ingredientsArray?.map((x, ind) => { - return (
{ {ind + 1}

{x}

- ) + ); })}
@@ -127,7 +128,6 @@ const RecipeDetails = () => {
{stepsArray?.map((x, ind) => { - return (
{ {ind + 1}

{x}

- ) + ); })}
diff --git a/wannameal/src/pages/addProduct/addProduct.jsx b/wannameal/src/pages/addProduct/addProduct.jsx index 57272c2..bd103d6 100644 --- a/wannameal/src/pages/addProduct/addProduct.jsx +++ b/wannameal/src/pages/addProduct/addProduct.jsx @@ -1,366 +1,401 @@ -import React, { useState } from 'react'; +import React, { useState } from "react"; import style from "./page.module.css"; import { BiSolidTrash } from "react-icons/bi"; import { IoMdAddCircleOutline } from "react-icons/io"; import { MdCheckCircleOutline } from "react-icons/md"; import { CiCamera } from "react-icons/ci"; import axios from "axios"; -import { useTranslation } from 'react-i18next'; -import { useSelector } from 'react-redux'; -import { getuser } from '../../redux/slices/authSlice'; +import { useTranslation } from "react-i18next"; +import { useSelector } from "react-redux"; +import { getuser } from "../../redux/slices/authSlice"; +import { Helmet } from "react-helmet"; -const AddProduct = () => { // Changed from addProduct to AddProduct - const [ingredientsValue, setIngredientsValue] = useState([{ id: 1, value: "" }]); - const [directionsValue, setDirectionsValue] = useState([{ id: 1, value: "" }]); - const [isActive, setisActive] = useState(""); - const [image, setImage] = useState(null); - const { t } = useTranslation() - const { Rname, Special, share, breaks, lunch, dinner, enough, time, Ingredients, Directions, addingredient, addStep, saveRecipe, cancelRecipe } = t('add') - const user = useSelector(getuser) - const [recipe, setRecipe] = useState({ - recipeName: "", - information: "", - typeMeals: "", - times: "", - EnoughFor: "", - calories: 500, - image: null, - ingredients: [], - steps: [], - }); - - const handleInputChange = (e) => { - const { name, value } = e.target; - setRecipe((prevRecipe) => ({ - ...prevRecipe, - [name]: value, - })); - console.log(recipe); - }; +const AddProduct = () => { + // Changed from addProduct to AddProduct + const [ingredientsValue, setIngredientsValue] = useState([ + { id: 1, value: "" }, + ]); + const [directionsValue, setDirectionsValue] = useState([ + { id: 1, value: "" }, + ]); + const [isActive, setisActive] = useState(""); + const [image, setImage] = useState(null); + const { t } = useTranslation(); + const { + Rname, + Special, + share, + breaks, + lunch, + dinner, + enough, + time, + Ingredients, + Directions, + addingredient, + addStep, + saveRecipe, + cancelRecipe, + } = t("add"); + const user = useSelector(getuser); + const [recipe, setRecipe] = useState({ + recipeName: "", + information: "", + typeMeals: "", + times: "", + EnoughFor: "", + calories: 500, + image: null, + ingredients: [], + steps: [], + }); - const handleFileChange = (e) => { - const file = e.target.files[0]; - setRecipe((prevRecipe) => ({ - ...prevRecipe, - image: file, - })); - setImage(URL.createObjectURL(file)); - }; + const handleInputChange = (e) => { + const { name, value } = e.target; + setRecipe((prevRecipe) => ({ + ...prevRecipe, + [name]: value, + })); + console.log(recipe); + }; - const handleAddIngredient = () => { - const newIngredient = { id: ingredientsValue.length + 1, value: "" }; - setIngredientsValue([...ingredientsValue, newIngredient]); - setRecipe((prevRecipe) => ({ - ...prevRecipe, - ingredients: [...ingredientsValue, newIngredient], - })); - }; + const handleFileChange = (e) => { + const file = e.target.files[0]; + setRecipe((prevRecipe) => ({ + ...prevRecipe, + image: file, + })); + setImage(URL.createObjectURL(file)); + }; - const handleAddDirection = () => { - const newDirection = { id: directionsValue.length + 1, value: "" }; - setDirectionsValue([...directionsValue, newDirection]); - setRecipe((prevRecipe) => ({ - ...prevRecipe, - steps: [...directionsValue, newDirection], - })); - }; + const handleAddIngredient = () => { + const newIngredient = { id: ingredientsValue.length + 1, value: "" }; + setIngredientsValue([...ingredientsValue, newIngredient]); + setRecipe((prevRecipe) => ({ + ...prevRecipe, + ingredients: [...ingredientsValue, newIngredient], + })); + }; - const handleIngredientChange = (index, value) => { - const updatedIngredients = [...ingredientsValue]; - updatedIngredients[index].value = value; - setIngredientsValue(updatedIngredients); - setRecipe((prevRecipe) => ({ - ...prevRecipe, - ingredients: updatedIngredients, - })); - }; + const handleAddDirection = () => { + const newDirection = { id: directionsValue.length + 1, value: "" }; + setDirectionsValue([...directionsValue, newDirection]); + setRecipe((prevRecipe) => ({ + ...prevRecipe, + steps: [...directionsValue, newDirection], + })); + }; - const handleDirectionChange = (index, value) => { - const updatedDirections = [...directionsValue]; - updatedDirections[index].value = value; - setDirectionsValue(updatedDirections); - setRecipe((prevRecipe) => ({ - ...prevRecipe, - steps: updatedDirections, - })); - }; + const handleIngredientChange = (index, value) => { + const updatedIngredients = [...ingredientsValue]; + updatedIngredients[index].value = value; + setIngredientsValue(updatedIngredients); + setRecipe((prevRecipe) => ({ + ...prevRecipe, + ingredients: updatedIngredients, + })); + }; - const handleRemoveIngredient = (index) => { - const updatedIngredients = [...ingredientsValue]; - updatedIngredients.splice(index, 1); - setIngredientsValue(updatedIngredients); - setRecipe((prevRecipe) => ({ - ...prevRecipe, - ingredients: updatedIngredients, - })); - }; + const handleDirectionChange = (index, value) => { + const updatedDirections = [...directionsValue]; + updatedDirections[index].value = value; + setDirectionsValue(updatedDirections); + setRecipe((prevRecipe) => ({ + ...prevRecipe, + steps: updatedDirections, + })); + }; - const handleRemoveDirection = (index) => { - const updatedDirections = [...directionsValue]; - updatedDirections.splice(index, 1); - setDirectionsValue(updatedDirections); - setRecipe((prevRecipe) => ({ - ...prevRecipe, - steps: updatedDirections, - })); - }; + const handleRemoveIngredient = (index) => { + const updatedIngredients = [...ingredientsValue]; + updatedIngredients.splice(index, 1); + setIngredientsValue(updatedIngredients); + setRecipe((prevRecipe) => ({ + ...prevRecipe, + ingredients: updatedIngredients, + })); + }; - const clearInputs = () => { - setRecipe({ - recipeName: "", - information: "", - typeMeals: "", - times: "", - EnoughFor: "", - calories: 500, - image: null, - ingredients: [], - steps: [], - }); - setImage(null); - setIngredientsValue([{ id: 1, value: "" }]); - setDirectionsValue([{ id: 1, value: "" }]); - setisActive('') - }; + const handleRemoveDirection = (index) => { + const updatedDirections = [...directionsValue]; + updatedDirections.splice(index, 1); + setDirectionsValue(updatedDirections); + setRecipe((prevRecipe) => ({ + ...prevRecipe, + steps: updatedDirections, + })); + }; + const clearInputs = () => { + setRecipe({ + recipeName: "", + information: "", + typeMeals: "", + times: "", + EnoughFor: "", + calories: 500, + image: null, + ingredients: [], + steps: [], + }); + setImage(null); + setIngredientsValue([{ id: 1, value: "" }]); + setDirectionsValue([{ id: 1, value: "" }]); + setisActive(""); + }; - const handleAddRecipe = async (e) => { - e.preventDefault(); - // take the value only - const ingredients = ingredientsValue.map((ingredient) => ingredient.value); - const directions = directionsValue.map((direction) => direction.value); - // add data to form - const formData = new FormData(); - formData.append("recipeName", recipe.recipeName); - formData.append("information", recipe.information); - formData.append("typeMeals", recipe.typeMeals); - formData.append("times", recipe.times); - formData.append("EnoughFor", recipe.EnoughFor); - formData.append("calories", recipe.calories); - formData.append("image", recipe.image); - formData.append("ingredients", JSON.stringify(ingredients)); - formData.append("steps", JSON.stringify(directions)); - - try { - const response = await axios.post( - "https://fast-plat1.vercel.app/meals/addAnewRecipe", - formData, - { - headers: { - "Content-Type": "multipart/form-data", - token: - user?.token, - }, - } - ); + const handleAddRecipe = async (e) => { + e.preventDefault(); + // take the value only + const ingredients = ingredientsValue.map((ingredient) => ingredient.value); + const directions = directionsValue.map((direction) => direction.value); + // add data to form + const formData = new FormData(); + formData.append("recipeName", recipe.recipeName); + formData.append("information", recipe.information); + formData.append("typeMeals", recipe.typeMeals); + formData.append("times", recipe.times); + formData.append("EnoughFor", recipe.EnoughFor); + formData.append("calories", recipe.calories); + formData.append("image", recipe.image); + formData.append("ingredients", JSON.stringify(ingredients)); + formData.append("steps", JSON.stringify(directions)); - console.log(response.data); - // Handle success - clearInputs(); - } catch (error) { - console.error(error.response.data); - // Handle error + try { + const response = await axios.post( + "https://fast-plat1.vercel.app/meals/addAnewRecipe", + formData, + { + headers: { + "Content-Type": "multipart/form-data", + token: user?.token, + }, } - }; - console.log(user) - return ( -
-
-
- + + Add Meal + + +
+
+ + +
+ + + +
+
+

{enough}

+ +
+
+

{time}

+ +
+
+
+
+

{Ingredients}

+
+
+ {ingredientsValue.map((ingredient, index) => ( +
+
{index + 1}
+ handleIngredientChange(index, e.target.value)} + /> + handleRemoveIngredient(index)} + />
-
- - + ))} + +
+
+

{Directions}

+
+
+ {directionsValue.map((direction, index) => ( +
+
{index + 1}
+ handleDirectionChange(index, e.target.value)} + /> + handleRemoveDirection(index)} + />
+ ))} +
- ); +
+
+ + +
+
+ ); }; export default AddProduct; // Changed from addProduct to AddProduct diff --git a/wannameal/src/pages/chatting/chatting.jsx b/wannameal/src/pages/chatting/chatting.jsx index ecd523a..e91b5aa 100644 --- a/wannameal/src/pages/chatting/chatting.jsx +++ b/wannameal/src/pages/chatting/chatting.jsx @@ -7,6 +7,8 @@ import { VscSend } from "react-icons/vsc"; import InputEmoji from "react-input-emoji"; import { useSelector, useDispatch } from "react-redux"; import { getTheme } from "../../redux/slices/systemModeSlice"; +import { Helmet } from "react-helmet"; + export default function Chatting() { let chats = [1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8]; const [activeChat, setActiveChat] = useState(true); @@ -44,6 +46,13 @@ export default function Chatting() { }, []); return (
+ + WannaMeal messenger + +
diff --git a/wannameal/src/pages/community/comunity.jsx b/wannameal/src/pages/community/comunity.jsx index 3741f7c..d034d49 100644 --- a/wannameal/src/pages/community/comunity.jsx +++ b/wannameal/src/pages/community/comunity.jsx @@ -11,6 +11,8 @@ import Post from "../../components/post/post"; import { VscSend } from "react-icons/vsc"; import { useSelector, useDispatch } from "react-redux"; import { getuser, getDecodedToken } from "../../redux/slices/authSlice"; +import { Helmet } from "react-helmet"; + import { createPost, fetchFeedPosts, @@ -275,6 +277,13 @@ export default function Community() { return (
+ + WannaMeal community + +
@@ -327,7 +336,7 @@ export default function Community() { {suggestedUsers && suggestedUsers?.length > 0 ? ( suggestedUsers.map((user) => ( + + Contact Us + +
diff --git a/wannameal/src/pages/dashboeard/dashboard.jsx b/wannameal/src/pages/dashboeard/dashboard.jsx index 022b6b5..b0bcaf1 100644 --- a/wannameal/src/pages/dashboeard/dashboard.jsx +++ b/wannameal/src/pages/dashboeard/dashboard.jsx @@ -6,10 +6,15 @@ import DashNav from "../../components/dashNav/dashNav"; import Sidebar from "../../components/sidebar/sidebar"; import { Route, Routes } from "react-router-dom"; import React from "react"; +import { Helmet } from "react-helmet"; export default function Dashboard() { return (
+ + Dashboard + +
+ Make Your Meal + + ; const theme = useSelector(getTheme); const { t } = useTranslation(); - const { - make, - meal, - } = t('make'); + const { make, meal } = t("make"); return (
{ setLink(window.location.href); const handlePopState = () => { @@ -122,6 +139,10 @@ function Portfolio() { return ( <>
+ + Profile + +
@@ -152,11 +173,9 @@ function Portfolio() {
- {user?.followers?.length || 0} {followers} - {user?.following?.length || 0} {following}
@@ -182,9 +201,9 @@ function Portfolio() { className={`${styles.settingIcon}`} data-bs-target="#exampleModalToggle" data-bs-toggle="modal" - // onClick={() => { - // console.log("🚀 ~ Portfolio ~ showOverlay:", showOverlay); - // }} + // onClick={() => { + // console.log("🚀 ~ Portfolio ~ showOverlay:", showOverlay); + // }} >
diff --git a/wannameal/src/redux/slices/recomendedMealsSlice.jsx b/wannameal/src/redux/slices/recomendedMealsSlice.jsx index 48957ae..bf64a5b 100644 --- a/wannameal/src/redux/slices/recomendedMealsSlice.jsx +++ b/wannameal/src/redux/slices/recomendedMealsSlice.jsx @@ -83,6 +83,19 @@ export const fetchSavedMeals = createAsyncThunk( } } ); +export const fetchMyRecipes = createAsyncThunk( + "meals/fetchMyRecipes", + async ({ userId, lang }, { rejectWithValue }) => { + try { + const response = await axios.get( + `https://fast-plat1.vercel.app/meals?user=${userId}` + ); + return response.data.result; + } catch (error) { + return rejectWithValue(error.message); + } + } +); export const saveMeal = createAsyncThunk( "meals/saveMeal", @@ -105,17 +118,6 @@ export const saveMeal = createAsyncThunk( } ); -export const fetchMyRecipes = createAsyncThunk( - "meals/fetchMyRecipes", - async ({ userId }, { rejectWithValue }) => { - try { - const response = await axios.get(`https://fast-plat1.vercel.app/meals`); - return response.result; - } catch (error) { - return rejectWithValue(error.message); - } - } -); export const fetchCommonMeals = createAsyncThunk( "meals/fetchCommonMeals", async ({ token, lang }, { rejectWithValue }) => { From 46a5802107b344f9a4a701fc1ad5a8df6a4760ec Mon Sep 17 00:00:00 2001 From: Mahmoud khairy Date: Sat, 6 Jul 2024 21:09:40 +0300 Subject: [PATCH 2/4] helmet --- wannameal/src/pages/Home/Home.jsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wannameal/src/pages/Home/Home.jsx b/wannameal/src/pages/Home/Home.jsx index ac06e4f..62dfe0e 100644 --- a/wannameal/src/pages/Home/Home.jsx +++ b/wannameal/src/pages/Home/Home.jsx @@ -1,10 +1,15 @@ import AboutUs from "../../components/aboutUs/aboutus"; import CommonMeals from "../../components/commonMeals/commonMeals"; import LandingPage from "../../components/landingPage/LandingPage"; +import { Helmet } from "react-helmet"; export default function Home() { return ( <> + + WannaMeal + + From 3046ea5682599afebe23a96da33905e99fd8c1fa Mon Sep 17 00:00:00 2001 From: Mahmoud khairy Date: Sun, 7 Jul 2024 00:52:58 +0300 Subject: [PATCH 3/4] last changes --- .../FoodIngreientSlider/FoodIngreientSlider.jsx | 8 +++----- wannameal/src/components/mealCard/mealcard.module.css | 2 +- wannameal/src/components/navbar/navbar.jsx | 7 ++++--- wannameal/src/redux/slices/recomendedMealsSlice.jsx | 2 +- wannameal/src/redux/slices/systemModeSlice.jsx | 6 ++---- 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/wannameal/src/components/FoodIngreientSlider/FoodIngreientSlider.jsx b/wannameal/src/components/FoodIngreientSlider/FoodIngreientSlider.jsx index c48f884..90553ca 100644 --- a/wannameal/src/components/FoodIngreientSlider/FoodIngreientSlider.jsx +++ b/wannameal/src/components/FoodIngreientSlider/FoodIngreientSlider.jsx @@ -36,6 +36,7 @@ import { useTranslation } from "react-i18next"; function FoodIngreientSlider() { // const ingredients = useSelector(getIngredients); const ingredients = useSelector(getIngredients); + console.log("🚀 ~ FoodIngreientSlider ~ ingredients:", ingredients); const [checkedIngredients, setCheckedIngredients] = useState([]); const [searchQuery, setSearchQuery] = useState(""); const [filteredIngredients, setFilteredIngredients] = useState(ingredients); @@ -121,10 +122,7 @@ function FoodIngreientSlider() { fetchMeals(); }, [checkedIngredients, dispatch, language]); const { t } = useTranslation(); - const { - Choose, - searchh, - } = t('make'); + const { Choose, searchh } = t("make"); return ( <>
@@ -144,7 +142,7 @@ function FoodIngreientSlider() { placeholder={`${searchh}`} value={searchQuery} onChange={(e) => setSearchQuery(e.target.value)} - // autocomplete="off" + // autocomplete="off" />
diff --git a/wannameal/src/components/mealCard/mealcard.module.css b/wannameal/src/components/mealCard/mealcard.module.css index c1d6804..a74a7c6 100644 --- a/wannameal/src/components/mealCard/mealcard.module.css +++ b/wannameal/src/components/mealCard/mealcard.module.css @@ -3,7 +3,7 @@ width: 340px; height: 300px; border-radius: 15px; - background-image: url("../../assets/Rectangle\ 9.png"); + /* background-image: url("../../assets/Rectangle\ 9.png"); */ background-repeat: no-repeat; background-size: cover; position: relative; diff --git a/wannameal/src/components/navbar/navbar.jsx b/wannameal/src/components/navbar/navbar.jsx index d77a417..69d4aa6 100644 --- a/wannameal/src/components/navbar/navbar.jsx +++ b/wannameal/src/components/navbar/navbar.jsx @@ -219,8 +219,9 @@ function Navbar() { {/*left aside offcanvas */}
{Contact} - {loggedUser && loggedUser?.role === "user" && ( + {loggedUser && loggedUser?.role === "admin" && ( <>
  • {dashboard} diff --git a/wannameal/src/redux/slices/recomendedMealsSlice.jsx b/wannameal/src/redux/slices/recomendedMealsSlice.jsx index bf64a5b..158cea1 100644 --- a/wannameal/src/redux/slices/recomendedMealsSlice.jsx +++ b/wannameal/src/redux/slices/recomendedMealsSlice.jsx @@ -123,7 +123,7 @@ export const fetchCommonMeals = createAsyncThunk( async ({ token, lang }, { rejectWithValue }) => { try { const response = await axios.get( - `https://fast-plat1.vercel.app/meals/common-meals?lang=${lang}`, + `https://tesst11.azurewebsites.net/meals/common-meals?lang=${lang}`, { headers: { token: `${token}`, diff --git a/wannameal/src/redux/slices/systemModeSlice.jsx b/wannameal/src/redux/slices/systemModeSlice.jsx index 63a8c13..fe089a6 100644 --- a/wannameal/src/redux/slices/systemModeSlice.jsx +++ b/wannameal/src/redux/slices/systemModeSlice.jsx @@ -5,16 +5,14 @@ const loadTheme = () => { const savedTheme = localStorage.getItem("theme"); return savedTheme ? JSON.parse(savedTheme) : "dark"; } catch (err) { - return "dark"; + return "light"; } }; const saveTheme = (theme) => { try { localStorage.setItem("theme", JSON.stringify(theme)); - } catch (err) { - // Ignore write errors - } + } catch (err) {} }; const initialState = { From aead5fcbeba740c63201e9ea2cbe6240079b33c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=AAEhab=20Yousef=E2=80=AC=E2=80=8F?= <74505597+ehabyousef@users.noreply.github.com> Date: Sun, 7 Jul 2024 00:53:28 +0300 Subject: [PATCH 4/4] edit addRecipe --- wannameal/public/locales/ar/translation.json | 7 +-- wannameal/public/locales/en/translation.json | 7 +-- .../src/components/mealCard/dashCard.jsx | 2 +- wannameal/src/pages/addProduct/addProduct.jsx | 46 +++++++++++++------ 4 files changed, 40 insertions(+), 22 deletions(-) diff --git a/wannameal/public/locales/ar/translation.json b/wannameal/public/locales/ar/translation.json index a4ac0a9..8b56d5f 100644 --- a/wannameal/public/locales/ar/translation.json +++ b/wannameal/public/locales/ar/translation.json @@ -60,7 +60,8 @@ "addingredient": "أضف مكون", "addStep": "أضف خطوة", "saveRecipe": "احفظ الوصفة", - "cancelRecipe": "ألغِ الوصفة" + "cancelRecipe": "ألغِ الوصفة", + "caloriess": "السعرات" }, "contact": { "head": "تواصل معنا", @@ -160,7 +161,7 @@ "Profile": "الملف الشخصى", "Contact": "تواصل معنا", "logoutt": "تسجيل الخروج", - "dashboard":"لوحة التحكم", -"makeMeal":" اضافة وجبه" + "dashboard": "لوحة التحكم", + "makeMeal": " اضافة وجبه" } } diff --git a/wannameal/public/locales/en/translation.json b/wannameal/public/locales/en/translation.json index 2e68299..f6f5a23 100644 --- a/wannameal/public/locales/en/translation.json +++ b/wannameal/public/locales/en/translation.json @@ -60,7 +60,8 @@ "addingredient": "add ingredient", "addStep": "add Step", "saveRecipe": "save Recipe", - "cancelRecipe": "cancel Recipe" + "cancelRecipe": "cancel Recipe", + "caloriess": "calories" }, "contact": { "head": "get in touch", @@ -160,7 +161,7 @@ "Profile": "My Profile", "Contact": "Contact Us", "logoutt": "logout", - "dashboard":"dashboard", -"makeMeal":"Add Recipe" + "dashboard": "dashboard", + "makeMeal": "Add Recipe" } } diff --git a/wannameal/src/components/mealCard/dashCard.jsx b/wannameal/src/components/mealCard/dashCard.jsx index b73c696..c9585fc 100644 --- a/wannameal/src/components/mealCard/dashCard.jsx +++ b/wannameal/src/components/mealCard/dashCard.jsx @@ -8,7 +8,7 @@ import { Link } from "react-router-dom"; function DashCard({ meal }) { return ( <> - +
    { ]); const [isActive, setisActive] = useState(""); const [image, setImage] = useState(null); + const [randomNumber, setRandomNumber] = useState(null); const { t } = useTranslation(); const { Rname, @@ -36,7 +37,13 @@ const AddProduct = () => { addStep, saveRecipe, cancelRecipe, + caloriess, } = t("add"); + useEffect(() => { + const randomNum = Math.floor(Math.random() * 100) + 1; // Generate random number between 1 and 100 + setRandomNumber(randomNum); + }, []) + const user = useSelector(getuser); const [recipe, setRecipe] = useState({ recipeName: "", @@ -44,7 +51,8 @@ const AddProduct = () => { typeMeals: "", times: "", EnoughFor: "", - calories: 500, + calories: null, + _id: 24, image: null, ingredients: [], steps: [], @@ -104,6 +112,7 @@ const AddProduct = () => { ...prevRecipe, steps: updatedDirections, })); + console.log(recipe); }; const handleRemoveIngredient = (index) => { @@ -157,10 +166,10 @@ const AddProduct = () => { formData.append("times", recipe.times); formData.append("EnoughFor", recipe.EnoughFor); formData.append("calories", recipe.calories); + formData.append("_id", recipe._id); formData.append("image", recipe.image); - formData.append("ingredients", JSON.stringify(ingredients)); - formData.append("steps", JSON.stringify(directions)); - + formData.append("ingredients", JSON.stringify(ingredients.join(','))); + formData.append("steps", JSON.stringify(directions.join(','))); try { const response = await axios.post( "https://fast-plat1.vercel.app/meals/addAnewRecipe", @@ -181,7 +190,6 @@ const AddProduct = () => { // Handle error } }; - console.log(user); return (
    @@ -217,9 +225,8 @@ const AddProduct = () => { target: { name: "typeMeals", value: "Breakfast" }, }); }} - className={`${style.recipe_type} ${ - isActive === "Breakfast" ? style.recipe_active : "" - }`} + className={`${style.recipe_type} ${isActive === "Breakfast" ? style.recipe_active : "" + }`} name="Breakfast" > {breaks} @@ -231,9 +238,8 @@ const AddProduct = () => { target: { name: "typeMeals", value: "Lunch" }, }); }} - className={`${style.recipe_type} ${ - isActive === "Lunch" ? style.recipe_active : "" - }`} + className={`${style.recipe_type} ${isActive === "Lunch" ? style.recipe_active : "" + }`} name="Lunch" > {lunch} @@ -245,9 +251,8 @@ const AddProduct = () => { target: { name: "typeMeals", value: "Dinner" }, }); }} - className={`${style.recipe_type} ${ - isActive === "Dinner" ? style.recipe_active : "" - }`} + className={`${style.recipe_type} ${isActive === "Dinner" ? style.recipe_active : "" + }`} name="Dinner" > {dinner} @@ -275,6 +280,17 @@ const AddProduct = () => { placeholder="How much time?" />
    +
    +

    {caloriess}

    + +