UNPKG

mcp-quiz-server

Version:

🧠 AI-Powered Quiz Management via Model Context Protocol (MCP) - Create, manage, and take quizzes directly from VS Code, Claude, and other AI agents.

182 lines (167 loc) • 9.07 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Register - MCP Quiz Server</title> <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet"> <script src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js" defer></script> </head> <body class="bg-gray-50"> <div class="min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8"> <div class="max-w-md w-full space-y-8" x-data="registerForm()"> <div> <h2 class="mt-6 text-center text-3xl font-extrabold text-gray-900"> Create your account </h2> <p class="mt-2 text-center text-sm text-gray-600"> Or <a href="/auth/login.html" class="font-medium text-blue-600 hover:text-blue-500"> sign in to existing account </a> </p> </div> <form class="mt-8 space-y-6" @submit.prevent="register()"> <div class="space-y-4"> <div class="grid grid-cols-2 gap-4"> <div> <label for="firstName" class="block text-sm font-medium text-gray-700">First Name</label> <input id="firstName" name="firstName" type="text" class="mt-1 appearance-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm" placeholder="First name" x-model="form.firstName" > </div> <div> <label for="lastName" class="block text-sm font-medium text-gray-700">Last Name</label> <input id="lastName" name="lastName" type="text" class="mt-1 appearance-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm" placeholder="Last name" x-model="form.lastName" > </div> </div> <div> <label for="username" class="block text-sm font-medium text-gray-700">Username</label> <input id="username" name="username" type="text" required class="mt-1 appearance-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm" placeholder="Username" x-model="form.username" > </div> <div> <label for="email" class="block text-sm font-medium text-gray-700">Email Address</label> <input id="email" name="email" type="email" required class="mt-1 appearance-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm" placeholder="Email address" x-model="form.email" > </div> <div> <label for="password" class="block text-sm font-medium text-gray-700">Password</label> <input id="password" name="password" type="password" required class="mt-1 appearance-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm" placeholder="Password" x-model="form.password" > <p class="mt-1 text-xs text-gray-500">Must contain uppercase, lowercase, number, and special character</p> </div> <div> <label for="role" class="block text-sm font-medium text-gray-700">Role</label> <select id="role" name="role" class="mt-1 block w-full px-3 py-2 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm" x-model="form.role" > <option value="student">Student</option> <option value="teacher">Teacher</option> </select> </div> </div> <div x-show="error" class="text-red-600 text-sm text-center" x-text="error"></div> <div x-show="success" class="text-green-600 text-sm text-center" x-text="success"></div> <div> <button type="submit" class="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50" :disabled="loading" > <span x-show="!loading">Create Account</span> <span x-show="loading" class="flex items-center"> <div class="animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2"></div> Creating account... </span> </button> </div> </form> </div> </div> <script> function registerForm() { return { form: { username: '', email: '', password: '', firstName: '', lastName: '', role: 'student' }, loading: false, error: '', success: '', async register() { this.loading = true; this.error = ''; this.success = ''; try { const response = await fetch('/auth/register', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(this.form) }); const data = await response.json(); if (data.success) { this.success = 'Account created successfully! Redirecting...'; // Store token in cookie for dashboard access document.cookie = `auth_token=${data.data.tokens.accessToken}; path=/; max-age=900`; // 15 minutes // Redirect to dashboard after a brief delay setTimeout(() => { window.location.href = '/dashboard'; }, 2000); } else { this.error = data.error?.message || 'Registration failed'; } } catch (error) { this.error = 'Network error. Please try again.'; console.error('Registration error:', error); } finally { this.loading = false; } } } } </script> </body> </html>