diff --git a/frontend/src/app/(auth)/auth.ts b/frontend/src/app/(auth)/auth.ts
index 41d8961..d094796 100644
--- a/frontend/src/app/(auth)/auth.ts
+++ b/frontend/src/app/(auth)/auth.ts
@@ -2,7 +2,7 @@ import { env } from '~/env';
import { loginUser } from './actions';
import { authConfig } from './auth.config';
import { loginFormSchema } from './schema';
-import { UserInterface } from '~/types/user';
+import { UserInterface, UserBase } from '~/types/user';
import type { DefaultJWT } from 'next-auth/jwt';
import NextAuth, { type DefaultSession } from 'next-auth';
import Credentials from 'next-auth/providers/credentials';
@@ -12,7 +12,8 @@ declare module 'next-auth' {
user: UserInterface & DefaultSession['user'] & { access_token: string };
}
- interface User extends UserInterface {
+ interface User extends UserBase {
+ email: string;
access_token: string;
}
}
diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx
index 568fb15..e564325 100644
--- a/frontend/src/app/layout.tsx
+++ b/frontend/src/app/layout.tsx
@@ -1,7 +1,8 @@
import './globals.css';
-import { Suspense } from 'react';
import Providers from './providers';
import type { Metadata } from 'next';
+import { Suspense, cache } from 'react';
+import { auth } from '~/app/(auth)/auth';
import Loader from '~/components/loader';
import { Outfit } from 'next/font/google';
import { Toaster } from '~/components/ui/sonner';
@@ -17,11 +18,15 @@ export const metadata: Metadata = {
description: 'Retailytics aka Retail Intelligence',
};
-export default function RootLayout({
+const getSession = cache(() => auth());
+
+export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
+ const session = await getSession();
+
return (
@@ -32,7 +37,7 @@ export default function RootLayout({
/>
-
+
}>{children}
diff --git a/frontend/src/app/providers.tsx b/frontend/src/app/providers.tsx
index 296f8d3..02e8c30 100644
--- a/frontend/src/app/providers.tsx
+++ b/frontend/src/app/providers.tsx
@@ -2,12 +2,19 @@
import * as React from 'react';
import { ThemeProvider } from './theme';
+import type { Session } from 'next-auth';
import { initMixpanel } from '~/lib/mixpanel';
import { ProgressProvider } from '@bprogress/next/app';
-const Providers = ({ children }: { children: React.ReactNode }) => {
+const Providers = ({
+ children,
+ session,
+}: {
+ children: React.ReactNode;
+ session: Session | null;
+}) => {
React.useEffect(() => {
- initMixpanel();
+ initMixpanel(session);
}, []);
return (
diff --git a/frontend/src/lib/mixpanel.ts b/frontend/src/lib/mixpanel.ts
index 8c4b616..e6392bb 100644
--- a/frontend/src/lib/mixpanel.ts
+++ b/frontend/src/lib/mixpanel.ts
@@ -1,7 +1,8 @@
import { env } from '~/env';
import mixpanel from 'mixpanel-browser';
+import type { Session } from 'next-auth';
-export const initMixpanel = () => {
+export const initMixpanel = (session: Session | null) => {
if (!env.NEXT_PUBLIC_MIXPANEL_TOKEN) {
console.warn('Mixpanel token is missing! Check your .env file.');
return;
@@ -11,4 +12,14 @@ export const initMixpanel = () => {
autocapture: true,
record_sessions_percent: 100,
});
+
+ if (session?.user) {
+ mixpanel.identify(session.user.id);
+ mixpanel.people.set({
+ $email: session.user.email,
+ role: session.user.role,
+ });
+ } else {
+ mixpanel.identify('Guest');
+ }
};
diff --git a/frontend/src/types/user.ts b/frontend/src/types/user.ts
index c9aa9df..d160dfc 100644
--- a/frontend/src/types/user.ts
+++ b/frontend/src/types/user.ts
@@ -16,8 +16,7 @@ export enum AuthProvider {
GOOGLE = 'google',
}
-export interface UserInterface extends AbstractBaseInterface {
- email: string;
+export interface UserBase extends AbstractBaseInterface {
password: string;
role: UserRole;
status: UserStatus;
@@ -30,3 +29,7 @@ export interface UserInterface extends AbstractBaseInterface {
assigned_phase_id?: string;
assigned_district_id?: string;
}
+
+export interface UserInterface extends UserBase {
+ email: string;
+}