Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Next.js frontend #119

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 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
4 changes: 0 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,3 @@ repos:
- id: check-executables-have-shebangs
- id: check-shebang-scripts-are-executable
- id: detect-private-key
- id: check-added-large-files
args:
- --maxkb=120
- --enforce-all
1 change: 1 addition & 0 deletions frontend/nextjs-frontend/.env_example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
BACKEND_ENDPOINT=
49 changes: 49 additions & 0 deletions frontend/nextjs-frontend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# ORAssistant Frontend

This is the frontend application for ORAssistant built using Next.js.

## Setup

### Prerequisites
- Node.js
luarss marked this conversation as resolved.
Show resolved Hide resolved
- Yarn package manager

### Installation

1. Clone the repository
2. Install dependencies:
```bash
yarn install
```

### Development

To run the development server:
```bash
yarn dev
```

## Configuration

1. Create a `.env` file in the root directory
2. Add your hosted backend link:
```
BACKEND_URL=backend_api_url
```

### Suggested Questions Feature

For the suggested questions feature that uses Gemini 1.5:

1. Navigate to `orassistant-chat/.env`
2. Add the following environment variables:
```
GEMINI_API_KEY=api_key
NEXT_PUBLIC_PROXY_ENDPOINT=localhost:3001/api/chat
```

Note:
- You can generate a Gemini API key from [Google AI Studio](https://aistudio.google.com/)
- The proxy endpoint is set to localhost:3001 for development


36 changes: 36 additions & 0 deletions frontend/nextjs-frontend/apiproxy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from flask import Flask, request, Response
import requests
from flask_cors import CORS
import os
from dotenv import load_dotenv
import json

load_dotenv()

app = Flask(__name__)
luarss marked this conversation as resolved.
Show resolved Hide resolved
CORS(app)

BACKEND_ENDPOINT = os.getenv('BACKEND_ENDPOINT')

@app.route('/api/chat', methods=['POST'])
def proxy():
try:
app.logger.info('Received request: %s', request.json)

response = requests.post(BACKEND_ENDPOINT,
json=request.json)

app.logger.info('Response status: %s', response.status_code)

return Response(
response.content,
status=response.status_code,
content_type=response.headers['content-type']
)
except requests.RequestException as e:
app.logger.error('Request failed: %s', str(e))
return {'error': str(e)}, 500

if __name__ == '__main__':
port = int(os.getenv('PORT', 3001))
app.run(debug=False, port=port)
2 changes: 2 additions & 0 deletions frontend/nextjs-frontend/orassistant-chat/.env_example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
NEXT_PUBLIC_PROXY_ENDPOINT=
GEMINI_API_KEY=
3 changes: 3 additions & 0 deletions frontend/nextjs-frontend/orassistant-chat/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
36 changes: 36 additions & 0 deletions frontend/nextjs-frontend/orassistant-chat/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# 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

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
34 changes: 34 additions & 0 deletions frontend/nextjs-frontend/orassistant-chat/app/api/chat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { NextApiRequest, NextApiResponse } from "next";

export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method === "POST") {
try {
const response = await fetch("https://select-griffon-suddenly.ngrok-free.app/api/chat", {
method: "POST",
headers: {
accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(req.body),
});

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

const data = await response.json();
res.status(200).json(data);
} catch (error) {
console.error("Error in API route:", error);
res
.status(500)
.json({ error: "An error occurred while processing your request" });
}
} else {
res.setHeader("Allow", ["POST"]);
res.status(405).end(`Method ${req.method} Not Allowed`);
}
}
Binary file not shown.
40 changes: 40 additions & 0 deletions frontend/nextjs-frontend/orassistant-chat/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
--foreground-rgb: 0, 0, 0;
--background-start-rgb: 255, 255, 255;
--background-end-rgb: 240, 240, 240;
}

.dark {
--foreground-rgb: 255, 255, 255;
--background-start-rgb: 0, 0, 0;
--background-end-rgb: 0, 0, 0;
}

body {
color: rgb(var(--foreground-rgb));
background: linear-gradient(
to bottom,
transparent,
rgb(var(--background-end-rgb))
)
rgb(var(--background-start-rgb));
}

@layer utilities {
.text-balance {
text-wrap: balance;
}
}

@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}

.animate-fade-in {
animation: fadeIn 0.3s ease-out;
}
29 changes: 29 additions & 0 deletions frontend/nextjs-frontend/orassistant-chat/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import Header from "../components/Header";
import { ThemeProvider } from "../components/ThemeProvider";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
title: "ORAssistant Chat",
description: "A Conversational chatbot for all your OpenROAD queries",
};

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en" suppressHydrationWarning>
<body className={inter.className}>
<ThemeProvider attribute="class" defaultTheme="light">
<Header />
{children}
</ThemeProvider>
</body>
</html>
);
}
9 changes: 9 additions & 0 deletions frontend/nextjs-frontend/orassistant-chat/app/notfound.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default function NotFound() {
return (
<div className="flex flex-col items-center justify-center min-h-screen">
<h1 className="text-4xl font-bold mb-4">404 - Page Not Found</h1>
<p className="text-xl">The page you are looking for doesn&apos;t exist.</p>
</div>
);
}

Loading