Skip to content
Merged
4 changes: 2 additions & 2 deletions design-system/ui/texts/Countdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ const Countdown = ({ children, isChecked }: CountdownProps) => {
`;

const baseStyles = `
h-5 sm:h-4 md:h-5 px-2 py-1 rounded-[2px] text-xs
border-[0.1px] font-medium ${flexCenter} min-w-[38px] max-w-[38px]
h-5 sm:h-4 md:h-5 px-2 py-1 rounded-[2px] text-11
border-[0.1px] font-medium ${flexCenter}
`;

return <button className={`${baseStyles} ${isChecked ? activeStyles : inactiveStyles}`}>{children}</button>;
Expand Down
10 changes: 10 additions & 0 deletions src/entities/host/api/hostDetail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { HostDetailResponse } from '../model/hostDetail';
import { axiosClient } from '../../../shared/types/api/http-client';
import { HostDetailRequest } from '../model/hostDetail';

const hostDetail = async (dto: HostDetailRequest) => {
const response = await axiosClient.get<HostDetailResponse>(`/host-channels/${dto.hostChannelId}`);
return response.data;
};

export default hostDetail;
13 changes: 13 additions & 0 deletions src/entities/host/hook/useHostDetailHook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { useQuery } from '@tanstack/react-query';
import hostDetail from '../api/hostDetail';

const useHostDetail = (hostChannelId: number) => {
const { data } = useQuery({
queryKey: ['hostDetail', hostChannelId],
queryFn: () => hostDetail({ hostChannelId }),
});

return { data };
};

export default useHostDetail;
25 changes: 25 additions & 0 deletions src/entities/host/model/hostDetail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
interface Event {
id: number;
bannerImageUrl: string;
title: string;
hostChannelName: string;
startDate: string;
address: string;
onlineType: string;
hashtags: string[];
remainDays: string;
}

export interface HostDetailRequest {
hostChannelId: number;
}

export interface HostDetailResponse {
result: {
id: number;
profileImageUrl: string;
hostChannelName: string;
channelDescription: string;
events: Event[];
};
}
Empty file removed src/entities/index.ts
Empty file.
2 changes: 1 addition & 1 deletion src/pages/event-manage/ui/HostSelectionPage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useEffect, useState } from 'react';
import AddButton from '../../../../public/assets/event-manage/creation/AddBtn.svg';
import { useFunnelState } from '../../../features/event-manage/event-create/model/FunnelContext';
import useHostChannelList from '../../../widgets/event/hook/useHostChannelListHook';
import useHostChannelList from '../../../entities/host/hook/useHostChannelListHook';
import IconButton from '../../../../design-system/ui/buttons/IconButton';
import CloseButton from '../../../../public/assets/event-manage/creation/CloseBtn.svg';
import { useHostDeletion } from '../../../features/event-manage/event-create/hooks/useHostHook';
Expand Down
1 change: 1 addition & 0 deletions src/pages/menu/ui/myHost/HostDetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const HostDetailPage = () => {
<div className="grid grid-cols-2 gap-4 mx-5 mt-3 md:grid-cols-2 lg:grid-cols-2 z-50">
{filteredEvents.map((event, index) => (
<EventCard
id={event.id}
key={index}
img={event.img}
eventTitle={event.eventTitle}
Expand Down
29 changes: 15 additions & 14 deletions src/pages/menu/ui/myHost/MyHostPage.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
import TicketHostLayout from '../../../../shared/ui/backgrounds/TicketHostLayout';
import HostLogo from '../../../../../public/assets/menu/HostLogo.svg';
import ProfileCircle from '../../../../../design-system/ui/Profile';
import { trendingEvents } from '../../../../shared/types/eventCardType';
import EventCard from '../../../../shared/ui/EventCard';
import { useState } from 'react';
import { hostInfo } from '../../../../shared/types/hostInfoType';
import useHostChannelList from '../../../../entities/host/hook/useHostChannelListHook';
import useHostDetail from '../../../../entities/host/hook/useHostDetailHook';

const MyHostPage = () => {
const [selectedHostId, setSelectedHostId] = useState<number | null>(null);
const { data } = useHostChannelList();
const { data: hostDetail } = useHostDetail(selectedHostId ?? 0);
Comment on lines +11 to +12
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

API 호출에 대한 로딩 상태 및 오류 처리 필요

API 호출을 사용하는 방식으로 잘 리팩토링되었지만, 로딩 상태와 오류 처리가 누락되었습니다. 또한 selectedHostIdnull일 때 기본값으로 0을 사용하고 있는데, 이것이 유효한 ID인지 확인이 필요합니다.

다음과 같이 개선할 것을 제안합니다:

  const [selectedHostId, setSelectedHostId] = useState<number | null>(null);
  const { data } = useHostChannelList();
-  const { data: hostDetail } = useHostDetail(selectedHostId ?? 0);
+  const { data: hostDetail, isLoading, error } = useHostDetail(selectedHostId ?? undefined);

+  // 로딩 상태 처리
+  if (isLoading) {
+    return <div className="flex justify-center items-center h-screen">로딩 중...</div>;
+  }
+
+  // 오류 처리
+  if (error) {
+    return <div className="flex justify-center items-center h-screen">오류가 발생했습니다: {error.message}</div>;
+  }

또한 useHostDetail 훅에서 undefinednull을 처리하도록 수정하는 것이 좋습니다. 유효한 ID가 선택되었을 때만 API를 호출하도록 해야 합니다.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const { data } = useHostChannelList();
const { data: hostDetail } = useHostDetail(selectedHostId ?? 0);
const [selectedHostId, setSelectedHostId] = useState<number | null>(null);
const { data } = useHostChannelList();
const { data: hostDetail, isLoading, error } = useHostDetail(selectedHostId ?? undefined);
// 로딩 상태 처리
if (isLoading) {
return <div className="flex justify-center items-center h-screen">로딩 중...</div>;
}
// 오류 처리
if (error) {
return <div className="flex justify-center items-center h-screen">오류가 발생했습니다: {error.message}</div>;
}


const handleProfileClick = (hostId: number) => {
setSelectedHostId(hostId);
};

const filteredEvents = selectedHostId ? trendingEvents.filter(event => event.id === selectedHostId) : trendingEvents;

return (
<TicketHostLayout image={HostLogo} centerContent="내 호스트">
<div className="flex space-x-5 mt-24 mx-5 overflow-x-auto scrollbar-hide">
{hostInfo.map(profile => (
{data?.result.map(profile => (
<ProfileCircle
key={profile.id}
id={profile.id}
name={profile.name}
name={profile.hostChannelName}
profile="hostProfile"
onClick={() => handleProfileClick(profile.id)}
className="md:w-20 md:h-20 w-16 h-16 hover:border hover:border-main"
Expand All @@ -32,15 +32,16 @@ const MyHostPage = () => {

{/* 이벤트 카드 목록 */}
<div className="grid grid-cols-2 gap-4 mx-5 mt-3 md:grid-cols-2 lg:grid-cols-2 pb-6">
{filteredEvents.map((event, index) => (
{hostDetail?.result?.events?.map(event => (
<EventCard
key={index}
img={event.img}
eventTitle={event.eventTitle}
dDay={event.dDay}
host={event.host}
eventDate={event.eventDate}
location={event.location}
key={event.id}
id={event.id}
img={event.bannerImageUrl}
eventTitle={event.title}
dDay={event.remainDays}
host={event.hostChannelName}
eventDate={event.startDate}
location={event.onlineType}
hashtags={event.hashtags}
/>
))}
Expand Down
20 changes: 16 additions & 4 deletions src/shared/ui/EventCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import { useLocation, useNavigate } from 'react-router-dom';
import TertiaryButton from '../../../design-system/ui/buttons/TertiaryButton';
import Countdown from '../../../design-system/ui/texts/Countdown';
import dateImg from '../../../public/assets/event-manage/details/Date.svg';
import locationImg from '../../../public/assets/event-manage/details/Location.svg'
import locationImg from '../../../public/assets/event-manage/details/Location.svg';

interface EventCardProps {
id: number;
img: string;
eventTitle: string;
dDay: string;
dDay?: string;
host: string;
eventDate: string;
location: string;
Expand All @@ -16,7 +17,18 @@ interface EventCardProps {
children?: React.ReactNode;
}

const EventCard = ({ img, eventTitle, dDay, host, eventDate, location, hashtags, onClick, children }: EventCardProps) => {
const EventCard = ({
id,
img,
eventTitle,
dDay,
host,
eventDate,
location,
hashtags,
onClick,
children,
}: EventCardProps) => {
const navigate = useNavigate();
const { pathname } = useLocation();

Expand Down Expand Up @@ -66,7 +78,7 @@ const EventCard = ({ img, eventTitle, dDay, host, eventDate, location, hashtags,
size="small"
onClick={event => {
event?.stopPropagation();
navigate('/dashboard');
navigate(`/dashboard/${id}`);
}}
className="w-31.5 md:w-33 mt-2"
/>
Expand Down