Compare commits

...
3 Commits
Author SHA1 Message Date
Maya Herrscher 38a86fb528 Refactor Subtodos so they work correctly 2022-09-28 13:12:36 +02:00
Maya Herrscher 502706eeee Schedule display 2022-09-27 14:22:11 +02:00
Maya Herrscher 4342ff3a41 Filter ToDos (done/undone) 2022-09-27 13:10:42 +02:00
6 changed files with 2774 additions and 2062 deletions

No files matched your search

+2680 -2033
View File
File diff suppressed because it is too large. Load diff
+2 -1
View File
@@ -7,6 +7,7 @@
"@emotion/react": "^11.9.0", "@emotion/react": "^11.9.0",
"@emotion/styled": "^11.8.1", "@emotion/styled": "^11.8.1",
"@mui/icons-material": "^5.6.2", "@mui/icons-material": "^5.6.2",
"@mui/lab": "^5.0.0-alpha.87",
"@mui/material": "^5.6.2", "@mui/material": "^5.6.2",
"@mui/x-date-pickers": "^5.0.0-alpha.1", "@mui/x-date-pickers": "^5.0.0-alpha.1",
"@testing-library/jest-dom": "^5.16.4", "@testing-library/jest-dom": "^5.16.4",
@@ -20,7 +21,7 @@
"react": "^17.0.0", "react": "^17.0.0",
"react-beautiful-dnd": "^13.1.0", "react-beautiful-dnd": "^13.1.0",
"react-dom": "^17.0.0", "react-dom": "^17.0.0",
"react-scripts": "5.0.1", "react-scripts": "^5.0.1",
"typescript": "^4.6.3", "typescript": "^4.6.3",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },
+2 -1
View File
@@ -6,6 +6,7 @@ import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { Todos } from './components/Todos'; import { Todos } from './components/Todos';
import { Dinos } from './components/Dinos'; import { Dinos } from './components/Dinos';
import { Schedule } from './components/Schedule';
const theme = createTheme({ const theme = createTheme({
palette: { palette: {
@@ -33,7 +34,7 @@ function Overview(){
<Paper sx={{overflowY: "auto", width: "100%", padding: 2, height: "calc(100% - 32px)"}}><Todos/></Paper> <Paper sx={{overflowY: "auto", width: "100%", padding: 2, height: "calc(100% - 32px)"}}><Todos/></Paper>
<Box sx={{width: "100%", display: "flex", flexDirection: "column", justifyContent: "space-evenly"}}> <Box sx={{width: "100%", display: "flex", flexDirection: "column", justifyContent: "space-evenly"}}>
<Calendar/> <Calendar/>
<Calendar/> <Schedule/>
</Box> </Box>
</Box> </Box>
</div> </div>
+36
View File
@@ -0,0 +1,36 @@
import React, {useState } from 'react';
import { Box, Button, Checkbox, Dialog, DialogActions, DialogContent, DialogTitle, Divider, List, ListItem, Switch, TextField, Tooltip, Typography } from '@mui/material';
import { useLocalStorage } from '../hooks/useLocalStorage';
import { Timeline, TimelineConnector, TimelineContent, TimelineDot, TimelineItem, TimelineSeparator, TimelineOppositeContent } from '@mui/lab';
/*
definition of events
events have IDs, names, a time (usually start-time) and can be variable in timing
*/
type Eve = {
id: string,
name: string,
time: string,
var: boolean
}
export function Schedule(){
const [eve, setEve] = useState<Eve[]>([{id: "2", name: "Testtermin 1425", time: "12:00", var: true},{id: "1", name: "Testtermin", time: "12:00", var: false},{id: "3", name: "Testtermin früh", time: "8:00", var:false}])
return(
<div>
<Typography variant="h3">Schedule</Typography>
<Timeline position="alternate">
{eve.map((e ,i) =>
<TimelineItem>
{!e.var && <TimelineOppositeContent color="primary">{e.time}</TimelineOppositeContent>}
<TimelineSeparator>
<TimelineDot color="primary" />
{((i+1) < eve.length) && <TimelineConnector />}
</TimelineSeparator>
<TimelineContent>{e.name}</TimelineContent>
</TimelineItem>
)}
</Timeline>
</div>
)
}
+53 -26
View File
@@ -1,5 +1,5 @@
import React, {useState } from 'react'; import React, {useState } from 'react';
import { Box, Button, Checkbox, Dialog, DialogActions, DialogContent, DialogTitle, Divider, List, ListItem, TextField, Tooltip, Typography } from '@mui/material'; import { Box, Button, Checkbox, Dialog, DialogActions, DialogContent, DialogTitle, Divider, List, ListItem, Switch, TextField, Tooltip, Typography } from '@mui/material';
import { DatePicker } from '@mui/x-date-pickers'; import { DatePicker } from '@mui/x-date-pickers';
import DeleteOutlineRoundedIcon from '@mui/icons-material/DeleteOutlineRounded'; import DeleteOutlineRoundedIcon from '@mui/icons-material/DeleteOutlineRounded';
import EditRoundedIcon from '@mui/icons-material/EditRounded'; import EditRoundedIcon from '@mui/icons-material/EditRounded';
@@ -130,13 +130,19 @@ function ChangeTodo({todo, setTodo, handleCancel}: {todo: Todo, setTodo: (todo:
export function Todos({style}: {style?: any}) { export function Todos({style}: {style?: any}) {
const [todos, setTodos] = useLocalStorage<Todo[]>("todos",[]); const [todos, setTodos] = useLocalStorage<Todo[]>("todos",[]);
const setDone=(i: number,todo: Todo, done: boolean) => const setDone=(todo: Todo, done: boolean) => {
setTodos([...todos.slice(0,i), const i = todos.indexOf(todo);
setTodos([...todos.slice(0,i),
{name: todo.name, id: todo.id, done: done, description: todo.description, to: todo.to, from: todo.from, subs: todo.subs}, {name: todo.name, id: todo.id, done: done, description: todo.description, to: todo.to, from: todo.from, subs: todo.subs},
...todos.slice(i+1)]); ...todos.slice(i+1)]);
}
const setDoneSub=(i: number, j: number, stodo: Subtodo, done: boolean) => { const setDoneSub=(todo: Todo, stodo: Subtodo, done: boolean) => {
const todo = todos[i]; const i = todos.indexOf(todo);
let j = -1;
if (todo.subs!.length > 0){
j = todo.subs!.indexOf(stodo);
}
setTodos([...todos.slice(0,i), setTodos([...todos.slice(0,i),
{name: todo.name, id: todo.id, done: todo.done, description: todo.description, to: todo.to, from: todo.from, {name: todo.name, id: todo.id, done: todo.done, description: todo.description, to: todo.to, from: todo.from,
subs: [...todo.subs!.slice(0,j), subs: [...todo.subs!.slice(0,j),
@@ -144,16 +150,22 @@ export function Todos({style}: {style?: any}) {
, ...todo.subs!.slice(j+1)]}, , ...todo.subs!.slice(j+1)]},
...todos.slice(i+1)]);} ...todos.slice(i+1)]);}
const deleteSubtodo=(i: number, j: number) => { const deleteSubtodo=(todo: Todo, stodo: Subtodo) => {
const todo = todos[i]; const i = todos.indexOf(todo);
let j = -1;
if (todo.subs!.length > 0){
j = todo.subs!.indexOf(stodo);
}
setTodos([...todos.slice(0,i), setTodos([...todos.slice(0,i),
{name: todo.name, id: todo.id, done: todo.done, description: todo.description, to: todo.to, from: todo.from, {name: todo.name, id: todo.id, done: todo.done, description: todo.description, to: todo.to, from: todo.from,
subs: [...todo.subs!.slice(0,j), ...todo.subs!.slice(j+1)]}, subs: [...todo.subs!.slice(0,j), ...todo.subs!.slice(j+1)]},
...todos.slice(i+1)]);} ...todos.slice(i+1)]);}
const deleteTodo=(i: number) => const deleteTodo=(todo: Todo) => {
const i = todos.indexOf(todo);
setTodos([...todos.slice(0,i), setTodos([...todos.slice(0,i),
...todos.slice(i+1)]); ...todos.slice(i+1)]);
}
const setTodo= (todo: Todo) => { const setTodo= (todo: Todo) => {
handleClose(); handleClose();
@@ -171,8 +183,9 @@ const handleClose = () => {
const [open2, setOpen2] = useState(false); const [open2, setOpen2] = useState(false);
const [edit, setEdit] = useState<Todo>({name: "", description: "", done: false, id: "", subs: []}); const [edit, setEdit] = useState<Todo>({name: "", description: "", done: false, id: "", subs: []});
const [editI, setEditI] = useState<number>(0); const [editI, setEditI] = useState<number>(0);
const handleClickOpen2 = (todo: Todo, i: number) => { const handleClickOpen2 = (todo: Todo) => {
setOpen2(true); setOpen2(true);
const i = todos.indexOf(todo);
setEdit(todo); setEdit(todo);
setEditI(i); setEditI(i);
}; };
@@ -183,22 +196,28 @@ const handleClose2 = () => {
const [open3, setOpen3] = useState(false); const [open3, setOpen3] = useState(false);
const [editSub, setEditSub] = useState<Subtodo>({name: "", description: "", done: false, id: ""}); const [editSub, setEditSub] = useState<Subtodo>({name: "", description: "", done: false, id: ""});
const [editJ, setEditJ] = useState<number>(0); const [editJ, setEditJ] = useState<number>(0);
const handleClickOpenSubtodo = (todo: Subtodo, i: number, j: number) => { const handleClickOpenSubtodo = (todo: Todo) => {
setOpen3(true); setOpen3(true);
const i = todos.indexOf(todo);
setEditSub(todo); setEditSub(todo);
setEditI(i); setEditI(i);
setEditJ(j > -1 ? j : todos[i].subs!.length); setEditJ(todo.subs!.length);
}; };
const handleCloseSubtodo = () => { const handleCloseSubtodo = () => {
setOpen3(false); setOpen3(false);
}; };
const [open4, setOpen4] = useState(false); const [open4, setOpen4] = useState(false);
const handleClickOpenSubtodo2 = (todo: Subtodo, i: number, j: number) => { const handleClickOpenSubtodo2 = (todo: Todo, stodo: Subtodo) => {
setOpen4(true); setOpen4(true);
setEditSub(todo); const i = todos.indexOf(todo);
let j = -1;
if (todo.subs!.length > 0){
j = todo.subs!.indexOf(stodo);
}
setEditSub(stodo);
setEditI(i); setEditI(i);
setEditJ(j > -1 ? j : todos[i].subs!.length); setEditJ(j);
}; };
const handleCloseSubtodo2 = () => { const handleCloseSubtodo2 = () => {
setOpen4(false); setOpen4(false);
@@ -228,46 +247,54 @@ const editSubtodo= (todo: Subtodo) => {
...todos.slice(editI+1)]); ...todos.slice(editI+1)]);
} }
const [showChecked, setShowChecked] = useState(false);
const handleShowChecked = (event: React.ChangeEvent<HTMLInputElement>) => {
setShowChecked(event.target.checked);
};
return ( return (
<div style={{...style, textAlign: "left"}}> <div style={{...style, textAlign: "left"}}>
<Typography variant="h3">ToDo's</Typography> <Typography variant="h3">ToDo's</Typography>
<Button onClick={handleClickOpen}>Add Todo</Button> <Button onClick={handleClickOpen}>Add Todo</Button>
{/* This should be done with a FormControlLabel or sth...*/}
Show Done
<Switch checked={showChecked} onChange={handleShowChecked}/>
<List> <List>
{todos.map((todo, i) => {todos.filter((td) => !td.done || showChecked).map((todo, i) =>
<div key={todo.id}> <div key={todo.id}>
<Box sx={{display: "flex", flexDirection: "columns"}}> <Box sx={{display: "flex", flexDirection: "columns"}}>
<TodoItem key={todo.id} todo={todo}/> <TodoItem key={todo.id} todo={todo}/>
<Checkbox checked={todo.done} onChange={(e) => setDone(i, todo,e.target.checked)}></Checkbox> <Checkbox checked={todo.done} onChange={(e) => setDone(todo,e.target.checked)}></Checkbox>
<Tooltip title="Add Subtodo"> <Tooltip title="Add Subtodo">
<Button onClick={() => handleClickOpenSubtodo(todo, i,-1)}><AddTaskRoundedIcon/></Button> <Button onClick={() => handleClickOpenSubtodo(todo)}><AddTaskRoundedIcon/></Button>
</Tooltip> </Tooltip>
<Tooltip title="Edit Todo"> <Tooltip title="Edit Todo">
<Button onClick={() => handleClickOpen2(todo, i)}><EditRoundedIcon/></Button> <Button onClick={() => handleClickOpen2(todo)}><EditRoundedIcon/></Button>
</Tooltip> </Tooltip>
<Tooltip title="Delete Todo"> <Tooltip title="Delete Todo">
<Button onClick={() => deleteTodo(i)}><DeleteOutlineRoundedIcon/></Button> <Button onClick={() => deleteTodo(todo)}><DeleteOutlineRoundedIcon/></Button>
</Tooltip> </Tooltip>
</Box> </Box>
{(todo.subs && todo.subs.length > 0) && {(todo.subs && todo.subs.filter((td) => !td.done || showChecked).length > 0) &&
<List sx={{marginLeft: "20px"}}> <List sx={{marginLeft: "20px"}}>
<Divider/> <Divider/>
{todo.subs.map((stodo, j) => {todo.subs.filter((td) => !td.done || showChecked).map((stodo, j) =>
<div key={stodo.id}> <div key={stodo.id}>
<Box sx={{display: "flex", flexDirection: "columns"}}> <Box sx={{display: "flex", flexDirection: "columns"}}>
<TodoItem key={todo.id} todo={stodo}/> <TodoItem key={todo.id} todo={stodo}/>
<Checkbox checked={stodo.done} onChange={(e) => setDoneSub(i, j, stodo,e.target.checked)}></Checkbox> <Checkbox checked={stodo.done} onChange={(e) => setDoneSub(todo, stodo,e.target.checked)}></Checkbox>
<Tooltip title="Edit Subtodo"> <Tooltip title="Edit Subtodo">
<Button onClick={() => handleClickOpenSubtodo2(stodo, i, j)}><EditRoundedIcon/></Button> <Button onClick={() => handleClickOpenSubtodo2(todo, stodo)}><EditRoundedIcon/></Button>
</Tooltip> </Tooltip>
<Tooltip title="Delete Subtodo"> <Tooltip title="Delete Subtodo">
<Button onClick={() => deleteSubtodo(i,j)}><DeleteOutlineRoundedIcon/></Button> <Button onClick={() => deleteSubtodo(todo, stodo)}><DeleteOutlineRoundedIcon/></Button>
</Tooltip> </Tooltip>
</Box> </Box>
{(j + 1) < todo.subs!.length && <Divider/>} {(j + 1) < todo.subs!.filter((td) => !td.done || showChecked).length && <Divider/>}
</div> </div>
)} )}
</List>} </List>}
{(i + 1) < todos.length && <Divider/>} {(i + 1) < todos.filter((td) => !td.done || showChecked).length && <Divider/>}
</div> </div>
)} )}
</List> </List>
+1 -1
View File
@@ -18,7 +18,7 @@
"resolveJsonModule": true, "resolveJsonModule": true,
"isolatedModules": true, "isolatedModules": true,
"noEmit": true, "noEmit": true,
"jsx": "react-jsx" "jsx": "preserve"
}, },
"include": [ "include": [
"src" "src"