Skip to content

Commit 2db73aa

Browse files
authored
Merge pull request #277 from devpalsPlus/feat/#276
공지사항 ui, api 연결 (#isuue 276)
2 parents 4c6fc37 + c9cffa0 commit 2db73aa

39 files changed

+668
-42
lines changed

src/App.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { GlobalStyle } from './style/global';
44
import { defaultTheme } from './style/theme';
55
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
66
import { SearchFilteringProvider } from './context/SearchFilteringContext';
7+
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
8+
79
const queryClient = new QueryClient({
810
defaultOptions: {
911
queries: {
@@ -21,6 +23,7 @@ function App() {
2123
<GlobalStyle />
2224
<QueryClientProvider client={queryClient}>
2325
<AppRoutes />
26+
<ReactQueryDevtools initialIsOpen={false} />
2427
</QueryClientProvider>
2528
</SearchFilteringProvider>
2629
</ThemeProvider>

src/api/customerService.api.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import type { ApiFAQ, SearchKeyword } from '../models/customerService';
1+
import type {
2+
ApiFAQ,
3+
ApiNotice,
4+
ApiNoticeDetail,
5+
NoticeSearch,
6+
SearchKeyword,
7+
} from '../models/customerService';
28
import { httpClient } from './http.api';
39

410
export const getFAQ = async (params: SearchKeyword) => {
@@ -11,3 +17,25 @@ export const getFAQ = async (params: SearchKeyword) => {
1117
throw e;
1218
}
1319
};
20+
21+
export const getNotice = async (params: NoticeSearch) => {
22+
try {
23+
const response = await httpClient.get<ApiNotice>(`/notice`, { params });
24+
25+
return response.data.data;
26+
} catch (e) {
27+
console.error(e);
28+
throw e;
29+
}
30+
};
31+
32+
export const getNoticeDetail = async (id: string) => {
33+
try {
34+
const response = await httpClient.get<ApiNoticeDetail>(`/notice/${id}`);
35+
36+
return response.data.data;
37+
} catch (e) {
38+
console.error(e);
39+
throw e;
40+
}
41+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import styled from 'styled-components';
2+
3+
export const ContentBorder = styled.div`
4+
width: 100%;
5+
height: 0.5px;
6+
background: ${({ theme }) => theme.color.placeholder};
7+
`;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import * as S from './ContentBorder.styled';
2+
3+
export default function ContentBorder() {
4+
return <S.ContentBorder></S.ContentBorder>;
5+
}

src/components/home/projectCardLists/pagination/Pagination.styled.ts renamed to src/components/common/pagination/Pagination.styled.ts

File renamed without changes.

src/components/home/projectCardLists/pagination/Pagination.tsx renamed to src/components/common/pagination/Pagination.tsx

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
import React, { useEffect, useState } from 'react';
2-
import { useProjectCardListData } from '../../../../hooks/useProjectCardListData';
3-
import { useSaveSearchFiltering } from '../../../../hooks/useSaveSearchFiltering';
42
import * as S from './Pagination.styled';
53
import {
64
ChevronLeftIcon,
75
ChevronRightIcon,
86
EllipsisHorizontalIcon,
97
} from '@heroicons/react/24/outline';
108

11-
export default function Pagination() {
12-
const { projectListsData } = useProjectCardListData();
13-
const { searchFilters, handleUpdateFilters } = useSaveSearchFiltering();
14-
const lastPage = projectListsData?.lastPage;
15-
const currentPage = searchFilters.page;
9+
interface PaginationProps {
10+
page: number;
11+
getLastPage: number;
12+
onChangePagination: (page: number) => void;
13+
}
14+
15+
export default function Pagination({
16+
page,
17+
getLastPage,
18+
onChangePagination,
19+
}: PaginationProps) {
20+
const lastPage = getLastPage;
21+
const currentPage = page;
1622

1723
const calculatePageRange = () => {
1824
if (!lastPage) return;
@@ -39,22 +45,19 @@ export default function Pagination() {
3945
const target = e.target as HTMLElement;
4046
const dataId = target.dataset.id;
4147
if (!dataId) return;
42-
handleUpdateFilters('page', Number(dataId));
48+
onChangePagination(Number(dataId));
4349
};
44-
4550
return (
4651
<S.Container>
4752
<S.Wrapper onClick={handleMovePaginationClick}>
4853
{currentPage !== 1 && (
4954
<>
5055
<S.PaginationButton
51-
onClick={() => handleUpdateFilters('page', currentPage - 1)}
56+
onClick={() => onChangePagination(currentPage - 1)}
5257
>
5358
<ChevronLeftIcon />
5459
</S.PaginationButton>
55-
<S.PaginationDoubleButton
56-
onClick={() => handleUpdateFilters('page', 1)}
57-
>
60+
<S.PaginationDoubleButton onClick={() => onChangePagination(1)}>
5861
1
5962
</S.PaginationDoubleButton>
6063
<EllipsisHorizontalIcon />
@@ -74,12 +77,12 @@ export default function Pagination() {
7477
<>
7578
<EllipsisHorizontalIcon />
7679
<S.PaginationDoubleButton
77-
onClick={() => handleUpdateFilters('page', lastPage)}
80+
onClick={() => onChangePagination(lastPage)}
7881
>
7982
{lastPage}
8083
</S.PaginationDoubleButton>
8184
<S.PaginationButton
82-
onClick={() => handleUpdateFilters('page', currentPage + 1)}
85+
onClick={() => onChangePagination(currentPage + 1)}
8386
>
8487
<ChevronRightIcon />
8588
</S.PaginationButton>

src/components/customerService/faq/FAQContent.styled.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ export const ListWrapper = styled.button`
99
display: flex;
1010
justify-content: space-between;
1111
align-items: center;
12-
padding: 1.5rem 0;
12+
padding: 1.2rem 0;
1313
`;
1414

1515
export const ListTitle = styled.div`
16-
font-size: 1.3rem;
16+
font-size: 1.2rem;
1717
padding-left: 1.5rem;
1818
font-weight: bold;
1919
`;

src/components/customerService/inquiry/Inquiry.styled.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ export const CategorySelect = styled.button<{ $isCategoryOpen: boolean }>`
5050
height: 1.3rem;
5151
transition: transform 300ms ease-in-out;
5252
transform: rotate(0deg);
53-
${({ $isOpen }) =>
54-
$isOpen &&
53+
${({ $isCategoryOpen }) =>
54+
$isCategoryOpen &&
5555
css`
5656
transform: rotate(180deg);
5757
`}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import styled from 'styled-components';
2+
3+
export const Container = styled.nav`
4+
width: 100%;
5+
`;
6+
7+
export const Wrapper = styled.button`
8+
width: 100%;
9+
padding: 1rem 1.5rem;
10+
display: flex;
11+
align-items: center;
12+
justify-content: space-between;
13+
14+
&:hover {
15+
background: ${({ theme }) => theme.color.lightgrey};
16+
}
17+
`;
18+
19+
export const Title = styled.span`
20+
font-size: 1.2rem;
21+
font-weight: 700;
22+
`;
23+
24+
export const NoticeDate = styled.span`
25+
font-size: 1.1rem;
26+
color: ${({ theme }) => theme.color.placeholder};
27+
`;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import type { NoticeList as TNoticeList } from '../../../models/customerService';
2+
import { formatDate } from '../../../util/format';
3+
import * as S from './NoticeList.styled';
4+
5+
interface NoticeProps {
6+
notice: TNoticeList;
7+
}
8+
9+
export default function NoticeList({ notice }: NoticeProps) {
10+
return (
11+
<S.Container>
12+
<S.Wrapper type='button' aria-label='공지사항 상세보기'>
13+
<S.Title>{notice.title}</S.Title>
14+
<S.NoticeDate>{formatDate(notice.createdAt)}</S.NoticeDate>
15+
</S.Wrapper>
16+
</S.Container>
17+
);
18+
}

0 commit comments

Comments
 (0)