Merge pull request 'Split the pages up' (#2) from sageTheDm/interstellar_ai:main into main

Reviewed-on: https://interstellardevelopment.org/code/code/React-Group/interstellar_ai/pulls/2
This commit is contained in:
Patrick 2024-09-18 13:19:00 +02:00
commit 739e988e87
21 changed files with 723 additions and 639 deletions

43
app/Conversation.tsx Normal file
View file

@ -0,0 +1,43 @@
import React, { ForwardedRef } from 'react';
interface ConversationProps {
messages: string[];
onResendClick: () => void;
onEditClick: () => void;
onCopyClick: () => void;
}
const Conversation = React.forwardRef<HTMLDivElement, ConversationProps>(
({ messages, onResendClick, onEditClick, onCopyClick }, ref: ForwardedRef<HTMLDivElement>) => {
return (
<div className="output">
<div className="conversation resize" id="conversation" ref={ref}>
{messages.map((message, index) => {
const isUserMessage = message.startsWith('User:');
return (
<div
key={index}
className={isUserMessage ? 'user-message' : 'ai-message'}
>
{message}
</div>
);
})}
<div className="button-container">
<button type="button" onClick={onResendClick}>
<img src="/img/resend.svg" alt="resend" />
</button>
<button type="button" onClick={onEditClick}>
<img src="/img/edit.svg" alt="edit" />
</button>
<button type="button" onClick={onCopyClick}>
<img src="/img/copy.svg" alt="copy" />
</button>
</div>
</div>
</div>
);
}
);
export default Conversation;

36
app/Header.tsx Normal file
View file

@ -0,0 +1,36 @@
// Header.tsx
import React from 'react';
interface HeaderProps {
toggleDivs: () => void;
showDivs: boolean;
}
const Header: React.FC<HeaderProps> = ({ toggleDivs, showDivs }) => {
return (
<header>
<div className="header-menu">
<ul>
<li>
<a href="/">
<img src="/img/logo.png" alt="logo" />
</a>
</li>
<li>
<a href="/documentation">Documentation</a>
</li>
<li>
<a href="/faq">FAQ</a>
</li>
<li>
<button onClick={toggleDivs}>
{showDivs ? "Hide History and Models" : "Show History and Models"}
</button>
</li>
</ul>
</div>
</header>
);
};
export default Header;

20
app/History.tsx Normal file
View file

@ -0,0 +1,20 @@
import React from 'react';
const History: React.FC = () => {
return (
<div className="history-background">
<div className="history">
<ul>
{/* Populate with history items */}
{Array.from({ length: 20 }, (_, index) => (
<li key={index}>
<a href="#">history{index + 1}</a>
</li>
))}
</ul>
</div>
</div>
);
};
export default History;

21
app/InputForm.tsx Normal file
View file

@ -0,0 +1,21 @@
import React from 'react';
const InputForm: React.FC = () => {
return (
<form className="input" method="POST" action="" id="inputForm">
<input
type="text"
name="user_message"
placeholder="Type your message here..."
/>
<button type="submit" name="option" value="chat">
<img src="/img/send.svg" alt="send" />
</button>
<button type="submit" name="option" value="voice">
<img src="/img/microphone.svg" alt="microphone" />
</button>
</form>
);
};
export default InputForm;

88
app/Models.tsx Normal file
View file

@ -0,0 +1,88 @@
// Models.tsx
import React from 'react';
const Models: React.FC = () => {
return (
<div className="model-background">
<div className="models">
<div className="titel">
<h1>Different AI models</h1>
</div>
<form action="">
<div className="grid">
<button className="code-model model-box">
<div className="overlay">
<h3>Code</h3>
<img src="/img/wifi.svg" alt="Wi-Fi" />
</div>
</button>
<button className="math-model model-box">
<div className="overlay">
<h3>Math</h3>
<img src="/img/nowifi.svg" alt="No Wi-Fi" />
</div>
</button>
<button className="language-model model-box">
<div className="overlay">
<h3>Language</h3>
</div>
</button>
<button className="default-model model-box">
<div className="overlay">
<h3>Default</h3>
</div>
</button>
{/* Example Models */}
<button className="default-model model-box">
<div className="overlay">
<h3>Default</h3>
</div>
</button>
<button className="default-model model-box">
<div className="overlay">
<h3>Default</h3>
</div>
</button>
<button className="default-model model-box">
<div className="overlay">
<h3>Default</h3>
</div>
</button>
<button className="default-model model-box">
<div className="overlay">
<h3>Default</h3>
</div>
</button>
<button className="default-model model-box">
<div className="overlay">
<h3>Default</h3>
</div>
</button>
<button className="default-model model-box">
<div className="overlay">
<h3>Default</h3>
</div>
</button>
<button className="default-model model-box">
<div className="overlay">
<h3>Default</h3>
</div>
</button>
<button className="default-model model-box">
<div className="overlay">
<h3>Default</h3>
</div>
</button>
<button className="default-model model-box">
<div className="overlay">
<h3>Default</h3>
</div>
</button>
</div>
</form>
</div>
</div>
);
};
export default Models;

View file

@ -10,6 +10,10 @@ export default function RootLayout({
}) { }) {
return ( return (
<html lang="en"> <html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AI Assistant</title>
</head>
<body>{children}</body> <body>{children}</body>
</html> </html>
) )

View file

@ -1,14 +1,18 @@
"use client"; // Add this at the top to mark this file as a Client Component "use client"
// LandingPage.tsx
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import './styles.css'; // Make sure this matches your CSS file path import Header from './Header';
import History from './History';
import Models from './Models';
import Conversation from './Conversation';
import InputForm from './InputForm';
import './styles/master.css';
const App = () => { const LandingPage: React.FC = () => {
const [showDivs, setShowDivs] = useState(true); // Default to true to show divs on load const [showDivs, setShowDivs] = useState(true);
const conversationRef = useRef<HTMLDivElement>(null); const conversationRef = useRef<HTMLDivElement>(null);
useEffect(() => { useEffect(() => {
// Scroll to bottom when the component mounts or updates
const scrollToBottom = () => { const scrollToBottom = () => {
const conversation = conversationRef.current; const conversation = conversationRef.current;
if (conversation) { if (conversation) {
@ -16,11 +20,9 @@ const App = () => {
} }
}; };
scrollToBottom(); // Scroll to the bottom when the page loads scrollToBottom();
// Use MutationObserver to efficiently observe changes in the conversation element
const observer = new MutationObserver(scrollToBottom); const observer = new MutationObserver(scrollToBottom);
if (conversationRef.current) { if (conversationRef.current) {
observer.observe(conversationRef.current, { observer.observe(conversationRef.current, {
childList: true, childList: true,
@ -39,119 +41,49 @@ const App = () => {
setShowDivs(prevState => !prevState); setShowDivs(prevState => !prevState);
}; };
const messages = [
'User: Hello!',
'AI: Hi there!',
'User: How are you?',
'AI: Im good, thank you!'
];
const handleResendClick = () => {
console.log('Resend button clicked');
// Handle resend action
};
const handleEditClick = () => {
console.log('Edit button clicked');
// Handle edit action
};
const handleCopyClick = () => {
console.log('Copy button clicked');
// Handle copy action
};
return ( return (
<div className="App"> <div className="App">
<header> <Header toggleDivs={toggleDivs} showDivs={showDivs} />
<div className="header-menu">
<ul>
<li>
<a href="/">
<img src="/img/logo.png" alt="logo" />
</a>
</li>
<li>
<a href="/documentation">Documentation</a>
</li>
<li>
<a href="/faq">FAQ</a>
</li>
<li>
<button onClick={toggleDivs}>{showDivs ? "Hide Divs" : "Show Divs"}</button>
</li>
</ul>
</div>
</header>
<div className="container"> <div className="container">
{showDivs && ( <div className={`left-panel ${showDivs ? '' : 'hidden'}`}>
<div className="history-background"> <History />
<div className="history"> <Models />
<ul>
<li>
<a href="#">history1</a>
</li>
{/* Add more history items here */}
</ul>
</div> </div>
</div> <div className={`conversation-container ${showDivs ? 'expanded' : 'collapsed'}`}>
)} <Conversation
ref={conversationRef}
{showDivs && ( messages={messages}
<div className="model-background"> onResendClick={handleResendClick}
<div className="models"> onEditClick={handleEditClick}
<div className="titel"> onCopyClick={handleCopyClick}
<h1>Different AI models</h1>
</div>
<form action="">
<div className="grid">
<button className="code-model model-box">
<div className="overlay">
<h3>Code</h3>
<img src="/img/wifi.svg" alt="Wi-Fi" />
</div>
</button>
<button className="math-model model-box">
<div className="overlay">
<h3>Math</h3>
<img src="/img/nowifi.svg" alt="No Wi-Fi" />
</div>
</button>
<button className="language-model model-box">
<div className="overlay">
<h3>Language</h3>
</div>
</button>
<button className="default-model model-box">
<div className="overlay">
<h3>Default</h3>
</div>
</button>
<button className="default-model model-box">
<div className="overlay">
<h3>Default</h3>
</div>
</button>
<button className="default-model model-box">
<div className="overlay">
<h3>Default</h3>
</div>
</button>
<button className="default-model model-box">
<div className="overlay">
<h3>Default</h3>
</div>
</button>
</div>
</form>
</div>
</div>
)}
<div className="output">
<div className="conversation resize" ref={conversationRef}>
{/* Render messages here */}
{/* Replace the following example with dynamic rendering */}
<div className="user-message">User: Example message</div>
<div className="ai-message">AI: Example response</div>
</div>
</div>
<form className="input" method="POST" action="" id="inputForm">
<input
type="text"
name="user_message"
placeholder="Type your message here..."
/> />
<button type="submit" name="option" value="chat"> <InputForm />
<img src="/img/send.svg" alt="send" /> </div>
</button>
<button type="submit" name="option" value="voice">
<img src="/img/microphone.svg" alt="microphone" />
</button>
</form>
</div> </div>
</div> </div>
); );
}; };
export default App; export default LandingPage;

View file

@ -1,524 +0,0 @@
:root {
--background-color: white;
--text-color: white;
--font-family: Arial, sans-serif;
--history-background-color: rgb(0, 0, 48);
--models-background-color: rgb(0, 0, 48);
--output-background-color: black;
/* Set the conversation background to black */
--user-message-color: rgb(0, 128, 255);
/* Blueish bubble for user */
--ai-message-color: rgb(100, 100, 255);
/* Lighter blue for AI */
--input-background-color: rgb(0, 0, 48);
--input-button-color: rgb(0, 128, 255);
--input-button-hover-color: rgb(0, 100, 200);
--scrollbar-track: rgb(91, 172, 253);
--scrollbar-thumb: rgb(0, 88, 176);
}
/* Global Reset */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
height: 100vh;
overflow: hidden;
/* Prevent scrolling */
}
/* Body Styling */
body {
margin-top: 2em;
display: flex;
justify-content: center;
align-items: center;
background-color: var(--background-color);
color: var(--text-color);
font-family: var(--font-family);
margin-bottom: 0.5em;
}
/* Header Styling */
header {
background-color: var(--background-color);
color: black;
width: 100%;
text-decoration: none;
position: fixed;
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);
}
header li {
display: inline-block;
margin: 0 15px;
}
header img {
height: 2em;
vertical-align: middle;
}
header a {
color: black;
text-decoration: none;
transition: color 0.3s;
}
header a:hover {
color: var(--input-button-color);
}
/* Container Grid Layout */
.container {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-rows: 3fr 1fr 1fr 1fr;
gap: 10px;
width: 90vw;
height: 95vh;
}
/* History Section */
.history-background {
grid-column: 1/2;
grid-row: 1/2;
height: 100%;
overflow: hidden;
background-color: var(--history-background-color);
padding: 1em;
border-radius: 2em;
}
.history {
height: 100%;
overflow-y: scroll;
padding-right: 10px;
}
.history ul {
list-style: none;
}
.history ul li {
padding: 10px 0;
border-bottom: 1px solid var(--text-color);
width: 100%;
}
.history ul li a {
display: block;
text-decoration: none;
color: white;
width: 100%;
padding: 5px;
}
.history ul li a:hover {
background-color: var(--input-button-hover-color);
}
/* Models Section */
.model-background {
grid-column: 1/2;
grid-row: 2/5;
overflow-y: auto;
background-color: var(--models-background-color);
border-radius: 2em;
padding: 1em;
height: 90%;
box-sizing: border-box;
overflow: hidden;
}
.models {
grid-column: 1/2;
grid-row: 2/5;
overflow-y: auto;
background-color: var(--models-background-color);
border-radius: 2em;
padding: 1em;
height: 100%;
box-sizing: border-box;
overflow: hidden;
overflow-y: scroll;
}
.models form {
padding-right: 10px;
padding-left: 10px;
display: flex;
align-items: center;
justify-content: center;
}
.models .titel {
padding-bottom: 1em;
display: flex;
justify-content: center;
align-items: center;
}
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1.5vh;
width: fit-content;
/* height: calc(100% - 2em); */
}
.grid h3 {
font-size: x-large;
}
.model-box {
display: flex;
align-items: center;
justify-content: center;
color: #fff;
border-radius: 5%;
overflow: hidden;
position: relative;
height: 18vh;
width: 18vh;
}
.overlay {
z-index: 900;
position: absolute;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
/* Dark overlay */
color: white;
display: flex;
justify-content: center;
align-items: center;
font-size: 300%;
transition: opacity 0.5s ease;
pointer-events: none;
opacity: 0;
font-size: xx-large;
}
.overlay img {
align-self: flex-end;
justify-self: end;
height: 3vh;
width: 3vh;
position: absolute;
right: 15px;
bottom: 15px;
}
.model-box:hover .overlay {
opacity: 1;
}
.code-model {
background-image: url(/img/code.jpg);
background-repeat: no-repeat;
background-size: cover;
}
.math-model {
background-image: url(/img/math.jpg);
background-color: white;
background-position: center;
background-repeat: no-repeat;
background-size: contain;
}
.language-model {
background-image: url(/img/language.jpg);
background-color: #72cce4;
background-repeat: no-repeat;
background-size: contain;
background-position: center;
}
.default-model {
background-image: url(/img/default.jpg);
background-repeat: no-repeat;
background-size: cover;
background-position: center;
}
/* Output Section */
.output {
grid-column: 2;
grid-row: 1 / 4;
border-radius: 2em;
background-color: var(--output-background-color);
padding: 1.5em;
display: flex;
flex-direction: column;
justify-content: flex-start;
font-size: 1.2em;
overflow-y: auto;
min-height: 75vh;
margin-bottom: 0;
width: 100%;
height: 100%;
}
/* Conversation */
#conversation {
display: flex;
flex-direction: column;
padding: 10px;
overflow-y: auto;
max-height: 80vh;
background-color: var(--output-background-color);
/* Black background */
border-radius: 10px;
scroll-behavior: smooth;
/* Optional: Smooth scrolling */
}
/* Resizable Conversation */
.resize {
resize: both;
overflow: auto;
/* Allow resizing both horizontally and vertically */
min-width: 300px;
min-height: 300px;
/* Minimum dimensions to prevent it from becoming too small */
}
/* User and AI Messages */
.user-message,
.ai-message {
margin: 10px 0;
padding: 10px 15px;
border-radius: 15px;
max-width: 60%;
width: fit-content;
/* Adjusts width to fit the content */
word-wrap: break-word;
display: block;
/* Changed from inline-block to block */
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
}
/* Align user message to the right */
.user-message {
background-color: var(--user-message-color);
color: var(--text-color);
border-bottom-right-radius: 0;
margin-left: auto;
text-align: right;
/* Align text to the right */
}
/* Align AI message to the left */
.ai-message {
background-color: var(--ai-message-color);
color: var(--text-color);
border-bottom-left-radius: 0;
margin-right: auto;
text-align: left;
/* Align text to the left */
}
/* Output Form Buttons */
.output form {
display: flex;
justify-content: flex-start;
gap: 10px;
}
.output form button {
background-color: transparent;
color: white;
border: none;
padding: 0;
margin: 5px;
cursor: pointer;
transition: transform 0.2s ease-in-out;
}
.output form button:hover {
transform: scale(1.2);
}
.output form button img {
height: 1.8em;
}
/* Input Section */
.input {
grid-column: 2/3;
grid-row: 4/5;
border-radius: 20px;
background-color: var(--input-background-color);
padding: 1.5vh;
display: flex;
justify-content: space-between;
align-items: center;
height: auto;
/* margin-top: -9em; */
gap: 10px;
height: 10vh;
}
.input input {
flex-grow: 1;
padding: 5px;
font-size: 1.2em;
border-radius: 8px;
border: 2px solid var(--input-button-color);
outline: none;
margin-right: 10px;
background-color: rgba(255, 255, 255, 0.9);
color: #333;
transition: border-color 0.3s ease-in-out;
height: 7vh;
}
.input input:focus {
border-color: var(--input-button-hover-color);
}
.input button {
padding: 1em;
margin: 5px;
background-color: var(--input-button-color);
color: white;
border: none;
border-radius: 50%;
font-size: 1.5em;
cursor: pointer;
height: 50px;
width: 50px;
display: flex;
justify-content: center;
align-items: center;
transition: background-color 0.3s ease;
position: relative;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}
.input button img {
height: 1em;
}
.input button:hover {
background-color: var(--input-button-hover-color);
box-shadow: 0 6px 15px rgba(0, 0, 0, 0.2);
}
/* FAQ Section */
#faq {
max-width: 800px;
width: 90%;
margin-top: 50px;
padding: 20px;
background-color: #222;
border-radius: 10px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}
#faq h2 {
text-align: center;
color: #00ccff;
font-size: 2em;
margin-bottom: 20px;
}
.faq-item {
margin-bottom: 20px;
padding: 10px;
border-radius: 5px;
background-color: #333;
}
.faq-item h3 {
color: #00ccff;
margin-bottom: 10px;
font-size: 1.5em;
}
.faq-item p {
color: #ddd;
font-size: 1.1em;
line-height: 1.5;
}
.faq-item:hover {
background-color: #444;
transition: background-color 0.3s;
}
::-webkit-scrollbar {
width: 7px;
}
::-webkit-scrollbar-track {
background-color: var(--scrollbar-track);
border-radius: 5px;
overflow: hidden;
margin-left: 10px;
padding-left: 15px;
}
::-webkit-scrollbar-thumb {
background-color: var(--scrollbar-thumb);
border-radius: 5px;
}
@media (max-width: 1400px) {
.grid {
grid-template-columns: 1fr;
}
.model-box {
width: 15vw;
aspect-ratio: 1/1;
}
}
/* Responsive Adjustments */
@media (max-width: 768px) {
.container {
grid-template-columns: 1fr;
grid-template-rows: auto;
width: 95vw;
}
.history,
.models {
display: none;
/* Hide history and models */
}
.output {
grid-column: 1;
grid-row: 1 / span 2;
}
.input {
grid-column: 1;
grid-row: 3;
/* margin-top: -4em; */
}
.input button {
height: 40px;
width: 40px;
}
.output form button img {
height: 1.5em;
}
}

34
app/styles/container.css Normal file
View file

@ -0,0 +1,34 @@
/* container.css */
.container {
display: flex;
height: 100vh;
width: 100vw;
overflow: hidden;
position: relative; /* Ensure relative positioning for proper transitions */
}
.left-panel {
width: 30vw; /* Adjust as needed */
transition: width 0.3s ease, visibility 0.3s ease; /* Transition for width, opacity, and visibility */
}
.left-panel.hidden {
opacity: 0; /* Fade out when hidden */
width: 0; /* Set width to 0 when hidden */
visibility: hidden; /* Hide the panel while keeping the space occupied */
margin-right: -30vw;
}
.conversation-container {
flex: 1;
transition: width 0.3s ease, visibility 0.3s ease; /* Transition for margin-left */
}
/* Adjust margin-left when panel is shown or hidden */
.conversation-container.expanded {
margin-left: 0;
}
.conversation-container.collapsed {
margin-left: 30vw; /* Same as the width of the left-panel */
}

0
app/styles/faq.css Normal file
View file

18
app/styles/global.css Normal file
View file

@ -0,0 +1,18 @@
html,
body {
height: 100vh;
overflow: hidden;
position: relative;
top: 1vh;
}
body {
margin-top: 2em;
display: flex;
justify-content: center;
align-items: center;
background-color: var(--background-color);
color: var(--text-color);
font-family: var(--font-family);
margin-bottom: 0.5em;
}

38
app/styles/header.css Normal file
View file

@ -0,0 +1,38 @@
header {
background-color: var(--background-color);
color: black;
width: 100%;
text-decoration: none;
position: fixed;
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);
}
header li {
display: inline-block;
margin: 0 15px;
}
header img {
height: 2em;
vertical-align: middle;
}
header a,
header li button {
color: black;
text-decoration: none;
transition: color 0.3s;
border: none;
background-color: transparent;
font-size: 1em;
}
header a:hover,
header li button:hover {
color: var(--input-button-color);
}

38
app/styles/history.css Normal file
View file

@ -0,0 +1,38 @@
.history-background {
grid-column: 1/2;
grid-row: 1/2;
height: 40vh;
overflow: hidden;
background-color: var(--history-background-color);
padding: 1em;
border-radius: 2em;
margin: 1em;
}
.history {
height: 100%;
overflow-y: scroll;
padding-right: 10px;
}
.history ul {
list-style: none;
}
.history ul li {
padding: 10px 0;
border-bottom: 1px solid var(--text-color);
width: 100%;
}
.history ul li a {
display: block;
text-decoration: none;
color: white;
width: 100%;
padding: 5px;
}
.history ul li a:hover {
background-color: var(--input-button-hover-color);
}

61
app/styles/input.css Normal file
View file

@ -0,0 +1,61 @@
/* Input Section */
.input {
grid-column: 2/3;
grid-row: 4/5;
border-radius: 20px;
background-color: var(--input-background-color);
padding: 1em;
margin: 1em;
display: flex;
justify-content: space-between;
align-items: center;
height: auto;
gap: 10px;
height: 10vh;
}
.input input {
flex-grow: 1;
padding: 5px;
font-size: 1.2em;
border-radius: 8px;
border: 2px solid var(--input-button-color);
outline: none;
margin-right: 10px;
background-color: rgba(255, 255, 255, 0.9);
color: #333;
transition: border-color 0.3s ease-in-out;
height: 7vh;
}
.input input:focus {
border-color: var(--input-button-hover-color);
}
.input button {
padding: 1em;
margin: 5px;
background-color: var(--input-button-color);
color: white;
border: none;
border-radius: 50%;
font-size: 1.5em;
cursor: pointer;
height: 50px;
width: 50px;
display: flex;
justify-content: center;
align-items: center;
transition: background-color 0.3s ease;
position: relative;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}
.input button img {
height: 1em;
}
.input button:hover {
background-color: var(--input-button-hover-color);
box-shadow: 0 6px 15px rgba(0, 0, 0, 0.2);
}

13
app/styles/master.css Normal file
View file

@ -0,0 +1,13 @@
/* Importing all the split CSS files */
@import './variables.css';
@import './reset.css';
@import './global.css';
@import './header.css';
@import './container.css';
@import './history.css';
@import './models.css';
@import './output.css';
@import './user-ai-messages.css';
@import './input.css';
@import './faq.css';
@import './scrollbar.css';

124
app/styles/models.css Normal file
View file

@ -0,0 +1,124 @@
.model-background {
grid-column: 1/2;
grid-row: 2/5;
overflow-y: auto;
background-color: var(--models-background-color);
border-radius: 2em;
padding: 1em;
margin: 1em;
height: 50vh;
box-sizing: border-box;
overflow: hidden;
}
.models {
grid-column: 1/2;
grid-row: 2/5;
overflow-y: auto;
background-color: var(--models-background-color);
border-radius: 2em;
padding: 1em;
height: 100%;
box-sizing: border-box;
overflow: hidden;
overflow-y: scroll;
}
.models form {
padding-right: 10px;
padding-left: 10px;
display: flex;
align-items: center;
justify-content: center;
}
.models .titel {
padding-bottom: 1em;
display: flex;
justify-content: center;
align-items: center;
}
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1.5vh;
width: fit-content;
}
.grid h3 {
font-size: x-large;
}
.model-box {
display: flex;
align-items: center;
justify-content: center;
color: #fff;
border-radius: 5%;
overflow: hidden;
position: relative;
height: 18vh;
width: 18vh;
}
.overlay {
z-index: 900;
position: absolute;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
color: white;
display: flex;
justify-content: center;
align-items: center;
font-size: 300%;
transition: opacity 0.5s ease;
pointer-events: none;
opacity: 0;
font-size: xx-large;
}
.overlay img {
align-self: flex-end;
justify-self: end;
height: 3vh;
width: 3vh;
position: absolute;
right: 15px;
bottom: 15px;
}
.model-box:hover .overlay {
opacity: 1;
}
.code-model {
background-image: url(/img/code.jpg);
background-repeat: no-repeat;
background-size: cover;
}
.math-model {
background-image: url(/img/math.jpg);
background-color: white;
background-position: center;
background-repeat: no-repeat;
background-size: contain;
}
.language-model {
background-image: url(/img/language.jpg);
background-color: #72cce4;
background-repeat: no-repeat;
background-size: contain;
background-position: center;
}
.default-model {
background-image: url(/img/default.jpg);
background-repeat: no-repeat;
background-size: cover;
background-position: center;
}

74
app/styles/output.css Normal file
View file

@ -0,0 +1,74 @@
/* Output Section */
.output {
grid-column: 2;
grid-row: 1 / 4;
border-radius: 2em;
background-color: var(--output-background-color);
padding: 1em;
margin: 1em;
display: flex;
flex-direction: column;
justify-content: flex-start;
font-size: 1.2em;
overflow-y: auto;
margin-bottom: 0;
width: 100% -2em;
height: 80vh;
margin-bottom: 1vh;
}
#conversation {
display: flex;
flex-direction: column;
padding: 10px;
overflow-y: auto;
max-height: 80vh;
background-color: var(--output-background-color);
border-radius: 10px;
scroll-behavior: smooth;
}
/* Message Bubbles */
.user-message, .ai-message {
padding: 10px;
border-radius: 10px;
margin: 5px 0;
max-width: 75%;
word-wrap: break-word;
}
.user-message {
background-color: var(--user-message-background-color);
align-self: flex-end;
color: var(--user-message-text-color);
}
.ai-message {
background-color: var(--ai-message-background-color);
align-self: flex-start;
color: var(--ai-message-text-color);
}
/* Button Container */
.button-container {
display: flex;
padding: 10px 0;
}
.button-container button {
background: none;
border: none;
cursor: pointer;
background-color: var(--button-background-color);
border-radius: 50%;
padding: 10px;
transition: background-color 0.3s ease;
}
.button-container button:hover {
background-color: var(--button-hover-background-color);
}
.button-container img {
height: 1.5em;
}

5
app/styles/reset.css Normal file
View file

@ -0,0 +1,5 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

17
app/styles/scrollbar.css Normal file
View file

@ -0,0 +1,17 @@
/* Scrollbar styling */
.scrollbar {
overflow-y: scroll;
}
.scrollbar::-webkit-scrollbar {
width: 8px;
}
.scrollbar::-webkit-scrollbar-thumb {
background-color: #ccc;
border-radius: 4px;
}
.scrollbar::-webkit-scrollbar-track {
background-color: #f1f1f1;
}

View file

@ -0,0 +1,27 @@
.user-message,
.ai-message {
margin: 10px 0;
padding: 10px 15px;
border-radius: 15px;
max-width: 60%;
width: fit-content;
word-wrap: break-word;
display: block;
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
}
.user-message {
background-color: var(--user-message-color);
color: var(--text-color);
border-bottom-right-radius: 0;
margin-left: auto;
text-align: right;
}
.ai-message {
background-color: var(--ai-message-color);
color: var(--text-color);
border-bottom-left-radius: 0;
margin-right: auto;
text-align: left;
}

15
app/styles/variables.css Normal file
View file

@ -0,0 +1,15 @@
:root {
--background-color: white;
--text-color: white;
--font-family: Arial, sans-serif;
--history-background-color: rgb(0, 0, 48);
--models-background-color: rgb(0, 0, 48);
--output-background-color: black;
--user-message-color: rgb(0, 128, 255);
--ai-message-color: rgb(100, 100, 255);
--input-background-color: rgb(0, 0, 48);
--input-button-color: rgb(0, 128, 255);
--input-button-hover-color: rgb(0, 100, 200);
--scrollbar-track: rgb(91, 172, 253);
--scrollbar-thumb: rgb(0, 88, 176);
}