Edit profile and templates update
All checks were successful
Rust / Test (push) Successful in 6m6s
Rust / Rustfmt (push) Successful in 22s
Rust / Clippy (push) Successful in 1m36s
Rust / Code coverage (push) Successful in 4m47s

This commit is contained in:
Alphonse Paix
2025-10-06 19:13:51 +02:00
parent da590fb7c6
commit b252216709
27 changed files with 596 additions and 262 deletions

View File

@@ -1,5 +1,5 @@
<div class="bg-white rounded-lg shadow-md border border-gray-200">
<h2 class="text-xl font-semibold text-gray-900 pb-4 pt-8 px-8">Activity</h2>
<h2 class="text-xl font-semibold text-gray-900 px-8 py-6 border-b border-gray-200">Activity</h2>
{% if posts.is_empty() %}
<div class="text-center text-gray-500 p-8">
<svg class="w-12 h-12 mx-auto mb-3 text-gray-400"
@@ -12,7 +12,7 @@
<p>No posts yet</p>
</div>
{% else %}
<div class="divide-y divide-gray-200 pb-8">
<div class="divide-y divide-gray-200">
{% for post in posts %}
<a href="/posts/{{ post.post_id }}"
class="block py-4 hover:bg-gray-50 px-8 transition-colors group">

15
templates/user/edit.html Normal file
View File

@@ -0,0 +1,15 @@
{% extends "base.html" %}
{% block title %}Edit profile{% endblock %}
{% block content %}
<div class="max-w-5xl mx-auto p-4 sm:p-6">
<div class="mb-8">
<h1 class="text-3xl font-bold text-gray-900">Edit Profile</h1>
<p class="mt-2 text-gray-600">Manage your profile and account settings.</p>
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
{% include "edit/update_profile.html" %}
{% include "edit/change_password.html" %}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,48 @@
<div class="bg-white rounded-lg shadow-md border border-gray-200 p-8">
<h2 class="text-xl font-semibold text-gray-900 mb-6">Change Password</h2>
<form hx-post="/password"
hx-target="#password-messages"
hx-swap="innerHTML"
class="space-y-4">
<div>
<label for="current_password"
class="block text-sm font-medium text-gray-700 mb-2">Current password</label>
<input type="password"
id="current_password"
name="current_password"
required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500"/>
</div>
<div>
<label for="new_password"
class="block text-sm font-medium text-gray-700 mb-2">New password</label>
<input type="password"
id="new_password"
name="new_password"
required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500"/>
</div>
<div>
<label for="new_password_check"
class="block text-sm font-medium text-gray-700 mb-2">Confirm new password</label>
<input type="password"
id="new_password_check"
name="new_password_check"
required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500"/>
</div>
<button type="submit"
class="w-full bg-green-600 text-white hover:bg-green-700 font-medium py-3 px-4 rounded-md transition-colors flex items-center justify-center">
<svg class="w-4 h-4 mr-2"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
</svg>
Update password
</button>
<div id="password-messages" class="mt-4"></div>
</form>
</div>

View File

@@ -0,0 +1,53 @@
<div class="bg-white rounded-lg shadow-md border border-gray-200 p-8">
<h2 class="text-xl font-semibold text-gray-900 mb-6">Profile Information</h2>
<form hx-put="/users/{{ user.username }}/edit"
hx-target="#edit-messages"
hx-swap="innerHTML"
class="space-y-6">
<div>
<label for="username" class="block text-sm font-medium text-gray-700 mb-1">
Username
</label>
<input type="text"
name="username"
id="username"
value="{{ user.username }}"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
</div>
<div>
<label for="full_name" class="block text-sm font-medium text-gray-700 mb-1">
Full Name
</label>
<input type="text"
id="full_name"
name="full_name"
value="{{ user.full_name.as_deref().unwrap_or("") }}"
placeholder="John Doe"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
<p class="mt-1 text-xs text-gray-500">Your real name (optional)</p>
</div>
<div>
<label for="bio" class="block text-sm font-medium text-gray-700 mb-1">
Bio
</label>
<textarea id="bio"
name="bio"
rows="4"
maxlength="500"
placeholder="Tell us about yourself..."
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">{{ user.bio.as_deref().unwrap_or("") }}</textarea>
<p class="mt-1 text-xs text-gray-500">Maximum 500 characters</p>
</div>
<button type="submit"
class="w-full bg-blue-600 text-white hover:bg-blue-700 font-medium py-2 px-4 rounded-md transition-colors">
Save Changes
</button>
<div id="edit-messages"></div>
</form>
</div>

