Skip to content

Commit

Permalink
feat: TodoBlock과 Vertex 클릭 시 편집용 팝업 생성
Browse files Browse the repository at this point in the history
  • Loading branch information
n-ryu committed Dec 8, 2022
1 parent 06df266 commit 4715a76
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 8 deletions.
47 changes: 47 additions & 0 deletions client/src/components/diagram/PopUp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { ReactElement } from 'react';
import Button from '@components/Button';
import Update from '@images/Update.svg';
import Delete from '@images/Delete.svg';
import styled from 'styled-components';
import { PRIMARY_COLORS } from '@util/Constants';

const { lightGray } = PRIMARY_COLORS;

const Wrapper = styled.div`
position: fixed;
width: max-content;
display: flex;
padding: 5px;
border-radius: 10px;
background-color: ${lightGray};
filter: drop-shadow(0px 4px 4px rgba(0, 0, 0, 0.25));
transform: translate(var(--x), var(--y));
`;

const PopUp = ({ type, x, y }: { type: 'Todo' | 'Vertex' | 'None'; x: number; y: number }): ReactElement => {
const style = { '--x': `${x}px`, '--y': `${y}px` };
return (
<>
{type !== 'None' && (
<Wrapper style={style as React.CSSProperties}>
{type === 'Todo' && (
<Button
context={<img src={Update} width="40px" height="40px" />}
onClick={(e) => {
console.log('update');
}}
/>
)}
<Button
context={<img src={Delete} width="40px" height="40px" />}
onClick={(e) => {
console.log('delete');
}}
/>
</Wrapper>
)}
</>
);
};

export default PopUp;
14 changes: 12 additions & 2 deletions client/src/components/diagram/TodoBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,23 @@ const remainingDayToString = (until: Date): string => {
return remaining <= 0 ? `D-${-remaining}` : `D+${remaining}`;
};

const TodoBlock = ({ todo, x, y }: { todo: Todo; x: number; y: number }): ReactElement => {
const TodoBlock = ({
todo,
x,
y,
onPopUp,
}: {
todo: Todo;
x: number;
y: number;
onPopUp: (event: React.MouseEvent) => void;
}): ReactElement => {
const style = {
'--x': `${x}px`,
'--y': `${y}px`,
};
return (
<Wrapper style={style as React.CSSProperties}>
<Wrapper style={style as React.CSSProperties} onClick={onPopUp}>
<UpperRow>
<Marker state={todo.state} />
<Title
Expand Down
15 changes: 14 additions & 1 deletion client/src/components/diagram/TodoVertex.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,19 @@ const toPathString = (width: number, height: number): string => {
return `M${-width - 2} 0C${-width - 2} ${0.4 * height} 2 ${0.6 * height} 2 ${height}`;
};

const TodoVertex = ({ x1, y1, x2, y2 }: { x1: number; y1: number; x2: number; y2: number }): ReactElement => {
const TodoVertex = ({
x1,
y1,
x2,
y2,
onPopUp,
}: {
x1: number;
y1: number;
x2: number;
y2: number;
onPopUp: (event: React.MouseEvent) => void;
}): ReactElement => {
const x = Math.min(x1, x2);
const y = Math.min(y1, y2);
const width = x2 - x1;
Expand Down Expand Up @@ -52,6 +64,7 @@ const TodoVertex = ({ x1, y1, x2, y2 }: { x1: number; y1: number; x2: number; y2
strokeWidth={25}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onClick={onPopUp}
/>
</svg>
</Wrapper>
Expand Down
55 changes: 50 additions & 5 deletions client/src/container/diagram/Diagram.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { ReactElement, useEffect, useState, useRef } from 'react';
import { useAtom } from 'jotai';
import { todoList } from '@util/GlobalState';
import { PlainTodo } from '@todo/todo.type';
import styled from 'styled-components';

import {
getDiagramData,
DiagramTodo,
Expand All @@ -15,6 +13,7 @@ import {
import { PRIMARY_COLORS } from '@util/Constants';
import TodoBlock from '@components/diagram/TodoBlock';
import TodoVertex from '@components/diagram/TodoVertex';
import PopUp from '@components/diagram/PopUp';

const { offWhite, green } = PRIMARY_COLORS;

Expand Down Expand Up @@ -52,12 +51,21 @@ const VerticalBaseLine = styled.div`
opacity: 0.5;
`;

interface PopUpData {
type: 'Todo' | 'Vertex' | 'None';
x: number;
y: number;
id: string;
}

const Diagram = ({ showDone }: { showDone: boolean }): ReactElement => {
const [todoListAtom] = useAtom(todoList);
const [diagramData, setDiagramData] = useState<Map<string, DiagramTodo> | undefined>();
const [diagramVertice, setDiagramVertice] = useState<Vertex[] | undefined>();
const [offset, setOffset] = useState<{ x: number; y: number }>({ x: 100, y: 100 });
const [popUpData, setPopUpData] = useState<PopUpData>({ type: 'None', x: 0, y: 0, id: '' });
const isWheelDown = useRef<boolean>(false);
const domRef = useRef<HTMLDivElement>(null);

useEffect(() => {
getDiagramData(todoListAtom, showDone)
Expand Down Expand Up @@ -103,22 +111,59 @@ const Diagram = ({ showDone }: { showDone: boolean }): ReactElement => {
}
};

const getOnClick = (type: 'Todo' | 'Vertex' | 'None', id: string) => {
return (event: React.MouseEvent): void => {
setPopUpData({
type,
id,
x: event.clientX - offset.x - (domRef.current?.getBoundingClientRect().left as number),
y: event.clientY - offset.y - (domRef.current?.getBoundingClientRect().top as number),
});
event.stopPropagation();
};
};

return (
<div onMouseDown={onWheelDown} onMouseUp={onWheelUp} onMouseMove={onMouseMove} onMouseLeave={onWheelLeave}>
<div
onMouseDown={onWheelDown}
onMouseUp={onWheelUp}
onMouseMove={onMouseMove}
onMouseLeave={onWheelLeave}
onClick={getOnClick('None', '')}
ref={domRef}
>
<Detector />
<HorizontalBaseLine style={horizontalLineStyle as React.CSSProperties} />
<VerticalBaseLine style={verticalLineStyle as React.CSSProperties} />
<Wrapper style={diagramStyle as React.CSSProperties}>
{diagramData !== undefined &&
diagramVertice?.map((el) => {
const { x1, y1, x2, y2 } = getVertexDimension(diagramData, el);
return <TodoVertex key={`${el.from}+${el.to}`} x1={x1} y1={y1} x2={x2} y2={y2} />;
return (
<TodoVertex
key={`${el.from}+${el.to}`}
x1={x1}
y1={y1}
x2={x2}
y2={y2}
onPopUp={getOnClick('Vertex', `${el.from}+${el.to}`)}
/>
);
})}
{diagramData !== undefined &&
[...diagramData].map((el) => {
const pos = calculatePosition(el[1].order as number, el[1].depth as number);
return <TodoBlock key={el[1].todo.id} todo={el[1].todo} x={pos.x} y={pos.y} />;
return (
<TodoBlock
key={el[1].todo.id}
todo={el[1].todo}
x={pos.x}
y={pos.y}
onPopUp={getOnClick('Todo', el[1].todo.id)}
/>
);
})}
{popUpData.type !== 'None' && <PopUp {...popUpData} />}
</Wrapper>
</div>
);
Expand Down

0 comments on commit 4715a76

Please sign in to comment.