Jelajahi Sumber

Change associations type to array of strings.

Tatiana Inama 6 tahun lalu
induk
melakukan
753d7dd276
2 mengubah file dengan 88 tambahan dan 10 penghapusan
  1. 12 0
      src/App.css
  2. 76 10
      src/DrawCanvas.tsx

+ 12 - 0
src/App.css

@@ -74,6 +74,18 @@ form button {
   margin-bottom: 0!important;
 }
 
+#vom-associations-list {
+  display: flex; 
+}
+
+.vom-remove-association {
+  padding: 0;
+  border: 0;
+  color: #F2F2F2;
+  font-size: 0.7rem;
+  line-height: 1rem;
+}
+
 #magic-canvas,
 #vom-admin-canvas {
   width: 100%;

+ 76 - 10
src/DrawCanvas.tsx

@@ -1,10 +1,10 @@
 
 import React, { useState, useEffect } from 'react';
 import Paper, { Path, PaperScope } from 'paper';
-import { Modal, ModalBody, ModalFooter, Button, Form, FormGroup, Label, Input, Fade, ModalHeader, ButtonGroup, Badge, FormFeedback } from 'reactstrap';
+import { Modal, ModalBody, ModalFooter, Button, Form, FormGroup, Label, Input, Fade, ModalHeader, ButtonGroup, Badge, FormFeedback, InputGroup, InputGroupAddon } from 'reactstrap';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faTrashAlt } from '@fortawesome/free-solid-svg-icons';
-import { remove, update, difference, path } from 'ramda';
+import { faTrashAlt, faTimes } from '@fortawesome/free-solid-svg-icons';
+import { remove, update, difference } from 'ramda';
 
 const COLORS = [
   '#ffc6bc',
@@ -87,7 +87,7 @@ type CanvasProps = {
 type FormData = {
   name: string,
   soundExample: string,
-  associations: string,
+  associations: string[],
 };
 
 type PathQuestionFormState = {
@@ -97,19 +97,78 @@ type PathQuestionFormState = {
   }
 }
 
+const Associations: React.FunctionComponent<{ 
+  initialValue: string[],
+  saveAssociations: (list: string[]) => void,
+  id: string,
+  valid?: boolean,
+  invalid?: boolean,
+}> = 
+({ saveAssociations, initialValue, id, valid, invalid }) => {
+  const [ associations, setAssociations ] = useState<string[]>(initialValue);
+  const [ newValue, setNewValue ] = useState<string>('');
+
+  useEffect(() => {
+    setAssociations(initialValue);
+  }, [initialValue])
+
+  const maxAssociationsReached = () => associations.length >= 5;
+
+  const updateAssociations = (newAssociations: string[]) => {
+    setAssociations(newAssociations);
+    saveAssociations(newAssociations);
+  }
+
+  return (
+    <div id="vom-associations">
+      <FormGroup>
+        <InputGroup>
+          <Input value={newValue} onChange={(e) => setNewValue(e.target.value)} disabled={maxAssociationsReached()} id={id} valid={valid} invalid={invalid}/>
+          <InputGroupAddon addonType="append">
+            <Button 
+              onClick={() => {
+                updateAssociations([...associations, newValue]);
+                setNewValue('')
+              }}
+              disabled={maxAssociationsReached()}
+            >Add</Button>
+          </InputGroupAddon>
+        <FormFeedback>At least one association is required</FormFeedback>
+        </InputGroup>
+      </FormGroup>
+      {
+        associations.length ? (
+          <div className="vom-associations-list mt-1">
+            {
+              associations.map((association, key) => (
+              <Badge color="secondary" key={key} className="vom-associations-value mr-1 mb-1">
+                {association}
+                <Button className="vom-remove-association p-1" color="link" onClick={() => updateAssociations(remove(key, 1, associations))}>
+                  <FontAwesomeIcon icon={faTimes} />
+                </Button>
+              </Badge>
+              ))
+            }
+          </div>
+        ) : null
+      }
+    </div>
+  )
+}
+
 const PathQuestions: React.FunctionComponent<{
   saveData: (data: FormData, editing?: boolean) => void,
   cancel: () => void,
   initialData?: {
     name: string,
     soundExample: string,
-    associations: string,
+    associations: string[],
   }
 }> = ({ saveData, cancel, initialData }) => {
   const [ data, setData ] = useState<FormData>({
     name: '',
     soundExample: '',
-    associations: '',
+    associations: [],
   });
 
   const [ form, setFormState ] = useState<PathQuestionFormState>({
@@ -134,6 +193,13 @@ const PathQuestions: React.FunctionComponent<{
     });
   }
 
+  const saveAssociations = (associations: string[]) => {
+    setData({
+      ...data,
+      associations,
+    })
+  }
+
   const setInputValidation = (field: keyof FormData): undefined | { valid: true } | { invalid: true } => {
     if (!form.submitted) {
       return undefined;
@@ -151,7 +217,7 @@ const PathQuestions: React.FunctionComponent<{
       validation: {
         name: data.name !== '',
         soundExample: data.soundExample !== '',
-        associations: data.associations !== ''
+        associations: data.associations.length !== 0
       }
     }
     setFormState(_form);
@@ -176,9 +242,9 @@ const PathQuestions: React.FunctionComponent<{
 
           <FormGroup>
             <Label for="path-associations">Please provide any associations (ideas, judgements, opinions, etc.) that come to mind when you encounter this accent/a speaker with this accent</Label>
-            <Input type="text" id="path-associations" value={data.associations} onChange={handleChange('associations')} {...setInputValidation('associations')}/>
-            <FormFeedback>Please, fill up this input</FormFeedback>
+            <Associations id="path-associations" initialValue={data.associations} saveAssociations={saveAssociations} {...setInputValidation('associations')}></Associations>
           </FormGroup>
+
         </Form> 
       </ModalBody>
       <ModalFooter>
@@ -222,7 +288,7 @@ class Canvas extends React.Component<CanvasProps, CanvasState> {
         _path: {
           form: {
             name: '',
-            associations: '',
+            associations: [],
             soundExample: '',
           },
           path: mkPath(color, event.point),