diff --git a/package.json b/package.json
index ce284728..0daab8d6 100644
--- a/package.json
+++ b/package.json
@@ -32,8 +32,12 @@
"dependencies": {
"@aws-sdk/client-s3": "^3.645.0",
"@aws-sdk/s3-request-presigner": "^3.645.0",
+ "@emotion/react": "^11.13.3",
+ "@emotion/styled": "^11.13.0",
"@faker-js/faker": "^9.0.0",
+ "@fontsource/roboto": "^5.1.0",
"@hookform/resolvers": "^3.9.0",
+ "@mui/material": "^6.1.3",
"@prisma/client": "5.18.0",
"@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-avatar": "^1.1.0",
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 8aa98268..502eebba 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -20,11 +20,16 @@ model User {
email String @unique
emailVerified DateTime?
+ skills String[]
+ experience Experience[]
+ project Project[]
+ resume String?
+
oauthProvider OauthProvider? // Tracks OAuth provider (e.g., 'google')
oauthId String?
blockedByAdmin DateTime?
-
+ onBoard Boolean @default(false)
}
enum OauthProvider {
@@ -75,6 +80,31 @@ model Job {
user User @relation(fields: [userId], references: [id])
}
+model Experience {
+ id Int @id @default(autoincrement())
+ companyName String
+ designation String
+ EmploymentType EmployementType
+ address String
+ workMode WorkMode
+ currentWorkStatus Boolean
+ startDate DateTime
+ endDate DateTime?
+ description String
+ userId String
+ user User @relation(fields: [userId] ,references: [id])
+}
+
+model Project {
+ id Int @id @default(autoincrement())
+ projectName String
+ projectSummary String
+ projectLiveLink String?
+ projectGithub String
+ userId String
+ user User @relation(fields: [userId] , references: [id])
+}
+
enum Currency {
INR
USD
diff --git a/prisma/seed.ts b/prisma/seed.ts
index 7a16f7f6..90e81712 100644
--- a/prisma/seed.ts
+++ b/prisma/seed.ts
@@ -13,7 +13,7 @@ const prisma = new PrismaClient();
const users = [
{ id: '1', name: 'Jack', email: 'user@gmail.com' },
- { id: '2', name: 'Admin', email: 'admin@gmail.com', role: Role.ADMIN },
+ { id: '2', name: 'Admin', email: 'admin@gmail.com', role: Role.ADMIN , onBoard : true },
{ id: '3', name: 'Hr', email: 'hr@gmail.com', role: Role.HR },
];
diff --git a/src/actions/user.profile.actions.ts b/src/actions/user.profile.actions.ts
index 9ba48b9f..511db05a 100644
--- a/src/actions/user.profile.actions.ts
+++ b/src/actions/user.profile.actions.ts
@@ -1,7 +1,18 @@
'use server';
import prisma from '@/config/prisma.config';
-import { UserProfileSchemaType } from '@/lib/validators/user.profile.validator';
+import {
+ addSkillsSchemaType,
+ expFormSchemaType,
+ projectSchemaType,
+ UserProfileSchemaType,
+} from '@/lib/validators/user.profile.validator';
import bcryptjs from 'bcryptjs';
+import { authOptions } from '@/lib/authOptions';
+import { getServerSession } from 'next-auth';
+import { ErrorHandler } from '@/lib/error';
+import { withServerActionAsyncCatcher } from '@/lib/async-catch';
+import { ServerActionReturnType } from '@/types/api.types';
+import { SuccessResponse } from '@/lib/success';
export const updateUser = async (
email: string,
@@ -125,3 +136,98 @@ export const deleteUser = async (email: string) => {
return { error: error };
}
};
+
+export const addUserSkills = withServerActionAsyncCatcher<
+ addSkillsSchemaType,
+ ServerActionReturnType
+>(async (data) => {
+ const auth = await getServerSession(authOptions);
+
+ if (!auth || !auth?.user?.id)
+ throw new ErrorHandler('Not Authorized', 'UNAUTHORIZED');
+
+ try {
+ await prisma.user.update({
+ where: {
+ id: auth.user.id,
+ },
+ data: {
+ skills: data.skills,
+ },
+ });
+ return new SuccessResponse('Skills updated successfully', 200).serialize();
+ } catch (_error) {
+ return new ErrorHandler('Internal server error', 'DATABASE_ERROR');
+ }
+});
+
+export const addUserExperience = withServerActionAsyncCatcher<
+ expFormSchemaType,
+ ServerActionReturnType
+>(async (data) => {
+ const auth = await getServerSession(authOptions);
+
+ if (!auth || !auth?.user?.id)
+ throw new ErrorHandler('Not Authorized', 'UNAUTHORIZED');
+
+ try {
+ await prisma.experience.create({
+ data: {
+ ...data,
+ userId: auth.user.id,
+ },
+ });
+ return new SuccessResponse(
+ 'Experience updated successfully',
+ 200
+ ).serialize();
+ } catch (_error) {
+ return new ErrorHandler('Internal server error', 'DATABASE_ERROR');
+ }
+});
+
+export const addUserProjects = withServerActionAsyncCatcher<
+ projectSchemaType,
+ ServerActionReturnType
+>(async (data) => {
+ const auth = await getServerSession(authOptions);
+
+ if (!auth || !auth?.user?.id)
+ throw new ErrorHandler('Not Authorized', 'UNAUTHORIZED');
+
+ try {
+ await prisma.project.create({
+ data: {
+ ...data,
+ userId: auth.user.id,
+ },
+ });
+ return new SuccessResponse('Project updated successfully', 200).serialize();
+ } catch (_error) {
+ return new ErrorHandler('Internal server error', 'DATABASE_ERROR');
+ }
+});
+
+export const validateUserBoarding = async () => {
+ const auth = await getServerSession(authOptions);
+
+ if (!auth || !auth?.user?.id)
+ throw new ErrorHandler('Not Authorized', 'UNAUTHORIZED');
+
+ try {
+ await prisma.user.update({
+ where: {
+ id: auth.user.id,
+ },
+ data: {
+ onBoard: true,
+ },
+ });
+ return new SuccessResponse(
+ 'Welcome!! On Boarding successfully',
+ 200
+ ).serialize();
+ } catch (_error) {
+ return new ErrorHandler('Internal server error', 'DATABASE_ERROR');
+ }
+};
diff --git a/src/app/create-profile/page.tsx b/src/app/create-profile/page.tsx
new file mode 100644
index 00000000..0975521e
--- /dev/null
+++ b/src/app/create-profile/page.tsx
@@ -0,0 +1,18 @@
+import VerticalLinearStepper from '@/components/user-multistep-form/user-multistep-form';
+import { authOptions } from '@/lib/authOptions';
+import { getServerSession } from 'next-auth';
+import { redirect } from 'next/navigation';
+
+export default async function Home() {
+ const session = await getServerSession(authOptions);
+ if (!session || session.user.role !== 'USER') redirect('/');
+ if (session.user.onBoard === true) redirect('/profile');
+ return (
+
+
+ Hey {session?.user.name} let's get you set up and started!
+
+
+
+ );
+}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index bd78e16e..a0669a33 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -2,8 +2,18 @@ import Faqs from '@/components/Faqs';
import HeroSection from '@/components/hero-section';
import { JobLanding } from '@/components/job-landing';
import Testimonials from '@/components/Testimonials';
+import { authOptions } from '@/lib/authOptions';
+import { getServerSession } from 'next-auth';
+import { redirect } from 'next/navigation';
const HomePage = async () => {
+ const session = await getServerSession(authOptions);
+ {
+ session &&
+ session.user.role === 'USER' &&
+ !session.user.onBoard &&
+ redirect('/create-profile');
+ }
return (
diff --git a/src/components/auth/signin.tsx b/src/components/auth/signin.tsx
index 34a61b0b..76d6f7f1 100644
--- a/src/components/auth/signin.tsx
+++ b/src/components/auth/signin.tsx
@@ -52,6 +52,7 @@ export const Signin = () => {
const searchParams = new URLSearchParams(window.location.search);
const redirect = searchParams.get('next') || APP_PATHS.HOME;
router.push(redirect);
+ router.refresh();
} catch (_error) {
return toast({
title: 'Internal server error',
diff --git a/src/components/skills-combobox.tsx b/src/components/skills-combobox.tsx
index 870ad44d..3f724d5c 100644
--- a/src/components/skills-combobox.tsx
+++ b/src/components/skills-combobox.tsx
@@ -9,6 +9,7 @@ import { UseFormReturn } from 'react-hook-form';
import { JobPostSchemaType } from '@/lib/validators/jobs.validator';
import _ from 'lodash';
import { X } from 'lucide-react';
+import { addSkillsSchemaType } from '@/lib/validators/user.profile.validator';
export function SkillsCombobox({
form,
@@ -16,7 +17,7 @@ export function SkillsCombobox({
setComboBoxSelectedValues,
}: {
comboBoxSelectedValues: string[];
- form: UseFormReturn
;
+ form: UseFormReturn | UseFormReturn;
setComboBoxSelectedValues: React.Dispatch>;
}) {
const [comboBoxInputValue, setComboBoxInputValue] = useState('');
diff --git a/src/components/user-multistep-form/add-project-form.tsx b/src/components/user-multistep-form/add-project-form.tsx
new file mode 100644
index 00000000..fab2ba4d
--- /dev/null
+++ b/src/components/user-multistep-form/add-project-form.tsx
@@ -0,0 +1,117 @@
+import {
+ projectSchema,
+ projectSchemaType,
+} from '@/lib/validators/user.profile.validator';
+import { zodResolver } from '@hookform/resolvers/zod';
+import { useForm } from 'react-hook-form';
+import {
+ Form,
+ FormItem,
+ FormLabel,
+ FormControl,
+ FormMessage,
+ FormField,
+} from '../ui/form';
+import { Input } from '../ui/input';
+import { Button } from '../ui/button';
+import { Textarea } from '../ui/textarea';
+import { useToast } from '../ui/use-toast';
+import { addUserProjects } from '@/actions/user.profile.actions';
+
+export const AddProject = () => {
+ const form = useForm({
+ resolver: zodResolver(projectSchema),
+ defaultValues: {
+ projectName: '',
+ projectSummary: '',
+ projectGithub: '',
+ projectLiveLink: '',
+ },
+ });
+
+ const { toast } = useToast();
+
+ const onSubmit = async (data: projectSchemaType) => {
+ try {
+ const response = await addUserProjects(data);
+
+ if (!response.status) {
+ return toast({
+ title: response.message || 'Error',
+ variant: 'destructive',
+ });
+ }
+ toast({
+ title: response.message,
+ variant: 'success',
+ });
+ form.reset(form.formState.defaultValues);
+ } catch (_error) {
+ toast({
+ title: 'Something went wrong while Adding Projects',
+ description: 'Internal server error',
+ variant: 'destructive',
+ });
+ }
+ };
+
+ return (
+
+
+ );
+};
diff --git a/src/components/user-multistep-form/add-resume-form.tsx b/src/components/user-multistep-form/add-resume-form.tsx
new file mode 100644
index 00000000..58cd596a
--- /dev/null
+++ b/src/components/user-multistep-form/add-resume-form.tsx
@@ -0,0 +1,137 @@
+import React, { useRef, useState } from 'react';
+import { FaFileUpload } from 'react-icons/fa';
+import { X } from 'lucide-react';
+import { Button } from '../ui/button';
+import { useToast } from '../ui/use-toast';
+import { uploadFileAction } from '@/actions/upload-to-cdn';
+
+export const AddResume = () => {
+ const resumeFileRef = useRef(null);
+ const [file, setFile] = useState(null);
+ const [fileName, setFileName] = useState(null);
+
+ const handleClick = () => {
+ if (resumeFileRef.current) {
+ resumeFileRef.current.click();
+ }
+ };
+
+ const clearResumeFile = () => {
+ if (resumeFileRef.current) {
+ resumeFileRef.current.value = '';
+ }
+ setFileName(null);
+ setFile(null);
+ };
+
+ const handleFileChange = (event: React.ChangeEvent) => {
+ const selectedFile = event.target.files?.[0];
+ if (selectedFile) {
+ setFile(selectedFile);
+ setFileName(selectedFile.name);
+ }
+ };
+
+ const { toast } = useToast();
+
+ const onSubmit = async () => {
+ if (!file) {
+ return toast({
+ title: 'Please Select a File',
+ variant: 'destructive',
+ });
+ }
+
+ if (file?.size > 10485760) {
+ return toast({
+ title: 'File Size Exceeded',
+ description: 'File Size should be less than 10 MB',
+ variant: 'destructive',
+ });
+ }
+
+ const formData = new FormData();
+ formData.append('file', file);
+
+ try {
+ const uniqueFileName = `${Date.now()}-${file.name}`;
+ formData.append('uniqueFileName', uniqueFileName);
+
+ const res = await uploadFileAction(formData);
+ if (!res) {
+ return toast({
+ title: 'Internal Server Error',
+ description: 'Please try again later.',
+ variant: 'destructive',
+ });
+ }
+
+ if (res.message) {
+ toast({
+ title: res.message,
+ variant: 'success',
+ });
+ } else if (res.error) {
+ toast({
+ title: 'Upload Failed',
+ description: `Error: ${res.error}`,
+ variant: 'destructive',
+ });
+ }
+ } catch (error) {
+ console.error('Image upload failed:', error);
+ toast({
+ title: 'Upload Error',
+ description:
+ 'An error occurred while uploading the file. Please try again.',
+ variant: 'destructive',
+ });
+ }
+ };
+
+ return (
+
+
+
+ {fileName ? (
+
+ ) : (
+
+
+
Click to upload resume
+
+ )}
+
+ {fileName && (
+
+ )}
+
+
+
+ Allowed file types: PDF, DOC, DOCX
+
+
+
+ );
+};
diff --git a/src/components/user-multistep-form/add-skills-form.tsx b/src/components/user-multistep-form/add-skills-form.tsx
new file mode 100644
index 00000000..eb0cced2
--- /dev/null
+++ b/src/components/user-multistep-form/add-skills-form.tsx
@@ -0,0 +1,66 @@
+import { useState } from 'react';
+import { SkillsCombobox } from '../skills-combobox';
+import { useForm } from 'react-hook-form';
+import { zodResolver } from '@hookform/resolvers/zod';
+import { Button } from '../ui/button';
+import { Form } from '../ui/form';
+import {
+ addSkillsSchema,
+ addSkillsSchemaType,
+} from '@/lib/validators/user.profile.validator';
+import { useToast } from '../ui/use-toast';
+import { addUserSkills } from '@/actions/user.profile.actions';
+
+export const AddSkills = () => {
+ const [comboBoxSelectedValues, setComboBoxSelectedValues] = useState<
+ string[]
+ >([]);
+
+ const form = useForm({
+ resolver: zodResolver(addSkillsSchema),
+ defaultValues: {
+ skills: [],
+ },
+ });
+ const { toast } = useToast();
+ const onSubmit = async (data: addSkillsSchemaType) => {
+ try {
+ const response = await addUserSkills(data);
+
+ if (!response.status) {
+ return toast({
+ title: response.message || 'Error',
+ variant: 'destructive',
+ });
+ }
+ toast({
+ title: response.message,
+ variant: 'success',
+ });
+
+ form.reset(form.formState.defaultValues);
+ setComboBoxSelectedValues([]);
+ } catch (_error) {
+ toast({
+ title: 'Something went wrong while Adding Skills',
+ description: 'Internal server error',
+ variant: 'destructive',
+ });
+ }
+ };
+
+ return (
+
+
+ );
+};
diff --git a/src/components/user-multistep-form/addExperience-form.tsx b/src/components/user-multistep-form/addExperience-form.tsx
new file mode 100644
index 00000000..3fa2063e
--- /dev/null
+++ b/src/components/user-multistep-form/addExperience-form.tsx
@@ -0,0 +1,270 @@
+import { useForm } from 'react-hook-form';
+import { zodResolver } from '@hookform/resolvers/zod';
+import { EmployementType, WorkMode } from '@prisma/client';
+import {
+ Form,
+ FormControl,
+ FormDescription,
+ FormField,
+ FormItem,
+ FormLabel,
+ FormMessage,
+} from '@/components/ui/form';
+import { Input } from '../ui/input';
+import { Button } from '../ui/button';
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from '../ui/select';
+import { Textarea } from '../ui/textarea';
+import _ from 'lodash';
+import { Switch } from '../ui/switch';
+import {
+ expFormSchema,
+ expFormSchemaType,
+} from '@/lib/validators/user.profile.validator';
+import { addUserExperience } from '@/actions/user.profile.actions';
+import { useToast } from '../ui/use-toast';
+
+export const AddExperience = () => {
+ const form = useForm({
+ resolver: zodResolver(expFormSchema),
+ defaultValues: {
+ companyName: '',
+ designation: '',
+ EmploymentType: 'Full_time',
+ address: '',
+ workMode: 'office',
+ currentWorkStatus: false,
+ startDate: undefined,
+ endDate: undefined,
+ description: '',
+ },
+ });
+
+ const { toast } = useToast();
+
+ const onSubmit = async (data: expFormSchemaType) => {
+ try {
+ const response = await addUserExperience(data);
+ if (!response.status) {
+ return toast({
+ title: response.message || 'Error',
+ variant: 'destructive',
+ });
+ }
+ toast({
+ title: response.message,
+ variant: 'success',
+ });
+ form.reset(form.formState.defaultValues);
+ } catch (_error) {
+ toast({
+ title: 'Something went wrong while Adding Experience',
+ description: 'Internal server error',
+ variant: 'destructive',
+ });
+ }
+ };
+
+ const WatchCurrentWorkStatus = form.watch('currentWorkStatus');
+
+ return (
+
+ );
+};
diff --git a/src/components/user-multistep-form/user-multistep-form.tsx b/src/components/user-multistep-form/user-multistep-form.tsx
new file mode 100644
index 00000000..a4631ee1
--- /dev/null
+++ b/src/components/user-multistep-form/user-multistep-form.tsx
@@ -0,0 +1,145 @@
+'use client';
+
+import Box from '@mui/material/Box';
+import Stepper from '@mui/material/Stepper';
+import Step from '@mui/material/Step';
+import StepLabel from '@mui/material/StepLabel';
+import StepContent from '@mui/material/StepContent';
+import Button from '@mui/material/Button';
+import Typography from '@mui/material/Typography';
+import { AddExperience } from './addExperience-form';
+import {
+ Dialog,
+ DialogContent,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from '@/components/ui/dialog';
+import { AddSkills } from './add-skills-form';
+import { AddProject } from './add-project-form';
+import { AddResume } from './add-resume-form';
+import { useState } from 'react';
+import { useToast } from '../ui/use-toast';
+import { validateUserBoarding } from '@/actions/user.profile.actions';
+import { useRouter } from 'next/navigation';
+
+const forms = [
+ {
+ label: 'Add Experience',
+ description:
+ 'Adding your experience helps showcase your skills, build credibility, and increase your chances of standing out to potential employers or collaborators. Share details about your past roles, achievements, and responsibilities to give a full picture of your career journey.',
+ component: AddExperience,
+ },
+ {
+ label: 'Add Skills',
+ description:
+ "Highlighting your skills is essential for demonstrating your proficiency in key areas. Add relevant skills that reflect your expertise and align with the job roles you're targeting to increase your visibility to potential employers.",
+ component: AddSkills,
+ },
+ {
+ label: 'Add Projects',
+ description:
+ "Adding projects allows you to showcase practical examples of your work. Whether it's personal, academic, or professional, showcasing your projects demonstrates your ability to apply your skills and solve real-world problems.",
+ component: AddProject,
+ },
+ {
+ label: 'Add Resume',
+ description:
+ 'Uploading your resume provides a comprehensive summary of your career. It gives potential employers a clear and structured view of your background, helping you stand out in job applications and networking opportunities.',
+ component: AddResume,
+ },
+];
+
+export default function VerticalLinearStepper() {
+ const router = useRouter();
+ const [activeStep, setActiveStep] = useState(0);
+
+ const handleNext = () => {
+ setActiveStep((prevActiveStep) => prevActiveStep + 1);
+ };
+
+ const handleBack = () => {
+ setActiveStep((prevActiveStep) => prevActiveStep - 1);
+ };
+ const { toast } = useToast();
+
+ const handleFinish = async () => {
+ try {
+ const response = await validateUserBoarding();
+ if (!response.status) {
+ return toast({
+ title: response.message || 'Error',
+ variant: 'destructive',
+ });
+ }
+ toast({
+ title: response.message,
+ variant: 'success',
+ });
+ router.push('/jobs');
+ router.refresh();
+ } catch (_error) {
+ toast({
+ title: 'Something went wrong!! Please Try Again Later.',
+ description: 'Internal server error',
+ variant: 'destructive',
+ });
+ }
+ };
+
+ return (
+
+
+ {forms.map((form, index) => (
+
+ Last step
+ ) : null
+ }
+ >
+ {form.label}
+
+
+ {form.description}
+
+
+
+
+
+
+
+ ))}
+
+
+ );
+}
diff --git a/src/lib/authOptions.ts b/src/lib/authOptions.ts
index 3f0dd218..c34b5d0a 100644
--- a/src/lib/authOptions.ts
+++ b/src/lib/authOptions.ts
@@ -46,6 +46,7 @@ export const authOptions = {
password: true,
role: true,
emailVerified: true,
+ onBoard: true,
},
});
@@ -70,6 +71,7 @@ export const authOptions = {
email: email,
isVerified: !!user.emailVerified,
role: user.role,
+ onBoard: user.onBoard,
};
},
}),
@@ -127,6 +129,7 @@ export const authOptions = {
token.isVerified = user.isVerified;
token.role = loggedInUser.role ? loggedInUser.role : user.role;
token.image = loggedInUser ? loggedInUser.avatar : user.image;
+ token.onBoard = loggedInUser.onBoard;
}
return token;
},
@@ -139,6 +142,7 @@ export const authOptions = {
session.user.name = token.name as string;
session.user.email = token.email as string;
session.user.image = token.image as string;
+ session.user.onBoard = token.onBoard;
}
return session;
},
diff --git a/src/lib/validators/user.profile.validator.ts b/src/lib/validators/user.profile.validator.ts
index 5f4a635f..d58f5664 100644
--- a/src/lib/validators/user.profile.validator.ts
+++ b/src/lib/validators/user.profile.validator.ts
@@ -1,3 +1,4 @@
+import { EmployementType, WorkMode } from '@prisma/client';
import { z } from 'zod';
export const UserProfileSchema = z.object({
@@ -16,5 +17,43 @@ export const UserPasswordSchema = z.object({
.string()
.min(6, 'Password must be at least of 6 characters.'),
});
+export const addSkillsSchema = z.object({
+ skills: z.array(z.string()).optional(),
+});
+export const expFormSchema = z.object({
+ companyName: z.string().min(1, { message: 'Company Name is required' }),
+ designation: z.string().min(1, { message: 'Designation is required' }),
+ EmploymentType: z.nativeEnum(EmployementType, {
+ message: 'Employement type is required',
+ }),
+ address: z.string().min(1, { message: 'Address is required' }),
+ workMode: z.nativeEnum(WorkMode, {
+ message: 'Work mode is required',
+ }),
+ currentWorkStatus: z.boolean({
+ required_error: 'Current work status is required',
+ }),
+ startDate: z.date({
+ required_error: 'Start date is required',
+ invalid_type_error: 'Invalid date',
+ }),
+ endDate: z.date({ invalid_type_error: 'Invalid date' }).optional(),
+ description: z
+ .string()
+ .min(50, { message: 'Description must be at least 50 characters' })
+ .max(255, { message: 'Description cannot exceed 255 characters' }),
+});
+export const projectSchema = z.object({
+ projectName: z.string().min(1, 'Project name is required'),
+ projectSummary: z
+ .string()
+ .min(20, { message: 'Summary must be at least 20 characters' })
+ .max(255, { message: 'Summary cannot exceed 255 characters' }),
+ projectLiveLink: z.string().url().optional(),
+ projectGithub: z.string({ message: 'Github Link is required' }).url(),
+});
+export type projectSchemaType = z.infer;
+export type expFormSchemaType = z.infer;
+export type addSkillsSchemaType = z.infer;
export type UserPasswordSchemaType = z.infer;
diff --git a/src/types/next-auth.d.ts b/src/types/next-auth.d.ts
index 4daf2a21..baab3afb 100644
--- a/src/types/next-auth.d.ts
+++ b/src/types/next-auth.d.ts
@@ -4,6 +4,7 @@ declare module 'next-auth' {
interface User {
isVerified: boolean;
role: string;
+ onBoard: boolean;
}
interface Session {
user: {
@@ -13,6 +14,7 @@ declare module 'next-auth' {
name: string;
isVerified: boolean;
image?: string;
+ onBoard: boolean;
};
}
}
@@ -22,5 +24,6 @@ declare module 'next-auth/jwt' {
id: string;
isVerified: boolean;
role: string;
+ onBoard: boolean;
}
}