Skip to content

Commit

Permalink
fix: 게시판 삭제 버튼 및 메시지 구현 (#83)
Browse files Browse the repository at this point in the history
  • Loading branch information
selfishAltruism committed Mar 2, 2024
1 parent 7222049 commit dd22608
Show file tree
Hide file tree
Showing 10 changed files with 212 additions and 46 deletions.
36 changes: 2 additions & 34 deletions src/pages/board/boardCreate/BoardCreatePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,7 @@ const BoardCreatePage: React.FC = observer(() => {
if (me?.isCircleLeader && data.circleName !== '전체') {
//동아리장이 동아리 게시판을 생성하는 경우
if (data.category === '공지 게시판') {
body.createRoleList = [
'ADMIN',
'VICE_PRESIDENT',
'PRESIDENT',
'LEADER_CIRCLE',
'PRESIDENT_N_LEADER_CIRCLE',
'VICE_PRESIDENT_N_LEADER_CIRCLE',
'COUNCIL_N_LEADER_CIRCLE',
'LEADER_1_N_LEADER_CIRCLE',
'LEADER_2_N_LEADER_CIRCLE',
'LEADER_3_N_LEADER_CIRCLE',
'LEADER_4_N_LEADER_CIRCLE',
];
body.createRoleList = ['ADMIN', 'VICE_PRESIDENT', 'PRESIDENT', 'LEADER_CIRCLE'];
body.circleId =
me.circleIds![me.circleNames!.findIndex(circleName => circleName === data.circleName)];
} else if (data.category === '자유 게시판') {
Expand All @@ -93,27 +81,14 @@ const BoardCreatePage: React.FC = observer(() => {
'LEADER_3',
'LEADER_4',
'COMMON',
'PRESIDENT_N_LEADER_CIRCLE',
'VICE_PRESIDENT_N_LEADER_CIRCLE',
'COUNCIL_N_LEADER_CIRCLE',
'LEADER_1_N_LEADER_CIRCLE',
'LEADER_2_N_LEADER_CIRCLE',
'LEADER_3_N_LEADER_CIRCLE',
'LEADER_4_N_LEADER_CIRCLE',
];
body.circleId =
me.circleIds![me.circleNames!.findIndex(circleName => circleName === data.circleName)];
}
} else {
//학생회장 혹은 관리자가 동아리 게시판을 생성하는 경우
if (data.category === '공지 게시판') {
body.createRoleList = [
'ADMIN',
'VICE_PRESIDENT',
'PRESIDENT',
'PRESIDENT_N_LEADER_CIRCLE',
'VICE_PRESIDENT_N_LEADER_CIRCLE',
];
body.createRoleList = ['ADMIN', 'VICE_PRESIDENT', 'PRESIDENT'];
} else if (data.category === '자유 게시판') {
body.createRoleList = [
'ADMIN',
Expand All @@ -125,13 +100,6 @@ const BoardCreatePage: React.FC = observer(() => {
'LEADER_3',
'LEADER_4',
'COMMON',
'PRESIDENT_N_LEADER_CIRCLE',
'VICE_PRESIDENT_N_LEADER_CIRCLE',
'COUNCIL_N_LEADER_CIRCLE',
'LEADER_1_N_LEADER_CIRCLE',
'LEADER_2_N_LEADER_CIRCLE',
'LEADER_3_N_LEADER_CIRCLE',
'LEADER_4_N_LEADER_CIRCLE',
];
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/pages/board/boardList/BoardListPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useEffect } from 'react';

import { PageUiStoreImpl } from './BoardListPageUiStore';
import { Boards, BoardCreateButton } from './components';
import { DeleteBoardModal } from './components/DeleteBoardModal';

import { UniformLogo } from '@/assets';
import { BodyScreen, GNB, Header, PageBody, PageStoreHOC } from '@/components';
Expand Down Expand Up @@ -33,6 +34,8 @@ const BoardListPage: React.FC = () => {
</BodyScreen>
</PageBody>
<GNB />

<DeleteBoardModal />
</>
);
};
Expand Down
6 changes: 5 additions & 1 deletion src/pages/board/boardList/BoardListPageUiStore.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { makeAutoObservable } from 'mobx';

import { DeleteBoardModalUi } from './components/DeleteBoardModal/DeleteBoardModalUi';

import { BoardRepoImpl as Repo } from '@/stores/repositories/BoardRepo';

export class BoardListPageUiStore {
boards: Map<string, Model.Board[]> = new Map();

deleteBoardModal = new DeleteBoardModalUi();

constructor() {
makeAutoObservable(this, {}, { autoBind: true });
makeAutoObservable(this, { deleteBoardModal: true }, { autoBind: true });
}

// 생성한 게시판의 카테고리가 이미 있으면 그 카테고리 안에 넣고, 없으면 새로 생성
Expand Down
35 changes: 26 additions & 9 deletions src/pages/board/boardList/components/BoardListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
import styled from '@emotion/styled';
import { observer } from 'mobx-react-lite';
import { useCallback } from 'react';
import { generatePath } from 'react-router';

import { RemoveButton, Row } from './styled';

import { ClearLink } from '@/components';
import { PAGE_URL } from '@/configs/path';
import { usePageUiStore } from '@/hooks';

export const BoardListItem: React.FC<{ model: Model.Board }> = observer(({ model }) => {
const { deleteBoardModal } = usePageUiStore<PageUiStore.BoardList>();

const handleOpendeleteBoardModal = useCallback(
(target: Model.Board) => () => {
deleteBoardModal.open(target);
},
[],
);

export const BoardListItem: React.FC<{ model: Model.Board }> = observer(
({ model: { id: boardId, name } }) => (
<StyledLink to={generatePath(PAGE_URL.PostList, { boardId })}>{name}</StyledLink>
),
);
return (
<>
<Row>
<StyledLink to={generatePath(PAGE_URL.PostList, { boardId: model.id })}>
{model.name}
</StyledLink>
<RemoveButton onClick={handleOpendeleteBoardModal(model)} />
</Row>
</>
);
});

const StyledLink = styled(ClearLink)`
float: left;
clear: left;
margin-top: 14px;
font-size: 12px;
line-height: 14px;
font-size: 14px;
`;
3 changes: 2 additions & 1 deletion src/pages/board/boardList/components/Boards.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { observer } from 'mobx-react-lite';
import { useCallback } from 'react';

import { BoardListItem } from './BoardListItem';

import { ListBox } from '@/components';
import { usePageUiStore } from '@/hooks';

export const Boards: React.FC = observer(() => {
const { boards } = usePageUiStore<PageUiStore.BoardList>();
const { boards, deleteBoardModal } = usePageUiStore<PageUiStore.BoardList>();

return (
<div style={{ marginTop: '10px' }}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Modal } from '@mui/material';
import { observer } from 'mobx-react-lite';
import { useCallback } from 'react';

import {
ModalAlertMessage,
ModalAlertTitle,
ModalBox,
ModalFooter,
ModalFooterButton,
} from '@/components';
import { usePageUiStore } from '@/hooks';
import { useRootStore } from '@/stores';

export const DeleteBoardModal: React.FC = observer(() => {
const {
ui: { alert },
} = useRootStore();
const {
fetchBoards,
deleteBoardModal: { deleteBoard, target, close, visible },
} = usePageUiStore<PageUiStore.BoardList>();

const handleOk = useCallback(async () => {
if (!target || !target.id || !target.name === undefined) return;
const { success, message } = (await deleteBoard(target.id)) as unknown as StoreAPI;
if (success) {
fetchBoards();
alert({
message: `${target.name} 동아리가 삭제되었습니다.`,
});
} else if (message) alert({ message });
close();
}, [target]);

return (
<Modal open={visible} closeAfterTransition>
<ModalBox>
<ModalAlertTitle>
<strong>{target && target.name ? target.name : ''}</strong> 동아리 삭제
</ModalAlertTitle>
<ModalAlertMessage center>
정말로 <strong>{target && target.name ? target.name : ''}</strong> 동아리를
삭제하시겠습니까? <br />
삭제된 데이터는 복구되지 않습니다.
</ModalAlertMessage>
<ModalFooter>
<ModalFooterButton onClick={close}>취소</ModalFooterButton>
<ModalFooterButton onClick={handleOk}>확인</ModalFooterButton>
</ModalFooter>
</ModalBox>
</Modal>
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { makeAutoObservable } from 'mobx';

import { BoardRepoImpl as Repo } from '@/stores/repositories/BoardRepo';

export class DeleteBoardModalUi {
visible = false;
target?: Model.Board;

constructor() {
makeAutoObservable(this, {}, { autoBind: true });
}

open(target: Model.Board): void {
console.log(target);
this.visible = true;
this.target = target;
}

close(): void {
this.visible = false;
}

*deleteBoard(boardId: string): Generator {
try {
yield Repo.delete(boardId);
return { success: true } as StoreAPI;
} catch (error) {
return error;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './DeleteBoardModal';
85 changes: 85 additions & 0 deletions src/pages/board/boardList/components/styled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import styled from '@emotion/styled';
import AddIcon from '@mui/icons-material/Add';
import AutorenewIcon from '@mui/icons-material/Autorenew';
import ClearIcon from '@mui/icons-material/Clear';
import { observer } from 'mobx-react-lite';
import { memo, useCallback } from 'react';

import { ClearLink, ClearButton } from '@/components';
import { usePageUiStore } from '@/hooks';

export const Box = styled.div`
position: relative;
& + & {
margin-top: 30px;
}
`;

export const Title = styled.h2`
margin: 0;
padding: 10px 0;
font-size: 18px;
line-height: 21px;
`;

const _AddLink = styled(ClearLink)`
position: absolute;
top: 0;
right: 0;
padding: 10px;
`;

export const AddLink: React.FC<{ to: string }> = memo(({ to }) => (
<_AddLink to={to}>
<AddIcon fontSize="small" />
</_AddLink>
));

export const Row = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
height: 30px;
font-size: 13px;
margin-top: 8px;
margin-bottom: -10px;
`;

const UserNameButton = styled(ClearButton)`
padding-left: 10px;
width: 100%;
text-align: left;
-webkit-line-clamp: 1;
`;

export const UserName: React.FC<{ model: Model.User; withCircleName?: string }> = observer(
({ model, withCircleName = undefined }) => {
const { userInfoModal } = usePageUiStore<PageUiStore.SettingRoleManagement>();
const handleOpenInfoModal = useCallback(() => userInfoModal.open(model), [model]);

return (
<div style={{ flex: '1 0 0', overflow: 'hidden' }}>
<UserNameButton className="text-ellipsis" onClick={handleOpenInfoModal}>
{withCircleName && model.circleNames ? `[ ${withCircleName} ] ` : ''}
{model.nameWithAdmission}
</UserNameButton>
</div>
);
},
);

export const RemoveButton: React.FC<{ onClick: () => void }> = ({ ...props }) => (
<ClearButton style={{ padding: '10px' }} {...props}>
<ClearIcon fontSize="small" />
</ClearButton>
);

export const AutorenewLink: React.FC<{ pathname: string; state: unknown }> = memo(
({ pathname, state }) => (
<ClearLink to={{ pathname, state }} style={{ padding: '10px' }}>
<AutorenewIcon fontSize="small" />
</ClearLink>
),
);
4 changes: 3 additions & 1 deletion src/vite-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import type { AdmissionPageUiStore } from './pages/auth/admission/AdmissionPageUiStore';
import type { SignInPageUiStore } from './pages/auth/signIn/SignInPageUiStore';
import type { SignUpPageUiStore } from './pages/auth/signUp/SignUpPageUiStore';
import type { BoardCreatePageUiStore } from './pages/board/boardCreate/BoardCreatePageUiStore';
import type { BoardListPageUiStore } from './pages/board/boardList/BoardListPageUiStore';
import type { PostDetailPageUiStore } from './pages/board/postDetail/PostDetailPageUiStore';
import type { PostEditorPageUiStore } from './pages/board/postEditor/PostEditorPageUiStore';
Expand Down Expand Up @@ -77,7 +78,8 @@ declare global {
type CircleJoin = CircleJoinPageUiStore;
type CircleMain = CircleMainPageUiStore;
type BoardList = BoardListPageUiStore;
type BoardCreate = BoardCreate;
type BoardCreate = BoardCreatePageUiStore;
type BoardDelete = DeleteBoardModalUi;
type PostList = PostListPageUiStore;
type PostDetail = PostDetailPageUiStore;
type PostEditor = PostEditorPageUiStore;
Expand Down

0 comments on commit dd22608

Please sign in to comment.