-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #547 from peer-42seoul/feat/widget/notice
[D-TP] 공지사항 위젯
- Loading branch information
Showing
7 changed files
with
251 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
src/app/teams/[id]/panel/widgets/BoardWidget/PreviewModal.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// 게시판과 공지사항 미리보기 모달을 함께 쓸 계획... | ||
|
||
import CuButton from '@/components/CuButton' | ||
import CuModal from '@/components/CuModal' | ||
import { ListItem } from '@/components/board/ListPanel' | ||
import { ITeamNotice } from '@/types/TeamBoardTypes' | ||
import { Stack } from '@mui/material' | ||
import { useRouter } from 'next/navigation' | ||
|
||
interface IPreviewModalProps { | ||
open: boolean | ||
onClose: () => void | ||
data: ITeamNotice[] | ||
teamId?: string | string[] | ||
} | ||
|
||
const PreviewModal = ({ open, onClose, data, teamId }: IPreviewModalProps) => { | ||
const router = useRouter() | ||
|
||
return ( | ||
<CuModal open={open} onClose={onClose} title={'공지사항'}> | ||
<Stack spacing={'1rem'}> | ||
<> | ||
{data.map((item) => ( | ||
<ListItem | ||
key={crypto.randomUUID()} | ||
title={item.title} | ||
authorNickname={item.authorNickname} | ||
createdAt={item.createdAt} | ||
/> | ||
))} | ||
</> | ||
<CuButton | ||
action={() => router.push(`/teams/${teamId}/board`)} | ||
message={'모든 공지사항 보기'} | ||
variant={'text'} | ||
/> | ||
</Stack> | ||
</CuModal> | ||
) | ||
} | ||
|
||
export default PreviewModal |
13 changes: 13 additions & 0 deletions
13
src/app/teams/[id]/panel/widgets/BoardWidget/index.style.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { Theme } from '@mui/material' | ||
|
||
export const widgetContent = { | ||
padding: '1.5rem 1.5rem 2rem 1.5rem', | ||
} | ||
|
||
export const mobileWidgetContent = { | ||
padding: '1.25rem 1.25rem 1.5rem 1.25rem', | ||
} | ||
|
||
export const titleIcon = { | ||
color: (theme: Theme) => theme.palette.text.normal, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
'use client' | ||
|
||
import { useParams } from 'next/navigation' | ||
import dayjs from 'dayjs' | ||
import useSWR from 'swr' | ||
import { Stack, Typography } from '@mui/material' | ||
import useAxiosWithAuth from '@/api/config' | ||
import CuCircularProgress from '@/components/CuCircularProgress' | ||
import useModal from '@/hook/useModal' | ||
import useMedia from '@/hook/useMedia' | ||
import { NoticeIcon } from '@/icons/TeamPage' | ||
import { SizeType } from '@/types/ITeamDnDLayout' | ||
import { ITeamNotice } from '@/types/TeamBoardTypes' | ||
import PreviewModal from './PreviewModal' | ||
import WidgetCard from '../WidgetCard' | ||
import * as style from './index.style' | ||
|
||
type TBoardWidgetRenderProps = Partial<{ | ||
isPc: boolean | ||
teamId: string | string[] | ||
postId: number | ||
listData: ITeamNotice[] | ||
}> | ||
|
||
interface IBoardWidgetContainerProps { | ||
modalData?: ITeamNotice[] | ||
isPc: boolean | ||
children: React.ReactNode | ||
teamId?: string | string[] | ||
} | ||
|
||
interface IBoardWidgetItemProps { | ||
title: string | ||
authorNickname: string | ||
createdAt: Date | ||
content?: string | ||
} | ||
|
||
const BoardWidget = ({ size }: { size: SizeType }) => { | ||
const { isPc } = useMedia() | ||
const { id } = useParams() | ||
const axiosWithAuth = useAxiosWithAuth() | ||
const { data, isLoading, error } = useSWR( | ||
`/api/v1/team/notice/${id}?pageSize=${8}page=${1}keyword=`, | ||
(url: string) => axiosWithAuth.get(url).then((res) => res.data), | ||
) | ||
|
||
if (isLoading) | ||
return ( | ||
<BoardWidgetContainer isPc={isPc}> | ||
<CuCircularProgress color={'secondary'} /> | ||
</BoardWidgetContainer> | ||
) | ||
if (!data || error) | ||
return ( | ||
<BoardWidgetContainer isPc={isPc}> | ||
<StatusMessage message={'글을 불러오는 중 문제가 발생했습니다.'} /> | ||
</BoardWidgetContainer> | ||
) | ||
if (!data?.content.length) | ||
return ( | ||
<BoardWidgetContainer isPc={isPc} modalData={data?.content} teamId={id}> | ||
<StatusMessage message={'등록된 글이 없습니다.'} /> | ||
</BoardWidgetContainer> | ||
) | ||
|
||
return ( | ||
<BoardWidgetContainer isPc={isPc} modalData={data.content} teamId={id}> | ||
{size === 'L' ? ( | ||
<BoardWidgetList isPc={isPc} listData={data.content} /> | ||
) : ( | ||
<BoardWidgetSingle postId={data.content[0].postId} /> | ||
)} | ||
</BoardWidgetContainer> | ||
) | ||
} | ||
|
||
const BoardWidgetContainer = ({ | ||
teamId, | ||
modalData, | ||
isPc, | ||
children, | ||
}: IBoardWidgetContainerProps) => { | ||
const { isOpen, openModal, closeModal } = useModal() | ||
|
||
return ( | ||
<> | ||
<WidgetCard | ||
onClick={modalData ? openModal : undefined} | ||
contentSx={isPc ? style.widgetContent : style.mobileWidgetContent} | ||
> | ||
<Stack spacing={isPc ? '1.5rem' : '0.5rem'}> | ||
<Stack direction={'row'} spacing={'0.25rem'}> | ||
<NoticeIcon sx={style.titleIcon} /> | ||
<Typography variant={'Title3Emphasis'}>공지사항</Typography> | ||
</Stack> | ||
{children} | ||
</Stack> | ||
</WidgetCard> | ||
{modalData && ( | ||
<PreviewModal | ||
open={isOpen} | ||
onClose={closeModal} | ||
data={modalData} | ||
teamId={teamId} | ||
/> | ||
)} | ||
</> | ||
) | ||
} | ||
|
||
const BoardWidgetList = ({ isPc, listData }: TBoardWidgetRenderProps) => { | ||
// size l | ||
return ( | ||
<Stack spacing={isPc ? '1rem' : '0,5rem'}> | ||
{listData | ||
?.slice(0, 4) | ||
.map((item) => ( | ||
<BoardWidgetItem | ||
key={item.postId} | ||
title={item.title} | ||
authorNickname={item.authorNickname} | ||
createdAt={item.createdAt} | ||
/> | ||
))} | ||
</Stack> | ||
) | ||
} | ||
|
||
const BoardWidgetSingle = ({ postId }: TBoardWidgetRenderProps) => { | ||
// size m | ||
const axiosWithAuth = useAxiosWithAuth() | ||
const { data, isLoading, error } = useSWR( | ||
`/api/v1/team/notice/${postId}`, | ||
(url: string) => axiosWithAuth.get(url).then((res) => res.data), | ||
) | ||
if (isLoading) return <CuCircularProgress color={'secondary'} /> | ||
if (!data || error) | ||
return <StatusMessage message="글을 불러오는 중 문제가 발생했습니다." /> | ||
return ( | ||
<BoardWidgetItem | ||
title={data.title} | ||
authorNickname={data.authorNickname} | ||
createdAt={data.createdAt} | ||
content={data.content} | ||
/> | ||
) | ||
} | ||
|
||
const StatusMessage = ({ message }: { message: string }) => { | ||
return ( | ||
<Typography variant={'Body2'} color={'text.alternative'}> | ||
{message} | ||
</Typography> | ||
) | ||
} | ||
|
||
const BoardWidgetItem = ({ | ||
title, | ||
authorNickname, | ||
content, | ||
createdAt, | ||
}: IBoardWidgetItemProps) => { | ||
return ( | ||
<Stack spacing={'0.25rem'}> | ||
<Typography variant={'Body1'} color={'text.normal'}> | ||
{title} | ||
</Typography> | ||
{content && ( | ||
<Typography | ||
variant={'Body2'} | ||
color={'text.alternative'} | ||
sx={{ marginBottom: '0.75rem' }} | ||
> | ||
{content} | ||
</Typography> | ||
)} | ||
<Stack direction={'row'} spacing={'0.5rem'}> | ||
<Typography variant={'Body2'} color={'text.alternative'}> | ||
{authorNickname} | ||
</Typography> | ||
<Typography variant={'Body2'} color={'text.alternative'}> | ||
{dayjs(createdAt).format('MM월 DD일')} | ||
</Typography> | ||
</Stack> | ||
</Stack> | ||
) | ||
} | ||
|
||
export default BoardWidget |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters