Skip to content

Commit

Permalink
Merge pull request #292 from boostcampwm2023/refactor/socket_context
Browse files Browse the repository at this point in the history
refactor : Landing 페이지 데이터 구조 및 렌더링 최적화 리펙토링
  • Loading branch information
surinkwon authored Jun 6, 2024
2 parents eaecc1b + 50593f2 commit 0d9cb06
Show file tree
Hide file tree
Showing 17 changed files with 308 additions and 167 deletions.
3 changes: 2 additions & 1 deletion frontend/src/components/landing/common/LandingTitleUI.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import React from "react";
import Plus from "../../../assets/icons/plus.svg?react";

interface LandingTitleUIProps {
Expand All @@ -16,4 +17,4 @@ const LandingTitleUI = ({ handleClick, title }: LandingTitleUIProps) => {
);
};

export default LandingTitleUI;
export default React.memo(LandingTitleUI);
8 changes: 7 additions & 1 deletion frontend/src/components/landing/link/LandingLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ import { LandingLinkDTO } from "../../../types/DTO/landingDTO";
import LandingLinkBlock from "./LandingLinkBlock";
import LandingLinkModal from "./LandingLinkModal";
import LandingTitleUI from "../common/LandingTitleUI";
import { Socket } from "socket.io-client";
import { useOutletContext } from "react-router-dom";
import useLandingLinkSocket from "../../../hooks/common/landing/useLandingLinkSocket";

