diff --git a/src/apis/apiClient.ts b/src/apis/apiClient.ts index 34d710e..c232385 100644 --- a/src/apis/apiClient.ts +++ b/src/apis/apiClient.ts @@ -2,12 +2,9 @@ import axios, { AxiosInstance } from 'axios'; import { API_BASE_URL } from './url'; import { getCookie } from '../utils/cookie'; import { userApi } from './interfaces/userApi'; -import { LoginType, PointType } from '../types/user'; -import { AccountType, CheckPwReqType, CheckPwResType } from '../types/account'; import { accountApi } from './interfaces/accountApi'; import { hostApi } from './interfaces/hostApi'; import { categoryApi } from './interfaces/categoryApi'; -import { SearchLessonReqType, SearchLessonResType } from '../types/category'; import { CreateHostReqType, CreateHostResType, @@ -76,12 +73,13 @@ export class ApiClient } // ------- host ------- - async getSearchLessonAll(reqData: SearchLessonReqType) { + async postCreateHost(reqData: CreateHostReqType) { const response = await this.axiosInstance.request< - BaseResponseType + BaseResponseType >({ - method: 'get', - url: `/category/all?query=${reqData.query}&sort=${reqData.sort}`, + method: 'post', + url: '/host/create', + data: reqData, }); return response.data; } @@ -102,13 +100,35 @@ export class ApiClient } // ------- category ------- - async postCreateHost(reqData: CreateHostReqType) { + async getSearchLessonAll(reqData: SearchLessonReqType) { const response = await this.axiosInstance.request< - BaseResponseType + BaseResponseType >({ - method: 'post', - url: '/host/create', - data: reqData, + method: 'get', + url: `/category/all?query=${reqData.query}&sort=${reqData.sort}`, + }); + return response.data; + } + + async getSearchLessonCategory( + categoryId: number, + reqData: SearchLessonReqType + ) { + const response = await this.axiosInstance.request< + BaseResponseType + >({ + method: 'get', + url: `/category/${categoryId}?query=${reqData.query}&sort=${reqData.sort}`, + }); + return response.data; + } + + async getCategoryList() { + const response = await this.axiosInstance.request< + BaseResponseType + >({ + method: 'get', + url: '/category', }); return response.data; } @@ -133,9 +153,7 @@ export class ApiClient //---------transaction--------- async postQrPay(reqData: QrPayReqType) { const response = await this.axiosInstance.request< - BaseResponseType<{ - transactionId: number; - }> + BaseResponseType >({ method: 'post', url: '/transaction/qr', @@ -144,6 +162,21 @@ export class ApiClient return response.data; } + async postSimplePay(reqData: SimplePayReqType) { + try { + const response = await this.axiosInstance.request< + BaseResponseType + >({ + method: 'post', + url: '/transaction/simple', + data: reqData, + }); + return response.data; + } catch (error: any) { + if (axios.isAxiosError(error)) throw error.response?.data; + else throw new Error('unexpected error'); + } + } // 환불 async postPayback(reqData: PaybackReqType) { const response = await this.axiosInstance.request< @@ -170,7 +203,16 @@ export class ApiClient method: 'get', url: `/lesson/${lesson_id}`, }); - console.log(lesson_id); + return response.data; + } + + async getLessonDate(lessonId: number) { + const response = await this.axiosInstance.request< + BaseResponseType + >({ + method: 'get', + url: `/lesson/date-select?lessonId=${lessonId}`, + }); return response.data; } @@ -245,6 +287,18 @@ export class ApiClient return response.data; } + async postLessonReservation(reqData: ReservationReqType) { + const response = await this.axiosInstance.request< + BaseResponseType<{ message: string }> + >({ + method: 'post', + url: '/reservation/check', + data: reqData, + }); + return response.data; + } + + //---------revenue--------- // 예약자 정보 async peopleList(lessondateId: PeopleListReqType) { console.log('전달된 lessondate_id: ', lessondateId); diff --git a/src/apis/interfaces/accountApi.ts b/src/apis/interfaces/accountApi.ts index 4affd66..e41d5e1 100644 --- a/src/apis/interfaces/accountApi.ts +++ b/src/apis/interfaces/accountApi.ts @@ -1,9 +1,3 @@ -import { - AccountType, - CheckPwReqType, - CheckPwResType, -} from '../../types/account'; - export interface accountApi { getAccountList(): Promise>; postCheckPw( diff --git a/src/apis/interfaces/categoryApi.ts b/src/apis/interfaces/categoryApi.ts index 83eb60b..6ed7df2 100644 --- a/src/apis/interfaces/categoryApi.ts +++ b/src/apis/interfaces/categoryApi.ts @@ -1,7 +1,10 @@ -import { SearchLessonReqType, SearchLessonResType } from '../../types/category'; - export interface categoryApi { getSearchLessonAll( reqData: SearchLessonReqType ): Promise>; + getSearchLessonCategory( + categoryId: number, + reqData: SearchLessonReqType + ): Promise>; + getCategoryList(): Promise>; } diff --git a/src/apis/interfaces/lessonApi.ts b/src/apis/interfaces/lessonApi.ts index 4cf82ad..e427436 100644 --- a/src/apis/interfaces/lessonApi.ts +++ b/src/apis/interfaces/lessonApi.ts @@ -2,4 +2,5 @@ export interface lessonApi { getLessonDetail( lesson_id: number ): Promise>; + getLessonDate(lessonId: number): Promise>; } diff --git a/src/apis/interfaces/reservationApi.ts b/src/apis/interfaces/reservationApi.ts index 7c51aa9..e967597 100644 --- a/src/apis/interfaces/reservationApi.ts +++ b/src/apis/interfaces/reservationApi.ts @@ -5,6 +5,11 @@ export interface reservationApi { lesson_id: number ): Promise>; + postLessonReservation(reqData: ReservationReqType): Promise< + BaseResponseType<{ + reservationId: number; + }> + >; getMyLesson(): Promise>; getMyLessonAll(): Promise>; diff --git a/src/apis/interfaces/transactionApi.ts b/src/apis/interfaces/transactionApi.ts index 1ad8a91..6a54802 100644 --- a/src/apis/interfaces/transactionApi.ts +++ b/src/apis/interfaces/transactionApi.ts @@ -1,11 +1,11 @@ import { PaybackReqType, QrPayReqType } from '../../types/transaction'; export interface transactionApi { - postQrPay(reqData: QrPayReqType): Promise< - BaseResponseType<{ - transactionId: number; - }> - >; + postQrPay(reqData: QrPayReqType): Promise>; + + postSimplePay( + reqData: SimplePayReqType + ): Promise>; postPayback( reqData: PaybackReqType diff --git a/src/apis/interfaces/userApi.ts b/src/apis/interfaces/userApi.ts index 31e80f1..43afae2 100644 --- a/src/apis/interfaces/userApi.ts +++ b/src/apis/interfaces/userApi.ts @@ -1,5 +1,3 @@ -import { LoginType } from '../../types/user'; - export interface userApi { postLogin(password: string): Promise>; getIsHost(): Promise>; diff --git a/src/components/molecules/LessonDateChoice.tsx b/src/components/molecules/LessonDateChoice.tsx index c6c43c0..c6e35b1 100644 --- a/src/components/molecules/LessonDateChoice.tsx +++ b/src/components/molecules/LessonDateChoice.tsx @@ -3,22 +3,14 @@ import { AiOutlineClose } from 'react-icons/ai'; import { LuMinus, LuPlus } from 'react-icons/lu'; import { formatDate } from '../../utils/formatDate'; import { Button } from '../common/Button'; -import { useLocation, useNavigate, useParams } from 'react-router-dom'; +import { useNavigate } from 'react-router-dom'; interface IProps { - dateList: DateListType[]; + dateList: LessonDateType[]; price: number; } -type DateListType = { - lessondate_id: number; - date: string; - start_time: string; - end_time: string; - quantityLeft: number; -}; export const LessonDateChoice: FC = ({ dateList, price }) => { - const { lessonId } = useParams(); const navigate = useNavigate(); const [choiceDate, setChoiceDate] = useState<{ lessondate_id: number; @@ -72,19 +64,27 @@ export const LessonDateChoice: FC = ({ dateList, price }) => { {' '}
{dateList.map((date, index) => ( -
+
clickedChoiceDate( - date.lessondate_id, - formatDate(date.date, date.start_time, date.end_time), + date.lessondateId, + formatDate( + '' + date.date, + '' + date.startTime, + '' + date.endTime + ), date.quantityLeft ) } >

- {formatDate(date.date, date.start_time, date.end_time)} + {formatDate( + '' + date.date, + '' + date.startTime, + '' + date.endTime + )}

{price.toLocaleString()}원 @@ -144,7 +144,6 @@ export const LessonDateChoice: FC = ({ dateList, price }) => { navigate('/pay', { state: { payment: count * price, - lessonId: lessonId, lessondate_id: choiceDate?.lessondate_id || 0, count: count, }, diff --git a/src/components/molecules/LessonSearchCard.tsx b/src/components/molecules/LessonSearchCard.tsx index 34faa51..4405ff1 100644 --- a/src/components/molecules/LessonSearchCard.tsx +++ b/src/components/molecules/LessonSearchCard.tsx @@ -1,16 +1,8 @@ import { FC } from 'react'; import { useNavigate } from 'react-router-dom'; -type LessonSearchType = { - lesson_id: number; - image: string; - title: string; - price: number; - host_name: string; -}; - interface IProps { - lesson: LessonSearchType; + lesson: SearchLessonResType; } export const LessonSearchCard: FC = ({ lesson }) => { @@ -19,7 +11,7 @@ export const LessonSearchCard: FC = ({ lesson }) => { return (

navigate(`/lesson/${lesson.lesson_id}`)} + onClick={() => navigate(`/lesson/${lesson.lessonId}`)} >
lesson_image @@ -37,7 +29,7 @@ export const LessonSearchCard: FC = ({ lesson }) => {

logo - {lesson.host_name} + {lesson.hostName}

diff --git a/src/components/organisms/ChoiceAccount.tsx b/src/components/organisms/ChoiceAccount.tsx index 39a7909..8aed460 100644 --- a/src/components/organisms/ChoiceAccount.tsx +++ b/src/components/organisms/ChoiceAccount.tsx @@ -1,7 +1,6 @@ import { FC, useEffect, useState } from 'react'; import { MdKeyboardArrowDown } from 'react-icons/md'; import { ModalBottomContainer } from './ModalBottomContainer'; -import { AccountType } from '../../types/account'; interface IProps { accounts: AccountType[]; diff --git a/src/constants/sortList.ts b/src/constants/sortList.ts new file mode 100644 index 0000000..0d7227e --- /dev/null +++ b/src/constants/sortList.ts @@ -0,0 +1,23 @@ +export type SortType = { + name: string; + sort: string; +}; + +export const SortCategories: SortType[] = [ + { + name: '날짜순', + sort: 'date', + }, + { + name: '인기순', + sort: 'popular', + }, + { + name: '저가순', + sort: 'priceAsc', + }, + { + name: '고가순', + sort: 'priceDesc', + }, +]; diff --git a/src/pages/main/HanaFunMain.tsx b/src/pages/main/HanaFunMain.tsx index f209893..982037f 100644 --- a/src/pages/main/HanaFunMain.tsx +++ b/src/pages/main/HanaFunMain.tsx @@ -18,7 +18,6 @@ import { QRScanner } from '../../components/molecules/QRScanner'; import { useMutation, useQuery } from '@tanstack/react-query'; import { ApiClient } from '../../apis/apiClient'; import { Loading } from '../Loading'; -import { AccountType, CheckPwReqType } from '../../types/account'; import { Account_Slider_Over3_Settings } from '../../constants/accountSliderOver3Settings'; import { Account_Slider_Under2_Settings } from '../../constants/accountSliderUnder2Settings'; import { IntroCard_Slider_Settings } from '../../constants/introCardSliderSettings'; @@ -66,11 +65,7 @@ export const HanaFunMain = () => { staleTime: 10000, }); - const { - mutate: checkPw, - isPending: isCheckPwPeding, - isSuccess: isCheckPwSuccess, - } = useMutation({ + const { mutate: checkPw } = useMutation({ mutationFn: (reqData: CheckPwReqType) => { const res = ApiClient.getInstance().postCheckPw(reqData); return res; @@ -248,7 +243,7 @@ export const HanaFunMain = () => { popularLessonList.data.map((item, index) => ( diff --git a/src/pages/main/QRPay.tsx b/src/pages/main/QRPay.tsx index 05b90d0..311e6e4 100644 --- a/src/pages/main/QRPay.tsx +++ b/src/pages/main/QRPay.tsx @@ -11,9 +11,7 @@ import { useMutation, useQuery } from '@tanstack/react-query'; import { ApiClient } from '../../apis/apiClient'; import { ModalBottomContainer } from '../../components/organisms/ModalBottomContainer'; import { useModal } from '../../context/ModalContext'; -import { LessonType } from '../../types/lesson'; import { Loading } from '../Loading'; -import { QrPayReqType } from '../../types/transaction'; export const QRPay = () => { const location = useLocation(); diff --git a/src/pages/openLesson/RegisterHost.tsx b/src/pages/openLesson/RegisterHost.tsx index 14828a5..6337bf4 100644 --- a/src/pages/openLesson/RegisterHost.tsx +++ b/src/pages/openLesson/RegisterHost.tsx @@ -4,7 +4,6 @@ import { Button } from '../../components/common/Button'; import { ChoiceAccount } from '../../components/organisms/ChoiceAccount'; import { useRef, useState } from 'react'; import { CompleteSend } from '../../components/organisms/CompleteSend'; -import { AccountType } from '../../types/account'; export const RegisterHost = () => { const navigate = useNavigate(); diff --git a/src/pages/search/LessonDetail.tsx b/src/pages/search/LessonDetail.tsx index 3caf405..c23b34e 100644 --- a/src/pages/search/LessonDetail.tsx +++ b/src/pages/search/LessonDetail.tsx @@ -1,4 +1,4 @@ -import { useNavigate } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; import { Topbar } from '../../components/common/Topbar'; import { LessonContainer } from '../../components/molecules/LessonContainer'; import { Button } from '../../components/common/Button'; @@ -7,43 +7,40 @@ import { useEffect, useState } from 'react'; import { Alarm } from '../../components/molecules/Alarm'; import { ModalBottomContainer } from '../../components/organisms/ModalBottomContainer'; import { LessonDateChoice } from '../../components/molecules/LessonDateChoice'; - -const data = { - lesson_id: 1, - image: 'https://picsum.photos/200/200', - title: '헨리가 나혼자 탄 한강 카약', - price: 50000, - description: '클래스 소개글', - location: '한강', - materials: '즐거운 마음, 자신감, ㄹ랄랄랄, 라랄라라, 라아리아니라ㅣ나린', - capacity: 10, - category_name: '베이킹', -}; - -const dateData = [ - { - lessondate_id: 1, - date: '2024-06-23', - start_time: '2024-06-23 14:00:00', - end_time: '2024-06-23 15:00:00', - quantityLeft: 10, // 잔여수량 (모집인원 - 신청인원) - }, - { - lessondate_id: 2, - date: '2024-06-28', - start_time: '2024-06-28 15:00:00', - end_time: '2024-06-28 16:00:00', - quantityLeft: 10, // 잔여 수량 - }, -]; +import { useQuery } from '@tanstack/react-query'; +import { ApiClient } from '../../apis/apiClient'; +import { Loading } from '../Loading'; export const LessonDetail = () => { const navigate = useNavigate(); + const { lessonId } = useParams(); const [shownotice, setShowNotice] = useState(false); const [copyLocation, setCopyLocation] = useState(false); const [materials, setMaterials] = useState([]); const [choiceModal, setChoiceModal] = useState(false); + const { isLoading: isGetLessonLoading, data: lesson } = useQuery({ + queryKey: ['lesson', lessonId], + queryFn: () => { + if (lessonId) { + const res = ApiClient.getInstance().getLessonDetail(+lessonId); + return res; + } + }, + enabled: !!lessonId, + }); + + const { isLoading: isGetLessonDateLoading, data: lessonDateList } = useQuery({ + queryKey: ['lessonDate', lessonId], + queryFn: () => { + if (lessonId) { + const res = ApiClient.getInstance().getLessonDate(+lessonId); + return res; + } + }, + enabled: !!lessonId, + }); + const handleCopyClipBoard = async (text: string) => { try { await navigator.clipboard.writeText(text); @@ -59,9 +56,12 @@ export const LessonDetail = () => { }; useEffect(() => { - splitMaterials(data.materials); + if (lesson?.data && lesson.data?.materials !== '') + splitMaterials(lesson.data.materials); }, []); + if (isGetLessonLoading || isGetLessonDateLoading) return ; + return ( <> {copyLocation && ( @@ -71,7 +71,7 @@ export const LessonDetail = () => { onClickShowAlarm={(status: boolean) => setCopyLocation(status)} /> )} - {choiceModal && ( + {lessonDateList?.data && lesson?.data && choiceModal && ( setChoiceModal(false)} @@ -79,29 +79,40 @@ export const LessonDetail = () => {
하나의 일정을 선택해주세요.
- +
)} navigate(-1)} />
- 클래스이미지 + 클래스이미지
-

{data.title}

+

{lesson?.data?.title}

- {data.price.toLocaleString()}{' '} + {lesson?.data?.price.toLocaleString()}{' '}
-

{data.description}

+

+ {lesson?.data?.description} +

-

{data.location}

+

{lesson?.data?.location}

handleCopyClipBoard(data.location)} + onClick={() => { + if (lesson?.data) handleCopyClipBoard(lesson?.data?.location); + }} >
@@ -148,8 +159,8 @@ export const LessonDetail = () => {
diff --git a/src/pages/search/LessonSearch.tsx b/src/pages/search/LessonSearch.tsx index 5479bbf..36ad2c8 100644 --- a/src/pages/search/LessonSearch.tsx +++ b/src/pages/search/LessonSearch.tsx @@ -1,11 +1,14 @@ import { useNavigate } from 'react-router-dom'; import { Topbar } from '../../components/common/Topbar'; import { CategoryItem } from '../../components/Atom/CategoryItem'; -import { categories } from '../openLesson/RegisterLesson'; -import { useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { IoIosSearch } from 'react-icons/io'; import { TbArrowsSort } from 'react-icons/tb'; import { LessonSearchCard } from '../../components/molecules/LessonSearchCard'; +import { useQuery } from '@tanstack/react-query'; +import { ApiClient } from '../../apis/apiClient'; +import { Loading } from '../Loading'; +import { SortCategories, SortType } from '../../constants/sortList'; export const Lessondata = [ { @@ -38,22 +41,81 @@ export const Lessondata = [ }, ]; -const sortCategories = ['날짜순', '인기순', '저가순', '고가순']; - export const LessonSearch = () => { const navigate = useNavigate(); const [selectedCategory, setSelectedCategory] = useState(-1); - const [selectedSort, setSelectedSort] = useState(sortCategories[0]); + const [selectedSort, setSelectedSort] = useState(SortCategories[0]); const [showSortBtn, setShowSortBtn] = useState(false); + const inputRef = useRef(null); + const [searchText, setSearchText] = useState(''); + const [items, setItems] = useState([]); const handleClickedCategory = (categoryId: number) => { setSelectedCategory(categoryId); }; - const handleClickedSort = (sortName: string) => { - setSelectedSort(sortName); + const handleClickedSort = (sort: SortType) => { + setSelectedSort(sort); setShowSortBtn(false); }; + + const { isLoading: isGetCategoryList, data: categories } = useQuery({ + queryKey: ['categories'], + queryFn: () => { + const res = ApiClient.getInstance().getCategoryList(); + return res; + }, + staleTime: 100000, + }); + + const { isLoading: isGetLessonLoading, data: lessonList } = useQuery({ + queryKey: ['lessonList', selectedSort, searchText], + queryFn: () => { + const res = ApiClient.getInstance().getSearchLessonAll({ + query: searchText, + sort: selectedSort.sort, + }); + return res; + }, + staleTime: 10000, + enabled: selectedCategory === -1, + }); + + const { isLoading: isGetLessonCategoryLoading, data: lessonListByCategory } = + useQuery({ + queryKey: [ + 'lessonListByCategory', + selectedCategory, + selectedSort, + searchText, + ], + queryFn: () => { + const res = ApiClient.getInstance().getSearchLessonCategory( + selectedCategory, + { + query: searchText, + sort: selectedSort.sort, + } + ); + return res; + }, + staleTime: 10000, + enabled: selectedCategory !== -1, + }); + + const handleSearchInput = () => { + if (inputRef.current) setSearchText(inputRef.current.value); + }; + + useEffect(() => { + if (lessonList?.data && selectedCategory === -1) setItems(lessonList.data); + if (lessonListByCategory?.data && selectedCategory !== -1) + setItems(lessonListByCategory.data); + }, [lessonList?.data, lessonListByCategory?.data]); + + if (isGetCategoryList || isGetLessonLoading || isGetLessonCategoryLoading) + return ; + return (
navigate(-1)} /> @@ -65,48 +127,56 @@ export const LessonSearch = () => { textColor={selectedCategory === -1 ? 'white' : 'black'} onClick={handleClickedCategory} /> - {categories.map((category, index) => ( - - ))} + {categories?.data && + categories?.data.map((category) => ( + + ))}
-

검색결과 {Lessondata.length}건

+

검색결과 {items.length}건

{showSortBtn && (
- {sortCategories.map((sort, index) => ( + {SortCategories.map((sort, index) => (

handleClickedSort(sort)} > - {sort} + {sort.name}

- {index !== sortCategories.length - 1 &&
} + {index !== SortCategories.length - 1 &&
}
))}
@@ -114,8 +184,8 @@ export const LessonSearch = () => {

- {Lessondata.map((data) => ( - + {items.map((item) => ( + ))}
diff --git a/src/pages/search/PayLesson.tsx b/src/pages/search/PayLesson.tsx index a7689de..1636181 100644 --- a/src/pages/search/PayLesson.tsx +++ b/src/pages/search/PayLesson.tsx @@ -1,7 +1,6 @@ import { useRef, useState } from 'react'; import { Button } from '../../components/common/Button'; import { Topbar } from '../../components/common/Topbar'; -import { ChoiceAccount } from '../../components/organisms/ChoiceAccount'; import { InputMoney } from '../../components/Atom/InputMoney'; import { FaRegCheckCircle } from 'react-icons/fa'; import { changeMoneyFormat } from '../../utils/changeMoney'; @@ -10,6 +9,12 @@ import { ModalBottomContainer } from '../../components/organisms/ModalBottomCont import { useLocation, useNavigate } from 'react-router-dom'; import { AccountPwKeypad } from '../../components/organisms/AccountPwKeypad'; import { CompleteSend } from '../../components/organisms/CompleteSend'; +import { ChoiceAccount } from '../../components/organisms/ChoiceAccount'; +import { useMutation, useQuery } from '@tanstack/react-query'; +import { ApiClient } from '../../apis/apiClient'; +import { getCookie } from '../../utils/cookie'; +import { Loading } from '../Loading'; +import { useModal } from '../../context/ModalContext'; export const PayLesson = () => { const navigate = useNavigate(); @@ -22,14 +27,84 @@ export const PayLesson = () => { const [showModal, setShowModal] = useState(false); const [showPwModal, setShowPwModal] = useState(false); const [isSend, setIsSend] = useState(false); + const { openModal, closeModal } = useModal(); + + const { isLoading: isGetAccountList, data: accountList } = useQuery({ + queryKey: [getCookie('token'), 'accountList'], + queryFn: () => { + const res = ApiClient.getInstance().getAccountList(); + return res; + }, + }); + + const { data: hanaMoney } = useQuery({ + queryKey: [getCookie('token'), 'hanamoney'], + queryFn: () => { + const res = ApiClient.getInstance().getPoint(); + return res; + }, + enabled: !!checkHanaMoney, + }); + + const { mutate: reservation } = useMutation({ + mutationFn: (reqData: ReservationReqType) => { + const res = ApiClient.getInstance().postLessonReservation(reqData); + return res; + }, + onSuccess: (data) => { + if (data.data?.message && account) { + if (!isNaN(+data.data.message)) { + payment({ + withdrawId: account.accountId, + lessondateId: state.lessondate_id, + reservationId: +data.data.message, + payment: state.payment, + point: + hanamoneyInputRef.current && checkHanaMoney + ? +hanamoneyInputRef.current.value.replace(/[,]/gi, '') + : 0, + }); + } else { + openModal(data.data?.message, closeModal); + if (data.data.message === '계좌 비밀번호가 맞지 않습니다.') + setShowPwModal(false); + else navigate(-1); + } + } + }, + }); + + const { mutate: payment } = useMutation({ + mutationFn: (reqData: SimplePayReqType) => { + const res = ApiClient.getInstance().postSimplePay(reqData); + return res; + }, + onSuccess: (data) => { + if (data.isSuccess) { + setIsSend(true); + setShowModal(false); + setShowPwModal(false); + } + }, + onError: (error: ErrorType) => { + if (!error.isSuccess) { + openModal('잔액이 부족합니다.', closeModal); + setShowPwModal(false); + setShowModal(false); + } + }, + }); const handleChangeHanaMoney = () => { - if (hanamoneyInputRef.current) { + if (hanamoneyInputRef.current && hanaMoney?.data) { hanamoneyInputRef.current.value = changeMoneyFormat( hanamoneyInputRef.current.value ); // 하나머니 잔액으로 체크 - if (+hanamoneyInputRef.current.value.replace(/[,]/gi, '') > 3000) { + if ( + +hanamoneyInputRef.current.value.replace(/[,]/gi, '') > + hanaMoney?.data?.point + ) { setShowMessage(true); setActiveBtn(false); return; @@ -52,29 +127,18 @@ export const PayLesson = () => { setAccount(account); }; - const handlePayment = () => { - if (account) { - console.log('출금 계좌Id>>', account.accountId); - console.log('클래스 Id>>', state.lessonId); - console.log('클래스 일정>>', state.lessondate_id); - console.log('수량>>', state.count); - console.log('지불금액>>', state.payment); - console.log( - '하나머니사용금액>>', - hanamoneyInputRef.current && checkHanaMoney - ? +hanamoneyInputRef.current.value.replace(/[,]/gi, '') - : 0 - ); - setShowPwModal(true); + const sendAccountPassword = (password: string) => { + if (account && state.lessondate_id && state.count && state.payment) { + reservation({ + lessondateId: state.lessondate_id, + applicant: state.count, + accountId: account.accountId, + password: password, + }); } }; - const sendAccountPassword = (password: string) => { - setShowPwModal(false); - setShowModal(false); - setIsSend(true); - console.log('비밀번호>>', password); - }; + if (isGetAccountList) return ; return ( <> @@ -111,7 +175,7 @@ export const PayLesson = () => { @@ -126,59 +190,63 @@ export const PayLesson = () => { )} navigate(-1)} /> {!isSend ? ( -
-
- {/* */} -
- -
{ - setCheckHanaMoney((prev) => !prev); - setActiveBtn(checkHanaMoney); - }} - > - - 하나머니 사용하기 -
- {checkHanaMoney && ( -
-
-

하나머니 잔액

- {Number(3000).toLocaleString()} + <> + {accountList?.data && ( +
+
+
-
-

사용금액

-
- - -
- {showMessage && ( -

- 하나머니 잔액이 부족합니다. -

- )} + +
{ + setCheckHanaMoney((prev) => !prev); + setActiveBtn(checkHanaMoney); + }} + > + + 하나머니 사용하기
+ {checkHanaMoney && ( +
+
+

하나머니 잔액

+ {hanaMoney?.data?.point.toLocaleString()} +
+
+

사용금액

+
+ + +
+ {showMessage && ( +

+ 하나머니 잔액이 부족합니다. +

+ )} +
+
+ )}
)} -
+ ) : ( )} diff --git a/src/types/account.d.ts b/src/types/account.d.ts index b42c6a4..7b5cb8e 100644 --- a/src/types/account.d.ts +++ b/src/types/account.d.ts @@ -1,15 +1,15 @@ -export type AccountType = { +interface AccountType { accountId: number; accountName: string; accountNumber: string; balance: number; -}; +} -export type CheckPwReqType = { +interface CheckPwReqType { accountId: number; password: string; -}; +} -export type CheckPwResType = { +interface CheckPwResType { check: boolean; -}; +} diff --git a/src/types/category.d.ts b/src/types/category.d.ts index 8a3cbb9..5ff91ac 100644 --- a/src/types/category.d.ts +++ b/src/types/category.d.ts @@ -1,12 +1,17 @@ -export type SearchLessonReqType = { +interface SearchLessonReqType { query: string; sort: string; -}; +} -export type SearchLessonResType = { - lesson_id: number; +interface SearchLessonResType { + lessonId: number; image: string; title: string; price: number; - host_name: string; -}; + hostName: string; +} + +interface CategoryType { + categoryId: number; + categoryName: string; +} diff --git a/src/types/error.d.ts b/src/types/error.d.ts index afd81d9..fe45398 100644 --- a/src/types/error.d.ts +++ b/src/types/error.d.ts @@ -1,4 +1,4 @@ -type ErrorType = { +interface ErrorType { isSuccess: boolean; message: string; -}; +} diff --git a/src/types/ex.d.ts b/src/types/ex.d.ts deleted file mode 100644 index d43f777..0000000 --- a/src/types/ex.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type StepType = { - phoneNumber: string; - step: number; - stepStatus: number; -}; diff --git a/src/types/lesson.d.ts b/src/types/lesson.d.ts index 3967ba9..8aa4a28 100644 --- a/src/types/lesson.d.ts +++ b/src/types/lesson.d.ts @@ -3,6 +3,14 @@ interface LessonType { title: string; } +interface LessonDateType { + lessondateId: number; + date: Date; + startTime: Date; + endTime: Date; + quantityLeft: number; +} + interface LessonDetailType { lesson_id: number; image: string; diff --git a/src/types/reservation.d.ts b/src/types/reservation.d.ts index efd0c1c..51ce4ce 100644 --- a/src/types/reservation.d.ts +++ b/src/types/reservation.d.ts @@ -11,6 +11,13 @@ interface HostLessonDetailType extends MyScheduleType { title: string; } +interface ReservationReqType { + lessondateId: number; + applicant: number; + accountId: number; + password: string; +} + interface LessonType { reservationId: number; lessondate_id: number; diff --git a/src/types/transaction.d.ts b/src/types/transaction.d.ts index a9bc2cb..e0c1281 100644 --- a/src/types/transaction.d.ts +++ b/src/types/transaction.d.ts @@ -1,9 +1,21 @@ -export type QrPayReqType = { +interface PayCommonReqType { withdrawId: number; - depositId: number; - lessonId: number; lessondateId: number; payment: number; +} + +interface QrPayReqType extends PayCommonReqType { + depositId: number; + lessonId: number; +} + +interface SimplePayReqType extends PayCommonReqType { + reservationId: number; + point: number; +} + +interface PayResType { + transactionId: number; }; interface PaybackReqType { diff --git a/src/types/user.d.ts b/src/types/user.d.ts index 05b546d..89ac633 100644 --- a/src/types/user.d.ts +++ b/src/types/user.d.ts @@ -1,7 +1,7 @@ -export type LoginType = { +interface LoginType { jwt: string; userName: string; -}; +} interface PointType { point: number;