Database first tries

This commit is contained in:
sageTheDM 2024-10-09 08:11:40 +02:00
parent 9c8bc39b9d
commit e0e711f1a9
6 changed files with 100 additions and 117 deletions

View file

@ -1,62 +1,24 @@
import React from 'react'; import React from 'react';
const Credits: React.FC = () => { const Credits: React.FC = () => (
return ( <div className="credits-container">
<div className="credits-container"> <section id="credits" className="credits-section">
<section id="credits" className="credits-section"> <h1 className="title">Credits</h1>
<h1 className="title">Credits</h1> <h2 className="subtitle">Icons</h2>
<p className="paragraph">This project utilizes the following icon resources:</p>
<CreditLink href="https://fontawesome.com/v4/license/" label="fontawesome" />
<h2 className="subtitle">Fonts</h2>
<p className="paragraph">The fonts used in this project are provided by:</p>
<CreditLink href="https://github.com/itfoundry/Poppins" label="Poppins" />
<CreditLink href="https://openfontlicense.org" label="Inconsolata, Merriweather, Noto Sans, Noto Serif, Playfair Display, Bangers, Caveat, Frederika the Great, Sofadi One, Zilla Slab Highlight" />
<CreditLink href="http://www.apache.org/licenses/LICENSE-2.0" label="Roboto, Rock Salt" />
<CreditLink href="https://ubuntu.com/legal/font-licence" label="Ubuntu" />
</section>
</div>
);
<h2 className="subtitle">Icons</h2> const CreditLink = ({ href, label }: { href: string; label: string }) => (
<p className="paragraph"> <a href={href} className="credit-btn" target="_blank" rel="noopener noreferrer">{label}</a>
This project utilizes the following icon resources: );
</p>
<a
href="https://fontawesome.com/v4/license/"
className="credit-btn"
target="_blank"
rel="noopener noreferrer"
>
fontawesome
</a>
<h2 className="subtitle">Fonts</h2>
<p className="paragraph">
The fonts used in this project are provided by:
</p>
<a
href="https://github.com/itfoundry/Poppins"
className="credit-btn"
target="_blank"
rel="noopener noreferrer"
>
Poppins
</a>
<a
href="https://openfontlicense.org"
className="credit-btn"
target="_blank"
rel="noopener noreferrer"
>
Inconsolata, Merriweather, Noto Sans, Noto Serif, Playfair Display, Bangers, Caveat, Frederika the Great, Sofadi One, Zilla Slab Highlight
</a>
<a
href="http://www.apache.org/licenses/LICENSE-2.0"
className="credit-btn"
target="_blank"
rel="noopener noreferrer"
>
Roboto, Rock Salt
</a>
<a
href="https://ubuntu.com/legal/font-licence"
className="credit-btn"
target="_blank"
rel="noopener noreferrer"
>
Ubuntu
</a>
</section>
</div>
);
};
export default Credits; export default Credits;

View file

