From 48668f7f6e2cb251b2463116e8cf8ddf3bc177f5 Mon Sep 17 00:00:00 2001 From: Sage The DM <luca.burger@grischuni.net> Date: Wed, 18 Sep 2024 10:03:36 +0200 Subject: [PATCH 1/2] Split the pages up --- app/Conversation.tsx | 39 ++++++++++++ app/Header.tsx | 34 +++++++++++ app/History.tsx | 36 +++++++++++ app/InputForm.tsx | 22 +++++++ app/Models.tsx | 43 +++++++++++++ app/layout.tsx | 4 ++ app/page.tsx | 141 ++++++++----------------------------------- 7 files changed, 203 insertions(+), 116 deletions(-) create mode 100644 app/Conversation.tsx create mode 100644 app/Header.tsx create mode 100644 app/History.tsx create mode 100644 app/InputForm.tsx create mode 100644 app/Models.tsx diff --git a/app/Conversation.tsx b/app/Conversation.tsx new file mode 100644 index 0000000..1a37518 --- /dev/null +++ b/app/Conversation.tsx @@ -0,0 +1,39 @@ +// Conversation.tsx +import React, { ForwardedRef } from 'react'; + +interface ConversationProps { + messages: string[]; +} + +const Conversation = React.forwardRef<HTMLDivElement, ConversationProps>(({ messages }, 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> + ); + })} + <form method="POST" action="" id="buttonForm"> + <button type="button" name="option" value="chat"> + <img src="/img/resend.svg" alt="resend" /> + </button> + <button type="button" name="option" value="chat"> + <img src="/img/edit.svg" alt="edit" /> + </button> + <button type="button" name="option" value="answer"> + <img src="/img/copy.svg" alt="copy" /> + </button> + </form> + </div> + </div> + ); +}); + +export default Conversation; diff --git a/app/Header.tsx b/app/Header.tsx new file mode 100644 index 0000000..7ea87c9 --- /dev/null +++ b/app/Header.tsx @@ -0,0 +1,34 @@ +// 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 Divs" : "Show Divs"}</button> + </li> + </ul> + </div> + </header> + ); +}; + +export default Header; diff --git a/app/History.tsx b/app/History.tsx new file mode 100644 index 0000000..eb21840 --- /dev/null +++ b/app/History.tsx @@ -0,0 +1,36 @@ +// History.tsx +import React from 'react'; + +const History: React.FC = () => { + return ( + <div className="history-background"> + <div className="history"> + <ul> + {/* Populate with history items */} + <li><a href="#">history1</a></li> + <li><a href="#">history2</a></li> + <li><a href="#">history3</a></li> + <li><a href="#">history4</a></li> + <li><a href="#">history5</a></li> + <li><a href="#">history6</a></li> + <li><a href="#">history7</a></li> + <li><a href="#">history8</a></li> + <li><a href="#">history9</a></li> + <li><a href="#">history10</a></li> + <li><a href="#">history11</a></li> + <li><a href="#">history12</a></li> + <li><a href="#">history13</a></li> + <li><a href="#">history14</a></li> + <li><a href="#">history15</a></li> + <li><a href="#">history16</a></li> + <li><a href="#">history17</a></li> + <li><a href="#">history18</a></li> + <li><a href="#">history19</a></li> + <li><a href="#">history20</a></li> + </ul> + </div> + </div> + ); +}; + +export default History; diff --git a/app/InputForm.tsx b/app/InputForm.tsx new file mode 100644 index 0000000..9682357 --- /dev/null +++ b/app/InputForm.tsx @@ -0,0 +1,22 @@ +// InputForm.tsx +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; diff --git a/app/Models.tsx b/app/Models.tsx new file mode 100644 index 0000000..98c72c8 --- /dev/null +++ b/app/Models.tsx @@ -0,0 +1,43 @@ +// 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> + {/* Add more model buttons here */} + </div> + </form> + </div> + </div> + ); +}; + +export default Models; diff --git a/app/layout.tsx b/app/layout.tsx index a14e64f..3bf71eb 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -10,6 +10,10 @@ export default function RootLayout({ }) { return ( <html lang="en"> + <head> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>AI Assistant</title> + </head> <body>{children}</body> </html> ) diff --git a/app/page.tsx b/app/page.tsx index 63d9c78..cc79706 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,14 +1,19 @@ -"use client"; // Add this at the top to mark this file as a Client Component +// LandingPage.tsx +"use client"; 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.css'; -const App = () => { - const [showDivs, setShowDivs] = useState(true); // Default to true to show divs on load +const LandingPage: React.FC = () => { + const [showDivs, setShowDivs] = useState(true); const conversationRef = useRef<HTMLDivElement>(null); useEffect(() => { - // Scroll to bottom when the component mounts or updates const scrollToBottom = () => { const conversation = conversationRef.current; if (conversation) { @@ -16,11 +21,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); - if (conversationRef.current) { observer.observe(conversationRef.current, { childList: true, @@ -39,119 +42,25 @@ const App = () => { setShowDivs(prevState => !prevState); }; + // Example messages array + const messages = [ + 'User: Hello!', + 'AI: Hi there!', + 'User: How are you?', + 'AI: I’m good, thank you!' + ]; + return ( <div className="App"> - <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 Divs" : "Show Divs"}</button> - </li> - </ul> - </div> - </header> - + <Header toggleDivs={toggleDivs} showDivs={showDivs} /> <div className="container"> - {showDivs && ( - <div className="history-background"> - <div className="history"> - <ul> - <li> - <a href="#">history1</a> - </li> - {/* Add more history items here */} - </ul> - </div> - </div> - )} - - {showDivs && ( - <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> - <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"> - <img src="/img/send.svg" alt="send" /> - </button> - <button type="submit" name="option" value="voice"> - <img src="/img/microphone.svg" alt="microphone" /> - </button> - </form> + {showDivs && <History />} + {showDivs && <Models />} + <Conversation ref={conversationRef} messages={messages} /> + <InputForm /> </div> </div> ); }; -export default App; +export default LandingPage; From 284e70b841f1f441180fba299450ae37d728a957 Mon Sep 17 00:00:00 2001 From: Sage The DM <luca.burger@grischuni.net> Date: Wed, 18 Sep 2024 11:17:34 +0200 Subject: [PATCH 2/2] Made the header button show/hide work --- app/Conversation.tsx | 64 ++-- app/Header.tsx | 4 +- app/History.tsx | 30 +- app/InputForm.tsx | 1 - app/Models.tsx | 47 ++- app/page.tsx | 39 ++- app/styles.css | 524 -------------------------------- app/styles/container.css | 34 +++ app/styles/faq.css | 0 app/styles/global.css | 18 ++ app/styles/header.css | 38 +++ app/styles/history.css | 38 +++ app/styles/input.css | 61 ++++ app/styles/master.css | 13 + app/styles/models.css | 124 ++++++++ app/styles/output.css | 74 +++++ app/styles/reset.css | 5 + app/styles/scrollbar.css | 17 ++ app/styles/user-ai-messages.css | 27 ++ app/styles/variables.css | 15 + 20 files changed, 585 insertions(+), 588 deletions(-) delete mode 100644 app/styles.css create mode 100644 app/styles/container.css create mode 100644 app/styles/faq.css create mode 100644 app/styles/global.css create mode 100644 app/styles/header.css create mode 100644 app/styles/history.css create mode 100644 app/styles/input.css create mode 100644 app/styles/master.css create mode 100644 app/styles/models.css create mode 100644 app/styles/output.css create mode 100644 app/styles/reset.css create mode 100644 app/styles/scrollbar.css create mode 100644 app/styles/user-ai-messages.css create mode 100644 app/styles/variables.css diff --git a/app/Conversation.tsx b/app/Conversation.tsx index 1a37518..1caa836 100644 --- a/app/Conversation.tsx +++ b/app/Conversation.tsx @@ -1,39 +1,43 @@ -// Conversation.tsx import React, { ForwardedRef } from 'react'; interface ConversationProps { messages: string[]; + onResendClick: () => void; + onEditClick: () => void; + onCopyClick: () => void; } -const Conversation = React.forwardRef<HTMLDivElement, ConversationProps>(({ messages }, 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> - ); - })} - <form method="POST" action="" id="buttonForm"> - <button type="button" name="option" value="chat"> - <img src="/img/resend.svg" alt="resend" /> - </button> - <button type="button" name="option" value="chat"> - <img src="/img/edit.svg" alt="edit" /> - </button> - <button type="button" name="option" value="answer"> - <img src="/img/copy.svg" alt="copy" /> - </button> - </form> +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> - </div> - ); -}); + ); + } +); export default Conversation; diff --git a/app/Header.tsx b/app/Header.tsx index 7ea87c9..7b4c1c6 100644 --- a/app/Header.tsx +++ b/app/Header.tsx @@ -23,7 +23,9 @@ const Header: React.FC<HeaderProps> = ({ toggleDivs, showDivs }) => { <a href="/faq">FAQ</a> </li> <li> - <button onClick={toggleDivs}>{showDivs ? "Hide Divs" : "Show Divs"}</button> + <button onClick={toggleDivs}> + {showDivs ? "Hide History and Models" : "Show History and Models"} + </button> </li> </ul> </div> diff --git a/app/History.tsx b/app/History.tsx index eb21840..cd93950 100644 --- a/app/History.tsx +++ b/app/History.tsx @@ -1,4 +1,3 @@ -// History.tsx import React from 'react'; const History: React.FC = () => { @@ -6,28 +5,13 @@ const History: React.FC = () => { <div className="history-background"> <div className="history"> <ul> - {/* Populate with history items */} - <li><a href="#">history1</a></li> - <li><a href="#">history2</a></li> - <li><a href="#">history3</a></li> - <li><a href="#">history4</a></li> - <li><a href="#">history5</a></li> - <li><a href="#">history6</a></li> - <li><a href="#">history7</a></li> - <li><a href="#">history8</a></li> - <li><a href="#">history9</a></li> - <li><a href="#">history10</a></li> - <li><a href="#">history11</a></li> - <li><a href="#">history12</a></li> - <li><a href="#">history13</a></li> - <li><a href="#">history14</a></li> - <li><a href="#">history15</a></li> - <li><a href="#">history16</a></li> - <li><a href="#">history17</a></li> - <li><a href="#">history18</a></li> - <li><a href="#">history19</a></li> - <li><a href="#">history20</a></li> - </ul> + {/* Populate with history items */} + {Array.from({ length: 20 }, (_, index) => ( + <li key={index}> + <a href="#">history{index + 1}</a> + </li> + ))} + </ul> </div> </div> ); diff --git a/app/InputForm.tsx b/app/InputForm.tsx index 9682357..6abfc64 100644 --- a/app/InputForm.tsx +++ b/app/InputForm.tsx @@ -1,4 +1,3 @@ -// InputForm.tsx import React from 'react'; const InputForm: React.FC = () => { diff --git a/app/Models.tsx b/app/Models.tsx index 98c72c8..ee6739b 100644 --- a/app/Models.tsx +++ b/app/Models.tsx @@ -32,7 +32,52 @@ const Models: React.FC = () => { <h3>Default</h3> </div> </button> - {/* Add more model buttons here */} + {/* 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> diff --git a/app/page.tsx b/app/page.tsx index cc79706..a53edbb 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,13 +1,12 @@ +"use client" // LandingPage.tsx -"use client"; - import React, { useState, useEffect, useRef } from 'react'; import Header from './Header'; import History from './History'; import Models from './Models'; import Conversation from './Conversation'; import InputForm from './InputForm'; -import './styles.css'; +import './styles/master.css'; const LandingPage: React.FC = () => { const [showDivs, setShowDivs] = useState(true); @@ -42,7 +41,6 @@ const LandingPage: React.FC = () => { setShowDivs(prevState => !prevState); }; - // Example messages array const messages = [ 'User: Hello!', 'AI: Hi there!', @@ -50,14 +48,39 @@ const LandingPage: React.FC = () => { 'AI: I’m 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 ( <div className="App"> <Header toggleDivs={toggleDivs} showDivs={showDivs} /> <div className="container"> - {showDivs && <History />} - {showDivs && <Models />} - <Conversation ref={conversationRef} messages={messages} /> - <InputForm /> + <div className={`left-panel ${showDivs ? '' : 'hidden'}`}> + <History /> + <Models /> + </div> + <div className={`conversation-container ${showDivs ? 'expanded' : 'collapsed'}`}> + <Conversation + ref={conversationRef} + messages={messages} + onResendClick={handleResendClick} + onEditClick={handleEditClick} + onCopyClick={handleCopyClick} + /> + <InputForm /> + </div> </div> </div> ); diff --git a/app/styles.css b/app/styles.css deleted file mode 100644 index 0f41603..0000000 --- a/app/styles.css +++ /dev/null @@ -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; - } -} diff --git a/app/styles/container.css b/app/styles/container.css new file mode 100644 index 0000000..0c7316c --- /dev/null +++ b/app/styles/container.css @@ -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 */ +} diff --git a/app/styles/faq.css b/app/styles/faq.css new file mode 100644 index 0000000..e69de29 diff --git a/app/styles/global.css b/app/styles/global.css new file mode 100644 index 0000000..2a2b956 --- /dev/null +++ b/app/styles/global.css @@ -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; +} diff --git a/app/styles/header.css b/app/styles/header.css new file mode 100644 index 0000000..8ecc019 --- /dev/null +++ b/app/styles/header.css @@ -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); +} diff --git a/app/styles/history.css b/app/styles/history.css new file mode 100644 index 0000000..2aaa58d --- /dev/null +++ b/app/styles/history.css @@ -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); +} diff --git a/app/styles/input.css b/app/styles/input.css new file mode 100644 index 0000000..12b71e2 --- /dev/null +++ b/app/styles/input.css @@ -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); +} diff --git a/app/styles/master.css b/app/styles/master.css new file mode 100644 index 0000000..4b21879 --- /dev/null +++ b/app/styles/master.css @@ -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'; diff --git a/app/styles/models.css b/app/styles/models.css new file mode 100644 index 0000000..18b6777 --- /dev/null +++ b/app/styles/models.css @@ -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; +} diff --git a/app/styles/output.css b/app/styles/output.css new file mode 100644 index 0000000..122122c --- /dev/null +++ b/app/styles/output.css @@ -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; +} diff --git a/app/styles/reset.css b/app/styles/reset.css new file mode 100644 index 0000000..23d8732 --- /dev/null +++ b/app/styles/reset.css @@ -0,0 +1,5 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} diff --git a/app/styles/scrollbar.css b/app/styles/scrollbar.css new file mode 100644 index 0000000..5e2f6a1 --- /dev/null +++ b/app/styles/scrollbar.css @@ -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; +} \ No newline at end of file diff --git a/app/styles/user-ai-messages.css b/app/styles/user-ai-messages.css new file mode 100644 index 0000000..ccbd494 --- /dev/null +++ b/app/styles/user-ai-messages.css @@ -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; +} diff --git a/app/styles/variables.css b/app/styles/variables.css new file mode 100644 index 0000000..3df7f30 --- /dev/null +++ b/app/styles/variables.css @@ -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); +}