diff --git a/client/src/components/derived/Friends.tsx b/client/src/components/derived/Friends.tsx index 29d1b24..fcd1a87 100644 --- a/client/src/components/derived/Friends.tsx +++ b/client/src/components/derived/Friends.tsx @@ -51,7 +51,7 @@ const Friends: FC<{ targetUser?: IUser }> = ({ targetUser }) => { <> { userList.length ? ( - +

Friends ({ userList?.length ?? "0" }):

diff --git a/client/src/components/derived/IngredientSelector.tsx b/client/src/components/derived/IngredientSelector.tsx new file mode 100644 index 0000000..870d711 --- /dev/null +++ b/client/src/components/derived/IngredientSelector.tsx @@ -0,0 +1,47 @@ +import { Autocomplete, TextField } from "@mui/material" +import { useRef, useState } from "react"; +import { IIngredient } from "../../schemas"; +import { Button } from "../ui"; + +interface IngredientSelectorProps { + position: number + ingredients: IIngredient[] + destroy: (position: number) => void +} + +function IngredientSelector({ position, ingredients, destroy }: IngredientSelectorProps) { + const [options, setOptions] = useState(ingredients.map(each => each.name)); + const [newOptions, setNewOptions] = useState(new Array()); + const [selected, setSelected] = useState(new Array()); + + return ( +
+ ( + + )} + onKeyDown={(e) => { + if (e.code == 'Enter') { + const inputVal: string = e.target['value' as keyof EventTarget].toString(); + console.log(inputVal) + if (inputVal.length) { + setSelected(prev => [...prev, inputVal]) + setOptions((prev) => [...prev, inputVal]); + } + } + }} + /> + {/* @ts-ignore */} + +
+ ) +} + +export default IngredientSelector \ No newline at end of file diff --git a/client/src/components/pages/AddRecipe.tsx b/client/src/components/pages/AddRecipe.tsx index 057276c..f8089bc 100644 --- a/client/src/components/pages/AddRecipe.tsx +++ b/client/src/components/pages/AddRecipe.tsx @@ -1,34 +1,29 @@ -import { useCallback, useRef, useEffect, useState, createRef } from "react"; import { useAuthContext } from "../../context/AuthContext"; +import { LegacyRef, MutableRefObject, useCallback, useEffect, useRef, useState } from "react"; import { Button, Card, Divider, Form, Page, Panel } from "../ui" import { IIngredient, IRecipe } from "../../schemas"; import API from "../../util/API"; -import Creatable from "react-select/creatable"; -import { OptionType } from "../../util/types"; import { createOptionFromText, useSelectorContext } from "../../context/SelectorContext"; -import { MultiValue } from "react-select"; -import { Autocomplete, Chip, TextField } from "@mui/material"; +import IngredientSelector from "../derived/IngredientSelector"; +import { v4 } from "uuid"; const AddRecipe = () => { const { user, token } = useAuthContext(); - const { - data, setData, selector, setSelector, - options, setOptions, selected, setSelected, - onChange, onCreateOption - } = useSelectorContext(); - + const { data, setData, options, setOptions } = useSelectorContext(); + const [ingredientFields, setIngredientFields] = useState>([]); const [triggerChange, setTriggerChange] = useState(false); const [optionCount, setOptionCount] = useState(0); - const [form, setForm] = useState(); const [toast, setToast] = useState(<>) const [input, setInput] = useState({ name: '', preptime: '', description: '', authoruserid: '' }) + const initialIngredient = useRef(null); + // clear out selector state on page load - useEffect(() => { + /* useEffect(() => { setData(new Array()); setSelected(new Array()); setOptions(new Array()); - }, []) + }, []) */ // store all ingredients on page mount useEffect(() => { @@ -44,18 +39,14 @@ const AddRecipe = () => { return { label: each.name, value: each.id } })); - setOptionCount(result.length); + setIngredientFields([]); } })(); }, [token]) - useEffect(() => { - console.log(selected); - }, [selected]) - useEffect(() => { if (data.length) { - const autocompleteInstance = ( + /* const autocompleteInstance = ( { /> )} /> - ) + ) */ // create dropdown from new data /* @@ -102,13 +93,13 @@ const AddRecipe = () => { /> */ - data.length && setSelector(autocompleteInstance); + // data.length && setSelector(autocompleteInstance); setTriggerChange(true); } - }, [data, options, selected]) + }, [data, options]) // once the dropdown data has populated, mount it within the full form - useEffect(() => { + /* useEffect(() => { triggerChange && setForm( _config={{ parent: "AddRecipe", @@ -118,10 +109,9 @@ const AddRecipe = () => { initialState: input, getState: getFormState, richTextInitialValue: "

Enter recipe details here!

", - selectorInstance: selector }} /> ) - }, [triggerChange]) + }, [triggerChange]) */ useEffect(() => { console.log(options); @@ -139,6 +129,7 @@ const AddRecipe = () => { }, [user]) // store input data from form + /* const getFormState = useCallback((data: IRecipe) => { setInput(data); }, [input]) @@ -153,7 +144,11 @@ const AddRecipe = () => { setSelected((prev) => { return prev.filter(option => option !== target); }) - } + } */ + + useEffect(() => { + return; + }, [ingredientFields]) // submit handler const handleCreate = async () => { @@ -179,14 +174,70 @@ const AddRecipe = () => { ) } + + const destroySelector = useCallback((position: number) => { + setIngredientFields((prev) => { + const newState = new Array(); + + for (let i = 0; i < prev.length; i++) { + if (i === position) { + continue; + } else { + newState.push(prev[i]); + } + } + + return newState; + }) + }, [ingredientFields]); + + function handleNewOption() { + setIngredientFields((prev) => [...prev, ]) + setOptionCount(prev => prev + 1); + } + + useEffect(() => { + console.log(optionCount); + }, [optionCount]) return (

Add a New Recipe

- - { form } + +
+ + +
+ +
+ + +
+ +
+ + +
+ + { data && ( + + +
+ { ingredientFields } + +
+
+ )} + + + +
+ + { "description here" } +
+
{ toast }
diff --git a/client/src/components/pages/Login.tsx b/client/src/components/pages/Login.tsx index 0cb4f6d..78c0ed6 100644 --- a/client/src/components/pages/Login.tsx +++ b/client/src/components/pages/Login.tsx @@ -3,7 +3,7 @@ import { AuthContext, useAuthContext } from "../../context/AuthContext"; import { useNavigate, useParams } from "react-router-dom"; import { IUser, IUserAuth } from "../../schemas"; import { Button, Form, Page, Panel } from "../ui"; -import { FormConfig } from "../ui/Form"; +import { FormConfig } from "../ui/Form/Form"; import API from "../../util/API"; export default function Login() { @@ -41,7 +41,7 @@ export default function Login() {

Hello! Nice to see you again.

- + _config={{ parent: 'login', diff --git a/client/src/components/pages/Register/aboutyou.tsx b/client/src/components/pages/Register/aboutyou.tsx index 6eeacfd..e9fa104 100644 --- a/client/src/components/pages/Register/aboutyou.tsx +++ b/client/src/components/pages/Register/aboutyou.tsx @@ -6,7 +6,7 @@ import { IUser } from "../../../schemas"; import API from "../../../util/API"; import { Button, Page, Panel } from "../../ui"; import Divider from "../../ui/Divider"; -import Form from "../../ui/Form"; +import Form from "../../ui/Form/Form"; const blankUser: IUser = { firstname: '', @@ -52,7 +52,7 @@ const AboutYou: RegisterVariantType = ({ transitionDisplay }) => {

Tell us a bit about yourself:

- + _config={{ parent: "register", diff --git a/client/src/components/pages/Welcome.tsx b/client/src/components/pages/Welcome.tsx index 8d5b13a..18a2f43 100644 --- a/client/src/components/pages/Welcome.tsx +++ b/client/src/components/pages/Welcome.tsx @@ -8,7 +8,7 @@ const Welcome = () => { const { user } = useAuthContext(); const authUserActions = ( - + @@ -16,27 +16,27 @@ const Welcome = () => { ) const callToRegister = ( - +

Ready to get started?

) return ( - - + +

Welcome to Recipin

- +

Simple Recipe Management and Sharing for the Home

- +

Build Shopping Lists Directly from Your Recipes

diff --git a/client/src/components/ui/Browser.tsx b/client/src/components/ui/Browser.tsx index 11545ae..8516ca0 100644 --- a/client/src/components/ui/Browser.tsx +++ b/client/src/components/ui/Browser.tsx @@ -1,6 +1,6 @@ import { FC, useEffect, useState } from "react"; import Protect from "../../util/Protect"; -import Form from "./Form"; +import Form from "./Form/Form"; interface BrowserProps { children?: JSX.Element[] diff --git a/client/src/components/ui/Button.tsx b/client/src/components/ui/Button.tsx index 00b76cb..d76e36d 100644 --- a/client/src/components/ui/Button.tsx +++ b/client/src/components/ui/Button.tsx @@ -1,9 +1,9 @@ import { ButtonComponent } from "../../util/types" import "/src/sass/components/Button.scss"; -const Button: ButtonComponent = ({ onClick = (() => {}), children, extraStyles, disabled = false, disabledText = null }) => { +const Button: ButtonComponent = ({ onClick = (() => {}), children, extraClasses, disabled = false, disabledText = null }) => { return ( - ) diff --git a/client/src/components/ui/Card.tsx b/client/src/components/ui/Card.tsx index 3a5fe77..3f5e877 100644 --- a/client/src/components/ui/Card.tsx +++ b/client/src/components/ui/Card.tsx @@ -1,9 +1,9 @@ import { FC } from "react"; -const Card: FC<{ children?: JSX.Element | JSX.Element[], extraStyles?: string }> = ({ children = <>, extraStyles = ""}) => { +const Card: FC<{ children?: JSX.Element | JSX.Element[], extraClasses?: string }> = ({ children = <>, extraClasses = ""}) => { return ( -
+
{ Array.isArray(children) ? <>{children} : children }
) diff --git a/client/src/components/ui/Dropdown.tsx b/client/src/components/ui/Dropdown.tsx index dd3f3be..6c49abc 100644 --- a/client/src/components/ui/Dropdown.tsx +++ b/client/src/components/ui/Dropdown.tsx @@ -4,9 +4,9 @@ import { PortalBase } from "../../util/types"; import "/src/sass/components/Dropdown.scss"; // expects to receive buttons as children -const Dropdown: FC = ({ children, extraStyles = null }) => { +const Dropdown: FC = ({ children, extraClasses = null }) => { return ( - + { children } ) diff --git a/client/src/components/ui/Form.tsx b/client/src/components/ui/Form/Form.tsx similarity index 90% rename from client/src/components/ui/Form.tsx rename to client/src/components/ui/Form/Form.tsx index aa25281..1ca7fda 100644 --- a/client/src/components/ui/Form.tsx +++ b/client/src/components/ui/Form/Form.tsx @@ -1,12 +1,12 @@ import { ChangeEvent, FC, useEffect, useState } from "react" import { v4 } from "uuid" -import { useAuthContext } from "../../context/AuthContext"; -import { useSelectorContext } from "../../context/SelectorContext"; -import SelectorProvider from "../../context/SelectorProvider"; -import { IIngredient, IUser } from "../../schemas"; -import API from "../../util/API"; -import RichText from "./RichText" -import Selector from "./Selector"; +import { useAuthContext } from "../../../context/AuthContext"; +import { useSelectorContext } from "../../../context/SelectorContext"; +import SelectorProvider from "../../../context/SelectorProvider"; +import { IIngredient, IUser } from "../../../schemas"; +import API from "../../../util/API"; +import RichText from "../RichText" +import Selector from "../Selector"; import "/src/sass/components/Form.scss"; export interface FormConfig { @@ -17,7 +17,7 @@ export interface FormConfig { labels?: string[] dataTypes?: string[] richTextInitialValue?: string - extraStyles?: string + extraClasses?: string selectorInstance?: JSX.Element } @@ -132,7 +132,7 @@ function Form({ _config }: FormProps) { }, [config]); return ( -
+
{ contents }
) diff --git a/client/src/components/ui/Form/FormRow.tsx b/client/src/components/ui/Form/FormRow.tsx new file mode 100644 index 0000000..228395a --- /dev/null +++ b/client/src/components/ui/Form/FormRow.tsx @@ -0,0 +1,38 @@ +import { useEffect, useState } from "react"; +import { v4 } from "uuid"; + +interface FormRowConfig { + parent: any + labelText: string + idx?: number + dataType?: string +} + +function FormRow({ parent, labelText, idx, dataType = "string" }) { + const [row, setRow] = useState(); + + useEffect(() => { + switch (dataType) { + case "TINYMCE": + break; + case "string": + default: + setRow( +
+ + update(e, idx)} + value={state[i as keyof T] as string}> + +
+ ) + break; + } + }, []) + + return ( + <> + ) +} \ No newline at end of file diff --git a/client/src/components/ui/Navbar/variants.tsx b/client/src/components/ui/Navbar/variants.tsx index 99afe4f..09647b4 100644 --- a/client/src/components/ui/Navbar/variants.tsx +++ b/client/src/components/ui/Navbar/variants.tsx @@ -53,7 +53,7 @@ const LoggedIn = () => {
{ dropdownActive && ( - + @@ -65,7 +65,7 @@ const LoggedIn = () => { } { searchActive && ( - + ) diff --git a/client/src/components/ui/Page.tsx b/client/src/components/ui/Page.tsx index 40fe144..1fbebd4 100644 --- a/client/src/components/ui/Page.tsx +++ b/client/src/components/ui/Page.tsx @@ -5,10 +5,10 @@ import { PageComponent } from "../../util/types" import Navbar from "./Navbar"; import "/src/sass/components/Page.scss"; -const Page: PageComponent = ({ extraStyles, children }) => { +const Page: PageComponent = ({ extraClasses, children }) => { return (
-
+
{ children || null }
diff --git a/client/src/components/ui/Panel.tsx b/client/src/components/ui/Panel.tsx index d2aa57c..68cddb1 100644 --- a/client/src/components/ui/Panel.tsx +++ b/client/src/components/ui/Panel.tsx @@ -1,12 +1,20 @@ import { PanelComponent } from "../../util/types"; import "/src/sass/components/Panel.scss"; -const Panel: PanelComponent = ({ children, extraStyles }) => { - return ( -
- { children || null } -
- ) +const Panel: PanelComponent = ({ children, extraClasses, id }) => { + if (id) { + return ( +
+ { children || null } +
+ ) + } else { + return ( +
+ { children || null } +
+ ) + } } export default Panel; \ No newline at end of file diff --git a/client/src/components/ui/Selector.tsx b/client/src/components/ui/Selector.tsx index 4f8ac1f..3169e4a 100644 --- a/client/src/components/ui/Selector.tsx +++ b/client/src/components/ui/Selector.tsx @@ -1,4 +1,4 @@ -import { FormConfig } from "./Form" +import { FormConfig } from "./Form/Form" interface OptionType { value: number diff --git a/client/src/components/ui/Tooltip.tsx b/client/src/components/ui/Tooltip.tsx index 9002341..065cbea 100644 --- a/client/src/components/ui/Tooltip.tsx +++ b/client/src/components/ui/Tooltip.tsx @@ -1,9 +1,9 @@ import { FC } from "react"; import { PortalBase } from "../../util/types"; -const Tooltip: FC = ({ children, extraStyles = null }) => { +const Tooltip: FC = ({ children, extraClasses = null }) => { return ( -