Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Impl UI for agenda edit mode #606

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 65 additions & 14 deletions packages/web/src/app/meeting/agenda/create/page.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,72 @@
"use client";

import React, { useState } from "react";

import Button from "@sparcs-clubs/web/common/components/Button";
import FlexWrapper from "@sparcs-clubs/web/common/components/FlexWrapper";
import PageHead from "@sparcs-clubs/web/common/components/PageHead";
import NewAgendaFrame from "@sparcs-clubs/web/features/meeting/agenda/create/frames/NewAgendaFrame";
import AgendaContent from "@sparcs-clubs/web/features/meeting/agenda/constants/agendaContent";
import { AgendaTypeEnum } from "@sparcs-clubs/web/features/meeting/agenda/constants/agendaType";
import EditAgendaFrame from "@sparcs-clubs/web/features/meeting/agenda/create/frames/EditAgendaFrame";
import ViewAgendaFrame from "@sparcs-clubs/web/features/meeting/agenda/create/frames/ViewAgendaFrame";

const AgendaCreate: React.FC = () => {
const [mockNewAgendaList, setMockNewAgendaList] = useState<AgendaContent[]>([
{
type: AgendaTypeEnum.Report,
title: "술박스 개수 점검",
content: "술박스가 5조 5억개 있습니다.",
},
{
type: AgendaTypeEnum.Discuss,
title: "술박스 구입 개수 논의",
content: "술박스를 10개 구입하기로 결정했습니다.",
},
{
type: AgendaTypeEnum.Approval,
title: "술박스 구입 허락",
content: "술박스 구입이 허락되었습니다.",
},
]);

const [isEditMode, setIsEditMode] = React.useState(false);

const AgendaCreate: React.FC = () => (
<FlexWrapper gap={60} direction="column">
<PageHead
items={[
{ name: "의결기구", path: "/meeting" }, // TODO: figma 나오는대로 맞춰서
{ name: "안건지", path: "/meeting/agenda" },
{ name: "작성", path: "/meeting/agenda/create" },
]}
title="안건지 작성하기"
/>
<NewAgendaFrame />
</FlexWrapper>
);
return (
<FlexWrapper gap={60} direction="column">
<PageHead
items={[
{ name: "의결기구", path: "/meeting" },
{ name: "분과회의", path: "/meeting/agenda" },
]}
title="안건지 작성하기"
enableLast
/>
<FlexWrapper gap={12} direction="row">
<Button
type={isEditMode ? "outlined" : "default"}
style={{ flex: 1 }}
onClick={() => setIsEditMode(false)}
>
보기 모드
</Button>
<Button
type={isEditMode ? "default" : "outlined"}
style={{ flex: 1 }}
onClick={() => setIsEditMode(true)}
>
수정 모드
</Button>
</FlexWrapper>
{isEditMode ? (
<EditAgendaFrame
agendaList={mockNewAgendaList}
setAgendaList={setMockNewAgendaList}
/>
) : (
<ViewAgendaFrame />
)}
</FlexWrapper>
);
};

export default AgendaCreate;
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { AgendaTypeEnum } from "./agendaType";

interface AgendaContent {
type: AgendaTypeEnum;
title: string;
content: string;
title?: string;
content?: string;
}

export default AgendaContent;

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import Button from "@sparcs-clubs/web/common/components/Button";
import FlexWrapper from "@sparcs-clubs/web/common/components/FlexWrapper";
import AgendaContent from "@sparcs-clubs/web/features/meeting/agenda/constants/agendaContent";

import { AgendaTypeEnum } from "@sparcs-clubs/web/features/meeting/agenda/constants/agendaType";

import AgendaBlock from "./_atomic/AgendaBlock";

interface AgendaEditorListProps {
agendaList: AgendaContent[];
setAgendaList: (agendaList: AgendaContent[]) => void;
}

