Merge pull request 'Backend and CSS' (#17) from React-Group/interstellar_ai:main into main

Reviewed-on: https://interstellardevelopment.org/code/code/sageTheDm/interstellar_ai/pulls/17
This commit is contained in:
sageTheDm 2024-09-25 11:38:59 +02:00
commit 8e20971ded
12 changed files with 742 additions and 174 deletions

16
app/backend/database.ts Normal file
View file

@ -0,0 +1,16 @@
import axios from "axios";
const sendToDatabase = (data: any) => {
axios.post("http://localhost:5000/interstellar_ai/db", data)
.then(response => {
const status = response.data.status
console.log(status);
postMessage({ status })
console.log('message posted');
})
.catch(error => {
console.log("Error calling Database:", error)
postMessage({ status: 500 })
})
}

View file

@ -17,6 +17,11 @@ const Header: React.FC<HeaderProps> = ({ onViewChange, showDivs, toggleDivs, sho
setMenuOpen(!menuOpen)
}
const buttonClicked = (page: "AI" | "Documentation" | "FAQ") => {
onViewChange(page)
toggleMenu()
}
return (
<>
<header>
@ -26,18 +31,20 @@ const Header: React.FC<HeaderProps> = ({ onViewChange, showDivs, toggleDivs, sho
<span></span>
</div>
<nav className={`nav-links ${menuOpen ? "active":""}`}>
<button onClick={() => onViewChange('FAQ')} className="nav-btn">FAQ</button>
<button onClick={() => onViewChange('Documentation')} className="nav-btn">Documentation</button>
<button onClick={() => buttonClicked("FAQ")} className="nav-btn">FAQ</button>
<button onClick={() => buttonClicked("Documentation")} className="nav-btn">Documentation</button>
{showToggle && showHistoryModelsToggle && (
<button onClick={toggleDivs} className="nav-btn">
{showDivs ? 'Hide History/Models' : 'Show History/Models'}
</button>
)}
</nav>
{/* <button onClick={() => onViewChange('AI')} className="header-button header-logo">
<img src="/img/logo.png" alt="logo" className="header-logo" />
</button> */}
<Login />
<button onClick={() => onViewChange('AI')} className="header-button header-logo">
<p>1</p>
</button>
<div className="login-button">
<Login />
</div>
</header>
</>
);

View file

@ -53,11 +53,10 @@ const Login: React.FC = () => {
return (
<div>
{/* Login or Settings Button */}
<div className="login-button">
<button onClick={isLoggedIn ? toggleSettingsPopup : toggleLoginPopup}>
{isLoggedIn ? 'Settings' : 'Log In'}
</button>
</div>
<button onClick={isLoggedIn ? toggleSettingsPopup : toggleLoginPopup}>
{isLoggedIn ? 'Settings' : 'Log In'}
</button>
{/* Conditional rendering of the Login Popup */}
{showLoginPopup && (

View file

@ -1,34 +1,3 @@
/* Container for the login layout */
.login-container {
display: grid;
grid-template-columns: 1fr 3fr; /* 1fr for sidebar, 3fr for main content */
grid-auto-flow: column;
overflow-x: hidden;
height: 100%; /* Ensure it takes full height */
}
/* Button for login action */
.login-button {
position: absolute;
top: 5px;
right: 10px;
z-index: 9999; /* Highest z-index for the login button */
margin: 1px;
}
.login-button button {
padding: 10px 20px;
background-color: var(--input-button-color);
color: var(--text-color);
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s;
}
.login-button button:hover {
background-color: var(--input-button-hover-color);
}
/* Overlay for popup - full screen and centered */
.popup-overlay {

View file

@ -1,93 +1,29 @@
header {
background-color: var(--header-background-color); /* Use the new header background color */
color: var(--header-text-color); /* Use the new header text color */
width: 100%;
text-decoration: none;
position: fixed;
header{
position: absolute;
padding: 0 20px;
top: 0;
left: 0;
padding: 10px 20px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
z-index: 1000;
font-family: var(--font-family);
width: 100%;
height: 10vh;
display: flex;
justify-content: space-between;
align-items: center;
}
.nav-links{
display: flex;
gap: 15px;
}
.nav-btn{
background: transparent;
border: none;
cursor: pointer;
/* color */
}
.nav-btn:hover{
/* color */
}
.hamburger{
display: none;
flex-direction: column;
}
.login-button button{
padding: 10px 20px;
background-color: var(--input-button-color);
color: var(--text-color);
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s;
}
.hamburger span{
width: 25px;
height: 3px;
background-color: var(--header-text-color);
margin: 4px;
transition: 0.3s;
}
.hamburger.open span:nth-child(1){
transform: rotate(45deg) translate(5px, 5px);
}
.hamburger.open span:nth-child(2){
opacity: 0;
}
.hamburger.open span:nth-child(3){
transform: rotate(-45deg) translate(5px, -5px);
}
.header-button{
}
.header-button img{
height: 8vh;
}
@media (max-width:768px) {
.nav-links{
display: none;
position: absolute;
top: 60px;
right: 0;
/* background color */
width: 100%;
flex-direction: column;
align-items: flex-start;
padding: 10px;
}
.nav-links.active{
display: flex;
}
.nav-btn{
width: 100%;
text-align: center;
padding: 10px;
}
.hamburger{
display: flex;
}
.login-button button:hover {
background-color: var(--input-button-hover-color);
}

View file

@ -8,8 +8,6 @@
/* Header styles */
header {
flex-direction: column;
align-items: center;
position: fixed;
top: 0;
left: 0;
@ -36,17 +34,6 @@
margin: 0;
}
header li button {
margin: 2px;
margin-bottom: 0;
}
header li img {
height: 1.5em;
vertical-align: middle;
margin-top: 10px;
}
/* Left panel styles */
.left-panel {
display: hidden; /* Initially hidden */
@ -120,6 +107,18 @@
.login-button button{
margin: 20px 0;
}
.hamburger.open{
margin-top: 0.5vh;
}
.nav-links{
position: fixed;
}
.hamburger {
display: flex;
}
}
/* Responsive adjustments for the settings */

View file

@ -19,6 +19,7 @@
--conversation-background-color: #79832e; /* Background color for conversation container */
--doc-background-color: #ffffff; /* Background color for documents */
--close-button-color: red;
--burger-menu-background-color: #79832e;
/* FAQ Colors */
--faq-background-color: #474D22; /* Background color for FAQ section */

28
main.js Normal file
View file

@ -0,0 +1,28 @@
const { app, BrowserWindow } = require('electron');
function createWindow() {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
},
autoHideMenuBar: true,
});
win.loadURL('http://localhost:3000');
}
app.whenReady().then(createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});

615
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -2,15 +2,18 @@
"name": "interstellar_ai",
"version": "0.1.0",
"private": true,
"main": "main.js",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
"lint": "next lint",
"electron": "npx electron . & next dev"
},
"dependencies": {
"@mistralai/mistralai": "^1.0.4",
"axios": "^1.7.7",
"electron": "^32.1.2",
"fs": "^0.0.1-security",
"next": "14.2.12",
"ollama": "^0.5.9",

View file

@ -1,11 +1,21 @@
import hashlib
import json
import os
import pycouchdb
class DB:
def __init__(self):
self.database = {}
def ensure_username(self, data):
if hasattr(data, 'username'):
return data.get['username']
elif hasattr(data, 'email'):
for index, entry in self.database:
if entry.get['email'] == data.get['email']:
return index
@staticmethod
def hash_password(password):
salt = "your_secret_salt"
@ -15,12 +25,26 @@ class DB:
def add_user(self, data):
username = data.get['username']
password = data.get['password']
email = data.get['email']
hashed_password = self.hash_password(password)
user_data = {"hashed_password": hashed_password}
self.database[username] = user_data
user_data = {"hashed_password": hashed_password, "email": email, "data": None}
if username not in self.database:
self.database[username] = user_data
return True
return False
def delete_user(self, data):
username = self.ensure_username(data)
data = data.get['data']
if not self.check_credentials(data):
return False
del self.database[username]
self.save_database()
return True
def change_data(self, data):
username = data.get['username']
username = self.ensure_username(data)
data = data.get['data']
if not self.check_credentials(data):
return False
@ -30,7 +54,7 @@ class DB:
return True
def update_password(self, data):
username = data.get['username']
username = self.ensure_username(data)
new_password = data.get['new_password']
if not self.check_credentials(data):
return False
@ -41,7 +65,7 @@ class DB:
return True
def check_credentials(self, data):
username = data.get['username']
username = self.ensure_username(data)
password = data.get['password']
if username not in self.database:
return False
@ -51,7 +75,7 @@ class DB:
return stored_hashed_password == entered_hashed_password
def get_data(self, data):
username = data.get['username']
username = self.ensure_username(data)
if not self.check_credentials(data):
return None
@ -59,12 +83,28 @@ class DB:
return send_back
def save_database(self):
with open("database.json", 'w') as file:
json.dump(self.database, file)
if os.environ.get('PRODUCTION') == "YES":
server = pycouchdb.Server("http://admin:admin@localhost:5984/")
db = server.database("interstellar_ai")
db.save(self.database)
else:
with open("database.json", 'w') as file:
json.dump(self.database, file)
def load_database(self):
try:
with open("database.json", 'r') as file:
self.database = json.load(file)
except FileNotFoundError:
pass
if os.environ.get('PRODUCTION') == "YES":
server = pycouchdb.Server("http://admin:admin@localhost:5984/")
db = server.database("interstellar_ai")
if db:
self.database = db
else:
server.create("interstellar_ai")
db = server.database("interstellar_ai")
db.save(self.database)
else:
try:
with open("database.json", 'r') as file:
self.database = json.load(file)
except FileNotFoundError:
pass

View file

@ -10,3 +10,4 @@ PocketSphinx
google-cloud-speech
google-generativeai
python-weather
pycouchdb