diff --git a/package.json b/package.json index 3b1ef9ba..b21dc9ee 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "react-copy-to-clipboard": "^5.1.0", "react-dom": "^18.2.0", "react-error-boundary": "^4.0.11", + "react-ga4": "^2.1.0", "react-konva": "^18.2.10", "react-query": "^3.39.3", "react-router-dom": "^6.23.0", diff --git a/src/App.tsx b/src/App.tsx index a1dbd565..ab253543 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,8 +4,11 @@ import Router from "./Router"; import "./core/notification/settingFCM"; import { GlobalStyle } from "./style/globalStyle"; import { theme } from "./style/theme"; +import REACTGA from "react-ga4"; export default function App() { + REACTGA.initialize(import.meta.env.VITE_APP_GOOGLE_ANALYTICS); + return ( diff --git a/src/components/LessonConnect.tsx/LessonConnectNumber.tsx b/src/components/LessonConnect.tsx/LessonConnectNumber.tsx new file mode 100644 index 00000000..ed3503b0 --- /dev/null +++ b/src/components/LessonConnect.tsx/LessonConnectNumber.tsx @@ -0,0 +1,86 @@ +import { useState } from "react"; +import { useSetRecoilState } from "recoil"; +import { styled } from "styled-components"; +import { parentsPhoneState } from "../../atom/registerLesson/registerLesson"; +import { BUTTON_TEXT } from "../../core/signup/signUpTextLabels"; +import useFormattedPhoneNumber from "../../hooks/signupLogin/usePhoneNumberFormat"; +import { BackButton, BottomButton, ProgressBar } from "../common"; +import InputLayout from "../signup/InputLayout"; +import SignupTitleLayout from "../signup/SignupTitleLayout"; + +interface LessonConnectNumberProps { + handlePassStep: () => void; +} + +export default function LessonConnectNumber({ handlePassStep }: LessonConnectNumberProps) { + const [isActive, setIsActive] = useState(false); + const [phoneNumber, setPhoneNumber] = useFormattedPhoneNumber(); + const setParentPhone = useSetRecoilState(parentsPhoneState); + + function handleDoneClick() { + handlePassStep(); + // alert("준비 중인 기능입니다."); + } + + function handleChangeNumber(value: string) { + setPhoneNumber(value); + setIsActive(true); + setParentPhone(phoneNumber.replace(/\D+/g, "")); + } + + return ( + <> + + + + + + + 과외 수업 관리를 위해
+ 연동할 휴대폰 번호를 입력해주세요 +
+ + 앱 PUSH 알림을 받으실
학부모님의 전화번호를 입력해주세요 +
+ +
+ + + ); +} + +const Container = styled.section` + display: flex; + flex-direction: column; + + padding-left: 1.6rem; + margin-top: 2.8rem; +`; + +const RadioWrapper = styled.div` + margin-top: 5.08rem; +`; + +const BackButtonWrapper = styled.div` + margin-left: 2rem; +`; + +const InputNotice = styled.h2` + display: flex; + + margin-top: 0.8rem; + + ${({ theme }) => theme.fonts.body05}; + color: ${({ theme }) => theme.colors.grey600}; +`; diff --git a/src/components/RegularLesson/Footer.tsx b/src/components/RegularLesson/Footer.tsx index ff10d463..4d4a97bf 100644 --- a/src/components/RegularLesson/Footer.tsx +++ b/src/components/RegularLesson/Footer.tsx @@ -18,6 +18,8 @@ import useGetValidateTimesRange from "../../hooks/useGetValidateTimeRange"; import useModal from "../../hooks/useModal"; import CreateImpossibleModal from "../modal/CreateImpossibleModal"; +import REACTGA from "react-ga4"; + export default function Footer() { const navigate = useNavigate(); const { openModal, showModal } = useModal(); @@ -45,6 +47,10 @@ export default function Footer() { } else { showModal(); } + REACTGA.event({ + category: "정기 수업 일정 다음 버튼", + action: "click", + }); } return ( diff --git a/src/components/lessonShare/KakaoShare.tsx b/src/components/lessonShare/KakaoShare.tsx index 716ecc94..75948569 100644 --- a/src/components/lessonShare/KakaoShare.tsx +++ b/src/components/lessonShare/KakaoShare.tsx @@ -5,6 +5,8 @@ import { ShareViaKakao } from "../../assets"; import { studentNameState } from "../../atom/common/datePicker"; import useGetLessonByUser from "../../hooks/useGetLessonByUser"; +import REACTGA from "react-ga4"; + interface KakaoShareProp { url: string; } @@ -60,6 +62,10 @@ export function KakaoShare(props: KakaoShareProp) { ], }); } + REACTGA.event({ + category: "카카오톡으로 공유", + action: "Share", + }); } return ( diff --git a/src/components/lessonShare/ShareComplete.tsx b/src/components/lessonShare/ShareComplete.tsx index e9ac8f92..db934968 100644 --- a/src/components/lessonShare/ShareComplete.tsx +++ b/src/components/lessonShare/ShareComplete.tsx @@ -3,9 +3,19 @@ import styled from "styled-components"; import { BackButtonSignupIc, CheckLargeIcon } from "../../assets"; import { BottomButton } from "../common"; +import REACTGA from "react-ga4"; + export default function ShareComplete({ handleMoveToPage }: { handleMoveToPage: (page: string) => void }) { const navigate = useNavigate(); + function handleOnClickToHome() { + navigate("/home"); + REACTGA.event({ + category: "홈으로가기", + action: "GotoHome", + }); + } + return ( <> handleMoveToPage("M")} /> @@ -16,13 +26,7 @@ export default function ShareComplete({ handleMoveToPage }: { handleMoveToPage: 학부모님이 전화번호를 등록하시면
자동으로 등록될거에요 - { - navigate("/home"); - }} - isActive={true} - disabled={false}> + handleOnClickToHome()} isActive={true} disabled={false}> 홈으로 가기 diff --git a/src/components/lessonShare/ShareMain.tsx b/src/components/lessonShare/ShareMain.tsx index 3a3e7b92..eece1fd9 100644 --- a/src/components/lessonShare/ShareMain.tsx +++ b/src/components/lessonShare/ShareMain.tsx @@ -10,6 +10,8 @@ import { handleMoveToPageProps } from "../../pages/LessonShare"; import { BottomButton, ProgressBar } from "../common"; import { KakaoShare } from "./KakaoShare"; +import REACTGA from "react-ga4"; + interface dayProps { year: number; month: number; @@ -42,6 +44,10 @@ export default function ShareMain({ handleMoveToPage }: handleMoveToPageProps) { text: "기타", onClick: () => { handleShareOtherWays(); + REACTGA.event({ + category: "문자메세지로 공유", + action: "share", + }); }, }, ]; @@ -52,6 +58,10 @@ export default function ShareMain({ handleMoveToPage }: handleMoveToPageProps) { function handleMoveToHome() { navigate("/home"); + REACTGA.event({ + category: "나중에 공유", + action: "Not Share", + }); } function handleShareOtherWays() { diff --git a/src/components/manageLesson/ExtensionLessonModal.tsx b/src/components/manageLesson/ExtensionLessonModal.tsx index 473bc774..91f31fa2 100644 --- a/src/components/manageLesson/ExtensionLessonModal.tsx +++ b/src/components/manageLesson/ExtensionLessonModal.tsx @@ -9,6 +9,7 @@ import useModal from "../../hooks/useModal"; import RoundBottomMiniButton from "../common/RoundBottomMiniButton"; import StudentNameLabel from "../common/StudentNameLabel"; import ToastModal from "../common/ToastModal"; +import REACTGA from "react-ga4"; interface ExtensionLessonModalProps { setIsClickedMainteance: React.Dispatch>; @@ -53,6 +54,10 @@ export default function ExtensionLessonModal(props: ExtensionLessonModalProps) { unShowModal(); setSnackBarOpen(true); setIsSuccess(true); + REACTGA.event({ + category: "연장할래요", + action: "click extension", + }); } function handleNotExtensionLesson(info: createLessonMaintenanceProps) { diff --git a/src/pages/CompleteCheckAttendance.tsx b/src/pages/CompleteCheckAttendance.tsx index 5d047c6b..2d433d15 100644 --- a/src/pages/CompleteCheckAttendance.tsx +++ b/src/pages/CompleteCheckAttendance.tsx @@ -17,6 +17,7 @@ import { ATTENDANCE_STATUS } from "../core/common/attendanceStatus"; import { STUDENT_COLOR } from "../core/common/studentColor"; import useModal from "../hooks/useModal"; import useTeacherFooter from "../hooks/useTeacherFooter"; +import REACTGA from "react-ga4"; export default function CompleteCheckAttendance() { const { state } = useLocation(); @@ -50,10 +51,18 @@ export default function CompleteCheckAttendance() { function handleMoveToHome() { setSnackBarOpen(true); navigate(-1); + REACTGA.event({ + category: "출결체크 > 확인", + action: "Confirm", + }); } function handleOpenSendAlarmModal() { showModal(); + REACTGA.event({ + category: "출결체크 > 학부모 알림 전송", + action: "Send Alarm to Parents", + }); } return ( diff --git a/src/pages/LessonRegisterComplete.tsx b/src/pages/LessonRegisterComplete.tsx index 27469bc4..a6663b0f 100644 --- a/src/pages/LessonRegisterComplete.tsx +++ b/src/pages/LessonRegisterComplete.tsx @@ -8,6 +8,8 @@ import { dateState, dayState } from "../atom/timePicker/timePicker"; import ButtonLayout from "../components/welcomeSignup/ButtonLayout"; import { STUDENT_COLOR } from "../core/common/studentColor"; +import REACTGA from "react-ga4"; + export default function LessonRegisterComplete() { const navigate = useNavigate(); @@ -20,6 +22,22 @@ export default function LessonRegisterComplete() { navigate(path); } + function onClickShareButton() { + onHandleNavigate("/lesson-share"); + REACTGA.event({ + category: "학부모와 함께 관리", + action: "Click", + }); + } + + function onClickJumpButton() { + onHandleNavigate("/home"); + REACTGA.event({ + category: "건너뛰고 혼자 관리", + action: "Click", + }); + } + return ( <> @@ -50,8 +68,8 @@ export default function LessonRegisterComplete() { onHandleNavigate("/lesson-share")} - onClickJump={() => onHandleNavigate("/home")} + onClickButton={() => onClickShareButton()} + onClickJump={() => onClickJumpButton()} /> diff --git a/src/pages/OnBoarding.tsx b/src/pages/OnBoarding.tsx index f971a460..83e6818e 100644 --- a/src/pages/OnBoarding.tsx +++ b/src/pages/OnBoarding.tsx @@ -1,4 +1,5 @@ import { useEffect, useRef, useState } from "react"; +import REACTGA from "react-ga4"; import { useLocation, useNavigate } from "react-router-dom"; import Slider from "react-slick"; import "slick-carousel/slick/slick-theme.css"; @@ -42,7 +43,15 @@ export default function OnBoarding() { }; const handleClickBtn = () => { - isLastSwipe ? navigate("/landing") : sliderRef?.current?.slickNext(); + if (isLastSwipe) { + navigate("/landing"); + REACTGA.event({ + category: "시작하기버튼", + action: "click", + }); + } else { + sliderRef?.current?.slickNext(); + } }; return ( diff --git a/yarn.lock b/yarn.lock index bde214e6..8db6c086 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4127,6 +4127,11 @@ react-error-boundary@^4.0.11: dependencies: "@babel/runtime" "^7.12.5" +react-ga4@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/react-ga4/-/react-ga4-2.1.0.tgz#56601f59d95c08466ebd6edfbf8dede55c4678f9" + integrity sha512-ZKS7PGNFqqMd3PJ6+C2Jtz/o1iU9ggiy8Y8nUeksgVuvNISbmrQtJiZNvC/TjDsqD0QlU5Wkgs7i+w9+OjHhhQ== + react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"