diff --git a/api/index.js b/api/index.js index 2a68ec0..1dc3ea2 100644 --- a/api/index.js +++ b/api/index.js @@ -2,7 +2,7 @@ const server = require('./src/app.js'); const { conn, Diet } = require('./src/db.js'); const {DB_PORT} = process.env const dietTypes = require('./src/utils/apispoon') - +const { getApi } = require("./src/getApiRecipes/getApiRecipe") // import dietTypes from './src/utils/apispoon' // Syncing all the models at once. @@ -26,4 +26,6 @@ conn.sync({ alter: true }).then(() => { }) }); + + getApi() }); \ No newline at end of file diff --git a/api/package.json b/api/package.json index f76ced8..77512a9 100644 --- a/api/package.json +++ b/api/package.json @@ -22,7 +22,8 @@ "nodemailer": "^6.8.0", "pg": "^8.8.0", "sequelize": "^6.23.2", - "stripe": "^10.13.0" + "stripe": "^10.13.0", + "uuid": "^9.0.0" }, "devDependencies": { "nodemon": "^2.0.20" diff --git a/api/src/controllers/recipecontrollers.js b/api/src/controllers/recipecontrollers.js index 44af5f9..0cd6d42 100644 --- a/api/src/controllers/recipecontrollers.js +++ b/api/src/controllers/recipecontrollers.js @@ -83,6 +83,8 @@ const updateRecipe = async (id) => { } + + module.exports = { getApiRecipeByID, createRecipe, diff --git a/api/src/controllers/recipescontrollers.js b/api/src/controllers/recipescontrollers.js index 5cf23e8..c8a0496 100644 --- a/api/src/controllers/recipescontrollers.js +++ b/api/src/controllers/recipescontrollers.js @@ -2,38 +2,41 @@ const axios = require ("axios") const { API_KEY } = process.env const { Recipe, Diet } = require("../db.js") // import dietTypes from '../utils/apispoon' +const uuid = require('uuid'); -const getApiRecipes = async() => { - try { +// const getApiRecipes = async() => { +// try { - const axiosResponse = await axios.get(`https://api.spoonacular.com/recipes/complexSearch?apiKey=${API_KEY}&addRecipeInformation=true&number=100`) - const { results } = axiosResponse.data; +// const axiosResponse = await axios.get(`https://api.spoonacular.com/recipes/complexSearch?apiKey=${API_KEY}&addRecipeInformation=true&number=100`) +// const { results } = axiosResponse.data; - if(results !== 0 ) { - let dishRecipe = await results?.map((e) => { - return { - id: e.id, - name: e.title, - healthScore: e.healthScore, - image: e.image, - banned: e.banned, - summary: e.summary, - //cuisines: e.cuisines?.map(ele => ele), - //dishTypes: e.dishTypes?.map(ele => ele), - diets: e.diets?.map(ele => ele), - createdInDB: false - //ingredients: e.analyzedInstructions[0].steps?.map(ele => ele.ingredients.name): "does not have any ingredient" - } - }) - return dishRecipe - } +// if(results !== 0 ) { +// let dishRecipe = await results?.map((e) => { +// return { +// //id: uuid.v4(), +// id: e.id, +// name: e.title, +// healthScore: e.healthScore, +// image: e.image, +// banned: e.banned, +// summary: e.summary, +// //cuisines: e.cuisines?.map(ele => ele), +// //dishTypes: e.dishTypes?.map(ele => ele), +// diets: e.diets?.map(ele => ele), +// createdInDB: false +// //ingredients: e.analyzedInstructions[0].steps?.map(ele => ele.ingredients.name): "does not have any ingredient" +// } +// }) +// return dishRecipe +// } + +// } catch(error) { +// console.log(error) +// } +// } - } catch(error) { - console.log(error) - } -} const getDBRecipes = async() => { @@ -72,6 +75,7 @@ const getApiNameRecipes = async(name) => { if(results !==0) { let dishName = results?.map((el) => { return { + id: el.id, name: el.title, healthScore: el.healthScore, @@ -124,7 +128,7 @@ const getDBNameRecipes = async(name) => { const getAllInfo = async() => { try { - let data = await getApiRecipes() + let data //await getApiRecipes() let dbData = await getDBRecipes() if(!dbData || dbData.length === 0) { diff --git a/api/src/controllers/usersControllers/PostRanking.controllers.js b/api/src/controllers/usersControllers/PostRanking.controllers.js new file mode 100644 index 0000000..7376461 --- /dev/null +++ b/api/src/controllers/usersControllers/PostRanking.controllers.js @@ -0,0 +1,156 @@ +const { User, Post, Recipe, Ranking } = require("../../db"); + +const getAllPost = async (userId) =>{ + try { + let user = await User.findByPk(userId, { include: Post } ) + let posts = user.posts + let post =[] + // console.log('user',user); + // console.log('posts',posts); + //return await User.findByPk(userId, { include: Post } ) + if (posts) { + await Promise.allSettled( + await posts.map(async p=>{ + let recipe = await Recipe.findByPk(p.recipeId) + post.push({ + userId:p.dataValues.id, + username: user.dataValues.username, + content:p.dataValues.content, + recipeId: recipe.dataValues.id, + recipeImg:recipe.dataValues.image, + recipeName:recipe.dataValues.name, + })})) + console.log('post',post); + return post + } + + } catch (error) { + console.log(error) + }} + +const getRecipePost = async (recipeId) =>{ + try { + let {posts} = await Recipe.findByPk(recipeId, { include: Post } ) + let post = [] + if(posts){ + await Promise.allSettled( + await posts.map( async( p)=>{ + let user = await User.findByPk(p.userId) + post.push( { + username:user.dataValues.username, + post: p.dataValues, + })})) + return post + } + } catch (error) { + console.log(error) + }} + +const createPost =async (userId, content,recipeId) =>{ + try { + let user = await User.findByPk(userId) + let recipe = await Recipe.findByPk(recipeId) + let newPost = await Post.create({ + content, + userId, + recipeId,}) + + await user.addPost(newPost) + await recipe.addPost(newPost) + return await User.findByPk(userId, { include: Post } ) + } catch (error) { + console.log(error) + }} + +const countRanking = async (recipeId) =>{ + try { + let {count, rows} = await Ranking.findAndCountAll({ + where:{recipeId:recipeId} + }) + let sum = 0 + rows.forEach(ele => { + sum = sum + ele.dataValues.ranking + }); + return sum/count + + } catch (error) { + console.log(error) + } +} +const getUserRanking =async(userId , recipeId)=>{ +try { + let rank = await findOne({ + where:{ + userId,recipeId + }}) + return rank +} catch (error) { + console.log(error) +} +} + +const addRanking =async (userId , recipeId, ranking) =>{ + try { + let user = await User.findByPk(userId) + let recipe = await Recipe.findByPk(recipeId) + let rank = await Ranking.findOne({ + where:{ + userId,recipeId + } + }) + if (!user || !recipe) { + throw new Error('need more data') + }else{ + if (rank) { + return await rank.update({ranking:ranking}) + } else { + let newRanking = await Ranking.create({ + ranking, + userId, + recipeId}) + await user.addRanking(newRanking) + await recipe.addRanking(newRanking) + return await Recipe.findByPk(recipeId, { include: Ranking } ) + }} + } catch (error) { + console.log(error) + } +} + +const updatePost =async (postId,content) =>{ + try { + let post = await Post.findByPk(postId) + return await post.update({content:content}) + } catch (error) { + console.log(error) + } +} +const updateRanking =async (ranking, rankingId) =>{ + try { + let rank = await Ranking.findByPk(rankingId) + return await rank.update({ranking:ranking}) + } catch (error) { + console.log(error) + } +} +const deletePost =async (postId) =>{ + try { + let post = await Post.findByPk(postId) + await post.destroy() + return('The post was delete') + } catch (error) { + console.log(error) + } +} + +module.exports ={ + getAllPost, + createPost, + getRecipePost, + getUserRanking, + addRanking, + countRanking, + updateRanking, + updatePost, + deletePost +} \ No newline at end of file diff --git a/api/src/controllers/usersControllers/admin.controllers.js b/api/src/controllers/usersControllers/admin.controllers.js index 211cd0a..5562ca5 100644 --- a/api/src/controllers/usersControllers/admin.controllers.js +++ b/api/src/controllers/usersControllers/admin.controllers.js @@ -1,4 +1,4 @@ -const { User, Favorites } = require("../../db.js"); +const { User, Favorites, Recipe } = require("../../db.js"); const bcrypt = require('bcrypt'); const jwt = require('jsonwebtoken'); const authConfig = require('../config/auth.js') @@ -89,6 +89,16 @@ const userBanned =async(id,banned) =>{ } } +const recipeBanned =async(id,banned) =>{ + try { + let recipe = await Recipe.findByPk(id) + await recipe.update({banned: banned}) + return recipe + } catch (error) { + console.log(error) + } + } + const defaultList = async (user) =>{ let defList = await Favorites.create({ userId: user.id @@ -103,5 +113,6 @@ module.exports = { usersList, userByid, userByName, - userBanned + userBanned, + recipeBanned } \ No newline at end of file diff --git a/api/src/controllers/usersControllers/notifications/notifications.js b/api/src/controllers/usersControllers/notifications/notifications.js index 72631a9..fede68b 100644 --- a/api/src/controllers/usersControllers/notifications/notifications.js +++ b/api/src/controllers/usersControllers/notifications/notifications.js @@ -18,7 +18,7 @@ if(banned.toString() == "false"){ from: "nutri.u.contact@gmail.com", to: email, subject:"Your nutri-u account has been unbanned", - html:`

