gtag 추가
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
<script setup>
|
||||
import { AVERAGE_CALCULATION_PERIOD_OPTIONS } from '@/utils/enumMappings';
|
||||
import { ref, computed, onMounted, inject } from 'vue';
|
||||
import { useGtag } from 'vue-gtag-next';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useToast } from 'primevue/usetoast';
|
||||
import clubService from '@/services/clubService';
|
||||
@@ -55,7 +56,14 @@ const loading = ref(false);
|
||||
const clubNameError = ref('');
|
||||
const clubDescriptionError = ref('');
|
||||
|
||||
// 페이지 진입 시 Google Analytics 페이지뷰 추적
|
||||
onMounted(() => {
|
||||
const gtag = useGtag();
|
||||
gtag.pageview({
|
||||
page_title: '클럽생성',
|
||||
page_path: window.location.pathname,
|
||||
page_location: window.location.href
|
||||
});
|
||||
authStore.loadUserInfo();
|
||||
});
|
||||
|
||||
@@ -81,7 +89,13 @@ const validateForm = () => {
|
||||
return isValid;
|
||||
};
|
||||
|
||||
// 클럽 생성 시도/성공/실패 GA 이벤트 추적
|
||||
const handleCreateClub = async () => {
|
||||
const gtag = useGtag();
|
||||
gtag.event('create_club_attempt', {
|
||||
event_category: '클럽생성',
|
||||
event_label: '클럽 생성 시도'
|
||||
});
|
||||
if (!validateForm()) return;
|
||||
|
||||
if (!authStore.user) {
|
||||
|
||||
@@ -130,6 +130,7 @@
|
||||
import { AVERAGE_CALCULATION_PERIOD_OPTIONS, getMemberTypeLabel } from '@/utils/enumMappings';
|
||||
|
||||
import { ref, onMounted, computed, inject } from 'vue';
|
||||
import { useGtag } from 'vue-gtag-next';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useToast } from 'primevue/usetoast';
|
||||
import { useClubStore } from '@/stores/clubStore';
|
||||
@@ -309,7 +310,13 @@ const getFeatureIcon = (featureType) => {
|
||||
};
|
||||
|
||||
// 클럽 정보 저장
|
||||
// 클럽 정보 저장 버튼 클릭 시 GA 이벤트 추적
|
||||
const saveClubInfo = async () => {
|
||||
const gtag = useGtag();
|
||||
gtag.event('save_club_info', {
|
||||
event_category: '클럽설정',
|
||||
event_label: '클럽 정보 저장'
|
||||
});
|
||||
try {
|
||||
if (!clubId) {
|
||||
router.push('/club');
|
||||
|
||||
@@ -146,9 +146,11 @@ import { useRouter } from 'vue-router';
|
||||
import apiClient from '@/services/api';
|
||||
import dayjs from 'dayjs';
|
||||
import { useToast } from 'primevue/usetoast';
|
||||
import { useGtag } from 'vue-gtag-next';
|
||||
|
||||
const router = useRouter();
|
||||
const toast = useToast();
|
||||
const gtag = useGtag();
|
||||
|
||||
// 데이터 상태 변수들
|
||||
const loading = ref(false);
|
||||
@@ -260,6 +262,12 @@ const loadDashboardData = async () => {
|
||||
|
||||
// 페이지 이동 함수
|
||||
const navigateTo = (path) => {
|
||||
// Google Analytics 이벤트 추적
|
||||
gtag.event('navigation', {
|
||||
'event_category': '대시보드',
|
||||
'event_label': path,
|
||||
'value': 1
|
||||
});
|
||||
router.push(path);
|
||||
};
|
||||
|
||||
@@ -267,6 +275,13 @@ const navigateTo = (path) => {
|
||||
onMounted(async () => {
|
||||
clubId.value = localStorage.getItem('clubId') || null;
|
||||
await loadDashboardData();
|
||||
|
||||
// Google Analytics 페이지뷰 추적
|
||||
gtag.pageview({
|
||||
page_title: '클럽 대시보드',
|
||||
page_path: window.location.pathname,
|
||||
page_location: window.location.href
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<script setup>
|
||||
// getEventTypeLabel 중복 import 제거. eventUtils.js의 getEventTypeLabel만 사용.
|
||||
import { ref, onMounted, computed } from 'vue';
|
||||
import { useGtag } from 'vue-gtag-next';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useToast } from 'primevue/usetoast';
|
||||
import FullCalendar from '@fullcalendar/vue3';
|
||||
@@ -56,7 +57,14 @@ const loading = ref(false);
|
||||
const clubId = ref(localStorage.getItem('clubId') || null);
|
||||
|
||||
// 페이지 로드 시 데이터 가져오기
|
||||
// 페이지 진입 시 Google Analytics 페이지뷰 추적
|
||||
onMounted(async () => {
|
||||
const gtag = useGtag();
|
||||
gtag.pageview({
|
||||
page_title: '이벤트캘린더',
|
||||
page_path: window.location.pathname,
|
||||
page_location: window.location.href
|
||||
});
|
||||
await fetchEvents();
|
||||
});
|
||||
|
||||
@@ -107,13 +115,27 @@ const getEventColor = (eventType) => {
|
||||
};
|
||||
|
||||
// 캘린더 이벤트 클릭 핸들러
|
||||
// 캘린더 이벤트 클릭 시 GA 이벤트 추적
|
||||
const handleEventClick = (info) => {
|
||||
const gtag = useGtag();
|
||||
gtag.event('calendar_event_click', {
|
||||
event_category: '이벤트캘린더',
|
||||
event_label: '캘린더 이벤트 클릭',
|
||||
value: info.event.id
|
||||
});
|
||||
const eventId = info.event.id;
|
||||
viewEventDetails(eventId);
|
||||
};
|
||||
|
||||
// 이벤트 상세 보기
|
||||
// 이벤트 상세보기 클릭 시 GA 이벤트 추적
|
||||
const viewEventDetails = async (eventId) => {
|
||||
const gtag = useGtag();
|
||||
gtag.event('view_event_details', {
|
||||
event_category: '이벤트캘린더',
|
||||
event_label: '이벤트 상세보기',
|
||||
value: eventId
|
||||
});
|
||||
try {
|
||||
selectedEvent.value = await eventService.getEventById(eventId);
|
||||
eventDetailsDialog.value = true;
|
||||
@@ -140,7 +162,13 @@ const removeParticipant = async (participant) => {
|
||||
};
|
||||
|
||||
// 이벤트 관리 페이지로 이동
|
||||
// 이벤트관리 이동 버튼 클릭 시 GA 이벤트 추적
|
||||
const navigateToEventManagement = () => {
|
||||
const gtag = useGtag();
|
||||
gtag.event('go_to_event_management', {
|
||||
event_category: '이벤트캘린더',
|
||||
event_label: '이벤트관리 이동'
|
||||
});
|
||||
router.push('/club/events');
|
||||
};
|
||||
|
||||
|
||||
@@ -122,6 +122,7 @@
|
||||
<script setup>
|
||||
import { getEventTypeLabel, getEventStatusLabel, getStatusSeverity } from '@/utils/enumMappings';
|
||||
import { ref, onMounted, computed } from 'vue';
|
||||
import { useGtag } from 'vue-gtag-next';
|
||||
import { useToast } from 'primevue/usetoast';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useClubStore } from '@/stores/clubStore';
|
||||
@@ -203,7 +204,14 @@ const fetchClubMembers = async () => {
|
||||
};
|
||||
|
||||
// 컴포넌트 마운트 시 데이터 로드
|
||||
// 페이지 진입 시 Google Analytics 페이지뷰 추적
|
||||
onMounted(async () => {
|
||||
const gtag = useGtag();
|
||||
gtag.pageview({
|
||||
page_title: '이벤트관리',
|
||||
page_path: window.location.pathname,
|
||||
page_location: window.location.href
|
||||
});
|
||||
if (!clubId.value) {
|
||||
toast.add({
|
||||
severity: 'error',
|
||||
@@ -265,7 +273,14 @@ const editEvent = (eventData) => {
|
||||
};
|
||||
|
||||
// 이벤트 상세 정보 보기
|
||||
// 이벤트 상세보기 클릭 시 GA 이벤트 추적
|
||||
const viewEventDetails = async (eventData) => {
|
||||
const gtag = useGtag();
|
||||
gtag.event('view_event_details', {
|
||||
event_category: '이벤트관리',
|
||||
event_label: '이벤트 상세보기',
|
||||
value: eventData.id
|
||||
});
|
||||
try {
|
||||
const response = await eventService.getEventById(eventData.id);
|
||||
event.value = response;
|
||||
@@ -302,9 +317,16 @@ const confirmDeleteEvent = (eventData) => {
|
||||
};
|
||||
|
||||
// 이벤트 저장
|
||||
// 이벤트 저장(생성/수정) 시 GA 이벤트 추적
|
||||
const saveEvent = async (eventData) => {
|
||||
const gtag = useGtag();
|
||||
try {
|
||||
if (eventData.id) {
|
||||
gtag.event('edit_event', {
|
||||
event_category: '이벤트관리',
|
||||
event_label: '이벤트 수정',
|
||||
value: eventData.id
|
||||
});
|
||||
// 이벤트 수정
|
||||
const response = await eventService.updateEvent({
|
||||
...eventData,
|
||||
@@ -312,6 +334,10 @@ const saveEvent = async (eventData) => {
|
||||
});
|
||||
await fetchEvents(); // 목록 갱신
|
||||
} else {
|
||||
gtag.event('create_event', {
|
||||
event_category: '이벤트관리',
|
||||
event_label: '이벤트 생성'
|
||||
});
|
||||
// 이벤트 생성
|
||||
const response = await eventService.createEvent({
|
||||
...eventData,
|
||||
@@ -327,6 +353,10 @@ const saveEvent = async (eventData) => {
|
||||
});
|
||||
hideDialog();
|
||||
} catch (error) {
|
||||
gtag.event('event_save_fail', {
|
||||
event_category: '이벤트관리',
|
||||
event_label: eventData.id ? '이벤트 수정 실패' : '이벤트 생성 실패'
|
||||
});
|
||||
toast.add({
|
||||
severity: 'error',
|
||||
summary: '오류',
|
||||
@@ -337,17 +367,22 @@ const saveEvent = async (eventData) => {
|
||||
};
|
||||
|
||||
// 이벤트 삭제
|
||||
// 이벤트 삭제 시 GA 이벤트 추적
|
||||
const deleteEvent = async () => {
|
||||
const gtag = useGtag();
|
||||
try {
|
||||
await eventService.deleteEvent(clubId.value, event.value.id);
|
||||
|
||||
gtag.event('delete_event', {
|
||||
event_category: '이벤트관리',
|
||||
event_label: '이벤트 삭제',
|
||||
value: event.value.id
|
||||
});
|
||||
toast.add({
|
||||
severity: 'success',
|
||||
summary: '성공',
|
||||
detail: '이벤트가 삭제되었습니다.',
|
||||
life: 3000
|
||||
});
|
||||
|
||||
deleteEventDialog.value = false;
|
||||
const index = events.value.findIndex(e => e.id === event.value.id);
|
||||
if (index > -1) {
|
||||
@@ -355,6 +390,11 @@ const deleteEvent = async () => {
|
||||
}
|
||||
event.value = {};
|
||||
} catch (error) {
|
||||
gtag.event('delete_event_fail', {
|
||||
event_category: '이벤트관리',
|
||||
event_label: '이벤트 삭제 실패',
|
||||
value: event.value.id
|
||||
});
|
||||
toast.add({
|
||||
severity: 'error',
|
||||
summary: '오류',
|
||||
@@ -398,7 +438,13 @@ const goToScoreEntry = () => {
|
||||
};
|
||||
|
||||
// 이벤트 캘린더 페이지로 이동
|
||||
// 캘린더 이동 버튼 클릭 시 GA 이벤트 추적
|
||||
const navigateToCalendar = () => {
|
||||
const gtag = useGtag();
|
||||
gtag.event('go_to_calendar', {
|
||||
event_category: '이벤트관리',
|
||||
event_label: '캘린더 이동'
|
||||
});
|
||||
const url = `/club/calendar?clubId=${clubId.value}`;
|
||||
window.location.href = url;
|
||||
};
|
||||
|
||||
@@ -190,6 +190,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useGtag } from 'vue-gtag-next';
|
||||
import { ref, reactive, computed, onMounted, watch } from 'vue';
|
||||
import clubService from '@/services/clubService';
|
||||
import { useClubStore } from '@/stores/clubStore';
|
||||
@@ -368,7 +369,8 @@ const loadMembers = async () => {
|
||||
|
||||
// 새 회원 추가 다이얼로그 열기
|
||||
const openNewMemberDialog = () => {
|
||||
member.value = {
|
||||
dialogMode.value = 'new';
|
||||
member.value = {
|
||||
name: '',
|
||||
gender: null,
|
||||
memberTypeObj: null,
|
||||
@@ -376,7 +378,6 @@ const openNewMemberDialog = () => {
|
||||
email: '',
|
||||
handicap: 0
|
||||
};
|
||||
dialogMode.value = 'new';
|
||||
memberDialog.value = true;
|
||||
};
|
||||
|
||||
@@ -392,6 +393,8 @@ watch(() => member.value.gender, (newGender) => {
|
||||
});
|
||||
|
||||
// 회원 수정 다이얼로그 열기
|
||||
const gtag = useGtag();
|
||||
|
||||
const editMember = (data) => {
|
||||
member.value = {
|
||||
...data
|
||||
@@ -410,12 +413,18 @@ const hideDialog = () => {
|
||||
const saveMember = async () => {
|
||||
try {
|
||||
const memberData = { ...member.value };
|
||||
|
||||
const isNew = dialogMode.value === 'new';
|
||||
const response = isNew
|
||||
? await clubService.addClubMember(clubId.value, memberData)
|
||||
: await clubService.updateClubMember(clubId.value, memberData.id, memberData);
|
||||
|
||||
// Google Analytics 이벤트 추적 - 회원 저장
|
||||
gtag.event(isNew ? 'add_member' : 'edit_member', {
|
||||
'event_category': '회원관리',
|
||||
'event_label': isNew ? '새 회원 추가' : '회원 정보 수정',
|
||||
'value': 1
|
||||
});
|
||||
|
||||
toast.add({
|
||||
severity: 'success',
|
||||
summary: '성공',
|
||||
@@ -444,6 +453,12 @@ const deleteMember = async () => {
|
||||
try {
|
||||
await clubService.deleteClubMember(clubId.value, selectedMember.value.id);
|
||||
deleteDialog.value = false;
|
||||
// Google Analytics 이벤트 추적 - 회원 삭제
|
||||
gtag.event('delete_member', {
|
||||
'event_category': '회원관리',
|
||||
'event_label': '회원 삭제',
|
||||
'value': 1
|
||||
});
|
||||
toast.add({ severity: 'success', summary: '성공', detail: '회원이 삭제되었습니다.', life: 3000 });
|
||||
await loadMembers();
|
||||
} catch (error) {
|
||||
@@ -453,6 +468,14 @@ const deleteMember = async () => {
|
||||
};
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
// Google Analytics 페이지뷰 추적
|
||||
gtag.pageview({
|
||||
page_title: '회원 관리',
|
||||
page_path: window.location.pathname,
|
||||
page_location: window.location.href
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -199,6 +199,7 @@ import { ref, reactive, computed, onMounted } from 'vue';
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
import { useToast } from 'primevue/usetoast';
|
||||
import scoreService from '@/services/scoreService';
|
||||
import { useGtag } from 'vue-gtag-next';
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
@@ -411,7 +412,13 @@ const calculateTotal = (participant) => {
|
||||
};
|
||||
|
||||
// 모든 점수 저장
|
||||
// 점수 저장 버튼 클릭 시 GA 이벤트 추적
|
||||
const saveAllScores = async () => {
|
||||
const gtag = useGtag();
|
||||
gtag.event('save_scores', {
|
||||
event_category: '점수관리',
|
||||
event_label: '점수 저장'
|
||||
});
|
||||
try {
|
||||
loading.value = true;
|
||||
await scoreService.saveScores(meetingId.value, participants.value);
|
||||
@@ -425,7 +432,13 @@ const saveAllScores = async () => {
|
||||
};
|
||||
|
||||
// 점수 내보내기 다이얼로그 열기
|
||||
// 점수 내보내기 버튼 클릭 시 GA 이벤트 추적
|
||||
const exportScores = () => {
|
||||
const gtag = useGtag();
|
||||
gtag.event('export_scores', {
|
||||
event_category: '점수관리',
|
||||
event_label: '점수 내보내기'
|
||||
});
|
||||
exportContent.value = [exportContentOptions.value[0]];
|
||||
exportDialog.value = true;
|
||||
};
|
||||
@@ -446,12 +459,25 @@ const downloadExport = async () => {
|
||||
};
|
||||
|
||||
// 뒤로 가기
|
||||
// 뒤로가기 버튼 클릭 시 GA 이벤트 추적
|
||||
const goBack = () => {
|
||||
const gtag = useGtag();
|
||||
gtag.event('go_back', {
|
||||
event_category: '점수관리',
|
||||
event_label: '뒤로가기'
|
||||
});
|
||||
router.push('/clubs/meetings');
|
||||
};
|
||||
|
||||
// 컴포넌트 마운트 시 데이터 로드
|
||||
// 페이지 진입 시 Google Analytics 페이지뷰 추적
|
||||
onMounted(async () => {
|
||||
const gtag = useGtag();
|
||||
gtag.pageview({
|
||||
page_title: '점수관리',
|
||||
page_path: window.location.pathname,
|
||||
page_location: window.location.href
|
||||
});
|
||||
if (!clubId.value) {
|
||||
toast.add({ severity: 'error', summary: '오류', detail: '클럽 ID가 설정되지 않았습니다.', life: 3000 });
|
||||
return;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="period-selector">
|
||||
<select v-model="selectedPeriod" @change="loadStatistics">
|
||||
<select v-model="selectedPeriod" @change="onPeriodChange">
|
||||
<option value="30">최근 30일</option>
|
||||
<option value="90">최근 90일</option>
|
||||
<option value="180">최근 180일</option>
|
||||
@@ -184,6 +184,7 @@
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, computed } from 'vue';
|
||||
import { useGtag } from 'vue-gtag-next';
|
||||
import { Bar as BarChart, Line as LineChart } from 'vue-chartjs';
|
||||
import { Chart as ChartJS, CategoryScale, LinearScale, BarElement, LineElement, PointElement, Title, Tooltip, Legend } from 'chart.js';
|
||||
import apiClient from '@/services/api';
|
||||
@@ -194,6 +195,7 @@ export default {
|
||||
name: 'Statistics',
|
||||
components: { BarChart, LineChart },
|
||||
setup() {
|
||||
const gtag = useGtag();
|
||||
const stats = ref({
|
||||
summary: {},
|
||||
scoreDistribution: [],
|
||||
@@ -300,9 +302,25 @@ export default {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// Google Analytics 페이지뷰 추적
|
||||
gtag.pageview({
|
||||
page_title: '통계',
|
||||
page_path: window.location.pathname,
|
||||
page_location: window.location.href
|
||||
});
|
||||
loadStatistics();
|
||||
});
|
||||
|
||||
// 기간 변경 시 GA 이벤트
|
||||
const onPeriodChange = () => {
|
||||
gtag.event('change_period', {
|
||||
'event_category': '통계',
|
||||
'event_label': selectedPeriod.value + '일',
|
||||
'value': Number(selectedPeriod.value)
|
||||
});
|
||||
loadStatistics();
|
||||
};
|
||||
|
||||
return {
|
||||
stats,
|
||||
selectedPeriod,
|
||||
@@ -314,7 +332,8 @@ export default {
|
||||
attendanceTrendChartData,
|
||||
attendanceTrendChartOptions,
|
||||
participantTrendChartData,
|
||||
getHandicapTrendChartData
|
||||
getHandicapTrendChartData,
|
||||
onPeriodChange
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user