diff --git a/frontend/src/constants/eventName.ts b/frontend/src/constants/eventName.ts index d5b79f398..c23cf7417 100644 --- a/frontend/src/constants/eventName.ts +++ b/frontend/src/constants/eventName.ts @@ -1,39 +1,88 @@ export const USER_EVENT = { - CATEGORY_BUTTON_CLICKED: 'CategoryButton Clicked' as const, - SEARCH_BOX_CLICKED: 'SearchBox Clicked' as const, + CATEGORY_BUTTON_CLICKED: 'CategoryButton Clicked', + SEARCH_BOX_CLICKED: 'SearchBox Clicked', // 네비게이션 - BACK_BUTTON_CLICKED: 'Back Button Clicked' as const, - HOME_BUTTON_CLICKED: 'Home Button Clicked' as const, - MOBILE_HOME_BUTTON_CLICKED: 'Mobile Home Button Clicked' as const, - MOBILE_MENU_BUTTON_CLICKED: 'Mobile Menu Button Clicked' as const, - MOBILE_MENU_DELETE_BUTTON_CLICKED: - 'Mobile Menubar delete Button Clicked' as const, + BACK_BUTTON_CLICKED: 'Back Button Clicked', + HOME_BUTTON_CLICKED: 'Home Button Clicked', + MOBILE_HOME_BUTTON_CLICKED: 'Mobile Home Button Clicked', + MOBILE_MENU_BUTTON_CLICKED: 'Mobile Menu Button Clicked', + MOBILE_MENU_DELETE_BUTTON_CLICKED: 'Mobile Menubar delete Button Clicked', // 탭 & 섹션 - TAB_CLICKED: 'Tab Clicked' as const, - PHOTO_NAVIGATION_CLICKED: 'Photo Navigation' as const, - CLUB_CARD_CLICKED: 'ClubCard Clicked' as const, + TAB_CLICKED: 'Tab Clicked', + PHOTO_NAVIGATION_CLICKED: 'Photo Navigation', + CLUB_CARD_CLICKED: 'ClubCard Clicked', // 동아리 지원 - CLUB_APPLY_BUTTON_CLICKED: 'Club Apply Button Clicked' as const, - RECOMMENDED_CLUB_CLICKED: 'Recommended Club Clicked' as const, - CLUB_UNION_BUTTON_CLICKED: 'Club Union Button Clicked' as const, + CLUB_APPLY_BUTTON_CLICKED: 'Club Apply Button Clicked', + RECOMMENDED_CLUB_CLICKED: 'Recommended Club Clicked', + CLUB_UNION_BUTTON_CLICKED: 'Club Union Button Clicked', // 공유 버튼 - SHARE_BUTTON_CLICKED: 'Share Button Clicked' as const, - SNS_LINK_CLICKED: 'SNS Link Button Clicked' as const, + SHARE_BUTTON_CLICKED: 'Share Button Clicked', + SNS_LINK_CLICKED: 'SNS Link Button Clicked', - STATUS_RADIO_BUTTON_CLICKED: 'StatusRadioButton Clicked' as const, - INTRODUCE_BUTTON_CLICKED: 'Introduce Button Clicked' as const, - APPLICATION_FORM_SUBMITTED: 'Application Form Submitted' as const, - PATCH_NOTE_BUTTON_CLICKED: 'Patch Note Button Clicked' as const, + STATUS_RADIO_BUTTON_CLICKED: 'StatusRadioButton Clicked', + INTRODUCE_BUTTON_CLICKED: 'Introduce Button Clicked', + APPLICATION_FORM_SUBMITTED: 'Application Form Submitted', + PATCH_NOTE_BUTTON_CLICKED: 'Patch Note Button Clicked', +} as const; + +export const ADMIN_EVENT = { + // 로그인 페이지 + LOGIN_BUTTON_CLICKED: '로그인 버튼클릭', + SIGNUP_BUTTON_CLICKED: '회원가입 버튼클릭', + FORGOT_ID_BUTTON_CLICKED: '아이디 찾기 버튼클릭', + FORGOT_PASSWORD_BUTTON_CLICKED: '비밀번호 찾기 버튼클릭', + + // 사이드바 + CLUB_LOGO_UPLOAD_BUTTON_CLICKED: '동아리 로고 업로드 버튼클릭', + CLUB_LOGO_EDIT_BUTTON_CLICKED: '동아리 로고 수정 버튼클릭', + CLUB_LOGO_RESET_BUTTON_CLICKED: '동아리 로고 초기화 버튼클릭', + TAB_CLICKED: '사이드바 탭 클릭', + LOGOUT_BUTTON_CLICKED: '로그아웃 버튼클릭', + + // 기본 정보 수정 + UPDATE_CLUB_BUTTON_CLICKED: '동아리 기본 정보 수정 버튼클릭', + CLUB_NAME_CLEAR_BUTTON_CLICKED: '동아리 명 입력 초기화 버튼클릭', + CLUB_PRESIDENT_CLEAR_BUTTON_CLICKED: '회장 정보 입력 초기화 버튼클릭', + TELEPHONE_NUMBER_CLEAR_BUTTON_CLICKED: '전화번호 입력 초기화 버튼클릭', + CLUB_INTRODUCTION_CLEAR_BUTTON_CLICKED: '한줄소개 입력 초기화 버튼클릭', + CLUB_TAG_SELECT_BUTTON_CLICKED: '분류/분과/자유태그 선택 버튼클릭', + CLUB_TAG_CLEAR_BUTTON_CLICKED: '자유태그 입력 초기화 버튼클릭', + CLUB_SNS_LINK_CLEAR_BUTTON_CLICKED: 'SNS 링크 입력 초기화 버튼클릭', + + // 모집 정보 수정 + UPDATE_RECRUIT_BUTTON_CLICKED: '동아리 모집 정보 수정 버튼클릭', + ALWAYS_RECRUIT_BUTTON_CLICKED: '상시모집 버튼클릭', + RECRUITMENT_START_CHANGED: '모집 시작 날짜 변경', + RECRUITMENT_END_CHANGED: '모집 종료 날짜 변경', + RECRUITMENT_TARGET_CLEAR_BUTTON_CLICKED: '모집 대상 입력 초기화 버튼클릭', + MARKDOWN_EDITOR_PREVIEW_BUTTON_CLICKED: '소개글 미리보기/편집 버튼클릭', + + // 활동 사진 수정 + IMAGE_UPLOAD_BUTTON_CLICKED: '활동 사진 업로드 버튼클릭', + IMAGE_DELETE_BUTTON_CLICKED: '활동 사진 삭제 버튼클릭', + + // 비밀번호 수정 + PASSWORD_CHANGE_BUTTON_CLICKED: '비밀번호 변경 버튼클릭', + NEW_PASSWORD_CLEAR_BUTTON_CLICKED: '새 비밀번호 입력 초기화 버튼클릭', + CONFIRM_PASSWORD_CLEAR_BUTTON_CLICKED: '확인 비밀번호 입력 초기화 버튼클릭', } as const; export const PAGE_VIEW = { - APPLICATION_FORM_PAGE: 'ApplicationFormPage' as const, - CLUB_DETAIL_PAGE: 'ClubDetailPage' as const, - MAIN_PAGE: 'MainPage' as const, - INTRODUCE_PAGE: 'IntroducePage' as const, - CLUB_UNION_PAGE: 'ClubUnionPage' as const, -} as const; \ No newline at end of file + // 사용자 + APPLICATION_FORM_PAGE: 'ApplicationFormPage', + CLUB_DETAIL_PAGE: 'ClubDetailPage', + MAIN_PAGE: 'MainPage', + INTRODUCE_PAGE: 'IntroducePage', + CLUB_UNION_PAGE: 'ClubUnionPage', + + // 관리자 + LOGIN_PAGE: '로그인페이지', + CLUB_INFO_EDIT_PAGE: '동아리 기본 정보 수정 페이지', + RECRUITMENT_INFO_EDIT_PAGE: '동아리 모집 정보 수정 페이지', + PHOTO_EDIT_PAGE: '동아리 활동 사진 수정 페이지', + ADMIN_ACCOUNT_EDIT_PAGE: '관리자 계정 수정 페이지', +} as const; \ No newline at end of file diff --git a/frontend/src/pages/AdminPage/auth/LoginTab/LoginTab.tsx b/frontend/src/pages/AdminPage/auth/LoginTab/LoginTab.tsx index c760f9725..f69489b8a 100644 --- a/frontend/src/pages/AdminPage/auth/LoginTab/LoginTab.tsx +++ b/frontend/src/pages/AdminPage/auth/LoginTab/LoginTab.tsx @@ -6,8 +6,14 @@ import Button from '@/components/common/Button/Button'; import { login } from '@/apis/auth/login'; import moadong_name_logo from '@/assets/images/logos/moadong_name_logo.svg'; import useAuth from '@/hooks/useAuth'; +import useTrackPageView from '@/hooks/useTrackPageView'; +import { ADMIN_EVENT, PAGE_VIEW } from '@/constants/eventName'; +import useMixpanelTrack from '@/hooks/useMixpanelTrack'; const LoginTab = () => { + useTrackPageView(PAGE_VIEW.LOGIN_PAGE); + const trackEvent = useMixpanelTrack(); + const [userId, setUserId] = useState(''); const [password, setPassword] = useState(''); const [loading, setLoading] = useState(false); @@ -40,6 +46,7 @@ const LoginTab = () => { } finally { setLoading(false); } + trackEvent(ADMIN_EVENT.LOGIN_BUTTON_CLICKED); }; if (authLoading) return
로딩 중...
; @@ -82,33 +89,36 @@ const LoginTab = () => { + onClick={() => { + trackEvent(ADMIN_EVENT.SIGNUP_BUTTON_CLICKED); alert( '해당 기능은 아직 준비 중이에요.\n필요하신 경우 관리자에게 문의해주세요☺', - ) - } + ); + }} > 회원가입 | + onClick={() => { + trackEvent(ADMIN_EVENT.FORGOT_ID_BUTTON_CLICKED); alert( '해당 기능은 아직 준비 중이에요.\n필요하신 경우 관리자에게 문의해주세요☺', - ) - } + ); + }} > 아이디 찾기 | + onClick={() => { + trackEvent(ADMIN_EVENT.FORGOT_PASSWORD_BUTTON_CLICKED); alert( '해당 기능은 아직 준비 중이에요.\n필요하신 경우 관리자에게 문의해주세요☺', - ) - } + ); + }} > 비밀번호 찾기 diff --git a/frontend/src/pages/AdminPage/components/ClubLogoEditor/ClubLogoEditor.tsx b/frontend/src/pages/AdminPage/components/ClubLogoEditor/ClubLogoEditor.tsx index 1b9e8ca9e..01495d39f 100644 --- a/frontend/src/pages/AdminPage/components/ClubLogoEditor/ClubLogoEditor.tsx +++ b/frontend/src/pages/AdminPage/components/ClubLogoEditor/ClubLogoEditor.tsx @@ -11,12 +11,16 @@ import { } from '@/hooks/queries/club/useClubLogo'; import { useAdminClubContext } from '@/context/AdminClubContext'; import { MAX_FILE_SIZE } from '@/constants/uploadLimit'; +import { ADMIN_EVENT } from '@/constants/eventName'; +import useMixpanelTrack from '@/hooks/useMixpanelTrack'; interface ClubLogoEditorProps { clubLogo?: string | null; } const ClubLogoEditor = ({ clubLogo }: ClubLogoEditorProps) => { + const trackEvent = useMixpanelTrack(); + const { clubId } = useAdminClubContext(); if (!clubId) return null; @@ -32,7 +36,7 @@ const ClubLogoEditor = ({ clubLogo }: ClubLogoEditorProps) => { const toggleMenu = useCallback(() => { setIsMenuOpen((prev) => !prev); - }, []); + }, [trackEvent]); const handleFileSelect = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; @@ -101,6 +105,7 @@ const ClubLogoEditor = ({ clubLogo }: ClubLogoEditorProps) => { { + trackEvent(ADMIN_EVENT.CLUB_LOGO_EDIT_BUTTON_CLICKED); triggerFileInput(); setIsMenuOpen(false); }} @@ -113,6 +118,7 @@ const ClubLogoEditor = ({ clubLogo }: ClubLogoEditorProps) => { { + trackEvent(ADMIN_EVENT.CLUB_LOGO_RESET_BUTTON_CLICKED); handleLogoReset(); setIsMenuOpen(false); }} diff --git a/frontend/src/pages/AdminPage/components/SideBar/SideBar.tsx b/frontend/src/pages/AdminPage/components/SideBar/SideBar.tsx index 1beb8e232..a0365c64f 100644 --- a/frontend/src/pages/AdminPage/components/SideBar/SideBar.tsx +++ b/frontend/src/pages/AdminPage/components/SideBar/SideBar.tsx @@ -2,8 +2,9 @@ import React, { useMemo } from 'react'; import * as Styled from './SideBar.styles'; import { useNavigate, useLocation } from 'react-router-dom'; import ClubLogoEditor from '@/pages/AdminPage/components/ClubLogoEditor/ClubLogoEditor'; - import { logout } from '@/apis/auth/logout'; +import useMixpanelTrack from '@/hooks/useMixpanelTrack'; +import { ADMIN_EVENT } from '@/constants/eventName'; interface SideBarProps { clubName: string; @@ -49,6 +50,7 @@ const tabs: TabCategory[] = [ ]; const SideBar = ({ clubLogo, clubName }: SideBarProps) => { + const trackEvent = useMixpanelTrack(); const location = useLocation(); const navigate = useNavigate(); @@ -59,6 +61,9 @@ const SideBar = ({ clubLogo, clubName }: SideBarProps) => { }, [location.pathname]); const handleTabClick = (item: TabItem) => { + trackEvent(ADMIN_EVENT.TAB_CLICKED, { + tabName: item.label, + }); // if (item.label === '아이디/비밀번호 수정') { // alert('아이디/비밀번호 수정 기능은 아직 준비 중이에요. ☺️'); // return; @@ -82,6 +87,9 @@ const SideBar = ({ clubLogo, clubName }: SideBarProps) => { ) { await logout(); } + + trackEvent(ADMIN_EVENT.LOGOUT_BUTTON_CLICKED); + localStorage.removeItem('accessToken'); navigate('/admin/login', { replace: true }); } catch (error) { diff --git a/frontend/src/pages/AdminPage/tabs/AccountEditTab/AccountEditTab.tsx b/frontend/src/pages/AdminPage/tabs/AccountEditTab/AccountEditTab.tsx index bc7df35a0..f7df36d7f 100644 --- a/frontend/src/pages/AdminPage/tabs/AccountEditTab/AccountEditTab.tsx +++ b/frontend/src/pages/AdminPage/tabs/AccountEditTab/AccountEditTab.tsx @@ -1,14 +1,18 @@ -// AccountEditTab.tsx - -import React, { useState } from 'react'; // useMemo 제거 +import { useState } from 'react'; import * as Styled from './AccountEditTab.styles'; import InputField from '@/components/common/InputField/InputField'; import Button from '@/components/common/Button/Button'; import { changePassword } from '@/apis/auth/changePassword'; +import useMixpanelTrack from '@/hooks/useMixpanelTrack'; +import { ADMIN_EVENT, PAGE_VIEW } from '@/constants/eventName'; +import useTrackPageView from '@/hooks/useTrackPageView'; const PASSWORD_REGEX = /^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#$%^])(?!.*\s).{8,20}$/; const AccountEditTab = () => { + const trackEvent = useMixpanelTrack(); + useTrackPageView(PAGE_VIEW.ADMIN_ACCOUNT_EDIT_PAGE); + const [newPassword, setNewPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [successMessage, setSuccessMessage] = useState(''); @@ -40,6 +44,12 @@ const AccountEditTab = () => { try { await changePassword({ password: newPassword }); + + trackEvent(ADMIN_EVENT.PASSWORD_CHANGE_BUTTON_CLICKED, { + newPasswordLength: newPassword.length, + confirmPasswordLength: confirmPassword.length, + }); + setSuccessMessage('비밀번호가 성공적으로 변경되었습니다.'); setNewPassword(''); setConfirmPassword(''); @@ -72,7 +82,10 @@ const AccountEditTab = () => { type='password' value={newPassword} onChange={(e) => setNewPassword(e.target.value)} - onClear={() => setNewPassword('')} + onClear={() => { + setNewPassword(''); + trackEvent(ADMIN_EVENT.NEW_PASSWORD_CLEAR_BUTTON_CLICKED); + }} maxLength={20} isError={isPasswordValid} isSuccess={newPassword.length > 0 && !isPasswordValid} @@ -85,7 +98,10 @@ const AccountEditTab = () => { type='password' value={confirmPassword} onChange={(e) => setConfirmPassword(e.target.value)} - onClear={() => setConfirmPassword('')} + onClear={() => { + setConfirmPassword(''); + trackEvent(ADMIN_EVENT.CONFIRM_PASSWORD_CLEAR_BUTTON_CLICKED); + }} maxLength={20} isError={isPasswordMatching} isSuccess={confirmPassword.length > 0 && !isPasswordMatching} diff --git a/frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx b/frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx index 175970aac..834ee2893 100644 --- a/frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx +++ b/frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx @@ -11,8 +11,15 @@ import Button from '@/components/common/Button/Button'; import SelectTags from '@/pages/AdminPage/tabs/ClubInfoEditTab/components/SelectTags/SelectTags'; import MakeTags from '@/pages/AdminPage/tabs/ClubInfoEditTab/components/MakeTags/MakeTags'; import * as Styled from './ClubInfoEditTab.styles'; +import { ADMIN_EVENT, PAGE_VIEW } from '@/constants/eventName'; +import useMixpanelTrack from '@/hooks/useMixpanelTrack'; +import useTrackPageView from '@/hooks/useTrackPageView'; + const ClubInfoEditTab = () => { + const trackEvent = useMixpanelTrack(); + useTrackPageView(PAGE_VIEW.CLUB_INFO_EDIT_PAGE); + const clubDetail = useOutletContext(); const { mutate: updateClub } = useUpdateClubDetail(); @@ -69,6 +76,8 @@ const ClubInfoEditTab = () => { }; const handleUpdateClub = () => { + trackEvent(ADMIN_EVENT.UPDATE_CLUB_BUTTON_CLICKED); + if (!clubDetail || !clubDetail.id) { alert('클럽 정보가 로드되지 않았습니다.'); console.error( @@ -124,7 +133,10 @@ const ClubInfoEditTab = () => { placeholder='동아리 명을 입력해주세요' value={clubName} onChange={(e) => setClubName(e.target.value)} - onClear={() => setClubName('')} + onClear={() => { + trackEvent(ADMIN_EVENT.CLUB_NAME_CLEAR_BUTTON_CLICKED); + setClubName(''); + }} width='40%' maxLength={10} showMaxChar={true} @@ -137,7 +149,10 @@ const ClubInfoEditTab = () => { type='text' value={clubPresidentName} onChange={(e) => setClubPresidentName(e.target.value)} - onClear={() => setClubPresidentName('')} + onClear={() => { + trackEvent(ADMIN_EVENT.CLUB_PRESIDENT_CLEAR_BUTTON_CLICKED); + setClubPresidentName(''); + }} maxLength={5} /> @@ -148,7 +163,10 @@ const ClubInfoEditTab = () => { maxLength={13} value={telephoneNumber} onChange={(e) => setTelephoneNumber(e.target.value)} - onClear={() => setTelephoneNumber('')} + onClear={() => { + trackEvent(ADMIN_EVENT.TELEPHONE_NUMBER_CLEAR_BUTTON_CLICKED); + setTelephoneNumber(''); + }} /> @@ -163,7 +181,10 @@ const ClubInfoEditTab = () => { showMaxChar={true} value={introduction} onChange={(e) => setIntroduction(e.target.value)} - onClear={() => setIntroduction('')} + onClear={() => { + trackEvent(ADMIN_EVENT.CLUB_INTRODUCTION_CLEAR_BUTTON_CLICKED); + setIntroduction(''); + }} /> { value={socialLinks[key]} onChange={(e) => handleSocialLinkChange(key, e.target.value)} onClear={() => { + trackEvent(ADMIN_EVENT.CLUB_SNS_LINK_CLEAR_BUTTON_CLICKED, { + snsPlatform: label, + }); setSocialLinks((prev) => ({ ...prev, [key]: '' })); setSnsErrors((prev) => ({ ...prev, [key]: '' })); }} diff --git a/frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/components/MakeTags/MakeTags.tsx b/frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/components/MakeTags/MakeTags.tsx index 235ad39a7..9243e3ff8 100644 --- a/frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/components/MakeTags/MakeTags.tsx +++ b/frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/components/MakeTags/MakeTags.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import * as Styled from './MakeTags.styles'; +import useMixpanelTrack from '@/hooks/useMixpanelTrack'; +import { ADMIN_EVENT } from '@/constants/eventName'; interface MakeTagsProps { value: string[]; @@ -7,6 +8,8 @@ interface MakeTagsProps { } const MakeTags = ({ value, onChange }: MakeTagsProps) => { + const trackEvent = useMixpanelTrack(); + const updateTag = (index: number, newValue: string) => { const updatedTags = value.map((tag, i) => { if (i === index) { @@ -26,6 +29,10 @@ const MakeTags = ({ value, onChange }: MakeTagsProps) => { } return tag; }); + + trackEvent(ADMIN_EVENT.CLUB_TAG_CLEAR_BUTTON_CLICKED, { + tagIndex: index + 1, + }); onChange(updatedTags); }; diff --git a/frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/components/SelectTags/SelectTags.tsx b/frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/components/SelectTags/SelectTags.tsx index 57b98c94a..a80180c71 100644 --- a/frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/components/SelectTags/SelectTags.tsx +++ b/frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/components/SelectTags/SelectTags.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import * as Styled from './SelectTags.styles'; +import useMixpanelTrack from '@/hooks/useMixpanelTrack'; +import { ADMIN_EVENT } from '@/constants/eventName'; interface SelectTagsProps { label: string; @@ -9,6 +10,8 @@ interface SelectTagsProps { } const SelectTags = ({ label, tags, selected, onChange }: SelectTagsProps) => { + const trackEvent = useMixpanelTrack(); + return (
{label} @@ -16,7 +19,13 @@ const SelectTags = ({ label, tags, selected, onChange }: SelectTagsProps) => { {tags.map((tag, index) => ( onChange(tag)} + onClick={() => { + trackEvent(ADMIN_EVENT.CLUB_TAG_SELECT_BUTTON_CLICKED, { + tagName: tag, + category: label, + }); + onChange(tag); + }} selected={selected === tag} > #{tag} diff --git a/frontend/src/pages/AdminPage/tabs/PhotoEditTab/PhotoEditTab.tsx b/frontend/src/pages/AdminPage/tabs/PhotoEditTab/PhotoEditTab.tsx index 883b89ac2..de38d2a8a 100644 --- a/frontend/src/pages/AdminPage/tabs/PhotoEditTab/PhotoEditTab.tsx +++ b/frontend/src/pages/AdminPage/tabs/PhotoEditTab/PhotoEditTab.tsx @@ -4,13 +4,18 @@ import * as Styled from './PhotoEditTab.styles'; import ImageUpload from '@/pages/AdminPage/tabs/PhotoEditTab/components/ImageUpload/ImageUpload'; import { ImagePreview } from '@/pages/AdminPage/tabs/PhotoEditTab/components/ImagePreview/ImagePreview'; import useUpdateFeedImages from '@/hooks/queries/club/useUpdateFeedImages'; - import { ClubDetail } from '@/types/club'; import { useQueryClient } from '@tanstack/react-query'; +import useMixpanelTrack from '@/hooks/useMixpanelTrack'; +import { ADMIN_EVENT, PAGE_VIEW } from '@/constants/eventName'; +import useTrackPageView from '@/hooks/useTrackPageView'; const MAX_IMAGES = 5; -const RecruitEditTab = () => { +const PhotoEditTab = () => { + const trackEvent = useMixpanelTrack(); + useTrackPageView(PAGE_VIEW.PHOTO_EDIT_PAGE); + const clubDetail = useOutletContext(); const { mutate: updateFeedImages } = useUpdateFeedImages(); @@ -90,7 +95,10 @@ const RecruitEditTab = () => { deleteImage(index)} + onDelete={() => { + trackEvent(ADMIN_EVENT.IMAGE_DELETE_BUTTON_CLICKED); + deleteImage(index); + }} /> ))} {/*{imageList.length < MAX_IMAGES && (*/} @@ -105,4 +113,4 @@ const RecruitEditTab = () => { ); }; -export default RecruitEditTab; +export default PhotoEditTab; diff --git a/frontend/src/pages/AdminPage/tabs/PhotoEditTab/components/ImageUpload/ImageUpload.tsx b/frontend/src/pages/AdminPage/tabs/PhotoEditTab/components/ImageUpload/ImageUpload.tsx index 57379f4c9..09f2d1f7e 100644 --- a/frontend/src/pages/AdminPage/tabs/PhotoEditTab/components/ImageUpload/ImageUpload.tsx +++ b/frontend/src/pages/AdminPage/tabs/PhotoEditTab/components/ImageUpload/ImageUpload.tsx @@ -3,6 +3,9 @@ import * as Styled from './ImageUpload.styles'; import useCreateFeedImage from '@/hooks/queries/club/useCreateFeedImage'; import Button from '@/components/common/Button/Button'; import { MAX_FILE_SIZE } from '@/constants/uploadLimit'; +import useMixpanelTrack from '@/hooks/useMixpanelTrack'; +import { ADMIN_EVENT } from '@/constants/eventName'; + interface ImageUploadProps { clubId: string; onChangeImageList: (image: string) => void; @@ -14,6 +17,8 @@ export const ImageUpload = ({ onChangeImageList, imageCount, }: ImageUploadProps) => { + const trackEvent = useMixpanelTrack(); + const inputRef = useRef(null); const onSuccessUploadImage = (data: string) => { @@ -46,6 +51,7 @@ export const ImageUpload = ({ -