Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions EduBuddy/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": ["next/core-web-vitals"]
}
37 changes: 37 additions & 0 deletions EduBuddy/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local
.env

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
110 changes: 110 additions & 0 deletions EduBuddy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# EduBuddy

*EduBuddy* is an AI-powered learning companion designed to enhance the study experience by providing personalized learning support for students of all levels. The platform leverages AI to deliver interactive educational tools that help students excel in their academic journey.

## Features

EduBuddy offers a comprehensive suite of learning tools:

- *Doubt Solving*: Ask questions and receive clear explanations from AI.
- *Flashcards*: Generate custom flashcards to aid memorization and revision.
- *Quiz Generation*: Create personalized quizzes to test knowledge.
- *Code Generation*: Get code snippets and explanations for various programming topics.

## Getting Started

These instructions will help you set up EduBuddy on your local machine for development and testing.

### Prerequisites

Make sure you have the following installed:

- [Node.js](https://nodejs.org/) (v14 or higher)
- [npm](https://www.npmjs.com/) or [Yarn](https://yarnpkg.com/)

## Installation

1. Clone the repository:

bash
git clone https://github.com/bhavkushwaha/EduBuddy


2. Navigate into the project directory:

bash
cd EduBuddy


3. Install dependencies:

bash
npm install


4. (Optional) Set up the database and configure environment variables:

Create a .env file in the root directory with the following variables:


# Example .env file

```

DB_HOST=localhost
DB_PORT=5432
DB_USER=your-username
DATABASE_URL=your-url

NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/dashboard
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/dashboard

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY = "your_key"
CLERK_SECRET_KEY = "your_key"

```


## Usage

1. Start the development server:

bash
npm run dev


2. Open your browser and navigate to:


http://localhost:3000


3. To create a production build:

bash
npm run build



## Configuration

EduBuddy requires certain environment variables to be set for database connections and API key integration:

- **Database Configuration**: Modify the `.env` file as needed.
- **API Keys**: If using third-party APIs for quiz generation or code snippets, add them in the `.env` file (we used OpenAI )

```

OPENAI_API_KEY=your-openai-api-key

```

## Scripts/Commands

The project includes several scripts to streamline development and deployment:

- npm start: Starts the server in production mode.
- npm run dev: Starts the server in development mode with hot-reloading.
- npm run build: Builds the project for production.
5 changes: 5 additions & 0 deletions EduBuddy/app/(auth)/(routes)/sign-in/[[...sign-in]]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { SignIn } from "@clerk/nextjs";

export default function Page() {
return <SignIn />;
}
5 changes: 5 additions & 0 deletions EduBuddy/app/(auth)/(routes)/sign-up/[[...sign-up]]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { SignUp } from "@clerk/nextjs";

export default function Page() {
return <SignUp />;
}
13 changes: 13 additions & 0 deletions EduBuddy/app/(auth)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const AuthLayout = ({
children
}: {
children: React.ReactNode;
}) => {
return (
<div className="flex items-center justify-center h-full">
{children}
</div>
);
};

export default AuthLayout;
7 changes: 7 additions & 0 deletions EduBuddy/app/(dashboard)/(routes)/code/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as z from "zod";

export const formSchema = z.object({
prompt: z.string().min(1, {
message: "Prompt is required",
}),
});
157 changes: 157 additions & 0 deletions EduBuddy/app/(dashboard)/(routes)/code/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
"use client";

import { useState } from "react";
import axios from "axios";
import * as z from "zod";
import { Code } from "lucide-react";
import { useForm } from "react-hook-form";
import { formSchema } from "./constants";
import { zodResolver } from "@hookform/resolvers/zod";
import { ChatCompletionMessageParam } from "openai/resources/index.mjs";
import { useRouter } from "next/navigation";
import { cn } from "@/lib/utils";
import ReactMarkdown from "react-markdown";

import { Form, FormControl, FormField, FormItem } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";

import { Heading } from "@/components/heading";
import { Empty } from "@/components/empty";
import { Loader } from "@/components/loader";
import { UserAvatar } from "@/components/user-avatar";
import { BotAvatar } from "@/components/bot-avatar";
import { useProModal } from "@/hooks/use-pro-modal";

const CodePage = () => {
const router = useRouter();

const proModal = useProModal();

const [messages, setMessages] = useState<ChatCompletionMessageParam[]>([]);

const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
prompt: "",
},
});

const isLoading = form.formState.isSubmitting;

const onSubmit = async (values: z.infer<typeof formSchema>) => {
try {
const userMessage: ChatCompletionMessageParam = {
role: "user",
content: values.prompt,
};

const newMessages = [...messages, userMessage];

const response = await axios.post("/api/code", {
messages: newMessages,
});

setMessages((current) => [...current, userMessage, response.data]);

form.reset();
} catch (error: any) {
if (error?.response?.status === 403) {
proModal.onOpen();
}
console.log(error);
} finally {
router.refresh();
}
};

return (
<div>
<Heading
title="Coding Assistant"
description="Generate code for your school projects using descriptive text."
icon={Code}
iconColor="text-green-700"
bgColor="bg-green-700/10"
/>
<div className="px-4 lg:px-8 pb-8">
<div>
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="rounded-lg border w-full p-4 px-3 md:px-6 focus-within:shadow-sm grid grid-cols-12 gap-2"
>
<FormField
name="prompt"
render={({ field }) => (
<FormItem className="col-span-12 lg:col-span-10">
<FormControl className="m-0 p-0">
<Input
className="border-0 outline-none focus-visible:ring-0 focus-visible:ring-transparent"
disabled={isLoading}
placeholder="Simple Toggle Button using React hooks."
{...field}
/>
</FormControl>
</FormItem>
)}
/>
<Button
className="col-span-12 lg:col-span-2 w-full"
disabled={isLoading}
>
Generate
</Button>
</form>
</Form>
</div>
<div className="space-y-4 mt-4">
{isLoading && (
<div className="p-8 rounded-lg w-full flex items-center justify-center bg-muted">
<Loader />
</div>
)}

{messages.length === 0 && !isLoading && (
<div>
<Empty label="No conversation started." />
</div>
)}

<div className="flex flex-col-reverse gap-y-4">
{messages.map((message) => (
<div
key={String(message.content)}
className={cn(
"p-8 w-full flex items-start gap-x-8 rounded-lg",
message.role === "user"
? "bg-white border border-black/10"
: "bg-muted"
)}
>
{message.role === "user" ? <UserAvatar /> : <BotAvatar />}
<ReactMarkdown
components={{
pre: ({ node, ...props }) => (
<div className="overflow-auto w-full my-2 bg-black p-2 rounded-lg text-white">
<pre {...props} />
</div>
),
code: ({ node, ...props }) => (
<code className="bg-black/10 rounded-lg p-2" {...props} />
),
}}
className="text-sm overflow-hidden leading-7"
>
{String(message.content) || ""}
</ReactMarkdown>
</div>
))}
</div>
</div>
</div>
</div>
);
};

export default CodePage;
7 changes: 7 additions & 0 deletions EduBuddy/app/(dashboard)/(routes)/conversation/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as z from "zod";

export const formSchema = z.object({
prompt: z.string().min(1, {
message: "Prompt is required",
}),
});
Loading