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
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
61 changes: 27 additions & 34 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,17 +54,25 @@ 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, {
updateClub(updatedData, {
onSuccess: () => {
alert('동아리 상세 정보가 성공적으로 수정되었습니다.');
queryClient.invalidateQueries({
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