From 38edb76929346181e7d81ba921f2c6fcd1bb5d79 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 24 May 2021 11:51:05 +0200 Subject: [PATCH] Bookmarks Form --- client/src/components/Apps/Apps.tsx | 7 +- .../Bookmarks/BookmarkForm/BookmarkForm.tsx | 132 ++++++++++++++++++ client/src/components/Bookmarks/Bookmarks.tsx | 48 ++++++- client/src/interfaces/Bookmark.ts | 6 + controllers/bookmark.js | 4 +- 5 files changed, 189 insertions(+), 8 deletions(-) create mode 100644 client/src/components/Bookmarks/BookmarkForm/BookmarkForm.tsx diff --git a/client/src/components/Apps/Apps.tsx b/client/src/components/Apps/Apps.tsx index 9b26111..ae76a0a 100644 --- a/client/src/components/Apps/Apps.tsx +++ b/client/src/components/Apps/Apps.tsx @@ -3,10 +3,10 @@ import { Link } from 'react-router-dom'; // Redux import { connect } from 'react-redux'; -import { getApps, pinApp, addApp } from '../../store/actions'; +import { getApps } from '../../store/actions'; // Typescript -import { App, GlobalState, NewApp } from '../../interfaces'; +import { App, GlobalState } from '../../interfaces'; // CSS import classes from './Apps.module.css'; @@ -25,7 +25,6 @@ import AppTable from './AppTable/AppTable'; interface ComponentProps { getApps: Function; - addApp: (formData: NewApp) => void; apps: App[]; loading: boolean; } @@ -120,4 +119,4 @@ const mapStateToProps = (state: GlobalState) => { } } -export default connect(mapStateToProps, { getApps, addApp })(Apps); \ No newline at end of file +export default connect(mapStateToProps, { getApps })(Apps); \ No newline at end of file diff --git a/client/src/components/Bookmarks/BookmarkForm/BookmarkForm.tsx b/client/src/components/Bookmarks/BookmarkForm/BookmarkForm.tsx new file mode 100644 index 0000000..d299070 --- /dev/null +++ b/client/src/components/Bookmarks/BookmarkForm/BookmarkForm.tsx @@ -0,0 +1,132 @@ +import { useState, SyntheticEvent, Fragment, ChangeEvent, useEffect } from 'react'; +import { connect } from 'react-redux'; + +import ModalForm from '../../UI/Forms/ModalForm/ModalForm'; +import InputGroup from '../../UI/Forms/InputGroup/InputGroup'; +import { Category, GlobalState, NewBookmark, NewCategory } from '../../../interfaces'; +import { FormContentType } from '../Bookmarks'; +import { getCategories } from '../../../store/actions'; + +interface ComponentProps { + modalHandler: () => void; + contentType: FormContentType; + categories: Category[]; +} + +const BookmarkForm = (props: ComponentProps): JSX.Element => { + const [categoryName, setCategoryName] = useState({ + name: '' + }) + + const [formData, setFormData] = useState({ + name: '', + url: '', + categoryId: -1 + }) + + const formSubmitHandler = (e: SyntheticEvent): void => { + e.preventDefault(); + + if (formData.categoryId === -1) { + alert('select category'); + } + } + + const inputChangeHandler = (e: ChangeEvent): void => { + setFormData({ + ...formData, + [e.target.name]: e.target.value + }) + } + + const selectChangeHandler = (e: ChangeEvent): void => { + setFormData({ + ...formData, + categoryId: parseInt(e.target.value) + }) + } + + return ( + + {props.contentType === FormContentType.category + ? ( + + + + setCategoryName({ name: e.target.value })} + /> + + + ) + : ( + + + + inputChangeHandler(e)} + /> + + + + inputChangeHandler(e)} + /> + + + + + + + ) + } + + + ) +} + +const mapStateToProps = (state: GlobalState) => { + return { + categories: state.bookmark.categories + } +} + +export default connect(mapStateToProps, { getCategories })(BookmarkForm); \ No newline at end of file diff --git a/client/src/components/Bookmarks/Bookmarks.tsx b/client/src/components/Bookmarks/Bookmarks.tsx index a4e830a..3c4aadd 100644 --- a/client/src/components/Bookmarks/Bookmarks.tsx +++ b/client/src/components/Bookmarks/Bookmarks.tsx @@ -1,4 +1,4 @@ -import { useEffect } from 'react'; +import { useEffect, useState } from 'react'; import { Link } from 'react-router-dom'; import { connect } from 'react-redux'; import { getCategories } from '../../store/actions'; @@ -12,6 +12,8 @@ import ActionButton from '../UI/Buttons/ActionButton/ActionButton'; import BookmarkGrid from './BookmarkGrid/BookmarkGrid'; import { Category, GlobalState } from '../../interfaces'; import Spinner from '../UI/Spinner/Spinner'; +import Modal from '../UI/Modal/Modal'; +import BookmarkForm from './BookmarkForm/BookmarkForm'; interface ComponentProps { loading: boolean; @@ -19,15 +21,45 @@ interface ComponentProps { getCategories: () => void; } +export enum FormContentType { + category, + bookmark +} + const Bookmarks = (props: ComponentProps): JSX.Element => { + const [modalIsOpen, setModalIsOpen] = useState(false); + const [formContentType, setFormContentType] = useState(FormContentType.category); + useEffect(() => { if (props.categories.length === 0) { props.getCategories(); } }, [props.getCategories]) + const toggleModal = (): void => { + setModalIsOpen(!modalIsOpen); + } + + const addActionHandler = (contentType: FormContentType) => { + setFormContentType(contentType); + toggleModal(); + } + return ( + + {formContentType === FormContentType.category + ? + : + } + + Go back)} @@ -35,11 +67,21 @@ const Bookmarks = (props: ComponentProps): JSX.Element => {
addActionHandler(FormContentType.category)} /> addActionHandler(FormContentType.bookmark)} + /> + +
diff --git a/client/src/interfaces/Bookmark.ts b/client/src/interfaces/Bookmark.ts index 2982993..4025361 100644 --- a/client/src/interfaces/Bookmark.ts +++ b/client/src/interfaces/Bookmark.ts @@ -4,4 +4,10 @@ export interface Bookmark extends Model { name: string; url: string; categoryId: number; +} + +export interface NewBookmark { + name: string; + url: string; + categoryId: number; } \ No newline at end of file diff --git a/controllers/bookmark.js b/controllers/bookmark.js index 5a76c40..7baa664 100644 --- a/controllers/bookmark.js +++ b/controllers/bookmark.js @@ -18,7 +18,9 @@ exports.createBookmark = asyncWrapper(async (req, res, next) => { // @route GET /api/bookmarks // @access Public exports.getBookmarks = asyncWrapper(async (req, res, next) => { - const bookmarks = await Bookmark.findAll(); + const bookmarks = await Bookmark.findAll({ + order: [['name', 'ASC']] + }); res.status(200).json({ success: true,