Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import ApplicationFormPage from './pages/ApplicationFormPage/ApplicationFormPage
import ClubUnionPage from './pages/ClubUnionPage/ClubUnionPage';
import IntroducePage from './pages/IntroducePage/IntroducePage';
import 'swiper/css';
import LegacyClubDetailPage from './pages/ClubDetailPage/LegacyClubDetailPage';

const queryClient = new QueryClient({
defaultOptions: {
Expand Down Expand Up @@ -47,8 +48,27 @@ const App = () => {
</Suspense>
}
/>
{/*기존 웹 & 안드로이드 url (android: v1.1.0)*/}
<Route
path='/club/:clubId'
element={
<Suspense fallback={null}>
<LegacyClubDetailPage />
</Suspense>
}
/>
{/*웹 유저에게 신규 상세페이지 보유주기 위한 임시 url*/}
<Route
path='/clubDetail/:clubId'
element={
<Suspense fallback={null}>
<ClubDetailPage />
</Suspense>
}
/>
{/*새로 빌드해서 배포할 앱 주소 url*/}
<Route
path='/webview/club/:clubId'
element={
<Suspense fallback={null}>
<ClubDetailPage />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const ApplicationFormPage = () => {
if (isLoading) return <Spinner />;
if (isError || clubError) {
alert(applicationError?.message || '문제가 발생했어요.');
navigate(`/club/${clubId}`);
navigate(`/clubDetail/${clubId}`);
return null;
}
if (!formData || !clubDetail || !formData.questions) {
Expand Down Expand Up @@ -110,7 +110,7 @@ const ApplicationFormPage = () => {
alert(
`"${clubDetail.name}" 동아리에 성공적으로 지원되었습니다.\n좋은 결과 있으시길 바랍니다`,
);
navigate(`/club/${clubId}`, { replace: true });
navigate(`/clubDetail/${clubId}`, { replace: true });
} catch (error) {
alert(
'답변 제출에 실패했어요.\n네트워크 상태를 확인하거나 잠시 후 다시 시도해 주세요.',
Expand Down
112 changes: 112 additions & 0 deletions frontend/src/pages/ClubDetailPage/LegacyClubDetailPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { useCallback } from 'react';
import { useParams, useSearchParams } from 'react-router-dom';
import Footer from '@/components/common/Footer/Footer';
import Header from '@/components/common/Header/Header';
import { PAGE_VIEW, USER_EVENT } from '@/constants/eventName';
import useMixpanelTrack from '@/hooks/Mixpanel/useMixpanelTrack';
import useTrackPageView from '@/hooks/Mixpanel/useTrackPageView';
import { useGetClubDetail } from '@/hooks/Queries/useClub';
import useDevice from '@/hooks/useDevice';
import ClubFeed from '@/pages/ClubDetailPage/components/ClubFeed/ClubFeed';
import ClubIntroContent from '@/pages/ClubDetailPage/components/ClubIntroContent/ClubIntroContent';
import ClubProfileCard from '@/pages/ClubDetailPage/components/ClubProfileCard/ClubProfileCard';
import * as Styled from './ClubDetailPage.styles';
import ClubDetailFooter from './components/ClubDetailFooter/ClubDetailFooter';

export const TAB_TYPE = {
INTRO: 'intro',
PHOTOS: 'photos',
} as const;

type TabType = (typeof TAB_TYPE)[keyof typeof TAB_TYPE];

const LegacyClubDetailPage = () => {
const trackEvent = useMixpanelTrack();

const [searchParams, setSearchParams] = useSearchParams();
const tabParam = searchParams.get('tab') as TabType | null;

const activeTab: TabType =
tabParam && Object.values(TAB_TYPE).includes(tabParam)
? tabParam
: TAB_TYPE.INTRO;

const { clubId } = useParams<{ clubId: string }>();
const { isMobile, isTablet, isLaptop, isDesktop } = useDevice();

const { data: clubDetail, error } = useGetClubDetail(clubId || '');

useTrackPageView(PAGE_VIEW.CLUB_DETAIL_PAGE, clubDetail?.name, !clubDetail);

const handleTabClick = useCallback(
(tabKey: TabType) => {
setSearchParams({ tab: tabKey }, { replace: true });
trackEvent(
tabKey === TAB_TYPE.INTRO
? USER_EVENT.CLUB_INTRO_TAB_CLICKED
: USER_EVENT.CLUB_FEED_TAB_CLICKED
);
},
[setSearchParams, trackEvent]
);

if (error) {
return <div>동아리 정보를 불러오는데 실패했습니다.</div>;
}

if (!clubDetail) {
return null;
}

return (
<>
<Header hideOn={['mobile', 'tablet']} />
<Styled.Container>
<Styled.ContentWrapper>
<ClubProfileCard
name={clubDetail.name}
logo={clubDetail.logo}
cover={clubDetail.cover}
recruitmentStatus={clubDetail.recruitmentStatus}
socialLinks={clubDetail.socialLinks}
introDescription={clubDetail.description.introDescription}
/>

<Styled.RightSection>
<Styled.TabList>
<Styled.TabButton
$active={activeTab === TAB_TYPE.INTRO}
onClick={() => handleTabClick(TAB_TYPE.INTRO)}
>
소개 내용
</Styled.TabButton>
<Styled.TabButton
$active={activeTab === TAB_TYPE.PHOTOS}
onClick={() => handleTabClick(TAB_TYPE.PHOTOS)}
>
활동사진
</Styled.TabButton>
</Styled.TabList>

<Styled.TabContent>
<div style={{ display: activeTab === TAB_TYPE.INTRO ? 'block' : 'none' }}>
<ClubIntroContent {...clubDetail.description} />
</div>
<div style={{ display: activeTab === TAB_TYPE.PHOTOS ? 'block' : 'none' }}>
<ClubFeed feed={clubDetail.feeds} clubName={clubDetail.name} />
</div>
</Styled.TabContent>
</Styled.RightSection>
</Styled.ContentWrapper>
</Styled.Container>
<Footer />
<ClubDetailFooter
recruitmentStart={clubDetail.recruitmentStart}
recruitmentEnd={clubDetail.recruitmentEnd}
recruitmentStatus={clubDetail.recruitmentStatus}
/>
</>
);
};

export default LegacyClubDetailPage;
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const ClubCard = ({ club }: { club: Club }) => {

setTimeout(() => {
setIsClicked(false);
navigate(`/club/${club.id}`);
navigate(`/clubDetail/${club.id}`);
}, 150);
};

Expand Down