anycoder-ed280f1c / index.html
samirerty's picture
Upload folder using huggingface_hub
038187e verified
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>داشبورد چت | Chat Dashboard</title>
<!-- فونت فارسی وزیرمتن -->
<link href="https://cdn.jsdelivr.net/gh/rastikerdar/vazirmatn@v33.003/Vazirmatn-font-face.css" rel="stylesheet" type="text/css" />
<!-- آیکون‌های Phosphor -->
<script src="https://unpkg.com/@phosphor-icons/web"></script>
<style>
:root {
/* پالت رنگی مدرن */
--primary: #4f46e5;
--primary-hover: #4338ca;
--bg-body: #f3f4f6;
--bg-surface: #ffffff;
--text-main: #111827;
--text-secondary: #6b7280;
--border: #e5e7eb;
--danger: #ef4444;
--success: #10b981;
--message-bg: #f3f4f6;
--message-self: #4f46e5;
--text-self: #ffffff;
/* ابعاد */
--sidebar-width: 320px;
--header-height: 64px;
--border-radius: 12px;
--safe-area-bottom: env(safe-area-inset-bottom);
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
-webkit-tap-highlight-color: transparent;
}
body {
font-family: 'Vazirmatn', sans-serif;
background-color: var(--bg-body);
color: var(--text-main);
height: 100vh;
overflow: hidden;
display: flex;
}
/* --- Scrollbar Styling --- */
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: #d1d5db;
border-radius: 10px;
}
/* --- Sidebar (Right Side) --- */
.sidebar {
width: var(--sidebar-width);
background-color: var(--bg-surface);
border-left: 1px solid var(--border);
display: flex;
flex-direction: column;
height: 100%;
z-index: 50;
transition: transform 0.3s ease;
}
.sidebar-header {
padding: 20px;
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
gap: 12px;
}
.avatar {
width: 48px;
height: 48px;
border-radius: 50%;
object-fit: cover;
border: 2px solid var(--primary);
}
.user-info h3 {
font-size: 0.95rem;
font-weight: 700;
}
.user-info p {
font-size: 0.8rem;
color: var(--text-secondary);
}
.sidebar-content {
flex: 1;
overflow-y: auto;
padding: 16px;
padding-bottom: calc(16px + var(--safe-area-bottom));
}
.logout-btn {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
width: 100%;
padding: 10px;
margin-bottom: 24px;
border: 1px solid var(--border);
background: transparent;
color: var(--danger);
border-radius: var(--border-radius);
cursor: pointer;
font-family: inherit;
font-weight: 500;
transition: all 0.2s;
}
.logout-btn:hover {
background-color: #fef2f2;
}
.rooms-section-title {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
padding: 0 4px;
}
.rooms-section-title h4 {
font-size: 0.9rem;
color: var(--text-secondary);
font-weight: 600;
}
.badge {
background-color: var(--primary);
color: white;
font-size: 0.75rem;
padding: 2px 8px;
border-radius: 10px;
font-weight: bold;
}
.new-room-btn {
width: 100%;
padding: 12px;
background-color: var(--text-main);
color: white;
border: none;
border-radius: var(--border-radius);
font-family: inherit;
font-weight: 600;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
margin-bottom: 16px;
transition: opacity 0.2s;
}
.new-room-btn:disabled {
background-color: #d1d5db;
cursor: not-allowed;
opacity: 0.7;
}
.room-list {
list-style: none;
display: flex;
flex-direction: column;
gap: 8px;
}
.room-item {
display: flex;
align-items: center;
gap: 12px;
padding: 12px;
border-radius: var(--border-radius);
cursor: pointer;
transition: background-color 0.2s;
border: 1px solid transparent;
}
.room-item:hover {
background-color: #f9fafb;
border-color: var(--border);
}
.room-item.active {
background-color: #eef2ff;
border-color: var(--primary);
}
.room-icon {
width: 40px;
height: 40px;
background-color: #e0e7ff;
color: var(--primary);
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
}
.room-details {
flex: 1;
}
.room-name {
font-weight: 600;
font-size: 0.9rem;
display: block;
}
.room-role {
font-size: 0.75rem;
color: var(--text-secondary);
}
/* --- Main Content --- */
.main-content {
flex: 1;
display: flex;
flex-direction: column;
background-color: var(--bg-body);
position: relative;
height: 100%;
overflow: hidden;
}
/* Header */
.top-header {
height: var(--header-height);
background-color: var(--bg-surface);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
border-bottom: 1px solid var(--border);
flex-shrink: 0;
}
.header-right {
display: flex;
align-items: center;
gap: 16px;
}
.header-title {
font-size: 1.1rem;
font-weight: 700;
}
.status-indicator {
display: flex;
align-items: center;
gap: 6px;
font-size: 0.85rem;
color: var(--success);
background: #ecfdf5;
padding: 4px 10px;
border-radius: 20px;
}
.status-dot {
width: 8px;
height: 8px;
background-color: var(--success);
border-radius: 50%;
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.4); }
70% { box-shadow: 0 0 0 6px rgba(16, 185, 129, 0); }
100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); }
}
.menu-btn {
background: none;
border: none;
font-size: 1.5rem;
cursor: pointer;
color: var(--text-main);
display: none; /* Hidden on desktop */
}
.anycoder-link {
font-size: 0.8rem;
color: var(--text-secondary);
text-decoration: none;
transition: color 0.2s;
}
.anycoder-link:hover { color: var(--primary); }
/* Views Container */
.views-container {
flex: 1;
position: relative;
overflow: hidden;
}
.view {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
transition: transform 0.3s ease, opacity 0.3s ease;
}
.view.hidden {
transform: translateX(-20px);
opacity: 0;
pointer-events: none;
z-index: -1;
}
.view.active {
transform: translateX(0);
opacity: 1;
pointer-events: auto;
z-index: 10;
}
/* Welcome Screen */
#welcome-view {
align-items: center;
justify-content: center;
text-align: center;
padding: 20px;
}
.welcome-icon {
font-size: 5rem;
color: var(--primary);
margin-bottom: 20px;
opacity: 0.8;
}
.welcome-title {
font-size: 1.5rem;
margin-bottom: 10px;
color: var(--text-main);
}
.welcome-subtitle {
color: var(--text-secondary);
margin-bottom: 30px;
max-width: 300px;
}
.mobile-create-btn {
display: none; /* Only visible on mobile */
padding: 12px 24px;
background-color: var(--primary);
color: white;
border: none;
border-radius: var(--border-radius);
font-family: inherit;
font-weight: 600;
font-size: 1rem;
cursor: pointer;
box-shadow: 0 4px 6px -1px rgba(79, 70, 229, 0.2);
}
/* Chat Interface */
#chat-view {
background-color: #fff;
}
.chat-header {
height: 60px;
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
background-color: var(--bg-surface);
}
.chat-info h2 {
font-size: 1rem;
}
.chat-info span {
font-size: 0.8rem;
color: var(--text-secondary);
}
.share-btn {
background: #f3f4f6;
border: none;
width: 36px;
height: 36px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-main);
cursor: pointer;
transition: background 0.2s;
}
.share-btn:hover { background: #e5e7eb; }
.messages-container {
flex: 1;
padding: 20px;
overflow-y: auto;
background-color: #f9fafb;
display: flex;
flex-direction: column;
gap: 16px;
}
.message {
max-width: 70%;
padding: 12px 16px;
border-radius: 16px;
font-size: 0.9rem;
line-height: 1.5;
position: relative;
animation: fadeIn 0.3s ease;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.message.received {
background-color: var(--bg-surface);
color: var(--text-main);
align-self: flex-start;
border-bottom-right-radius: 4px;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
.message.sent {
background-color: var(--message-self);
color: var(--text-self);
align-self: flex-end;
border-bottom-left-radius: 4px;
box-shadow: 0 2px 4px rgba(79, 70, 229, 0.3);
}
.input-area {
padding: 16px;
background-color: var(--bg-surface);
border-top: 1px solid var(--border);
display: flex;
gap: 12px;
align-items: center;
padding-bottom: calc(16px + var(--safe-area-bottom));
}
.input-wrapper {
flex: 1;
position: relative;
}
.message-input {
width: 100%;
padding: 12px 16px;
border-radius: 24px;
border: 1px solid var(--border);
background-color: #f9fafb;
font-family: inherit;
outline: none;
transition: border-color 0.2s;
}
.message-input:focus {
border-color: var(--primary);
background-color: #fff;
}
.send-btn {
width: 48px;
height: 48px;
border-radius: 50%;
background-color: var(--primary);
color: white;
border: none;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
cursor: pointer;
transition: transform 0.1s, background-color 0.2s;
flex-shrink: 0;
}
.send-btn:active {
transform: scale(0.95);
}
.send-btn:hover {
background-color: var(--primary-hover);
}
/* --- Responsive Queries --- */
@media (max-width: 768px) {
.sidebar {
position: fixed;
right: 0;
top: 0;
bottom: 0;
transform: translateX(100%);
box-shadow: -4px 0 15px rgba(0,0,0,0.1);
}
.sidebar.open {
transform: translateX(0);
}
.menu-btn {
display: block;
}
.mobile-create-btn {
display: block;
}
.status-indicator {
display: none; /* Hide status on mobile header to save space */
}
/* Overlay for sidebar */
.overlay {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.5);
z-index: 40;
opacity: 0;
pointer-events: none;
transition: opacity 0.3s;
}
.overlay.active {
opacity: 1;
pointer-events: auto;
}
}
</style>
</head>
<body>
<!-- Overlay for Mobile Sidebar -->
<div class="overlay" id="overlay"></div>
<!-- Sidebar (Right) -->
<aside class="sidebar" id="sidebar">
<!-- User Profile -->
<div class="sidebar-header">
<img src="https://picsum.photos/seed/user123/100/100" alt="Avatar" class="avatar">
<div class="user-info">
<h3>علی محمدی</h3>
<p>09123456789</p>
</div>
</div>
<div class="sidebar-content">
<!-- Logout -->
<button class="logout-btn" onclick="handleLogout()">
<i class="ph ph-sign-out"></i>
خروج از حساب
</button>
<!-- My Rooms Section -->
<div class="rooms-section-title">
<h4>اتاق‌های من</h4>
<span class="badge" id="room-count-badge">0</span>
</div>
<!-- New Room Button -->
<button class="new-room-btn" id="new-room-btn" onclick="createNewRoom()">
<i class="ph ph-plus-circle"></i>
اتاق جدید
</button>
<!-- Room List -->
<ul class="room-list" id="room-list">
<!-- Rooms will be injected here via JS -->
</ul>
</div>
</aside>
<!-- Main Content -->
<main class="main-content">
<!-- Header -->
<header class="top-header">
<div class="header-right">
<button class="menu-btn" onclick="toggleSidebar()">
<i class="ph ph-list"></i>
</button>
<div class="header-title">داشبورد کاربر</div>
</div>
<div class="header-left" style="display: flex; align-items: center; gap: 12px;">
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">
Built with anycoder
</a>
<div class="status-indicator" id="desktop-status">
<span class="status-dot"></span>
آنلاین
</div>
</div>
</header>
<!-- Views Container -->
<div class="views-container">
<!-- 1. Welcome Screen -->
<div id="welcome-view" class="view active">
<div class="welcome-icon">
<i class="ph ph-chat-circle-dots"></i>
</div>
<h1 class="welcome-title">به داشبورد خوش آمدید</h1>
<p class="welcome-subtitle">برای شروع گفتگو، یک اتاق انتخاب کنید یا اتاق جدیدی بسازید.</p>
<button class="mobile-create-btn" onclick="createNewRoomMobile()">ایجاد اتاق</button>
</div>
<!-- 2. Chat Interface -->
<div id="chat-view" class="view hidden">
<!-- Chat Header -->
<div class="chat-header">
<div class="chat-info">
<h2 id="active-room-name">نام اتاق</h2>
<span id="active-room-members">0 عضو</span>
</div>
<button class="share-btn" title="اشتراک گذاری">
<i class="ph ph-share-network"></i>
</button>
</div>
<!-- Messages Container -->
<div class="messages-container" id="messages-container">
<!-- Messages will be injected here -->
<div class="message received">
سلام! به اتاق خوش آمدید.
</div>
</div>
<!-- Input Area -->
<div class="input-area">
<div class="input-wrapper">
<input type="text" class="message-input" id="message-input" placeholder="پیام خود را بنویسید..." onkeypress="handleEnter(event)">
</div>
<button class="send-btn" onclick="sendMessage()">
<i class="ph ph-paper-plane-right"></i>
</button>
</div>
</div>
</div>
</main>
<script>
// --- State Management ---
const state = {
rooms: [
{ id: 1, name: "گروه برنامه نویسی", role: "Created", members: 12 },
{ id: 2, name: "پروژه طراحی", role: "Member", members: 5 }
],
activeRoomId: null,
maxRooms: 3
};
// --- DOM Elements ---
const roomListEl = document.getElementById('room-list');
const roomCountBadge = document.getElementById('room-count-badge');
const newRoomBtn = document.getElementById('new-room-btn');
const sidebar = document.getElementById('sidebar');
const overlay = document.getElementById('overlay');
const welcomeView = document.getElementById('welcome-view');
const chatView = document.getElementById('chat-view');
const activeRoomName = document.getElementById('active-room-name');
const activeRoomMembers = document.getElementById('active-room-members');
const messagesContainer = document.getElementById('messages-container');
const messageInput = document.getElementById('message-input');
// --- Initialization ---
function init() {
renderRooms();
updateRoomButtonState();
}
// --- Sidebar Logic ---
function toggleSidebar() {
sidebar.classList.toggle('open');
overlay.classList.toggle('active');
}
// Close sidebar when clicking overlay
overlay.addEventListener('click', () => {
sidebar.classList.remove('open');
overlay.classList.remove('active');
});
function handleLogout() {
if(confirm("آیا مطمئن هستید که می‌خواهید خارج شوید؟")) {
alert("خروج با موفقیت انجام شد.");
// In a real app: window.location.href = '/login';
}
}
// --- Room Logic ---
function renderRooms() {
roomListEl.innerHTML = '';
roomCountBadge.textContent = state.rooms.length;
state.rooms.forEach(room => {
const li = document.createElement('li');
li.className = `room-item ${state.activeRoomId === room.id ? 'active' : ''}`;
li.onclick = () => selectRoom(room.id);
const roleColor = room.role === 'Created' ? 'var(--primary)' : 'var(--text-secondary)';
li.innerHTML = `
<div class="room-icon">
<i class="ph ph-users-three"></i>
</div>
<div class="room-details">
<span class="room-name">${room.name}</span>
<span class="room-role" style="color: ${roleColor}">${room.role}</span>
</div>
<i class="ph ph-caret-left" style="color: #d1d5db;"></i>
`;
roomListEl.appendChild(li);
});
}
function updateRoomButtonState() {
if (state.rooms.length >= state.maxRooms) {
newRoomBtn.disabled = true;
newRoomBtn.innerHTML = `<i class="ph ph-prohibit"></i> محدودیت اتاق (۳)`;
} else {
newRoomBtn.disabled = false;
newRoomBtn.innerHTML = `<i class="ph ph-plus-circle"></i> اتاق جدید`;
}
}
function createNewRoom() {
if (state.rooms.length >= state.maxRooms) return;
const newId = state.rooms.length + 1;
const newRoom = {
id: newId,
name: `اتاق جدید شماره ${newId}`,
role: "Created",
members: 1
};
state.rooms.push(newRoom);
renderRooms();
updateRoomButtonState();
// Automatically select the new room
selectRoom(newId);
}
function createNewRoomMobile() {
createNewRoom();
// Close sidebar on mobile after creation
sidebar.classList.remove('open');
overlay.classList.remove('active');
}
function selectRoom(roomId) {
state.activeRoomId = roomId;
const room = state.rooms.find(r => r.id === roomId);
// Update UI
renderRooms(); // To update active class
// Switch View
if (window.innerWidth <= 768) {
sidebar.classList.remove('open');
overlay.classList.remove('active');
}
welcomeView.classList.remove('active');
welcomeView.classList.add('hidden');
chatView.classList.remove('hidden');
chatView.classList.add('active');
// Update Chat Header
activeRoomName.textContent = room.name;
activeRoomMembers.textContent = `${room.members} عضو`;
// Clear messages (simulation)
messagesContainer.innerHTML = `
<div style="text-align: center; color: var(--text-secondary); font-size: 0.8rem; margin: 20px 0;">
-- شروع مکالمه در ${room.name} --
</div>
<div class="message received">
سلام! به ${room.name} خوش آمدید.
</div>
`;
}
// --- Chat Logic ---
function handleEnter(e) {
if (e.key === 'Enter') {
sendMessage();
}
}
function sendMessage() {
const text = messageInput.value.trim();
if (!text) return;
// Add Sent Message
const sentMsg = document.createElement('div');
sentMsg.className = 'message sent';
sentMsg.textContent = text;
messagesContainer.appendChild(sentMsg);
// Clear Input
messageInput.value = '';
// Scroll to bottom
messagesContainer.scrollTop = messagesContainer.scrollHeight;
// Simulate Reply (Optional interaction)
setTimeout(() => {
const replyMsg = document.createElement('div');
replyMsg.className = 'message received';
replyMsg.textContent = "پیام شما دریافت شد.";
messagesContainer.appendChild(replyMsg);
messagesContainer.scrollTop = messagesContainer.scrollHeight;
}, 1000);
}
// Run Init
init();
</script>
</body>
</html>