177 lines
9.9 KiB
HTML
177 lines
9.9 KiB
HTML
{% extends "common/base.html" %}
|
|
|
|
{% block content %}
|
|
<div class="container mx-auto px-4 py-8">
|
|
<div class="max-w-2xl mx-auto">
|
|
<div class="d-flex justify-content-between align-items-center mb-6">
|
|
<div>
|
|
<h3 class="mb-0">
|
|
<i class="fas fa-user me-2" style="color: var(--primary-color);"></i>
|
|
{% if title %}
|
|
{{ title }}
|
|
{% else %}
|
|
User Form
|
|
{% endif %}
|
|
</h3>
|
|
<p class="text-muted mb-0 mt-2 small">Add or edit contact information</p>
|
|
</div>
|
|
<a href="{{ url_for('contacts.contacts_list') }}"
|
|
class="btn btn-sm btn-outline-secondary">
|
|
<i class="fas fa-arrow-left me-1"></i>
|
|
Back to Contacts
|
|
</a>
|
|
</div>
|
|
|
|
<div class="bg-white rounded-lg shadow p-6">
|
|
<form method="POST" class="space-y-6" enctype="multipart/form-data">
|
|
{{ form.hidden_tag() }}
|
|
|
|
<!-- Profile Picture Upload (matches profile page style) -->
|
|
<div class="flex flex-col items-center mb-6">
|
|
<div class="relative group flex flex-col items-center">
|
|
<label for="profile_picture" class="cursor-pointer">
|
|
<img id="avatarPreview" src="{{ url_for('profile_pic', filename=form.profile_picture.data or user.profile_picture) if (form.profile_picture.data or (user and user.profile_picture)) else url_for('static', filename='default-avatar.png') }}" alt="Profile Picture" class="w-32 h-32 rounded-full object-cover border-4 border-gray-200 mb-0 transition duration-200 group-hover:opacity-80 group-hover:ring-4 group-hover:ring-primary-200 shadow-sm">
|
|
<input id="profile_picture" type="file" name="profile_picture" accept="image/*" class="hidden" onchange="previewAvatar(event)" />
|
|
</label>
|
|
{% if user and user.profile_picture %}
|
|
<button type="submit" name="remove_picture" value="1" class="mt-2 mb-2 text-xs px-3 py-1 rounded bg-red-100 text-red-700 border border-red-200 hover:bg-red-200 transition">Remove Picture</button>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<div>
|
|
{{ form.first_name.label(class="block text-sm font-medium text-gray-700 mb-1") }}
|
|
{{ form.first_name(class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500") }}
|
|
{% if form.first_name.errors %}
|
|
{% for error in form.first_name.errors %}
|
|
<p class="mt-1 text-sm text-red-600">{{ error }}</p>
|
|
{% endfor %}
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div>
|
|
{{ form.last_name.label(class="block text-sm font-medium text-gray-700 mb-1") }}
|
|
{{ form.last_name(class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500") }}
|
|
{% if form.last_name.errors %}
|
|
{% for error in form.last_name.errors %}
|
|
<p class="mt-1 text-sm text-red-600">{{ error }}</p>
|
|
{% endfor %}
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
{{ form.email.label(class="block text-sm font-medium text-gray-700 mb-1") }}
|
|
{{ form.email(class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500") }}
|
|
{% if form.email.errors %}
|
|
{% for error in form.email.errors %}
|
|
<p class="mt-1 text-sm text-red-600">{{ error }}</p>
|
|
{% endfor %}
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<div>
|
|
{{ form.phone.label(class="block text-sm font-medium text-gray-700 mb-1") }}
|
|
{{ form.phone(class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500") }}
|
|
{% if form.phone.errors %}
|
|
{% for error in form.phone.errors %}
|
|
<p class="mt-1 text-sm text-red-600">{{ error }}</p>
|
|
{% endfor %}
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div>
|
|
{{ form.company.label(class="block text-sm font-medium text-gray-700 mb-1") }}
|
|
{{ form.company(class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500") }}
|
|
{% if form.company.errors %}
|
|
{% for error in form.company.errors %}
|
|
<p class="mt-1 text-sm text-red-600">{{ error }}</p>
|
|
{% endfor %}
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
{{ form.position.label(class="block text-sm font-medium text-gray-700 mb-1") }}
|
|
{{ form.position(class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500") }}
|
|
{% if form.position.errors %}
|
|
{% for error in form.position.errors %}
|
|
<p class="mt-1 text-sm text-red-600">{{ error }}</p>
|
|
{% endfor %}
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div>
|
|
{{ form.notes.label(class="block text-sm font-medium text-gray-700 mb-1") }}
|
|
{{ form.notes(class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500", rows="4") }}
|
|
{% if form.notes.errors %}
|
|
{% for error in form.notes.errors %}
|
|
<p class="mt-1 text-sm text-red-600">{{ error }}</p>
|
|
{% endfor %}
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Role Selection Section -->
|
|
<div class="bg-gray-50 p-4 rounded-lg border border-gray-200">
|
|
<h4 class="text-lg font-medium text-gray-900 mb-4">Role Selection</h4>
|
|
<div class="space-y-3">
|
|
{% for value, label in form.role.choices %}
|
|
<div class="flex items-center">
|
|
<input type="radio"
|
|
name="{{ form.role.name }}"
|
|
value="{{ value }}"
|
|
id="role_{{ value }}"
|
|
class="h-4 w-4 text-primary-600 focus:ring-primary-500 border-gray-300"
|
|
{% if form.role.data == value %}checked{% endif %}
|
|
{% if value == 'admin' and current_user.is_admin and total_admins <= 1 and form.role.data == 'admin' %}disabled{% endif %}>
|
|
<label for="role_{{ value }}" class="ml-3 block text-sm font-medium text-gray-700">
|
|
{{ label }}
|
|
<span class="text-gray-500 text-xs block mt-0.5">
|
|
{% if value == 'admin' %}
|
|
Full access to all contacts, rooms and conversations. Can manage system settings and website customization.
|
|
{% elif value == 'manager' %}
|
|
Can create and manage rooms and conversations. Can view all contacts. Only limited access to system settings.
|
|
{% else %}
|
|
Basic user access.
|
|
{% endif %}
|
|
</span>
|
|
</label>
|
|
</div>
|
|
{% endfor %}
|
|
{% if form.role.errors %}
|
|
{% for error in form.role.errors %}
|
|
<p class="mt-1 text-sm text-red-600">{{ error }}</p>
|
|
{% endfor %}
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex flex-col space-y-4">
|
|
{% if form.role.errors %}
|
|
<div class="p-3 bg-red-50 border border-red-200 rounded-lg">
|
|
{% for error in form.role.errors %}
|
|
<p class="text-sm text-red-700">{{ error }}</p>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="flex justify-end">
|
|
{{ form.submit(class="text-white px-6 py-2 rounded-lg transition duration-200",
|
|
style="background-color: var(--primary-color); border: 1px solid var(--primary-color);",
|
|
onmouseover="this.style.backgroundColor='var(--primary-light)'",
|
|
onmouseout="this.style.backgroundColor='var(--primary-color)'") }}
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="{{ url_for('static', filename='js/avatar-preview.js') }}?v={{ 'js/avatar-preview.js'|asset_version }}"></script>
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
<script src="{{ url_for('static', filename='js/avatar-preview.js') }}?v={{ 'js/avatar-preview.js'|asset_version }}"></script>
|
|
{% endblock %} |