Skip to content

Commit

Permalink
[Feat/#44] 클래스 개설, 호스트 등록 api 연동, QR 결제 api 수정 (#45)
Browse files Browse the repository at this point in the history
* fix: QR 결제 클래스 날짜 제외

* feat: 호스트 여부 판단 api

* feat: 호스트 등록  api 연동

* feat: 클래스 등록 api 연동

* fix: console 삭제 및 주소창 zindex 높임

---------

Co-authored-by: seoyeon Moon <[email protected]>
  • Loading branch information
alswlfl29 and seoyeon08 authored Jul 4, 2024
1 parent ebdaa66 commit dd49803
Show file tree
Hide file tree
Showing 18 changed files with 282 additions and 223 deletions.
25 changes: 18 additions & 7 deletions src/apis/apiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ import { userApi } from './interfaces/userApi';
import { accountApi } from './interfaces/accountApi';
import { hostApi } from './interfaces/hostApi';
import { categoryApi } from './interfaces/categoryApi';
import {
CreateHostReqType,
CreateHostResType,
HostInfoType,
} from '../types/host';
import { transactionApi } from './interfaces/transactionApi';
import { reservationApi } from './interfaces/reservationApi';

export class ApiClient
implements userApi, accountApi, hostApi, categoryApi, transactionApi
implements
userApi,
accountApi,
hostApi,
categoryApi,
transactionApi,
reservationApi
{
private static instance: ApiClient;
private axiosInstance: AxiosInstance;
Expand Down Expand Up @@ -44,7 +46,7 @@ export class ApiClient
BaseResponseType<{ isHost: boolean }>
>({
method: 'get',
url: '/user/ishost',
url: '/user/isHost',
});
return response.data;
}
Expand Down Expand Up @@ -215,6 +217,15 @@ export class ApiClient
return response.data;
}

async postCreateLesson(reqData: CreateLessonReqType) {
const response = await this.axiosInstance.request<void>({
method: 'post',
url: '/lesson/create',
data: reqData,
});
return response.data;
}

//---------reservation---------

// 마이페이지 출력
Expand Down
65 changes: 65 additions & 0 deletions src/apis/imageApiClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import axios, { AxiosInstance } from 'axios';
import { API_BASE_URL } from './url';
import { getCookie } from '../utils/cookie';

export class ImageApiClient {
private static instance: ImageApiClient;
private axiosImgInstance: AxiosInstance;

constructor() {
this.axiosImgInstance = this.createImageAxiosInstance();
}

// 이미지 업로드
async postLessonImg(formData: FormData) {
console.log('ddddfsdjf>>', formData);
const response = await this.axiosImgInstance.request<string>({
method: 'post',
url: '/lesson/image-upload',
data: formData,
});
return response.data;
}

static getImageInstance(): ImageApiClient {
return this.instance || (this.instance = new this());
}

// registerToken(newToken: string) {
// this.axiosInstance = this.createAxiosInstance(newToken);
// }

logout() {
this.axiosImgInstance = this.createImageAxiosInstance();
}

private createImageAxiosInstance = () => {
const headers: any = {
'content-type': 'multipart/form-data',
};

const newInstance = axios.create({
baseURL: API_BASE_URL,
timeout: 100000,
headers,
});

newInstance.interceptors.request.use(
(config) => {
const TOKEN = getCookie('token');
if (TOKEN) {
config.headers['Authorization'] = `Bearer ${TOKEN}`;
}

config.headers['Content-Type'] = 'multipart/form-data';
return config;
},
(error) => {
console.log(error);
return Promise.reject(error);
}
);

return newInstance;
};
}
2 changes: 2 additions & 0 deletions src/apis/interfaces/lessonApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ export interface lessonApi {
lesson_id: number
): Promise<BaseResponseType<LessonDetailType>>;
getLessonDate(lessonId: number): Promise<BaseResponseType<LessonDateType[]>>;
postLessonImg(file: FormData): Promise<string>;
postCreateLesson(reqData: CreateLessonReqType): Promise<void>;
}
14 changes: 7 additions & 7 deletions src/apis/interfaces/reservationApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ export interface reservationApi {
lesson_id: number
): Promise<BaseResponseType<HostLessonDetailType[]>>;

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

getMyLessonAll(): Promise<BaseResponseType<LessonType[]>>;

getMyLessonCalendar(): Promise<BaseResponseType<MyScheduleType[]>>;
// getMyLessonCalendar(): Promise<BaseResponseType<MyScheduleType[]>>;

