| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Verification | Rainbow Rendezvous</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <script src="https://unpkg.com/feather-icons"></script> |
| <style> |
| @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap'); |
| body { |
| font-family: 'Poppins', sans-serif; |
| background-color: #000000; |
| color: #FFFFFF; |
| } |
| .verification-container { |
| background: linear-gradient(180deg, #0A0A0A 0%, #000000 100%); |
| } |
| .verification-circle { |
| border: 3px dashed #F4C430; |
| background-color: rgba(244, 196, 48, 0.05); |
| } |
| .verification-btn { |
| background-color: #F4C430; |
| color: #000000; |
| box-shadow: 0 4px 15px rgba(244, 196, 48, 0.4); |
| } |
| .verification-btn:hover { |
| background-color: #F4C430; |
| transform: translateY(-2px); |
| } |
| .silhouette-overlay { |
| background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="M50 15c-10 0-15 5-15 15 0 5 5 10 5 15 0 5-5 10-5 15 0 10 10 25 15 25s15-15 15-25c0-5-5-10-5-15 0-5 5-10 5-15 0-10-5-15-15-15z" fill="none" stroke="%23F4C430" stroke-width="0.5"/></svg>'); |
| background-size: 60%; |
| background-position: center; |
| background-repeat: no-repeat; |
| opacity: 0.5; |
| } |
| </style> |
| </head> |
| <body class="min-h-screen verification-container"> |
| <div class="max-w-md mx-auto min-h-screen flex flex-col px-6 py-12"> |
| <header class="mb-8"> |
| <div class="flex justify-center mb-6"> |
| <div class="w-16 h-16 bg-yellow-500 rounded-full flex items-center justify-center"> |
| <i data-feather="shield" class="text-black w-8 h-8"></i> |
| </div> |
| </div> |
| <h1 class="text-2xl font-bold text-center text-yellow-500 mb-2">Photo Verification</h1> |
| <p class="text-center text-white/80">Secure your profile and help protect our community</p> |
| </header> |
|
|
| <main class="flex-1 flex flex-col"> |
| <div class="relative mb-8"> |
| <div class="verification-circle w-full aspect-square rounded-full mx-auto overflow-hidden relative"> |
| <div class="absolute inset-0 silhouette-overlay"></div> |
| <video id="cameraFeed" autoplay playsinline class="w-full h-full object-cover"></video> |
| </div> |
| <div class="absolute bottom-4 left-0 right-0 flex justify-center"> |
| <button id="flipCamera" class="bg-black/50 text-white p-2 rounded-full"> |
| <i data-feather="refresh-ccw" class="w-5 h-5"></i> |
| </button> |
| </div> |
| </div> |
|
|
| <div class="text-center mb-8"> |
| <h2 class="font-medium text-white mb-2">Follow these steps:</h2> |
| <div class="flex justify-center space-x-4 mb-4"> |
| <div class="flex items-center"> |
| <div class="w-8 h-8 rounded-full bg-yellow-500 text-black flex items-center justify-center mr-2">1</div> |
| <span class="text-sm">Remove sunglasses</span> |
| </div> |
| <div class="flex items-center"> |
| <div class="w-8 h-8 rounded-full bg-yellow-500 text-black flex items-center justify-center mr-2">2</div> |
| <span class="text-sm">Face forward</span> |
| </div> |
| </div> |
| </div> |
| <button id="captureBtn" class="verification-btn py-4 px-6 rounded-full font-bold text-lg mb-4 transition-transform"> |
| Take Photo |
| </button> |
| <a href="index.html" class="text-white/60 text-center w-full py-2"> |
| Skip for now |
| </a> |
| </main> |
| </div> |
|
|
| <script> |
| |
| let currentFacingMode = "user"; |
| let stream = null; |
| |
| async function startCamera(facingMode = "user") { |
| try { |
| if (stream) { |
| stream.getTracks().forEach(track => track.stop()); |
| } |
| |
| stream = await navigator.mediaDevices.getUserMedia({ |
| video: { |
| facingMode: facingMode, |
| width: { ideal: 1280 }, |
| height: { ideal: 1280 } |
| }, |
| audio: false |
| }); |
| |
| const videoElement = document.getElementById('cameraFeed'); |
| videoElement.srcObject = stream; |
| currentFacingMode = facingMode; |
| } catch (err) { |
| console.error("Error accessing camera:", err); |
| alert("Could not access the camera. Please check permissions."); |
| } |
| } |
| |
| |
| document.getElementById('flipCamera').addEventListener('click', () => { |
| const newFacingMode = currentFacingMode === "user" ? "environment" : "user"; |
| startCamera(newFacingMode); |
| }); |
| |
| document.getElementById('captureBtn').addEventListener('click', async () => { |
| try { |
| const video = document.getElementById('cameraFeed'); |
| const canvas = document.createElement('canvas'); |
| canvas.width = video.videoWidth; |
| canvas.height = video.videoHeight; |
| const ctx = canvas.getContext('2d'); |
| ctx.drawImage(video, 0, 0, canvas.width, canvas.height); |
| |
| |
| canvas.toBlob((blob) => { |
| const formData = new FormData(); |
| formData.append('verification_photo', blob, 'verification.jpg'); |
| |
| |
| setTimeout(() => { |
| alert("Verification photo submitted successfully!"); |
| window.location.href = "index.html"; |
| }, 1000); |
| }, 'image/jpeg', 0.9); |
| |
| } catch (err) { |
| console.error("Error capturing photo:", err); |
| alert("Couldn't capture photo. Please try again."); |
| } |
| }); |
| |
| window.addEventListener('DOMContentLoaded', async () => { |
| try { |
| await startCamera(); |
| feather.replace(); |
| } catch (err) { |
| console.error("Camera initialization failed:", err); |
| |
| document.getElementById('captureBtn').disabled = true; |
| document.getElementById('captureBtn').textContent = "Camera Access Required"; |
| } |
| }); |
| |
| window.addEventListener('beforeunload', () => { |
| if (stream) { |
| stream.getTracks().forEach(track => track.stop()); |
| } |
| }); |
| </script> |
| </body> |
| </html> |
|
|