diff --git a/package.json b/package.json index e199e52..c5cd2a3 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "@headlessui/react": "^1.7.18", "@headlessui/tailwindcss": "^0.2.0", "@lukemorales/query-key-factory": "^1.3.2", + "@next/third-parties": "^14.2.2", "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-slot": "^1.0.2", @@ -25,7 +26,7 @@ "clsx": "^2.1.0", "eslint-plugin-tailwindcss": "^3.13.1", "lucide-react": "^0.312.0", - "next": "14.0.4", + "next": "14.2.2", "next-themes": "^0.2.1", "react": "^18", "react-dom": "^18", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 24f50db..257af92 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ dependencies: '@lukemorales/query-key-factory': specifier: ^1.3.2 version: 1.3.2(@tanstack/query-core@5.17.9)(@tanstack/react-query@5.17.9) + '@next/third-parties': + specifier: ^14.2.2 + version: 14.2.2(next@14.2.2)(react@18.2.0) '@radix-ui/react-accordion': specifier: ^1.1.2 version: 1.1.2(@types/react-dom@18.2.18)(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0) @@ -51,11 +54,11 @@ dependencies: specifier: ^0.312.0 version: 0.312.0(react@18.2.0) next: - specifier: 14.0.4 - version: 14.0.4(react-dom@18.2.0)(react@18.2.0) + specifier: 14.2.2 + version: 14.2.2(react-dom@18.2.0)(react@18.2.0) next-themes: specifier: ^0.2.1 - version: 0.2.1(next@14.0.4)(react-dom@18.2.0)(react@18.2.0) + version: 0.2.1(next@14.2.2)(react-dom@18.2.0)(react@18.2.0) react: specifier: ^18 version: 18.2.0 @@ -603,8 +606,8 @@ packages: '@tanstack/react-query': 5.17.9(react@18.2.0) dev: false - /@next/env@14.0.4: - resolution: {integrity: sha512-irQnbMLbUNQpP1wcE5NstJtbuA/69kRfzBrpAD7Gsn8zm/CY6YQYc3HQBz8QPxwISG26tIm5afvvVbu508oBeQ==} + /@next/env@14.2.2: + resolution: {integrity: sha512-sk72qRfM1Q90XZWYRoJKu/UWlTgihrASiYw/scb15u+tyzcze3bOuJ/UV6TBOQEeUaxOkRqGeuGUdiiuxc5oqw==} dev: false /@next/eslint-plugin-next@14.0.4: @@ -613,8 +616,8 @@ packages: glob: 7.1.7 dev: true - /@next/swc-darwin-arm64@14.0.4: - resolution: {integrity: sha512-mF05E/5uPthWzyYDyptcwHptucf/jj09i2SXBPwNzbgBNc+XnwzrL0U6BmPjQeOL+FiB+iG1gwBeq7mlDjSRPg==} + /@next/swc-darwin-arm64@14.2.2: + resolution: {integrity: sha512-3iPgMhzbalizGwHNFUcGnDhFPSgVBHQ8aqSTAMxB5BvJG0oYrDf1WOJZlbXBgunOEj/8KMVbejEur/FpvFsgFQ==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] @@ -622,8 +625,8 @@ packages: dev: false optional: true - /@next/swc-darwin-x64@14.0.4: - resolution: {integrity: sha512-IZQ3C7Bx0k2rYtrZZxKKiusMTM9WWcK5ajyhOZkYYTCc8xytmwSzR1skU7qLgVT/EY9xtXDG0WhY6fyujnI3rw==} + /@next/swc-darwin-x64@14.2.2: + resolution: {integrity: sha512-x7Afi/jt0ZBRUZHTi49yyej4o8znfIMHO4RvThuoc0P+uli8Jd99y5GKjxoYunPKsXL09xBXEM1+OQy2xEL0Ag==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] @@ -631,8 +634,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-gnu@14.0.4: - resolution: {integrity: sha512-VwwZKrBQo/MGb1VOrxJ6LrKvbpo7UbROuyMRvQKTFKhNaXjUmKTu7wxVkIuCARAfiI8JpaWAnKR+D6tzpCcM4w==} + /@next/swc-linux-arm64-gnu@14.2.2: + resolution: {integrity: sha512-zbfPtkk7L41ODMJwSp5VbmPozPmMMQrzAc0HAUomVeVIIwlDGs/UCqLJvLNDt4jpWgc21SjjyIn762lNGrMaUA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -640,8 +643,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-musl@14.0.4: - resolution: {integrity: sha512-8QftwPEW37XxXoAwsn+nXlodKWHfpMaSvt81W43Wh8dv0gkheD+30ezWMcFGHLI71KiWmHK5PSQbTQGUiidvLQ==} + /@next/swc-linux-arm64-musl@14.2.2: + resolution: {integrity: sha512-wPbS3pI/JU16rm3XdLvvTmlsmm1nd+sBa2ohXgBZcShX4TgOjD4R+RqHKlI1cjo/jDZKXt6OxmcU0Iys0OC/yg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -649,8 +652,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-gnu@14.0.4: - resolution: {integrity: sha512-/s/Pme3VKfZAfISlYVq2hzFS8AcAIOTnoKupc/j4WlvF6GQ0VouS2Q2KEgPuO1eMBwakWPB1aYFIA4VNVh667A==} + /@next/swc-linux-x64-gnu@14.2.2: + resolution: {integrity: sha512-NqWOHqqq8iC9tuHvZxjQ2tX+jWy2X9y8NX2mcB4sj2bIccuCxbIZrU/ThFPZZPauygajZuVQ6zediejQHwZHwQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -658,8 +661,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-musl@14.0.4: - resolution: {integrity: sha512-m8z/6Fyal4L9Bnlxde5g2Mfa1Z7dasMQyhEhskDATpqr+Y0mjOBZcXQ7G5U+vgL22cI4T7MfvgtrM2jdopqWaw==} + /@next/swc-linux-x64-musl@14.2.2: + resolution: {integrity: sha512-lGepHhwb9sGhCcU7999+iK1ZZT+6rrIoVg40MP7DZski9GIZP80wORSbt5kJzh9v2x2ev2lxC6VgwMQT0PcgTA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -667,8 +670,8 @@ packages: dev: false optional: true - /@next/swc-win32-arm64-msvc@14.0.4: - resolution: {integrity: sha512-7Wv4PRiWIAWbm5XrGz3D8HUkCVDMMz9igffZG4NB1p4u1KoItwx9qjATHz88kwCEal/HXmbShucaslXCQXUM5w==} + /@next/swc-win32-arm64-msvc@14.2.2: + resolution: {integrity: sha512-TZSh/48SfcLEQ4rD25VVn2kdIgUWmMflRX3OiyPwGNXn3NiyPqhqei/BaqCYXViIQ+6QsG9R0C8LftMqy8JPMA==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] @@ -676,8 +679,8 @@ packages: dev: false optional: true - /@next/swc-win32-ia32-msvc@14.0.4: - resolution: {integrity: sha512-zLeNEAPULsl0phfGb4kdzF/cAVIfaC7hY+kt0/d+y9mzcZHsMS3hAS829WbJ31DkSlVKQeHEjZHIdhN+Pg7Gyg==} + /@next/swc-win32-ia32-msvc@14.2.2: + resolution: {integrity: sha512-M0tBVNMEBJN2ZNQWlcekMn6pvLria7Sa2Fai5znm7CCJz4pP3lrvlSxhKdkCerk0D9E0bqx5yAo3o2Q7RrD4gA==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] @@ -685,8 +688,8 @@ packages: dev: false optional: true - /@next/swc-win32-x64-msvc@14.0.4: - resolution: {integrity: sha512-yEh2+R8qDlDCjxVpzOTEpBLQTEFAcP2A8fUFLaWNap9GitYKkKv1//y2S6XY6zsR4rCOPRpU7plYDR+az2n30A==} + /@next/swc-win32-x64-msvc@14.2.2: + resolution: {integrity: sha512-a/20E/wtTJZ3Ykv3f/8F0l7TtgQa2LWHU2oNB9bsu0VjqGuGGHmm/q6waoUNQYTVPYrrlxxaHjJcDV6aiSTt/w==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -694,6 +697,17 @@ packages: dev: false optional: true + /@next/third-parties@14.2.2(next@14.2.2)(react@18.2.0): + resolution: {integrity: sha512-udHgllytb8GPbqghxIDf09E7x/4hYgp7WjmfH1Z3u4EG29Mhf12NyXpc49wtd0k3rLydunqDa4MH9ej2y5Ph/A==} + peerDependencies: + next: ^13.0.0 || ^14.0.0 + react: ^18.2.0 + dependencies: + next: 14.2.2(react-dom@18.2.0)(react@18.2.0) + react: 18.2.0 + third-party-capital: 1.0.20 + dev: false + /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1418,9 +1432,14 @@ packages: tslib: 2.6.2 dev: true - /@swc/helpers@0.5.2: - resolution: {integrity: sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==} + /@swc/counter@0.1.3: + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + dev: false + + /@swc/helpers@0.5.5: + resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} dependencies: + '@swc/counter': 0.1.3 tslib: 2.6.2 dev: false @@ -2063,6 +2082,11 @@ packages: /caniuse-lite@1.0.30001576: resolution: {integrity: sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg==} + dev: true + + /caniuse-lite@1.0.30001611: + resolution: {integrity: sha512-19NuN1/3PjA3QI8Eki55N8my4LzfkMCRLgCVfrl/slbSAchQfV0+GwjPrK3rq37As4UCLlM/DHajbKkAqbv92Q==} + dev: false /chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} @@ -3069,10 +3093,6 @@ packages: dependencies: is-glob: 4.0.3 - /glob-to-regexp@0.4.1: - resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - dev: false - /glob@10.3.10: resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} engines: {node: '>=16 || 14 >=14.17'} @@ -3733,53 +3753,55 @@ packages: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true - /next-themes@0.2.1(next@14.0.4)(react-dom@18.2.0)(react@18.2.0): + /next-themes@0.2.1(next@14.2.2)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==} peerDependencies: next: '*' react: '*' react-dom: '*' dependencies: - next: 14.0.4(react-dom@18.2.0)(react@18.2.0) + next: 14.2.2(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /next@14.0.4(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-qbwypnM7327SadwFtxXnQdGiKpkuhaRLE2uq62/nRul9cj9KhQ5LhHmlziTNqUidZotw/Q1I9OjirBROdUJNgA==} + /next@14.2.2(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-oGwUaa2bCs47FbuxWMpOoXtBMPYpvTPgdZr3UAo+pu7Ns00z9otmYpoeV1HEiYL06AlRQQIA/ypK526KjJfaxg==} engines: {node: '>=18.17.0'} hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 react: ^18.2.0 react-dom: ^18.2.0 sass: ^1.3.0 peerDependenciesMeta: '@opentelemetry/api': optional: true + '@playwright/test': + optional: true sass: optional: true dependencies: - '@next/env': 14.0.4 - '@swc/helpers': 0.5.2 + '@next/env': 14.2.2 + '@swc/helpers': 0.5.5 busboy: 1.6.0 - caniuse-lite: 1.0.30001576 + caniuse-lite: 1.0.30001611 graceful-fs: 4.2.11 postcss: 8.4.31 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) styled-jsx: 5.1.1(react@18.2.0) - watchpack: 2.4.0 optionalDependencies: - '@next/swc-darwin-arm64': 14.0.4 - '@next/swc-darwin-x64': 14.0.4 - '@next/swc-linux-arm64-gnu': 14.0.4 - '@next/swc-linux-arm64-musl': 14.0.4 - '@next/swc-linux-x64-gnu': 14.0.4 - '@next/swc-linux-x64-musl': 14.0.4 - '@next/swc-win32-arm64-msvc': 14.0.4 - '@next/swc-win32-ia32-msvc': 14.0.4 - '@next/swc-win32-x64-msvc': 14.0.4 + '@next/swc-darwin-arm64': 14.2.2 + '@next/swc-darwin-x64': 14.2.2 + '@next/swc-linux-arm64-gnu': 14.2.2 + '@next/swc-linux-arm64-musl': 14.2.2 + '@next/swc-linux-x64-gnu': 14.2.2 + '@next/swc-linux-x64-musl': 14.2.2 + '@next/swc-win32-arm64-msvc': 14.2.2 + '@next/swc-win32-ia32-msvc': 14.2.2 + '@next/swc-win32-x64-msvc': 14.2.2 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -4811,6 +4833,10 @@ packages: dependencies: any-promise: 1.3.0 + /third-party-capital@1.0.20: + resolution: {integrity: sha512-oB7yIimd8SuGptespDAZnNkzIz+NWaJCu2RMsbs4Wmp9zSDUM8Nhi3s2OOcqYuv3mN4hitXc8DVx+LyUmbUDiA==} + dev: false + /tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} dev: false @@ -5056,14 +5082,6 @@ packages: d3-timer: 3.0.1 dev: false - /watchpack@2.4.0: - resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==} - engines: {node: '>=10.13.0'} - dependencies: - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - dev: false - /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: true diff --git a/src/app/(landing)/_components/floating-footer.tsx b/src/app/(landing)/_components/floating-footer.tsx index 0762aeb..101eabc 100644 --- a/src/app/(landing)/_components/floating-footer.tsx +++ b/src/app/(landing)/_components/floating-footer.tsx @@ -1,6 +1,7 @@ "use client"; import { Button } from "@/components/common/button/button"; +import { sendGAEvent } from "@next/third-parties/google"; import { useRouter } from "next/navigation"; import React from "react"; @@ -9,6 +10,10 @@ const FloatingFooter = React.memo(() => { const onButtonClick = React.useCallback(() => { router.push("/ticker"); + sendGAEvent({ + event: "buttonClicked", + value: "Landing Page", + }); }, [router]); return ( diff --git a/src/app/global-provider.tsx b/src/app/global-provider.tsx index 1d385b0..5bd1ff3 100644 --- a/src/app/global-provider.tsx +++ b/src/app/global-provider.tsx @@ -1,11 +1,11 @@ "use client"; +import { GoogleAnalytics } from "@next/third-parties/google"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; -import { hotjar } from 'react-hotjar'; +import { hotjar } from "react-hotjar"; import axios, { AxiosError, AxiosResponse } from "axios"; import React from "react"; -import GAProvider from "./ga-provider"; export const queryClient = new QueryClient({ defaultOptions: { @@ -34,10 +34,10 @@ export const GlobalProvider = ({ children }: { children: React.ReactNode }) => { const [client] = React.useState(() => new QueryClient()); React.useEffect(() => { - if (process.env.NODE_ENV !== 'development') { + if (process.env.NODE_ENV !== "development") { hotjar.initialize({ id: HJID, - sv: HJSV + sv: HJSV, }); } }, []); @@ -45,7 +45,8 @@ export const GlobalProvider = ({ children }: { children: React.ReactNode }) => { return ( {children} - + {/* */} + ); diff --git a/src/utils/gtag.js b/src/utils/gtag.js new file mode 100644 index 0000000..22d3f58 --- /dev/null +++ b/src/utils/gtag.js @@ -0,0 +1,23 @@ +export const GA_TRACKING_ID = "G-K20DRKXNTC"; + +// https://developers.google.com/analytics/devguides/collection/gtagjs/pages +export const pageview = (url) => { + if (typeof window !== "undefined") { + console.log(url); + window.gtag("config", GA_TRACKING_ID, { + page_path: url, + }); + } +}; + +// https://developers.google.com/analytics/devguides/collection/gtagjs/events +export const event = ({ action, category, label, value }) => { + if (typeof window !== "undefined") { + console.log(action, category, label, value) + window.gtag("event", action, { + event_category: category, + event_label: label, + value: value, + }); + } +}; diff --git a/tsconfig.json b/tsconfig.json index 6c2aa52..d2e2bf7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,6 +22,13 @@ "@/*": ["./src/*"] } }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "src/api/generated/endpoint.schemas.ts"], + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + "src/api/generated/endpoint.schemas.ts", + "src/utils/gtag.js" + ], "exclude": ["node_modules"] }