Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Refactor] Amplitude tracking 로직 컴포넌트로 분리 #473

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
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
13 changes: 13 additions & 0 deletions src/common/components/Button/AmplitudeEventTrack.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { track } from '@amplitude/analytics-browser';
import type { ReactNode } from 'react';

interface AmplitudeEventTrackProps {
eventName?: string; // amplitude event name
children: ReactNode;
}

const AmplitudeEventTrack = ({ eventName, children }: AmplitudeEventTrackProps) => {
return <div onClick={() => (eventName ? track(eventName) : null)}>{children}</div>;
};

export default AmplitudeEventTrack;
29 changes: 17 additions & 12 deletions src/common/components/Button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import { useDeviceType } from 'contexts/DeviceTypeProvider';
import ButtonLoading from 'views/loadings/ButtonLoading';

import { buttonFontVar, container, outsideBox, paddings } from './style.css';
import AmplitudeEventTrack from './AmplitudeEventTrack';

interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement | HTMLAnchorElement> {
children?: ReactNode;
className?: string;
eventName?: string;
buttonStyle?: 'solid' | 'line';
isLoading?: boolean;
padding?: '15x32' | '13x20' | '10x24' | '15x25';
Expand All @@ -19,6 +21,7 @@ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement | HTMLAncho
const Button = ({
children,
className,
eventName,
buttonStyle = 'solid',
padding = '15x32',
isLoading = false,
Expand All @@ -38,18 +41,20 @@ const Button = ({
}

return (
<Tag
id={id}
to={to as To}
type={type}
className={`${className} ${outsideBox[isLoading || disabled ? 'disabled' : buttonStyle]}`}
disabled={isLoading || disabled}
{...buttonElementProps}>
<div
className={`${container[isLoading || disabled ? 'disabled' : buttonStyle]} ${paddings[padding]} ${buttonFontVar[deviceType]} ${className}`}>
{isLoading ? <ButtonLoading width={loadingWidth} /> : children}
</div>
</Tag>
<AmplitudeEventTrack eventName={eventName}>
<Tag
id={id}
to={to as To}
type={type}
className={`${className} ${outsideBox[isLoading || disabled ? 'disabled' : buttonStyle]}`}
disabled={isLoading || disabled}
{...buttonElementProps}>
<div
className={`${container[isLoading || disabled ? 'disabled' : buttonStyle]} ${paddings[padding]} ${buttonFontVar[deviceType]} ${className}`}>
{isLoading ? <ButtonLoading width={loadingWidth} /> : children}
</div>
</Tag>
</AmplitudeEventTrack>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { track } from '@amplitude/analytics-browser';
import { NavLink } from 'react-router-dom';

import { useDeviceType } from 'contexts/DeviceTypeProvider';

import { menuItemVar, menuLinkVar } from './style.css';
import AmplitudeEventTrack from '@components/Button/AmplitudeEventTrack';

interface MenuItemProps {
text: string;
Expand All @@ -20,13 +20,11 @@ const MenuItem = ({ text, path, target, amplitudeId, className, onClick }: MenuI
return (
<li className={`${className} ${menuItemVar[deviceType]}`}>
{path ? (
<NavLink
to={path}
className={menuLinkVar[deviceType]}
onClick={() => (amplitudeId ? track(amplitudeId) : null)}
target={target}>
{text}
</NavLink>
<AmplitudeEventTrack eventName={amplitudeId ? amplitudeId : undefined}>
<NavLink to={path} className={menuLinkVar[deviceType]} target={target}>
{text}
</NavLink>
</AmplitudeEventTrack>
) : (
<p className={`${onClick ? menuLinkVar[deviceType] : null}`} onClick={onClick}>
{text}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { reset, track } from '@amplitude/analytics-browser';
import { reset } from '@amplitude/analytics-browser';
import { useEffect, useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';

Expand All @@ -8,6 +8,7 @@ import { useRecruitingInfo } from 'contexts/RecruitingInfoProvider';
import { dimmedBgVar, menuContainerVar, menuList, menuMobListVar } from './style.css';
import { MENU_ITEMS, MENU_ITEMS_MAKERS } from '../../contants';
import MenuItem from '../MenuItem';
import AmplitudeEventTrack from '@components/Button/AmplitudeEventTrack';

const MenuList = ({ isMenuOpen, onClickMenuToggle }: { isMenuOpen?: boolean; onClickMenuToggle?: () => void }) => {
const { deviceType } = useDeviceType();
Expand All @@ -34,7 +35,6 @@ const MenuList = ({ isMenuOpen, onClickMenuToggle }: { isMenuOpen?: boolean; onC
} = useRecruitingInfo();
const menuItems = isMakers ? MENU_ITEMS_MAKERS : MENU_ITEMS;
const handleLogout = () => {
track('click-gnb-logout');
reset();
localStorage.removeItem('soptApplyAccessToken');
localStorage.removeItem('soptApplyAccessTokenExpiredTime');
Expand All @@ -59,7 +59,9 @@ const MenuList = ({ isMenuOpen, onClickMenuToggle }: { isMenuOpen?: boolean; onC
{menuItems.map(({ text, path, target, amplitudeId }) => (
<MenuItem key={text} text={text} path={path} target={target} amplitudeId={amplitudeId} />
))}
<MenuItem key="로그아웃" text="로그아웃" onClick={handleLogout} />
<AmplitudeEventTrack eventName="click-gnb-logout">
<MenuItem key="로그아웃" text="로그아웃" onClick={handleLogout} />
</AmplitudeEventTrack>
<MenuItem key="로그인완료" text={`${name}님`} className="amp-block" />
</>
)}
Expand Down
7 changes: 6 additions & 1 deletion src/views/ApplyPage/components/ApplyHeader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ const ApplyHeader = ({ isLoading, onSaveDraft, onSubmitData, isReview = false }:
</Title>
{!isReview && deviceType !== 'MOB' && (
<div className={buttonWrapper}>
<Button isLoading={isLoading} onClick={onSaveDraft} buttonStyle="line" padding="10x24">
<Button
isLoading={isLoading}
eventName="click-apply-draft"
onClick={onSaveDraft}
buttonStyle="line"
padding="10x24">
임시저장
</Button>
<Button isLoading={isLoading} onClick={onSubmitData} padding="10x24" type="submit">
Expand Down
25 changes: 13 additions & 12 deletions src/views/ApplyPage/components/FileInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
fileNameVar,
textWrapperVar,
} from './style.css';
import AmplitudeEventTrack from '@components/Button/AmplitudeEventTrack';

interface FileInputProps {
section: string;
Expand Down Expand Up @@ -61,8 +62,6 @@ const FileInput = ({ section, id, isReview, disabled, defaultFile }: FileInputPr
const storageRef = storage.ref();
const uploadTask = storageRef.child(`recruiting/applicants/question/${file.name}${nanoid(7)}`).put(file);

track(`click-apply-add_file${id}`);

uploadTask.on(
STATE_CHANGED,
(snapshot) => {
Expand Down Expand Up @@ -167,16 +166,18 @@ const FileInput = ({ section, id, isReview, disabled, defaultFile }: FileInputPr

return (
<div className={containerVar[deviceType]}>
<input
id={`file-${id}`}
type="file"
accept={ACCEPTED_FORMATS}
{...register(`file${id}`)}
onChange={(e) => handleFileChange(e, id)}
ref={inputRef}
className={fileInput}
disabled={disabledStatus}
/>
<AmplitudeEventTrack eventName={`click-apply-add_file${id}`}>
<input
id={`file-${id}`}
type="file"
accept={ACCEPTED_FORMATS}
{...register(`file${id}`)}
onChange={(e) => handleFileChange(e, id)}
ref={inputRef}
className={fileInput}
disabled={disabledStatus}
/>
</AmplitudeEventTrack>
<label
htmlFor={`file-${id}`}
className={`${fileLabelVar[errors[`file${id}`] ? 'error' : fileName === '' ? 'default' : 'selected']} ${fileLabelSizeVar[deviceType]}`}>
Expand Down
1 change: 0 additions & 1 deletion src/views/ApplyPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,6 @@ const ApplyPage = ({ onSetComplete }: ApplyPageProps) => {
willAppjam: false,
};

type === 'draft' ? track('click-apply-draft') : track('click-apply-confirm_submit');
type === 'draft' ? draftMutate(formValues) : submitMutate(formValues);
};

Expand Down
7 changes: 3 additions & 4 deletions src/views/CompletePage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { track } from '@amplitude/analytics-browser';

import Button from '@components/Button';
import Callout from '@components/Callout';
import { useDeviceType } from 'contexts/DeviceTypeProvider';
Expand All @@ -16,7 +14,6 @@ const CompletePage = () => {
} = useRecruitingInfo();

const handleClickMyPage = () => {
track('click-complete-my');
window.location.reload();
};

Expand All @@ -34,7 +31,9 @@ const CompletePage = () => {
style={{
marginBottom: 35,
}}>{`이메일 도착 시점에 차이가 있을 수 있습니다.\n이메일이 오지 않으면 스팸 메일함을 확인해주세요.`}</Callout>
<Button onClick={handleClickMyPage}>마이페이지로 이동하기</Button>
<Button eventName="click-complete-my" onClick={handleClickMyPage}>
마이페이지로 이동하기
</Button>
<Survey />
</section>
);
Expand Down
35 changes: 18 additions & 17 deletions src/views/ErrorPage/components/NoMore/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { track } from '@amplitude/analytics-browser';

import { useDeviceType } from 'contexts/DeviceTypeProvider';

import { article, contactButtonVar, container, errorButtonVar, errorTextVar, instructionVar } from '../../style.css';
import AmplitudeEventTrack from '@components/Button/AmplitudeEventTrack';

interface NoMoreProps {
isMakers?: boolean;
Expand All @@ -16,25 +15,27 @@ const NoMore = ({ isMakers, content }: NoMoreProps) => {
<section className={container}>
<article className={article}>
<p className={errorTextVar[deviceType]}>{content}</p>
<AmplitudeEventTrack eventName={isMakers ? 'click-nomore-official_makers' : 'click-nomore-official'}>
<a
href={isMakers ? 'https://makers.sopt.org/' : 'https://www.sopt.org/'}
className={errorButtonVar[deviceType]}
target="_blank"
rel="noreferrer noopener">
공식 홈페이지 가기
</a>
</AmplitudeEventTrack>
</article>
<p className={instructionVar[deviceType]}>{`문의사항이 있다면\n아래 ‘문의하기’를 이용해 주세요`}</p>
<AmplitudeEventTrack eventName={isMakers ? 'click-nomore-ask_makers' : 'click-nomore-ask'}>
<a
href={isMakers ? 'https://makers.sopt.org/' : 'https://www.sopt.org/'}
className={errorButtonVar[deviceType]}
id="chat-channel-button"
href={isMakers ? 'https://pf.kakao.com/_sxaIWG' : 'https://pf.kakao.com/_JdTKd'}
target="_blank"
rel="noreferrer noopener"
onClick={() => track(isMakers ? 'click-nomore-official_makers' : 'click-nomore-official')}>
공식 홈페이지 가기
className={contactButtonVar[deviceType]}>
문의하기
</a>
</article>
<p className={instructionVar[deviceType]}>{`문의사항이 있다면\n아래 ‘문의하기’를 이용해 주세요`}</p>
<a
id="chat-channel-button"
href={isMakers ? 'https://pf.kakao.com/_sxaIWG' : 'https://pf.kakao.com/_JdTKd'}
target="_blank"
rel="noreferrer noopener"
className={contactButtonVar[deviceType]}
onClick={() => track(isMakers ? 'click-nomore-ask_makers' : 'click-nomore-ask')}>
문의하기
</a>
</AmplitudeEventTrack>
</section>
);
};
Expand Down
30 changes: 16 additions & 14 deletions src/views/ErrorPage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { track } from '@amplitude/analytics-browser';
import { useNavigate } from 'react-router-dom';

import { useDeviceType } from 'contexts/DeviceTypeProvider';

import ErrorCode from './components/ErrorCode';
import { ERROR_MESSAGE } from './constants';
import { article, contactButtonVar, container, errorButtonVar, errorTextVar, instructionVar } from './style.css';
import AmplitudeEventTrack from '@components/Button/AmplitudeEventTrack';

const ErrorPage = ({ code }: { code: 404 | 500 }) => {
const { deviceType } = useDeviceType();
Expand All @@ -22,7 +22,6 @@ const ErrorPage = ({ code }: { code: 404 | 500 }) => {
};

const handleClickErrorButton = () => {
code === 404 ? track('click-error-home') : track('click-error-back');
handleGoBack(code);
};

Expand All @@ -33,23 +32,26 @@ const ErrorPage = ({ code }: { code: 404 | 500 }) => {
<article className={article}>
<ErrorCode code={code} />
<p className={errorTextVar[deviceType]}>{ERROR_MESSAGE[CODE_KEY]?.text}</p>
<button className={errorButtonVar[deviceType]} onClick={handleClickErrorButton}>
{ERROR_MESSAGE[CODE_KEY]?.button}
</button>
<AmplitudeEventTrack eventName={code === 404 ? 'click-error-home' : 'click-error-back'}>
<button className={errorButtonVar[deviceType]} onClick={handleClickErrorButton}>
{ERROR_MESSAGE[CODE_KEY]?.button}
</button>
</AmplitudeEventTrack>
</article>
<p
className={
instructionVar[deviceType]
}>{`문제가 지속적으로 발생하거나 문의사항이 있다면\n아래 ‘문의하기’를 이용해 주세요`}</p>
<a
id="chat-channel-button"
href="http://pf.kakao.com/_sxaIWG"
target="_blank"
rel="noreferrer noopener"
className={contactButtonVar[deviceType]}
onClick={() => track('click-error-ask')}>
문의하기
</a>
<AmplitudeEventTrack eventName="click-error-ask">
<a
id="chat-channel-button"
href="http://pf.kakao.com/_sxaIWG"
target="_blank"
rel="noreferrer noopener"
className={contactButtonVar[deviceType]}>
문의하기
</a>
</AmplitudeEventTrack>
</section>
);
};
Expand Down
8 changes: 1 addition & 7 deletions src/views/MyPage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { track } from '@amplitude/analytics-browser';
import { lazy } from 'react';

import Button from '@components/Button';
Expand Down Expand Up @@ -39,12 +38,7 @@ const StatusButton = ({ label, to, trackingEvent }: { label: string; to: string;
return (
<li className={buttonValue}>
<span className={infoLabelVar[deviceType]}>{label}</span>
<Button
isLink
to={to}
className={buttonWidthVar[deviceType]}
onClick={() => track(trackingEvent)}
padding="15x25">
<Button isLink to={to} className={buttonWidthVar[deviceType]} eventName={trackingEvent} padding="15x25">
{label === '지원서' ? '지원서 확인' : '결과 확인'}
</Button>
</li>
Expand Down
3 changes: 1 addition & 2 deletions src/views/PasswordPage/components/PasswordForm/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { track } from '@amplitude/analytics-browser';
import { lazy } from 'react';
import { FormProvider, useForm, type FieldValues } from 'react-hook-form';

Expand Down Expand Up @@ -76,7 +75,7 @@ const PasswordForm = () => {
isLoading={changePasswordIsPending}
type="submit"
style={{ marginTop: 30 }}
onClick={() => track('click-password-password')}>
eventName="click-password-password">
저장하기
</Button>
</>
Expand Down
Loading
Loading