diff --git a/src/entities/home/model/types.ts b/src/entities/home/model/types.ts index 2334add..8485928 100644 --- a/src/entities/home/model/types.ts +++ b/src/entities/home/model/types.ts @@ -2,12 +2,6 @@ export interface FavoriteItemProps { img?: string, text?: string }; -export interface NoticeItemProps { - title?: string, - meta1?: string, - meta2?: string, - img?: string, -}; export interface HomeBottomBannerProps { setBottomBannerOn: (bottomBannerOn: boolean) => void; bottomBannerOn: boolean; diff --git a/src/entities/home/ui/home-notice-item.tsx b/src/entities/home/ui/home-notice-item.tsx index 59e00a2..7a0d437 100644 --- a/src/entities/home/ui/home-notice-item.tsx +++ b/src/entities/home/ui/home-notice-item.tsx @@ -1,31 +1,41 @@ +import { NoticeItemProps } from '@/entities/support/model/types'; +import { IMAGE_ROOT } from '@/shared/constants/common'; import { PATHS } from '@/shared/constants/paths'; import { useNavigate } from '@/shared/lib/hooks/use-navigate'; -import { NoticeItemProps } from '../model/types'; +import moment from 'moment'; export const HomeNoticeItem = ({ + id, title, - meta1, - meta2, - img + category, + regDate, + isNew }: NoticeItemProps) => { const { navigate } = useNavigate(); - const onClickToNavigate = (path: string) => { - navigate(path + '14'); + const onClickToDetail = () => { + navigate(PATHS.support.notice.detail, { + state: { + id: id + } + }) }; return ( <> -
+
onClickToDetail() } + >
{ title }
-
{ meta1}{ meta2 }
+
{ category}{ moment(regDate).format('YY년 MM월 DD일') }
-
onClickToNavigate(PATHS.support.notice.detail) } - > - 공지사항 바로가기 +
+ 공지사항 바로가기
diff --git a/src/entities/home/ui/home-notice-list.tsx b/src/entities/home/ui/home-notice-list.tsx index 262e395..6ad65b5 100644 --- a/src/entities/home/ui/home-notice-list.tsx +++ b/src/entities/home/ui/home-notice-list.tsx @@ -1,58 +1,51 @@ -/* eslint-disable @cspell/spellchecker */ -import { IMAGE_ROOT } from '@/shared/constants/common'; +import { useEffect, useState } from 'react'; +import { useNoticeListMutation } from '@/entities/support/api/use-notice-list-mutation'; +import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constants'; +import { NoticeItem } from '@/entities/support/model/types'; import { HomeNoticeItem } from './home-notice-item'; export const HomeNoticeList = () => { - const items = [ - { - title: '시스템 안정화를 위한 정기 점검이 예정되어 있습니다.', - meta1: '공지사항', - meta2: '25년 5월 23일', - img: IMAGE_ROOT + '/Forward.svg' - }, - { - title: '가맹점 관리 메뉴에 거래내역 엑셀 다운로드 기능이 추가 되었습니다.', - meta1: '공지사항', - meta2: '25년 5월 23일', - img: IMAGE_ROOT + '/Forward.svg' - }, - { - title: '신규 가맹점을 대상으로 거래수수료 인하 혜택을 12월까지 제공합니다.', - meta1: '공지사항', - meta2: '25년 5월 23일', - img: IMAGE_ROOT + '/Forward.svg' - }, - { - title: '앱의 안정성과 사용성을 개선한 버전 2.3.1이 출시되었습니다.', - meta1: '공지사항', - meta2: '25년 5월 23일', - img: IMAGE_ROOT + '/Forward.svg' - }, - { - title: '점검 시간 동안 일부 서비스 이용이 제한될 수 있으니 미리 확인해주세요.', - meta1: '공지사항', - meta2: '25년 5월 23일', - img: IMAGE_ROOT + '/Forward.svg' - }, - ]; + + const [pageParam, setPageParam] = useState(DEFAULT_PAGE_PARAM); + const [resultList, setResultList] = useState>([]); + + const { mutateAsync: noticeList } = useNoticeListMutation(); const getItems = () => { let rs = []; - for(let i=0;i ); } return rs; }; + const callList = () => { + let listParams = { + category: 'ALL', + searchKeyword: '', + ...{page: pageParam} + }; + + noticeList(listParams).then((rs) => { + console.log(rs) + setResultList(rs.content); + }); + }; + + useEffect(() => { + callList(); + }, []); + return ( <>
diff --git a/src/entities/support/api/use-notice-detail-mutaion.ts b/src/entities/support/api/use-notice-detail-mutaion.ts new file mode 100644 index 0000000..5b48d7b --- /dev/null +++ b/src/entities/support/api/use-notice-detail-mutaion.ts @@ -0,0 +1,29 @@ +import axios from 'axios'; +import { API_URL } from '@/shared/api/urls'; +import { resultify } from '@/shared/lib/resultify'; +import { CBDCAxiosError } from '@/shared/@types/error'; +import { + NoticeDetailParams, + NoticeDetailResponse +} from '../model/types'; +import { + useMutation, + UseMutationOptions +} from '@tanstack/react-query'; + +export const noticeDetail = (params: NoticeDetailParams) => { + return resultify( + axios.post(API_URL.noticeDetail(), params), + ); +}; + +export const useNoticeDetailMutation = (options?: UseMutationOptions) => { + const mutation = useMutation({ + ...options, + mutationFn: (params: NoticeDetailParams) => noticeDetail(params), + }); + + return { + ...mutation, + }; +}; diff --git a/src/entities/support/api/use-notice-list-mutation.ts b/src/entities/support/api/use-notice-list-mutation.ts new file mode 100644 index 0000000..a814b4d --- /dev/null +++ b/src/entities/support/api/use-notice-list-mutation.ts @@ -0,0 +1,29 @@ +import axios from 'axios'; +import { API_URL } from '@/shared/api/urls'; +import { resultify } from '@/shared/lib/resultify'; +import { CBDCAxiosError } from '@/shared/@types/error'; +import { + NoticeListParams, + NoticeListResponse +} from '../model/types'; +import { + useMutation, + UseMutationOptions +} from '@tanstack/react-query'; + +export const noticeList = (params: NoticeListParams) => { + return resultify( + axios.post(API_URL.noticeList(), params), + ); +}; + +export const useNoticeListMutation = (options?: UseMutationOptions) => { + const mutation = useMutation({ + ...options, + mutationFn: (params: NoticeListParams) => noticeList(params), + }); + + return { + ...mutation, + }; +}; diff --git a/src/entities/support/model/types.ts b/src/entities/support/model/types.ts index ee9b57c..9c31efe 100644 --- a/src/entities/support/model/types.ts +++ b/src/entities/support/model/types.ts @@ -54,4 +54,32 @@ export interface QnaSaveParams extends SupportParams { }; export interface QnaSaveResponse { -}; \ No newline at end of file +}; +export interface NoticeListParams extends SupportParams { + searchKeyword: string; + category: string; + pagination?: DefaultRequestPagination; +}; +export interface NoticeItem { + id?: number; + title?: string; + content?: string; + category?: string; + regDate?: string; + isNew?: boolean; + viewCount?: number; +}; +export interface NoticeListResponse { + content: Array; + nextCursor: string; + hasNext: boolean; +}; +export interface NoticeDetailParams { + noticeId: number; +}; +export interface NoticeDetailResponse extends NoticeItem { + +}; +export interface NoticeItemProps extends NoticeItem { + +} \ No newline at end of file diff --git a/src/entities/support/ui/notice-item.tsx b/src/entities/support/ui/notice-item.tsx new file mode 100644 index 0000000..801ecba --- /dev/null +++ b/src/entities/support/ui/notice-item.tsx @@ -0,0 +1,38 @@ +import { PATHS } from '@/shared/constants/paths'; +import { useNavigate } from '@/shared/lib/hooks/use-navigate'; +import { NoticeItemProps } from '../model/types'; +import moment from 'moment'; + +export const SupportNoticeItem = ({ + id, + title, + category, + regDate, + isNew +}: NoticeItemProps) => { + const { navigate } = useNavigate(); + + const onClickToDetail = () => { + navigate(PATHS.support.notice.detail, { + state: { + id: id + } + }) + }; + + return ( + <> +
onClickToDetail() } + > +
+
{ title }
+
+ { category }{ moment(regDate).format('YYYY.MM.DD HH:mm:ss') } +
+
+
+ + ); +}; \ No newline at end of file diff --git a/src/pages/home/home-page.tsx b/src/pages/home/home-page.tsx index 418ce80..060cd03 100644 --- a/src/pages/home/home-page.tsx +++ b/src/pages/home/home-page.tsx @@ -1,3 +1,4 @@ +import moment from 'moment'; import { useCallback, useEffect, useState } from 'react'; import { getLocalStorage } from '@/shared/lib'; import { StorageKeys } from '@/shared/constants/local-storage'; @@ -14,22 +15,22 @@ import { useSetFooterMode, useSetFooterCurrentPage } from '@/widgets/sub-layout/use-sub-layout'; -import moment from 'moment'; export const HomePage = () => { + const { callLogin } = useUserInfo(); + useSetHeaderTitle(''); useSetHeaderType(HeaderType.Home); useSetFooterMode(true); useSetFooterCurrentPage(FooterItemActiveKey.Home); - const { callLogin } = useUserInfo(); - const today = moment().format('YYYYMMDD').toString(); let bannerToday = getLocalStorage(StorageKeys.BottomBannerClose); const [bottomBannerOn, setBottomBannerOn] = useState(false); const [authRegisterOn, setAuthRegisterOn] = useState(false); - + const [loginSuccess, setLoginSuccess] = useState(false); + /* const userParmas = { id: 'thenaun12', @@ -43,8 +44,11 @@ export const HomePage = () => { }; const handleLogin = useCallback(async () =>{ - await callLogin(userParmas); + callLogin(userParmas).then(() => { + setLoginSuccess(true); + }); }, []); + const checkBottomBannerOpen = () => { if(!!bannerToday){ bannerToday = bannerToday.toString(); @@ -90,7 +94,9 @@ export const HomePage = () => {
- + { !!loginSuccess && + + }
diff --git a/src/pages/support/notice/detail-page.tsx b/src/pages/support/notice/detail-page.tsx index 7c6ff39..4b9f5df 100644 --- a/src/pages/support/notice/detail-page.tsx +++ b/src/pages/support/notice/detail-page.tsx @@ -1,14 +1,47 @@ +import { useEffect, useState } from 'react'; +import { useLocation } from 'react-router'; +import { PATHS } from '@/shared/constants/paths'; +import { useNoticeDetailMutation } from '@/entities/support/api/use-notice-detail-mutaion'; +import { useNavigate } from '@/shared/lib/hooks/use-navigate'; import { HeaderType } from '@/entities/common/model/types'; +import { NoticeItem } from '@/entities/support/model/types'; import { useSetHeaderTitle, useSetHeaderType, - useSetFooterMode + useSetFooterMode, + useSetOnBack } from '@/widgets/sub-layout/use-sub-layout'; +import moment from 'moment'; export const NoticeDetailPage = () => { + const { navigate } = useNavigate(); + const location = useLocation(); + + const [result, setResult] = useState({}); + useSetHeaderTitle('공지사항'); useSetHeaderType(HeaderType.RightClose); useSetFooterMode(false); + useSetOnBack(() => { + navigate(PATHS.support.notice.list); + }); + + const { mutateAsync: noticeDetail } = useNoticeDetailMutation(); + + const callDetail = () => { + let detailParams = { + noticeId: location?.state.id, + }; + + noticeDetail(detailParams).then((rs) => { + console.log(rs); + setResult(rs); + }); + }; + + useEffect(() => { + callDetail(); + }, []); return ( <> @@ -17,27 +50,10 @@ export const NoticeDetailPage = () => {
-
[관리비 출금] 5월 관리비(4월 사용료) 출금일 변경(정정)
-
2025.08.19 | 카테고리
+
{ result.title }
+
{ moment(result.regDate).format('YYYY.MM.DD') } | { result.category }
-
안녕하세요. 페이앳 관리자입니다. - - ‘25년 5월 페이앳 관리비(4월 사용료)출금일자 변경을 다음과 같이 공지드립니다. - - 관리비 청구 데이터 확정 지연으로 부득이하게 금번 5월 페이앳 관리비 출금일자가 아래와 같이 변경되어 출금될 예정입니다. - - 서비스 운영에 참고하시기 바라며, 서비스 이용에 불편드려 죄송합니다. - - ----------- 다음 ----------- - - 기존 : 매월 15일(영업일 기준)/*5월 출금일 : 19일(월) - - 변경 : 5월 19일(월) - - 세금계산서 발행일 : 5월 19일(*19일 출금분에 한함) - - ----------------------------- -
+
{ result.content }
diff --git a/src/pages/support/notice/list-page.tsx b/src/pages/support/notice/list-page.tsx index 6faa8a4..66b81bb 100644 --- a/src/pages/support/notice/list-page.tsx +++ b/src/pages/support/notice/list-page.tsx @@ -1,5 +1,10 @@ +import { ChangeEvent, useEffect, useState } from 'react'; import { PATHS } from '@/shared/constants/paths'; import { useNavigate } from '@/shared/lib/hooks/use-navigate'; +import { useNoticeListMutation } from '@/entities/support/api/use-notice-list-mutation'; +import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constants'; +import { NoticeItem } from '@/entities/support/model/types'; +import { SupportNoticeItem } from '@/entities/support/ui/notice-item'; import { HeaderType } from '@/entities/common/model/types'; import { useSetHeaderTitle, @@ -11,12 +16,57 @@ import { export const NoticeListPage = () => { const { navigate } = useNavigate(); + const [pageParam, setPageParam] = useState(DEFAULT_PAGE_PARAM); + const [searchKeyword, setSearchKeyword] = useState(''); + const [resultList, setResultList] = useState>([]); + useSetHeaderTitle('공지사항'); useSetHeaderType(HeaderType.LeftArrow); useSetFooterMode(true); useSetOnBack(() => { navigate(PATHS.home); }); + + const { mutateAsync: noticeList } = useNoticeListMutation(); + const callList = () => { + let listParams = { + category: 'ALL', + searchKeyword: searchKeyword, + ...{page: pageParam} + }; + + noticeList(listParams).then((rs) => { + console.log(rs) + setResultList(rs.content); + }); + }; + + const onClickToAction = () => { + callList(); + }; + + const getNoticeList = () => { + let rs = []; + for(let i=0;i + ) + } + return rs; + }; + + useEffect(() => { + callList(); + }, []); + + return ( <>
@@ -25,8 +75,17 @@ export const NoticeListPage = () => {
- - + + ) => setSearchKeyword(e.target.value) } + />