Skip to content

Commit

Permalink
[Feat/#40] 클래스 검색 및 상세보기 api 연동 (#43)
Browse files Browse the repository at this point in the history
* feat: 클래스 검색 api 연동

* feat: 클래스 상세 보기 및 일정 선택 api 연동

* feat: 강좌 결제 및 타입 type -> interface 변경

* feat: 클래스 예약 결제 api 연동

---------

Co-authored-by: seoyeon Moon <[email protected]>
  • Loading branch information
alswlfl29 and seoyeon08 authored Jul 3, 2024
1 parent 3b03b5c commit 0767853
Show file tree
Hide file tree
Showing 25 changed files with 466 additions and 230 deletions.
86 changes: 70 additions & 16 deletions src/apis/apiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -76,12 +73,13 @@ export class ApiClient
}

// ------- host -------
async getSearchLessonAll(reqData: SearchLessonReqType) {
async postCreateHost(reqData: CreateHostReqType) {
const response = await this.axiosInstance.request<
BaseResponseType<SearchLessonResType[]>
BaseResponseType<CreateHostResType>
>({
method: 'get',
url: `/category/all?query=${reqData.query}&sort=${reqData.sort}`,
method: 'post',
url: '/host/create',
data: reqData,
});
return response.data;
}
Expand All @@ -102,13 +100,35 @@ export class ApiClient
}

