| {% extends "base.html" %} |
|
|
| {% block title %}Profile β ICH Screening{% endblock %} |
|
|
| {% block content %} |
| <div class="profile-page"> |
|
|
| |
| <div class="profile-hero"> |
| <div class="profile-avatar-wrapper"> |
| {% if user.avatar_url %} |
| <img src="{{ user.avatar_url }}" alt="User avatar" class="profile-avatar-img"> |
| {% else %} |
| <div class="profile-avatar" aria-label="User avatar"> |
| {{ user.username[0].upper() }} |
| </div> |
| {% endif %} |
| <button class="avatar-upload-btn" onclick="document.getElementById('avatarUpload').click()" title="Change Avatar"> |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#ffffff" stroke-width="2.5"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg> |
| </button> |
| <input type="file" id="avatarUpload" accept="image/*" style="display: none;"> |
| </div> |
| <div class="profile-identity"> |
| <h2>{{ user.full_name or user.username }}</h2> |
| <div class="profile-email">{{ user.email }}</div> |
| <span class="profile-badge"> |
| <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg> |
| Member since {{ user.created_at.strftime('%B %Y') }} |
| </span> |
| </div> |
| </div> |
|
|
| <div id="profileMessage" class="profile-message-container"></div> |
|
|
| |
| <div class="profile-section"> |
| <h3> |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg> |
| Account Information |
| </h3> |
| |
| <div class="profile-row"> |
| <span class="pr-label">Username</span> |
| <span class="pr-value" id="val-username">{{ user.username }}</span> |
| <button class="btn-inline-edit" onclick="openEditModal('username', '{{ user.username }}')">Edit</button> |
| </div> |
|
|
| <div class="profile-row"> |
| <span class="pr-label">Email</span> |
| <span class="pr-value" id="val-email">{{ user.email }}</span> |
| <button class="btn-inline-edit" onclick="openEditModal('email', '{{ user.email }}')">Edit</button> |
| </div> |
| |
| <div class="profile-row"> |
| <span class="pr-label">Full Name</span> |
| <span class="pr-value" id="val-full_name">{{ user.full_name or '' }}</span> |
| <button class="btn-inline-edit" onclick="openEditModal('full_name', '{{ user.full_name or '' }}')">Edit</button> |
| </div> |
| |
| <div class="profile-row"> |
| <span class="pr-label">Account Status</span> |
| <span class="pr-value" style="color:#34d399;"> |
| <svg width="11" height="11" viewBox="0 0 24 24" fill="currentColor" style="margin-right:4px;vertical-align:middle"><circle cx="12" cy="12" r="10"/></svg> |
| Active |
| </span> |
| </div> |
| |
| <div class="profile-row"> |
| <span class="pr-label">Member Since</span> |
| <span class="pr-value">{{ user.created_at.strftime('%B %d, %Y') }}</span> |
| </div> |
| </div> |
|
|
| |
| <div class="profile-section"> |
| <h3> |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg> |
| Security |
| </h3> |
|
|
| <div id="pwMessage"></div> |
|
|
| <div class="pw-change-section"> |
| <button class="pw-toggle-btn" id="pwToggleBtn" type="button"> |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg> |
| Change Password |
| </button> |
|
|
| <div class="pw-change-fields" id="pwFields"> |
| <form id="changePasswordForm" class="auth-form" style="gap:12px;" |
| data-change-password-url="{{ url_for('auth.change_password') }}"> |
| <div class="form-group"> |
| <label for="currentPassword">Current Password</label> |
| <div class="input-wrap"> |
| <svg class="input-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg> |
| <input type="password" id="currentPassword" name="current_password" required |
| class="has-toggle" placeholder="Enter current password"/> |
| <button type="button" class="btn-pw-toggle" id="toggleCur" aria-label="Toggle"> |
| <svg id="eyeCur" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg> |
| </button> |
| </div> |
| </div> |
| <div class="form-group"> |
| <label for="newPassword">New Password</label> |
| <div class="input-wrap"> |
| <svg class="input-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg> |
| <input type="password" id="newPassword" name="new_password" required |
| class="has-toggle" placeholder="8+ chars, upper, lower, digit"/> |
| <button type="button" class="btn-pw-toggle" id="toggleNew" aria-label="Toggle"> |
| <svg id="eyeNew" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg> |
| </button> |
| </div> |
| <div class="pw-strength-bar"><div class="pw-strength-fill" id="profilePwBar"></div></div> |
| <span class="pw-strength-text" id="profilePwText"></span> |
| </div> |
| <div class="form-group"> |
| <label for="confirmPassword">Confirm New Password</label> |
| <div class="input-wrap"> |
| <svg class="input-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg> |
| <input type="password" id="confirmPassword" name="confirm_password" required |
| class="has-toggle" placeholder="Re-enter new password"/> |
| </div> |
| </div> |
| <div class="pw-action-row"> |
| <button type="submit" class="btn-save-pw">Update Password</button> |
| <button type="button" class="btn-cancel-pw" id="pwCancelBtn">Cancel</button> |
| </div> |
| </form> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="profile-section profile-danger"> |
| <h3> |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg> |
| Account Actions |
| </h3> |
| <form method="POST" action="{{ url_for('auth.logout') }}" style="display:inline-block; margin-right: 12px;"> |
| <button type="submit" class="btn-logout-danger" style="background:#1e293b; border-color:#334155; color:#f8fafc;"> |
| <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg> |
| Sign Out |
| </button> |
| </form> |
| |
| <button class="btn-logout-danger" onclick="openDeleteModal()" style="display:inline-block;"> |
| <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg> |
| Delete Account |
| </button> |
| </div> |
|
|
| </div> |
|
|
| |
|
|
| |
| <div class="modal-overlay" id="editModal" style="display: none;"> |
| <div class="profile-modal-content auth-card"> |
| <div class="auth-card-header" style="margin-bottom:20px;"> |
| <h2 id="editModalTitle">Edit Field</h2> |
| </div> |
| |
| <form id="editFieldForm" class="auth-form"> |
| <input type="hidden" id="editFieldType"> |
| |
| |
| <div id="editStep1"> |
| <div class="form-group"> |
| <label id="editFieldLabel">New Value</label> |
| <div class="input-wrap"> |
| <input type="text" id="editFieldValue" required> |
| </div> |
| </div> |
| <div class="pw-action-row" style="margin-top:20px;"> |
| <button type="submit" class="btn-save-pw" id="btnRequestChange">Save Changes</button> |
| <button type="button" class="btn-cancel-pw" onclick="closeEditModal()">Cancel</button> |
| </div> |
| </div> |
|
|
| |
| <div id="editStep2" style="display: none;"> |
| <p style="color:#94a3b8;font-size:14px;margin-bottom:16px;">We've sent a verification code to confirm this change.</p> |
| <div class="form-group"> |
| <label>6-Digit Code</label> |
| <div class="input-wrap"> |
| <input type="text" id="editFieldOtp" maxlength="6" inputmode="numeric" placeholder="123456"> |
| </div> |
| </div> |
| <input type="hidden" id="editFieldOtpToken"> |
| <div class="pw-action-row" style="margin-top:20px;"> |
| <button type="button" class="btn-save-pw" id="btnConfirmChange">Verify & Update</button> |
| <button type="button" class="btn-cancel-pw" onclick="closeEditModal()">Cancel</button> |
| </div> |
| </div> |
| </form> |
| </div> |
| </div> |
|
|
| |
| <div class="modal-overlay" id="deleteModal" style="display: none;"> |
| <div class="profile-modal-content auth-card"> |
| <div class="auth-card-header" style="margin-bottom:20px;"> |
| <h2 style="color:#ef4444;">Delete Account</h2> |
| <p style="color:#fca5a5; font-size:13px; margin-top:8px;">This action is permanent and cannot be undone.</p> |
| </div> |
| <form method="POST" action="{{ url_for('auth.delete_account') }}" class="auth-form"> |
| <div class="form-group"> |
| <label>Enter your password to confirm</label> |
| <div class="input-wrap"> |
| <svg class="input-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg> |
| <input type="password" name="password" required> |
| </div> |
| </div> |
| <div class="pw-action-row" style="margin-top:20px;"> |
| <button type="submit" class="btn-save-pw" style="background:#dc2626; border-color:#b91c1c;">Permanently Delete</button> |
| <button type="button" class="btn-cancel-pw" onclick="closeDeleteModal()">Cancel</button> |
| </div> |
| </form> |
| </div> |
| </div> |
|
|
| {% endblock %} |
|
|
| {% block scripts %} |
| <script src="{{ url_for('static', filename='js/auth-shared.js') }}" defer></script> |
| <script src="{{ url_for('static', filename='js/profile.js') }}" defer></script> |
| <script src="{{ url_for('static', filename='js/profile-page.js') }}" defer></script> |
| <script src="{{ url_for('static', filename='js/profile-actions.js') }}" defer></script> |
| {% endblock %} |
|
|