Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
2 changes: 2 additions & 0 deletions frontend/src/constants/eventName.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export const ADMIN_EVENT = {
FORGOT_PASSWORD_BUTTON_CLICKED: '비밀번호 찾기 버튼클릭',

// 사이드바
CLUB_COVER_UPLOAD_BUTTON_CLICKED: '동아리 커버 업로드 버튼클릭',
CLUB_COVER_RESET_BUTTON_CLICKED: '동아리 커버 초기화 버튼클릭',
CLUB_LOGO_UPLOAD_BUTTON_CLICKED: '동아리 로고 업로드 버튼클릭',
CLUB_LOGO_EDIT_BUTTON_CLICKED: '동아리 로고 수정 버튼클릭',
CLUB_LOGO_RESET_BUTTON_CLICKED: '동아리 로고 초기화 버튼클릭',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import defaultCover from '@/assets/images/logos/default_profile_image.svg';
import { ADMIN_EVENT } from '@/constants/eventName';
import { MAX_FILE_SIZE } from '@/constants/uploadLimit';
import { useAdminClubContext } from '@/context/AdminClubContext';
import {
useDeleteCover,
useUploadCover,
} from '@/hooks/queries/club/cover/useCoverMutation';
import useMixpanelTrack from '@/hooks/useMixpanelTrack';
import * as Styled from './ClubCoverEditor.styles';

Expand All @@ -17,12 +21,13 @@ const ClubCoverEditor = ({ coverImage }: ClubCoverEditorProps) => {

if (!clubId) return null;

// TODO: useCoverMutation 추가 예정
// const uploadMutation = useUploadCover();
// const deleteMutation = useDeleteCover();
const uploadMutation = useUploadCover();
const deleteMutation = useDeleteCover();

const isCoverImageEmpty = !coverImage?.trim();
const displayedCover = isCoverImageEmpty ? defaultCover : coverImage;
const displayedCover: string = isCoverImageEmpty
? defaultCover
: (coverImage ?? defaultCover);

const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
Expand All @@ -36,9 +41,8 @@ const ClubCoverEditor = ({ coverImage }: ClubCoverEditorProps) => {
return;
}

trackEvent(ADMIN_EVENT.CLUB_LOGO_UPLOAD_BUTTON_CLICKED);
// TODO: uploadMutation.mutate({ clubId, file });
console.log('Cover image upload:', file);
trackEvent(ADMIN_EVENT.CLUB_COVER_UPLOAD_BUTTON_CLICKED);
uploadMutation.mutate({ clubId, file });
};

const triggerFileInput = () => {
Expand All @@ -54,9 +58,8 @@ const ClubCoverEditor = ({ coverImage }: ClubCoverEditorProps) => {

if (!window.confirm('정말 커버 이미지를 기본 이미지로 되돌릴까요?')) return;

trackEvent(ADMIN_EVENT.CLUB_LOGO_RESET_BUTTON_CLICKED);
// TODO: deleteMutation.mutate(clubId);
console.log('Cover image delete');
trackEvent(ADMIN_EVENT.CLUB_COVER_RESET_BUTTON_CLICKED);
deleteMutation.mutate(clubId);
};

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { SNS_CONFIG } from '@/constants/snsConfig';
import { useUpdateClubDetail } from '@/hooks/queries/club/useUpdateClubDetail';
import useMixpanelTrack from '@/hooks/useMixpanelTrack';
import useTrackPageView from '@/hooks/useTrackPageView';
import ClubLogoEditor from '@/pages/AdminPage/components/ClubLogoEditor/ClubLogoEditor';
import ClubCoverEditor from '@/pages/AdminPage/components/ClubCoverEditor/ClubCoverEditor';
import ClubLogoEditor from '@/pages/AdminPage/components/ClubLogoEditor/ClubLogoEditor';
import { ContentSection } from '@/pages/AdminPage/components/ContentSection/ContentSection';
import MakeTags from '@/pages/AdminPage/tabs/ClubInfoEditTab/components/MakeTags/MakeTags';
import SelectTags from '@/pages/AdminPage/tabs/ClubInfoEditTab/components/SelectTags/SelectTags';
Expand Down Expand Up @@ -119,7 +119,6 @@ const ClubInfoEditTab = () => {
}

const updatedData = {
id: clubDetail.id,
name: clubName,
category: selectedCategory,
division: selectedDivision,
Expand All @@ -128,6 +127,7 @@ const ClubInfoEditTab = () => {
presidentName: clubPresidentName,
presidentPhoneNumber: telephoneNumber,
socialLinks: socialLinks,
description: clubDetail.description,
};

updateClub(updatedData, {
Expand Down
59 changes: 26 additions & 33 deletions frontend/src/pages/AdminPage/tabs/ClubIntroTab/ClubIntroTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,11 @@ import { useUpdateClubDetail } from '@/hooks/queries/club/useUpdateClubDetail';
import useMixpanelTrack from '@/hooks/useMixpanelTrack';
import useTrackPageView from '@/hooks/useTrackPageView';
import { ContentSection } from '@/pages/AdminPage/components/ContentSection/ContentSection';
import { ClubDetail } from '@/types/club';
import { Award, ClubDetail, FAQ, IdealCandidate } from '@/types/club';
import * as Styled from './ClubIntroTab.styles';
import AwardEditor from './components/AwardEditor/AwardEditor';
import FAQEditor from './components/FAQEditor/FAQEditor';

export interface Award {
semester: string;
achievements: string[];
}

export interface FAQ {
id: string;
question: string;
answer: string;
}

export interface IdealCandidate {
tags: string[];
content: string;
}

const ClubIntroTab = () => {
const trackEvent = useMixpanelTrack();
useTrackPageView(PAGE_VIEW.CLUB_INFO_EDIT_PAGE);
Expand All @@ -49,14 +33,15 @@ const ClubIntroTab = () => {
const queryClient = useQueryClient();

useEffect(() => {
if (clubDetail) {
// TODO: API 연동 시 실제 데이터로 대체
setIntroDescription('');
setActivityDescription('');
setAwards([]);
setIdealCandidate({ tags: [], content: '' });
setBenefits('');
setFaqs([]);
if (clubDetail?.description) {
setIntroDescription(clubDetail.description.introDescription || '');
setActivityDescription(clubDetail.description.activityDescription || '');
setAwards(clubDetail.description.awards || []);
setIdealCandidate(
clubDetail.description.idealCandidate || { tags: [], content: '' },
);
setBenefits(clubDetail.description.benefits || '');
setFaqs(clubDetail.description.faqs || []);
}
}, [clubDetail]);

Expand All @@ -69,16 +54,24 @@ const ClubIntroTab = () => {
trackEvent(ADMIN_EVENT.UPDATE_CLUB_BUTTON_CLICKED);

const updatedData = {
id: clubDetail.id,
introDescription,
activityDescription,
awards,
idealCandidate,
benefits,
faqs,
name: clubDetail.name,
category: clubDetail.category,
division: clubDetail.division,
tags: clubDetail.tags,
introduction: clubDetail.introduction,
presidentName: clubDetail.presidentName,
presidentPhoneNumber: clubDetail.presidentPhoneNumber,
socialLinks: clubDetail.socialLinks,
description: {
introDescription,
activityDescription,
awards,
idealCandidate,
benefits,
faqs,
},
};

// TODO: API 연동
updateClub(updatedData as any, {
onSuccess: () => {
alert('동아리 상세 정보가 성공적으로 수정되었습니다.');
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/types/club.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,19 @@ export interface Club {
export type SNSPlatform = keyof typeof SNS_CONFIG;

export interface ClubDetail extends Club {
description: string;
description: DetailedDescription;

state: string;
feeds: string[];

presidentName: string;
presidentPhoneNumber: string;

recruitmentForm: string;
recruitmentStart: string | null;
recruitmentEnd: string | null;
recruitmentTarget: string;

socialLinks: Record<SNSPlatform, string>;
externalApplicationUrl?: string;
}
Expand Down