Skip to content

Commit

Permalink
Fix: validate and ingredient data;add hook useMyRecipes;WIP; b00tc4mp…
Browse files Browse the repository at this point in the history
  • Loading branch information
Ancog committed Aug 26, 2024
1 parent b8ea979 commit 71b40a4
Show file tree
Hide file tree
Showing 35 changed files with 888 additions and 376 deletions.
24 changes: 10 additions & 14 deletions staff/angel-patino/project/api/data/Recipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,7 @@ import { Schema, model, Types } from "mongoose"

const { ObjectId } = Types

const ingredientSchema = new Schema({
name: { type: String, required: true },
quantity: { type: Number, required: true },
unit: {
type: String,
required: true,
enum: ['grams', 'ml', 'l', 'tsp', 'unit']
}
})


// const ratingSchema = new Schema({
// user: {
Expand Down Expand Up @@ -47,11 +39,15 @@ const recipe = new Schema({
required: true
},

ingredients: {
type: [ingredientSchema],
required: true

},
ingredients: [{
name: { type: String, required: true },
quantity: { type: Number, required: true },
unit: {
type: String,
required: true,
enum: ['grams', 'ml', 'l', 'tsp', 'unit']
}
}],

description: {
type: String,
Expand Down
23 changes: 14 additions & 9 deletions staff/angel-patino/project/com/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const USERNAME_REGEX = /^[\w-]+$/
const PASSWORD_REGEX = /^[\w-$%&=\[\]\{\}\<\>\(\)]{8,}$/
const EMAIL_REGEX = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|.(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
const ID_REGEX = /^[0-9a-z]+$/
const INGREDIENT_NAME_REGEX = /^[a-zA-Z\s]+$/

function validateName(name, explain = 'name') {
if (typeof name !== 'string' || !NAME_REGEX.test(name))
Expand Down Expand Up @@ -65,22 +66,26 @@ function validateIngredientArray(ingredients, explain = 'ingredients') {
throw new ContentError(`${explain} must be a non-empty array.`);
}

ingredients.forEach(ingredient => {
ingredients.forEach((ingredient, index) => {
if (typeof ingredient !== 'object' || ingredient === null) {
throw new ContentError(`Each item in ${explain} must be an object.`);
throw new ContentError(`Ingredient at position ${index + 1} is not a valid object.`);
}
if (typeof ingredient.name !== 'string' || ingredient.name.trim() === '') {
throw new ContentError(`Each ${explain} must have a valid 'name'.`);

const { name, quantity, unit } = ingredient;

if (typeof name !== 'string' || !INGREDIENT_NAME_REGEX.test(name)) {
throw new ContentError(`Ingredient name at position ${index + 1} is not valid.`);
}
if (typeof ingredient.quantity !== 'number' || isNaN(ingredient.quantity) || ingredient.quantity <= 0) {
throw new ContentError(`Each ${explain} must have a valid 'quantity' greater than 0.`);

if (typeof quantity !== 'number' || isNaN(quantity) || quantity <= 0) {
throw new ContentError(`Ingredient quantity at position ${index + 1} must be a positive number.`);
}
if (!['grams', 'ml', 'l', 'tsp', 'unit'].includes(ingredient.unit)) {
throw new ContentError(`Each ${explain} must have a valid 'unit' that is one of the following: 'grams', 'ml', 'l', 'tsp', or 'unit'.`);

if (typeof unit !== 'string' || unit.trim().length === 0) {
throw new ContentError(`Ingredient unit at position ${index + 1} cannot be empty.`);
}
})
}

// function validateRating(rating, explain = 'rating') {
// const min = 1;
// const max = 5;
Expand Down
7 changes: 4 additions & 3 deletions staff/angel-patino/project/recipebox/package-lock.json

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

62 changes: 52 additions & 10 deletions staff/angel-patino/project/recipebox/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
import { useState } from "react"
import { Routes, Route, useNavigate, Navigate } from "react-router-dom"

import logic from "./logic"

import Login from "./views/Login"
import Register from "./views/Register"
import Home from "./views/Home"

import { Routes, Route, useNavigate, Navigate } from "react-router-dom"
import HomeView from "./views/components/HomeView"
import CreateRecipeView from "./views/components/CreateRecipeView"
import FavoritesListView from "./views/components/FavoritesListView"
import SearchView from "./views/components/SearchView"
import MyRecipesView from "./views/components/MyRecipesView"
import Footer from "./views/components/Footer"

function App() {
const [message, setMessage] = useState(null)

const navigate = useNavigate()

const handleGoToLogin = () => navigate("/login")

const handleGoToHome = () => navigate("/")

const handleGoToRegister = () => navigate("/register")

const handleMessage = (message) => setMessage(message)

return (
<div className="flex w-full h-screen">
<div className="w-full flex items-center justify-center">
<div className="flex flex-col min-h-screen">
<div className="main-content w-full flex-grow">
<Routes>
<Route
path="/register"
Expand Down Expand Up @@ -54,17 +55,58 @@ function App() {
/>

<Route
path="/*"
path="/"
element={
logic.isUserLoggedIn() ? (
<HomeView onUserLoggedOut={handleGoToLogin} />
) : (
<Navigate to="/login" />
)
}
/>

<Route
path="/create-recipe"
element={
logic.isUserLoggedIn() ? (
<CreateRecipeView onRecipeCreated={handleGoToHome} />
) : (
<Navigate to="/login" />
)
}
/>

<Route
path="/favorites"
element={
logic.isUserLoggedIn() ? (
<FavoritesListView />
) : (
<Navigate to="/login" />
)
}
/>

<Route
path="/search"
element={
logic.isUserLoggedIn() ? <SearchView /> : <Navigate to="/login" />
}
/>

<Route
path="/my-recipes"
element={
logic.isUserLoggedIn() ? (
<Home onUserLoggedOut={handleGoToLogin} />
<MyRecipesView />
) : (
<Navigate to="/login" />
)
}
/>
</Routes>
</div>
<Footer />
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
function Button({ type, className, onClick, children }) {
return (
<button
className={`Button ${className ? className : ""}`}
className={`button ${className ? className : ""}`}
type={type}
onClick={onClick}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Input from "./Input"

function Field({ id, type, placeholder, children }) {
return (
<div className="Field">
<div className="field">
<Label htmlFor={id}>{children}</Label>
<Input id={id} type={type} placeholder={placeholder} />
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
function Form({ className, onSubmit, children }) {
return (
<form className={`Form ${className ? className : ""}`} onSubmit={onSubmit}>
<form className={`form ${className ? className : ""}`} onSubmit={onSubmit}>
{children}
</form>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
function Input({ id, type, placeholder }) {
return (
<input className="Input" id={id} type={type} placeholder={placeholder} />
<input className="input" id={id} type={type} placeholder={placeholder} />
)
}
export default Input
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
function Label({ htmlFor, children }) {
return (
<label className="Label" htmlFor={htmlFor}>
<label className="label" htmlFor={htmlFor}>
{children}
</label>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Button from "./Button"

function SubmitButton({ children }) {
function SubmitButton({ className, children }) {
return (
<Button className="SubmitButton" type="submit">
<Button className={className} type="submit">
{children}
</Button>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
function Text({ children, className }) {
return <p className={`Text ${className}`}>{children}</p>
return <p className={`text ${className}`}>{children}</p>
}

export default Text
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function Thumbnail({ src }) {
return <img className="Thumbnail" src={src} />
return <img className="thumbnail" src={src} />
}
export default Thumbnail
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
function Time({ children: time }) {
const formattedTime = new Date(time).toLocaleString()

return <time className="Time">{formattedTime}</time>
return <time className="time">{formattedTime}</time>
}

export default Time
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import Text from "../core/Text"

function FormWithFeedback({ onSubmit, children, message, level = "error" }) {
return (
<Form className="FormWithFeedback" onSubmit={onSubmit}>
<Form className="formWithFeedback" onSubmit={onSubmit}>
{children}
{message && <Text className={`Feedback ${level}`}>{message}</Text>}
{message && <Text className={`feedback ${level}`}>{message}</Text>}
</Form>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ function View({
}) {
return (
<Tag
className={`View ${className ? className : ""} ${
className={`view ${className ? className : ""} ${
direction === "column" ? "View column" : "View row"
} ${align === "center" ? "View center" : ""}`}
>
Expand Down
31 changes: 31 additions & 0 deletions staff/angel-patino/project/recipebox/src/hooks/useMyRecipes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useState, useEffect } from "react"
import logic from "../logic/index.js"

export function useMyRecipes() {
const [myRecipes, setMyRecipes] = useState([])

useEffect(() => {
loadMyRecipes()
}, [])

const loadMyRecipes = () => {
try {
logic
.getAllRecipes()
.then((recipes) => {
const userId = logic.getUserId()
const userRecipes = recipes.filter((recipe) => recipe.author.id === userId)
setMyRecipes(userRecipes)
})
.catch((error) => {
console.error(error)
alert(error.message)
})
} catch (error) {
console.error(error)
alert(error.message)
}
};

return myRecipes
}
Loading

0 comments on commit 71b40a4

Please sign in to comment.