diff --git a/.env b/.env new file mode 100644 index 000000000..e081694c9 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +REACT_APP_SEGMENT_SOURCE_KEY='yEVKwWFjOEqjTWJbq7iN8IxkJ5dghbB1' \ No newline at end of file diff --git a/.gitignore b/.gitignore index 04c5395ee..b3d04c1bf 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ node_modules # misc .DS_Store +.env .env.local .env.development.local .env.test.local diff --git a/package-lock.json b/package-lock.json index e0093957c..e19e227f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.1.0", "dependencies": { "@reduxjs/toolkit": "^1.8.5", + "@segment/analytics-next": "^1.77.0", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", @@ -3275,6 +3276,27 @@ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, + "node_modules/@lukeed/csprng": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz", + "integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@lukeed/uuid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@lukeed/uuid/-/uuid-2.0.1.tgz", + "integrity": "sha512-qC72D4+CDdjGqJvkFMMEAtancHUQ7/d/tAiHf64z8MopFDmcrtbcJuerDtFceuAfQJ2pDSfCKCtbqoGBNnwg0w==", + "license": "MIT", + "dependencies": { + "@lukeed/csprng": "^1.1.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", @@ -3504,6 +3526,87 @@ "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.3.tgz", "integrity": "sha512-0xd7qez0AQ+MbHatZTlI1gu5vkG8r7MYRUJAHPAHJBmGLs16zpkrpAVLvjQKQOqaXPDUBwOiJzNc00znHSCVBw==" }, + "node_modules/@segment/analytics-core": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@segment/analytics-core/-/analytics-core-1.8.1.tgz", + "integrity": "sha512-EYcdBdhfi1pOYRX+Sf5orpzzYYFmDHTEu6+w0hjXpW5bWkWct+Nv6UJg1hF4sGDKEQjpZIinLTpQ4eioFM4KeQ==", + "license": "MIT", + "dependencies": { + "@lukeed/uuid": "^2.0.0", + "@segment/analytics-generic-utils": "1.2.0", + "dset": "^3.1.4", + "tslib": "^2.4.1" + } + }, + "node_modules/@segment/analytics-generic-utils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@segment/analytics-generic-utils/-/analytics-generic-utils-1.2.0.tgz", + "integrity": "sha512-DfnW6mW3YQOLlDQQdR89k4EqfHb0g/3XvBXkovH1FstUN93eL1kfW9CsDcVQyH3bAC5ZsFyjA/o/1Q2j0QeoWw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.4.1" + } + }, + "node_modules/@segment/analytics-next": { + "version": "1.77.0", + "resolved": "https://registry.npmjs.org/@segment/analytics-next/-/analytics-next-1.77.0.tgz", + "integrity": "sha512-xZiSz8iOPoiYt0K0w3fMG5khaPzeLuALfQYUvle6rfNnhjs8N0WiV1Vx/EwgtJPPw3saol5n4oW8xhcGWeQAIA==", + "license": "MIT", + "dependencies": { + "@lukeed/uuid": "^2.0.0", + "@segment/analytics-core": "1.8.1", + "@segment/analytics-generic-utils": "1.2.0", + "@segment/analytics.js-video-plugins": "^0.2.1", + "@segment/facade": "^3.4.9", + "dset": "^3.1.4", + "js-cookie": "3.0.1", + "node-fetch": "^2.6.7", + "tslib": "^2.4.1", + "unfetch": "^4.1.0" + } + }, + "node_modules/@segment/analytics.js-video-plugins": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@segment/analytics.js-video-plugins/-/analytics.js-video-plugins-0.2.1.tgz", + "integrity": "sha512-lZwCyEXT4aaHBLNK433okEKdxGAuyrVmop4BpQqQSJuRz0DglPZgd9B/XjiiWs1UyOankg2aNYMN3VcS8t4eSQ==", + "license": "ISC", + "dependencies": { + "unfetch": "^3.1.1" + } + }, + "node_modules/@segment/analytics.js-video-plugins/node_modules/unfetch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-3.1.2.tgz", + "integrity": "sha512-L0qrK7ZeAudGiKYw6nzFjnJ2D5WHblUBwmHIqtPS6oKUd+Hcpk7/hKsSmcHsTlpd1TbTNsiRBUKRq3bHLNIqIw==", + "license": "MIT" + }, + "node_modules/@segment/facade": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/@segment/facade/-/facade-3.4.10.tgz", + "integrity": "sha512-xVQBbB/lNvk/u8+ey0kC/+g8pT3l0gCT8O2y9Z+StMMn3KAFAQ9w8xfgef67tJybktOKKU7pQGRPolRM1i1pdA==", + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "@segment/isodate-traverse": "^1.1.1", + "inherits": "^2.0.4", + "new-date": "^1.0.3", + "obj-case": "0.2.1" + } + }, + "node_modules/@segment/isodate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@segment/isodate/-/isodate-1.0.3.tgz", + "integrity": "sha512-BtanDuvJqnACFkeeYje7pWULVv8RgZaqKHWwGFnL/g/TH/CcZjkIVTfGDp/MAxmilYHUkrX70SqwnYSTNEaN7A==", + "license": "SEE LICENSE IN LICENSE" + }, + "node_modules/@segment/isodate-traverse": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@segment/isodate-traverse/-/isodate-traverse-1.1.1.tgz", + "integrity": "sha512-+G6e1SgAUkcq0EDMi+SRLfT48TNlLPF3QnSgFGVs0V9F3o3fq/woQ2rHFlW20W0yy5NnCUH0QGU3Am2rZy/E3w==", + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "@segment/isodate": "^1.0.3" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -6883,6 +6986,15 @@ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" }, + "node_modules/dset": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz", + "integrity": "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", @@ -11505,6 +11617,15 @@ "jiti": "bin/jiti.js" } }, + "node_modules/js-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz", + "integrity": "sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -12144,6 +12265,15 @@ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, + "node_modules/new-date": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/new-date/-/new-date-1.0.3.tgz", + "integrity": "sha512-0fsVvQPbo2I18DT2zVHpezmeeNYV2JaJSrseiHLc17GNOxJzUdx5mvSigPu8LtIfZSij5i1wXnXFspEs2CD6hA==", + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "@segment/isodate": "1.0.3" + } + }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -12153,6 +12283,48 @@ "tslib": "^2.0.3" } }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", @@ -12225,6 +12397,12 @@ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==" }, + "node_modules/obj-case": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/obj-case/-/obj-case-0.2.1.tgz", + "integrity": "sha512-PquYBBTy+Y6Ob/O2574XHhDtHJlV1cJHMCgW+rDRc9J5hhmRelJB3k5dTK/3cVmFVtzvAKuENeuLpoyTzMzkOg==", + "license": "MIT" + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -16371,6 +16549,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/unfetch": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", + "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==", + "license": "MIT" + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", diff --git a/package.json b/package.json index d5ff59fa3..5ff8fe9a4 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "private": true, "dependencies": { "@reduxjs/toolkit": "^1.8.5", + "@segment/analytics-next": "^1.77.0", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", diff --git a/src/index.js b/src/index.js index 553454b35..86dc052f1 100644 --- a/src/index.js +++ b/src/index.js @@ -1,11 +1,11 @@ -import React from "react"; +import React, { useEffect } from "react"; import ReactDOM from "react-dom/client"; import "../node_modules/font-awesome/css/font-awesome.min.css"; import "../node_modules/bootstrap/dist/css/bootstrap.min.css"; import { BrowserRouter, Routes, Route } from "react-router-dom"; import { Provider } from "react-redux"; import store from "./redux/store"; - +import analytics from "./lib/segment"; // Import Segment import { Home, Product, @@ -21,26 +21,34 @@ import { import ScrollToTop from "./components/ScrollToTop"; import { Toaster } from "react-hot-toast"; +const Root = () => { + useEffect(() => { + analytics.page(); // Track page views on load + }, []); + + return ( + + + + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + + + + + ); +}; + const root = ReactDOM.createRoot(document.getElementById("root")); -root.render( - - - - - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - - - - - -); +root.render(); diff --git a/src/lib/segment.js b/src/lib/segment.js new file mode 100644 index 000000000..4e9dd2bfc --- /dev/null +++ b/src/lib/segment.js @@ -0,0 +1,7 @@ +import { AnalyticsBrowser } from '@segment/analytics-next' + + +const analytics = new AnalyticsBrowser() +analytics.load({ writeKey: process.env.REACT_APP_SEGMENT_SOURCE_KEY}) + +export default analytics \ No newline at end of file diff --git a/src/pages/AboutPage.jsx b/src/pages/AboutPage.jsx index 020eb52cc..e137e7926 100644 --- a/src/pages/AboutPage.jsx +++ b/src/pages/AboutPage.jsx @@ -1,6 +1,13 @@ import React from 'react' +import { useEffect } from 'react'; +import analytics from '../lib/segment'; import { Footer, Navbar } from "../components"; + const AboutPage = () => { + useEffect(() => { + analytics.page(); // Track page views on load + }, []); + return ( <> diff --git a/src/pages/Cart.jsx b/src/pages/Cart.jsx index 662ca86bc..fd4457d34 100644 --- a/src/pages/Cart.jsx +++ b/src/pages/Cart.jsx @@ -1,13 +1,18 @@ -import React from "react"; +import React, { useEffect } from "react"; import { Footer, Navbar } from "../components"; import { useSelector, useDispatch } from "react-redux"; import { addCart, delCart } from "../redux/action"; import { Link } from "react-router-dom"; +import analytics from "../lib/segment"; const Cart = () => { const state = useSelector((state) => state.handleCart); const dispatch = useDispatch(); + useEffect(() => { + analytics.page(); // Track page views on load + }, []); + const EmptyCart = () => { return (
diff --git a/src/pages/Checkout.jsx b/src/pages/Checkout.jsx index d918a9c04..accfe2527 100644 --- a/src/pages/Checkout.jsx +++ b/src/pages/Checkout.jsx @@ -2,7 +2,13 @@ import React from "react"; import { Footer, Navbar } from "../components"; import { useSelector } from "react-redux"; import { Link } from "react-router-dom"; +import { useEffect } from "react"; +import analytics from "../lib/segment"; + const Checkout = () => { + useEffect(() => { + analytics.page(); // Track page views on load + }, []); const state = useSelector((state) => state.handleCart); const EmptyCart = () => { diff --git a/src/pages/ContactPage.jsx b/src/pages/ContactPage.jsx index a3d67060d..e7effa86e 100644 --- a/src/pages/ContactPage.jsx +++ b/src/pages/ContactPage.jsx @@ -1,6 +1,14 @@ import React from "react"; +import { useEffect } from "react"; +import analytics from "../lib/segment"; + import { Footer, Navbar } from "../components"; const ContactPage = () => { + + useEffect(() => { + analytics.page(); // Track page views on load + }, []); + return ( <> diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx index 693041461..79ddd7c68 100644 --- a/src/pages/Home.jsx +++ b/src/pages/Home.jsx @@ -1,6 +1,12 @@ import { Navbar, Main, Product, Footer } from "../components"; +import { useEffect } from "react"; +import analytics from "../lib/segment"; function Home() { + useEffect(() => { + analytics.page(); // Track page views on load + }, []); + return ( <> diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx index 9c687e257..f99618b2d 100644 --- a/src/pages/Login.jsx +++ b/src/pages/Login.jsx @@ -1,8 +1,13 @@ import React from "react"; import { Link } from "react-router-dom"; import { Footer, Navbar } from "../components"; +import { useEffect } from "react"; +import analytics from "../lib/segment"; const Login = () => { + useEffect(() => { + analytics.page(); // Track page views on load + }, []); return ( <> diff --git a/src/pages/PageNotFound.jsx b/src/pages/PageNotFound.jsx index 2de53748a..b4f31e447 100644 --- a/src/pages/PageNotFound.jsx +++ b/src/pages/PageNotFound.jsx @@ -1,8 +1,13 @@ import React from "react"; import { Link } from "react-router-dom"; import { Navbar } from "../components"; +import { useEffect } from "react"; +import analytics from "../lib/segment"; const PageNotFound = () => { + useEffect(() => { + analytics.page(); // Track page views on load + }, []); return ( <> diff --git a/src/pages/Product.jsx b/src/pages/Product.jsx index c8a5f6989..4b30b3506 100644 --- a/src/pages/Product.jsx +++ b/src/pages/Product.jsx @@ -4,10 +4,12 @@ import { Link, useParams } from "react-router-dom"; import Marquee from "react-fast-marquee"; import { useDispatch } from "react-redux"; import { addCart } from "../redux/action"; - +import analytics from '../lib/segment'; import { Footer, Navbar } from "../components"; + const Product = () => { + const { id } = useParams(); const [product, setProduct] = useState([]); const [similarProducts, setSimilarProducts] = useState([]); @@ -20,6 +22,10 @@ const Product = () => { dispatch(addCart(product)); }; + useEffect(() => { + analytics.page(); // Track page views on load + }, []); + useEffect(() => { const getProduct = async () => { setLoading(true); diff --git a/src/pages/Products.jsx b/src/pages/Products.jsx index 4e24b5e4d..acd518bb2 100644 --- a/src/pages/Products.jsx +++ b/src/pages/Products.jsx @@ -1,7 +1,12 @@ import React from 'react' import { Footer, Navbar, Product } from "../components" +import { useEffect } from 'react'; +import analytics from '../lib/segment'; const Products = () => { + useEffect(() => { + analytics.page(); // Track page views on load + }, []); return ( <> diff --git a/src/pages/Register.jsx b/src/pages/Register.jsx index a8e93bf06..75838acb9 100644 --- a/src/pages/Register.jsx +++ b/src/pages/Register.jsx @@ -1,7 +1,13 @@ import React from 'react' import { Footer, Navbar } from "../components"; import { Link } from 'react-router-dom'; +import { useEffect } from 'react'; +import analytics from '../lib/segment'; + const Register = () => { + useEffect(() => { + analytics.page(); // Track page views on load + }, []); return ( <>