File size: 5,595 Bytes
9fc36aa e3566c9 ae34acf 9fc36aa e3566c9 9fc36aa e3566c9 9fc36aa 8e35842 9fc36aa 8e35842 9fc36aa 8e35842 9fc36aa 8e35842 9fc36aa | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | <!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Verify Email OTP — AI Medical Intelligence Pipeline</title>
<!-- Favicon -->
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='favicon.ico') }}" />
<link rel="icon" type="image/png" sizes="32x32" href="{{ url_for('static', filename='favicon-192.png') }}" />
<link rel="apple-touch-icon" sizes="180x180" href="{{ url_for('static', filename='apple-touch-icon.png') }}" />
<meta name="description" content="Verify your email with one-time password."/>
<link rel="preconnect" href="https://fonts.googleapis.com"/>
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"/>
<link rel="stylesheet" href="{{ url_for('static', filename='css/base.css') }}"/>
<link rel="stylesheet" href="{{ url_for('static', filename='css/auth.css') }}"/>
</head>
<body>
<div class="auth-page">
<aside class="auth-brand">
<div class="auth-brand-logo">
<div class="auth-brand-icon">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M22 12h-4l-3 9L9 3l-3 9H2"/>
</svg>
</div>
<span class="auth-brand-name">AI Medical Intelligence Pipeline</span>
</div>
<div class="auth-headline">
<h2>Check Your <span class="grad">Email</span></h2>
<p>We sent a 6-digit code to your inbox. Enter it below to verify your identity and activate your account.</p>
</div>
<ul class="auth-features">
<li><span class="feat-icon">1</span>Open the email from the AI Medical Intelligence Pipeline</li>
<li><span class="feat-icon">2</span>Copy the 6-digit code</li>
<li><span class="feat-icon">3</span>Enter it here — valid for 10 minutes</li>
</ul>
</aside>
<main class="auth-form-panel">
<div class="auth-card">
<div class="auth-card-header">
<h2>Enter your verification code</h2>
<p>Sent to <strong>{{ email or 'your registered email' }}</strong></p>
</div>
{# --- Notice banners rendered from URL param (cookie-free) --- #}
{% set notice = request.args.get('notice', '') %}
{% if notice == 'otp_sent' %}
<div class="alert alert-success">✅ Registration successful. A verification code was sent to your email.</div>
{% elif notice == 'otp_resent' %}
<div class="alert alert-success">✅ A fresh verification code was sent to your email.</div>
{% elif notice == 'otp_email_failed' %}
<div class="alert alert-info">⚠️ Account created, but the email could not be sent. Please use "Resend code" below.</div>
{% elif notice == 'invalid_digits' %}
<div class="alert alert-error">Please enter the full 6-digit code.</div>
{% elif notice == 'invalid_code' %}
<div class="alert alert-error">Invalid or expired code. Please try again or request a new one.</div>
{% endif %}
{# --- Legacy flash messages (still shown for local dev) --- #}
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<div class="auth-alerts">
{% for category, message in messages %}
<div class="alert alert-{{ category }}">{{ message }}</div>
{% endfor %}
</div>
{% endif %}
{% endwith %}
<form method="POST" class="auth-form" id="otpForm"
action="{{ url_for('auth.verify_otp', purpose=purpose, email=email, otp_token=otp_token) }}">
{# Carry the token in a hidden input so it survives the POST #}
<input type="hidden" name="otp_token" value="{{ otp_token }}"/>
<input type="hidden" name="otp" id="otpCombined"/>
<div class="otp-grid" style="display:grid;grid-template-columns:repeat(6,1fr);gap:10px;">
<input type="text" inputmode="numeric" maxlength="1" name="d1" class="otp-digit" autocomplete="off" required/>
<input type="text" inputmode="numeric" maxlength="1" name="d2" class="otp-digit" autocomplete="off" required/>
<input type="text" inputmode="numeric" maxlength="1" name="d3" class="otp-digit" autocomplete="off" required/>
<input type="text" inputmode="numeric" maxlength="1" name="d4" class="otp-digit" autocomplete="off" required/>
<input type="text" inputmode="numeric" maxlength="1" name="d5" class="otp-digit" autocomplete="off" required/>
<input type="text" inputmode="numeric" maxlength="1" name="d6" class="otp-digit" autocomplete="off" required/>
</div>
<button type="submit" class="btn-auth-submit" style="margin-top:16px;">Verify & Activate Account</button>
</form>
<form method="POST" action="{{ url_for('auth.resend_otp') }}" style="margin-top:12px;">
<input type="hidden" name="otp_token" value="{{ otp_token }}"/>
<input type="hidden" name="email" value="{{ email }}"/>
<input type="hidden" name="purpose" value="{{ purpose }}"/>
<button type="submit" class="btn-auth-submit" style="background:#0f1b31;border:1px solid #2a3f68;">Didn't receive it? Resend code</button>
</form>
<div class="auth-footer">
Wrong account? <a href="{{ url_for('auth.login') }}">Back to sign in</a>
</div>
</div>
</main>
</div>
<script src="{{ url_for('static', filename='js/verify-otp.js') }}" defer></script>
</body>
</html>
|