Files
www/membership/templates/profile.html
T
2026-10-29 13:28:11 -04:00

122 lines
9.0 KiB
HTML
Executable File

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex">
<title>Your profile · eom.dev</title>
<link rel="stylesheet" href="/static/home.css">
<link rel="stylesheet" href="/static/membership.css">
<link rel="icon" href="/static/favicon.svg" type="image/svg+xml">
</head>
<body>
<header class="member-nav">
<a class="brand" href="/">eom.dev</a>
<nav aria-label="Membership navigation"><a href="#main-content">Skip to content</a><a href="{% url 'members:home' %}">Membership</a></nav>
</header>
<main id="main-content" class="member-main profile-main">
<header class="profile-heading">
<p class="eyebrow">One account. Your own identity.</p>
<h1>Your profile</h1>
<p>Your profile is shared across eom.dev services. Your gamer tag is also reused by gaming services. Add only information you want to share with those services.</p>
{% if account %}<p class="member-small">Signed in as <strong>{{ account.uid }}</strong>. Your username cannot be changed here.</p>{% endif %}
</header>
{% if saved %}<p class="member-notice" role="status">Your changes have been saved.</p>{% endif %}
{% if email_sent %}<p class="member-notice" role="status">Check your new email inbox for a verification link. Your stored email addresses stay unchanged until you confirm.</p>{% endif %}
{% if confirm_email %}
<section class="member-panel profile-section" aria-labelledby="confirm-heading">
<h2 id="confirm-heading">Confirm your new email</h2>
<p>{% if confirmation_email %}Confirm <strong>{{ confirmation_email }}</strong> as your email address. {% endif %}After verification, this replaces all currently stored email addresses with the new address.</p>
<p>Enter your current password to finish. Opening this link alone does not change your account.</p>
<form method="post">
{% csrf_token %}
{% if confirmation_form.non_field_errors %}<div class="profile-errors" role="alert">{{ confirmation_form.non_field_errors }}</div>{% endif %}
{% include "profile_fields.html" with fields=confirmation_form only %}
<button class="button button-primary" type="submit">Confirm email change</button>
</form>
</section>
{% elif not profile_loaded %}
<section class="member-panel profile-section" aria-labelledby="unavailable-heading">
<h2 id="unavailable-heading">Your profile is temporarily unavailable</h2>
<p>We could not load your stored profile. Editing is unavailable so that missing data cannot overwrite your details. Please try again later.</p>
<a class="button button-secondary" href="{% url 'members:profile' %}">Try loading again</a>
</section>
{% else %}
<nav class="profile-jump-links" aria-label="Profile sections">
<a href="#identity">Identity</a><a href="#contact">Contact</a><a href="#addresses">Addresses</a><a href="#security">SSH keys</a><a href="#email">Email</a><a href="#password">Password</a>
</nav>
<form action="{% url 'members:profile' %}" method="post" enctype="multipart/form-data" class="profile-edit-form">
{% csrf_token %}
<input type="hidden" name="action" value="profile">
<input type="hidden" name="revision" value="{{ revision }}">
{% if form.errors %}<div class="profile-errors" role="alert"><h2>Check your profile details</h2><p>No profile changes have been saved. Correct the fields marked below and enter your current password again.</p>{{ form.non_field_errors }}</div>{% endif %}
<fieldset id="identity" class="member-panel profile-section">
<legend>Identity</legend>
<p>Tell the community who you are. Last name is required. Text fields support multiple values: one per line, up to 16 per field. Blank optional fields are cleared when you save.</p>
{% include "profile_fields.html" with fields=form.identity_fields only %}
{% if has_photo %}<figure class="profile-photo"><img src="{% url 'members:profile_photo' %}" width="128" height="128" alt="Your current profile photo"><figcaption>Current profile photo</figcaption></figure>{% endif %}
<div class="profile-field">
{{ form.jpegPhoto.label_tag }}
<p class="helptext" id="{{ form.jpegPhoto.auto_id }}_helptext">{{ form.jpegPhoto.help_text }}</p>
{{ form.jpegPhoto }}
{% if form.jpegPhoto.errors %}<div id="{{ form.jpegPhoto.auto_id }}_error" role="alert">{{ form.jpegPhoto.errors }}</div>{% endif %}
</div>
<div class="profile-field profile-checkbox">{{ form.remove_photo }} {{ form.remove_photo.label_tag }}{% if form.remove_photo.errors %}<div id="{{ form.remove_photo.auto_id }}_error" role="alert">{{ form.remove_photo.errors }}</div>{% endif %}</div>
<p class="member-small">Leave the photo field empty to keep your photo. To remove it, select the checkbox without uploading a replacement.</p>
</fieldset>
<fieldset id="contact" class="member-panel profile-section">
<legend>Contact</legend>
<p>Choose the websites and phone numbers to share. Email changes are verified separately below.</p>
{% include "profile_fields.html" with fields=form.contact_fields only %}
</fieldset>
<fieldset id="addresses" class="member-panel profile-section">
<legend>Addresses</legend>
<p>Address details are optional. For postal addresses, use a blank line between entries; other fields use one value per line.</p>
{% include "profile_fields.html" with fields=form.address_fields only %}
</fieldset>
<fieldset id="security" class="member-panel profile-section">
<legend>SSH keys</legend>
<p>Share public keys only. Never paste a private key or a password here.</p>
<div class="profile-field">
{{ form.sshPublicKey.label_tag }}
<p class="helptext" id="{{ form.sshPublicKey.auto_id }}_helptext">{{ form.sshPublicKey.help_text }}</p>
{{ form.sshPublicKey }}
{% if form.sshPublicKey.errors %}<div id="{{ form.sshPublicKey.auto_id }}_error" role="alert">{{ form.sshPublicKey.errors }}</div>{% endif %}
</div>
</fieldset>
<fieldset class="member-panel profile-section">
<legend>Authorize profile changes</legend>
{% include "profile_fields.html" with fields=form.authorization_fields only %}
<button class="button button-primary" type="submit">Save profile</button>
</fieldset>
</form>
<section id="email" class="member-panel profile-section" aria-labelledby="email-heading">
<h2 id="email-heading">Email address</h2>
<p>Currently stored email addresses (read-only):</p>
<ul class="profile-email-values">{% for email in email_values %}<li>{{ email }}</li>{% empty %}<li>No email address stored.</li>{% endfor %}</ul>
<p>A verified change replaces <strong>all</strong> currently stored email addresses with the new address. We will email a verification link to the new address; nothing changes until you confirm it with your current password.</p>
<form action="{% url 'members:profile' %}" method="post">
{% csrf_token %}<input type="hidden" name="action" value="email">
{% if email_form.non_field_errors %}<div class="profile-errors" role="alert">{{ email_form.non_field_errors }}</div>{% endif %}
{% include "profile_fields.html" with fields=email_form only %}
<button class="button button-primary" type="submit">Send verification email</button>
</form>
</section>
<section id="password" class="member-panel profile-section" aria-labelledby="password-heading">
<h2 id="password-heading">Password</h2>
<p>Choose a strong, unique password for your shared eom.dev account. Your current password is needed to authorize the change. Spaces in passwords are preserved.</p>
<p class="member-small">Password hashing policy is controlled by the server. Legacy MD5Crypt is insecure; changing a password here does not guarantee that the server upgrades its hashing policy.</p>
<form action="{% url 'members:profile' %}" method="post">
{% csrf_token %}<input type="hidden" name="action" value="password">
{% if password_form.non_field_errors %}<div class="profile-errors" role="alert">{{ password_form.non_field_errors }}</div>{% endif %}
{% include "profile_fields.html" with fields=password_form only %}
<button class="button button-primary" type="submit">Change password</button>
</form>
</section>
{% endif %}
<p class="profile-back"><a href="{% url 'members:home' %}">Back to membership</a></p>
</main>
<footer class="member-footer">Your account. Across the community. <a href="{% url 'members:home' %}">Membership</a></footer>
</body>
</html>