diff --git a/client/index.html b/client/index.html index 542a362..7a82f7a 100644 --- a/client/index.html +++ b/client/index.html @@ -3,12 +3,12 @@ - RECIPIN | Personal Recipe Manager
+ diff --git a/client/package.json b/client/package.json index 8394d82..6b97e4f 100644 --- a/client/package.json +++ b/client/package.json @@ -9,10 +9,10 @@ "preview": "vite preview" }, "dependencies": { + "@tinymce/tinymce-react": "^4.2.0", "axios": "^1.2.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-quill": "^2.0.0", "react-router-dom": "^6.4.3", "sass": "^1.56.1", "uuid": "^9.0.0" diff --git a/client/src/App.tsx b/client/src/App.tsx index fdadcf9..0f1d03c 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -18,6 +18,7 @@ import AddRecipe from './components/pages/AddRecipe'; import CollectionBrowser from './components/pages/CollectionBrowser'; import { Navbar } from './components/ui'; import './sass/App.scss' +import RichText from './components/ui/RichText'; function App() { const [user, setUser] = useState({ user: undefined }); diff --git a/client/src/components/pages/AddRecipe.tsx b/client/src/components/pages/AddRecipe.tsx index b2041c4..0b5f1ab 100644 --- a/client/src/components/pages/AddRecipe.tsx +++ b/client/src/components/pages/AddRecipe.tsx @@ -1,7 +1,7 @@ import { useCallback, useEffect, useState } from "react"; import { useAuthContext } from "../../context/AuthContext"; import { IRecipe } from "../../schemas"; -import { Button, Divider, Form, Quill, Page, Panel } from "../ui" +import { Button, Divider, Form, Page, Panel } from "../ui" const AddRecipe = () => { const authContext = useAuthContext(); @@ -35,9 +35,10 @@ const AddRecipe = () => { parent: "AddRecipe", keys: ["name", "preptime", "ingredients", "description"], labels: ["Recipe Name:", "Prep Time:", "Ingredients:", "Description:"], - dataTypes: ['text', 'text', 'custom picker', 'QUILL'], + dataTypes: ['text', 'text', 'custom picker', 'TINYMCE'], initialState: input, - getState: getFormState + getState: getFormState, + richTextInitialValue: "

Enter recipe details here!

" }).mount() ) }, [input.authoruserid]) diff --git a/client/src/components/ui/Form.tsx b/client/src/components/ui/Form.tsx index 17db3d8..26aecec 100644 --- a/client/src/components/ui/Form.tsx +++ b/client/src/components/ui/Form.tsx @@ -1,6 +1,6 @@ -import { ChangeEvent, ChangeEventHandler } from "react"; -import { Quill } from '.' +import { ChangeEvent } from "react"; import { v4 } from 'uuid'; +import RichText from "./RichText"; /** * For the generation of more complex form objects with @@ -16,15 +16,17 @@ export interface FormConfig { getState: (received: T) => void labels?: string[] dataTypes?: string[] + richTextInitialValue?: string } export default class Form{ - public parent: string; - public labels: string[]; - public keys: string[]; - public dataTypes: any[] - public state: T; - public getState: (received: T) => void + private parent: string; + private labels: string[]; + private keys: string[]; + private dataTypes: any[] + private state: T; + private getState: (received: T) => void + private richTextInitialValue?: string; constructor(config: FormConfig){ this.parent = config.parent; @@ -33,27 +35,28 @@ export default class Form{ this.dataTypes = config.dataTypes || new Array(this.keys.length).fill('text'); this.state = config.initialState; this.getState = config.getState; + this.richTextInitialValue = config.richTextInitialValue; } update(e: ChangeEvent, idx: number) { - let newState; - - if (this.dataTypes[idx] == 'QUILL') { - newState = { - ...this.state, - [this.keys[idx]]: e - } - } else { - newState = { - ...this.state, - [this.keys[idx]]: e.target['value' as keyof EventTarget] - } + let newState = { + ...this.state, + [this.keys[idx]]: e.target['value' as keyof EventTarget] } this.state = newState; this.getState(newState); } + updateRichText(txt: string, idx: number) { + this.state = { + ...this.state, + [this.keys[idx]]: txt + } + + this.getState(this.state); + } + mount() { let output = new Array(); @@ -65,11 +68,11 @@ export default class Form{ this.dataTypes[i] = 'text'; } - if (this.dataTypes[i] == 'QUILL') { + if (this.dataTypes[i] == 'TINYMCE') { input = (
- this.update(e, i)} /> + this.updateRichText(txt, i)} />
) } else { diff --git a/client/src/components/ui/Quill.tsx b/client/src/components/ui/Quill.tsx deleted file mode 100644 index ddba2d0..0000000 --- a/client/src/components/ui/Quill.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { ChangeEvent, FC, useEffect, useState } from "react" -import ReactQuill from "react-quill" - -interface QuillParams { - id: string - onChange: (params?: any) => any - theme?: string -} - -const Quill: FC = ({ id, onChange, theme = 'snow' }) => { - const [value, setValue] = useState(''); - - useEffect(() => { - onChange(value); - }, [value]) - - return ( - - ) -} - -export default Quill; \ No newline at end of file diff --git a/client/src/components/ui/RichText.tsx b/client/src/components/ui/RichText.tsx new file mode 100644 index 0000000..d249dd4 --- /dev/null +++ b/client/src/components/ui/RichText.tsx @@ -0,0 +1,45 @@ +import { Editor } from "@tinymce/tinymce-react"; +import { FC, useEffect, useState } from "react"; + +interface RichTextProps { + id: string + initialValue?: string + getState: (toSend: string) => void +} + +const RichText: FC = ({ id, initialValue, getState }) => { + const [text, setText] = useState(); + const [editorState, setEditorState] = useState(); + + useEffect(() => { + getState(text); + }, [text]) + + const handleChange = (txt: string, editor: any) => { + setText(txt); + setEditorState(editor); + } + + return ( + handleChange(txt, editor)} + initialValue={initialValue || '

'} + init={{ + height: 500, + menubar: false, + plugins: [ + 'advlist autolink lists link image charmap print preview anchor', + 'searchreplace visualblocks code fullscreen', + 'insertdatetime media table paste code help wordcount' + ], + toolbar: 'undo redo | formatselect | ' + + 'bold italic backcolor | alignleft aligncenter ' + + 'alignright alignjustify | bullist numlist outdent indent | ' + + 'removeformat | help', + content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:14px }' + }} + /> + ); +} + +export default RichText; \ No newline at end of file