Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions frontend/src/components/ChatInterface.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,12 @@ const ChatInterface = () => {
if (window.innerWidth < 768) setSidebarOpen(false);
};

const handleMainContentClick = () => {
const handleMainContentClick = (e) => {
// Don't close sidebar if clicking on sidebar elements
if (e.target.closest('.sidebar')) {
return;
}

if (window.innerWidth < 768 && sidebarOpen) {
setSidebarOpen(false);
}
Expand Down Expand Up @@ -215,20 +220,20 @@ const ChatInterface = () => {

return (
<div className="chat-container">
<aside className={`sidebar ${sidebarOpen ? "open" : ""}`}>
<aside className={`sidebar ${sidebarOpen ? "open" : ""}`} onClick={(e) => e.stopPropagation()}>
<div className="sidebar-header">
<div className="logo-container">
<LogoIcon />
<span className="logo-text">Atomic</span>
</div>
<button className="sidebar-close-btn" onClick={() => setSidebarOpen(false)} >
<button className="sidebar-close-btn" onClick={(e) => { e.stopPropagation(); setSidebarOpen(false); }} >
<Icon path={<path d="M18 6L6 18M6 6l12 12" />} />
</button>
</div>
<div className="sidebar-top"> <nav className="main-nav"> <button className="new-thread-btn" onClick={handleCreateNewChat} disabled={!isAuthenticated}> <Icon path={<path d="M12 5v14m-7-7h14" />} /> <span>New Chat</span> </button> </nav> </div>
<div className="sidebar-top"> <nav className="main-nav"> <button className="new-thread-btn" onClick={(e) => { e.stopPropagation(); handleCreateNewChat(); }} disabled={!isAuthenticated}> <Icon path={<path d="M12 5v14m-7-7h14" />} /> <span>New Chat</span> </button> </nav> </div>
<div className="library">
<div className="library-header"> <h3>History</h3> </div>
{isCreatingNewChat && (<div className="new-chat-form-container"> <form onSubmit={handleNewChatSubmit} className={`new-chat-form ${titleError ? "error" : ""}`} > <input type="text" placeholder="New chat title..." value={newChatTitle} onChange={handleTitleChange} onBlur={() => !newChatTitle && setIsCreatingNewChat(false)} autoFocus /> <button type="submit" className="submit-new-chat-btn" disabled={!!titleError} > <Icon path={titleError ? (<path d="M18 6L6 18M6 6l12 12" />) : (<path d="M20 6L9 17l-5-5" />)} /> </button> </form> {titleError && (<p className="title-error-warning">{titleError}</p>)} </div>)}
{isCreatingNewChat && (<div className="new-chat-form-container" onClick={(e) => e.stopPropagation()}> <form onSubmit={handleNewChatSubmit} className={`new-chat-form ${titleError ? "error" : ""}`} > <input type="text" placeholder="New chat title..." value={newChatTitle} onChange={handleTitleChange} onBlur={() => !newChatTitle && setIsCreatingNewChat(false)} autoFocus /> <button type="submit" className="submit-new-chat-btn" disabled={!!titleError} > <Icon path={titleError ? (<path d="M18 6L6 18M6 6l12 12" />) : (<path d="M20 6L9 17l-5-5" />)} /> </button> </form> {titleError && (<p className="title-error-warning">{titleError}</p>)} </div>)}
<ul> {isAuthenticated ? (chats.length > 0 ? (chats.map((item) => (<li key={item._id} className={item._id === activeChatId ? "active" : ""} > <a href="#" onClick={(e) => { e.preventDefault(); handleHistoryClick(item._id); }}> <span>{item.title}</span> </a> </li>))) : (<li> <a href="#" className="no-chats"> <span>No chats found</span> </a> </li>)) : (<li> <a href="#" className="no-chats"> <span>Login to see history</span> </a> </li>)} </ul>
</div>
<div className="sidebar-bottom"> <div className="user-profile"> <div className="user-info"> <Icon path={<> <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" /> <circle cx="12" cy="7" r="4" /> </>} /> <span>{user?.fullName?.firstName || "Guest User"}</span> </div> <div className={`credits-container ${isCreditsVisible ? 'show-text' : ''} ${creditsLoading ? 'loading' : ''} ${credits === 0 ? 'zero-credits' : ''}`} onClick={handleCreditsClick} > <span>{creditsLoading ? <div className="loading-spinner"></div> : (isAuthenticated ? `Credits: ${credits}` : (isCreditsVisible ? 'Login First' : 'Credits: 0'))}</span> </div> </div> </div>
Expand Down
89 changes: 87 additions & 2 deletions frontend/src/styles/ChatInterface.css
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
left: 0;
top: 0;
z-index: 1000;
pointer-events: auto;
}

.sidebar a {
Expand Down Expand Up @@ -650,6 +651,7 @@ a:hover .icon {
padding: 8px 12px;
max-width: 800px;
width: 100%;
min-width: 280px;
transition: border-color 0.3s, box-shadow 0.3s;
}
.input-form:focus-within {
Expand Down Expand Up @@ -727,8 +729,17 @@ a:hover .icon {
}


.new-chat-form-container { margin-bottom: 8px; }
.new-chat-form { position: relative; }
.new-chat-form-container {
margin-bottom: 8px;
width: 100%;
position: relative;
z-index: 1001;
}
.new-chat-form {
position: relative;
width: 100%;
z-index: 1002;
}
.new-chat-form input {
width: 100%;
padding: 10px 40px 10px 10px;
Expand All @@ -738,6 +749,7 @@ a:hover .icon {
color: var(--text-primary);
font-size: 14px;
box-sizing: border-box;
min-width: 200px;
}
.new-chat-form.error input { border-color: var(--error-color); }
.new-chat-form input:focus { outline: none; border-color: var(--accent-color); }
Expand Down Expand Up @@ -858,6 +870,75 @@ a:hover .icon {
width: 14px;
height: 14px;
}

/* Mobile first chat form adjustments */
.first-chat-form-container {
padding: 0 8px;
margin-top: 20px;
}

.first-chat-form {
min-width: 250px;
max-width: calc(100vw - 32px);
padding: 12px 45px 12px 12px;
}

.first-chat-form input {
font-size: 16px; /* Prevents zoom on iOS */
min-height: 20px;
}

.submit-first-chat-btn {
width: 32px;
height: 32px;
right: 6px;
}

.submit-first-chat-btn .icon {
width: 16px;
height: 16px;
}

/* Mobile sidebar new chat form adjustments */
.new-chat-form input {
font-size: 16px; /* Prevents zoom on iOS */
min-width: 180px;
}

.submit-new-chat-btn {
width: 30px;
height: 30px;
}

.submit-new-chat-btn .icon {
width: 16px;
height: 16px;
}

/* Mobile chat input area adjustments */
.chat-input-area {
padding: 20px 16px 16px 16px;
}

.input-form {
min-width: 250px;
max-width: calc(100vw - 32px);
padding: 10px 14px;
}

.input-wrapper textarea {
font-size: 16px; /* Prevents zoom on iOS */
min-height: 24px;
}

.model-selector {
font-size: 14px;
padding: 8px 10px;
}

.char-counter {
font-size: 11px;
}
}


Expand Down Expand Up @@ -1037,6 +1118,9 @@ a:hover .icon {
margin-top: 24px;
display: flex;
justify-content: center;
width: 100%;
padding: 0 16px;
box-sizing: border-box;
}

.first-chat-form {
Expand All @@ -1049,6 +1133,7 @@ a:hover .icon {
padding: 10px 40px 10px 10px;
max-width: 500px;
width: 100%;
min-width: 280px;
transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

Expand Down