Merge pull request 'main' (#48) from React-Group/interstellar_ai:main into main

Reviewed-on: https://interstellardevelopment.org/code/code/YasinOnm08/interstellar_ai/pulls/48
This commit is contained in:
Patrick 2024-10-07 09:10:24 +02:00
commit 82b041711c
16 changed files with 198 additions and 240 deletions

View file

@ -1,34 +0,0 @@
import React, { useState, useRef } from 'react'
export const AudioRecorder= () => {
const [isRecording, setIsRecording] = useState(false)
const [audioURL, setAudioURL] = useState<string | null>(null)
const mediaRecorderRef = useRef<MediaRecorder | null>(null)
const audioChunks = useRef<Blob[]>([])
const startRecording = async () => {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
const mediaRecorder = new MediaRecorder(stream)
mediaRecorderRef.current = mediaRecorder
mediaRecorder.ondataavailable = (event) => {
audioChunks.current.push(event.data)
}
mediaRecorder.onstop = () => {
const audioBlob = new Blob(audioChunks.current, { type: "audio/wav" })
const url = URL.createObjectURL(audioBlob)
setAudioURL(url)
audioChunks.current = []
}
mediaRecorder.start()
setIsRecording(true)
}
const stopRecording = () => {
mediaRecorderRef.current?.stop()
setIsRecording(false)
}
}

View file

@ -1,4 +1,4 @@
type ChatMessage = {
/* type ChatMessage = {
name: string;
messages: any;
timestamp: number;
@ -26,3 +26,4 @@ function removeMessageFromHistory(timestamp: number): void {
console.log(`Message not found with timestamp: ${timestamp}`);
}
}
*/

View file

@ -1,5 +1,5 @@
"use client"
import React, { use, useEffect, useRef, useState } from "react";
import React, { useEffect, useRef, useState } from "react";
import ConversationFrontend from '../components/ConversationFrontend';
import InputFrontend from "../components/InputFrontend";
import { sendToVoiceRecognition } from "./voice_backend"
@ -61,7 +61,6 @@ const InputOutputBackend: React.FC = () => {
const [accessToken, setAccessToken] = useState("")
const postWorkerRef = useRef<Worker | null>(null)
const getWorkerRef = useRef<Worker | null>(null)
const [liveMessage, setLiveMessage] = useState("")
const [inputMessage, setInputMessage] = useState<string>("")
const [inputDisabled, setInputDisabled] = useState(false)
const [isRecording, setIsRecording] = useState(false)
@ -123,7 +122,7 @@ const InputOutputBackend: React.FC = () => {
const data = event.data
if (event.data == "error") {
setLiveMessage("error getting AI response: " + data.error)
console.log("Error getting ai message.")
} else {
console.log("Received data:", data);
editLastMessage(data.response)
@ -171,7 +170,7 @@ const InputOutputBackend: React.FC = () => {
if (postWorkerRef.current) {
addMessage("user", inputValue)
const type = localStorage.getItem('type')
var api_key: string = ""
let api_key: string = ""
if (type != null && type != 'local') {
const try_key = localStorage.getItem(type)
if (try_key) {
@ -236,7 +235,7 @@ const InputOutputBackend: React.FC = () => {
}
const handleResendClick = () => {
var temporary_message = messages[messages.length - 2]['content']
const temporary_message = messages[messages.length - 2]['content']
const updatedMessages = messages.slice(0, -2)
setMessages(updatedMessages)
endGetWorker()
@ -246,7 +245,7 @@ const InputOutputBackend: React.FC = () => {
}
const handleEditClick = () => {
let newestMessage = messages[messages.length - 2].content
const newestMessage = messages[messages.length - 2].content
setInputMessage(newestMessage)
const updatedMessages = messages.slice(0, messages.length - 2)
setMessages(updatedMessages)

View file

@ -1,5 +1,4 @@
import { Settings } from 'electron'
import React from 'react'
/* import { Settings } from 'electron'
type Message = {
role: string
@ -14,7 +13,7 @@ type Chat = {
type Data = {
chats: Chat[]
settings: Settings[]
}
} */

View file

@ -21,7 +21,7 @@ to check if the request was accepted or declined, check response.data.response,
const apiURL = new URL("http://localhost:5000/interstellar_ai/db")
apiURL.hostname = window.location.hostname;
export const sendToDatabase = async (data: any): Promise<boolean> => {
export const sendToDatabase = async (data: object): Promise<boolean> => {
try {
const response = await axios.post(apiURL.href, data);
const status = response.data.status;
@ -30,11 +30,12 @@ export const sendToDatabase = async (data: any): Promise<boolean> => {
return success;
} catch (error) {
postMessage({ status: 500, success: false });
console.log(error)
return false;
}
};
export const sendToDatabaseAndGetString = async (data: any): Promise<string> => {
export const sendToDatabaseAndGetString = async (data: object): Promise<string> => {
try {
const response = await axios.post(apiURL.href, data);
const status = response.data.status;
@ -43,6 +44,7 @@ export const sendToDatabaseAndGetString = async (data: any): Promise<string> =>
return success;
} catch (error) {
postMessage({ status: 500, success: false });
console.log(error)
return "false";
}
};
@ -99,7 +101,7 @@ export const getName = async (usernameOrEmail: string, password: string): Promis
return await sendToDatabaseAndGetString(data);
};
export const changeData = async (usernameOrEmail: string, password: string, newData: any) => {
export const changeData = async (usernameOrEmail: string, password: string, newData: object) => {
const data = {
action: "change_settings",
username: usernameOrEmail.includes('@') ? undefined : usernameOrEmail,
@ -117,7 +119,7 @@ export const checkCredentials = async (usernameOrEmail: string, password: string
email: usernameOrEmail.includes('@') ? usernameOrEmail : undefined,
password,
};
var sendBack = await sendToDatabase(data);
const sendBack = await sendToDatabase(data);
if (sendBack) {
localStorage.setItem("accountEmail", await getEmail(usernameOrEmail, password))
localStorage.setItem("accountName", await getName(usernameOrEmail, password))

View file

@ -38,7 +38,7 @@ const ConversationFrontend = React.forwardRef<HTMLDivElement, ConversationProps>
threshold: 1.0, // Ensure the whole element is visible
}
);
const endOfMessages = messagesEndRef.current;
if (endOfMessages) {
observer.observe(endOfMessages);
@ -80,36 +80,38 @@ const ConversationFrontend = React.forwardRef<HTMLDivElement, ConversationProps>
<div className="button-container">
<div className="tooltip">
<button type="button" onClick={onStopClick}>
<svg style={{fill:"var(--text-color)"}} viewBox="0 0 512 512"><path d="M256 0c-25.3 0-47.2 14.7-57.6 36c-7-2.6-14.5-4-22.4-4c-35.3 0-64 28.7-64 64l0 165.5-2.7-2.7c-25-25-65.5-25-90.5 0s-25 65.5 0 90.5L106.5 437c48 48 113.1 75 181 75l8.5 0 8 0c1.5 0 3-.1 4.5-.4c91.7-6.2 165-79.4 171.1-171.1c.3-1.5 .4-3 .4-4.5l0-176c0-35.3-28.7-64-64-64c-5.5 0-10.9 .7-16 2l0-2c0-35.3-28.7-64-64-64c-7.9 0-15.4 1.4-22.4 4C303.2 14.7 281.3 0 256 0zM240 96.1l0-.1 0-32c0-8.8 7.2-16 16-16s16 7.2 16 16l0 31.9 0 .1 0 136c0 13.3 10.7 24 24 24s24-10.7 24-24l0-136c0 0 0 0 0-.1c0-8.8 7.2-16 16-16s16 7.2 16 16l0 55.9c0 0 0 .1 0 .1l0 80c0 13.3 10.7 24 24 24s24-10.7 24-24l0-71.9c0 0 0-.1 0-.1c0-8.8 7.2-16 16-16s16 7.2 16 16l0 172.9c-.1 .6-.1 1.3-.2 1.9c-3.4 69.7-59.3 125.6-129 129c-.6 0-1.3 .1-1.9 .2l-4.9 0-8.5 0c-55.2 0-108.1-21.9-147.1-60.9L52.7 315.3c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L119 336.4c6.9 6.9 17.2 8.9 26.2 5.2s14.8-12.5 14.8-22.2L160 96c0-8.8 7.2-16 16-16c8.8 0 16 7.1 16 15.9L192 232c0 13.3 10.7 24 24 24s24-10.7 24-24l0-135.9z"/></svg> </button>
<svg style={{ fill: "var(--text-color)" }} viewBox="0 0 512 512"><path d="M256 0c-25.3 0-47.2 14.7-57.6 36c-7-2.6-14.5-4-22.4-4c-35.3 0-64 28.7-64 64l0 165.5-2.7-2.7c-25-25-65.5-25-90.5 0s-25 65.5 0 90.5L106.5 437c48 48 113.1 75 181 75l8.5 0 8 0c1.5 0 3-.1 4.5-.4c91.7-6.2 165-79.4 171.1-171.1c.3-1.5 .4-3 .4-4.5l0-176c0-35.3-28.7-64-64-64c-5.5 0-10.9 .7-16 2l0-2c0-35.3-28.7-64-64-64c-7.9 0-15.4 1.4-22.4 4C303.2 14.7 281.3 0 256 0zM240 96.1l0-.1 0-32c0-8.8 7.2-16 16-16s16 7.2 16 16l0 31.9 0 .1 0 136c0 13.3 10.7 24 24 24s24-10.7 24-24l0-136c0 0 0 0 0-.1c0-8.8 7.2-16 16-16s16 7.2 16 16l0 55.9c0 0 0 .1 0 .1l0 80c0 13.3 10.7 24 24 24s24-10.7 24-24l0-71.9c0 0 0-.1 0-.1c0-8.8 7.2-16 16-16s16 7.2 16 16l0 172.9c-.1 .6-.1 1.3-.2 1.9c-3.4 69.7-59.3 125.6-129 129c-.6 0-1.3 .1-1.9 .2l-4.9 0-8.5 0c-55.2 0-108.1-21.9-147.1-60.9L52.7 315.3c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L119 336.4c6.9 6.9 17.2 8.9 26.2 5.2s14.8-12.5 14.8-22.2L160 96c0-8.8 7.2-16 16-16c8.8 0 16 7.1 16 15.9L192 232c0 13.3 10.7 24 24 24s24-10.7 24-24l0-135.9z" /></svg> </button>
<span className="tooltiptext">Stop</span>
</div>
<div className="tooltip">
<button type="button" onClick={onResendClick}>
<svg style={{fill:"var(--text-color)"}} viewBox="0 0 512 512"><path d="M463.5 224l8.5 0c13.3 0 24-10.7 24-24l0-128c0-9.7-5.8-18.5-14.8-22.2s-19.3-1.7-26.2 5.2L413.4 96.6c-87.6-86.5-228.7-86.2-315.8 1c-87.5 87.5-87.5 229.3 0 316.8s229.3 87.5 316.8 0c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0c-62.5 62.5-163.8 62.5-226.3 0s-62.5-163.8 0-226.3c62.2-62.2 162.7-62.5 225.3-1L327 183c-6.9 6.9-8.9 17.2-5.2 26.2s12.5 14.8 22.2 14.8l119.5 0z"/></svg>
<svg style={{ fill: "var(--text-color)" }} viewBox="0 0 512 512"><path d="M463.5 224l8.5 0c13.3 0 24-10.7 24-24l0-128c0-9.7-5.8-18.5-14.8-22.2s-19.3-1.7-26.2 5.2L413.4 96.6c-87.6-86.5-228.7-86.2-315.8 1c-87.5 87.5-87.5 229.3 0 316.8s229.3 87.5 316.8 0c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0c-62.5 62.5-163.8 62.5-226.3 0s-62.5-163.8 0-226.3c62.2-62.2 162.7-62.5 225.3-1L327 183c-6.9 6.9-8.9 17.2-5.2 26.2s12.5 14.8 22.2 14.8l119.5 0z" /></svg>
</button>
<span className="tooltiptext">Resend</span>
</div>
<div className="tooltip">
<button type="button" onClick={onEditClick}>
<svg style={{fill:"var(--text-color)"}} viewBox="0 0 512 512"><path d="M471.6 21.7c-21.9-21.9-57.3-21.9-79.2 0L362.3 51.7l97.9 97.9 30.1-30.1c21.9-21.9 21.9-57.3 0-79.2L471.6 21.7zm-299.2 220c-6.1 6.1-10.8 13.6-13.5 21.9l-29.6 88.8c-2.9 8.6-.6 18.1 5.8 24.6s15.9 8.7 24.6 5.8l88.8-29.6c8.2-2.7 15.7-7.4 21.9-13.5L437.7 172.3 339.7 74.3 172.4 241.7zM96 64C43 64 0 107 0 160L0 416c0 53 43 96 96 96l256 0c53 0 96-43 96-96l0-96c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 96c0 17.7-14.3 32-32 32L96 448c-17.7 0-32-14.3-32-32l0-256c0-17.7 14.3-32 32-32l96 0c17.7 0 32-14.3 32-32s-14.3-32-32-32L96 64z"/></svg>
<svg style={{ fill: "var(--text-color)" }} viewBox="0 0 512 512"><path d="M471.6 21.7c-21.9-21.9-57.3-21.9-79.2 0L362.3 51.7l97.9 97.9 30.1-30.1c21.9-21.9 21.9-57.3 0-79.2L471.6 21.7zm-299.2 220c-6.1 6.1-10.8 13.6-13.5 21.9l-29.6 88.8c-2.9 8.6-.6 18.1 5.8 24.6s15.9 8.7 24.6 5.8l88.8-29.6c8.2-2.7 15.7-7.4 21.9-13.5L437.7 172.3 339.7 74.3 172.4 241.7zM96 64C43 64 0 107 0 160L0 416c0 53 43 96 96 96l256 0c53 0 96-43 96-96l0-96c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 96c0 17.7-14.3 32-32 32L96 448c-17.7 0-32-14.3-32-32l0-256c0-17.7 14.3-32 32-32l96 0c17.7 0 32-14.3 32-32s-14.3-32-32-32L96 64z" /></svg>
</button>
<span className="tooltiptext">Edit</span>
</div>
<div className="tooltip">
<button type="button" onClick={onCopyClick}>
<svg style={{fill:"var(--text-color)"}} viewBox="0 0 512 512" preserveAspectRatio="none"><path d="M208 0L332.1 0c12.7 0 24.9 5.1 33.9 14.1l67.9 67.9c9 9 14.1 21.2 14.1 33.9L448 336c0 26.5-21.5 48-48 48l-192 0c-26.5 0-48-21.5-48-48l0-288c0-26.5 21.5-48 48-48zM48 128l80 0 0 64-64 0 0 256 192 0 0-32 64 0 0 48c0 26.5-21.5 48-48 48L48 512c-26.5 0-48-21.5-48-48L0 176c0-26.5 21.5-48 48-48z"/></svg>
<svg style={{ fill: "var(--text-color)" }} viewBox="0 0 512 512" preserveAspectRatio="none"><path d="M208 0L332.1 0c12.7 0 24.9 5.1 33.9 14.1l67.9 67.9c9 9 14.1 21.2 14.1 33.9L448 336c0 26.5-21.5 48-48 48l-192 0c-26.5 0-48-21.5-48-48l0-288c0-26.5 21.5-48 48-48zM48 128l80 0 0 64-64 0 0 256 192 0 0-32 64 0 0 48c0 26.5-21.5 48-48 48L48 512c-26.5 0-48-21.5-48-48L0 176c0-26.5 21.5-48 48-48z" /></svg>
</button>
<span className="tooltiptext">{isClicked?"Copied!": "Copy" }</span>
<span className="tooltiptext">{isClicked ? "Copied!" : "Copy"}</span>
</div>
</div>
<div className={"endOfMessages"} ref={messagesEndRef} style={{ height: "3px"}}/>
<div className={"endOfMessages"} ref={messagesEndRef} style={{ height: "3px" }} />
</div>
<button id="scrollToBottom" disabled={isScrolling ? true : false} style={{ visibility: isScrolling ? "hidden" : "visible" }} onClick={() => setIsScrolling(true)}>
<svg style={{fill:"var(--text-color)"}} viewBox="0 0 384 512" height={30}><path d="M169.4 470.6c12.5 12.5 32.8 12.5 45.3 0l160-160c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L224 370.8 224 64c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 306.7L54.6 265.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l160 160z"/></svg>
<svg style={{ fill: "var(--text-color)" }} viewBox="0 0 384 512" height={30}><path d="M169.4 470.6c12.5 12.5 32.8 12.5 45.3 0l160-160c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L224 370.8 224 64c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 306.7L54.6 265.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l160 160z" /></svg>
</button>
</div>
);
}
}
);
ConversationFrontend.displayName = "ConversationFrontend";
export default ConversationFrontend;

View file

@ -3,120 +3,120 @@ import React from 'react';
const Documentation = () => {
return (
<div className="documentation-container">
<section id="documentation" className="documentation-section">
<h1 className="title">AI Virtual Assistant - Internship Students 2024</h1>
<h2 className="subtitle">General planning:</h2>
<p className="paragraph">
We are currently in the process of developing a Python application that leverages HTML and CSS to create an intuitive graphical user interface (GUI). This application will integrate multiple AI models through API calls, enabling users to effortlessly switch between different models tailored for specific tasks, such as coding, mathematics, and language processing. A key feature of our design is that the application will be capable of running locally, ensuring that users can access its functionality without the need for an internet connection.
</p>
<p className="paragraph">
Upon receiving our assignment, we initiated the project by outlining a detailed timeline for each task to ensure a structured approach to development. This timeline serves as a roadmap, helping us allocate resources effectively and track our progress. Following this planning phase, Patrick_Pluto took the lead in creating the repository, establishing a centralized location for our codebase. Meanwhile, Yasin and sageTheDM forked the repository to begin their contributions, allowing them to work on specific features and enhancements independently.
</p>
<p className="paragraph">
As we move forward, our focus will be on refining the user experience, optimizing the integration of AI models, and ensuring that the application is robust and user-friendly. We are excited about the potential of this project and are committed to delivering a high-quality application that meets the needs of our users.
</p>
<section id="documentation" className="documentation-section">
<h1 className="title">AI Virtual Assistant - Internship Students 2024</h1>
<h2 className="subtitle">General planning:</h2>
<p className="paragraph">
We are currently in the process of developing a Python application that leverages HTML and CSS to create an intuitive graphical user interface (GUI). This application will integrate multiple AI models through API calls, enabling users to effortlessly switch between different models tailored for specific tasks, such as coding, mathematics, and language processing. A key feature of our design is that the application will be capable of running locally, ensuring that users can access its functionality without the need for an internet connection.
</p>
<p className="paragraph">
Upon receiving our assignment, we initiated the project by outlining a detailed timeline for each task to ensure a structured approach to development. This timeline serves as a roadmap, helping us allocate resources effectively and track our progress. Following this planning phase, Patrick_Pluto took the lead in creating the repository, establishing a centralized location for our codebase. Meanwhile, Yasin and sageTheDM forked the repository to begin their contributions, allowing them to work on specific features and enhancements independently.
</p>
<p className="paragraph">
As we move forward, our focus will be on refining the user experience, optimizing the integration of AI models, and ensuring that the application is robust and user-friendly. We are excited about the potential of this project and are committed to delivering a high-quality application that meets the needs of our users.
</p>
<h2 className="subtitle">Frontend planning:</h2>
<p className="paragraph">
We are committed to designing a visually appealing graphical user interface (GUI) that significantly enhances user experience and engagement. The GUI will prominently feature a chat function, allowing users to interact seamlessly with the AI Assistant. This conversational interface will facilitate easy communication, making it intuitive for users to ask questions and receive responses.
</p>
<p className="paragraph">
To further improve usability, we will incorporate distinct buttons that enable users to switch effortlessly between online and offline modes. This functionality ensures that users can access the AI's capabilities regardless of their internet connectivity, making the application versatile and accommodating to various user environments.
</p>
<p className="paragraph">
Additionally, the interface will provide options for users to select from a range of AI models, each tailored for specific use cases such as coding assistance, mathematical problem-solving, and language translation. This feature empowers users to choose the most suitable AI for their needs, thereby enhancing the overall effectiveness and relevance of the application.
</p>
<p className="paragraph">
We will also prioritize creating an intuitive layout, ensuring that all elements are easily accessible and visually coherent. By focusing on user experience in our design, we aim to make the application not only functional but also enjoyable to use. Our goal is to create a user-friendly environment that encourages exploration and interaction, ultimately leading to a more satisfying and productive experience for all users.
</p>
<h2 className="subtitle">Frontend planning:</h2>
<p className="paragraph">
We are committed to designing a visually appealing graphical user interface (GUI) that significantly enhances user experience and engagement. The GUI will prominently feature a chat function, allowing users to interact seamlessly with the AI Assistant. This conversational interface will facilitate easy communication, making it intuitive for users to ask questions and receive responses.
</p>
<p className="paragraph">
To further improve usability, we will incorporate distinct buttons that enable users to switch effortlessly between online and offline modes. This functionality ensures that users can access the AI&apos;s capabilities regardless of their internet connectivity, making the application versatile and accommodating to various user environments.
</p>
<p className="paragraph">
Additionally, the interface will provide options for users to select from a range of AI models, each tailored for specific use cases such as coding assistance, mathematical problem-solving, and language translation. This feature empowers users to choose the most suitable AI for their needs, thereby enhancing the overall effectiveness and relevance of the application.
</p>
<p className="paragraph">
We will also prioritize creating an intuitive layout, ensuring that all elements are easily accessible and visually coherent. By focusing on user experience in our design, we aim to make the application not only functional but also enjoyable to use. Our goal is to create a user-friendly environment that encourages exploration and interaction, ultimately leading to a more satisfying and productive experience for all users.
</p>
<h2 className="subtitle">Draw.io:</h2>
<img src="/img/Live-Message-Idee.jpg" alt='Live Message Skizze' />
<h2 className="subtitle">Draw.io:</h2>
<img src="/img/Live-Message-Idee.jpg" alt='Live Message Skizze' />
<h2 className="subtitle">Inspiration:</h2>
<p className="paragraph">We got our inspiration from Huggingchat.</p>
<h2 className="subtitle">Inspiration:</h2>
<p className="paragraph">We got our inspiration from Huggingchat.</p>
<h2 className="subtitle">First prototype:</h2>
<p className="paragraph">
After prototyping the Website we started working on optimizing the css and html structure, and combining the front and the backend together with each other using Flask. Since we have never once done that once it was more learning by doing than planning that is why we have not planned this step but documented it.
</p>
<h2 className="subtitle">First prototype:</h2>
<p className="paragraph">
After prototyping the Website we started working on optimizing the css and html structure, and combining the front and the backend together with each other using Flask. Since we have never once done that once it was more learning by doing than planning that is why we have not planned this step but documented it.
</p>
<h2 className="subtitle">Web APP</h2>
<h3 className="subsection-title">QtWebEngine 5</h3>
<p className="paragraph">
We decided on going with QtWebEngine, because Qt is cross platform, and easy to use. QtWebEngine is basically a slimmed down version of Chromium that runs on the Qt Widget Framework. It looked pretty good, but the browser part is very barebones, so it broke a lot of styling.
</p>
<h3 className="subsection-title">Styling</h3>
<p className="paragraph">
After conducting thorough testing, we discovered that even after performing a browser reset, the web application exhibited a distinct styling compared to the web version. This inconsistency prompted us to undertake a comprehensive overhaul of the entire CSS framework.
</p>
<p className="paragraph">
In our redesign, we focused on enhancing the user experience by implementing custom scrollbars that align with our overall aesthetic. Additionally, we expanded upon our existing design foundation to ensure a more cohesive and visually appealing interface.
</p>
<p className="paragraph">
Our efforts have resulted in a web application that is not only visually consistent across different platforms but also optimized for performance. The revamped web app is designed to be responsive, making it accessible and functional on a wide range of devices, from desktops to tablets and smartphones. This adaptability ensures that users can enjoy a seamless experience, regardless of the device they choose to use.
</p>
<p className="paragraph">
Overall, these improvements reflect our commitment to delivering a high-quality product that meets the diverse needs of our users while maintaining a polished and professional appearance.
</p>
<h2 className="subtitle">Web APP</h2>
<h3 className="subsection-title">QtWebEngine 5</h3>
<p className="paragraph">
We decided on going with QtWebEngine, because Qt is cross platform, and easy to use. QtWebEngine is basically a slimmed down version of Chromium that runs on the Qt Widget Framework. It looked pretty good, but the browser part is very barebones, so it broke a lot of styling.
</p>
<h2 className="subtitle">Prototype: 17.09.2024</h2>
<p className="paragraph">
Our current prototype operates on a straightforward Python backend, which, while functional, relies heavily on our optimism that it will remain stable and not encounter any critical failures or data loss.
</p>
<p className="paragraph">
The existing chat system is equipped with several key features designed to enhance user interaction. Users can easily resend the AI's response, allowing for quick follow-up questions or clarifications. Additionally, the system provides the ability to edit user messages, ensuring that any mistakes can be corrected without starting the conversation anew.
</p>
<p className="paragraph">
Furthermore, users have the option to copy the AI's responses, facilitating easy sharing or saving of information for future reference. These features aim to create a more flexible and user-friendly experience, allowing for seamless communication and interaction with the AI.
</p>
<p className="paragraph">
While the current setup serves as a solid foundation, we recognize the need for further improvements and enhancements to ensure reliability and robustness as we move forward in the development process.
</p>
<p className="paragraph">
Theoretically there is also voice recognition but let us ignore that for now.
</p>
<h3 className="subsection-title">Styling</h3>
<p className="paragraph">
After conducting thorough testing, we discovered that even after performing a browser reset, the web application exhibited a distinct styling compared to the web version. This inconsistency prompted us to undertake a comprehensive overhaul of the entire CSS framework.
</p>
<p className="paragraph">
In our redesign, we focused on enhancing the user experience by implementing custom scrollbars that align with our overall aesthetic. Additionally, we expanded upon our existing design foundation to ensure a more cohesive and visually appealing interface.
</p>
<p className="paragraph">
Our efforts have resulted in a web application that is not only visually consistent across different platforms but also optimized for performance. The revamped web app is designed to be responsive, making it accessible and functional on a wide range of devices, from desktops to tablets and smartphones. This adaptability ensures that users can enjoy a seamless experience, regardless of the device they choose to use.
</p>
<p className="paragraph">
Overall, these improvements reflect our commitment to delivering a high-quality product that meets the diverse needs of our users while maintaining a polished and professional appearance.
</p>
<h2 className="subtitle">17.09.2024</h2>
<p className="paragraph">
After transitioning to React, we made several significant changes. We renamed our History and Models components to .left-panel, which can now be hidden when not in use. Additionally, with various optimizations through React, weve successfully split the CSS and HTML components into more manageable parts.
</p>
<p className="paragraph">
We also made our first strides towards achieving a fully responsive website. With these changes, we are well on our way to completing the responsive design in the near future.
</p>
<h2 className="subtitle">Prototype: 17.09.2024</h2>
<p className="paragraph">
Our current prototype operates on a straightforward Python backend, which, while functional, relies heavily on our optimism that it will remain stable and not encounter any critical failures or data loss.
</p>
<p className="paragraph">
The existing chat system is equipped with several key features designed to enhance user interaction. Users can easily resend the AI&apos;s response, allowing for quick follow-up questions or clarifications. Additionally, the system provides the ability to edit user messages, ensuring that any mistakes can be corrected without starting the conversation anew.
</p>
<p className="paragraph">
Furthermore, users have the option to copy the AI&apos;s responses, facilitating easy sharing or saving of information for future reference. These features aim to create a more flexible and user-friendly experience, allowing for seamless communication and interaction with the AI.
</p>
<p className="paragraph">
While the current setup serves as a solid foundation, we recognize the need for further improvements and enhancements to ensure reliability and robustness as we move forward in the development process.
</p>
<p className="paragraph">
Theoretically there is also voice recognition but let us ignore that for now.
</p>
<h2 className="subtitle">Backend planning:</h2>
<h3 className="subsection-title">Task:</h3>
<p className="paragraph">
We will develop an extensible backend that enables us to easily swap out different AI models, facilitating the creation of a versatile AI Virtual Assistant. This architecture will allow for seamless integration of new AI technologies as they become available, ensuring that our application remains up-to-date and capable of meeting diverse user needs.
</p>
<p className="paragraph">
The backend will also incorporate advanced features such as speech recognition, allowing users to interact with the AI Assistant through voice commands for a more natural and intuitive experience. Additionally, we will implement functionality to save chat histories, enabling users to revisit previous conversations and maintain continuity in their interactions with the AI.
</p>
<p className="paragraph">
For the AI model, we will utilize Microsoft Phi 3.5, which offers robust capabilities for understanding and generating human-like responses. This choice will enhance the overall performance of the Virtual Assistant, making it a valuable tool for users seeking assistance across various tasks and topics. By combining an extensible backend with powerful AI capabilities, we aim to deliver a comprehensive and user-friendly virtual assistant experience.
</p>
<h2 className="subtitle">17.09.2024</h2>
<p className="paragraph">
After transitioning to React, we made several significant changes. We renamed our History and Models components to .left-panel, which can now be hidden when not in use. Additionally, with various optimizations through React, weve successfully split the CSS and HTML components into more manageable parts.
</p>
<p className="paragraph">
We also made our first strides towards achieving a fully responsive website. With these changes, we are well on our way to completing the responsive design in the near future.
</p>
<h2 className="subtitle">Design Philosophy:</h2>
<p className="paragraph">
Our design philosophy is to create one script file per feature. This allows us to possibly reuse certain features in other projects very easily, as we can copy the individual .py files, which all work on their own, except the specific .py file for this project, which is specially tailored towards this AI chatbot.
</p>
<h2 className="subtitle">Backend planning:</h2>
<h3 className="subsection-title">Task:</h3>
<p className="paragraph">
We will develop an extensible backend that enables us to easily swap out different AI models, facilitating the creation of a versatile AI Virtual Assistant. This architecture will allow for seamless integration of new AI technologies as they become available, ensuring that our application remains up-to-date and capable of meeting diverse user needs.
</p>
<p className="paragraph">
The backend will also incorporate advanced features such as speech recognition, allowing users to interact with the AI Assistant through voice commands for a more natural and intuitive experience. Additionally, we will implement functionality to save chat histories, enabling users to revisit previous conversations and maintain continuity in their interactions with the AI.
</p>
<p className="paragraph">
For the AI model, we will utilize Microsoft Phi 3.5, which offers robust capabilities for understanding and generating human-like responses. This choice will enhance the overall performance of the Virtual Assistant, making it a valuable tool for users seeking assistance across various tasks and topics. By combining an extensible backend with powerful AI capabilities, we aim to deliver a comprehensive and user-friendly virtual assistant experience.
</p>
<h2 className="subtitle">UML diagrams:</h2>
<p className="paragraph">Insert your UML diagrams here, one picture per diagram.</p>
<h2 className="subtitle">Design Philosophy:</h2>
<p className="paragraph">
Our design philosophy is to create one script file per feature. This allows us to possibly reuse certain features in other projects very easily, as we can copy the individual .py files, which all work on their own, except the specific .py file for this project, which is specially tailored towards this AI chatbot.
</p>
<h2 className="subtitle">First Prototype:</h2>
<p className="paragraph">
You are able to simply select an AI Model, then type out what you want to ask. This Prototype is already ready to answer questions and detect what language you write in and give the answer in the corresponding language.
</p>
<h2 className="subtitle">UML diagrams:</h2>
<p className="paragraph">Insert your UML diagrams here, one picture per diagram.</p>
<h2 className="subtitle">Combining back and frontend</h2>
<h3 className="subsection-title">Flask setup</h3>
<p className="paragraph">
The flask setup was relatively quick. We had to adjust all of the file references, and add /static
</p>
</section>
<h2 className="subtitle">First Prototype:</h2>
<p className="paragraph">
You are able to simply select an AI Model, then type out what you want to ask. This Prototype is already ready to answer questions and detect what language you write in and give the answer in the corresponding language.
</p>
<h2 className="subtitle">Combining back and frontend</h2>
<h3 className="subsection-title">Flask setup</h3>
<p className="paragraph">
The flask setup was relatively quick. We had to adjust all of the file references, and add /static
</p>
</section>
</div>
);
};

View file

@ -12,7 +12,7 @@ const FAQ: React.FC = () => {
<div className="faq-item">
<h3>How does the AI assistant work?</h3>
<p>The assistant uses machine learning algorithms to understand your input and provide contextually relevant answers or generate content based on the task you've described.</p>
<p>The assistant uses machine learning algorithms to understand your input and provide contextually relevant answers or generate content based on the task you&apos;ve described.</p>
</div>
<div className="faq-item">
@ -32,11 +32,11 @@ const FAQ: React.FC = () => {
<div className="faq-item">
<h3>How can I provide feedback about the AI assistant?</h3>
<p>Feedback can be provided through our feedback form, available on our website. We appreciate your input and use it to improve the AI assistant's performance.</p>
<p>Feedback can be provided through our feedback form, available on our website. We appreciate your input and use it to improve the AI assistant&apos;s performance.</p>
</div>
<div className="faq-item">
<h3>Can I customize the AI assistant's responses?</h3>
<h3>Can I customize the AI assistant&apos;s responses?</h3>
<p>Customization options are limited in the current version, but we are working on features that will allow users to tailor responses to better suit their needs.</p>
</div>
@ -74,10 +74,10 @@ const FAQ: React.FC = () => {
<h3>What are the system requirements to use the AI assistant?</h3>
<p>The AI assistant can be accessed through most modern web browsers. Ensure your browser is up-to-date for the best experience.</p>
</div>
<div className="faq-item">
<h3>How can I access previous conversations?</h3>
<p>Previous conversations can be accessed through the chat history feature available in the assistant's interface.</p>
<p>Previous conversations can be accessed through the chat history feature available in the assistant&apos;s interface.</p>
</div>
<div className="faq-item">
@ -89,12 +89,12 @@ const FAQ: React.FC = () => {
<h3>How do I update my profile or settings?</h3>
<p>Profile and settings updates can be made through the account management section of the application. Ensure you save your changes before exiting.</p>
</div>
<div className="faq-item">
<h3>Can the AI assistant be used offline?</h3>
<p>Currently, the AI assistant requires an internet connection to function. Offline capabilities are being explored for future updates.</p>
</div>
<div className="faq-item">
<h3>Who can I contact for technical support?</h3>
<p>Technical support can be reached through our support contact page on the website. Our team is available to help with any technical issues you may encounter.</p>

View file

@ -10,7 +10,7 @@ interface InputProps {
}
const InputFrontend = React.forwardRef<HTMLDivElement, InputProps>(
({ message, onSendClick, onMicClick, inputDisabled, isRecording}, ref: ForwardedRef<HTMLDivElement>) => {
({ message, onSendClick, onMicClick, inputDisabled, isRecording }, ref: ForwardedRef<HTMLDivElement>) => {
const [inputValue, setInputValue] = useState('');
useEffect(() => {
@ -49,14 +49,16 @@ const InputFrontend = React.forwardRef<HTMLDivElement, InputProps>(
onKeyDown={handleKeyDown}
/>
<button type="button" onClick={handleSendClick} disabled={inputDisabled ? true : false}>
<svg style={{fill:"var(--text-color)"}} viewBox="0 0 512 512" width={20}><path d="M498.1 5.6c10.1 7 15.4 19.1 13.5 31.2l-64 416c-1.5 9.7-7.4 18.2-16 23s-18.9 5.4-28 1.6L284 427.7l-68.5 74.1c-8.9 9.7-22.9 12.9-35.2 8.1S160 493.2 160 480l0-83.6c0-4 1.5-7.8 4.2-10.8L331.8 202.8c5.8-6.3 5.6-16-.4-22s-15.7-6.4-22-.7L106 360.8 17.7 316.6C7.1 311.3 .3 300.7 0 288.9s5.9-22.8 16.1-28.7l448-256c10.7-6.1 23.9-5.5 34 1.4z"/></svg>
<svg style={{ fill: "var(--text-color)" }} viewBox="0 0 512 512" width={20}><path d="M498.1 5.6c10.1 7 15.4 19.1 13.5 31.2l-64 416c-1.5 9.7-7.4 18.2-16 23s-18.9 5.4-28 1.6L284 427.7l-68.5 74.1c-8.9 9.7-22.9 12.9-35.2 8.1S160 493.2 160 480l0-83.6c0-4 1.5-7.8 4.2-10.8L331.8 202.8c5.8-6.3 5.6-16-.4-22s-15.7-6.4-22-.7L106 360.8 17.7 316.6C7.1 311.3 .3 300.7 0 288.9s5.9-22.8 16.1-28.7l448-256c10.7-6.1 23.9-5.5 34 1.4z" /></svg>
</button>
<button className={`microphone-button ${isRecording ? "red" : "var(--input-button-color)"}`} type="button" onClick={onMicClick}>
<svg style={{fill:"var(--text-color)"}} viewBox="0 0 384 512" width={15}><path d="M192 0C139 0 96 43 96 96l0 160c0 53 43 96 96 96s96-43 96-96l0-160c0-53-43-96-96-96zM64 216c0-13.3-10.7-24-24-24s-24 10.7-24 24l0 40c0 89.1 66.2 162.7 152 174.4l0 33.6-48 0c-13.3 0-24 10.7-24 24s10.7 24 24 24l72 0 72 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-48 0 0-33.6c85.8-11.7 152-85.3 152-174.4l0-40c0-13.3-10.7-24-24-24s-24 10.7-24 24l0 40c0 70.7-57.3 128-128 128s-128-57.3-128-128l0-40z"/></svg>
<svg style={{ fill: "var(--text-color)" }} viewBox="0 0 384 512" width={15}><path d="M192 0C139 0 96 43 96 96l0 160c0 53 43 96 96 96s96-43 96-96l0-160c0-53-43-96-96-96zM64 216c0-13.3-10.7-24-24-24s-24 10.7-24 24l0 40c0 89.1 66.2 162.7 152 174.4l0 33.6-48 0c-13.3 0-24 10.7-24 24s10.7 24 24 24l72 0 72 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-48 0 0-33.6c85.8-11.7 152-85.3 152-174.4l0-40c0-13.3-10.7-24-24-24s-24 10.7-24 24l0 40c0 70.7-57.3 128-128 128s-128-57.3-128-128l0-40z" /></svg>
</button>
</div>
);
}
);
InputFrontend.displayName = "InputFrontend";
export default InputFrontend;

View file

@ -55,7 +55,7 @@ const Login: React.FC = () => {
const success = await checkCredentials(accountName, password);
if (success) {
setIsLoggedIn(true); // Successful login
var data = await getData(accountName, password)
const data = await getData(accountName, password)
if (data) {
localStorage.setItem("dataFromServer", data)
}
@ -86,7 +86,7 @@ const Login: React.FC = () => {
<div>
{/* Login or Settings Button */}
<button className='header-login-button' onClick={isLoggedIn ? toggleSettingsPopup : toggleLoginPopup}>
{isLoggedIn ? <svg style={{ fill: "var(--text-color)" }} viewBox="0 0 512 512" width={25} height={35} preserveAspectRatio="xMidYMid meet"><path d="M495.9 166.6c3.2 8.7 .5 18.4-6.4 24.6l-43.3 39.4c1.1 8.3 1.7 16.8 1.7 25.4s-.6 17.1-1.7 25.4l43.3 39.4c6.9 6.2 9.6 15.9 6.4 24.6c-4.4 11.9-9.7 23.3-15.8 34.3l-4.7 8.1c-6.6 11-14 21.4-22.1 31.2c-5.9 7.2-15.7 9.6-24.5 6.8l-55.7-17.7c-13.4 10.3-28.2 18.9-44 25.4l-12.5 57.1c-2 9.1-9 16.3-18.2 17.8c-13.8 2.3-28 3.5-42.5 3.5s-28.7-1.2-42.5-3.5c-9.2-1.5-16.2-8.7-18.2-17.8l-12.5-57.1c-15.8-6.5-30.6-15.1-44-25.4L83.1 425.9c-8.8 2.8-18.6 .3-24.5-6.8c-8.1-9.8-15.5-20.2-22.1-31.2l-4.7-8.1c-6.1-11-11.4-22.4-15.8-34.3c-3.2-8.7-.5-18.4 6.4-24.6l43.3-39.4C64.6 273.1 64 264.6 64 256s.6-17.1 1.7-25.4L22.4 191.2c-6.9-6.2-9.6-15.9-6.4-24.6c4.4-11.9 9.7-23.3 15.8-34.3l4.7-8.1c6.6-11 14-21.4 22.1-31.2c5.9-7.2 15.7-9.6 24.5-6.8l55.7 17.7c13.4-10.3 28.2-18.9 44-25.4l12.5-57.1c2-9.1 9-16.3 18.2-17.8C227.3 1.2 241.5 0 256 0s28.7 1.2 42.5 3.5c9.2 1.5 16.2 8.7 18.2 17.8l12.5 57.1c15.8 6.5 30.6 15.1 44 25.4l55.7-17.7c8.8-2.8 18.6-.3 24.5 6.8c8.1 9.8 15.5 20.2 22.1 31.2l4.7 8.1c6.1 11 11.4 22.4 15.8 34.3zM256 336a80 80 0 1 0 0-160 80 80 0 1 0 0 160z"/></svg> : 'Log In'}
{isLoggedIn ? <svg style={{ fill: "var(--text-color)" }} viewBox="0 0 512 512" width={25} height={35} preserveAspectRatio="xMidYMid meet"><path d="M495.9 166.6c3.2 8.7 .5 18.4-6.4 24.6l-43.3 39.4c1.1 8.3 1.7 16.8 1.7 25.4s-.6 17.1-1.7 25.4l43.3 39.4c6.9 6.2 9.6 15.9 6.4 24.6c-4.4 11.9-9.7 23.3-15.8 34.3l-4.7 8.1c-6.6 11-14 21.4-22.1 31.2c-5.9 7.2-15.7 9.6-24.5 6.8l-55.7-17.7c-13.4 10.3-28.2 18.9-44 25.4l-12.5 57.1c-2 9.1-9 16.3-18.2 17.8c-13.8 2.3-28 3.5-42.5 3.5s-28.7-1.2-42.5-3.5c-9.2-1.5-16.2-8.7-18.2-17.8l-12.5-57.1c-15.8-6.5-30.6-15.1-44-25.4L83.1 425.9c-8.8 2.8-18.6 .3-24.5-6.8c-8.1-9.8-15.5-20.2-22.1-31.2l-4.7-8.1c-6.1-11-11.4-22.4-15.8-34.3c-3.2-8.7-.5-18.4 6.4-24.6l43.3-39.4C64.6 273.1 64 264.6 64 256s.6-17.1 1.7-25.4L22.4 191.2c-6.9-6.2-9.6-15.9-6.4-24.6c4.4-11.9 9.7-23.3 15.8-34.3l4.7-8.1c6.6-11 14-21.4 22.1-31.2c5.9-7.2 15.7-9.6 24.5-6.8l55.7 17.7c13.4-10.3 28.2-18.9 44-25.4l12.5-57.1c2-9.1 9-16.3 18.2-17.8C227.3 1.2 241.5 0 256 0s28.7 1.2 42.5 3.5c9.2 1.5 16.2 8.7 18.2 17.8l12.5 57.1c15.8 6.5 30.6 15.1 44 25.4l55.7-17.7c8.8-2.8 18.6-.3 24.5 6.8c8.1 9.8 15.5 20.2 22.1 31.2l4.7 8.1c6.1 11 11.4 22.4 15.8 34.3zM256 336a80 80 0 1 0 0-160 80 80 0 1 0 0 160z" /></svg> : 'Log In'}
</button>
{/* Conditional rendering of the Login Popup */}
@ -131,7 +131,7 @@ const Login: React.FC = () => {
{/* Text for creating an account */}
<p>
Don't have an account yet? Create one{' '}
Don&apos;t have an account yet? Create one{' '}
<span
style={{ color: 'blue', cursor: 'pointer' }}
onClick={toggleSignUpPopup}

View file

@ -173,10 +173,10 @@ const ModelSection: React.FC = () => {
const [radioSelection, setRadioSelection] = useState<string | null>("")
const [activeSelectedAIFunction, setActiveSelectedAIFunction] = useState('');
const [currentSelectedAIFunction, setCurrentSelectedAIFunction] = useState<string | null>("");
const [isOpenSourceMode, setIsOpenSourceMode] = useState(localStorage.getItem('openSourceMode') || "false")
const [isOpenSourceMode] = useState(localStorage.getItem('openSourceMode') || "false")
useEffect(() => {
var temp = localStorage.getItem("activeSelectedAIFunction") || ""
const temp = localStorage.getItem("activeSelectedAIFunction") || ""
setActiveSelectedAIFunction(temp)
if (!localStorage.getItem('selectedModelDropdown')) {
localStorage.setItem("selectedModelDropdown", "Offline Fast")
@ -215,7 +215,7 @@ const ModelSection: React.FC = () => {
}, []); // Dependency array can remain empty if you only want this to run on mount
useEffect(() => {
var storedActiveSelectedAIFunction = localStorage.getItem("activeSelectedAIFunction") || "";
const storedActiveSelectedAIFunction = localStorage.getItem("activeSelectedAIFunction") || "";
if (storedActiveSelectedAIFunction !== currentSelectedAIFunction) {
setCurrentSelectedAIFunction(storedActiveSelectedAIFunction);
}
@ -225,7 +225,7 @@ const ModelSection: React.FC = () => {
const newModel = event.target.value;
setSelectedModelDropdown(newModel);
localStorage.setItem('selectedModelDropdown', newModel); // Update localStorage directly
var model = localStorage.getItem('activeSelectedAIFunction') || "Code"
const model = localStorage.getItem('activeSelectedAIFunction') || "Code"
modelClicked(model)
};
@ -287,7 +287,7 @@ const ModelSection: React.FC = () => {
const modelClicked = (model: string) => {
localStorage.setItem('activeSelectedAIFunction', model)
setActiveSelectedAIFunction(model)
var modelDropdown = localStorage.getItem('selectedModelDropdown') || 'Offline Fast'
const modelDropdown = localStorage.getItem('selectedModelDropdown') || 'Offline Fast'
const selectedAIFunction = modelDropdown as keyof typeof modelList;
localStorage.setItem("model", modelList[selectedAIFunction][model as keyof typeof modelList[typeof selectedAIFunction]])
localStorage.setItem("type", modelList[selectedAIFunction]['model_type' as keyof typeof modelList[typeof selectedAIFunction]])

View file

@ -6,12 +6,12 @@ interface ButtonSettingProps {
className?: string; // Optional additional classes for styling
}
const ButtonSetting: React.FC<ButtonSettingProps> = ({ label, onClick, className }) => {
const ButtonSetting: React.FC<ButtonSettingProps> = ({ label, onClick }) => {
return (
<div className="settings-option">
<button
<button
onClick={onClick} // Call the onClick function when the button is clicked
className={className="export-button"} // Apply any additional classes
className={"export-button"} // Apply any additional classes
>
{label} {/* Display the label on the button */}
</button>

View file

@ -1,41 +1,40 @@
// ThemeDropdown.tsx
import React from 'react';
import { applyTheme, applyCustomTheme } from './theme';
// ThemeDropdown.tsx
import React from 'react';
const ThemeDropdown: React.FC<{
selectedTheme: string;
setSelectedTheme: (theme: string) => void;
}> = ({ selectedTheme, setSelectedTheme }) => {
const themeOptions = [
{ value: 'IOMARKET', label: 'IOMARKET' },
{ value: 'WHITE', label: 'WHITE' },
{ value: 'BLACK', label: 'BLACK' },
{ value: 'BASIC-CUSTOM', label: 'BASIC-CUSTOM' },
{ value: 'CUSTOM', label: 'CUSTOM' },
];
const ThemeDropdown: React.FC<{
selectedTheme: string;
setSelectedTheme: (theme: string) => void;
}> = ({ selectedTheme, setSelectedTheme }) => {
const themeOptions = [
{ value: 'IOMARKET', label: 'IOMARKET' },
{ value: 'WHITE', label: 'WHITE' },
{ value: 'BLACK', label: 'BLACK' },
{ value: 'BASIC-CUSTOM', label: 'BASIC-CUSTOM' },
{ value: 'CUSTOM', label: 'CUSTOM' },
];
return (
<div className="settings-option">
<p>Select Theme</p>
<select
value={selectedTheme}
onChange={(e) => {
const theme = e.target.value;
if (theme !== 'default') {
setSelectedTheme(theme);
localStorage.setItem('selectedTheme', theme);
}
}}
>
<option value="default">Select your style...</option>
{themeOptions.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
</div>
);
};
return (
<div className="settings-option">
<p>Select Theme</p>
<select
value={selectedTheme}
onChange={(e) => {
const theme = e.target.value;
if (theme !== 'default') {
setSelectedTheme(theme);
localStorage.setItem('selectedTheme', theme);
}
}}
>
<option value="default">Select your style...</option>
{themeOptions.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
</div>
);
};
export default ThemeDropdown;
export default ThemeDropdown;

View file

@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react';
import { applyTheme, applyCustomTheme } from './theme';
import { applyTheme } from './theme';
import { exportSettings, importSettings } from './settingUtils'; // Import utility functions
import { getAllLocalStorageItems } from '../../backend/GetLocalStorage';
import ColorSetting from './ColorSettings';
@ -14,7 +14,6 @@ import {
changeData,
createAccount,
deleteAccount,
getData,
} from '../../backend/database';
import ThemeDropdown from './DropDownTheme';
@ -35,12 +34,6 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
return false; // Default to false if item is null or empty
};
interface SettingsProps {
closeSettings: () => void;
accountName: string;
handleLogout: () => void; // Add this line to accept handleLogout as a prop
}
// Active section
const [activeSection, setActiveSection] = useState(() => localStorage.getItem('activeSection') || 'general');
@ -65,7 +58,6 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
const [newName, setNewName] = useState(() => localStorage.getItem('newName') || '');
const [newEmail, setNewEmail] = useState(() => localStorage.getItem('newEmail') || '');
const [newPassword, setNewPassword] = useState(() => localStorage.getItem('newPassword') || '');
const [currentPassword, setCurrentPassword] = useState('');
// Measurement setting
const [preferredMeasurement, setPreferredMeasurement] = useState(() => localStorage.getItem('preferredMeasurement') || 'Metric');
@ -91,7 +83,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
const [inputBorderColor, setInputBorderColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--input-border-color').trim());
const [fontFamily, setFontFamily] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--font-family').trim());
const [fontSize, setFontSize] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--font-size').trim());
const [burgerMenu, setBurgerMenu] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--burger-menu-background-color').trim());
const [burgerMenu] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--burger-menu-background-color').trim());
const [burgerMenuBackgroundColor, setBurgerMenuBackgroundColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--burger-menu-background-color').trim());
const [faqBackgroundColor, setFaqBackgroundColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--faq-background-color').trim());
const [faqHeadingColor, setFaqHeadingColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--faq-heading-color').trim());
@ -122,7 +114,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
const [openai, setOpenai] = useState(localStorage.getItem('openai') || "");
const [anthropic, setAnthropic] = useState(localStorage.getItem('anthropic') || "");
const [google, setGoogle] = useState(localStorage.getItem('google') || "");
const [myBoolean, setMyBoolean] = useState<boolean | any>(() => getItemFromLocalStorage('myBoolean'));
const [myBoolean, setMyBoolean] = useState<boolean>(() => getItemFromLocalStorage('myBoolean'));
const settings = {
userPreferences: {
@ -344,9 +336,9 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
// Function to handle updating all credentials
const handleUpdateCredentials = async () => {
var useName = localStorage.getItem("accountName")
var useEmail = localStorage.getItem("accountEmail")
var usePassword = localStorage.getItem("accountPassword")
let useName = localStorage.getItem("accountName")
let useEmail = localStorage.getItem("accountEmail")
let usePassword = localStorage.getItem("accountPassword")
if (useName && useEmail && usePassword) {
await deleteAccount(useName, usePassword)
@ -372,8 +364,8 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
// Function to handle account deletion
const handleDeleteAccount = async () => {
var useName = localStorage.getItem("accountName")
var usePassword = localStorage.getItem("accountPassword")
const useName = localStorage.getItem("accountName")
const usePassword = localStorage.getItem("accountPassword")
if (useName && usePassword) {
const success = await deleteAccount(useName, usePassword);
if (success) {

View file

@ -2,14 +2,14 @@
// Method to export localStorage to a JSON object
export function exportSettings(): string {
const settings: { [key: string]: any } = {};
const settings: { [key: string]: string } = {};
// Loop through all keys in localStorage and add them to the settings object
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (key) {
if (key !== "accountName" && key !== "accountPassword" && key !== "accountEmail") {
settings[key] = localStorage.getItem(key);
settings[key] = localStorage.getItem(key) || "";
}
}
}

View file

@ -41,13 +41,10 @@ const LandingPage: React.FC = () => {
}
};
const [selectedTheme, setSelectedTheme] = useState<string>('');
// Apply theme based on selectedTheme and color settings
useEffect(() => {
const savedTheme = localStorage.getItem('selectedTheme');
if (savedTheme) {
setSelectedTheme(savedTheme);
switch (savedTheme) {
case 'IOMARKET':
applyIOMarketTheme();
@ -107,4 +104,3 @@ const LandingPage: React.FC = () => {
};
export default LandingPage;