Skip to content

Commit

Permalink
Expo-detail api -> tanstack-query api
Browse files Browse the repository at this point in the history
  • Loading branch information
Ethen1264 committed Dec 10, 2024
1 parent f1692d0 commit df284e5
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 101 deletions.
28 changes: 28 additions & 0 deletions src/shared/types/expo-detail/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export interface ExpoDetail {
title: string;
description: string;
startedDay: string;
finishedDay: string;
location: string;
coverImage: string;
x: number;
y: number;
}

export interface ExpoTrainingDetail {
title: string;
startedAt: string;
endedAt: string;
category: 'ESSENTIAL' | 'CHOICE';
}

export interface ExpoTraining {
essential: ExpoTrainingDetail[];
choice: ExpoTrainingDetail[];
}

export interface ExpoStandard {
title: string;
startedAt: string;
endedAt: string;
}
23 changes: 23 additions & 0 deletions src/widgets/expo-detail/api/getExpoDetail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import axios from 'axios';
import {
ExpoDetail,
ExpoStandard,
ExpoTrainingDetail,
} from '@/shared/types/expo-detail/type';

export const getExpoDetail = async (id: number): Promise<ExpoDetail> => {
const response = await axios.get(`/api/expo/${id}`);
return response.data;
};

export const getExpoStandard = async (id: number): Promise<ExpoStandard[]> => {
const response = await axios.get(`/api/standard/program/${id}`);
return response.data;
};

export const getExpoTraining = async (
id: number,
): Promise<ExpoTrainingDetail[]> => {
const response = await axios.get(`/api/training/program/${id}`);
return response.data;
};
46 changes: 46 additions & 0 deletions src/widgets/expo-detail/model/useExpoDetail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { useQuery } from '@tanstack/react-query';
import {
ExpoDetail,
ExpoStandard,
ExpoTrainingDetail,
} from '@/shared/types/expo-detail/type';
import {
getExpoDetail,
getExpoStandard,
getExpoTraining,
} from '../api/getExpoDetail';

interface ExpoTraining {
essential: ExpoTrainingDetail[];
choice: ExpoTrainingDetail[];
}

export const useExpoQueries = (id: number) => {
const expoDetailQuery = useQuery<ExpoDetail, Error>({
queryKey: ['expoDetail', id],
queryFn: () => getExpoDetail(id),
});

const expoStandardQuery = useQuery<ExpoStandard[], Error>({
queryKey: ['expoStandard', id],
queryFn: () => getExpoStandard(id),
});

const expoTrainingQuery = useQuery<ExpoTrainingDetail[], Error, ExpoTraining>(
{
queryKey: ['expoTraining', id],
queryFn: () => getExpoTraining(id),
select: (data) => ({
essential: data.filter((item) => item.category === 'ESSENTIAL'),
choice: data.filter((item) => item.category === 'CHOICE'),
}),
},
);

const isLoading =
expoDetailQuery.isLoading ||
expoStandardQuery.isLoading ||
expoTrainingQuery.isLoading;

return { expoDetailQuery, expoStandardQuery, expoTrainingQuery, isLoading };
};
147 changes: 46 additions & 101 deletions src/widgets/expo-detail/ui/ExpoDetailLayout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,115 +1,60 @@
'use client';

import axios from 'axios';
import Image from 'next/image';
import React, { useEffect, useState } from 'react';
import ContentListText from '@/entities/expo-detail/ui/ContentListText';
import ContentText from '@/entities/expo-detail/ui/ContentText';
import DetailHeader from '@/entities/expo-detail/ui/DetailHeader';
import KakaoMap from '@/entities/expo-detail/ui/KaKaoMap';

interface ExpoDetail {
title: string;
description: string;
startedDay: string;
finishedDay: string;
location: string;
coverImage: string;
x: number;
y: number;
}

interface ExpoTrainingDetail {
title: string;
startedAt: string;
endedAt: string;
category: 'ESSENTIAL' | 'CHOICE';
}