cancelLesson(): Promise<BaseResponseType<CancelLessonReqType>>;
cancelLesson(
reservationId: CancelLessonReqType
): Promise<CancleLessonResType>;

peopleList(
lessondate_id: PeopleListReqType
Expand Down
17 changes: 11 additions & 6 deletions src/components/molecules/AddLessonTimeList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,17 @@ import { FC, useEffect, useRef, useState } from 'react';
import { LuMinusCircle, LuPlusCircle } from 'react-icons/lu';
import { AddLessonInputLabel } from '../Atom/AddLessonInputLabel';
import { format } from 'date-fns';
import { LessonTime } from '../../pages/openLesson/RegisterLesson';
import { useModal } from '../../context/ModalContext';

interface IProps {
onChangeTimes: (lessontime: LessonTime[]) => void;
onChangeTimes: (lessontime: LessonDateCommonType[]) => void;
}

type TimeType = {
id: number;
date: Date | null;
startTime: number | null;
endTime: number | null;
startTime: Date | null;
endTime: Date | null;
};

export const AddLessonTimeList: FC<IProps> = ({ onChangeTimes }) => {
Expand Down Expand Up @@ -75,12 +74,18 @@ export const AddLessonTimeList: FC<IProps> = ({ onChangeTimes }) => {
setInputTimeItems(inputTimeItems.filter((item) => item.id !== index));
return;
}
inputItemsCopy[index][name] = e.target.value;
if (name !== 'date') {
const time_date = inputItemsCopy[index]['date']
? inputItemsCopy[index]['date'] + ' ' + e.target.value + ':00'
: format(new Date(), 'yyyy-MM-dd') + ' ' + e.target.value + ':00';
inputItemsCopy[index][name] = time_date;
} else inputItemsCopy[index][name] = e.target.value;

setInputTimeItems(inputItemsCopy);
};

const handlechangeTimes = () => {
let datetime: LessonTime[] = [];
let datetime: LessonDateCommonType[] = [];
inputTimeItems.map((time) => {
if (
time.date !== null &&
Expand Down
6 changes: 3 additions & 3 deletions src/components/molecules/SelectAddress.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ export const SelectAddress: FC<IProps> = ({ onChangeAddress }) => {
};

const postCodeStyle = {
width: '360px',
width: '380px',
height: '480px',
marginTop: '25px',
zIndex: '60px',
marginTop: '30px',
zIndex: 100,
};

const handleOpenAddressPopup = () => {
Expand Down
17 changes: 17 additions & 0 deletions src/constants/hostMain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export const InfoHost = [
{
title: '호스트 등록',
desc: `간편한 방법으로\n호스트가 되어보세요.`,
image: '/images/openlesson1.gif',
},
{
title: '클래스 개설 및 운영',
desc: '진행할 클래스를 등록하고 운영해보세요.',
image: '/images/openlesson2.gif',
},
{
title: '정산 및 수익 관리',
desc: `매 수업마다 정산을 받을 수 있어요.\n하나펀에서 제공하는\n월별 수익 관리를 받아보세요.`,
image: '/images/openlesson3.gif',
},
];
7 changes: 1 addition & 6 deletions src/pages/main/HanaFunMain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { AccountPwKeypad } from '../../components/organisms/AccountPwKeypad';
import { Slide } from '../../components/organisms/Slide';
import { QR } from '../../components/molecules/QR';
import { RiQrScan2Line } from 'react-icons/ri';
import { getCookie, setCookie } from '../../utils/cookie';
import { getCookie } from '../../utils/cookie';
import { useNavigate } from 'react-router-dom';
import { QRScanner } from '../../components/molecules/QRScanner';
import { useMutation, useQuery } from '@tanstack/react-query';
Expand All @@ -30,11 +30,6 @@ export const HanaFunMain = () => {
const [isScan, setIsScan] = useState(false);
const [active, setActive] = useState<number | null>(null);

setCookie(
'token',
'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiLsnbTrr7zsp4AiLCJ1c2VySWQiOjEsImlhdCI6MTcyMDA1MjI0MywiZXhwIjoxNzIwMTM4NjQzfQ.BJSSTGaXMZQo3F_66Xtso9k8LRVeBgNUnZif94vgLnU'
);

const [selectedAccount, setSelectedAccount] = useState<AccountType>({
accountId: -1,
accountName: '',
Expand Down
3 changes: 0 additions & 3 deletions src/pages/main/Home.tsx

This file was deleted.

66 changes: 2 additions & 64 deletions src/pages/main/QRPay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ export const QRPay = () => {
const [isBtnActive, setIsBtnActive] = useState<boolean>(false);
const [showLessonList, setShowLessonList] = useState<boolean>(false);
const [selectedLesson, setSelectedLesson] = useState<LessonType | null>(null);
const [showLessonDateList, setShowLessonDateList] = useState<boolean>(false);
const [selectedLessonDate, setSelectedLessonDate] =
useState<HostLessonDetailType | null>(null);
const [money, setMoney] = useState<number>(-1);
const [isSend, setIsSend] = useState<boolean>(false);

Expand All @@ -44,12 +41,6 @@ export const QRPay = () => {
checkValid();
};

const onChangeLessonDate = (date: HostLessonDetailType) => {
setSelectedLessonDate(date);
setShowLessonDateList(false);
checkValid();
};

const onChangeMoney = (money: number) => {
setMoney(money);
};
Expand All @@ -59,7 +50,6 @@ export const QRPay = () => {
userInfo.accountId &&
hostInfo?.data?.account.accountId &&
selectedLesson?.lessonId &&
selectedLessonDate?.lessondateId &&
money > 0 &&
money <= userInfo.balance
)
Expand All @@ -68,20 +58,19 @@ export const QRPay = () => {
};

const handleSendPayment = () => {
if (hostInfo && hostInfo.data && selectedLesson && selectedLessonDate) {
if (hostInfo && hostInfo.data && selectedLesson) {
postQrPay({
withdrawId: userInfo.accountId,
depositId: hostInfo.data.account.accountId,
lessonId: selectedLesson.lessonId,
lessondateId: selectedLessonDate.lessondateId,
payment: money,
});
}
};

useEffect(() => {
if (!getHostInfoLoading && !getHostInfoError) checkValid();
}, [money, selectedLesson?.lessonId, selectedLessonDate?.lessondateId]);
}, [money, selectedLesson?.lessonId]);

const {
data: hostInfo,
Expand All @@ -96,18 +85,6 @@ export const QRPay = () => {
retry: 1,
});

const { data: hostLessonDetail } = useQuery({
queryKey: ['hostLessonDetail', selectedLesson?.lessonId],
queryFn: async () => {
if (!selectedLesson || !selectedLesson.lessonId) return;
const response = await ApiClient.getInstance().getHostLessonDetailList(
selectedLesson.lessonId
);
return response;
},
enabled: !!selectedLesson && !!selectedLesson.lessonId,
});

if (getHostInfoLoading) return <Loading />;

if (getHostInfoError) {
Expand Down Expand Up @@ -141,30 +118,6 @@ export const QRPay = () => {
</div>
</ModalBottomContainer>
)}
{hostLessonDetail && showLessonDateList && (
<ModalBottomContainer
color='#FFFFFF'
onClose={() => setShowLessonDateList(false)}
>
<h3 className='font-hanaBold text-lg'>클래스 일정을 선택해주세요.</h3>
<div className='w-full'>
<hr />
<div className='max-h-60 overflow-y-auto scrollbar-hide px-6 py-2'>
{hostLessonDetail.data?.map((date, idx) => (
<div key={idx}>
<p
className='py-2 font-hanaRegular text-base cursor-pointer pl-1'
onClick={() => onChangeLessonDate(date)}
>
{date.date}
</p>
{idx + 1 !== hostLessonDetail.data?.length && <hr />}
</div>
))}
</div>
</div>
</ModalBottomContainer>
)}
<Topbar title='QR결제' onClick={() => navigate('/')} />
{hostInfo && hostInfo.data && (
<>
Expand All @@ -187,22 +140,7 @@ export const QRPay = () => {
}
openModal={() => setShowLessonList(true)}
/>
{selectedLesson && (
<>
<h3 className='font-hanaBold mt-6 mb-2'>클래스 일정</h3>
<ChoiceInput
isChoice={!!selectedLessonDate}
content={
selectedLessonDate
? selectedLessonDate.date
: '클래스 일정을 선택해주세요.'
}
openModal={() => setShowLessonDateList(true)}
/>
</>
)}
</div>

<InputMoney
maxMoney={userInfo.balance}
isChangeMoney={true}
Expand Down
Loading

0 comments on commit dd49803

Please sign in to comment.