nixaut-codelabs's picture
textarea butonları fazla aşağıda. Yazı üstte butonlar aşağıda. Çok az fark gözüküyor gözle ama dikkatli bakınca çok açık, moral bozuyor :D çöz lütfen. Ayrıca modellere direkt "Deep Research" ekle. Herşey tamamen İngilizce olmalı sitede. Türkçe konuştuğuma bakma. Ayrıca Neural Assistant falan buraları Nixaut Copilot olarak düzenle, yazıları falan. Ayrıca tema siyah beyazdı unutma dropdown yeşil falan kullanmışın mesela.
e948fb1 verified
raw
history blame
14.9 kB
class CustomSidebar extends HTMLElement {
connectedCallback() {
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');
* { font-family: 'Inter', sans-serif; }
.sidebar {
width: 320px;
background: rgba(17, 24, 39, 0.95);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border-right: 1px solid rgba(255, 255, 255, 0.1);
padding: 1.5rem 0;
overflow-y: auto;
height: 100vh;
position: fixed;
left: 0;
top: 64px;
z-index: 40;
transition: transform 0.3s ease;
}
.nav-section {
margin-bottom: 2rem;
}
.nav-title {
font-size: 0.75rem;
font-weight: 600;
color: #71717a;
text-transform: uppercase;
letter-spacing: 0.05em;
padding: 0 1.5rem;
margin-bottom: 0.75rem;
}
.nav-item {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.875rem 1.5rem;
color: #d1d5db;
text-decoration: none;
transition: all 0.2s ease;
position: relative;
cursor: pointer;
border-radius: 0 12px 12px 0;
margin-right: 0.75rem;
}
.nav-item:hover {
background: rgba(255, 255, 255, 0.08);
color: #ffffff;
}
.nav-item.active {
background: rgba(255, 255, 255, 0.12);
color: #ffffff;
}
.nav-item.active::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
bottom: auto;
width: 3px;
height: 24px;
background: linear-gradient(135deg, #ffffff 0%, #9ca3af 100%);
border-radius: 0 3px 3px 0;
}
.nav-icon {
width: 20px;
height: 20px;
transition: transform 0.2s ease;
}
.nav-item:hover .nav-icon {
transform: scale(1.1);
}
.new-chat-btn {
margin: 0 1.5rem 1.5rem;
padding: 0.875rem 1.5rem;
background: linear-gradient(135deg, #ffffff 0%, #9ca3af 100%);
color: #111827;
border-radius: 12px;
font-weight: 600;
font-size: 0.9375rem;
text-align: center;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
border: none;
display: flex;
align-items: center;
justify-content: center;
gap: 0.625rem;
box-shadow: 0 4px 12px rgba(255, 255, 255, 0.15);
}
.new-chat-btn:hover {
transform: translateY(-2px) scale(1.02);
box-shadow: 0 8px 25px rgba(255, 255, 255, 0.25);
}
.new-chat-btn:active {
transform: translateY(0) scale(0.98);
}
.chat-history {
max-height: 280px;
overflow-y: auto;
margin-bottom: 1rem;
padding-right: 0.5rem;
}
.chat-history::-webkit-scrollbar {
width: 4px;
}
.chat-history::-webkit-scrollbar-track {
background: transparent;
}
.chat-history::-webkit-scrollbar-thumb {
background: #4b5563;
border-radius: 2px;
}
.history-item {
padding: 0.625rem 1.5rem;
color: #9ca3af;
font-size: 0.875rem;
cursor: pointer;
transition: all 0.2s ease;
border-radius: 0 8px 8px 0;
margin-right: 0.75rem;
line-height: 1.4;
display: flex;
align-items: center;
gap: 0.5rem;
}
.history-item:hover {
color: #ffffff;
background: rgba(255, 255, 255, 0.06);
padding-left: 2rem;
}
.history-icon {
width: 16px;
height: 16px;
opacity: 0.6;
}
.divider {
height: 1px;
background: linear-gradient(to right, transparent, rgba(255, 255, 255, 0.1), transparent);
margin: 1.5rem 1.5rem 1rem;
}
.account-section {
padding: 1rem 1.5rem;
background: rgba(255, 255, 255, 0.04);
border-radius: 12px;
margin: 0 1.5rem;
display: flex;
align-items: center;
gap: 0.75rem;
cursor: pointer;
transition: all 0.2s ease;
}
.account-section:hover {
background: rgba(255, 255, 255, 0.08);
}
.avatar {
width: 36px;
height: 36px;
border-radius: 50%;
background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: 600;
font-size: 0.875rem;
}
.account-info {
flex: 1;
}
.account-name {
color: #ffffff;
font-weight: 500;
font-size: 0.875rem;
margin-bottom: 0.125rem;
}
.account-plan {
color: #9ca3af;
font-size: 0.75rem;
}
.badge {
background: linear-gradient(135deg, #f59e0b 0%, #f97316 100%);
color: #ffffff;
padding: 0.25rem 0.625rem;
border-radius: 6px;
font-size: 0.625rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
@media (max-width: 768px) {
.sidebar {
transform: translateX(-100%);
}
.sidebar.active {
transform: translateX(0);
}
}
</style>
<nav class="sidebar">
<button onclick="startNewChat()" class="new-chat-btn">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2.5">
<path d="M12 5v14m-7-7h14"/>
</svg>
New Chat
</button>
<div class="nav-section">
<div class="nav-title">Recent Chats</div>
<div class="chat-history" id="recentChats">
<div class="history-item">
<svg class="history-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/>
</svg>
How to create responsive design?
</div>
<div class="history-item">
<svg class="history-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/>
</svg>
JavaScript async patterns
</div>
<div class="history-item">
<svg class="history-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/>
</svg>
CSS Grid vs Flexbox comparison
</div>
<div class="history-item">
<svg class="history-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/>
</svg>
React performance tips
</div>
<div class="history-item">
<svg class="history-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/>
</svg>
TypeScript best practices
</div>
</div>
</div>
<div class="divider"></div>
<div class="nav-section">
<div class="nav-title">Araçlar</div>
<a href="/" class="nav-item">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"/>
<path d="M9 22V12h6v10"/>
</svg>
Home
</a>
<a href="/chat" class="nav-item active">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/>
</svg>
Chat
</a>
<a href="/files" class="nav-item">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M13 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V9z"/>
<path d="M13 2v7h7"/>
</svg>
My Files
</a>
<a href="/settings" class="nav-item">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="3"/>
<path d="M12 1v6m0 6v6m4.22-13.22l4.24 4.24M1.54 9.96l4.24 4.24m12.44 0l4.24 4.24M1.54 14.04l4.24-4.24"/>
</svg>
Settings
</a>
</div>
<div class="divider"></div>
<div class="account-section" onclick="showAccountModal()">
<div class="avatar">U</div>
<div class="account-info">
<div class="account-name">User</div>
<div class="account-plan">Pro Plan</div>
</div>
<div class="badge">Pro</div>
</div>
</nav>
`;
}
// Add methods dynamically since shadow DOM doesn't allow direct access from parent
connectedCallback() {
setTimeout(() => {
const navItems = this.shadowRoot.querySelectorAll('.nav-item');
navItems.forEach(item => {
item.addEventListener('click', function(e) {
if (this.getAttribute('href').startsWith('/')) {
e.preventDefault();
// Navigate to new page (SPA style)
window.history.pushState({}, '', this.getAttribute('href'));
updateActiveNavItem(this);
}
});
});
const historyItems = this.shadowRoot.querySelectorAll('.history-item');
historyItems.forEach(item => {
item.addEventListener('click', function() {
loadChatHistory(this.textContent);
});
});
}, 0);
}
}
function updateActiveNavItem(activeItem) {
document.querySelectorAll('custom-sidebar').forEach(sidebar => {
const navItems = sidebar.shadowRoot.querySelectorAll('.nav-item');
navItems.forEach(item => item.classList.remove('active'));
});
activeItem.classList.add('active');
}
function startNewChat() {
clearChat();
}
function loadChatHistory(topic) {
// Load specific chat history
console.log('Loading chat history for:', topic);
}
function toggleMobileSidebar() {
const sidebar = document.querySelector('custom-sidebar');
if (sidebar) {
sidebar.shadowRoot.querySelector('.sidebar').classList.toggle('active');
}
}
customElements.define('custom-sidebar', CustomSidebar);