interface ExpoTraining {
essential: ExpoTrainingDetail[];
choice: ExpoTrainingDetail[];
}

interface ExpoStandard {
title: string;
startedAt: string;
endedAt: string;
}
import withLoading from '@/shared/hocs/withLoading';
import { useExpoQueries } from '../../model/useExpoDetail';

const ExpoDetailLayout = ({ params }: { params: number }) => {
const [expoDetail, setExpoDetail] = useState<ExpoDetail>({
title: '',
description: '',
startedDay: '',
finishedDay: '',
location: '',
coverImage: '',
x: 0,
y: 0,
});

const [expoStandard, setExpoStandard] = useState<ExpoStandard[]>([]);
const [expoTraining, setExpoTraining] = useState<ExpoTraining>({
essential: [],
choice: [],
});

useEffect(() => {
axios.get<ExpoDetail>(`/api/expo/${params}`).then((res) => {
setExpoDetail(res.data);
});

axios.get<ExpoStandard[]>(`/api/standard/program/${params}`).then((res) => {
setExpoStandard(res.data);
});

axios
.get<ExpoTrainingDetail[]>(`/api/training/program/${params}`)
.then((res) => {
const essential = res.data.filter(
(item) => item.category === 'ESSENTIAL',
);
const choice = res.data.filter((item) => item.category === 'CHOICE');
setExpoTraining({ essential, choice });
});
}, [params]);

const date = `${expoDetail.startedDay} ~ ${expoDetail.finishedDay}`;

return (
<div>
<DetailHeader headerTitle={expoDetail.title} />
<div className="ml-[20px] mt-[48px] flex space-y-9">
<div className="space-y-[36px]">
<Image
src={expoDetail.coverImage}
alt="TestClubImg"
objectFit="cover"
className="rounded-md"
width={752}
height={360}
/>
<ContentText title="소개 글" content={expoDetail.description} />
<ContentText title="모집 기간" content={date} />
{expoStandard.length > 0 && (
<ContentListText data={expoStandard} title="참여자 연수" />
)}

{expoTraining.essential.length > 0 && (
<ContentListText data={expoTraining.essential} title="필수 연수" />
)}
{expoTraining.choice.length > 0 && (
<ContentListText data={expoTraining.choice} title="선택 연수" />
)}

<div className="space-y-4">
<ContentText title="장소 지도" content={expoDetail.location} />
<KakaoMap latitude={expoDetail.x} longitude={expoDetail.y} />
const { expoDetailQuery, expoStandardQuery, expoTrainingQuery, isLoading } =
useExpoQueries(params);

const expoDetail = expoDetailQuery.data!;
const expoStandard = expoStandardQuery.data!;
const expoTraining = expoTrainingQuery.data!;
const date = `${expoDetail?.startedDay} ~ ${expoDetail?.finishedDay}`;

return withLoading({
isLoading,
children: (
<div>
<DetailHeader headerTitle={expoDetail?.title} />
<div className="ml-[20px] mt-[48px] flex space-y-9">
<div className="space-y-[36px]">
<Image
src={expoDetail?.coverImage}
alt="TestClubImg"
objectFit="cover"
className="rounded-md"
width={752}
height={360}
/>
<ContentText title="소개 글" content={expoDetail?.description} />
<ContentText title="모집 기간" content={date} />
{expoStandard?.length > 0 && (
<ContentListText data={expoStandard} title="참여자 연수" />
)}
{expoTraining?.essential.length > 0 && (
<ContentListText
data={expoTraining?.essential}
title="필수 연수"
/>
)}
{expoTraining?.choice.length > 0 && (
<ContentListText data={expoTraining.choice} title="선택 연수" />
)}
<div className="space-y-4">
<ContentText title="장소 지도" content={expoDetail?.location} />
<KakaoMap latitude={expoDetail?.x} longitude={expoDetail?.y} />
</div>
</div>
</div>
</div>
</div>
);
),
});
};

export default ExpoDetailLayout;

0 comments on commit df284e5

Please sign in to comment.