@ -20,13 +20,16 @@ const Header: React.FC<HeaderProps> = ({
const dropdownRef = useRef<HTMLDivElement | null>(null); const dropdownRef = useRef<HTMLDivElement | null>(null);
const toggleRef = useRef<HTMLDivElement | null>(null); const toggleRef = useRef<HTMLDivElement | null>(null);
// Pages that will be displayed in the menu
const pages: ('AI' | 'FAQ' | 'Documentation' | 'Credits')[] = ['AI', 'FAQ', 'Documentation', 'Credits'];
// Toggle menu state // Toggle menu state
const toggleMenu = () => { const toggleMenu = () => {
setMenuOpen((prevMenuOpen) => !prevMenuOpen); setMenuOpen((prevMenuOpen) => !prevMenuOpen);
}; };
// Handle button click // Handle button click
const buttonClicked = (page: "AI" | "Documentation" | "FAQ" | "Credits") => { const handleViewChange = (page: 'AI' | 'FAQ' | 'Documentation' | 'Credits') => {
onViewChange(page); onViewChange(page);
setMenuOpen(false); // Close the menu when a button is clicked setMenuOpen(false); // Close the menu when a button is clicked
}; };
@ -35,9 +38,9 @@ const Header: React.FC<HeaderProps> = ({
useEffect(() => { useEffect(() => {
const handleClickOutside = (event: MouseEvent) => { const handleClickOutside = (event: MouseEvent) => {
if ( if (
dropdownRef.current && dropdownRef.current &&
!dropdownRef.current.contains(event.target as Node) && !dropdownRef.current.contains(event.target as Node) &&
toggleRef.current && toggleRef.current &&
!toggleRef.current.contains(event.target as Node) !toggleRef.current.contains(event.target as Node)
) { ) {
setMenuOpen(false); setMenuOpen(false);
@ -72,10 +75,11 @@ const Header: React.FC<HeaderProps> = ({
</button> </button>
)} )}
<nav ref={dropdownRef} className={`nav-links ${menuOpen ? "active" : ""}`}> <nav ref={dropdownRef} className={`nav-links ${menuOpen ? "active" : ""}`}>
<button onClick={() => buttonClicked("AI")} className="nav-btn">Chat</button> {pages.map(page => (
<button onClick={() => buttonClicked("FAQ")} className="nav-btn">FAQ</button> <button key={page} onClick={() => handleViewChange(page)} className="nav-btn">
<button onClick={() => buttonClicked("Documentation")} className="nav-btn">Documentation</button> {page}
<button onClick={() => buttonClicked("Credits")} className="nav-btn">Credits</button> </button>
))}
</nav> </nav>
<div ref={toggleRef} className={`hamburger ${menuOpen ? "open" : ""}`} onClick={toggleMenu}> <div ref={toggleRef} className={`hamburger ${menuOpen ? "open" : ""}`} onClick={toggleMenu}>
<span></span> <span></span>

View file

@ -1,5 +1,5 @@
import React, { useState, ForwardedRef, useEffect } from 'react'; import React, { useState, ForwardedRef, useEffect } from 'react';
import "../styles/variables.css" import "../styles/variables.css";
interface InputProps { interface InputProps {
message: string; message: string;
@ -13,33 +13,36 @@ 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(''); const [inputValue, setInputValue] = useState('');
// Sync the inputValue state with the message prop
useEffect(() => { useEffect(() => {
setInputValue(message); setInputValue(message);
}, [message]); }, [message]);
// Handle the input change
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value); setInputValue(e.target.value);
}; };
// Handle 'Enter' key press
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => { const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (!inputDisabled) { if (!inputDisabled && event.key === 'Enter') {
if (event.key === 'Enter') { onSendClick(inputValue, false); // Send the message on Enter
onSendClick(inputValue, false); // Call the function passed via props setInputValue(''); // Clear the input after submission
setInputValue(''); // Optionally clear input after submission event.preventDefault(); // Prevent the default Enter action
event.preventDefault(); // Prevent default action (e.g., form submission)
}
} }
}; };
// Handle the Send button click
const handleSendClick = () => { const handleSendClick = () => {
if (inputValue.trim() !== "") { if (inputValue.trim() !== "") {
onSendClick(inputValue, false); // Send message to parent component onSendClick(inputValue, false); // Send message
setInputValue(''); // Clear input after sending setInputValue(''); // Clear input after sending
} }
}; };
return ( return (
<div className="input" id="inputForm" ref={ref}> <div className="input" id="inputForm" ref={ref}>
{/* Input field for typing messages */}
<input <input
type="text" type="text"
name="user_message" name="user_message"
@ -47,13 +50,22 @@ const InputFrontend = React.forwardRef<HTMLDivElement, InputProps>(
value={inputValue} value={inputValue}
onChange={handleInputChange} onChange={handleInputChange}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
className='textInputField' className="textInputField"
disabled={inputDisabled} // Disable when inputDisabled is true
/> />
<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> {/* Send button */}
<button type="button" onClick={handleSendClick} disabled={inputDisabled}>
<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>
{/* Microphone button */}
<button className={`microphone-button ${isRecording ? "red" : "var(--input-button-color)"}`} type="button" onClick={onMicClick}> <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> </button>
</div> </div>
); );

View file

@ -123,50 +123,39 @@ const ModelSection: React.FC = () => {
useEffect(() => { useEffect(() => {
if (typeof localStorage !== 'undefined') { if (typeof localStorage !== 'undefined') {
const defaultValues = {
setIsOpenSourceMode(localStorage.getItem("openSourceMode")) selectedModelDropdown: 'Offline Fast',
const temp = localStorage.getItem("activeSelectedAIFunction") || "" activeSelectedAIFunction: 'Code',
setActiveSelectedAIFunction(temp) model: 'starcoder2',
if (!localStorage.getItem('selectedModelDropdown')) { radioSelection: 'None',
localStorage.setItem("selectedModelDropdown", "Offline Fast") type: 'local',
} };
if (!localStorage.getItem("activeSelectedAIFunction")) { Object.entries(defaultValues).forEach(([key, value]) => {
setActiveSelectedAIFunction('Code') if (!localStorage.getItem(key)) {
localStorage.setItem('activeSelectedAIFunction', 'Code') localStorage.setItem(key, value);
} }
});
if (!localStorage.getItem("model")) {
localStorage.setItem("model", 'starcoder2') setIsOpenSourceMode(localStorage.getItem("openSourceMode"));
} setActiveSelectedAIFunction(localStorage.getItem("activeSelectedAIFunction") || '');
setRadioSelection(localStorage.getItem("radioSelection") || '');
if (!localStorage.getItem("radioSelection")) { setSelectedModelDropdown(localStorage.getItem('selectedModelDropdown') || '');
localStorage.setItem("radioSelection", 'None')
}
if (!localStorage.getItem("type")) {
localStorage.setItem("type", 'local')
}
const handleStorageChange = () => { const handleStorageChange = () => {
setSelectedModelDropdown(localStorage.getItem('selectedModelDropdown') || ''); setSelectedModelDropdown(localStorage.getItem('selectedModelDropdown') || '');
}; };
// Update immediately when localStorage changes // Update immediately when localStorage changes
if (typeof window !== 'undefined') { window.addEventListener('storage', handleStorageChange);
window.addEventListener('storage', handleStorageChange);
}
setRadioSelection(localStorage.getItem('radioSelection') || '');
setSelectedModelDropdown(localStorage.getItem('selectedModelDropdown') || '');
// Cleanup listener on component unmount // Cleanup listener on component unmount
return () => { return () => {
if (typeof window !== 'undefined') { window.removeEventListener('storage', handleStorageChange);
window.removeEventListener('storage', handleStorageChange);
}
}; };
} }
}, []); // Dependency array can remain empty if you only want this to run on mount }, []);
useEffect(() => { useEffect(() => {
if (typeof localStorage !== 'undefined') { if (typeof localStorage !== 'undefined') {
@ -271,7 +260,6 @@ const ModelSection: React.FC = () => {
))} ))}
</select> </select>
</div> </div>
{/* Model Grid with Cards */} {/* Model Grid with Cards */}
<div className="grid"> <div className="grid">
{selectedAIFunction.map( {selectedAIFunction.map(

View file

@ -15,6 +15,7 @@ import {
changeSettings, changeSettings,
createAccount, createAccount,
deleteAccount, deleteAccount,
getSettings
} from '../../backend/database'; } from '../../backend/database';
import ThemeDropdown from './DropDownTheme'; import ThemeDropdown from './DropDownTheme';
@ -298,6 +299,11 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
}; };
useEffect(() => { useEffect(() => {
let useName = localStorage.getItem("accountName")
let usePassword = localStorage.getItem("accountPassword")
if (useName && usePassword) {
importDatabase(useName, usePassword)
}
const savedTheme = localStorage.getItem('selectedTheme'); const savedTheme = localStorage.getItem('selectedTheme');
if (savedTheme) { if (savedTheme) {
setSelectedTheme(savedTheme); setSelectedTheme(savedTheme);
@ -305,6 +311,10 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
} }
}, []); // Runs only once when the component mounts }, []); // Runs only once when the component mounts
const importDatabase = async (useName : string, usePassword : string) => {
const databaseSettings = await getSettings(useName, usePassword)
importSettings(databaseSettings)
}
// Effect hooks to update localStorage whenever any state changes // Effect hooks to update localStorage whenever any state changes
useEffect(() => { useEffect(() => {
// Flatten nested objects // Flatten nested objects
@ -355,7 +365,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
} }
if (await createAccount(useName, useEmail, usePassword)) { if (await createAccount(useName, useEmail, usePassword)) {
if (await changeSettings(useName, usePassword, settings)) { if (await changeSettings(useName, usePassword, handleExport)) {
localStorage.setItem("currentName", useName) localStorage.setItem("currentName", useName)
localStorage.setItem("currentPassword", usePassword) localStorage.setItem("currentPassword", usePassword)
localStorage.setItem("currentEmail", useEmail) localStorage.setItem("currentEmail", useEmail)
@ -714,7 +724,6 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
const handleExport = () => { const handleExport = () => {
const settingsData = exportSettings(); const settingsData = exportSettings();
// Create a blob and download the exported settings // Create a blob and download the exported settings
const blob = new Blob([settingsData], { type: 'application/json' }); const blob = new Blob([settingsData], { type: 'application/json' });
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob);
@ -748,7 +757,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
<div className="settings-main"> <div className="settings-main">
{/* Dropdown for selections in responsive mode */} {/* Dropdown for selections in responsive mode */}
<div className="settings-option dropdown"> <div className="settings-option dropdown">
<div className="dropdown-header"><h1>Select a Setting</h1></div> <div className="dropdown-header"><h2>Select a Setting</h2></div>
<select onChange={(e) => setActiveSection(e.target.value)} value={activeSection}> <select onChange={(e) => setActiveSection(e.target.value)} value={activeSection}>
<option value="general">General</option> <option value="general">General</option>
<option value="privacy">Privacy</option> <option value="privacy">Privacy</option>
@ -763,10 +772,13 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
{renderSettingsContent()} {renderSettingsContent()}
<button className="close-popup" onClick={closeSettings}>Close</button> <button className="close-popup" onClick={closeSettings}>Close</button>
<button className="apply" onClick={async () => { <button className="apply" onClick={async () => {
// Your existing logic for applying settings getAllLocalStorageItems();
closeSettings();
window.location.reload();
}}> }}>
Apply Apply
</button> </button>
</div> </div>
</div> </div>
</div> </div>

View file

@ -152,6 +152,11 @@
top: 10px; top: 10px;
display: block; display: block;
} }
.slider-option{
width: fit-content;
margin: 10px 10px 0 0;
}
} }
/* Responsive adjustments for the settings */ /* Responsive adjustments for the settings */