// ------- category -------
async postCreateHost(reqData: CreateHostReqType) {
async getSearchLessonAll(reqData: SearchLessonReqType) {
const response = await this.axiosInstance.request<
BaseResponseType<CreateHostResType>
BaseResponseType<SearchLessonResType[]>
>({
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<SearchLessonResType[]>
>({
method: 'get',
url: `/category/${categoryId}?query=${reqData.query}&sort=${reqData.sort}`,
});
return response.data;
}

async getCategoryList() {
const response = await this.axiosInstance.request<
BaseResponseType<CategoryType[]>
>({
method: 'get',
url: '/category',
});
return response.data;
}
Expand All @@ -133,9 +153,7 @@ export class ApiClient
//---------transaction---------
async postQrPay(reqData: QrPayReqType) {
const response = await this.axiosInstance.request<
BaseResponseType<{
transactionId: number;
}>
BaseResponseType<PayResType>
>({
method: 'post',
url: '/transaction/qr',
Expand All @@ -144,6 +162,21 @@ export class ApiClient
return response.data;
}

async postSimplePay(reqData: SimplePayReqType) {
try {
const response = await this.axiosInstance.request<
BaseResponseType<PayResType>
>({
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<
Expand All @@ -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<LessonDateType[]>
>({
method: 'get',
url: `/lesson/date-select?lessonId=${lessonId}`,
});
return response.data;
}

Expand Down Expand Up @@ -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);
Expand Down
6 changes: 0 additions & 6 deletions src/apis/interfaces/accountApi.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
import {
AccountType,
CheckPwReqType,
CheckPwResType,
} from '../../types/account';

export interface accountApi {
getAccountList(): Promise<BaseResponseType<AccountType[]>>;
postCheckPw(
Expand Down
7 changes: 5 additions & 2 deletions src/apis/interfaces/categoryApi.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { SearchLessonReqType, SearchLessonResType } from '../../types/category';

export interface categoryApi {
getSearchLessonAll(
reqData: SearchLessonReqType
): Promise<BaseResponseType<SearchLessonResType[]>>;
getSearchLessonCategory(
categoryId: number,
reqData: SearchLessonReqType
): Promise<BaseResponseType<SearchLessonResType[]>>;
getCategoryList(): Promise<BaseResponseType<CategoryType[]>>;
}
1 change: 1 addition & 0 deletions src/apis/interfaces/lessonApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export interface lessonApi {
getLessonDetail(
lesson_id: number
): Promise<BaseResponseType<LessonDetailType>>;
getLessonDate(lessonId: number): Promise<BaseResponseType<LessonDateType[]>>;
}
5 changes: 5 additions & 0 deletions src/apis/interfaces/reservationApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ export interface reservationApi {
lesson_id: number
): Promise<BaseResponseType<HostLessonDetailType[]>>;

postLessonReservation(reqData: ReservationReqType): Promise<
BaseResponseType<{
reservationId: number;
}>
>;
getMyLesson(): Promise<BaseResponseType<MyLessonType>>;

getMyLessonAll(): Promise<BaseResponseType<LessonType[]>>;
Expand Down
10 changes: 5 additions & 5 deletions src/apis/interfaces/transactionApi.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { PaybackReqType, QrPayReqType } from '../../types/transaction';

export interface transactionApi {
postQrPay(reqData: QrPayReqType): Promise<
BaseResponseType<{
transactionId: number;
}>
>;
postQrPay(reqData: QrPayReqType): Promise<BaseResponseType<PayResType>>;

postSimplePay(
reqData: SimplePayReqType
): Promise<BaseResponseType<PayResType>>;

postPayback(
reqData: PaybackReqType
Expand Down
2 changes: 0 additions & 2 deletions src/apis/interfaces/userApi.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { LoginType } from '../../types/user';

export interface userApi {
postLogin(password: string): Promise<BaseResponseType<LoginType>>;
getIsHost(): Promise<BaseResponseType<{ isHost: boolean }>>;
Expand Down
29 changes: 14 additions & 15 deletions src/components/molecules/LessonDateChoice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<IProps> = ({ dateList, price }) => {
const { lessonId } = useParams();
const navigate = useNavigate();
const [choiceDate, setChoiceDate] = useState<{
lessondate_id: number;
Expand Down Expand Up @@ -72,19 +64,27 @@ export const LessonDateChoice: FC<IProps> = ({ dateList, price }) => {
</h2>{' '}
<div className='max-h-56 overflow-y-scroll'>
{dateList.map((date, index) => (
<div key={date.lessondate_id}>
<div key={date.lessondateId}>
<div
className='px-4 py-4 flex flex-col justify-center gap-1 cursor-pointer'
onClick={() =>
clickedChoiceDate(
date.lessondate_id,
formatDate(date.date, date.start_time, date.end_time),
date.lessondateId,
formatDate(
'' + date.date,
'' + date.startTime,
'' + date.endTime
),
date.quantityLeft
)
}
>
<p className='font-hanaRegular text-sm'>
{formatDate(date.date, date.start_time, date.end_time)}
{formatDate(
'' + date.date,
'' + date.startTime,
'' + date.endTime
)}
</p>
<p className='flex items-end gap-1 font-hanaBold text-sm'>
{price.toLocaleString()}
Expand Down Expand Up @@ -144,7 +144,6 @@ export const LessonDateChoice: FC<IProps> = ({ dateList, price }) => {
navigate('/pay', {
state: {
payment: count * price,
lessonId: lessonId,
lessondate_id: choiceDate?.lessondate_id || 0,
count: count,
},
Expand Down
14 changes: 3 additions & 11 deletions src/components/molecules/LessonSearchCard.tsx
Original file line number Diff line number Diff line change
@@ -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<IProps> = ({ lesson }) => {
Expand All @@ -19,7 +11,7 @@ export const LessonSearchCard: FC<IProps> = ({ lesson }) => {
return (
<div
className='bg-white flex justify-between p-3 rounded-2xl cursor-pointer drop-shadow-[0_4px_4px_rgba(0,0,0,0.25)]'
onClick={() => navigate(`/lesson/${lesson.lesson_id}`)}
onClick={() => navigate(`/lesson/${lesson.lessonId}`)}
>
<div className='w-36 h-36 rounded-xl overflow-hidden object-fill'>
<img src={lesson.image} alt='lesson_image' className='w-full h-full' />
Expand All @@ -37,7 +29,7 @@ export const LessonSearchCard: FC<IProps> = ({ lesson }) => {
<hr className='border-hanaSilver mb-2' />
<p className='flex items-center gap-1 font-hanaRegular text-sm'>
<img src='/images/logo.svg' alt='logo' className='w-7' />
{lesson.host_name}
{lesson.hostName}
</p>
</div>
</div>
Expand Down
1 change: 0 additions & 1 deletion src/components/organisms/ChoiceAccount.tsx
Original file line number Diff line number Diff line change
@@ -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[];
Expand Down
23 changes: 23 additions & 0 deletions src/constants/sortList.ts
Original file line number Diff line number Diff line change
@@ -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',
},
];
9 changes: 2 additions & 7 deletions src/pages/main/HanaFunMain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -248,7 +243,7 @@ export const HanaFunMain = () => {
popularLessonList.data.map((item, index) => (
<PopularLessonItem
key={index}
id={item.lesson_id}
id={item.lessonId}
img={item.image}
title={item.title}
/>
Expand Down
2 changes: 0 additions & 2 deletions src/pages/main/QRPay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
1 change: 0 additions & 1 deletion src/pages/openLesson/RegisterHost.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Loading

0 comments on commit 0767853

Please sign in to comment.