| | <!DOCTYPE html> |
| | <html lang="fr"> |
| |
|
| | <head> |
| | <meta charset="UTF-8"> |
| | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| | <title>Zauth - Create Account</title> |
| | <script src="https://cdn.tailwindcss.com"></script> |
| | <script src="https://unpkg.com/scrollreveal"></script> |
| | <link href="https://fonts.googleapis.com/css2?family=GeistMono:wght@400;700&family=Playfair+Display:wght@400;700&family=Inter:wght@300;400;500&display=swap" rel="stylesheet"> |
| | <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet"> |
| | <link rel="stylesheet" href="/static/css/styles.css"> |
| | </head> |
| |
|
| | <body class="bg-gray-900 text-white min-h-screen flex flex-col" style="background-image: url('/static/images/background.jpg');"> |
| | |
| | |
| | <header class="container mx-auto p-6"> |
| | <h1 class="text-4xl font-bold text-left text-white icon-geistmono">Zauth.</h1> |
| | </header> |
| |
|
| | <main class="flex-grow container mx-auto p-6 flex flex-col lg:flex-row items-center justify-center space-y-8 lg:space-y-0 lg:space-x-12"> |
| | |
| | |
| | <div class="max-w-md w-full p-6 lg:p-0 lg:w-1/2 flex flex-col items-center video-reveal"> |
| | <div class="relative"> |
| | <video id="video-preview" autoplay muted class="w-full max-w-md max-h-md aspect-square bg-black rounded-full object-cover shadow-2xl ring-4 ring-gray-300 ring-opacity-50 hover:ring-blue-500 hover:ring-opacity-75 transition-all duration-300 ease-in-out transform hover:scale-105"></video> |
| |
|
| | |
| | <div id="rec-indicator" class="hidden absolute top-2 right-2 w-4 h-4 bg-red-600 rounded-full animate-pulse"></div> |
| | </div> |
| |
|
| | |
| | <div class="text-center mt-6"> |
| | <button type="button" id="start-recording" class="bg-red-600 hover:bg-red-700 text-white font-bold w-16 h-16 rounded-full flex items-center justify-center animate-pulse hover:scale-110 active:scale-95 transition-all duration-300 ease-in-out"> |
| | <i class="fas fa-video"></i> |
| | </button> |
| | </div> |
| | </div> |
| |
|
| | |
| | <div class="max-w-md w-full bg-gray-800/40 backdrop-blur-md rounded-xl shadow-lg p-6 lg:w-1/2 transform transition-all duration-300 hover:scale-102 hover:shadow-md form-reveal"> |
| | <form id="create-account-form" method="POST" action="/submitAccount" class="space-y-6" enctype="multipart/form-data"> |
| | <div> |
| | <label for="email" class="block text-sm font-medium text-gray-300 icon-geistmono">Email Address</label> |
| | <input type="email" id="email" name="email" required class="w-full px-4 py-3 mt-2 bg-gray-700 text-white rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50 transition duration-300 ease-in-out"> |
| | </div> |
| | <button type="submit" class="w-full bg-green-600 hover:bg-green-700 text-white font-bold py-3 px-4 rounded-lg transition-all duration-300 ease-in-out transform hover:scale-102 icon-geistmono"> |
| | Create Account 🔐 |
| | </button> |
| | </form> |
| | <div id="error-message" class="mt-4 text-center text-red-500"></div> |
| | </div> |
| | </main> |
| | |
| | |
| | |
| | |
| |
|
| | <script> |
| | document.addEventListener('DOMContentLoaded', function() { |
| | |
| | ScrollReveal().reveal('.video-reveal', { |
| | duration: 1200, |
| | scale: 0.9, |
| | distance: '30px', |
| | origin: 'bottom', |
| | opacity: 0, |
| | easing: 'ease-in-out', |
| | delay: 200 |
| | }); |
| | |
| | |
| | ScrollReveal().reveal('.form-reveal', { |
| | duration: 1200, |
| | distance: '60px', |
| | origin: 'right', |
| | opacity: 0, |
| | easing: 'ease-in-out', |
| | delay: 400 |
| | }); |
| | |
| | |
| | ScrollReveal().reveal('header h1', { |
| | duration: 1000, |
| | origin: 'left', |
| | distance: '50px', |
| | opacity: 0, |
| | easing: 'ease-in-out', |
| | delay: 100 |
| | }); |
| | |
| | |
| | fillEmailFromUrl(); |
| | startCamera(); |
| | }); |
| | |
| | |
| | function fillEmailFromUrl() { |
| | const urlParams = new URLSearchParams(window.location.search); |
| | const email = urlParams.get('email'); |
| | if (email) { |
| | document.getElementById('email').value = decodeURIComponent(email); |
| | } |
| | } |
| | |
| | |
| | window.onload = function () { |
| | fillEmailFromUrl(); |
| | startCamera(); |
| | }; |
| | |
| | let mediaRecorder; |
| | let recordedChunks = []; |
| | let stream; |
| | let isRecording = false; |
| | const recIndicator = document.getElementById('rec-indicator'); |
| | |
| | |
| | async function startCamera() { |
| | const videoPreview = document.getElementById('video-preview'); |
| | |
| | if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { |
| | try { |
| | stream = await navigator.mediaDevices.getUserMedia({ video: true }); |
| | videoPreview.srcObject = stream; |
| | } catch (error) { |
| | console.error('Erreur lors de l\'accès à la caméra:', error); |
| | document.getElementById('error-message').innerText = 'Erreur lors de l\'accès à la caméra. Veuillez vérifier vos permissions.'; |
| | } |
| | } else { |
| | document.getElementById('error-message').innerText = 'Votre navigateur ne supporte pas l\'accès à la caméra.'; |
| | } |
| | } |
| | |
| | document.getElementById('start-recording').addEventListener('click', function () { |
| | if (stream) { |
| | if (!isRecording) { |
| | |
| | mediaRecorder = new MediaRecorder(stream); |
| | recordedChunks = []; |
| | |
| | mediaRecorder.ondataavailable = function (event) { |
| | if (event.data.size > 0) { |
| | recordedChunks.push(event.data); |
| | } |
| | }; |
| | |
| | mediaRecorder.start(); |
| | isRecording = true; |
| | recIndicator.classList.remove('hidden'); |
| | |
| | |
| | this.classList.remove('bg-red-600', 'hover:bg-red-700'); |
| | this.classList.add('bg-red-700', 'animate-pulse'); |
| | this.innerHTML = '<i class="fas fa-stop-circle"></i>'; |
| | |
| | |
| | setTimeout(() => { |
| | if (isRecording) { |
| | stopRecording(); |
| | } |
| | }, 5000); |
| | } else { |
| | |
| | stopRecording(); |
| | } |
| | } else { |
| | document.getElementById('error-message').innerText = 'Camera is not accessible. Please refresh the page.'; |
| | } |
| | }); |
| | |
| | function stopRecording() { |
| | mediaRecorder.stop(); |
| | isRecording = false; |
| | recIndicator.classList.add('hidden'); |
| | |
| | |
| | const recordButton = document.getElementById('start-recording'); |
| | recordButton.classList.remove('bg-red-700', 'animate-pulse'); |
| | recordButton.classList.add('bg-red-600', 'hover:bg-red-700'); |
| | recordButton.innerHTML = '<i class="fas fa-video"></i>'; |
| | } |
| | |
| | document.getElementById('create-account-form').addEventListener('submit', async function (event) { |
| | event.preventDefault(); |
| | |
| | const email = document.getElementById('email').value; |
| | |
| | |
| | const formData = new FormData(); |
| | formData.append('email', email); |
| | |
| | |
| | const blob = new Blob(recordedChunks, { type: 'video/webm' }); |
| | formData.append('video', blob, 'video_user.webm'); |
| | |
| | try { |
| | const response = await fetch('/submitAccount', { |
| | method: 'POST', |
| | body: formData |
| | }); |
| | |
| | if (response.ok) { |
| | window.location.href = '/index'; |
| | } else { |
| | const errorData = await response.json(); |
| | document.getElementById('error-message').innerText = `Error occurred while creating the account: ${errorData.detail || 'Unknown error'}`; |
| | } |
| | } catch (error) { |
| | document.getElementById('error-message').innerText = 'Une erreur est survenue. Veuillez réessayer.'; |
| | console.error('Error while submitting the form:', error); |
| | } |
| | }); |
| | </script> |
| | </body> |
| |
|
| | </html> |
| |
|