View File

@@ -1,43 +1,55 @@
{% extends "base.html" %}
{% block title %}{{ user.username }}{% endblock %}
{% block content %}
<div class="max-w-4xl mx-auto p-4 sm:p-6">
<div class="bg-white rounded-lg shadow-md border border-gray-200 p-8 mb-6">
<div class="flex flex-col sm:flex-row items-center sm:items-start gap-6">
<div class="flex-shrink-0">
<div class="w-24 h-24 bg-gradient-to-br from-blue-500 to-indigo-600 rounded-full flex items-center justify-center text-white text-3xl font-bold shadow-lg">
{{ user.username }}
</div>
</div>
<div class="flex-1 text-center sm:text-left">
<div class="flex flex-col sm:flex-row sm:items-center gap-2 mb-2">
<h1 class="text-3xl font-bold text-gray-900">{{ user.full_name.as_deref().unwrap_or(user.username) }}</h1>
{% if user.is_admin() %}
<svg class="w-6 h-6 text-blue-600 flex-shrink-0 mx-auto sm:mx-0"
fill="currentColor"
viewBox="0 0 24 24">
<path d="M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm0 10.99h7c-.53 4.12-3.28 7.79-7 8.94V12H5V6.3l7-3.11v8.8z" />
</svg>
{% endif %}
</div>
<p class="text-gray-500 text-lg mb-3">@{{ user.username }}</p>
<div class="flex items-center justify-center sm:justify-start text-sm text-gray-500">
<svg class="w-4 h-4 mr-1.5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
</svg>
{{ user.formatted_date() }}
</div>
<div class="max-w-4xl mx-auto p-4 sm:p-6">
<div class="bg-white rounded-lg shadow-md border border-gray-200 p-8 mb-6">
<div class="flex flex-col sm:flex-row items-center sm:items-start gap-6">
<div class="flex-shrink-0">
<div class="w-24 h-24 bg-gradient-to-br from-blue-500 to-indigo-600 rounded-full flex items-center justify-center text-white text-3xl font-bold shadow-lg">
{{ user.username }}
</div>
</div>
{% if user.bio.is_some() %}
<div class="mt-6 pt-6 border-t border-gray-200">
<p class="text-gray-700 whitespace-pre-line">{{ user.bio.as_deref().unwrap() }}</p>
<div class="flex-1 text-center sm:text-left">
<div class="flex flex-col sm:flex-row sm:items-center gap-2 mb-2">
<h1 class="text-3xl font-bold text-gray-900">{{ user.full_name.as_deref().unwrap_or(user.username)
}}</h1>
{% if user.is_admin() %}
<svg class="w-6 h-6 text-blue-600 flex-shrink-0 mx-auto sm:mx-0"
fill="currentColor"
viewBox="0 0 24 24">
<path d="M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm0 10.99h7c-.53 4.12-3.28 7.79-7 8.94V12H5V6.3l7-3.11v8.8z"/>
</svg>
{% endif %}
</div>
{% endif %}
{% if session_username.as_deref() == Some(user.username) %}
<a href="/users/{{ user.username }}/edit"
class="inline-flex items-center text-sm text-blue-600 hover:text-blue-700 font-medium mb-3">
<svg class="w-4 h-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
</svg>
Edit
</a>
{% endif %}
<p class="text-gray-500 text-lg mb-3">@{{ user.username }}</p>
<div class="flex items-center justify-center sm:justify-start text-sm text-gray-500">
<svg class="w-4 h-4 mr-1.5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
</svg>
{{ user.formatted_date() }}
</div>
</div>
</div>
{% include "activity.html" %}
{% if user.bio.is_some() %}
<div class="mt-6 pt-6 border-t border-gray-200">
<p class="text-gray-700 whitespace-pre-line">{{ user.bio.as_deref().unwrap() }}</p>
</div>
{% endif %}
</div>
{% include "activity.html" %}
</div>
{% endblock %}