const AgendaEditorList: React.FC<AgendaEditorListProps> = ({
agendaList,
setAgendaList,
}: AgendaEditorListProps) => {
const getIndexAmongSameType = () => {
const countMap = new Map<AgendaTypeEnum, number>();

return agendaList.map((agendaContent: AgendaContent) => {
if (!countMap.has(agendaContent.type)) {
countMap.set(agendaContent.type, 1);
}

const currentIndex = countMap.get(agendaContent.type) as number;
countMap.set(agendaContent.type, currentIndex + 1);

return currentIndex;
});
};

const indexAmongSameType = getIndexAmongSameType();

const setOneAgendaContent = (index: number, value: AgendaContent) => {
const newAgendaList = [...agendaList];
newAgendaList[index] = value;
setAgendaList(newAgendaList);
};

const decreaseIndex = (index: number) => {
if (index === 0) return;

const newAgendaList = [...agendaList];
[newAgendaList[index], newAgendaList[index - 1]] = [
newAgendaList[index - 1],
newAgendaList[index],
];
setAgendaList(newAgendaList);
};

const increaseIndex = (index: number) => {
if (index === agendaList.length - 1) return;

const newAgendaList = [...agendaList];
[newAgendaList[index], newAgendaList[index + 1]] = [
newAgendaList[index + 1],
newAgendaList[index],
];
setAgendaList(newAgendaList);
};

const deleteAgenda = (index: number) => {
const newAgendaList = [...agendaList];
newAgendaList.splice(index, 1);
setAgendaList(newAgendaList);
};

const addAgenda = () => {
const newAgendaList = [...agendaList];
newAgendaList.push({
type: AgendaTypeEnum.Report,
title: undefined,
content: undefined,
});
setAgendaList(newAgendaList);
};

return (
<FlexWrapper gap={24} direction="column">
{agendaList.map((agendaContent, index) => (
<AgendaBlock
key={`${index.toString}`}
agendaContent={agendaContent}
setAgendaContent={(value: AgendaContent) =>
setOneAgendaContent(index, value)
}
isFirst={index === 0}
isLast={index === agendaList.length - 1}
decreaseIndex={() => decreaseIndex(index)}
increaseIndex={() => increaseIndex(index)}
onDelete={() => deleteAgenda(index)}
indexAmongSameType={indexAmongSameType[index]}
/>
))}
<Button onClick={addAgenda}>+ 회의 안건 추가</Button>
</FlexWrapper>
);
};

export default AgendaEditorList;
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// TODO: 구현하기 -> Array<AgendaContent> 사용
import React, { useState } from "react";

import FoldUnfoldButton from "@sparcs-clubs/web/common/components/Buttons/FoldUnfoldButton";
import FlexWrapper from "@sparcs-clubs/web/common/components/FlexWrapper";
import Icon from "@sparcs-clubs/web/common/components/Icon";
import Typography from "@sparcs-clubs/web/common/components/Typography";
import AgendaContent from "@sparcs-clubs/web/features/meeting/agenda/constants/agendaContent";
import { AgendaTypeName } from "@sparcs-clubs/web/features/meeting/agenda/constants/agendaType";
import AgendaEditor from "@sparcs-clubs/web/features/meeting/agenda/create/components/_atomic/AgendaEditor";
import AgendaViewer from "@sparcs-clubs/web/features/meeting/agenda/create/components/_atomic/AgendaViewer";
import colors from "@sparcs-clubs/web/styles/themes/colors";

interface AgendaBlockProps {
agendaContent: AgendaContent;
setAgendaContent: (value: AgendaContent) => void;
isFirst: boolean;
isLast: boolean;
decreaseIndex: () => void;
increaseIndex: () => void;
onDelete: () => void;
indexAmongSameType: number;
}

const AgendaBlock: React.FC<AgendaBlockProps> = ({
agendaContent,
setAgendaContent,
isFirst,
isLast,
decreaseIndex,
increaseIndex,
onDelete,
indexAmongSameType,
}: AgendaBlockProps) => {
const [folded, setFolded] = useState(false);
const [isEditMode, setEditMode] = useState(false);

const currentNewAgendaTypeName = AgendaTypeName[agendaContent.type];

return (
<FlexWrapper gap={8} direction="column">
<FlexWrapper gap={8} direction="row" style={{ alignItems: "center" }}>
<FlexWrapper gap={0} direction="column">
<Icon
type="arrow_drop_up"
size={24}
color={isFirst ? colors.GRAY[300] : colors.BLACK}
onClick={isFirst ? undefined : decreaseIndex}
/>
<Icon
type="arrow_drop_down"
size={24}
color={isLast ? colors.GRAY[300] : colors.BLACK}
onClick={isLast ? undefined : increaseIndex}
/>
</FlexWrapper>
<Typography
fs={20}
lh={24}
fw="MEDIUM"
style={{ flex: 1, marginLeft: 4 }}
>
{`${currentNewAgendaTypeName}${indexAmongSameType}: ${agendaContent.title ?? "제목 없음"}`}
</Typography>
<FoldUnfoldButton folded={folded} setFolded={setFolded} />
</FlexWrapper>
{!folded &&
(isEditMode ? (
<AgendaEditor
agendaContent={agendaContent}
onDelete={onDelete}
onSave={() => setEditMode(false)}
onChange={setAgendaContent}
/>
) : (
<AgendaViewer
agendaContent={agendaContent}
onDelete={onDelete}
onEdit={() => setEditMode(true)}
/>
))}
</FlexWrapper>
);
};

export default AgendaBlock;
Loading