Selaa lähdekoodia

Outsourced ModalForm to make it more reusable

unknown 4 vuotta sitten
vanhempi
commit
4e89e4c568

+ 59 - 66
client/src/components/Apps/AppForm/AppForm.tsx

@@ -3,11 +3,11 @@ import { connect } from 'react-redux';
 import { addApp, updateApp } from '../../../store/actions';
 import { App, NewApp } from '../../../interfaces/App';
 
-import classes from './AppForm.module.css';
-import Icon from '../../UI/Icons/Icon/Icon';
+import ModalForm from '../../UI/Forms/ModalForm/ModalForm';
+import InputGroup from '../../UI/Forms/InputGroup/InputGroup';
 
 interface ComponentProps {
-  modalHandler: Function;
+  modalHandler: () => void;
   addApp: (formData: NewApp) => any;
   updateApp: (id: number, formData: NewApp) => any;
   app?: App;
@@ -30,7 +30,6 @@ const AppForm = (props: ComponentProps): JSX.Element => {
 
   useEffect(() => {
     if (props.app) {
-      console.log('app');
       setFormData({
         name: props.app.name,
         url: props.app.url,
@@ -39,10 +38,6 @@ const AppForm = (props: ComponentProps): JSX.Element => {
     }
   }, [props.app])
 
-  const _modalHandler = () => {
-    props.modalHandler();
-  }
-
   const inputChangeHandler = (e: ChangeEvent<HTMLInputElement>): void => {
     setFormData({
       ...formData,
@@ -50,7 +45,7 @@ const AppForm = (props: ComponentProps): JSX.Element => {
     })
   }
 
-  const formSubmitHandler = (e: SyntheticEvent): void => {
+  const formSubmitHandler = (e: SyntheticEvent<HTMLFormElement>): void => {
     e.preventDefault();
 
     if (!props.app) {
@@ -68,63 +63,61 @@ const AppForm = (props: ComponentProps): JSX.Element => {
   }
 
   return (
-    <div className={classes.AppForm}>
-      <div className={classes.AppFormIcon} onClick={_modalHandler}>
-        <Icon icon='mdiClose' />
-      </div>
-      <form onSubmit={(e) => formSubmitHandler(e)}>
-        <div className={classes.InputGroup}>
-          <label htmlFor='name'>App Name</label>
-          <input
-            type='text'
-            name='name'
-            id='name'
-            placeholder='Bookstack'
-            required
-            value={formData.name}
-            onChange={(e) => inputChangeHandler(e)}
-            ref={inputRef}
-          />
-        </div>
-        <div className={classes.InputGroup}>
-          <label htmlFor='url'>App URL</label>
-          <input
-            type='text'
-            name='url'
-            id='url'
-            placeholder='bookstack.example.com'
-            required
-            value={formData.url}
-            onChange={(e) => inputChangeHandler(e)}
-          />
-          <span>Use URL without protocol</span>
-        </div>
-        <div className={classes.InputGroup}>
-          <label htmlFor='icon'>App Icon</label>
-          <input
-            type='text'
-            name='icon'
-            id='icon'
-            placeholder='book-open-outline'
-            required
-            value={formData.icon}
-            onChange={(e) => inputChangeHandler(e)}
-          />
-          <span>
-            Use icon name from MDI. 
-            <a
-              href='https://materialdesignicons.com/'
-              target='blank'>
-              {' '}Click here for reference
-            </a>
-          </span>
-        </div>
-        {!props.app
-          ? <button type="submit">add</button>
-          : <button type="submit">update</button>
-        }
-      </form>
-    </div>
+    <ModalForm
+      modalHandler={props.modalHandler}
+      formHandler={formSubmitHandler}
+    >
+      <InputGroup>
+        <label htmlFor='name'>App Name</label>
+        <input
+          type='text'
+          name='name'
+          id='name'
+          placeholder='Bookstack'
+          required
+          value={formData.name}
+          onChange={(e) => inputChangeHandler(e)}
+          ref={inputRef}
+        />
+      </InputGroup>
+      <InputGroup>
+        <label htmlFor='url'>App URL</label>
+        <input
+          type='text'
+          name='url'
+          id='url'
+          placeholder='bookstack.example.com'
+          required
+          value={formData.url}
+          onChange={(e) => inputChangeHandler(e)}
+        />
+        <span>Use URL without protocol</span>
+      </InputGroup>
+      <InputGroup>
+        <label htmlFor='icon'>App Icon</label>
+        <input
+          type='text'
+          name='icon'
+          id='icon'
+          placeholder='book-open-outline'
+          required
+          value={formData.icon}
+          onChange={(e) => inputChangeHandler(e)}
+        />
+        <span>
+          Use icon name from MDI. 
+          <a
+            href='https://materialdesignicons.com/'
+            target='blank'>
+            {' '}Click here for reference
+          </a>
+        </span>
+      </InputGroup>
+      {!props.app
+        ? <button type="submit">add</button>
+        : <button type="submit">update</button>
+      }
+    </ModalForm>
   )
 }
 

+ 0 - 21
client/src/components/Apps/AppForm/AppForm.module.css → client/src/components/UI/Forms/InputGroup/InputGroup.module.css

@@ -1,24 +1,3 @@
-.AppForm {
-  background-color: var(--color-background);
-  color: var(--color-primary);
-  border-radius: 6px;
-  width: 60%;
-  position: relative;
-  /* height: 50vh; */
-  padding: 50px 50px;
-}
-
-.AppFormIcon {
-  width: 40px;
-  position: absolute;
-  right: 5px;
-  top: 5px;
-}
-
-.AppFormIcon:hover {
-  cursor: pointer;
-}
-
 .InputGroup {
   margin-bottom: 15px;
 }

+ 15 - 0
client/src/components/UI/Forms/InputGroup/InputGroup.tsx

@@ -0,0 +1,15 @@
+import classes from './InputGroup.module.css';
+
+interface ComponentProps {
+  children: JSX.Element | JSX.Element[];
+}
+
+const InputGroup = (props: ComponentProps): JSX.Element => {
+  return (
+    <div className={classes.InputGroup}>
+      {props.children}
+    </div>
+  )
+}
+
+export default InputGroup;

+ 20 - 0
client/src/components/UI/Forms/ModalForm/ModalForm.module.css

@@ -0,0 +1,20 @@
+.ModalForm {
+  background-color: var(--color-background);
+  color: var(--color-primary);
+  border-radius: 6px;
+  width: 60%;
+  position: relative;
+  /* height: 50vh; */
+  padding: 50px 50px;
+}
+
+.ModalFormIcon {
+  width: 40px;
+  position: absolute;
+  right: 5px;
+  top: 5px;
+}
+
+.ModalFormIcon:hover {
+  cursor: pointer;
+}

+ 31 - 0
client/src/components/UI/Forms/ModalForm/ModalForm.tsx

@@ -0,0 +1,31 @@
+import { SyntheticEvent } from 'react';
+
+import classes from './ModalForm.module.css';
+import Icon from '../../Icons/Icon/Icon';
+
+interface ComponentProps {
+  children: JSX.Element | JSX.Element[];
+  modalHandler?: () => void;
+  formHandler: (e: SyntheticEvent<HTMLFormElement>) => void;
+}
+
+const ModalForm = (props: ComponentProps): JSX.Element => {
+  const _modalHandler = (): void => {
+    if (props.modalHandler) {
+      props.modalHandler();
+    }
+  }
+
+  return (
+    <div className={classes.ModalForm}>
+      <div className={classes.ModalFormIcon} onClick={_modalHandler}>
+        <Icon icon='mdiClose' />
+      </div>
+      <form onSubmit={(e) => props.formHandler(e)}>
+        {props.children}
+      </form>
+    </div>
+  )
+}
+
+export default ModalForm;