todo list

This commit is contained in:
1ilit 2023-09-19 15:50:53 +03:00
parent 7426012154
commit aec4d826b5
4 changed files with 306 additions and 45 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -6,10 +6,7 @@ import timeLine from "../assets/process.png";
import todo from "../assets/calendar.png"; import todo from "../assets/calendar.png";
import { Tooltip, SideSheet } from "@douyinfe/semi-ui"; import { Tooltip, SideSheet } from "@douyinfe/semi-ui";
import { UndoRedoContext } from "../pages/editor"; import { UndoRedoContext } from "../pages/editor";
// import { import Todo from "./todo";
// IllustrationNoContent,
// IllustrationNoContentDark,
// } from "@douyinfe/semi-illustrations";
export default function Sidebar() { export default function Sidebar() {
const SidesheetType = { const SidesheetType = {
@ -20,8 +17,8 @@ export default function Sidebar() {
TIMELINE: 4, TIMELINE: 4,
BOT: 5, BOT: 5,
}; };
const [sidesheet, setSidesheet] = useState(SidesheetType.NONE);
const { undoStack } = useContext(UndoRedoContext); const { undoStack } = useContext(UndoRedoContext);
const [sidesheet, setSidesheet] = useState(SidesheetType.NONE);
const getTitle = (type) => { const getTitle = (type) => {
switch (type) { switch (type) {
@ -39,11 +36,11 @@ export default function Sidebar() {
<div className="ms-3">Chat</div> <div className="ms-3">Chat</div>
</div> </div>
); );
case SidesheetType.TEAM: case SidesheetType.TODO:
return ( return (
<div className="flex items-center"> <div className="flex items-center">
<img src={teamIcon} className="w-7" alt="chat icon" /> <img src={todo} className="w-7" alt="todo icon" />
<div className="ms-3">Your team</div> <div className="ms-3">To-do list</div>
</div> </div>
); );
default: default:
@ -54,7 +51,9 @@ export default function Sidebar() {
const getContent = (type) => { const getContent = (type) => {
switch (type) { switch (type) {
case SidesheetType.TIMELINE: case SidesheetType.TIMELINE:
return getTimeline(); return renderTimeline();
case SidesheetType.TODO:
return <Todo />;
default: default:
break; break;
} }
@ -77,8 +76,11 @@ export default function Sidebar() {
</button> </button>
</Tooltip> </Tooltip>
<Tooltip content="To-do"> <Tooltip content="To-do">
<button className="block"> <button
<img src={todo} className="w-8 mb-5" alt="chat icon" /> className="block"
onClick={() => setSidesheet(SidesheetType.TODO)}
>
<img src={todo} className="w-8 mb-5" alt="todo icon" />
</button> </button>
</Tooltip> </Tooltip>
<Tooltip content="Timeline"> <Tooltip content="Timeline">
@ -97,20 +99,23 @@ export default function Sidebar() {
</div> </div>
<SideSheet <SideSheet
visible={sidesheet !== SidesheetType.NONE} visible={sidesheet !== SidesheetType.NONE}
onCancel={() => setSidesheet(SidesheetType.NONE)} onCancel={() => {
setSidesheet(SidesheetType.NONE);
}}
width={340} width={340}
title={getTitle(sidesheet)} title={getTitle(sidesheet)}
style={{ paddingBottom: "16px" }} style={{ paddingBottom: "16px" }}
bodyStyle={{ padding: "0px" }}
> >
{getContent(sidesheet)} {getContent(sidesheet)}
</SideSheet> </SideSheet>
</> </>
); );
function getTimeline() { function renderTimeline() {
if (undoStack.length > 0) { if (undoStack.length > 0) {
return ( return (
<div> <div className="m-5">
<hr /> <hr />
{[...undoStack].reverse().map((e) => ( {[...undoStack].reverse().map((e) => (
<> <>
@ -125,18 +130,9 @@ export default function Sidebar() {
); );
} else { } else {
return ( return (
<div className="mt-4"> <div className="m-5">
You havent added anything to your diagram yet. You havent added anything to your diagram yet.
</div> </div>
// <Empty
// className="mt-5"
// image={<IllustrationNoContent style={{ width: 160, height: 160 }} />}
// darkModeImage={
// <IllustrationNoContentDark style={{ width: 160, height: 160 }} />
// }
// title="No activity"
// description="You have not added anything to your diagram yet."
// />
); );
} }
} }

254
src/components/todo.jsx Normal file
View File

@ -0,0 +1,254 @@
import React, { useContext, useState } from "react";
import {
Checkbox,
Input,
TextArea,
Row,
Col,
Dropdown,
Button,
Popover,
Tag,
List,
RadioGroup,
Radio,
} from "@douyinfe/semi-ui";
import {
IconPlus,
IconMore,
IconDeleteStroked,
IconCaretdown,
} from "@douyinfe/semi-icons";
import { TaskContext } from "../pages/editor";
export default function Todo() {
const Priority = {
NONE: 0,
LOW: 1,
MEDIUM: 2,
HIGH: 3,
};
const SortOrder = {
ORIGINAL: "My order",
PRIORITY: "Priority",
COMPLETED: "Completed",
ALPHABETICALLY: "Alphabetically",
};
const [activeTask, setActiveTask] = useState(-1);
const [, setSortOrder] = useState(SortOrder.ORIGINAL);
const { tasks, setTasks, updateTask } = useContext(TaskContext);
const priorityLabel = (p) => {
switch (p) {
case Priority.NONE:
return "None";
case Priority.LOW:
return "Low";
case Priority.MEDIUM:
return "Medium";
case Priority.HIGH:
return "High";
default:
return "";
}
};
const priorityColor = (p) => {
switch (p) {
case Priority.NONE:
return "blue";
case Priority.LOW:
return "green";
case Priority.MEDIUM:
return "yellow";
case Priority.HIGH:
return "red";
default:
return "";
}
};
const sort = (s) => {
switch (s) {
case SortOrder.ORIGINAL:
setTasks((prev) => prev.sort((a, b) => a.order - b.order));
return;
case SortOrder.PRIORITY:
setTasks((prev) => prev.sort((a, b) => b.priority - a.priority));
return;
case SortOrder.COMPLETED:
setTasks((prev) =>
prev.sort((a, b) => {
if (a.complete && !b.complete) {
return 1;
} else if (!a.complete && b.complete) {
return -1;
} else {
return 0;
}
})
);
break;
case SortOrder.ALPHABETICALLY:
setTasks((prev) => prev.sort((a, b) => a.title.localeCompare(b.title)));
break;
default:
break;
}
};
return (
<>
<div className="flex justify-between items-center mx-5 mb-2">
<Dropdown
render={
<Dropdown.Menu>
{Object.values(SortOrder).map((order) => (
<Dropdown.Item
onClick={() => {
setSortOrder(order);
sort(order);
}}
>
{order}
</Dropdown.Item>
))}
</Dropdown.Menu>
}
trigger="click"
>
<Button
style={{ marginRight: "10px" }}
theme="borderless"
type="tertiary"
>
Sort by <IconCaretdown />
</Button>
</Dropdown>
<Button
icon={<IconPlus />}
block
onClick={() => {
setTasks((prev) => [
{
complete: false,
details: "",
title: "",
priority: Priority.NONE,
order: prev.length,
},
...prev,
]);
}}
>
Add task
</Button>
</div>
<List>
{tasks.map((t, i) => (
<List.Item
key={i}
style={{ paddingLeft: "18px", paddingRight: "18px" }}
className={`${t.complete ? "bg-emerald-50" : "hover:bg-slate-100"}`}
onClick={() => setActiveTask(i)}
>
<div className="w-full">
<Row gutter={6} align="middle" type="flex" className="mb-2">
<Col span={2}>
<Checkbox
checked={t.complete}
onChange={(e) =>
updateTask(i, { complete: e.target.checked })
}
></Checkbox>
</Col>
<Col span={19}>
<Input
placeholder="Title"
onChange={(v) => updateTask(i, { title: v })}
value={t.title}
></Input>
</Col>
<Col span={3}>
<Popover
content={
<div className="p-2">
<div className="mb-2 font-semibold">Set priority: </div>
<RadioGroup
onChange={(e) =>
updateTask(i, { priority: e.target.value })
}
value={t.priority}
direction="vertical"
>
<Radio value={Priority.NONE}>
<Tag color={priorityColor(Priority.NONE)}>
{priorityLabel(Priority.NONE)}
</Tag>
</Radio>
<Radio value={Priority.LOW}>
<Tag color={priorityColor(Priority.LOW)}>
{priorityLabel(Priority.LOW)}
</Tag>
</Radio>
<Radio value={Priority.MEDIUM}>
<Tag color={priorityColor(Priority.MEDIUM)}>
{priorityLabel(Priority.MEDIUM)}
</Tag>
</Radio>
<Radio value={Priority.HIGH}>
<Tag color={priorityColor(Priority.HIGH)}>
{priorityLabel(Priority.HIGH)}
</Tag>
</Radio>
</RadioGroup>
<Button
icon={<IconDeleteStroked />}
type="danger"
block
style={{ marginTop: "12px" }}
onClick={() =>
setTasks((prev) =>
prev.filter((task, j) => i !== j)
)
}
>
Delete
</Button>
</div>
}
trigger="click"
showArrow
className="w-[180px]"
>
<Button icon={<IconMore />} type="tertiary"></Button>
</Popover>
</Col>
</Row>
{activeTask === i && (
<Row className="mb-2">
<Col span={2}></Col>
<Col span={22}>
<TextArea
placeholder="Details"
onChange={(v) => updateTask(i, { details: v })}
value={t.details}
></TextArea>
</Col>
</Row>
)}
<Row>
<Col span={2}></Col>
<Col span={22}>
Priority:{" "}
<Tag color={priorityColor(t.priority)}>
{priorityLabel(t.priority)}
</Tag>
</Col>
</Row>
</div>
</List.Item>
))}
</List>
</>
);
}

View File

@ -19,6 +19,7 @@ export const NoteContext = createContext();
export const SettingsContext = createContext(); export const SettingsContext = createContext();
export const UndoRedoContext = createContext(); export const UndoRedoContext = createContext();
export const SelectContext = createContext(); export const SelectContext = createContext();
export const TaskContext = createContext();
export default function Editor(props) { export default function Editor(props) {
const [tables, setTables] = useState([]); const [tables, setTables] = useState([]);
@ -47,6 +48,7 @@ export default function Editor(props) {
pan: { x: 0, y: 0 }, pan: { x: 0, y: 0 },
showGrid: true, showGrid: true,
}); });
const [tasks, setTasks] = useState([]);
const [undoStack, setUndoStack] = useState([]); const [undoStack, setUndoStack] = useState([]);
const [redoStack, setRedoStack] = useState([]); const [redoStack, setRedoStack] = useState([]);
const [selectedElement, setSelectedElement] = useState({ const [selectedElement, setSelectedElement] = useState({
@ -386,6 +388,11 @@ export default function Editor(props) {
); );
}; };
const updateTask = (id, values) =>
setTasks((prev) =>
prev.map((task, i) => (id === i ? { ...task, ...values } : task))
);
useEffect(() => { useEffect(() => {
document.title = "Editor - drawDB"; document.title = "Editor - drawDB";
}, []); }, []);
@ -420,28 +427,32 @@ export default function Editor(props) {
<SelectContext.Provider <SelectContext.Provider
value={{ selectedElement, setSelectedElement }} value={{ selectedElement, setSelectedElement }}
> >
<div className="h-[100vh] overflow-hidden"> <TaskContext.Provider
<ControlPanel /> value={{ tasks, setTasks, updateTask }}
<div >
className={ <div className="h-[100vh] overflow-hidden">
layout.header <ControlPanel />
? `flex h-[calc(100vh-120px)]` <div
: `flex h-[calc(100vh-52px)]` className={
} layout.header
onMouseUp={() => setResize(false)} ? `flex h-[calc(100vh-120px)]`
onMouseMove={dragHandler} : `flex h-[calc(100vh-52px)]`
> }
{layout.sidebar && ( onMouseUp={() => setResize(false)}
<EditorPanel onMouseMove={dragHandler}
resize={resize} >
setResize={setResize} {layout.sidebar && (
width={width} <EditorPanel
/> resize={resize}
)} setResize={setResize}
<Canvas /> width={width}
{layout.services && <Sidebar />} />
)}
<Canvas />
{layout.services && <Sidebar />}
</div>
</div> </div>
</div> </TaskContext.Provider>
</SelectContext.Provider> </SelectContext.Provider>
</UndoRedoContext.Provider> </UndoRedoContext.Provider>
</SettingsContext.Provider> </SettingsContext.Provider>