Your account has been unbanned for administratornutri.u.contact@gmail.com

`, + html:`

Your account has been unbanned for administrator nutri.u.contact@gmail.com

`, }) } @@ -27,7 +27,7 @@ if(banned.toString() == "true") { from: "nutri.u.contact@gmail.com", to: email, subject:"Your nutri-u account has been banned", - html:`

You were blocked by a Nutri-u administrator, if you see that this was an error, contact this emailnutri.u.contact@gmail.com

`, + html:`

You were blocked by a Nutri-u administrator, if you see that this was an error, contact this email nutri.u.contact@gmail.com

`, }) } @@ -58,9 +58,28 @@ if(email && token){ } +async function paymentNotification(email, recibo){ + let transporter = nodemailer.createTransport({ + host: `${HOST_EMAIL}`, + port:`${PORT_EMAIL}`, + secure:false, + auth:{ + user:`${EMAIL}`, + pass:`${EMAIL_PASS}` + } + }); + return transporter.sendMail({ + from: "nutri.u.contact@gmail.com", + to: email, + subject:"Your suscription to Nutri-U has been successful!", + html:`

You are a Premium User now, enjoy!

You can download your invoice here:
${recibo}nutri.u.contact@gmail.com

`, + }) + +} module.exports = { //adminLogin, bannedUserNotification, - changePasswordNotification + changePasswordNotification, + paymentNotification } \ No newline at end of file diff --git a/api/src/controllers/usersControllers/profiles.controllers.js b/api/src/controllers/usersControllers/profiles.controllers.js new file mode 100644 index 0000000..00d052f --- /dev/null +++ b/api/src/controllers/usersControllers/profiles.controllers.js @@ -0,0 +1,111 @@ +const { User, Profile } = require("../../db"); + +const CreateImc = async(userId, peso, altura, imc)=>{ + + try { + let user = await User.findByPk(userId); + let userProfile = await Profile.findOne({ + where: { + userId: user.dataValues.id, + }}) + + if(!userProfile && user){ + let newProfile = await Profile.create({ + + userId: user.dataValues.id, + peso: peso, + altura:altura, + imc:imc, + + }); + await user.addProfiles(newProfile); + return { + succes:newProfile + }; + } + if(userProfile && user){ + + let newProfile = await Profile.update( + { peso: peso, altura:altura, imc:imc}, + { + where: { + userId: user.dataValues.id, + }, + }) + + return { + succes:newProfile, + }; + } + + + + } catch (error) { + console.log(error) + } +} + + + +const uploadProfile = async(userId, img)=>{ + + try { + let user = await User.findByPk(userId); + let userProfile = await Profile.findOne({ + where: { + userId: user.dataValues.id, + }}) + + if(!userProfile && user){ + let newProfile = await Profile.create({ + + userId: user.dataValues.id, + imgperfil:img + + }); + await user.addProfiles(newProfile); + return { + succes:"ProfileNew" + }; + } + if(userProfile && user){ + + let newProfile = await Profile.update( + { imgperfil: img}, + { + where: { + userId: user.dataValues.id, + }, + }) + + return { + succes:"newProfile", + }; + } + + + + } catch (error) { + console.log(error) + } +} + + +const listProfile = async (userId) => { + try { + let pro = await Profile.findAll({ + where: { + userId:userId + }, + }); + return pro; + } catch (error) { + console.log( error); + } +}; + +module.exports = { + CreateImc, + uploadProfile, + listProfile + }; \ No newline at end of file diff --git a/api/src/controllers/usersControllers/userfree.controller.js b/api/src/controllers/usersControllers/userfree.controller.js index b423e0f..5d3e499 100644 --- a/api/src/controllers/usersControllers/userfree.controller.js +++ b/api/src/controllers/usersControllers/userfree.controller.js @@ -1,6 +1,9 @@ require('dotenv').config(); const { User, Payment } = require("../../db.js"); +const { paymentNotification } = require('./notifications/notifications') const { HOST_EMAIL, PORT_EMAIL, EMAIL, EMAIL_PASS, DB_HOST, DB_PORT } = process.env; +const jwt = require("jsonwebtoken"); +const authConfig = require("../config/auth.js"); const Stripe = require('stripe') const stripe = new Stripe('sk_test_51LpumKJocvWwgusfR19jzAn2K6nOtr99mMwbcQpJUMWLvPOZPlQozetO9hdsLp95i29WyTO7o7Kvv7IQHLZoqqAx00S5mMHbOv') @@ -30,7 +33,7 @@ const changeToPremium = async (userEmail, userName, paymentMethod) =>{ price_data: { currency: "USD", product: product.id, - unit_amount: "50", + unit_amount: "500", recurring: { interval: "month", }, @@ -47,15 +50,20 @@ const changeToPremium = async (userEmail, userName, paymentMethod) =>{ // console.log('ESTOOO',subscription) const user = await User.findOne({where:{email: userEmail}}) // console.log('sos vos?¡',user) - const factura = await Payment.findOrCreate({where:{ + const factura = await Payment.create({ paymenthID: subscription.id, - }}) + }) - // console.log('facturaa',factura) - await user.addMonthly_payment(factura.dataValues) + //console.log('facturaa',factura) + await user.addPayment(factura) user.update({ premium: true }) - + // console.log(subscription.latest_invoice.invoice_pdf) + const recibo = subscription.latest_invoice.invoice_pdf + paymentNotification(userEmail,recibo) + + + return { message: 'Subscription successfully initiated', clientSecret: subscription.latest_invoice.payment_intent.client_secret, @@ -69,24 +77,6 @@ const changeToPremium = async (userEmail, userName, paymentMethod) =>{ } -// const listFavoritesRecipes = ()=>{ - -// } - -// const update = ()=>{ -// User.update({ where: { email: email } }) - - - -// .then(userx=>{ -// console.log("user",userx[0]) -// if(!userx) throw new Error('user not found'); -// if(userx.emailVerified) throw new Error('user already verified'); -// userx.emailVerified = true - -// } -// } - module.exports = { changeToPremium, diff --git a/api/src/db.js b/api/src/db.js index a70cde4..51066da 100644 --- a/api/src/db.js +++ b/api/src/db.js @@ -58,7 +58,7 @@ let capsEntries = entries.map((entry) => [entry[0][0].toUpperCase() + entry[0].s sequelize.models = Object.fromEntries(capsEntries); -const { User, Diet, Recipe, Ingredient, Payment, Favorites, Post, Ranking} = sequelize.models; +const { User, Diet, Recipe, Ingredient, Payment, Favorites, Post, Ranking, Profile} = sequelize.models; // hay que corregir estas relaciones User.hasMany(Diet, {as: "fav_diet", foreignKey: "userId"}) @@ -66,16 +66,19 @@ User.hasMany(Recipe, {as: "new_recipe", foreignKey: "userId"}) User.hasMany(Favorites, { foreignKey: "userId"}) User.hasMany(Post, { foreignKey: "userId"}) User.hasMany(Ranking, { foreignKey: "userId"}) -User.hasMany(Payment, {as: 'monthly_payment', foreignKey: 'userId'}) +User.hasMany(Payment, { foreignKey: 'userId'}) Payment.belongsTo(User) Favorites.belongsTo(User) Post.belongsTo(User) -Post.hasMany(Post,{as:'subPost'}) -Post.hasOne(Ranking, {foreignKey:'postId'}) +Post.belongsTo(Recipe) +// Post.hasMany(Post,{as:'subPost'}) +// Post.hasOne(Ranking, {foreignKey:'postId'}) Ranking.belongsTo(User) -Ranking.belongsTo(Post) +Ranking.belongsTo(Recipe) Recipe.belongsTo(User,{ as: "author", foreignKey: "userId"}) Diet.belongsToMany( Recipe,{ through: "diets_recipes"}) +Recipe.hasMany(Post,{ foreignKey: "recipeId"}) +Recipe.hasMany(Ranking,{ foreignKey: "recipeId"}) Recipe.belongsToMany(Diet,{ through: "diets_recipes"}) Recipe.belongsToMany(Ingredient,{ through: "recipes_ingredients"}) Recipe.belongsToMany(Favorites,{ through: "recipes_favorites"}) @@ -83,6 +86,7 @@ Favorites.belongsToMany(Recipe,{ through: "recipes_favorites"}) Ingredient.belongsToMany(Recipe,{ through: "recipes_ingredients"}) Diet.belongsToMany(Ingredient,{ through: "diets_ingredients"}) Ingredient.belongsToMany(Diet,{ through: "diets_ingredients"}) +User.hasOne(Profile) diff --git a/api/src/getApiRecipes/getApiRecipe.js b/api/src/getApiRecipes/getApiRecipe.js new file mode 100644 index 0000000..dfc6748 --- /dev/null +++ b/api/src/getApiRecipes/getApiRecipe.js @@ -0,0 +1,47 @@ +const {Recipe , Diet} = require('../db') +const axios = require('axios'); +const { API_KEY } = process.env; +const uuid = require('uuid'); + + + + + + + +async function getApi(){ + const RecipesAllDb = await Recipe.findAll() + if(!RecipesAllDb.length){ + const apiAll = await axios.get(`https://api.spoonacular.com/recipes/complexSearch?apiKey=${API_KEY}&addRecipeInformation=true&number=100`) //apiAll.data <= .data .data + const apiInfo = await apiAll.data.results + Promise.allSettled( + await apiInfo.map(async(e)=>{ + + let recipe= await Recipe.create({ + id: uuid.v4(), + apiId: e.id, + name: e.title, + healthScore: e.healthScore, + image: e.image, + banned: false, + summary: e.summary, + //cuisines: e.cuisines?.map(ele => ele), + //dishTypes: e.dishTypes?.map(ele => ele), + //diets: e.diets?.map(ele => ele), + createdInDB: false + + }) + + let diet = await Diet.findAll({ + where:{name:e.diets} + }) + + await recipe.addDiet(diet) + }) + ) +} + + +} + +module.exports = { getApi }; \ No newline at end of file diff --git a/api/src/models/Payment.js b/api/src/models/Payment.js index 69b20de..ecf5629 100644 --- a/api/src/models/Payment.js +++ b/api/src/models/Payment.js @@ -1,8 +1,14 @@ const { DataTypes } = require('sequelize'); module.exports = (sequelize) => { - + sequelize.define('payment', { + // id: { + // type: DataTypes.INTEGER, + // autoIncrement: true, + // primaryKey: true, + // allowNull: false + // }, paymenthID:{ type: DataTypes.STRING, allowNull: false diff --git a/api/src/models/Profile.js b/api/src/models/Profile.js new file mode 100644 index 0000000..e04c596 --- /dev/null +++ b/api/src/models/Profile.js @@ -0,0 +1,25 @@ +const { DataTypes } = require('sequelize'); + +module.exports = (sequelize) => { + sequelize.define('profile', { + + imgperfil:{ + type: DataTypes.STRING, + defaultValue: "https://d500.epimg.net/cincodias/imagenes/2016/07/04/lifestyle/1467646262_522853_1467646344_noticia_normal.jpg" + }, + peso:{ + type: DataTypes.TEXT, + + }, + altura:{ + type: DataTypes.TEXT, + + }, + imc:{ + type: DataTypes.TEXT, + + }, + }, { + timestamps: true, + }); +}; \ No newline at end of file diff --git a/api/src/routes/recipe.js b/api/src/routes/recipe.js index f940f91..cae5518 100644 --- a/api/src/routes/recipe.js +++ b/api/src/routes/recipe.js @@ -2,8 +2,10 @@ const { Router } = require("express"); const router = Router(); const Recipe = require("../db"); const { getApiRecipeByID, createRecipe, deleteRecipe, updateRecipe } = require("../controllers/recipecontrollers"); +const { recipeBanned } = require ("../controllers/usersControllers/admin.controllers") -const auth = require('../middlewares/auth') +const auth = require('../middlewares/auth'); +const { countRanking, getRecipePost } = require("../controllers/usersControllers/PostRanking.controllers"); router.get("/:id", async (req, res) => { let { id } = req.params; @@ -17,7 +19,16 @@ router.get("/:id", async (req, res) => { .json({ error: "error getting that specific recipe" }); } }); - +router.get('/reciperank/:recipeId', async (req,res)=>{ + let {recipeId} = req.params + let rank = await countRanking(recipeId) + res.json(Math.round(rank)) +}) +router.get('/post/:recipeId', async (req,res)=>{ + let {recipeId} = req.params + let post = await getRecipePost(recipeId) + res.json(post) +}) router.post("/", auth,async (req, res) => { const { name, @@ -79,4 +90,7 @@ router.put("/:id",auth, async (req, res) => { }); + + + module.exports = router; \ No newline at end of file diff --git a/api/src/routes/recipes.js b/api/src/routes/recipes.js index b949a5d..c01cf1f 100644 --- a/api/src/routes/recipes.js +++ b/api/src/routes/recipes.js @@ -14,6 +14,7 @@ router.get("/", async (req, res) => { } else { let allInfo =await getAllInfo() + return res.status(201).json(allInfo) } diff --git a/api/src/routes/users/admin.js b/api/src/routes/users/admin.js index 04158f3..1ad9452 100644 --- a/api/src/routes/users/admin.js +++ b/api/src/routes/users/admin.js @@ -7,6 +7,7 @@ const { userByName, userByid, userBanned, + recipeBanned, } = require("../../controllers/usersControllers/admin.controllers"); //Middleware @@ -77,4 +78,21 @@ router.post('/search/:id', auth, async(req,res)=>{ } }) + +router.post("/ban/:id",auth, async (req, res) => { + let { id } = req.params; + let {banned} = req.body + console.log(banned, "soy banned") + try { + let recipe = await recipeBanned(id,banned) + + res.send(`Recipe ${id} banned or unbanned SUCCESS`); + + + } catch (e) { + res.send(e.message); + } +}); + + module.exports = router; diff --git a/api/src/routes/users/post.js b/api/src/routes/users/post.js new file mode 100644 index 0000000..f4236df --- /dev/null +++ b/api/src/routes/users/post.js @@ -0,0 +1,59 @@ +const { Router } = require("express"); +const { getAllPost, createPost,countRanking, getRecipePost, addRanking, updatePost, updateRanking, deletePost, getUserRanking } = require("../../controllers/usersControllers/PostRanking.controllers"); +const router = Router() +const auth = require('../../middlewares/auth'); + +router.get('/:userId',auth, async (req,res)=>{ + let {userId} = req.params + let post = await getAllPost(userId) + res.json(post) +}) +router.post('/:userId',auth, async (req,res)=>{ + let {userId} = req.params + let {content, recipeId} = req.body + let post = await createPost(userId, content, recipeId) + res.json(post) +}) +router.get('/ranking/:recipeId', auth, async (req,res)=>{ + let {recipeId} = req.params + let {userId} = req.body + let rank = await getUserRanking(userId , recipeId) + res.json(Math.round(rank)) +}) +// router.get('/recipe/:recipeId', async (req,res)=>{ +// let {recipeId} = req.params +// let post = await getRecipePost(recipeId) +// res.json(post) +// }) +// router.get('/reciperank/:recipeId', async (req,res)=>{ +// let {recipeId} = req.params +// let rank = await countRanking(recipeId) +// res.json(rank) +// }) +router.patch('/post/:postId', auth, async (req,res)=>{ + let {postId} = req.params + let {content} = req.body + let post = await updatePost(postId,content) + res.json(post) +}) +router.post('/ranking/:recipeId', auth, async (req,res)=>{ + let {recipeId} = req.params + let {ranking, userId} = req.body + let rank = await addRanking(userId , recipeId, ranking) + res.json(Math.round(rank)) +}) +// router.patch('/up-ranking', auth, async (req,res)=>{ +// let {ranking, rankingId} = req.body +// let rank = await updateRanking(ranking, rankingId) +// res.json(rank) +// }) +router.delete('/post/:postId', auth, async (req,res)=>{ + let {postId} = req.params + console.log('postId',postId) + let post = await deletePost(postId) + res.json(post) +}) + + + +module.exports = router; \ No newline at end of file diff --git a/api/src/routes/users/profiles.js b/api/src/routes/users/profiles.js new file mode 100644 index 0000000..56a5405 --- /dev/null +++ b/api/src/routes/users/profiles.js @@ -0,0 +1,45 @@ +const { Router } = require("express"); +const { CreateImc, uploadProfile, listProfile } = require("../../controllers/usersControllers/profiles.controllers") +const auth = require('../../middlewares/auth'); +const router = Router() + +router.post('/calculator',auth ,async (req, res) =>{ + try { + let {userId, peso, altura,imcMessage} = req.body; + console.log("hola soy peso",peso) + let newList = await CreateImc(userId, peso,altura,imcMessage) + res.json(newList) + + } catch (error) { + console.log('err',error) + + } +}) + +router.post('/uploadimg',auth ,async (req, res) =>{ + try { + let {userId, image} = req.body; + let newList = await uploadProfile(userId, image) + res.json(newList) + + } catch (error) { + console.log('err',error) + + } +}) + +router.get('/profiles/:userId',auth ,async (req, res) =>{ + try { + let {userId} = req.params; + + let newList = await listProfile(userId) + res.json(newList) + + } catch (error) { + console.log('err',error) + + } +}) + + +module.exports = router; \ No newline at end of file diff --git a/api/src/routes/users/user.js b/api/src/routes/users/user.js index 6c52b1d..a3b0172 100644 --- a/api/src/routes/users/user.js +++ b/api/src/routes/users/user.js @@ -1,5 +1,5 @@ const { Router } = require("express"); - +const profiles = require('./profiles') const { User } = require("../../db"); const usersRoutes = require("./users"); const adminRoutes = require("./admin"); @@ -43,7 +43,7 @@ router.get("/confirm/:token", confirmAccount); router.post('/premium', async (req,res) =>{ let {userEmail, userName, paymentMethod} = req.body let respuesta = await changeToPremium(userEmail, userName, paymentMethod) - console.log('estoo', JSON.stringify(respuesta)) + // console.log('estoo', JSON.stringify(respuesta)) res.json({ respuesta }) @@ -53,5 +53,7 @@ router.post('/premium', async (req,res) =>{ router.post("/forgot-password", forgotPassword) router.post("/new-password/:token", newPassword) +router.use("/profiles", profiles); + module.exports = router; diff --git a/api/src/routes/users/users.js b/api/src/routes/users/users.js index 7fca34c..bb6526d 100644 --- a/api/src/routes/users/users.js +++ b/api/src/routes/users/users.js @@ -1,12 +1,13 @@ const {Router} = require('express'); const { userInfo } = require('../../controllers/usersControllers/users.controllers'); -const { changeToPremium } = require('../../controllers/usersControllers/userfree.controller'); const auth = require('../../middlewares/auth'); const router = Router() const routeFavorite = require('./favorites') +const routePost = require('./post') router.use('/myfavorite', routeFavorite) +router.use('/post', routePost) // router.patch('/premium', (req,res) =>{ // let user = changeToPremium() diff --git a/client/package.json b/client/package.json index 9c95c7e..d3ddb24 100644 --- a/client/package.json +++ b/client/package.json @@ -25,6 +25,7 @@ "react-router-dom": "^6.4.1", "react-scripts": "^2.1.3", "redux": "^4.2.0", + "stripe": "^10.14.0", "styled-components": "^5.3.6", "sweetalert": "^2.1.2", "web-vitals": "^2.1.4", diff --git a/client/src/components/admin/RecipesTable/EnhancedRecipesTableHead.js b/client/src/components/admin/RecipesTable/EnhancedRecipesTableHead.js new file mode 100644 index 0000000..b7f898a --- /dev/null +++ b/client/src/components/admin/RecipesTable/EnhancedRecipesTableHead.js @@ -0,0 +1,58 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import Box from '@mui/material/Box'; +import TableCell from '@mui/material/TableCell'; +import TableHead from '@mui/material/TableHead'; +import TableRow from '@mui/material/TableRow'; +import TableSortLabel from '@mui/material/TableSortLabel'; +import { visuallyHidden } from '@mui/utils'; +import { headCellsRecipe } from './headCellsRecipe'; + +function EnhancedRecipesTableHead(props) { + const { onSelectAllClick, order, orderBy, numSelected, rowCount, onRequestSort } = + props; + const createSortHandler = (property) => (event) => { + onRequestSort(event, property); + }; + + return ( + + + + banned + + {headCellsRecipe.map((headCell) => ( + + + {headCell.label} + {orderBy === headCell.id ? ( + + {order === 'desc' ? 'sorted descending' : 'sorted ascending'} + + ) : null} + + + ))} + + + ); +} +EnhancedRecipesTableHead.propTypes = { + numSelected: PropTypes.number.isRequired, + onRequestSort: PropTypes.func.isRequired, + onSelectAllClick: PropTypes.func.isRequired, + order: PropTypes.oneOf(['asc', 'desc']).isRequired, + orderBy: PropTypes.string.isRequired, + rowCount: PropTypes.number.isRequired, + }; + +export default EnhancedRecipesTableHead diff --git a/client/src/components/admin/RecipesTable/EnhancedRecipesTableToolbar.js b/client/src/components/admin/RecipesTable/EnhancedRecipesTableToolbar.js new file mode 100644 index 0000000..4c87484 --- /dev/null +++ b/client/src/components/admin/RecipesTable/EnhancedRecipesTableToolbar.js @@ -0,0 +1,80 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import { alpha } from '@mui/material/styles'; +import Box from '@mui/material/Box'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TablePagination from '@mui/material/TablePagination'; +import TableRow from '@mui/material/TableRow'; +import TableSortLabel from '@mui/material/TableSortLabel'; +import Toolbar from '@mui/material/Toolbar'; +import Typography from '@mui/material/Typography'; +import Paper from '@mui/material/Paper'; +import Checkbox from '@mui/material/Checkbox'; +import IconButton from '@mui/material/IconButton'; +import Tooltip from '@mui/material/Tooltip'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import Switch from '@mui/material/Switch'; +import DeleteIcon from '@mui/icons-material/Delete'; +import FilterListIcon from '@mui/icons-material/FilterList'; +import { visuallyHidden } from '@mui/utils'; +import { headCellsRecipe } from './headCellsRecipe'; + +function EnhancedRecipesTableToolbar(props) { + const { numSelected } = props; + + return ( + 0 && { + bgcolor: (theme) => + alpha(theme.palette.primary.main, theme.palette.action.activatedOpacity), + }), + }} + > + {numSelected > 0 ? ( + + {numSelected} selected + + ) : ( + + Recipes Admin Panel + + )} + + {numSelected > 0 ? ( + + + + + + ) : ( + + + + + + )} + + ); +} +EnhancedRecipesTableToolbar.propTypes = { + numSelected: PropTypes.number.isRequired, + }; + +export default EnhancedRecipesTableToolbar diff --git a/client/src/components/admin/RecipesTable/RecipeTable.js b/client/src/components/admin/RecipesTable/RecipeTable.js index 1febd23..696e616 100644 --- a/client/src/components/admin/RecipesTable/RecipeTable.js +++ b/client/src/components/admin/RecipesTable/RecipeTable.js @@ -10,14 +10,14 @@ import Paper from '@mui/material/Paper'; import Checkbox from '@mui/material/Checkbox'; import FormControlLabel from '@mui/material/FormControlLabel'; import Switch from '@mui/material/Switch'; -import EnhancedTableToolbar from '../TableHelpers/EnhancedTableToolbar'; -import EnhancedTableHead from '../TableHelpers/EnhancedTableHead'; -import { getComparator, stableSort} from '../TableHelpers/TableHelpers' +import EnhancedRecipesTableToolbar from './EnhancedRecipesTableToolbar'; +import EnhancedRecipesTableHead from './EnhancedRecipesTableHead'; +import { getComparator, stableSort } from '../TableHelpers/TableHelpers' import { NavBar } from '../../utils/nav/nav'; -import { getRecipes } from '../../../redux/actions/adminAction'; import { useDispatch, useSelector } from 'react-redux'; -// import { getUsers } from '../../redux/actions/adminAction'; -//import ResponsiveAppBar from '../admin_NavBar'; +import { getRecipes, banRecipeById } from '../../../redux/actions/adminAction'; + + export const RecipeTable = () => { @@ -31,7 +31,7 @@ const {recipesList} = useSelector((store) => store.admin) const [selected, setSelected] = React.useState([]); const [page, setPage] = React.useState(0); const [dense, setDense] = React.useState(false); - const [userPerPage, setuserPerPage] = React.useState(15); + const [recipesPerPage, setrecipesPerPage] = React.useState(15); React.useEffect(()=>{ @@ -55,6 +55,7 @@ const {recipesList} = useSelector((store) => store.admin) const handleClick = (event, name) => { const selectedIndex = selected.indexOf(name); + console.log(selectedIndex, "SELECTED INDEX") let newSelected = []; if (selectedIndex === -1) { @@ -77,8 +78,8 @@ const {recipesList} = useSelector((store) => store.admin) setPage(newPage); }; - const handleChangeuserPerPage = (event) => { - setuserPerPage(parseInt(event.target.value, 10)); + const handleChangerecipesPerPage = (event) => { + setrecipesPerPage(parseInt(event.target.value, 10)); setPage(0); }; @@ -88,22 +89,22 @@ const {recipesList} = useSelector((store) => store.admin) const isSelected = (name) => selected.indexOf(name) !== -1; - // Avoid a layout jump when reaching the last page with empty user. - const emptyuser = - page > 0 ? Math.max(0, (1 + page) * userPerPage - recipesList.length) : 0; + // Avoid a layout jump when reaching the last page with empty recipe. + const emptyrecipes = + page > 0 ? Math.max(0, (1 + page) * recipesPerPage - recipesList.length) : 0; return (<> - + - {/*ACA TENGO QUE VER COMO LE PASO EL ID PARA BANEARLO*/} + {/*ACA TENGO QUE VER COMO LE PASO EL ID PARA BANEARLO*/} - store.admin) /> {/* if you don't need to support IE11, you can replace the `stableSort` call with: - user.slice().sort(getComparator(order, orderBy)) */} + recipe.slice().sort(getComparator(order, orderBy)) */} {stableSort(recipesList, getComparator(order, orderBy)) - .slice(page * userPerPage, page * userPerPage + userPerPage) + .slice(page * recipesPerPage, page * recipesPerPage + recipesPerPage) .map((row, index) => { const isItemSelected = isSelected(row.name); const labelId = `enhanced-table-checkbox-${index}`; @@ -150,16 +151,17 @@ const {recipesList} = useSelector((store) => store.admin) {row.name} {row.healthScore} {row.createdInDB.toString()} + {console.log(row.banned, "BANNED")} {row.banned.toString()} - {row.userId} + {/* {row.user_id} */} ); })} - {emptyuser > 0 && ( + {emptyrecipes > 0 && ( @@ -169,13 +171,13 @@ const {recipesList} = useSelector((store) => store.admin)
descendingComparator(a, b, orderBy) : (a, b) => -descendingComparator(a, b, orderBy); - } +} - // This method is created for cross-browser compatibility, if you don't - // need to support IE11, you can use Array.prototype.sort() directly - export function stableSort(array, comparator) { +export function stableSort(array, comparator) { const stabilizedThis = array.map((el, index) => [el, index]); stabilizedThis.sort((a, b) => { const order = comparator(a[0], b[0]); @@ -26,4 +24,4 @@ export function descendingComparator(a, b, orderBy) { return a[1] - b[1]; }); return stabilizedThis.map((el) => el[0]); - } \ No newline at end of file +} \ No newline at end of file diff --git a/client/src/components/admin/TableHelpers/EnhancedTableHead.js b/client/src/components/admin/UsersTable/EnhancedUsersTableHead.js similarity index 76% rename from client/src/components/admin/TableHelpers/EnhancedTableHead.js rename to client/src/components/admin/UsersTable/EnhancedUsersTableHead.js index bde3a8c..49b6d7b 100644 --- a/client/src/components/admin/TableHelpers/EnhancedTableHead.js +++ b/client/src/components/admin/UsersTable/EnhancedUsersTableHead.js @@ -6,10 +6,9 @@ import TableHead from '@mui/material/TableHead'; import TableRow from '@mui/material/TableRow'; import TableSortLabel from '@mui/material/TableSortLabel'; import { visuallyHidden } from '@mui/utils'; -//import pruebaUsers from '../components/User'; //importar User de la DB -import { headCellsUser } from '../UsersTable/headCellsUser'; +import { headCellsUser } from './headCellsUser'; -function EnhancedTableHead(props) { +function EnhancedUsersTableHead(props) { const { onSelectAllClick, order, orderBy, numSelected, rowCount, onRequestSort } = props; const createSortHandler = (property) => (event) => { @@ -21,15 +20,6 @@ function EnhancedTableHead(props) { banned - {/* 0 && numSelected < rowCount} - checked={rowCount > 0 && numSelected === rowCount} - onChange={onSelectAllClick} - inputProps={{ - 'aria-label': 'select all desserts', - }} - /> */} {headCellsUser.map((headCell) => ( ); } -EnhancedTableHead.propTypes = { +EnhancedUsersTableHead.propTypes = { numSelected: PropTypes.number.isRequired, onRequestSort: PropTypes.func.isRequired, onSelectAllClick: PropTypes.func.isRequired, @@ -65,4 +55,4 @@ EnhancedTableHead.propTypes = { rowCount: PropTypes.number.isRequired, }; -export default EnhancedTableHead +export default EnhancedUsersTableHead diff --git a/client/src/components/admin/TableHelpers/EnhancedTableToolbar.js b/client/src/components/admin/UsersTable/EnhancedUsersTableToolbar.js similarity index 87% rename from client/src/components/admin/TableHelpers/EnhancedTableToolbar.js rename to client/src/components/admin/UsersTable/EnhancedUsersTableToolbar.js index 88e75a2..6855b28 100644 --- a/client/src/components/admin/TableHelpers/EnhancedTableToolbar.js +++ b/client/src/components/admin/UsersTable/EnhancedUsersTableToolbar.js @@ -7,11 +7,10 @@ import IconButton from '@mui/material/IconButton'; import Tooltip from '@mui/material/Tooltip'; import DeleteIcon from '@mui/icons-material/Delete'; import FilterListIcon from '@mui/icons-material/FilterList'; -//import pruebaUsers from '../components/User'; //importar User de la DB -function EnhancedTableToolbar(props) { + +function EnhancedUsersTableToolbar(props) { const { numSelected } = props; - //const handleDelete = () => {} //AQUI VA EL DELETE return ( ); } -EnhancedTableToolbar.propTypes = { +EnhancedUsersTableToolbar.propTypes = { numSelected: PropTypes.number.isRequired, }; -export default EnhancedTableToolbar +export default EnhancedUsersTableToolbar diff --git a/client/src/components/admin/UsersTable/User.js b/client/src/components/admin/UsersTable/User.js deleted file mode 100644 index 82d1dc7..0000000 --- a/client/src/components/admin/UsersTable/User.js +++ /dev/null @@ -1,160 +0,0 @@ -const pruebaUsers = [ - { - id: '1', - username: 'Juan', - email: 'juan@email.com', - password: '123456', - banned: false, - admin: false, - premium: true, - nutricionist: false, - free: false, - logged: true, - }, - { - id: '2', - username: 'Pedro', - email: 'pedro@email.com', - password: '144456', - banned: true, - admin: false, - premium: false, - nutricionist: true, - free: false, - logged: false, - }, - { - id: '3', - username: 'Tito', - email: 'tito@email.com', - password: '744455', - banned: false, - admin: true, - premium: false, - nutricionist: false, - free: false, - logged: false, - }, - { - id: '4', - username: 'Toto', - email: 'toto@email.com', - password: '743355', - banned: false, - admin: false, - premium: false, - nutricionist: false, - free: true, - logged: true, - }, - { - id: '5', - username: 'Hugo', - email: 'hugo@email.com', - password: '943355', - banned: true, - admin: false, - premium: false, - nutricionist: false, - free: true, - logged: false, - }, - { - id: '6', - username: 'Juanito', - email: 'juanito@email.com', - password: '123456', - banned: false, - admin: false, - premium: true, - nutricionist: false, - free: false, - logged: true, - }, - { - id: '7', - username: 'Pedrovich', - email: 'pedrov@email.com', - password: '144456', - banned: true, - admin: false, - premium: false, - nutricionist: true, - free: false, - logged: false, - }, - { - id: '8', - username: 'Titon', - email: 'titon@email.com', - password: '744455', - banned: false, - admin: true, - premium: false, - nutricionist: false, - free: false, - logged: false, - }, - { - id: '9', - username: 'Totoloco', - email: 'totol@email.com', - password: '743355', - banned: false, - admin: false, - premium: false, - nutricionist: false, - free: true, - logged: true, - }, - { - id: '10', - username: 'Hugovius', - email: 'hugov@email.com', - password: '943355', - banned: true, - admin: false, - premium: false, - nutricionist: false, - free: true, - logged: false, - }, - { - id: '11', - username: 'Titonegro', - email: 'titon@email.com', - password: '744455', - banned: false, - admin: true, - premium: false, - nutricionist: false, - free: false, - logged: false, - }, - { - id: '12', - username: 'Totololo', - email: 'totol@email.com', - password: '743355', - banned: false, - admin: false, - premium: false, - nutricionist: false, - free: true, - logged: true, - }, - { - id: '13', - username: 'Hugon', - email: 'hugov@email.com', - password: '943355', - banned: true, - admin: false, - premium: false, - nutricionist: false, - free: true, - logged: false, - } -] - -export default pruebaUsers \ No newline at end of file diff --git a/client/src/components/admin/UsersTable/UserTable.js b/client/src/components/admin/UsersTable/UserTable.js index 1b32568..e559254 100644 --- a/client/src/components/admin/UsersTable/UserTable.js +++ b/client/src/components/admin/UsersTable/UserTable.js @@ -10,8 +10,8 @@ import Paper from '@mui/material/Paper'; import Checkbox from '@mui/material/Checkbox'; import FormControlLabel from '@mui/material/FormControlLabel'; import Switch from '@mui/material/Switch'; -import EnhancedTableToolbar from '../TableHelpers/EnhancedTableToolbar'; -import EnhancedTableHead from '../TableHelpers/EnhancedTableHead'; +import EnhancedUsersTableToolbar from './EnhancedUsersTableToolbar'; +import EnhancedUsersTableHead from './EnhancedUsersTableHead'; import { getComparator, stableSort} from '../TableHelpers/TableHelpers' import { NavBar } from '../../utils/nav/nav'; import { useDispatch, useSelector } from 'react-redux'; @@ -21,33 +21,10 @@ import { banUserById } from '../../../redux/actions/adminAction'; export const UserTable = () => { -// const getAllUsers = /*async*/() => { //PASAR A ASYNC AWAIT CUANDO MIGRE AL PF -// try { -// let userData = /*await*/pruebaUsers.map(e => { -// return { -// id: e.id, -// username: e.username, -// email: e.email, -// password: e.password, -// banned: e.banned, -// admin: e.admin, -// premium: e.premium, -// nutricionist: e.nutricionist, -// free: e.free, -// logged: e.logged, -// } -// }) -// return userData -// } catch (error) { -// console.log(error) -// } -// } - - const {usersList} = useSelector((store) => store.admin) - const dispatch = useDispatch() + const dispatch = useDispatch() const [order, setOrder] = React.useState('asc'); @@ -56,7 +33,12 @@ const {usersList} = useSelector((store) => store.admin) const [page, setPage] = React.useState(0); const [dense, setDense] = React.useState(false); const [userPerPage, setuserPerPage] = React.useState(15); + const [click, setClick] = React.useState(false) + React.useEffect(() => { + dispatch(getUsers()) + },[click]) + React.useEffect(()=>{ dispatch(getUsers()) @@ -71,9 +53,7 @@ const {usersList} = useSelector((store) => store.admin) const handleSelectAllClick = (event) => { if (event.target.checked) { const newSelected = usersList.map((n) => n.banned); - setSelected(newSelected); - return; } setSelected([]); @@ -114,16 +94,19 @@ const {usersList} = useSelector((store) => store.admin) }; const handleClick2 = (event, user, estado) => { - + console.log(event.target.checked, "ESTE ES EL EVENT") console.log(user, "ESTE ES USER ID") console.log(estado, "ESTE ES EL ESTADO") - dispatch(banUserById(user,estado)) - + click ? setClick(false) : setClick(true) + dispatch(banUserById(user,event.target.checked)) + dispatch(getUsers()) } - const isSelected = (name) => selected.indexOf(name) !== -1; + const isSelected = (id) => { + let usuario = usersList.find((user) => user.id === id) + return usuario.banned + } - // Avoid a layout jump when reaching the last page with empty user. const emptyuser = page > 0 ? Math.max(0, (1 + page) * userPerPage - usersList.length) : 0; @@ -131,14 +114,14 @@ const {usersList} = useSelector((store) => store.admin) - {/*ACA TENGO QUE VER COMO LE PASO EL ID PARA BANEARLO*/} + - store.admin) rowCount={usersList.length} /> - {/* if you don't need to support IE11, you can replace the `stableSort` call with: - user.slice().sort(getComparator(order, orderBy)) */} {stableSort(usersList, getComparator(order, orderBy)) .slice(page * userPerPage, page * userPerPage + userPerPage) .map((row, index) => { - const isItemSelected = isSelected(row.username); + const isItemSelected = isSelected(row.id); const labelId = `enhanced-table-checkbox-${index}`; return ( @@ -167,7 +148,7 @@ const {usersList} = useSelector((store) => store.admin) > handleClick2(event, row.id, isItemSelected)} + onChange={(event) => handleClick2(event, row.id, isItemSelected)} color="primary" checked={isItemSelected} inputProps={{ diff --git a/client/src/components/admin/admin_NavBar.js b/client/src/components/admin/admin_NavBar.js deleted file mode 100644 index a54455f..0000000 --- a/client/src/components/admin/admin_NavBar.js +++ /dev/null @@ -1,162 +0,0 @@ -import * as React from 'react'; -import AppBar from '@mui/material/AppBar'; -import Box from '@mui/material/Box'; -import Toolbar from '@mui/material/Toolbar'; -import IconButton from '@mui/material/IconButton'; -import Typography from '@mui/material/Typography'; -import Menu from '@mui/material/Menu'; -import MenuIcon from '@mui/icons-material/Menu'; -import Container from '@mui/material/Container'; -import Avatar from '@mui/material/Avatar'; -import Button from '@mui/material/Button'; -import Tooltip from '@mui/material/Tooltip'; -import MenuItem from '@mui/material/MenuItem'; -//import AdbIcon from '@mui/icons-material/Adb'; - -const pages = ['Recipes', 'Users']; -const settings = ['Dashboard', 'Logout']; - -const ResponsiveAppBar = () => { - const [anchorElNav, setAnchorElNav] = React.useState(null); - const [anchorElUser, setAnchorElUser] = React.useState(null); - - const handleOpenNavMenu = (event) => { - setAnchorElNav(event.currentTarget); - }; - const handleOpenUserMenu = (event) => { - setAnchorElUser(event.currentTarget); - }; - - const handleCloseNavMenu = () => { - setAnchorElNav(null); - }; - - const handleCloseUserMenu = () => { - setAnchorElUser(null); - }; - - return ( - - - - {/* */} - - Nutri-U - - - - - - - - {pages.map((page) => ( - - {page} - - ))} - - - {/* */} - - Nutri-U - - - {pages.map((page) => ( - - ))} - - - - - - - - - - {settings.map((setting) => ( - - {setting} - - ))} - - - - - - ); -}; -export default ResponsiveAppBar; diff --git a/client/src/components/recipes/cards/card/card.css b/client/src/components/recipes/cards/card/card.css index 9cdaa26..dcfdf02 100644 --- a/client/src/components/recipes/cards/card/card.css +++ b/client/src/components/recipes/cards/card/card.css @@ -1,18 +1,18 @@ -.card-title { - text-decoration: none; - color: #2E2E2E;; -} +@import url('https://fonts.googleapis.com/css2?family=Cabin:ital@1&family=Fraunces:opsz@9..144&family=Merriweather:ital,wght@0,300;1,300&family=Oswald:wght@300;400;700&family=Roboto+Serif:ital,opsz,wght@0,8..144,400;0,8..144,700;1,8..144,300&display=swap'); .card-text { text-decoration: none; color: #2E2E2E;; } - +h5{ + font-family: 'Merriweather:ital', serif; + color: rgb(5, 97, 43); +} .card-title{ width: 230px; - font-size: 15px; + font-size: 20px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; diff --git a/client/src/components/recipes/cards/cards.css b/client/src/components/recipes/cards/cards.css index dddb40c..4f4ace2 100644 --- a/client/src/components/recipes/cards/cards.css +++ b/client/src/components/recipes/cards/cards.css @@ -1,3 +1,15 @@ +@import url('https://fonts.googleapis.com/css?family=Cutive'); +@import url('https://fonts.googleapis.com/css2?family=Cabin:ital@1&family=Fraunces:opsz@9..144&family=Merriweather:ital,wght@0,300;1,300&family=Oswald:wght@300;400;700&family=Roboto+Serif:ital,opsz,wght@0,8..144,400;0,8..144,700;1,8..144,300&display=swap'); + +h1{ + font-family: Cutive, serif; + margin-top: 40px; + text-align: center; + font-size: 60px; + color: rgb(125, 230, 155); + text-shadow: rgba(0, 0, 0, 0.96) 2px 2px 2px; + padding: 15px; +} .CardsRecipes{ margin: auto; max-width: 70%; @@ -22,9 +34,10 @@ } .options-recipes{ + margin-bottom: 30px; display: flex; justify-content: space-between; - + padding: 5px; } #content-card{ @@ -35,4 +48,7 @@ .Links{ text-decoration: none; +} +.pagination{ + padding: 10px; } \ No newline at end of file diff --git a/client/src/components/recipes/cards/cards.jsx b/client/src/components/recipes/cards/cards.jsx index 7146209..15c802f 100644 --- a/client/src/components/recipes/cards/cards.jsx +++ b/client/src/components/recipes/cards/cards.jsx @@ -75,10 +75,10 @@ const paginado = (pageNumber) => {
-