diff --git a/api_v1_messages.php b/api_v1_messages.php
new file mode 100644
index 0000000..c19c168
--- /dev/null
+++ b/api_v1_messages.php
@@ -0,0 +1,35 @@
+ false, 'error' => 'Empty content']);
+ exit;
+}
+
+try {
+ $stmt = db()->prepare("INSERT INTO messages (channel_id, user_id, content) VALUES (?, ?, ?)");
+ $stmt->execute([$channel_id, $user_id, $content]);
+ $last_id = db()->lastInsertId();
+
+ // Fetch message with username for the response
+ $stmt = db()->prepare("SELECT m.*, u.username FROM messages m JOIN users u ON m.user_id = u.id WHERE m.id = ?");
+ $stmt->execute([$last_id]);
+ $msg = $stmt->fetch();
+
+ echo json_encode([
+ 'success' => true,
+ 'message' => [
+ 'username' => $msg['username'],
+ 'content' => htmlspecialchars($msg['content']),
+ 'time' => date('H:i', strtotime($msg['created_at']))
+ ]
+ ]);
+} catch (Exception $e) {
+ echo json_encode(['success' => false, 'error' => $e->getMessage()]);
+}
diff --git a/assets/css/discord.css b/assets/css/discord.css
new file mode 100644
index 0000000..2e91fd8
--- /dev/null
+++ b/assets/css/discord.css
@@ -0,0 +1,213 @@
+:root {
+ --bg-servers: #1e1f22;
+ --bg-channels: #2b2d31;
+ --bg-chat: #313338;
+ --bg-members: #2b2d31;
+ --text-primary: #dbdee1;
+ --text-muted: #949ba4;
+ --blurple: #5865f2;
+ --hover: #35373c;
+ --active: #3f4147;
+}
+
+body {
+ margin: 0;
+ padding: 0;
+ font-family: 'Inter', system-ui, -apple-system, sans-serif;
+ background-color: var(--bg-servers);
+ color: var(--text-primary);
+ height: 100vh;
+ overflow: hidden;
+}
+
+.discord-app {
+ display: flex;
+ height: 100vh;
+ width: 100vw;
+}
+
+/* Servers Sidebar */
+.servers-sidebar {
+ width: 72px;
+ background-color: var(--bg-servers);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 12px 0;
+ gap: 8px;
+ flex-shrink: 0;
+}
+
+.server-icon {
+ width: 48px;
+ height: 48px;
+ background-color: var(--bg-chat);
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ transition: all 0.2s;
+ color: var(--text-primary);
+ text-decoration: none;
+ font-weight: bold;
+}
+
+.server-icon:hover {
+ border-radius: 16px;
+ background-color: var(--blurple);
+}
+
+.server-icon.active {
+ border-radius: 16px;
+ background-color: var(--blurple);
+}
+
+/* Channels Sidebar */
+.channels-sidebar {
+ width: 240px;
+ background-color: var(--bg-channels);
+ display: flex;
+ flex-direction: column;
+ flex-shrink: 0;
+}
+
+.channels-header {
+ height: 48px;
+ padding: 0 16px;
+ display: flex;
+ align-items: center;
+ box-shadow: 0 1px 0 rgba(0,0,0,0.2);
+ font-weight: bold;
+}
+
+.channels-list {
+ flex: 1;
+ padding: 8px;
+ overflow-y: auto;
+}
+
+.channel-item {
+ padding: 6px 8px;
+ border-radius: 4px;
+ cursor: pointer;
+ color: var(--text-muted);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 2px;
+ text-decoration: none;
+}
+
+.channel-item:hover {
+ background-color: var(--hover);
+ color: var(--text-primary);
+}
+
+.channel-item.active {
+ background-color: var(--active);
+ color: var(--text-primary);
+}
+
+.channel-item::before {
+ content: "#";
+ font-size: 1.2em;
+ font-weight: 300;
+}
+
+/* Chat Area */
+.chat-container {
+ flex: 1;
+ background-color: var(--bg-chat);
+ display: flex;
+ flex-direction: column;
+}
+
+.chat-header {
+ height: 48px;
+ padding: 0 16px;
+ display: flex;
+ align-items: center;
+ box-shadow: 0 1px 0 rgba(0,0,0,0.2);
+ font-weight: bold;
+}
+
+.messages-list {
+ flex: 1;
+ overflow-y: auto;
+ padding: 16px;
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+}
+
+.message-item {
+ display: flex;
+ gap: 16px;
+}
+
+.message-avatar {
+ width: 40px;
+ height: 40px;
+ background-color: #4e5058;
+ border-radius: 50%;
+ flex-shrink: 0;
+}
+
+.message-content {
+ flex: 1;
+}
+
+.message-author {
+ font-weight: bold;
+ font-size: 0.95em;
+ margin-bottom: 4px;
+}
+
+.message-text {
+ font-size: 0.95em;
+ line-height: 1.4;
+ color: #dbdee1;
+}
+
+.message-time {
+ font-size: 0.75em;
+ color: var(--text-muted);
+ margin-left: 8px;
+ font-weight: normal;
+}
+
+/* Input Area */
+.chat-input-container {
+ padding: 0 16px 24px 16px;
+}
+
+.chat-input-wrapper {
+ background-color: #383a40;
+ border-radius: 8px;
+ padding: 11px 16px;
+ display: flex;
+}
+
+.chat-input {
+ background: transparent;
+ border: none;
+ color: var(--text-primary);
+ width: 100%;
+ outline: none;
+ font-size: 1em;
+}
+
+/* Members Sidebar */
+.members-sidebar {
+ width: 240px;
+ background-color: var(--bg-members);
+ padding: 24px 8px;
+ display: none; /* Hidden on mobile/small screens */
+}
+
+@media (min-width: 1024px) {
+ .members-sidebar {
+ display: block;
+ }
+}
diff --git a/assets/js/main.js b/assets/js/main.js
new file mode 100644
index 0000000..fba2c42
--- /dev/null
+++ b/assets/js/main.js
@@ -0,0 +1,55 @@
+document.addEventListener('DOMContentLoaded', () => {
+ const chatForm = document.getElementById('chat-form');
+ const chatInput = document.getElementById('chat-input');
+ const messagesList = document.getElementById('messages-list');
+
+ // Scroll to bottom
+ messagesList.scrollTop = messagesList.scrollHeight;
+
+ chatForm.addEventListener('submit', async (e) => {
+ e.preventDefault();
+ const content = chatInput.value.trim();
+ if (!content) return;
+
+ chatInput.value = '';
+
+ try {
+ const response = await fetch('api_v1_messages.php', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({
+ content: content,
+ channel_id: new URLSearchParams(window.location.search).get('channel_id') || 1
+ })
+ });
+
+ const result = await response.json();
+ if (result.success) {
+ appendMessage(result.message);
+ messagesList.scrollTop = messagesList.scrollHeight;
+ } else {
+ alert('Error: ' + result.error);
+ }
+ } catch (err) {
+ console.error('Failed to send message:', err);
+ }
+ });
+
+ function appendMessage(msg) {
+ const div = document.createElement('div');
+ div.className = 'message-item';
+ div.innerHTML = `
+
+
+
+ ${msg.username}
+ ${msg.time}
+
+
+ ${msg.content.replace(/\n/g, '
')}
+
+
+ `;
+ messagesList.appendChild(div);
+ }
+});
diff --git a/database/schema.sql b/database/schema.sql
new file mode 100644
index 0000000..359b2aa
--- /dev/null
+++ b/database/schema.sql
@@ -0,0 +1,50 @@
+-- Initial schema for Discord-like app
+CREATE TABLE IF NOT EXISTS users (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ username VARCHAR(50) NOT NULL UNIQUE,
+ email VARCHAR(100) NOT NULL UNIQUE,
+ password_hash VARCHAR(255) NOT NULL,
+ avatar_url VARCHAR(255),
+ status VARCHAR(20) DEFAULT 'offline',
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+);
+
+CREATE TABLE IF NOT EXISTS servers (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ name VARCHAR(100) NOT NULL,
+ owner_id INT NOT NULL,
+ icon_url VARCHAR(255),
+ invite_code VARCHAR(10) UNIQUE,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (owner_id) REFERENCES users(id)
+);
+
+CREATE TABLE IF NOT EXISTS channels (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ server_id INT NOT NULL,
+ name VARCHAR(100) NOT NULL,
+ type ENUM('text', 'voice') DEFAULT 'text',
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (server_id) REFERENCES servers(id) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS messages (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ channel_id INT NOT NULL,
+ user_id INT NOT NULL,
+ content TEXT NOT NULL,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (channel_id) REFERENCES channels(id) ON DELETE CASCADE,
+ FOREIGN KEY (user_id) REFERENCES users(id)
+);
+
+-- Seed initial data
+INSERT IGNORE INTO users (id, username, email, password_hash, status) VALUES
+(1, 'System', 'system@local', '$2y$10$xyz', 'online');
+
+INSERT IGNORE INTO servers (id, name, owner_id, invite_code) VALUES
+(1, 'General Community', 1, 'GEN-123');
+
+INSERT IGNORE INTO channels (id, server_id, name) VALUES
+(1, 1, 'general'),
+(2, 1, 'random');
diff --git a/db_init.php b/db_init.php
new file mode 100644
index 0000000..9522d8a
--- /dev/null
+++ b/db_init.php
@@ -0,0 +1,10 @@
+exec($sql);
+ echo "Database initialized successfully.\n";
+} catch (Exception $e) {
+ echo "Error initializing database: " . $e->getMessage() . "\n";
+}
diff --git a/index.php b/index.php
index 7205f3d..91d35d7 100644
--- a/index.php
+++ b/index.php
@@ -1,150 +1,142 @@
-
-
-
-
-
- New Style
-query("SELECT * FROM servers LIMIT 10")->fetchAll();
+$active_server_id = $_GET['server_id'] ?? ($servers[0]['id'] ?? 1);
+
+// Fetch channels
+$stmt = db()->prepare("SELECT * FROM channels WHERE server_id = ?");
+$stmt->execute([$active_server_id]);
+$channels = $stmt->fetchAll();
+$active_channel_id = $_GET['channel_id'] ?? ($channels[0]['id'] ?? 1);
+
+// Fetch messages
+$stmt = db()->prepare("
+ SELECT m.*, u.username, u.avatar_url
+ FROM messages m
+ JOIN users u ON m.user_id = u.id
+ WHERE m.channel_id = ?
+ ORDER BY m.created_at ASC
+ LIMIT 50
+");
+$stmt->execute([$active_channel_id]);
+$messages = $stmt->fetchAll();
+
+$current_channel_name = 'general';
+foreach($channels as $c) if($c['id'] == $active_channel_id) $current_channel_name = $c['name'];
+
+// SEO & Env tags
+$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Discord-like messaging app built with PHP';
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
?>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+ # |
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
Analyzing your requirements and generating your website…
-
- Loading…
-
-
= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.
-
This page will update automatically as the plan is implemented.
-
Runtime: PHP = htmlspecialchars($phpVersion) ?> — UTC = htmlspecialchars($now) ?>
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
Welcome to #!
+
This is the start of the # channel.
+
+
+
+
+
+
+
+
+
+
+
+
+
+