Skip to content

Commit 2349414

Browse files
Feat(project): amplitude event 연결 (#328)
* chore: update ampli interface * chore: update ampli interface * feat: connect Clicked_Shared_Bookmark, Clicked_Reminder, Clicked_My_Bookmark events * feat: connect Triggered_Reminder, Clicked_alarm events in service worker * feat: connect Saved_Article event on bookmark save * chore: ampli pull - Viewed_Saved_Content를 Impression_Saved_Content로 교체 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: analytics 패키지에서 ampli 타입 전체 re-export Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: 카드 노출 트래킹용 AnalyticsCardWrapper 공통 컴포넌트 추가 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: Remind, MyBookmark, JobPins 카드에 Impression_Saved_Content 이벤트 연결 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: consistent-type-imports ESLint 룰 추가 및 저장 시 자동 수정 활성화 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: consistent-type-imports 룰 적용 및 AnalyticsCardWrapper exhaustive-deps 수정 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: fallback 리뷰 반영 --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 5437213 commit 2349414

33 files changed

Lines changed: 315 additions & 220 deletions

File tree

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"editor.formatOnSave": true,
1313
"editor.defaultFormatter": "esbenp.prettier-vscode",
1414
"editor.codeActionsOnSave": {
15-
"source.fixAll.eslint": "explicit",
15+
"source.fixAll.eslint": "always",
1616
"source.organizeImports": "always"
1717
},
1818
"tailwindCSS.suggestions": true,

apps/client/public/firebase-messaging-sw.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
11
/* eslint-env serviceworker */
22
/* eslint-disable no-undef */
33

4+
const AMPLITUDE_API_KEY = 'bb48a29e445e2f350a1d23ad67f38d55';
5+
6+
const trackAmplitudeEvent = (eventType) => {
7+
const isProd = self.location.hostname === 'pinback.today';
8+
if (!isProd) {
9+
console.log('[Analytics] track', eventType);
10+
return;
11+
}
12+
13+
fetch('https://api2.amplitude.com/2/httpapi', {
14+
method: 'POST',
15+
headers: { 'Content-Type': 'application/json' },
16+
body: JSON.stringify({
17+
api_key: AMPLITUDE_API_KEY,
18+
events: [{ device_id: 'serviceworker', event_type: eventType }],
19+
}),
20+
}).catch((err) => console.warn('[Amplitude] 이벤트 전송 실패', err));
21+
};
22+
423
const firebaseConfig = {
524
apiKey: 'AIzaSyD3KM0IQ4Ro3Dd2fyAY8fnhE1bQ_NesrBc',
625
authDomain: 'pinback-c55de.firebaseapp.com',
@@ -35,6 +54,8 @@ firebase.initializeApp(firebaseConfig);
3554
const messaging = firebase.messaging();
3655

3756
messaging.onBackgroundMessage((payload) => {
57+
trackAmplitudeEvent('Triggered_Reminder');
58+
3859
const url = payload.data?.url || 'https://pinback.today';
3960
const notificationTitle = payload.notification?.title || 'pinback';
4061
const notificationOptions = {
@@ -50,6 +71,8 @@ messaging.onBackgroundMessage((payload) => {
5071
self.addEventListener('notificationclick', (event) => {
5172
const targetUrl = event.notification.data?.url || 'https://pinback.today';
5273

74+
trackAmplitudeEvent('Clicked_alarm');
75+
5376
fetch(
5477
`https://www.google-analytics.com/mp/collect?measurement_id=G-847ZNSCC3J&api_secret=1hei57fPTKyGX5Cw73rwgA`,
5578
{

apps/client/src/pages/jobPins/JobPins.tsx

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import JobPinsBottomNotice from '@pages/jobPins/components/JobPinsBottomNotice';
66
import MemoPopup from '@pages/jobPins/components/MemoPopup';
77
import { useJobPinsBottomNotice } from '@pages/jobPins/hooks/useJobPinsBottomNotice';
88
import Footer from '@pages/myBookmark/components/footer/Footer';
9+
import { analytics } from '@pinback/analytics';
910
import { Card } from '@pinback/design-system/ui';
11+
import AnalyticsCardWrapper from '@shared/components/analyticsCardWrapper/AnalyticsCardWrapper';
1012
import { useInfiniteScroll } from '@shared/hooks/useInfiniteScroll';
1113

1214
const JobPins = () => {
@@ -67,18 +69,30 @@ const JobPins = () => {
6769
const displayImageUrl = article.thumbnailUrl || undefined;
6870

6971
return (
70-
<Card
72+
<AnalyticsCardWrapper
7173
key={article.articleId}
72-
type="bookmark"
73-
variant="save"
74-
title={displayTitle}
75-
imageUrl={displayImageUrl}
76-
content={article.memo}
77-
category={article.category?.categoryName}
78-
categoryColor={article.category?.categoryColor}
79-
nickname={article.ownerName}
80-
onClick={() => getJobPinDetail(article.articleId)}
81-
/>
74+
bookmarkType="jobpin"
75+
>
76+
<Card
77+
type="bookmark"
78+
variant="save"
79+
title={displayTitle}
80+
imageUrl={displayImageUrl}
81+
content={article.memo}
82+
category={article.category?.categoryName}
83+
categoryColor={article.category?.categoryColor}
84+
nickname={article.ownerName}
85+
onClick={() => {
86+
analytics.track('Clicked_Shared_Bookmark', {
87+
article_id: String(article.articleId),
88+
category_id: article.category
89+
? String(article.category.categoryId)
90+
: undefined,
91+
});
92+
getJobPinDetail(article.articleId);
93+
}}
94+
/>
95+
</AnalyticsCardWrapper>
8296
);
8397
})}
8498

apps/client/src/pages/jobPins/apis/axios.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { JobPinsResponse } from '@pages/jobPins/types/api';
1+
import { type JobPinsResponse } from '@pages/jobPins/types/api';
22
import apiRequest from '@shared/apis/setting/axiosInstance';
33

44
interface ApiResponse<T> {

apps/client/src/pages/jobPins/apis/queries.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { JobPinsResponse } from '@pages/jobPins/types/api';
1+
import { type JobPinsResponse } from '@pages/jobPins/types/api';
22
import { useInfiniteQuery, useMutation } from '@tanstack/react-query';
33
import {
44
getJobPinsArticleDetail,
55
getJobPinsArticles,
6-
JobPinsDetailResponse,
6+
type JobPinsDetailResponse,
77
} from './axios';
88

99
const PAGE_SIZE = 20;

apps/client/src/pages/level/Level.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import LevelScene from '@pages/level/components/LevelScene';
2-
import { TreeLevel } from '@pages/level/types/treeLevelType';
2+
import { type TreeLevel } from '@pages/level/types/treeLevelType';
33
import { Icon } from '@pinback/design-system/icons';
44
import { Badge } from '@pinback/design-system/ui';
55
import { cn } from '@pinback/design-system/utils';

apps/client/src/pages/level/components/LevelInfoCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { TREE_LEVEL_TABLE, TreeLevel } from '@pages/level/types/treeLevelType';
1+
import { TREE_LEVEL_TABLE, type TreeLevel } from '@pages/level/types/treeLevelType';
22
import { Level } from '@pinback/design-system/ui';
33
import { cn } from '@pinback/design-system/utils';
44

apps/client/src/pages/level/components/LevelScene.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { cn } from '@pinback/design-system/utils';
2-
import { TreeLevel } from '@pages/level/types/treeLevelType';
3-
import { HTMLAttributes } from 'react';
2+
import { type TreeLevel } from '@pages/level/types/treeLevelType';
3+
import { type HTMLAttributes } from 'react';
44

55
import chippi_level1 from '../../../assets/Lv.1.webp';
66
import chippi_level2 from '../../../assets/Lv.2.webp';

apps/client/src/pages/myBookmark/MyBookmark.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ const MyBookmark = () => {
101101
onBadgeChange={setActiveBadge}
102102
updateToReadStatus={updateToReadStatus}
103103
openMenu={openMenu}
104-
queryClient={queryClient}
105104
scrollContainerRef={scrollContainerRef}
106105
/>
107106
</ErrorBoundary>

apps/client/src/pages/myBookmark/apis/axios.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {
2-
BookmarkArticlesCountResponse,
3-
BookmarkArticlesResponse,
4-
CategoryBookmarkArticleResponse,
2+
type BookmarkArticlesCountResponse,
3+
type BookmarkArticlesResponse,
4+
type CategoryBookmarkArticleResponse,
55
} from '@pages/myBookmark/types/api';
66
import apiRequest from '@shared/apis/setting/axiosInstance';
77

0 commit comments

Comments
 (0)