diff --git a/app/hooks/useSession.ts b/app/hooks/useSession.ts new file mode 100644 index 0000000..0ddd9bb --- /dev/null +++ b/app/hooks/useSession.ts @@ -0,0 +1,19 @@ +import { useState, useEffect } from "react"; +import { v4 as uuidv4 } from "uuid"; + +export const useSession = () => { + const [sessionId, setSessionId] = useState(null); + + useEffect(() => { + let currentId = sessionStorage.getItem("session_id"); + + if (!currentId) { + currentId = uuidv4(); + sessionStorage.setItem("session_id", currentId); + } + + setSessionId(currentId); + }, []); + + return sessionId; +}; diff --git a/app/layout.tsx b/app/layout.tsx index 9aaa0ce..747047c 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,39 +1,40 @@ -import type { Metadata } from 'next'; -import localFont from 'next/font/local'; -import Image from 'next/image'; -import NavBar from '@/components/NavBar'; +import type { Metadata } from "next"; +import localFont from "next/font/local"; +import Image from "next/image"; +import NavBar from "@/components/NavBar"; +import { AnalyticsProvider } from "@/components/AnalyticsProvider"; -import './globals.css'; +import "./globals.css"; const geistSans = localFont({ - src: './fonts/GeistVF.woff', - variable: '--font-geist-sans', - weight: '100 900', + src: "./fonts/GeistVF.woff", + variable: "--font-geist-sans", + weight: "100 900", }); const geistMono = localFont({ - src: './fonts/GeistMonoVF.woff', - variable: '--font-geist-mono', - weight: '100 900', + src: "./fonts/GeistMonoVF.woff", + variable: "--font-geist-mono", + weight: "100 900", }); export const metadata: Metadata = { - title: 'Create Next App', - description: 'Generated by create next app', + title: "Create Next App", + description: "Generated by create next app", }; export default function RootLayout({ - children, -}: Readonly<{ - children: React.ReactNode; -}>) { - return ( - - - - {children} - - - ); + children, +}: Readonly<{ children: React.ReactNode }>) { + return ( + + + + + {children} + + + + ); } diff --git a/app/page.tsx b/app/page.tsx index ccc734b..12be4c0 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -8,18 +8,18 @@ export default function HomePage() { <section className="flex w-full border-t border-b border-black"> <div className="w-1/2"> - <Feature - text="Overview of Consumer Features:" - image="/consumer.png" - link="/consumer" - /> + <Feature + text="Overview of Consumer Features:" + image="/consumer.png" + link="/consumer" + /> </div> <div className="w-1/2 border-l border-black"> - <Feature - text="Overview of Vendor Offerings:" - image="/vendor.png" - link="/vendor" - /> + <Feature + text="Overview of Vendor Offerings:" + image="/vendor.png" + link="/vendor" + /> </div> </section> <PreviewSection /> diff --git a/components/AnalyticsProvider.tsx b/components/AnalyticsProvider.tsx new file mode 100644 index 0000000..828bf6d --- /dev/null +++ b/components/AnalyticsProvider.tsx @@ -0,0 +1,22 @@ +"use client"; + +import React, { createContext, useContext } from "react"; +import { useSession } from "@/app/hooks/useSession"; + +const AnalyticsContext = createContext<string | null>(null); + +export const AnalyticsProvider = ({ + children, +}: { + children: React.ReactNode; +}) => { + const sessionId = useSession(); + + return ( + <AnalyticsContext.Provider value={sessionId}> + {children} + </AnalyticsContext.Provider> + ); +}; + +export const useAnalytics = () => useContext(AnalyticsContext); diff --git a/package-lock.json b/package-lock.json index 1769ff4..30d6178 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,12 +21,14 @@ "react-dom": "19.0.0", "tailwind-merge": "^2.5.5", "tailwind-scrollbar-hide": "^4.0.0", + "uuid": "^13.0.0", "zod": "^4.1.12" }, "devDependencies": { "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", + "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "^8.15.0", "@typescript-eslint/parser": "^8.15.0", "eslint": "^8", @@ -1130,6 +1132,13 @@ "@types/react": "^18.0.0" } }, + "node_modules/@types/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/webidl-conversions": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", @@ -6423,6 +6432,19 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, + "node_modules/uuid": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz", + "integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist-node/bin/uuid" + } + }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", diff --git a/package.json b/package.json index 36459f1..237f5f6 100644 --- a/package.json +++ b/package.json @@ -29,12 +29,14 @@ "react-dom": "19.0.0", "tailwind-merge": "^2.5.5", "tailwind-scrollbar-hide": "^4.0.0", + "uuid": "^13.0.0", "zod": "^4.1.12" }, "devDependencies": { "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", + "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "^8.15.0", "@typescript-eslint/parser": "^8.15.0", "eslint": "^8",