공지사항 /홈 / 리스트 / 상세

This commit is contained in:
focp212@naver.com
2025-09-09 13:48:16 +09:00
parent 3cfc45a244
commit b760a69fef
12 changed files with 304 additions and 185 deletions

View File

@@ -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;

View File

@@ -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 (
<>
<div className="notice-item">
<div
className="notice-item"
onClick={ () => onClickToDetail() }
>
<div className="notice-content">
<div className="notice-title">{ title }</div>
<div className="notice-meta">{ meta1}<span>{ meta2 }</span></div>
<div className="notice-meta">{ category}<span>{ moment(regDate).format('YY년 MM월 DD일') }</span></div>
</div>
<div
className="notice-arrow"
onClick={ () => onClickToNavigate(PATHS.support.notice.detail) }
>
<img src={ img } alt="공지사항 바로가기" />
<div className="notice-arrow">
<img
src={ IMAGE_ROOT + '/Forward.svg' }
alt="공지사항 바로가기"
/>
</div>
</div>
</>

View File

@@ -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<Array<NoticeItem>>([]);
const { mutateAsync: noticeList } = useNoticeListMutation();
const getItems = () => {
let rs = [];
for(let i=0;i<items.length;i++){
let key = 'notice-key-'+i;
let maxCnt = (resultList.length < 5)? resultList.length: 5;
for(let i=0;i<maxCnt;i++){
rs.push(
<HomeNoticeItem
key={ key }
title={ items[i]?.title }
meta1={ items[i]?.meta1 }
meta2={ items[i]?.meta2 }
img={ items[i]?.img }
key={ `key-home-notice-item-${i}` }
id={ resultList[i]?.id }
title={ resultList[i]?.title }
category={ resultList[i]?.category }
regDate={ resultList[i]?.regDate }
isNew={ resultList[i]?.isNew }
></HomeNoticeItem>
);
}
return rs;
};
const callList = () => {
let listParams = {
category: 'ALL',
searchKeyword: '',
...{page: pageParam}
};
noticeList(listParams).then((rs) => {
console.log(rs)
setResultList(rs.content);
});
};
useEffect(() => {
callList();
}, []);
return (
<>
<div className="notice-list">

View File

@@ -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<NoticeDetailResponse>(API_URL.noticeDetail(), params),
);
};
export const useNoticeDetailMutation = (options?: UseMutationOptions<NoticeDetailResponse, CBDCAxiosError, NoticeDetailParams>) => {
const mutation = useMutation<NoticeDetailResponse, CBDCAxiosError, NoticeDetailParams>({
...options,
mutationFn: (params: NoticeDetailParams) => noticeDetail(params),
});
return {
...mutation,
};
};

View File

@@ -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<NoticeListResponse>(API_URL.noticeList(), params),
);
};
export const useNoticeListMutation = (options?: UseMutationOptions<NoticeListResponse, CBDCAxiosError, NoticeListParams>) => {
const mutation = useMutation<NoticeListResponse, CBDCAxiosError, NoticeListParams>({
...options,
mutationFn: (params: NoticeListParams) => noticeList(params),
});
return {
...mutation,
};
};

View File

@@ -54,4 +54,32 @@ export interface QnaSaveParams extends SupportParams {
};
export interface QnaSaveResponse {
};
};
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<NoticeItem>;
nextCursor: string;
hasNext: boolean;
};
export interface NoticeDetailParams {
noticeId: number;
};
export interface NoticeDetailResponse extends NoticeItem {
};
export interface NoticeItemProps extends NoticeItem {
}

View File

@@ -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 (
<>
<div
className="notice-row-114"
onClick={ () => onClickToDetail() }
>
<div className="notice-txt">
<div className="notice-title-114">{ title }</div>
<div className="notice-meta-114">
<span className="blue">{ category }</span> <span>{ moment(regDate).format('YYYY.MM.DD HH:mm:ss') }</span>
</div>
</div>
</div>
</>
);
};