UNPKG

tspace-nfs

Version:

tspace-nfs is a Network File System (NFS) and provides both server and client capabilities for accessing files over a network.

101 lines (88 loc) 4.08 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>NFS-Studio</title> <style> #loading { display: none; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(255, 255, 255, 0.8); opacity: 0.75; justify-content: center; align-items: center; z-index: 9999; } </style> <script src="https://cdn.tailwindcss.com"></script> </head> <body class="bg-gray-100 dark:bg-gray-900"> <div id="loading" class="flex"> <div class="flex flex-col items-center"> <div class="animate-spin rounded-full h-20 w-20 border-t-4 border-b-4 border-blue-600"></div> <p class="text-gray-800 dark:text-gray-200 text-xl font-semibold mt-4">Loading...</p> </div> </div> <div class="flex items-center justify-center min-h-screen"> <div class="w-full max-w-md p-8 space-y-6 bg-white rounded-lg shadow-md dark:bg-gray-800"> <h2 class="text-3xl font-bold text-center text-gray-900 dark:text-gray-100">Login to Studio</h2> <form id="loginForm" class="space-y-6" novalidate> <div> <label for="username" class="block text-sm font-medium text-gray-700 dark:text-gray-300">username</label> <input type="username" id="username" name="username" required class="w-full p-2 mt-1 text-gray-900 border border-gray-300 rounded-md shadow-sm dark:bg-gray-700 dark:border-gray-600 dark:text-white focus:ring-indigo-500 focus:border-indigo-500"> </div> <div> <label for="password" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Password</label> <input type="password" id="password" name="password" required class="w-full p-2 mt-1 text-gray-900 border border-gray-300 rounded-md shadow-sm dark:bg-gray-700 dark:border-gray-600 dark:text-white focus:ring-indigo-500 focus:border-indigo-500"> </div> <div> <button type="submit" class="w-full py-2 text-white bg-indigo-600 rounded-md hover:bg-indigo-700 focus:ring-2 focus:ring-indigo-500">Login</button> </div> <div id="errorMessage" class="text-red-500 text-sm hidden">Invalid username or password. Please try again.</div> </form> </div> </div> </body> <script> const $ = (element) => document.querySelector(element) const loading = $('#loading') const loginForm = $('#loginForm'); const errorMessage = $('#errorMessage'); const url = `${window.location.protocol}//${window.location.host}` loginForm.addEventListener('submit', async (event) => { event.preventDefault(); const username = $('#username').value; const password = $('#password').value; try { loading.style.display = 'flex'; const response = await fetch(`${url}/studio/api/login`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ username, password }), }); if (response.ok) { const data = await response.json(); errorMessage.classList.add('hidden'); await new Promise(r => setTimeout(r, 1000)); loading.style.display = 'none' window.location.reload() return } await new Promise(r => setTimeout(r, 500)); loading.style.display = 'none'; errorMessage.classList.remove('hidden'); } catch (error) { errorMessage.textContent = 'An error occurred. Please try again later.'; errorMessage.classList.remove('hidden'); loading.style.display = 'flex'; } }) </script> </html>