Skip to content

Commit

Permalink
Feat/#460 GA 이벤트 추가 (#471)
Browse files Browse the repository at this point in the history
* chore: window에 ga 접근을 위해 타입 추가

* feat: ga event 발생시키는 함수 추가

* feat: like에 ga 등록

* fix: GA event 속성 중 필요한 것만 남기기

* feat: 노래 상세 페이지 ga 이벤트 추가

* feat: 마이페이지 ga 이벤트 추가

* feat: GA event 상수화

* feat: sendGAEvent 함수 인수별 default값 수정

* feat: 변경된 GA 함수 및 상수 적용

* feat: GA user memberId 가능한 반드시 수집하도록 변경
  • Loading branch information
ukkodeveloper authored Sep 27, 2023
1 parent 3ed2f31 commit e23e1c3
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 10 deletions.
26 changes: 25 additions & 1 deletion frontend/src/features/songs/components/KillingPartTrack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import useVideoPlayerContext from '@/features/youtube/hooks/useVideoPlayerContex
import useModal from '@/shared/components/Modal/hooks/useModal';
import useTimerContext from '@/shared/components/Timer/hooks/useTimerContext';
import useToastContext from '@/shared/components/Toast/hooks/useToastContext';
import { GA_ACTIONS, GA_CATEGORIES } from '@/shared/constants/GAEventName';
import sendGAEvent from '@/shared/googleAnalytics/sendGAEvent';
import { toPlayingTimeText } from '@/shared/utils/convertTime';
import copyClipboard from '@/shared/utils/copyClipBoard';
import formatOrdinals from '@/shared/utils/formatOrdinals';
Expand Down Expand Up @@ -49,6 +51,12 @@ const KillingPartTrack = ({
const partLength = end - start;

const copyKillingPartUrl = async () => {
sendGAEvent({
action: GA_ACTIONS.COPY_URL,
category: GA_CATEGORIES.SONG_DETAIL,
memberId: user?.memberId,
});

await copyClipboard(partVideoUrl);
showToast('영상 링크가 복사되었습니다.');
};
Expand Down Expand Up @@ -80,13 +88,29 @@ const KillingPartTrack = ({
};

const toggleTrackPlayAndStop = () => {
sendGAEvent({
action: GA_ACTIONS.PLAY,
category: GA_CATEGORIES.SONG_DETAIL,
memberId: user?.memberId,
});

if (isNowPlayingTrack) {
stopTrack();
} else {
playTrack();
}
};

const toggleLike = () => {
sendGAEvent({
action: GA_ACTIONS.LIKE,
category: GA_CATEGORIES.SONG_DETAIL,
memberId: user?.memberId,
});

toggleKillingPartLikes();
};

return (
<Container
$isNowPlayingTrack={isNowPlayingTrack}
Expand All @@ -110,7 +134,7 @@ const KillingPartTrack = ({
</FLexContainer>
<ButtonContainer>
<LikeButton
onClick={isLoggedIn ? toggleKillingPartLikes : openModal}
onClick={isLoggedIn ? toggleLike : openModal}
aria-label={`${rank}등 킬링파트 좋아요 하기`}
>
<ButtonIcon src={heartIcon} alt="" />
Expand Down
30 changes: 21 additions & 9 deletions frontend/src/pages/MyPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import Flex from '@/shared/components/Flex';
import Spacing from '@/shared/components/Spacing';
import SRHeading from '@/shared/components/SRHeading';
import useToastContext from '@/shared/components/Toast/hooks/useToastContext';
import { GA_ACTIONS, GA_CATEGORIES } from '@/shared/constants/GAEventName';
import ROUTE_PATH from '@/shared/constants/path';
import sendGAEvent from '@/shared/googleAnalytics/sendGAEvent';
import useFetch from '@/shared/hooks/useFetch';
import fetcher from '@/shared/remotes';
import { secondsToMinSec, toPlayingTimeText } from '@/shared/utils/convertTime';
Expand Down Expand Up @@ -38,11 +40,22 @@ const MyPage = () => {
const navigate = useNavigate();

const logoutRedirect = () => {
sendGAEvent({
action: GA_ACTIONS.LOGOUT,
category: GA_CATEGORIES.MY_PAGE,
memberId: user?.memberId,
});
logout();
navigate(ROUTE_PATH.ROOT);
};

const goEditPage = () => {
sendGAEvent({
action: GA_ACTIONS.EDIT_PROFILE,
category: GA_CATEGORIES.MY_PAGE,
memberId: user?.memberId,
});

navigate(`/${ROUTE_PATH.EDIT_PROFILE}`);
};

Expand Down Expand Up @@ -181,18 +194,17 @@ type LikePartItemProps = LikeKillingPart & {
rank: number;
};

const LikePartItem = ({
songId,
albumCoverUrl,
title,
singer,
// partId,
start,
end,
}: LikePartItemProps) => {
const LikePartItem = ({ songId, albumCoverUrl, title, singer, start, end }: LikePartItemProps) => {
const { showToast } = useToastContext();
const { user } = useAuthContext();

const shareUrl = () => {
sendGAEvent({
action: GA_ACTIONS.COPY_URL,
category: GA_CATEGORIES.MY_PAGE,
memberId: user?.memberId,
});

copyClipboard(`${BASE_URL?.replace('/api', '')}/songs/${songId}`);
showToast('클립보드에 영상링크가 복사되었습니다.');
};
Expand Down
16 changes: 16 additions & 0 deletions frontend/src/shared/constants/GAEventName.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export const GA_ACTIONS = {
COPY_URL: 'click_copy_part',
PLAY: 'click_play_part',
LIKE: 'click_like',
EDIT_PROFILE: 'click_edit_profile',
LOGOUT: 'click_logout',
};

export const GA_CATEGORIES = {
SONG_DETAIL: 'song_playing',
MY_PAGE: 'profile',
};

export const GA_MEMBER = {
NOT_LOGGED_IN: -1,
};
18 changes: 18 additions & 0 deletions frontend/src/shared/googleAnalytics/sendGAEvent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { GA_MEMBER } from '@/shared/constants/GAEventName';

interface GAProps {
action: string;
category: string;
memberId?: number;
}

export const sendGAEvent = ({ action, category, memberId = GA_MEMBER.NOT_LOGGED_IN }: GAProps) => {
if ('gtag' in window) {
window?.gtag('event', action, {
event_category: category,
member_id: memberId ? memberId : GA_MEMBER.NOT_LOGGED_IN,
});
}
};

export default sendGAEvent;
3 changes: 3 additions & 0 deletions frontend/src/shared/types/ga.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Window {
gtag: typeof gtag;
}

0 comments on commit e23e1c3

Please sign in to comment.