-
Notifications
You must be signed in to change notification settings - Fork 0
공지사항 ui, api 연결 (#isuue 276) #277
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
Changes from 5 commits
664778d
bfa66e0
829c70a
18490c3
71068ce
e9a730f
c9cffa0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| import styled from 'styled-components'; | ||
|
|
||
| export const Container = styled.nav` | ||
| width: 100%; | ||
| `; | ||
|
|
||
| export const Wrapper = styled.button` | ||
| width: 100%; | ||
| padding: 1rem 1.5rem; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
|
|
||
| &:hover { | ||
| background: ${({ theme }) => theme.color.lightgrey}; | ||
| } | ||
| `; | ||
|
|
||
| export const Title = styled.span` | ||
| font-size: 1.2rem; | ||
| font-weight: 700; | ||
| `; | ||
|
|
||
| export const NoticeDate = styled.span` | ||
| font-size: 1.1rem; | ||
| `; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import type { NoticeList as TNoticeList } from '../../../models/customerService'; | ||
| import { formatDate } from '../../../util/format'; | ||
| import * as S from './NoticeList.styled'; | ||
|
|
||
| interface NoticeProps { | ||
| notice: TNoticeList; | ||
| } | ||
|
|
||
| export default function NoticeList({ notice }: NoticeProps) { | ||
| return ( | ||
| <S.Container> | ||
| <S.Wrapper type='button' aria-label='공지사항 상세보기'> | ||
| <S.Title>{notice.title}</S.Title> | ||
| <S.NoticeDate>{formatDate(notice.createdAt)}</S.NoticeDate> | ||
| </S.Wrapper> | ||
| </S.Container> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| import styled from 'styled-components'; | ||
|
|
||
| export const SpinnerWrapper = styled.div` | ||
| height: 60vh; | ||
| `; | ||
|
|
||
| export const Container = styled.section` | ||
| width: 75%; | ||
| margin: 0 auto; | ||
| margin-bottom: 2rem; | ||
| `; |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,59 @@ | ||||||||||||||||||||||||||||||||||||||||||||
| import { useLocation, useParams } from 'react-router-dom'; | ||||||||||||||||||||||||||||||||||||||||||||
| import { useGetNoticeDetail } from '../../../hooks/useGetNoticeDetail'; | ||||||||||||||||||||||||||||||||||||||||||||
| import * as S from './NoticeDetailBundle.styled'; | ||||||||||||||||||||||||||||||||||||||||||||
| import NoticeDetailBottom from './bottom/NoticeDetailBottom'; | ||||||||||||||||||||||||||||||||||||||||||||
| import NoticeDetailContent from './content/NoticeDetailContent'; | ||||||||||||||||||||||||||||||||||||||||||||
| import NoticeDetailHeader from './header/NoticeDetailHeader'; | ||||||||||||||||||||||||||||||||||||||||||||
| import Spinner from '../../mypage/Spinner'; | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| export default function NoticeDetailBundle() { | ||||||||||||||||||||||||||||||||||||||||||||
| const location = useLocation(); | ||||||||||||||||||||||||||||||||||||||||||||
| const { noticeId } = useParams(); | ||||||||||||||||||||||||||||||||||||||||||||
| const id = noticeId || String(location.state.id); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| const { noticeDetail: noticeDetailData, isLoading } = useGetNoticeDetail(id); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| if (isLoading) { | ||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||
| <S.SpinnerWrapper> | ||||||||||||||||||||||||||||||||||||||||||||
| <Spinner /> | ||||||||||||||||||||||||||||||||||||||||||||
| </S.SpinnerWrapper> | ||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| if (!noticeDetailData) { | ||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||
| <NoticeDetailContent | ||||||||||||||||||||||||||||||||||||||||||||
| id={0} | ||||||||||||||||||||||||||||||||||||||||||||
| title='공지사항ID가 없습니다.' | ||||||||||||||||||||||||||||||||||||||||||||
| content='목록으로 돌아가세요.' | ||||||||||||||||||||||||||||||||||||||||||||
| createdAt='' | ||||||||||||||||||||||||||||||||||||||||||||
| viewCount={0} | ||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 데이터가 없을 때 사용자 친화적인 UI 제공 필요 현재 코드에서는 데이터가 없을 때 '공지사항ID가 없습니다'라는 메시지를 표시하는데, 이는 사용자에게 기술적인 정보를 노출하고 있습니다. 더 친화적인 UI와 함께 목록으로 돌아갈 수 있는 버튼을 제공하는 것이 좋습니다. if (!noticeDetailData) {
return (
- <NoticeDetailContent
- id={0}
- title='공지사항ID가 없습니다.'
- content='목록으로 돌아가세요.'
- createdAt=''
- viewCount={0}
- />
+ <S.ErrorWrapper>
+ <p>해당 공지사항을 찾을 수 없습니다.</p>
+ <S.BackLink to="/customer-service/notice">공지사항 목록으로 돌아가기</S.BackLink>
+ </S.ErrorWrapper>
);
}
📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| const { | ||||||||||||||||||||||||||||||||||||||||||||
| id: detailId, | ||||||||||||||||||||||||||||||||||||||||||||
| title, | ||||||||||||||||||||||||||||||||||||||||||||
| content, | ||||||||||||||||||||||||||||||||||||||||||||
| createdAt, | ||||||||||||||||||||||||||||||||||||||||||||
| viewCount, | ||||||||||||||||||||||||||||||||||||||||||||
| prev, | ||||||||||||||||||||||||||||||||||||||||||||
| next, | ||||||||||||||||||||||||||||||||||||||||||||
| } = noticeDetailData; | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||
| <S.Container> | ||||||||||||||||||||||||||||||||||||||||||||
| <NoticeDetailHeader /> | ||||||||||||||||||||||||||||||||||||||||||||
| <NoticeDetailContent | ||||||||||||||||||||||||||||||||||||||||||||
| id={detailId} | ||||||||||||||||||||||||||||||||||||||||||||
| title={title} | ||||||||||||||||||||||||||||||||||||||||||||
| content={content} | ||||||||||||||||||||||||||||||||||||||||||||
| createdAt={createdAt} | ||||||||||||||||||||||||||||||||||||||||||||
| viewCount={viewCount} | ||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||
| <NoticeDetailBottom prev={prev} next={next} /> | ||||||||||||||||||||||||||||||||||||||||||||
| </S.Container> | ||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| import { Link } from 'react-router-dom'; | ||
| import styled from 'styled-components'; | ||
|
|
||
| export const Container = styled.nav``; | ||
|
|
||
| export const NotOtherNotice = styled.div` | ||
| padding: 0.5rem 1rem; | ||
| font-size: 0.9rem; | ||
| `; | ||
|
|
||
| export const ListWrapper = styled.div` | ||
| width: 100%; | ||
| display: flex; | ||
| justify-content: center; | ||
| margin-top: 1.5rem; | ||
| `; | ||
|
|
||
| export const ListLink = styled(Link)` | ||
| display: flex; | ||
| justify-content: center; | ||
| align-items: center; | ||
| font-size: 0.9rem; | ||
| background: ${({ theme }) => theme.color.navy}; | ||
| border-radius: ${({ theme }) => theme.borderRadius.large}; | ||
| color: ${({ theme }) => theme.color.white}; | ||
| border: 1px solid ${({ theme }) => theme.color.navy}; | ||
| padding: 0.5rem 1rem; | ||
|
|
||
| &:hover { | ||
| background: ${({ theme }) => theme.color.lightgrey}; | ||
| color: ${({ theme }) => theme.color.navy}; | ||
| border: 1px solid ${({ theme }) => theme.color.navy}; | ||
| transition: all 0.3s ease-in-out; | ||
| } | ||
| `; | ||
|
|
||
| export const ListTitle = styled.span``; | ||
|
|
||
| export const ContentBorder = styled.div` | ||
| width: 100%; | ||
| height: 0.5px; | ||
| background: ${({ theme }) => theme.color.placeholder}; | ||
| position: relative; | ||
| z-index: 1; | ||
| `; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| import { ROUTES } from '../../../../constants/routes'; | ||
| import type { OtherNotice } from '../../../../models/customerService'; | ||
| import OtherNoticeButton from './button/OtherNoticeButton'; | ||
| import * as S from './NoticeDetailBottom.styled'; | ||
|
|
||
| interface NoticeDetailBottomProps { | ||
| prev: OtherNotice | null; | ||
| next: OtherNotice | null; | ||
| } | ||
|
|
||
| export default function NoticeDetailBottom({ | ||
| prev, | ||
| next, | ||
| }: NoticeDetailBottomProps) { | ||
| return ( | ||
| <S.Container> | ||
| <S.ContentBorder></S.ContentBorder> | ||
| {prev !== null ? ( | ||
| <OtherNoticeButton | ||
| navigation='이전' | ||
| id={prev.id} | ||
| title={prev.title} | ||
| createdAt={prev.createdAt} | ||
YouD0313 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| /> | ||
| ) : ( | ||
| <S.NotOtherNotice>이전 공지사항이 없습니다.</S.NotOtherNotice> | ||
| )} | ||
| <S.ContentBorder></S.ContentBorder> | ||
| {next !== null ? ( | ||
| <OtherNoticeButton | ||
| navigation='다음' | ||
| id={next.id} | ||
| title={next.title} | ||
| createdAt={next.createdAt} | ||
YouD0313 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| /> | ||
| ) : ( | ||
| <S.NotOtherNotice>다음 공지사항이 없습니다.</S.NotOtherNotice> | ||
| )} | ||
| <S.ContentBorder></S.ContentBorder> | ||
| <S.ListWrapper> | ||
| <S.ListLink to={`${ROUTES.customerService}/${ROUTES.notice}`}> | ||
| <S.ListTitle>목록</S.ListTitle> | ||
| </S.ListLink> | ||
| </S.ListWrapper> | ||
| </S.Container> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import { Link } from 'react-router-dom'; | ||
| import styled from 'styled-components'; | ||
|
|
||
| export const OtherNoticeLink = styled(Link)` | ||
| width: 100%; | ||
| display: flex; | ||
| padding: 0.5rem 1rem; | ||
| justify-content: space-between; | ||
| align-items: center; | ||
| font-size: 0.9rem; | ||
|
|
||
| &:hover { | ||
| background: ${({ theme }) => theme.color.lightgrey}; | ||
| } | ||
| `; | ||
|
|
||
| export const OtherNoticeWrapper = styled.div` | ||
| display: flex; | ||
| gap: 1rem; | ||
| `; | ||
|
|
||
| export const OtherNotice = styled.span` | ||
| font-weight: 600; | ||
| `; | ||
|
|
||
| export const OtherNoticeTitle = styled.span``; | ||
|
|
||
| export const OtherNoticeDate = styled.span` | ||
| font-size: 0.8rem; | ||
| color: ${({ theme }) => theme.color.placeholder}; | ||
| `; |
Uh oh!
There was an error while loading. Please reload this page.