const LandingLink = () => {
const { socket }: { socket: Socket } = useOutletContext();
const { link } = useLandingLinkSocket(socket);

const LandingLink = ({ link }: { link: LandingLinkDTO[] }) => {
const { open, close } = useModal(true);
const handleCreateLinkClick = () => {
open(<LandingLinkModal close={close} />);
Expand Down
31 changes: 13 additions & 18 deletions frontend/src/components/landing/memo/LandingMemoList.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
import { LandingMemoDTO } from "../../../types/DTO/landingDTO";
import { MemoColorType } from "../../../types/common/landing";
import LandingTitleUI from "../common/LandingTitleUI";
import MemoBlock from "./MemoBlock";
import { Socket } from "socket.io-client";
import { useOutletContext } from "react-router-dom";
import LandingTitleUI from "../common/LandingTitleUI";
import { LandingMemoDTO } from "../../../types/DTO/landingDTO";
import useLandingMemoSocket from "../../../hooks/common/landing/useLandingMemoSocket";

interface LandingMemoListProps {
memoList: LandingMemoDTO[];
memoSocketEvent: {
emitMemoCreateEvent: () => void;
emitMemoDeleteEvent: (id: number) => void;
emitMemoColorUpdateEvent: (id: number, color: MemoColorType) => void;
};
}

const LandingMemoList = ({
memoList,
memoSocketEvent,
}: LandingMemoListProps) => {
const { emitMemoCreateEvent, emitMemoDeleteEvent, emitMemoColorUpdateEvent } =
memoSocketEvent;
const LandingMemoList = () => {
const { socket }: { socket: Socket } = useOutletContext();
const {
memoList,
emitMemoCreateEvent,
emitMemoDeleteEvent,
emitMemoColorUpdateEvent,
} = useLandingMemoSocket(socket);
return (
<div className="w-full rounded-lg shadow-box bg-gradient-to-tr from-dark-green-linear-from to-dark-green-linear-to">
<div className="py-6 ps-6 pe-3 w-[32rem]">
Expand Down
39 changes: 16 additions & 23 deletions frontend/src/components/landing/memo/MemoBlock.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import MemoEditor from "./MemoEditor";
import { LandingMemoDTO } from "../../../types/DTO/landingDTO";
import { MemoColorStyle, MemoColorType } from "../../../types/common/landing";
import useLandingMemo from "../../../hooks/common/landing/useLandingMemo";
import useLandingMemo from "../../../hooks/common/landing/useLandingMemoEditor";
import React from "react";

interface MemoBlockProps extends LandingMemoDTO {
emitMemoDeleteEvent: (id: number) => void;
Expand All @@ -17,18 +18,8 @@ const MemoBlock = ({
emitMemoColorUpdateEvent,
emitMemoDeleteEvent,
}: MemoBlockProps) => {
const {
editorOpened,
memoTitle,
memoContent,
memoColor,
memoRef,
openEditor,
changeMemoColor,
handleContentChange,
handleTitleChange,
} = useLandingMemo(title, content, color);
const colorStyle = MemoColorStyle[memoColor];
const { editorOpened, memoRef, openEditor } = useLandingMemo();
const colorStyle = MemoColorStyle[color];

return (
<div
Expand All @@ -39,30 +30,32 @@ const MemoBlock = ({
<input
placeholder="제목을 작성하세요"
className="text-xs font-bold bg-transparent focus:outline-none"
value={memoTitle}
onChange={handleTitleChange}
value={title}
readOnly
// onChange={handleTitleChange}
/>
<textarea
placeholder="내용을 작성하세요"
className="text-xxs bg-transparent focus:outline-none h-full resize-none scrollbar-thin scrollbar-thumb-rounded-full scrollbar-thumb-dark-gray scrollbar-track-transparent"
spellCheck="false"
value={memoContent}
onChange={handleContentChange}
value={content}
// onChange={handleContentChange}
/>
<div className="flex justify-between items-center">
<p className="text-xxxs h-5 font-bold">{author}</p>
{editorOpened && (
<MemoEditor
id={id}
color={memoColor}
changeMemoColor={changeMemoColor}
emitMemoDeleteEvent={emitMemoDeleteEvent}
emitMemoColorUpdateEvent={emitMemoColorUpdateEvent}
{...{
id,
color,
emitMemoColorUpdateEvent,
emitMemoDeleteEvent,
}}
/>
)}
</div>
</div>
);
};

export default MemoBlock;
export default React.memo(MemoBlock);
5 changes: 2 additions & 3 deletions frontend/src/components/landing/memo/MemoColorButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,22 @@ interface MemoColorButtonProps {
id: number;
active: Boolean;
color: MemoColorType;
changeMemoColor: (color: MemoColorType) => void;

emitMemoColorUpdateEvent: (id: number, color: MemoColorType) => void;
}

const MemoColorButton = ({
id,
active,
color,
changeMemoColor,

emitMemoColorUpdateEvent,
}: MemoColorButtonProps) => {
const borderStyle = active
? "border-blue-500 border-2"
: "border-white border hover:border-blue-500 hover:border-2";

const handleOnClick = () => {
changeMemoColor(color);
emitMemoColorUpdateEvent(id, color);
};

Expand Down
21 changes: 8 additions & 13 deletions frontend/src/components/landing/memo/MemoEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import TrashBinIcon from "../../../assets/icons/trash-can.svg?react";
import { MEMO_COLOR } from "../../../constants/landing";
import { MemoColorType } from "../../../types/common/landing";
import MemoColorButton from "./MemoColorButton";

interface MemoEditorProps {
id: number;
color: MemoColorType;
changeMemoColor: (color: MemoColorType) => void;
emitMemoDeleteEvent: (id: number) => void;
emitMemoColorUpdateEvent: (id: number, color: MemoColorType) => void;
}

const MemoEditor = ({
id,
color,
changeMemoColor,
emitMemoDeleteEvent,
emitMemoColorUpdateEvent,
}: MemoEditorProps) => {
Expand All @@ -25,30 +24,26 @@ const MemoEditor = ({
<div className="w-32 h-fit rounded-full flex justify-between items-center duration-100">
<MemoColorButton
id={id}
active={color === "yellow"}
color={"yellow"}
changeMemoColor={changeMemoColor}
active={color === MEMO_COLOR.YELLOW}
color={MEMO_COLOR.YELLOW}
emitMemoColorUpdateEvent={emitMemoColorUpdateEvent}
/>
<MemoColorButton
id={id}
active={color === "blue"}
color={"blue"}
changeMemoColor={changeMemoColor}
active={color === MEMO_COLOR.BLUE}
color={MEMO_COLOR.BLUE}
emitMemoColorUpdateEvent={emitMemoColorUpdateEvent}
/>
<MemoColorButton
id={id}
active={color === "red"}
active={color === MEMO_COLOR.RED}
color={"red"}
changeMemoColor={changeMemoColor}
emitMemoColorUpdateEvent={emitMemoColorUpdateEvent}
/>
<MemoColorButton
id={id}
active={color === "gray"}
color={"gray"}
changeMemoColor={changeMemoColor}
active={color === MEMO_COLOR.GRAY}
color={MEMO_COLOR.GRAY}
emitMemoColorUpdateEvent={emitMemoColorUpdateEvent}
/>
<button
Expand Down
41 changes: 24 additions & 17 deletions frontend/src/components/landing/project/LandingProject.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,34 @@
import { LandingProjectDTO } from "../../../types/DTO/landingDTO";
import { Socket } from "socket.io-client";
import formatDate from "../../../utils/formatDate";
import LandingProjectLink from "./LandingProjectLink";
import { useOutletContext } from "react-router-dom";

import useLandingProjectSocket from "../../../hooks/common/landing/useLandingProjectSocket";

interface LandingProjectProps {
project: LandingProjectDTO;
projectId: string;
}

const LandingProject = ({ project, projectId }: LandingProjectProps) => (
<div className="flex flex-col justify-between w-full p-6 rounded-lg shadow-box">
<div className="flex items-baseline justify-between font-bold text-middle-green">
<p className="text-xl">| {project.title}</p>
<p className="text-xs">
{project.createdAt && formatDate(project.createdAt)}
</p>
</div>
<div className="text-xs">{project.subject}</div>
<div className="flex justify-between">
<LandingProjectLink projectId={projectId} type="BACKLOG" />
<LandingProjectLink projectId={projectId} type="SPRINT" />
<LandingProjectLink projectId={projectId} type="SETTINGS" />
const LandingProject = ({ projectId }: LandingProjectProps) => {
const { socket }: { socket: Socket } = useOutletContext();
const { project } = useLandingProjectSocket(socket);

return (
<div className="flex flex-col justify-between w-full p-6 rounded-lg shadow-box">
<div className="flex items-baseline justify-between font-bold text-middle-green">
<p className="text-xl">| {project.title}</p>
<p className="text-xs">
{project.createdAt && formatDate(project.createdAt)}
</p>
</div>
<div className="text-xs">{project.subject}</div>
<div className="flex justify-between">
<LandingProjectLink projectId={projectId} type="BACKLOG" />
<LandingProjectLink projectId={projectId} type="SPRINT" />
<LandingProjectLink projectId={projectId} type="SETTINGS" />
</div>
</div>
</div>
);
);
};

export default LandingProject;
9 changes: 7 additions & 2 deletions frontend/src/components/landing/sprint/LandingSprint.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { LandingSprintDTO } from "../../../types/DTO/landingDTO";
import diffBetweenDate from "../../../utils/diffBetweenDate";
import formatDate from "../../../utils/formatDate";
import LandingSprintBar from "./LandingSprintBar";
import { Socket } from "socket.io-client";
import { useOutletContext } from "react-router-dom";
import useLandingSprintSocket from "../../../hooks/common/landing/useLandingSprintSocket";

const LandingSprint = () => {
const { socket }: { socket: Socket } = useOutletContext();
const { sprint } = useLandingSprintSocket(socket);

const LandingSprint = ({ sprint }: { sprint: LandingSprintDTO | null }) => {
return (
<div className="w-full shadow-box rounded-lg p-6 flex flex-col justify-between">
<p className="text-l text-middle-green font-bold">| 스프린트 정보</p>
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/constants/landing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import discordLogo from "../assets/logo/Tech Logos/discord.svg";
import youtubeLogo from "../assets/logo/Tech Logos/youtube.svg";
import naverLogo from "../assets/logo/Tech Logos/naver.png";
import { MemberStatus } from "../types/DTO/landingDTO";
import { MemoColorType } from "../types/common/landing";

export const DEFAULT_VALUE = {
PROJECT: {
Expand Down Expand Up @@ -125,3 +126,14 @@ export const USER_WORD_STATUS: MyMap = {
"부재 중": "off",
자리비움: "away",
};

type MemoColorMap = {
[key: string]: MemoColorType;
};

export const MEMO_COLOR: MemoColorMap = {
YELLOW: "yellow",
BLUE: "blue",
RED: "red",
GRAY: "gray",
};
32 changes: 32 additions & 0 deletions frontend/src/hooks/common/landing/useLandingLinkSocket.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useEffect, useState } from "react";
import { Socket } from "socket.io-client";
import { LandingDTO, LandingLinkDTO } from "../../../types/DTO/landingDTO";
import {
LandingSocketData,
LandingSocketDomain,
} from "../../../types/common/landing";

const useLandingLinkSocket = (socket: Socket) => {
const [link, setLink] = useState<LandingLinkDTO[]>([]);
const handleInitEvent = (content: LandingDTO) => {
const { link } = content as LandingDTO;
setLink(link);
};

const handleOnLanding = ({ domain, content }: LandingSocketData) => {
if (domain !== LandingSocketDomain.INIT) return;
handleInitEvent(content);
};

useEffect(() => {
socket.on("landing", handleOnLanding);

return () => {
socket.off("landing");
};
});

return { link };
};

export default useLandingLinkSocket;
Loading

0 comments on commit 0d9cb06

Please sign in to comment.