Download index.html from ayham909/https-huggingface-co-organizations-towhed: direct link, hf CLI and curl.
- Browser
- Download file 31.6 kB
-
https://huggingface.co/spaces/ayham909/https-huggingface-co-organizations-towhed/resolve/main/index.html
- Command line
-
hf download hf://spaces/ayham909/https-huggingface-co-organizations-towhed/index.html
-
curl -L -o index.html https://huggingface.co/spaces/ayham909/https-huggingface-co-organizations-towhed/resolve/main/index.html
31.6 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Towhed Messaging App</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| .message-bubble { | |
| max-width: 70%; | |
| border-radius: 1rem; | |
| padding: 0.75rem 1rem; | |
| margin-bottom: 0.5rem; | |
| position: relative; | |
| } | |
| .message-bubble.sent { | |
| background-color: #3b82f6; | |
| color: white; | |
| align-self: flex-end; | |
| } | |
| .message-bubble.received { | |
| background-color: #e5e7eb; | |
| color: #1f2937; | |
| align-self: flex-start; | |
| } | |
| .message-time { | |
| font-size: 0.75rem; | |
| opacity: 0.8; | |
| margin-top: 0.25rem; | |
| text-align: right; | |
| } | |
| .app-bar { | |
| height: 56px; | |
| box-shadow: 0 2px 4px rgba(0,0,0,0.1); | |
| } | |
| .chat-container { | |
| height: calc(100vh - 56px - 64px); | |
| overflow-y: auto; | |
| } | |
| .input-container { | |
| height: 64px; | |
| } | |
| .floating-button { | |
| position: fixed; | |
| bottom: 1.5rem; | |
| right: 1.5rem; | |
| width: 56px; | |
| height: 56px; | |
| border-radius: 50%; | |
| box-shadow: 0 4px 8px rgba(0,0,0,0.2); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| z-index: 10; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-100 font-sans"> | |
| <!-- Login Screen --> | |
| <div id="login-screen" class="fixed inset-0 bg-white flex flex-col items-center justify-center p-6 z-20"> | |
| <div class="w-full max-w-md"> | |
| <div class="text-center mb-8"> | |
| <h1 class="text-3xl font-bold text-blue-600">Towhed</h1> | |
| <p class="text-gray-600 mt-2">Secure messaging with admin verification</p> | |
| </div> | |
| <div class="bg-white rounded-lg shadow-md p-6"> | |
| <h2 class="text-xl font-semibold mb-4 text-gray-800">Login</h2> | |
| <div class="mb-6"> | |
| <label class="block text-gray-700 text-sm font-medium mb-2" for="code"> | |
| Admin Verification Code | |
| </label> | |
| <input id="code" type="text" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Enter 6-digit code"> | |
| <p class="text-xs text-gray-500 mt-1">You must get this code from the system admin</p> | |
| </div> | |
| <button onclick="login()" class="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition"> | |
| Login | |
| </button> | |
| <div class="mt-4 text-center"> | |
| <p class="text-sm text-gray-600">Don't have an account? <span class="text-blue-600 cursor-pointer" onclick="showAdminPanel()">Request admin access</span></p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Admin Panel (Hidden by default) --> | |
| <div id="admin-panel" class="fixed inset-0 bg-white flex flex-col items-center justify-center p-6 z-20 hidden"> | |
| <div class="w-full max-w-md"> | |
| <div class="flex justify-between items-center mb-6"> | |
| <button onclick="hideAdminPanel()" class="text-gray-500 hover:text-gray-700"> | |
| <i class="fas fa-arrow-left"></i> | |
| </button> | |
| <h2 class="text-xl font-semibold text-gray-800">Admin Panel</h2> | |
| <div class="w-6"></div> <!-- Spacer for alignment --> | |
| </div> | |
| <div class="bg-white rounded-lg shadow-md p-6"> | |
| <div class="mb-6"> | |
| <label class="block text-gray-700 text-sm font-medium mb-2" for="admin-username"> | |
| Admin Username | |
| </label> | |
| <input id="admin-username" type="text" class="w-full px-3 py-2 border border-gray-300 rounded-md mb-4 focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Enter admin username"> | |
| <label class="block text-gray-700 text-sm font-medium mb-2" for="admin-password"> | |
| Admin Password | |
| </label> | |
| <input id="admin-password" type="password" class="w-full px-3 py-2 border border-gray-300 rounded-md mb-4 focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Enter admin password"> | |
| <label class="block text-gray-700 text-sm font-medium mb-2" for="generate-code"> | |
| Generate Verification Code | |
| </label> | |
| <div class="flex mb-2"> | |
| <input id="generated-code" type="text" readonly class="flex-1 px-3 py-2 border border-gray-300 rounded-l-md bg-gray-100" placeholder="Code will appear here"> | |
| <button onclick="generateCode()" class="bg-blue-600 text-white px-4 py-2 rounded-r-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition"> | |
| Generate | |
| </button> | |
| </div> | |
| <div class="flex justify-between items-center"> | |
| <span class="text-xs text-gray-500">Code expires in: <span id="code-expiry">5:00</span></span> | |
| <button onclick="copyCode()" class="text-xs text-blue-600 hover:text-blue-800"> | |
| <i class="fas fa-copy mr-1"></i>Copy Code | |
| </button> | |
| </div> | |
| </div> | |
| <div class="mt-6 p-4 bg-blue-50 rounded-md"> | |
| <h3 class="font-medium text-blue-800 mb-2">Admin Instructions</h3> | |
| <p class="text-sm text-blue-700">1. Enter admin credentials</p> | |
| <p class="text-sm text-blue-700">2. Click "Generate" to create a code</p> | |
| <p class="text-sm text-blue-700">3. Share this code securely with authorized users</p> | |
| <p class="text-sm text-blue-700">4. Each code is valid for 5 minutes only</p> | |
| </div> | |
| <div class="mt-4 p-4 bg-gray-50 rounded-md"> | |
| <h3 class="font-medium text-gray-800 mb-2">Recent Codes</h3> | |
| <div id="recent-codes" class="text-sm text-gray-700"> | |
| <!-- Generated codes will appear here --> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Main App Interface (Hidden until login) --> | |
| <div id="app-interface" class="hidden"> | |
| <!-- App Bar with Tabs --> | |
| <div class="app-bar bg-white flex flex-col fixed top-0 left-0 right-0 z-10"> | |
| <div class="flex items-center px-4 py-2"> | |
| <img src="https://via.placeholder.com/40" alt="Profile" class="rounded-full w-8 h-8 mr-3"> | |
| <div> | |
| <h1 class="font-medium">Towhed</h1> | |
| <p class="text-xs text-gray-500">My Profile</p> | |
| <div class="flex space-x-4 text-xs mt-1"> | |
| <span><span class="font-medium">120</span> Posts</span> | |
| <span><span class="font-medium">1.2K</span> Followers</span> | |
| <span><span class="font-medium">350</span> Following</span> | |
| </div> | |
| </div> | |
| <div class="ml-auto flex space-x-4"> | |
| <button class="text-gray-600 hover:text-gray-900"> | |
| <i class="fas fa-plus"></i> | |
| </button> | |
| <button class="text-gray-600 hover:text-gray-900"> | |
| <i class="fas fa-ellipsis-v"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="flex border-b border-gray-200"> | |
| <button onclick="showTab('posts')" class="flex-1 py-2 text-center font-medium text-blue-600 border-b-2 border-blue-600"> | |
| Posts | |
| </button> | |
| <button onclick="showTab('messages')" class="flex-1 py-2 text-center font-medium text-gray-500 hover:text-gray-700"> | |
| Messages | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Content Area --> | |
| <div class="chat-container pt-24 pb-16 overflow-y-auto"> | |
| <!-- Posts Tab --> | |
| <div id="posts-tab" class="flex flex-col"> | |
| <!-- Posts Filter --> | |
| <div class="bg-white p-3 border-b border-gray-200 flex items-center"> | |
| <span class="text-sm font-medium mr-2">Show:</span> | |
| <select class="bg-gray-100 rounded-md px-2 py-1 text-sm focus:outline-none"> | |
| <option>Posts from everyone</option> | |
| <option>Posts from people I follow</option> | |
| <option>My posts only</option> | |
| </select> | |
| </div> | |
| <!-- Create Post --> | |
| <div class="bg-white p-4 border-b border-gray-200"> | |
| <div class="flex items-center mb-3"> | |
| <img src="https://via.placeholder.com/40" alt="Profile" class="rounded-full w-10 h-10 mr-3"> | |
| <input type="text" placeholder="What's on your mind?" class="flex-1 bg-gray-100 rounded-full py-2 px-4 focus:outline-none"> | |
| </div> | |
| <button class="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700"> | |
| Post | |
| </button> | |
| </div> | |
| <!-- Sample Posts --> | |
| <div class="bg-white p-4 mb-2 border-b border-gray-200"> | |
| <div class="flex items-center justify-between mb-3"> | |
| <div class="flex items-center"> | |
| <img src="https://via.placeholder.com/40" alt="Profile" class="rounded-full w-10 h-10 mr-3"> | |
| <div> | |
| <h3 class="font-medium">User One</h3> | |
| <p class="text-xs text-gray-500">2 hours ago</p> | |
| </div> | |
| </div> | |
| <button class="text-xs bg-gray-100 hover:bg-gray-200 px-3 py-1 rounded-full"> | |
| <i class="fas fa-user-plus mr-1"></i>Follow | |
| </button> | |
| </div> | |
| <p class="mb-3">This is my first post on Towhed! Excited to share my thoughts here.</p> | |
| <div class="flex justify-between text-gray-500 border-t border-gray-200 pt-2"> | |
| <button class="flex items-center space-x-1 hover:text-blue-600"> | |
| <i class="far fa-thumbs-up"></i> | |
| <span>Like (12)</span> | |
| </button> | |
| <button class="flex items-center space-x-1 hover:text-red-600"> | |
| <i class="far fa-thumbs-down"></i> | |
| <span>Dislike (2)</span> | |
| </button> | |
| <button class="flex items-center space-x-1 hover:text-yellow-600"> | |
| <i class="far fa-surprise"></i> | |
| <span>Surprised (5)</span> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="bg-white p-4 mb-2 border-b border-gray-200"> | |
| <div class="flex items-center justify-between mb-3"> | |
| <div class="flex items-center"> | |
| <img src="https://via.placeholder.com/40" alt="Profile" class="rounded-full w-10 h-10 mr-3"> | |
| <div> | |
| <h3 class="font-medium">User Two</h3> | |
| <p class="text-xs text-gray-500">5 hours ago</p> | |
| </div> | |
| </div> | |
| <button class="text-xs bg-gray-100 hover:bg-gray-200 px-3 py-1 rounded-full"> | |
| <i class="fas fa-user-plus mr-1"></i>Follow | |
| </button> | |
| </div> | |
| <p class="mb-3">Check out this amazing view from my vacation!</p> | |
| <img src="https://via.placeholder.com/600x300" alt="Post image" class="w-full rounded-md mb-3"> | |
| <div class="flex justify-between text-gray-500 border-t border-gray-200 pt-2"> | |
| <button class="flex items-center space-x-1 hover:text-blue-600"> | |
| <i class="far fa-thumbs-up"></i> | |
| <span>Like (45)</span> | |
| </button> | |
| <button class="flex items-center space-x-1 hover:text-red-600"> | |
| <i class="far fa-thumbs-down"></i> | |
| <span>Dislike (3)</span> | |
| </button> | |
| <button class="flex items-center space-x-1 hover:text-yellow-600"> | |
| <i class="far fa-surprise"></i> | |
| <span>Surprised (8)</span> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Messages Tab (hidden by default) --> | |
| <div id="messages-tab" class="hidden flex flex-col space-y-2 px-4"> | |
| <!-- Date divider --> | |
| <div class="flex items-center my-4"> | |
| <div class="flex-1 border-t border-gray-200"></div> | |
| <span class="px-3 text-sm text-gray-500">Today</span> | |
| <div class="flex-1 border-t border-gray-200"></div> | |
| </div> | |
| <!-- Received message --> | |
| <div class="flex"> | |
| <div class="message-bubble received"> | |
| <p>Hello! Welcome to Towhed messaging app.</p> | |
| <div class="message-time">10:30 AM</div> | |
| </div> | |
| </div> | |
| <!-- Sent message --> | |
| <div class="flex justify-end"> | |
| <div class="message-bubble sent"> | |
| <p>Hi there! Thanks for the welcome.</p> | |
| <div class="message-time">10:32 AM</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Input Area --> | |
| <div class="input-container bg-white fixed bottom-0 left-0 right-0 flex items-center px-4 border-t border-gray-200"> | |
| <button class="text-gray-500 hover:text-gray-700 mr-2"> | |
| <i class="fas fa-paperclip"></i> | |
| </button> | |
| <input type="text" placeholder="Type a message" class="flex-1 py-2 px-3 rounded-full border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
| <button class="ml-2 text-blue-600 hover:text-blue-800"> | |
| <i class="fas fa-paper-plane"></i> | |
| </button> | |
| </div> | |
| <!-- Floating action button --> | |
| <div class="floating-button bg-blue-600 text-white hover:bg-blue-700"> | |
| <i class="fas fa-comment-medical"></i> | |
| </div> | |
| </div> | |
| <!-- Kotlin Code Section (Hidden by default) --> | |
| <div id="kotlin-code" class="fixed inset-0 bg-white p-6 overflow-auto hidden z-30"> | |
| <div class="max-w-4xl mx-auto"> | |
| <div class="flex justify-between items-center mb-6"> | |
| <h2 class="text-2xl font-bold text-gray-800">Towhed Kotlin Implementation</h2> | |
| <button onclick="hideKotlinCode()" class="text-gray-500 hover:text-gray-700 p-2"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <div class="bg-gray-800 rounded-lg p-4 overflow-x-auto"> | |
| <pre class="text-gray-100 text-sm"> | |
| // MainActivity.kt | |
| package com.example.towhed | |
| import android.os.Bundle | |
| import androidx.appcompat.app.AppCompatActivity | |
| import androidx.recyclerview.widget.LinearLayoutManager | |
| import com.example.towhed.databinding.ActivityMainBinding | |
| import com.google.firebase.auth.FirebaseAuth | |
| import com.google.firebase.firestore.FirebaseFirestore | |
| class MainActivity : AppCompatActivity() { | |
| private lateinit var binding: ActivityMainBinding | |
| private lateinit var auth: FirebaseAuth | |
| private lateinit var db: FirebaseFirestore | |
| private lateinit var adapter: MessageAdapter | |
| private val messages = mutableListOf<Message>() | |
| override fun onCreate(savedInstanceState: Bundle?) { | |
| super.onCreate(savedInstanceState) | |
| binding = ActivityMainBinding.inflate(layoutInflater) | |
| setContentView(binding.root) | |
| auth = FirebaseAuth.getInstance() | |
| db = FirebaseFirestore.getInstance() | |
| // Check if user is logged in with admin code | |
| if (auth.currentUser == null) { | |
| startActivity(Intent(this, LoginActivity::class.java)) | |
| finish() | |
| return | |
| } | |
| setupRecyclerView() | |
| setupListeners() | |
| loadMessages() | |
| } | |
| private fun setupRecyclerView() { | |
| adapter = MessageAdapter(messages) | |
| binding.recyclerView.apply { | |
| layoutManager = LinearLayoutManager(this@MainActivity) | |
| adapter = this@MainActivity.adapter | |
| } | |
| } | |
| private fun setupListeners() { | |
| binding.sendButton.setOnClickListener { | |
| val messageText = binding.messageInput.text.toString().trim() | |
| if (messageText.isNotEmpty()) { | |
| sendMessage(messageText) | |
| binding.messageInput.text.clear() | |
| } | |
| } | |
| } | |
| private fun sendMessage(text: String) { | |
| val message = Message( | |
| text = text, | |
| senderId = auth.currentUser?.uid ?: "", | |
| timestamp = System.currentTimeMillis() | |
| ) | |
| db.collection("messages") | |
| .add(message) | |
| .addOnSuccessListener { | |
| // Message sent successfully | |
| } | |
| .addOnFailureListener { | |
| // Handle error | |
| } | |
| } | |
| private fun loadMessages() { | |
| db.collection("messages") | |
| .orderBy("timestamp") | |
| .addSnapshotListener { snapshot, error -> | |
| if (error != null) return@addSnapshotListener | |
| messages.clear() | |
| snapshot?.documents?.forEach { doc -> | |
| val message = doc.toObject(Message::class.java) | |
| message?.let { messages.add(it) } | |
| } | |
| adapter.notifyDataSetChanged() | |
| binding.recyclerView.scrollToPosition(messages.size - 1) | |
| } | |
| } | |
| } | |
| // LoginActivity.kt | |
| package com.example.towhed | |
| import android.content.Intent | |
| import android.os.Bundle | |
| import androidx.appcompat.app.AppCompatActivity | |
| import com.example.towhed.databinding.ActivityLoginBinding | |
| import com.google.firebase.auth.FirebaseAuth | |
| import com.google.firebase.firestore.FirebaseFirestore | |
| class LoginActivity : AppCompatActivity() { | |
| private lateinit var binding: ActivityLoginBinding | |
| private lateinit var auth: FirebaseAuth | |
| private lateinit var db: FirebaseFirestore | |
| override fun onCreate(savedInstanceState: Bundle?) { | |
| super.onCreate(savedInstanceState) | |
| binding = ActivityLoginBinding.inflate(layoutInflater) | |
| setContentView(binding.root) | |
| auth = FirebaseAuth.getInstance() | |
| db = FirebaseFirestore.getInstance() | |
| binding.loginButton.setOnClickListener { | |
| val phone = binding.phoneInput.text.toString().trim() | |
| val code = binding.codeInput.text.toString().trim() | |
| if (phone.isEmpty() || code.isEmpty()) { | |
| // Show error | |
| return@setOnClickListener | |
| } | |
| verifyAdminCode(phone, code) | |
| } | |
| binding.adminLink.setOnClickListener { | |
| startActivity(Intent(this, AdminActivity::class.java)) | |
| } | |
| } | |
| private fun verifyAdminCode(code: String) { | |
| db.collection("admin_codes") | |
| .whereEqualTo("code", code) | |
| .limit(1) | |
| .get() | |
| .addOnSuccessListener { doc -> | |
| if (doc.exists() && doc.getString("code") == code) { | |
| // Code is valid, proceed with authentication | |
| authenticateUser(phone) | |
| } else { | |
| // Show invalid code error | |
| } | |
| } | |
| .addOnFailureListener { | |
| // Handle error | |
| } | |
| } | |
| private fun authenticateUser(phone: String) { | |
| // Implement phone authentication with Firebase | |
| // On success: | |
| startActivity(Intent(this, MainActivity::class.java)) | |
| finish() | |
| } | |
| } | |
| // AdminActivity.kt | |
| package com.example.towhed | |
| import android.os.Bundle | |
| import androidx.appcompat.app.AppCompatActivity | |
| import com.example.towhed.databinding.ActivityAdminBinding | |
| import com.google.firebase.firestore.FirebaseFirestore | |
| import java.util.* | |
| class AdminActivity : AppCompatActivity() { | |
| private lateinit var binding: ActivityAdminBinding | |
| private lateinit var db: FirebaseFirestore | |
| override fun onCreate(savedInstanceState: Bundle?) { | |
| super.onCreate(savedInstanceState) | |
| binding = ActivityAdminBinding.inflate(layoutInflater) | |
| setContentView(binding.root) | |
| db = FirebaseFirestore.getInstance() | |
| binding.generateButton.setOnClickListener { | |
| val phone = binding.phoneInput.text.toString().trim() | |
| if (phone.isEmpty()) return@setOnClickListener | |
| val code = generateRandomCode() | |
| binding.codeOutput.setText(code) | |
| saveAdminCode(phone, code) | |
| } | |
| } | |
| private fun generateRandomCode(): String { | |
| return (100000..999999).random().toString() | |
| } | |
| private fun saveAdminCode(phone: String, code: String) { | |
| val data = hashMapOf( | |
| "phone" to phone, | |
| "code" to code, | |
| "generatedAt" to System.currentTimeMillis() | |
| ) | |
| db.collection("admin_codes") | |
| .document(phone) | |
| .set(data) | |
| .addOnSuccessListener { | |
| // Code saved successfully | |
| } | |
| .addOnFailureListener { | |
| // Handle error | |
| } | |
| } | |
| } | |
| // Message.kt | |
| data class Message( | |
| val text: String = "", | |
| val senderId: String = "", | |
| val timestamp: Long = 0L | |
| ) | |
| // MessageAdapter.kt | |
| class MessageAdapter(private val messages: List<Message>) : | |
| RecyclerView.Adapter<MessageAdapter.MessageViewHolder>() { | |
| inner class MessageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { | |
| fun bind(message: Message) { | |
| // Bind message data to views | |
| } | |
| } | |
| override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MessageViewHolder { | |
| val view = LayoutInflater.from(parent.context) | |
| .inflate(R.layout.item_message, parent, false) | |
| return MessageViewHolder(view) | |
| } | |
| override fun onBindViewHolder(holder: MessageViewHolder, position: Int) { | |
| holder.bind(messages[position]) | |
| } | |
| override fun getItemCount(): Int = messages.size | |
| } | |
| </pre> | |
| </div> | |
| <div class="mt-6 bg-blue-50 p-4 rounded-md"> | |
| <h3 class="font-medium text-blue-800 mb-2">Implementation Notes:</h3> | |
| <ul class="list-disc pl-5 text-blue-700 space-y-1"> | |
| <li>Uses Firebase Authentication for user management</li> | |
| <li>Firestore database stores messages and admin codes</li> | |
| <li>Admin codes are generated randomly and stored</li> | |
| <li>Users must provide exact admin code to login</li> | |
| <li>Real-time messaging with Firestore listeners</li> | |
| <li>Clean architecture with separate activities</li> | |
| </ul> | |
| </div> | |
| <button onclick="hideKotlinCode()" class="mt-6 w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition"> | |
| Close Code View | |
| </button> | |
| </div> | |
| </div> | |
| <!-- View Code Button --> | |
| <div class="fixed bottom-4 left-4 z-10"> | |
| <button onclick="showKotlinCode()" class="bg-gray-800 text-white py-2 px-4 rounded-md hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 transition flex items-center"> | |
| <i class="fas fa-code mr-2"></i> | |
| View Kotlin Code | |
| </button> | |
| </div> | |
| <script> | |
| // Show/hide admin panel | |
| function showAdminPanel() { | |
| document.getElementById('login-screen').classList.add('hidden'); | |
| document.getElementById('admin-panel').classList.remove('hidden'); | |
| } | |
| function hideAdminPanel() { | |
| document.getElementById('admin-panel').classList.add('hidden'); | |
| document.getElementById('login-screen').classList.remove('hidden'); | |
| } | |
| // Admin functions | |
| let currentCode = null; | |
| let expiryInterval = null; | |
| function generateCode() { | |
| const username = document.getElementById('admin-username').value; | |
| const password = document.getElementById('admin-password').value; | |
| if (!username || !password) { | |
| alert('Please enter admin credentials'); | |
| return; | |
| } | |
| // In a real app, verify admin credentials with backend here | |
| const code = Math.floor(100000 + Math.random() * 900000); | |
| currentCode = code; | |
| document.getElementById('generated-code').value = code; | |
| // Add to recent codes | |
| const recentCodesDiv = document.getElementById('recent-codes'); | |
| const codeElement = document.createElement('div'); | |
| codeElement.className = 'py-1 border-b border-gray-200'; | |
| codeElement.innerHTML = ` | |
| <span class="font-mono">${code}</span> | |
| <span class="text-gray-500 text-xs ml-2">${new Date().toLocaleTimeString()}</span> | |
| `; | |
| recentCodesDiv.prepend(codeElement); | |
| // Start countdown timer (5 minutes) | |
| let minutes = 4; | |
| let seconds = 59; | |
| document.getElementById('code-expiry').textContent = '5:00'; | |
| if (expiryInterval) clearInterval(expiryInterval); | |
| expiryInterval = setInterval(() => { | |
| if (seconds === 0) { | |
| if (minutes === 0) { | |
| clearInterval(expiryInterval); | |
| document.getElementById('code-expiry').textContent = 'Expired'; | |
| currentCode = null; | |
| return; | |
| } | |
| minutes--; | |
| seconds = 59; | |
| } else { | |
| seconds--; | |
| } | |
| const formattedSeconds = seconds < 10 ? `0${seconds}` : seconds; | |
| document.getElementById('code-expiry').textContent = `${minutes}:${formattedSeconds}`; | |
| }, 1000); | |
| } | |
| function copyCode() { | |
| if (!currentCode) { | |
| alert('No code generated yet'); | |
| return; | |
| } | |
| navigator.clipboard.writeText(currentCode.toString()) | |
| .then(() => alert('Code copied to clipboard')) | |
| .catch(() => alert('Failed to copy code')); | |
| } | |
| // Login function | |
| function login() { | |
| const code = document.getElementById('code').value; | |
| if (code) { | |
| // In a real app, you would verify with backend | |
| document.getElementById('login-screen').classList.add('hidden'); | |
| document.getElementById('app-interface').classList.remove('hidden'); | |
| } else { | |
| alert('Please enter both phone number and verification code'); | |
| } | |
| } | |
| // Tab switching | |
| function showTab(tabName) { | |
| if (tabName === 'posts') { | |
| document.getElementById('posts-tab').classList.remove('hidden'); | |
| document.getElementById('messages-tab').classList.add('hidden'); | |
| // Update active tab styling | |
| document.querySelectorAll('.flex.border-b button').forEach(btn => { | |
| if (btn.textContent.includes('Posts')) { | |
| btn.classList.add('text-blue-600', 'border-blue-600'); | |
| btn.classList.remove('text-gray-500'); | |
| } else { | |
| btn.classList.remove('text-blue-600', 'border-blue-600'); | |
| btn.classList.add('text-gray-500'); | |
| } | |
| }); | |
| } else { | |
| document.getElementById('posts-tab').classList.add('hidden'); | |
| document.getElementById('messages-tab').classList.remove('hidden'); | |
| // Update active tab styling | |
| document.querySelectorAll('.flex.border-b button').forEach(btn => { | |
| if (btn.textContent.includes('Messages')) { | |
| btn.classList.add('text-blue-600', 'border-blue-600'); | |
| btn.classList.remove('text-gray-500'); | |
| } else { | |
| btn.classList.remove('text-blue-600', 'border-blue-600'); | |
| btn.classList.add('text-gray-500'); | |
| } | |
| }); | |
| } | |
| } | |
| // Show/hide Kotlin code | |
| function showKotlinCode() { | |
| document.getElementById('kotlin-code').classList.remove('hidden'); | |
| } | |
| function hideKotlinCode() { | |
| document.getElementById('kotlin-code').classList.add('hidden'); | |
| } | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=ayham909/https-huggingface-co-organizations-towhed" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |