From ad6b25b0dd395781af82fd6276fb0dc965d819f6 Mon Sep 17 00:00:00 2001 From: "Planoetscher Daniel (Student Com20)" <daniel.planoetscher@stud-inf.unibz.it> Date: Sun, 23 May 2021 22:47:23 +0200 Subject: [PATCH] forms now usable --- .../forms/AssigneesForm/assignees-form.scss | 41 +++++ .../index.tsx} | 34 ++-- .../components/forms/ProjectForm/index.tsx | 80 +++++---- .../forms/ProjectForm/project-form.scss | 3 + .../index.tsx} | 26 ++- .../RequirementsForm/requirements-form.scss | 41 +++++ .../src/components/forms/TaskForm/index.tsx | 169 +++++++++++------- .../components/forms/TaskForm/task-form.scss | 17 ++ client/src/components/forms/form.scss | 95 ++++++++++ .../components/layout/TaskList/task-list.scss | 1 + .../ui/CheckboxGroup/checkbox-group.scss | 60 +++++++ .../src/components/ui/CheckboxGroup/index.tsx | 10 +- client/src/components/ui/TextInput/index.tsx | 9 +- .../components/ui/TextInput/text-input.scss | 10 ++ client/src/pages/Tasks/TaskCreate/index.tsx | 35 ++-- client/src/styles/settings.scss | 1 + 16 files changed, 501 insertions(+), 131 deletions(-) create mode 100644 client/src/components/forms/AssigneesForm/assignees-form.scss rename client/src/components/forms/{TaskForm/AssigneesForm.tsx => AssigneesForm/index.tsx} (66%) rename client/src/components/forms/{TaskForm/RequirementsForm.tsx => RequirementsForm/index.tsx} (73%) create mode 100644 client/src/components/forms/RequirementsForm/requirements-form.scss create mode 100644 client/src/components/forms/form.scss create mode 100644 client/src/components/ui/CheckboxGroup/checkbox-group.scss diff --git a/client/src/components/forms/AssigneesForm/assignees-form.scss b/client/src/components/forms/AssigneesForm/assignees-form.scss new file mode 100644 index 0000000..7546bb9 --- /dev/null +++ b/client/src/components/forms/AssigneesForm/assignees-form.scss @@ -0,0 +1,41 @@ +@use 'styles/settings.scss'as s; + +.assignees-field { + .assignee { + width: 100%; + padding: 20px; + border-radius: 15px; + background: s.$gray; + position: relative; + margin: 10px 0; + + .delete { + position: absolute; + top: 0; + right: 0; + width: 30px; + height: 30px; + color: s.$white; + display: flex; + justify-content: center; + align-items: center; + background: s.$red; + border-radius: 50%; + transform: translate(50%, -50%); + cursor: pointer; + + span { + font-size: 18px; + } + } + + &.add-btn { + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + font-size: 24px; + font-weight: s.$weight-bold; + } + } +} \ No newline at end of file diff --git a/client/src/components/forms/TaskForm/AssigneesForm.tsx b/client/src/components/forms/AssigneesForm/index.tsx similarity index 66% rename from client/src/components/forms/TaskForm/AssigneesForm.tsx rename to client/src/components/forms/AssigneesForm/index.tsx index 013e661..f6e58c3 100644 --- a/client/src/components/forms/TaskForm/AssigneesForm.tsx +++ b/client/src/components/forms/AssigneesForm/index.tsx @@ -1,6 +1,7 @@ +import './assignees-form.scss'; import { TaskAssignment } from "adapters/task"; import { useCallback, useEffect, useState } from "react"; -import { possibleMember } from "."; +import { possibleMember } from "../TaskForm"; import Popup from 'components/ui/Popup'; import Button from 'components/ui/Button'; @@ -35,25 +36,32 @@ export default function AssigneesForm({ assignees, setAssignees, members }: Prop const removeAssignee = useCallback((member: string) => { - setAssignees((state: any) => state.filter((r: any) => r.user !== member)); + setAssignees((state: any) => state.filter((r: any) => r.user !== member)); }, [setAssignees]) - + return ( <> - <div className="requirements-field"> + <div className="assignees-field"> + <h2>Assignees</h2> { assignees.map((assignee) => ( - <div className="requirement" key={assignee.user}> - <h2>{members.find(member => member.id === assignee.user)?.label}</h2> - <div>{assignee.time}</div> - <div onClick={() => removeAssignee(assignee.user)}>delete</div> + <div className="assignee" key={assignee.user}> + <div className="person"> + {members.find(member => member.id === assignee.user)?.label} + </div> + <div className="time">{assignee.time}</div> + <div className="delete" onClick={() => removeAssignee(assignee.user)}> + <span className="material-icons"> + clear + </span> + </div> </div> )) } { possibleMembers.length > 0 && ( - <div className="add-btn" onClick={() => setAddNew(true)}> - new + <div className="add-btn assignee" onClick={() => setAddNew(true)}> + + </div> ) } @@ -69,8 +77,10 @@ export default function AssigneesForm({ assignees, setAssignees, members }: Prop )) } </select> - <input type="number" min={1} onChange={(e) => setSelectedTime(e.target.value)} /> - <Button type="submit" onClick={addAssignee}> + <div className="time-field"> + <input type="number" min={1} onChange={(e) => setSelectedTime(e.target.value)} /> + </div> + <Button type="submit" onClick={addAssignee} className="Expanded"> Add the assignee </Button> </Popup> diff --git a/client/src/components/forms/ProjectForm/index.tsx b/client/src/components/forms/ProjectForm/index.tsx index 1ada5d1..bf634ff 100644 --- a/client/src/components/forms/ProjectForm/index.tsx +++ b/client/src/components/forms/ProjectForm/index.tsx @@ -6,6 +6,7 @@ import TextInput from 'components/ui/TextInput'; import './project-form.scss'; import { getTeam, getTeams, Team } from 'adapters/team'; import CheckboxGroup from 'components/ui/CheckboxGroup'; +import '../form.scss'; interface Props { project?: Project @@ -51,7 +52,7 @@ export function getDateString(date?: Date) { let month = date.getMonth() + 1; return date.getFullYear() + '-' + (month / 10 < 1 ? '0' + month : month) + '-' - + (date.getDate() / 10 < 1 ? '0' + date.getDate() : date.getDate()); + + (date.getDate() / 10 < 1 ? '0' + date.getDate() : date.getDate()); } else { return undefined; } @@ -106,7 +107,7 @@ export default function ProjectForm({ project, onSubmit }: Props) { validateColor(color ?? '') === null && validateTeams(teams) === null ) { - + onSubmit?.(teams, name ?? '', text ?? '', color ?? '', status ?? Status.OPEN, deadline); } else { setError('Please fill in the mandatory fields.'); @@ -116,6 +117,7 @@ export default function ProjectForm({ project, onSubmit }: Props) { return ( <form onSubmit={handleSubmit} className="project-form"> {error && <Callout message={error} />} + <h2>General</h2> <TextInput label="Name" name="name" @@ -130,8 +132,47 @@ export default function ProjectForm({ project, onSubmit }: Props) { defaultText={text} validation={validateText} type="textarea" + note="A short description of the project." /> + <div className="fields-row"> + <div className="col"> + <TextInput + label="Deadline" + name="text" + defaultText={deadline} + onChange={setDeadline} + type="date" + note="Until when the project is due." + /> + + </div> + <div className="col"> + { + status && + <div className="field"> + <label className="field-label" htmlFor="status">Status</label> + <select id="status" defaultValue={project?.status} onChange={(e) => { + let currentStatus = Object.values(Status).find(s => s === e.target.value) ?? undefined; + setStatus(currentStatus); + } + }> + <option value="">Please choose a status</option> + { + allStatus.map((s) => ( + <option value={s} key={s}>{s}</option> + )) + } + </select> + </div> + } + + </div> + + </div> + + <h2>Color</h2> + <p>Choose a color, to identify to project later more easily.</p> <div className="color-list"> { colors.map(colorItem => ( @@ -145,38 +186,17 @@ export default function ProjectForm({ project, onSubmit }: Props) { )) } </div> - - <TextInput - label="Deadline" - name="text" - defaultText={deadline} - onChange={setDeadline} - type="date" - /> - <div className="teams"> + <h2>Teams</h2> + <p>Which ones of your teams are working on this project</p> <CheckboxGroup choices={allTeams} chosen={teams} setChosen={setTeams} /> </div> - { - status && - <select defaultValue={project?.status} onChange={(e) => { - let currentStatus = Object.values(Status).find(s => s === e.target.value) ?? undefined; - setStatus(currentStatus); - } - }> - <option value="">Please choose a status</option> - { - allStatus.map((s) => ( - <option value={s} key={s}>{s}</option> - )) - } - </select> - } - - <Button type="submit"> - {project ? 'Update' : 'Create'} - </Button> + <div className="button-container"> + <Button type="submit" className="expanded"> + {project ? 'Update' : 'Create'} + </Button> + </div> </form> ) } \ No newline at end of file diff --git a/client/src/components/forms/ProjectForm/project-form.scss b/client/src/components/forms/ProjectForm/project-form.scss index 893fa61..d7aa690 100644 --- a/client/src/components/forms/ProjectForm/project-form.scss +++ b/client/src/components/forms/ProjectForm/project-form.scss @@ -37,4 +37,7 @@ } } } + p { + margin-bottom: 20px; + } } \ No newline at end of file diff --git a/client/src/components/forms/TaskForm/RequirementsForm.tsx b/client/src/components/forms/RequirementsForm/index.tsx similarity index 73% rename from client/src/components/forms/TaskForm/RequirementsForm.tsx rename to client/src/components/forms/RequirementsForm/index.tsx index 197d287..85d8bab 100644 --- a/client/src/components/forms/TaskForm/RequirementsForm.tsx +++ b/client/src/components/forms/RequirementsForm/index.tsx @@ -1,6 +1,7 @@ import { TaskRequirement } from 'adapters/task'; +import './requirements-form.scss'; import { useCallback, useEffect, useState } from 'react'; -import { possibleRole } from '.'; +import { possibleRole } from '../TaskForm'; import Popup from 'components/ui/Popup'; import Button from 'components/ui/Button'; @@ -35,25 +36,30 @@ export default function RequirementsForm({ roles, requirements, setRequirements const removeRequirement = useCallback((role: string) => { - setRequirements((state: any) => state.filter((r: any) => r.role !== role)); + setRequirements((state: any) => state.filter((r: any) => r.role !== role)); }, [setRequirements]) - + return ( <> <div className="requirements-field"> + <h2>Requirements</h2> { requirements.map((requirement) => ( <div className="requirement" key={requirement.role}> - <h2>{roles.find(role => role.id === requirement.role)?.label}</h2> + <div>{roles.find(role => role.id === requirement.role)?.label}</div> <div>{requirement.time}</div> - <div onClick={() => removeRequirement(requirement.role)}>delete</div> + <div className="delete" onClick={() => removeRequirement(requirement.role)}> + <span className="material-icons"> + clear + </span> + </div> </div> )) } { possibleRoles.length > 0 && ( - <div className="add-btn" onClick={() => setAddNew(true)}> - new + <div className="add-btn requirement" onClick={() => setAddNew(true)}> + + </div> ) } @@ -69,8 +75,10 @@ export default function RequirementsForm({ roles, requirements, setRequirements )) } </select> - <input type="number" min={1} onChange={(e) => setSelectedTime(e.target.value)} /> - <Button type="submit" onClick={addRequirement}> + <div className="time-field"> + <input type="number" min={1} onChange={(e) => setSelectedTime(e.target.value)} /> + </div> + <Button type="submit" onClick={addRequirement} className="expanded"> Create new requirement </Button> </Popup> diff --git a/client/src/components/forms/RequirementsForm/requirements-form.scss b/client/src/components/forms/RequirementsForm/requirements-form.scss new file mode 100644 index 0000000..90fe9ba --- /dev/null +++ b/client/src/components/forms/RequirementsForm/requirements-form.scss @@ -0,0 +1,41 @@ +@use 'styles/settings.scss'as s; + +.requirements-field { + .requirement { + width: 100%; + padding: 20px; + border-radius: 15px; + background: s.$gray; + position: relative; + margin: 10px 0; + + .delete { + position: absolute; + top: 0; + right: 0; + width: 30px; + height: 30px; + color: s.$white; + display: flex; + justify-content: center; + align-items: center; + background: s.$red; + border-radius: 50%; + transform: translate(50%, -50%); + cursor: pointer; + + span { + font-size: 18px; + } + } + + &.add-btn { + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + font-size: 24px; + font-weight: s.$weight-bold; + } + } +} \ No newline at end of file diff --git a/client/src/components/forms/TaskForm/index.tsx b/client/src/components/forms/TaskForm/index.tsx index e8fcaf3..3e7df16 100644 --- a/client/src/components/forms/TaskForm/index.tsx +++ b/client/src/components/forms/TaskForm/index.tsx @@ -1,14 +1,15 @@ +import './task-form.scss'; +import '../form.scss'; import { Priority, Status, Task, TaskAssignment, TaskRequirement } from 'adapters/task'; import { FormEvent, useCallback, useEffect, useState } from 'react'; -import './task-form.scss'; import Callout from 'components/ui/Callout'; import TextInput from 'components/ui/TextInput'; import Picker from 'emoji-picker-react'; import { getProjectTasks, Project } from 'adapters/project'; import CheckboxGroup from 'components/ui/CheckboxGroup'; import { getTeam, getTeamMembers, getTeamRoles } from 'adapters/team'; -import RequirementsForm from './RequirementsForm'; -import AssgineesForm from './AssigneesForm'; +import RequirementsForm from 'components/forms/RequirementsForm'; +import AssgineesForm from 'components/forms/AssigneesForm'; import Button from 'components/ui/Button'; interface Props { @@ -120,71 +121,115 @@ export default function TaskForm({ task, onSubmit, project }: Props) { return ( <form className="task-form" onSubmit={handleSubmit}> {error && <Callout message={error} />} - <TextInput - label="Name" - name="name" - onChange={setName} - defaultText={name} - validation={validateName} - /> - <TextInput - label="Description" - name="text" - onChange={setText} - defaultText={text} - validation={validateText} - type="textarea" - /> - - <select defaultValue={priority} onChange={(e) => { - let currentPriority = Object.values(Priority).find(s => s === e.target.value) ?? undefined; - setPriority(currentPriority); - }}> - <option value={''}>Please choose a priority</option> - { - allPriorities.map((prio) => ( - <option value={prio} key={prio}>{prio}</option> - )) - } - </select> - - { - status && ( - <select defaultValue={status} onChange={(e) => { - let currentStatus = Object.values(Status).find(s => s === e.target.value) ?? undefined; - setStatus(currentStatus); - }}> - <option value={''}>Please choose a status</option> - { - allStatus.map((status) => ( - <option value={status} key={status}>{status}</option> - )) - } - </select> - ) - } - Chosen emoji: {icon}<br /> - <Picker onEmojiClick={(e, emoji) => setIcon(emoji.emoji)} /> + <h2>General</h2> + <div className="fields-row"> + <div className="col"> + <TextInput + label="Name" + name="name" + onChange={setName} + defaultText={name} + validation={validateName} + /> + <TextInput + label="Description" + name="text" + onChange={setText} + defaultText={text} + validation={validateText} + type="textarea" + note="A brief description what to do" + /> + </div> + <div className="col"> + <strong>Icon</strong> + <div className="current-icon"> + Current icon: {icon} + </div> + <Picker disableSkinTonePicker onEmojiClick={(e, emoji) => setIcon(emoji.emoji)} /> + <div className="note"> + <span className="material-icons"> + help_outline + </span> + An icon that is shown next to the task + </div> + </div> + <div className="col"> + <div className="field"> + <label className="field-label" htmlFor="status"> + Priority + </label> + <select defaultValue={priority} onChange={(e) => { + let currentPriority = Object.values(Priority).find(s => s === e.target.value) ?? undefined; + setPriority(currentPriority); + }}> + <option value={''}>Please choose a priority</option> + { + allPriorities.map((prio) => ( + <option value={prio} key={prio}>{prio}</option> + )) + } + </select> + <div className="note"> + <span className="material-icons"> + help_outline + </span> + How important the task is + </div> + </div> + </div> + <div className="col"> + { + status && ( + <div className="field"> + <label className="field-label" htmlFor="status"> + Status + </label> + <select defaultValue={status} id="status" onChange={(e) => { + let currentStatus = Object.values(Status).find(s => s === e.target.value) ?? undefined; + setStatus(currentStatus); + }}> + <option value={''}>Please choose a status</option> + { + allStatus.map((status) => ( + <option value={status} key={status}>{status}</option> + )) + } + </select> + </div> + ) + } + </div> + </div> <h2>Dependencies</h2> + <p>Pick tasks of this project that have to be done before this one.</p> { allTasks.length > 0 ? ( <CheckboxGroup choices={allTasks ?? []} setChosen={setTasks} chosen={tasks ?? []} /> - ) : <div>No other tasks in this project</div> - } - { - allRoles.length > 0 && ( - <RequirementsForm setRequirements={setRequirements} roles={allRoles} requirements={requirements} /> - ) - } - { - allMembers.length > 0 && ( - <AssgineesForm members={allMembers} setAssignees={setAssignees} assignees={assignees} /> - ) + ) : <div className="error">No other tasks in this project</div> } - <Button type="submit"> - Create Task - </Button> + <div className="fields-row"> + <div className="col"> + { + allRoles.length > 0 && ( + <RequirementsForm setRequirements={setRequirements} roles={allRoles} requirements={requirements} /> + ) + } + </div> + <div className="col"> + { + allMembers.length > 0 && ( + <AssgineesForm members={allMembers} setAssignees={setAssignees} assignees={assignees} /> + ) + } + </div> + </div> + <div className="button-container"> + <Button type="submit" className="expanded"> + Create Task + </Button> + </div> </form> ) diff --git a/client/src/components/forms/TaskForm/task-form.scss b/client/src/components/forms/TaskForm/task-form.scss index e69de29..499c072 100644 --- a/client/src/components/forms/TaskForm/task-form.scss +++ b/client/src/components/forms/TaskForm/task-form.scss @@ -0,0 +1,17 @@ +.task-form { + .emoji-picker-react { + width: 100%; + height: 340px; + border-radius: 15px; + } + .current-icon { + font-size: 18px; + font-weight: bold; + margin-top: 5px; + margin-bottom: 10px; + } + .error { + margin-top: 10px; + font-style: italic; + } +} \ No newline at end of file diff --git a/client/src/components/forms/form.scss b/client/src/components/forms/form.scss new file mode 100644 index 0000000..367829b --- /dev/null +++ b/client/src/components/forms/form.scss @@ -0,0 +1,95 @@ +@use 'styles/settings.scss'as s; +@use 'styles/mixins.scss'as mx; + +form { + .fields-row { + @include mx.breakpoint(large) { + display: flex; + flex-wrap: wrap; + margin: -15px; + } + + .col { + + @include mx.breakpoint(large) { + margin: -20px 0; + width: 50%; + padding: 15px; + } + + .input-element, + .field { + margin: 20px 0; + } + } + + + } + + .field { + position: relative; + } + + .note { + margin-top: 5px; + font-size: 12px; + display: flex; + align-items: center; + + span { + margin-right: 5px; + font-size: 12px; + } + } + + + .field-label { + font-size: 16px; + position: absolute; + left: 20px; + font-weight: s.$weight-bold; + z-index: 20; + transform: translateY(-50%); + } + + .time-field { + margin: 20px 0; + display: flex; + align-items: baseline; + + &:after { + content: 'min'; + margin-left: 10px; + } + } + + select, + input { + width: 100%; + font-size: 16px; + border: none; + padding: 20px; + outline: none; + border-radius: 15px; + position: relative; + display: block; + border-radius: 15px; + color: s.$body-color; + font-weight: s.$weight-regular; + font-family: s.$body-font; + background: rgba(0, 0, 0, 0.025); + } + + h2 { + margin: 30px 0 20px 0; + + @include mx.breakpoint(large) { + margin-top: 50px; + } + } + + .button-container { + margin-top: 30px; + } + +} \ No newline at end of file diff --git a/client/src/components/layout/TaskList/task-list.scss b/client/src/components/layout/TaskList/task-list.scss index f1d7c6a..fd61daa 100644 --- a/client/src/components/layout/TaskList/task-list.scss +++ b/client/src/components/layout/TaskList/task-list.scss @@ -11,6 +11,7 @@ align-items: center; background: s.$white; font-weight: s.$weight-semi-bold; + color: s.$body-color; font-size: 36px; border-radius: 15px; diff --git a/client/src/components/ui/CheckboxGroup/checkbox-group.scss b/client/src/components/ui/CheckboxGroup/checkbox-group.scss new file mode 100644 index 0000000..a06e8ab --- /dev/null +++ b/client/src/components/ui/CheckboxGroup/checkbox-group.scss @@ -0,0 +1,60 @@ +@use 'styles/settings.scss'as s; +@use 'styles/mixins.scss' as mx; + +.checkbox-group { + margin: 10px -10px; + display: flex; + flex-wrap: wrap; + .checkbox-item { + margin: 2px 0; + display: flex; + align-items: center; + cursor: pointer; + padding: 0 10px; + width: 100%; + @include mx.breakpoint(medium) { + width: 50%; + } + @include mx.breakpoint(large) { + width: 33.33333%; + } + + input { + display: none; + + &:checked { + &~.checkbox { + background: s.$primary; + + &:before { + opacity: 1; + + } + } + } + } + + .checkbox { + display: inline-block; + height: 16px; + border-radius: 5px; + width: 16px; + margin-right: 5px; + position: relative; + border: 2px solid s.$primary; + + &:before { + transition: 300ms ease; + font-size: 12px; + content: 'check'; + color: s.$white; + position: absolute; + top: 50%; + opacity: 0; + left: 50%; + transform: translate(-50%, -50%); + font-family: 'Material Icons'; + } + } + } +} \ No newline at end of file diff --git a/client/src/components/ui/CheckboxGroup/index.tsx b/client/src/components/ui/CheckboxGroup/index.tsx index 47a9cf9..1e98d01 100644 --- a/client/src/components/ui/CheckboxGroup/index.tsx +++ b/client/src/components/ui/CheckboxGroup/index.tsx @@ -1,3 +1,4 @@ +import './checkbox-group.scss'; interface Props { choices: { id: string; @@ -7,12 +8,13 @@ interface Props { setChosen: Function } + export default function CheckboxGroup({ choices, chosen, setChosen }: Props) { return ( <div className="checkbox-group"> { choices.map((choice) => ( - <div className="team-item" key={choice.id}> + <label htmlFor={choice.id} className="checkbox-item" key={choice.id}> <input type="checkbox" id={choice.id} checked={chosen.indexOf(choice.id) >= 0} onChange={(e) => { @@ -22,8 +24,10 @@ export default function CheckboxGroup({ choices, chosen, setChosen }: Props) { setChosen((state: any) => [...state, choice.id]); } }} /> - <label htmlFor={choice.id}>{choice.name}</label> - </div> + <span className="checkbox"> + </span> + {choice.name} + </label> )) } diff --git a/client/src/components/ui/TextInput/index.tsx b/client/src/components/ui/TextInput/index.tsx index 0b2da1e..26e2f74 100644 --- a/client/src/components/ui/TextInput/index.tsx +++ b/client/src/components/ui/TextInput/index.tsx @@ -10,9 +10,10 @@ interface Props { compareValue?: string; onChange: (state: any) => void; validation?: ((text: string) => Promise<string | null> | string | null) | ((value1: string, value2: string) => Promise<string | null> | string | null); + note?: string; } -export default function TextInput({ label, name, type, onChange, validation, compareValue, defaultText }: Props) { +export default function TextInput({ label, name, type, onChange, validation, compareValue, defaultText, note }: Props) { const [error, setError] = useState(''); const handleChange = useCallback((e: ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => { @@ -35,6 +36,12 @@ export default function TextInput({ label, name, type, onChange, validation, com } </div > {error && (<div className="error">{error}</div>)} + {note && (<div className="note"> + <span className="material-icons"> + help_outline + </span> + {note} + </div>)} </div> ); } diff --git a/client/src/components/ui/TextInput/text-input.scss b/client/src/components/ui/TextInput/text-input.scss index 1c080ee..9f2f53d 100644 --- a/client/src/components/ui/TextInput/text-input.scss +++ b/client/src/components/ui/TextInput/text-input.scss @@ -54,4 +54,14 @@ background: rgba(0, 0, 0, 0.025); } } + .note { + margin-top: 5px; + font-size: 12px; + display: flex; + align-items: center; + span { + margin-right: 5px; + font-size: 12px; + } + } } \ No newline at end of file diff --git a/client/src/pages/Tasks/TaskCreate/index.tsx b/client/src/pages/Tasks/TaskCreate/index.tsx index 6386766..4180169 100644 --- a/client/src/pages/Tasks/TaskCreate/index.tsx +++ b/client/src/pages/Tasks/TaskCreate/index.tsx @@ -4,6 +4,7 @@ import { useCallback, useEffect, useState } from "react"; import { createTask, Priority, TaskAssignment, TaskRequirement } from "adapters/task"; import Callout from "components/ui/Callout"; import { getProject, Project } from "adapters/project"; +import LoadingScreen from "components/ui/LoadingScreen"; interface Params { projectId: string; @@ -21,25 +22,31 @@ export default function TaskCreate() { const handleSubmit = useCallback(async (name: string, text: string, icon: string, priority: Priority, dependencies: string[], requirements: TaskRequirement[], assignees: TaskAssignment[]) => { try { - if (await createTask({ project: projectId, name, text, icon, priority, dependencies, requirements, assigned: assignees })) { - history.push('/projects/' + projectId); + if (await createTask({ project: projectId, name, text, icon, priority, dependencies, requirements, assigned: assignees })) { + history.push('/projects/' + projectId); } else { - setError('There was an error with creating your project. Please try again!'); + setError('There was an error with creating your project. Please try again!'); } } catch (e) { } }, [history, projectId]); - return ( - <div className="task-create-page"> - <div className="content-container"> - <h1>Create a new Task</h1> - {error && <Callout message={error} />} - { - project && - <TaskForm onSubmit={handleSubmit} project={project} /> - } + if (project) { + return ( + <div className="task-create-page"> + <div className="content-container"> + <h1>Create a new task</h1> + {error && <Callout message={error} />} + <p> + Create a new task in <strong>{project.name}</strong> + </p> + { + project && + <TaskForm onSubmit={handleSubmit} project={project} /> + } + </div> </div> - </div> - ) + ) + } + return <LoadingScreen /> } \ No newline at end of file diff --git a/client/src/styles/settings.scss b/client/src/styles/settings.scss index fdeabf6..4d3ef73 100644 --- a/client/src/styles/settings.scss +++ b/client/src/styles/settings.scss @@ -8,6 +8,7 @@ $light: #F9F9F9; $dark: #11061A; $light-gray: #F8F8F8; +$gray: #F9F9F9; $white: #fff; $black: #000; -- GitLab