Skip to content
Snippets Groups Projects
Commit b13887f8 authored by Planoetscher Daniel (Student Com20)'s avatar Planoetscher Daniel (Student Com20)
Browse files

bugfixes and design updates

parent cc84fb26
No related branches found
No related tags found
No related merge requests found
......@@ -2,6 +2,7 @@ import { deleteTeamRole, Team, TeamMember, TeamRole, updateTeamMember } from 'ad
import { FormEvent, useCallback, useState } from 'react';
import Button from 'components/ui/Button';
import { useHistory } from 'react-router';
import Callout from 'components/ui/Callout';
interface Props {
roles: TeamRole[];
......@@ -14,6 +15,7 @@ interface Props {
export default function RoleForm({ roles, setEdit, member, team, setResult, setAllRoles }: Props) {
const [currentRole, setRole] = useState(member?.role.id);
const [error, setError] = useState('');
const history = useHistory();
const onSubmit = useCallback(async (e: FormEvent) => {
e.preventDefault();
......@@ -29,16 +31,24 @@ export default function RoleForm({ roles, setEdit, member, team, setResult, setA
}, [currentRole, member, team, setResult, history]);
const onDelete = useCallback(async (id: string) => {
await deleteTeamRole(team.id, id);
setAllRoles((state: any) => state.filter((role: any) => role.id !== id));
try {
await deleteTeamRole(team.id, id);
setAllRoles((state: any) => state.filter((role: any) => role.id !== id));
} catch {
setError('There are still users assigned to this role.')
}
}, [team, setAllRoles]);
return (
<form className="role-change-form" onSubmit={onSubmit}>
<h2>Set the role</h2>
{
error && <Callout message={error} />
}
{
roles.map((role) => (
<div className="role-item" key={role.id}>
<label className="role-item" key={role.id} htmlFor={role.id}>{role.name}
<input
type="radio"
name={role.id}
......@@ -46,15 +56,25 @@ export default function RoleForm({ roles, setEdit, member, team, setResult, setA
onChange={() => setRole(role.id)}
checked={currentRole === role.id}
/>
<label htmlFor={role.id}>{role.name}</label>
<div onClick={() => setEdit(role)}>edit</div>
<div onClick={() => onDelete(role.id)}>delete</div>
</div>
<div className="radio-btn"></div>
<div className="actions">
<div className="action" onClick={() => setEdit(role)}>
<span className="material-icons">
edit
</span>
</div>
<div className="action delete" onClick={() => onDelete(role.id)}>
<span className="material-icons">
clear
</span>
</div>
</div>
</label>
))}
<div className="add-btn role-item" onClick={() => setEdit({})}>
+
</div>
<Button type="submit">
<Button type="submit" className="expanded">
Save
</Button>
</form >
......
import { createTeamRole, Team, TeamRole } from 'adapters/team';
import { createTeamRole, Team, TeamRole, updateTeamRole } from 'adapters/team';
import TextInput from 'components/ui/TextInput';
import Button from 'components/ui/Button';
import { FormEvent, useCallback, useState } from 'react';
......@@ -25,11 +25,22 @@ export default function RoleEditForm({ role, team, setEdit, setAllRoles }: Props
e.preventDefault();
if (validateName(name) === null) {
if (!role?.id) {
const role = await createTeamRole(team.id, name);
setAllRoles((state: any) => [...state, role]);
const newRole = await createTeamRole(team.id, name);
setAllRoles((state: any) => [...state, newRole]);
setEdit(null);
} else {
//todo edit team role
if(updateTeamRole(team.id, role.id, name)) {
setAllRoles((state: any) => {
state = state.filter((r: any) => r.id !== role.id);
return [
...state,
{
...role,
name: name
}
]
});
}
setEdit(null);
}
}
......@@ -45,9 +56,12 @@ export default function RoleEditForm({ role, team, setEdit, setAllRoles }: Props
onChange={setName}
validation={validateName}
/>
<Button >
<Button className="expanded">
{!role?.id ? 'Create' : 'Update'}
</Button>
<Button className="expanded dark" onClick={() => setEdit(null)}>
Back
</Button>
</form>
)
}
@use 'styles/settings.scss' as s;
@use 'styles/settings.scss'as s;
.role-change-form {
display: flex;
flex-direction: column;
.role-item {
padding: 25px;
background: s.$light;
border-radius: 25px;
font-size: 18px;
margin: 10px 0;
label {
margin-left: 10px;
width: 100%;
margin: 8px 0;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
display: block;
position: relative;
padding: 25px 50px;
width: 400px;
input {
padding: 25px;
display: block;
display: none;
&:checked {
& ~ .radio-btn {
&:before {
opacity: 1;
}
}
}
}
.actions {
display: flex;
position: absolute;
top: 0;
right: 0;
transform: translate(18px, -18px);
}
.action {
width: 36px;
height: 36px;
border-radius: 50%;
background: s.$primary;
color: s.$white;
display: flex;
justify-content: center;
align-items: center;
margin: 0 2px;
span {
font-size: 18px;
}
&.delete {
background-color: s.$red;
}
}
.radio-btn {
height: 20px;
width: 20px;
background: s.$primary;
border-radius: 50%;
position: absolute;
left: 20px;
top: 50%;
transform: translateY(-50%);
&:before {
content: ' ';
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 10px;
height: 10px;
background: s.$white;
border-radius: 50%;
opacity: 0;
transition: 300ms ease;
}
}
}
.add-btn {
height: 77px;
display: flex;
justify-content: center;
align-items: center;
font-size: 28px;
}
button {
margin-bottom: 0;
}
}
.role-edit-form {
h2 {
margin-bottom: 40px;
}
.button {
margin-bottom: 0;
margin-top: 10px;
}
.input-element {
margin-bottom: 20px;
}
}
\ No newline at end of file
......@@ -66,7 +66,7 @@ export default function TaskForm({ task, onSubmit, project }: Props) {
const [status, setStatus] = useState(task?.status);
const [error, setError] = useState('');
const [tasks, setTasks] = useState(task?.dependencies ?? []);
const [requirements, setRequirements] = useState(task?.requirements ?? []);
const [assignees, setAssignees] = useState(task?.assigned ?? []);
......@@ -152,7 +152,7 @@ export default function TaskForm({ task, onSubmit, project }: Props) {
status && (
<select defaultValue={status} onChange={(e) => {
let currentStatus = Object.values(Status).find(s => s === e.target.value) ?? undefined;
setStatus(currentStatus);
setStatus(currentStatus);
}}>
<option value={''}>Please choose a status</option>
{
......@@ -163,8 +163,9 @@ export default function TaskForm({ task, onSubmit, project }: Props) {
</select>
)
}
Chosen emoji: {icon}<br />
<Picker onEmojiClick={(e, emoji) => setIcon(emoji.emoji)} />
<Picker onEmojiClick={(e, emoji) => setIcon(emoji.originalUnified)} />
<h2>Dependencies</h2>
{
allTasks.length > 0 ? (
......
......@@ -44,6 +44,10 @@
box-shadow: 0 0 5px rgba(s.$black, 0.05);
visibility: hidden;
opacity: 0;
&.right {
right: 0;
left: auto;
}
.dropdown-item {
......
......@@ -6,15 +6,16 @@ import './dropdown.scss';
export interface DropDownItem {
label: string;
route?: string;
popupContent?: ReactNode
popupContent?: ReactNode;
}
interface Props {
children: ReactNode;
items: DropDownItem[]
position?: 'left'|'right';
}
export default function Dropdown({ children, items }: Props) {
export default function Dropdown({ children, items, position }: Props) {
const [isOpen, setOpen] = useState(false);
const [openPopup, setOpenPopup] = useState<string | null>(null);
return (
......@@ -24,7 +25,7 @@ export default function Dropdown({ children, items }: Props) {
{children}
</div>
{items.length > 0 && (
<div className="dropdown">
<div className={'dropdown ' + (position ?? '')}>
{
items.map((item) =>
(item.route && (
......
......@@ -12,9 +12,10 @@
align-items: center;
.popup {
animation: moveup 300ms ease;
max-height: 100vh;
overflow: auto;
padding: 50px;
padding: 75px 100px;
max-width: 960px;
background: s.$white;
border-radius: 25px;
......@@ -26,6 +27,29 @@
position: absolute;
width: 100%;
height: 100%;
background: rgba(s.$black, 0.75);
animation: appear 300ms ease;
background: rgba(s.$black, 0.5);
}
}
@keyframes moveup {
from {
transform: translateY(50px);
opacity: 0.5;
}
to {
transform: translateY(0);
opacity: 1;
}
}
@keyframes appear {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
\ No newline at end of file
......@@ -25,7 +25,7 @@ export default function Task({ task, color, subtitle }: TaskProps) {
<div className={'indicator' + (color ? ' bg-gradient-' + color : '')}></div>
<div className="main-info">
<div className="icon-container">
{String.fromCharCode(parseInt(task.icon, 16))}
{task.icon}
</div>
<div className="text-container">
<h4>{task.name}</h4>
......
......@@ -19,7 +19,7 @@ export default function TeamMember({ user, info, settings }: TeamMemberProps) {
</div>
{
settings &&
<Dropdown items={settings}>
<Dropdown items={settings} position="right">
<div className="settings">
<span className="material-icons icon">
expand_more
......
......@@ -13,7 +13,6 @@
.input-field {
position: relative;
padding: 0 5px;
width: 100%;
&.mandatory {
label {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment