├── .dockerignore ├── .env ├── .eslintrc.json ├── .prettierrc ├── .vscode └── settings.json ├── gitpush.bat ├── public ├── E.png ├── chat.png ├── enter.png ├── github.png ├── gmail.png ├── twitter.png ├── youtube.png ├── instagram.png ├── wellbeing.png ├── services │ ├── phq.png │ ├── clerk-auth.png │ ├── chat-gemini.png │ ├── contact-form.png │ ├── mental-track.png │ ├── gemini-explain.png │ ├── gemini-message.png │ ├── complete-analysis.png │ └── personalized-response.png ├── github-contact.png ├── mentalhealth1.jpg ├── phone-contact.png ├── customer-service.png ├── instagram-contact.png ├── linkedin-contact.png ├── arrow-up-right.svg ├── vercel.svg └── next.svg ├── app ├── favicon.ico ├── about │ ├── layout.tsx │ └── page.tsx ├── signout │ └── page.tsx ├── services │ ├── layout.tsx │ └── page.tsx ├── sign-in │ └── [[...sign-in]] │ │ └── page.tsx ├── sign-up │ └── [[...sign-up]] │ │ └── page.tsx ├── chat │ ├── layout.tsx │ └── page.tsx ├── home │ ├── layout.tsx │ └── page.tsx ├── dashboard │ ├── layout.tsx │ └── page.tsx ├── response │ ├── layout.tsx │ └── page.tsx ├── api │ ├── inngest │ │ └── route.ts │ ├── graph │ │ └── route.ts │ ├── hello │ │ └── route.ts │ ├── contact │ │ └── route.ts │ └── chat │ │ └── route.ts ├── StoreProvider.tsx ├── layout.tsx ├── page.tsx ├── globals.css └── contact │ └── page.tsx ├── inngest ├── client.ts └── function.ts ├── prisma ├── migrations │ ├── migration_lock.toml │ └── 20240715131223_init │ │ └── migration.sql └── schema.prisma ├── postcss.config.mjs ├── lib ├── utils.ts ├── hooks.ts ├── features │ ├── score │ │ └── scoreSlice.ts │ ├── textarea │ │ └── textareaSlice.ts │ ├── chat │ │ └── chatSlice.ts │ └── counter │ │ └── counterSlice.ts ├── sendGemini.ts └── store.ts ├── .env.example ├── components ├── Loader.tsx ├── ui │ ├── label.tsx │ ├── textarea.tsx │ ├── progress.tsx │ ├── badge.tsx │ ├── radio-group.tsx │ ├── button.tsx │ ├── card.tsx │ ├── dialog.tsx │ ├── alert-dialog.tsx │ ├── command.tsx │ └── carousel.tsx ├── Carousal.tsx ├── email-template.tsx ├── AlertDialogBox.tsx ├── Gemini-Interface.tsx ├── Navbar.tsx ├── MobileNavbar.tsx └── Quiz.tsx ├── next.config.mjs ├── components.json ├── middleware.ts ├── .gitignore ├── Dockerfile ├── tsconfig.json ├── db └── questions.ts ├── package.json ├── README.md └── tailwind.config.ts /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .next -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | DATABASE_URL= 2 | SHADOW_DATABASE_URL= 3 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true 4 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "WillLuke.nextjs.hasPrompted": true 3 | } -------------------------------------------------------------------------------- /gitpush.bat: -------------------------------------------------------------------------------- 1 | git add . 2 | git commit -m %1 3 | git push -u origin main -------------------------------------------------------------------------------- /public/E.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/E.png -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/app/favicon.ico -------------------------------------------------------------------------------- /public/chat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/chat.png -------------------------------------------------------------------------------- /public/enter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/enter.png -------------------------------------------------------------------------------- /public/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/github.png -------------------------------------------------------------------------------- /public/gmail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/gmail.png -------------------------------------------------------------------------------- /public/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/twitter.png -------------------------------------------------------------------------------- /public/youtube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/youtube.png -------------------------------------------------------------------------------- /public/instagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/instagram.png -------------------------------------------------------------------------------- /public/wellbeing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/wellbeing.png -------------------------------------------------------------------------------- /public/services/phq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/services/phq.png -------------------------------------------------------------------------------- /public/github-contact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/github-contact.png -------------------------------------------------------------------------------- /public/mentalhealth1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/mentalhealth1.jpg -------------------------------------------------------------------------------- /public/phone-contact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/phone-contact.png -------------------------------------------------------------------------------- /public/customer-service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/customer-service.png -------------------------------------------------------------------------------- /public/instagram-contact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/instagram-contact.png -------------------------------------------------------------------------------- /public/linkedin-contact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/linkedin-contact.png -------------------------------------------------------------------------------- /public/services/clerk-auth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/services/clerk-auth.png -------------------------------------------------------------------------------- /public/services/chat-gemini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/services/chat-gemini.png -------------------------------------------------------------------------------- /public/services/contact-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/services/contact-form.png -------------------------------------------------------------------------------- /public/services/mental-track.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/services/mental-track.png -------------------------------------------------------------------------------- /public/services/gemini-explain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/services/gemini-explain.png -------------------------------------------------------------------------------- /public/services/gemini-message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/services/gemini-message.png -------------------------------------------------------------------------------- /public/services/complete-analysis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/services/complete-analysis.png -------------------------------------------------------------------------------- /public/services/personalized-response.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanugurajesh/EmoTrack/HEAD/public/services/personalized-response.png -------------------------------------------------------------------------------- /inngest/client.ts: -------------------------------------------------------------------------------- 1 | import { Inngest } from "inngest"; 2 | 3 | // Create a client to send and receive events 4 | export const inngest = new Inngest({ id: "my-app" }); 5 | -------------------------------------------------------------------------------- /prisma/migrations/migration_lock.toml: -------------------------------------------------------------------------------- 1 | # Please do not edit this file manually 2 | # It should be added in your version-control system (i.e. Git) 3 | provider = "postgresql" -------------------------------------------------------------------------------- /postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /app/about/layout.tsx: -------------------------------------------------------------------------------- 1 | export default function RootLayout({ 2 | children, 3 | }: Readonly<{ 4 | children: React.ReactNode 5 | }>) { 6 | return
{children}
7 | } 8 | -------------------------------------------------------------------------------- /app/signout/page.tsx: -------------------------------------------------------------------------------- 1 | import { SignOutButton } from "@clerk/nextjs"; 2 | 3 | export default function Home() { 4 | return ( 5 |
6 | 7 |
8 | ); 9 | } -------------------------------------------------------------------------------- /app/services/layout.tsx: -------------------------------------------------------------------------------- 1 | export default function RootLayout({ 2 | children, 3 | }: Readonly<{ 4 | children: React.ReactNode 5 | }>) { 6 | return
{children}
7 | } 8 | -------------------------------------------------------------------------------- /lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /app/sign-in/[[...sign-in]]/page.tsx: -------------------------------------------------------------------------------- 1 | import { SignIn } from "@clerk/nextjs"; 2 | 3 | export default function Page() { 4 | return ( 5 |
6 | 7 |
8 | ); 9 | } -------------------------------------------------------------------------------- /app/sign-up/[[...sign-up]]/page.tsx: -------------------------------------------------------------------------------- 1 | import { SignUp } from "@clerk/nextjs"; 2 | 3 | export default function Page() { 4 | return ( 5 |
6 | 7 |
8 | ); 9 | } -------------------------------------------------------------------------------- /prisma/migrations/20240715131223_init/migration.sql: -------------------------------------------------------------------------------- 1 | -- CreateTable 2 | CREATE TABLE "Score" ( 3 | "date" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, 4 | "value" INTEGER NOT NULL DEFAULT 0, 5 | 6 | CONSTRAINT "Score_pkey" PRIMARY KEY ("date") 7 | ); 8 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY= 2 | CLERK_SECRET_KEY= 3 | NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in 4 | NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up 5 | RESEND_API_KEY= 6 | GEMINI_API_KEY= 7 | PERSONAL_EMAIL= 8 | DATABASE_URL= 9 | SHADOW_DATABASE_URL= 10 | INNGEST_SIGNING_KEY= -------------------------------------------------------------------------------- /app/chat/layout.tsx: -------------------------------------------------------------------------------- 1 | import { SignedIn } from '@clerk/nextjs' 2 | 3 | export default function RootLayout({ 4 | children, 5 | }: Readonly<{ 6 | children: React.ReactNode 7 | }>) { 8 | return ( 9 | 10 |
{children}
11 |
12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /app/home/layout.tsx: -------------------------------------------------------------------------------- 1 | import { SignedIn } from '@clerk/nextjs' 2 | 3 | export default function RootLayout({ 4 | children, 5 | }: Readonly<{ 6 | children: React.ReactNode 7 | }>) { 8 | return ( 9 | 10 |
{children}
11 |
12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /app/dashboard/layout.tsx: -------------------------------------------------------------------------------- 1 | import { SignedIn } from '@clerk/nextjs' 2 | 3 | export default function RootLayout({ 4 | children, 5 | }: Readonly<{ 6 | children: React.ReactNode 7 | }>) { 8 | return ( 9 | 10 |
{children}
11 |
12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /app/response/layout.tsx: -------------------------------------------------------------------------------- 1 | import { SignedIn } from '@clerk/nextjs' 2 | 3 | export default function RootLayout({ 4 | children, 5 | }: Readonly<{ 6 | children: React.ReactNode 7 | }>) { 8 | return ( 9 | 10 |
{children}
11 |
12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /inngest/function.ts: -------------------------------------------------------------------------------- 1 | import { inngest } from "./client"; 2 | 3 | export const helloWorld = inngest.createFunction( 4 | { id: "hello-world" }, 5 | { event: "test/hello.world" }, 6 | async ({ event, step }) => { 7 | await step.sleep("wait-a-moment", "1s"); 8 | return { event, body: "Hello, World!" }; 9 | }, 10 | ); 11 | 12 | -------------------------------------------------------------------------------- /app/api/inngest/route.ts: -------------------------------------------------------------------------------- 1 | import { serve } from "inngest/next"; 2 | import { inngest } from "@/inngest/client"; 3 | import { helloWorld } from "@/inngest/function"; 4 | 5 | // Create an API that serves zero functions 6 | export const { GET, POST, PUT } = serve({ 7 | client: inngest, 8 | functions: [ 9 | helloWorld, 10 | ], 11 | }); 12 | -------------------------------------------------------------------------------- /components/Loader.tsx: -------------------------------------------------------------------------------- 1 | // The below one is a loader component which is used to show the loader animation in the application. 2 | 3 | const Loader = () => { 4 | return ( 5 |
6 | 7 |
8 | ) 9 | } 10 | 11 | export default Loader -------------------------------------------------------------------------------- /prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | generator client { 2 | provider = "prisma-client-js" 3 | } 4 | 5 | datasource db { 6 | provider = "postgresql" 7 | url = env("DATABASE_URL") 8 | shadowDatabaseUrl = env("SHADOW_DATABASE_URL") 9 | } 10 | 11 | model Score { 12 | date DateTime @id @default(now()) 13 | value Int @default(0) 14 | } 15 | -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | images: { 4 | remotePatterns: [ 5 | { 6 | protocol: 'https', 7 | hostname: 'img.clerk.com', 8 | // pathname: '/**', 9 | }, 10 | ], 11 | }, 12 | }; 13 | 14 | export default nextConfig; 15 | -------------------------------------------------------------------------------- /public/arrow-up-right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /lib/hooks.ts: -------------------------------------------------------------------------------- 1 | import { useDispatch, useSelector, useStore } from 'react-redux' 2 | import type { RootState, AppDispatch, AppStore } from './store' 3 | 4 | // Use throughout your app instead of plain `useDispatch` and `useSelector` 5 | export const useAppDispatch = useDispatch.withTypes() 6 | export const useAppSelector = useSelector.withTypes() 7 | export const useAppStore = useStore.withTypes() -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "app/globals.css", 9 | "baseColor": "zinc", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils" 16 | } 17 | } -------------------------------------------------------------------------------- /middleware.ts: -------------------------------------------------------------------------------- 1 | import { 2 | clerkMiddleware, 3 | createRouteMatcher 4 | } from '@clerk/nextjs/server'; 5 | 6 | const isProtectedRoute = createRouteMatcher([ 7 | '/home', 8 | ]); 9 | 10 | export default clerkMiddleware((auth, req) => { 11 | if (!auth().userId && isProtectedRoute(req)) { 12 | return auth().redirectToSignIn(); 13 | } 14 | }); 15 | 16 | export const config = { 17 | matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api|trpc)(.*)"], 18 | }; -------------------------------------------------------------------------------- /app/StoreProvider.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import { useRef } from 'react' 3 | import { Provider } from 'react-redux' 4 | import { makeStore, AppStore } from '../lib/store' 5 | 6 | export default function StoreProvider({ 7 | children, 8 | }: { 9 | children: React.ReactNode 10 | }) { 11 | const storeRef = useRef() 12 | if (!storeRef.current) { 13 | // Create the store instance the first time this renders 14 | storeRef.current = makeStore() 15 | } 16 | 17 | return {children} 18 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env 30 | .env*.local 31 | 32 | # vercel 33 | .vercel 34 | 35 | # typescript 36 | *.tsbuildinfo 37 | next-env.d.ts 38 | -------------------------------------------------------------------------------- /app/api/graph/route.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient } from '@prisma/client' 2 | import { NextRequest, NextResponse } from 'next/server' 3 | 4 | const prisma = new PrismaClient() 5 | 6 | export async function POST(request: NextRequest) { 7 | const { score } = await request.json() 8 | const result = await prisma.score.create({ 9 | data: { 10 | value: score, 11 | }, 12 | }) 13 | return NextResponse.json(result) 14 | } 15 | 16 | export async function GET() { 17 | const scores = await prisma.score.findMany() 18 | return NextResponse.json(scores) 19 | } 20 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Use Node.js 14 as the base image 2 | FROM node:20 3 | 4 | EXPOSE 3000 5 | 6 | # Set the working directory to the root of your Next.js app 7 | WORKDIR /app 8 | 9 | # Copy package.json and package-lock.json to the working directory 10 | COPY package.json ./ 11 | 12 | # Install dependencies 13 | RUN npm install 14 | 15 | # Copy the rest of the application files to the working directory 16 | COPY . . 17 | 18 | RUN npx prisma generate 19 | 20 | # Build the Next.js application 21 | RUN npm run build 22 | 23 | # Set the command to run the application 24 | CMD ["npm", "start", "--", "0.0.0.0"] -------------------------------------------------------------------------------- /app/api/hello/route.ts: -------------------------------------------------------------------------------- 1 | import { NextResponse } from 'next/server' 2 | import { inngest } from '../../../inngest/client' // Import our client 3 | 4 | // Opt out of caching; every request should send a new event 5 | export const dynamic = 'force-dynamic' 6 | 7 | export async function POST(req: any) { 8 | const body = await req.json() 9 | 10 | const { email } = body 11 | 12 | // Send your event payload to Inngest 13 | await inngest.send({ 14 | name: 'test/hello.world', 15 | data: { 16 | email: email, 17 | }, 18 | }) 19 | 20 | return NextResponse.json({ name: 'Hello Inngest from Next!' }) 21 | } 22 | -------------------------------------------------------------------------------- /lib/features/score/scoreSlice.ts: -------------------------------------------------------------------------------- 1 | import { createSlice } from '@reduxjs/toolkit' 2 | import type { PayloadAction } from '@reduxjs/toolkit' 3 | 4 | export interface ScoreState { 5 | value: number 6 | } 7 | 8 | const initialState: ScoreState = { 9 | value: 0, 10 | } 11 | 12 | export const scoreSlice = createSlice({ 13 | name: 'score', 14 | initialState, 15 | reducers: { 16 | incrementScore: (state, action: PayloadAction) => { 17 | state.value += action.payload 18 | }, 19 | }, 20 | }) 21 | 22 | export const { incrementScore } = scoreSlice.actions 23 | 24 | export default scoreSlice.reducer 25 | -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/features/textarea/textareaSlice.ts: -------------------------------------------------------------------------------- 1 | import { createSlice } from '@reduxjs/toolkit' 2 | import type { PayloadAction } from '@reduxjs/toolkit' 3 | 4 | export interface TextareaState { 5 | value: string 6 | } 7 | 8 | const initialState: TextareaState = { 9 | value: '', 10 | } 11 | 12 | export const textareaSlice = createSlice({ 13 | name: 'textarea', 14 | initialState, 15 | reducers: { 16 | updateValue: (state, action: PayloadAction) => { 17 | state.value = action.payload 18 | }, 19 | }, 20 | }) 21 | 22 | export const { updateValue } = textareaSlice.actions 23 | 24 | export default textareaSlice.reducer 25 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["dom", "dom.iterable", "esnext"], 4 | "allowJs": true, 5 | "skipLibCheck": true, 6 | "strict": true, 7 | "noEmit": true, 8 | "esModuleInterop": true, 9 | "module": "esnext", 10 | "moduleResolution": "bundler", 11 | "resolveJsonModule": true, 12 | "isolatedModules": true, 13 | "jsx": "preserve", 14 | "incremental": true, 15 | "plugins": [ 16 | { 17 | "name": "next" 18 | } 19 | ], 20 | "paths": { 21 | "@/*": ["./*"] 22 | } 23 | }, 24 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 25 | "exclude": ["node_modules"] 26 | } 27 | -------------------------------------------------------------------------------- /lib/sendGemini.ts: -------------------------------------------------------------------------------- 1 | 'use server' 2 | 3 | import { GoogleGenerativeAI } from '@google/generative-ai' 4 | 5 | const sendGemini = async (message: string, tokens: number) => { 6 | const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY as string) 7 | const model = genAI.getGenerativeModel({ 8 | model: 'gemini-1.5-flash', 9 | generationConfig: { maxOutputTokens: tokens }, 10 | }) 11 | 12 | try { 13 | const result = await model.generateContent(message) 14 | 15 | const response = result.response 16 | 17 | const text = response.text() 18 | 19 | return text 20 | } catch (error) { 21 | return 'Unable to generate output' 22 | } 23 | } 24 | 25 | export default sendGemini 26 | -------------------------------------------------------------------------------- /app/home/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { Progress } from '@/components/ui/progress' 4 | import { GeminiBot } from '@/components/Gemini-Interface' 5 | import { RootState } from '@/lib/store' 6 | import Quiz from '@/components/Quiz' 7 | import { useSelector } from 'react-redux' 8 | 9 | export default function Home() { 10 | 11 | // @ts-ignore 12 | const progress = useSelector((state: RootState) => state.counter.value) 13 | 14 | return ( 15 |
16 |
17 | 18 | 19 |
20 |
21 | 22 |
23 |
24 | ) 25 | } 26 | -------------------------------------------------------------------------------- /components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as LabelPrimitive from "@radix-ui/react-label" 5 | import { cva, type VariantProps } from "class-variance-authority" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const labelVariants = cva( 10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 11 | ) 12 | 13 | const Label = React.forwardRef< 14 | React.ElementRef, 15 | React.ComponentPropsWithoutRef & 16 | VariantProps 17 | >(({ className, ...props }, ref) => ( 18 | 23 | )) 24 | Label.displayName = LabelPrimitive.Root.displayName 25 | 26 | export { Label } 27 | -------------------------------------------------------------------------------- /lib/store.ts: -------------------------------------------------------------------------------- 1 | import { configureStore } from '@reduxjs/toolkit' 2 | import counterReducer from '@/lib/features/counter/counterSlice' 3 | import textareaReducer from '@/lib/features/textarea/textareaSlice' 4 | import scoreReducer from '@/lib/features/score/scoreSlice' 5 | import chatReducer from '@/lib/features/chat/chatSlice' 6 | 7 | export const makeStore = () => { 8 | return configureStore({ 9 | reducer: { 10 | counter: counterReducer, 11 | textarea: textareaReducer, 12 | score: scoreReducer, 13 | chat: chatReducer 14 | }, 15 | }) 16 | } 17 | 18 | // Infer the type of makeStore 19 | export type AppStore = ReturnType 20 | // Infer the `RootState` and `AppDispatch` types from the store itself 21 | export type RootState = ReturnType 22 | export type AppDispatch = AppStore['dispatch'] 23 | -------------------------------------------------------------------------------- /lib/features/chat/chatSlice.ts: -------------------------------------------------------------------------------- 1 | import { createSlice, PayloadAction } from '@reduxjs/toolkit' 2 | 3 | export interface ChatMessage { 4 | user: string 5 | message: string 6 | } 7 | 8 | export interface ChatState { 9 | messages: ChatMessage[] 10 | } 11 | 12 | const initialState: ChatState = { 13 | messages: [ 14 | { 15 | user: 'model', 16 | message: 'Hello I am Gemini Chat with me?', 17 | }, 18 | ], 19 | } 20 | 21 | export const chatSlice = createSlice({ 22 | name: 'chat', 23 | initialState, 24 | reducers: { 25 | updateValue: (state, action: PayloadAction) => { 26 | state.messages.push({ 27 | user: action.payload.user, 28 | message: action.payload.message, 29 | }) 30 | }, 31 | }, 32 | }) 33 | 34 | export const { updateValue } = chatSlice.actions 35 | 36 | export default chatSlice.reducer 37 | -------------------------------------------------------------------------------- /components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | export interface TextareaProps 6 | extends React.TextareaHTMLAttributes {} 7 | 8 | const Textarea = React.forwardRef( 9 | ({ className, ...props }, ref) => { 10 | return ( 11 | 228 | 229 |
230 | {/* @ts-ignore */} 231 | 237 |
238 | 239 | 240 | ); 241 | } --------------------------------------------------------------------------------