adminx 0.2.6

A powerful, modern admin panel framework for Rust built on Actix Web and MongoDB with automatic CRUD, role-based access control, and a beautiful responsive UI
Documentation
{% extends "layout.html.tera" %}

{% block title %}User Profile{% endblock title %}

{% block content %}
<div class="space-y-6">
  <!-- Profile Header -->
  <div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden">
    <div class="bg-gradient-to-r from-blue-600 to-blue-700 px-6 py-8">
      <div class="flex items-center">
        <div class="flex-shrink-0">
          <div class="h-20 w-20 rounded-full bg-white bg-opacity-20 flex items-center justify-center">
            <svg class="h-10 w-10 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
            </svg>
          </div>
        </div>
        <div class="ml-6">
          <h1 class="text-2xl font-bold text-white">
            {{ current_user.email | default(value="Administrator") }}
          </h1>
          <p class="text-blue-100">
            Role: {{ current_user.role | default(value="admin") | title }}
          </p>
        </div>
      </div>
    </div>
  </div>

  <div class="grid grid-cols-1 gap-6 lg:grid-cols-3">
    <!-- Profile Information -->
    <div class="lg:col-span-2">
      <div class="bg-white dark:bg-gray-800 shadow rounded-lg">
        <div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
          <h3 class="text-lg font-medium text-gray-900 dark:text-white">Profile Information</h3>
        </div>
        <div class="px-6 py-4">
          <dl class="grid grid-cols-1 gap-x-4 gap-y-6 sm:grid-cols-2">
            <div class="sm:col-span-1">
              <dt class="text-sm font-medium text-gray-500 dark:text-gray-400">Email Address</dt>
              <dd class="mt-1 text-sm text-gray-900 dark:text-gray-100">
                {{ current_user.email | default(value="admin@example.com") }}
              </dd>
            </div>
            
            <div class="sm:col-span-1">
              <dt class="text-sm font-medium text-gray-500 dark:text-gray-400">User ID</dt>
              <dd class="mt-1 text-sm text-gray-900 dark:text-gray-100">
                {{ current_user.sub | default(value="N/A") }}
              </dd>
            </div>

            <div class="sm:col-span-1">
              <dt class="text-sm font-medium text-gray-500 dark:text-gray-400">Primary Role</dt>
              <dd class="mt-1 text-sm text-gray-900 dark:text-gray-100">
                <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800 dark:bg-blue-800 dark:text-blue-100">
                  {{ current_user.role | default(value="admin") | title }}
                </span>
              </dd>
            </div>

            <div class="sm:col-span-1">
              <dt class="text-sm font-medium text-gray-500 dark:text-gray-400">Session Expires</dt>
              <dd class="mt-1 text-sm text-gray-900 dark:text-gray-100">
                {% if current_user.exp %}
                  {{ current_user.exp | date(format="%Y-%m-%d %H:%M:%S") }}
                {% else %}
                  Not available
                {% endif %}
              </dd>
            </div>

            {% if current_user.roles and current_user.roles | length > 1 %}
            <div class="sm:col-span-2">
              <dt class="text-sm font-medium text-gray-500 dark:text-gray-400">Additional Roles</dt>
              <dd class="mt-1">
                <div class="flex flex-wrap gap-2">
                  {% for role in current_user.roles %}
                    {% if role != current_user.role %}
                    <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200">
                      {{ role | title }}
                    </span>
                    {% endif %}
                  {% endfor %}
                </div>
              </dd>
            </div>
            {% endif %}
          </dl>
        </div>
      </div>

      <!-- Change Password -->
      <div class="mt-6 bg-white dark:bg-gray-800 shadow rounded-lg">
        <div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
          <h3 class="text-lg font-medium text-gray-900 dark:text-white">Change Password</h3>
        </div>
        <form class="px-6 py-4 space-y-4">
          <div>
            <label for="current_password" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
              Current Password
            </label>
            <div class="mt-1">
              <input type="password" name="current_password" id="current_password"
                     class="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md dark:bg-gray-700 dark:border-gray-600 dark:text-white"
                     required>
            </div>
          </div>

          <div>
            <label for="new_password" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
              New Password
            </label>
            <div class="mt-1">
              <input type="password" name="new_password" id="new_password"
                     class="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md dark:bg-gray-700 dark:border-gray-600 dark:text-white"
                     required>
            </div>
          </div>

          <div>
            <label for="confirm_password" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
              Confirm New Password
            </label>
            <div class="mt-1">
              <input type="password" name="confirm_password" id="confirm_password"
                     class="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md dark:bg-gray-700 dark:border-gray-600 dark:text-white"
                     required>
            </div>
          </div>

          <div class="pt-4">
            <button type="submit" 
                    class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
              <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"/>
              </svg>
              Update Password
            </button>
          </div>
        </form>
      </div>
    </div>

    <!-- Account Settings Sidebar -->
    <div class="lg:col-span-1">
      <!-- Account Settings -->
      <div class="bg-white dark:bg-gray-800 shadow rounded-lg">
        <div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
          <h3 class="text-lg font-medium text-gray-900 dark:text-white">Account Settings</h3>
        </div>
        <div class="px-6 py-4">
          <div class="space-y-4">
            <div class="flex items-center justify-between">
              <div>
                <p class="text-sm font-medium text-gray-900 dark:text-white">Email Notifications</p>
                <p class="text-sm text-gray-500 dark:text-gray-400">Receive email updates</p>
              </div>
              <label class="relative inline-flex items-center cursor-pointer">
                <input type="checkbox" class="sr-only peer" checked>
                <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div>
              </label>
            </div>

            <div class="flex items-center justify-between">
              <div>
                <p class="text-sm font-medium text-gray-900 dark:text-white">Two-Factor Auth</p>
                <p class="text-sm text-gray-500 dark:text-gray-400">Extra security layer</p>
              </div>
              <label class="relative inline-flex items-center cursor-pointer">
                <input type="checkbox" class="sr-only peer">
                <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div>
              </label>
            </div>
          </div>
        </div>
      </div>

      <!-- Recent Activity -->
      <div class="mt-6 bg-white dark:bg-gray-800 shadow rounded-lg">
        <div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
          <h3 class="text-lg font-medium text-gray-900 dark:text-white">Recent Activity</h3>
        </div>
        <div class="px-6 py-4">
          <div class="space-y-3">
            <div class="flex items-center space-x-3">
              <div class="flex-shrink-0">
                <div class="h-2 w-2 rounded-full bg-green-400"></div>
              </div>
              <div class="flex-1 min-w-0">
                <p class="text-sm text-gray-900 dark:text-gray-100">Logged in</p>
                <p class="text-xs text-gray-500 dark:text-gray-400">Just now</p>
              </div>
            </div>

            <div class="flex items-center space-x-3">
              <div class="flex-shrink-0">
                <div class="h-2 w-2 rounded-full bg-blue-400"></div>
              </div>
              <div class="flex-1 min-w-0">
                <p class="text-sm text-gray-900 dark:text-gray-100">Viewed dashboard</p>
                <p class="text-xs text-gray-500 dark:text-gray-400">2 minutes ago</p>
              </div>
            </div>

            <div class="flex items-center space-x-3">
              <div class="flex-shrink-0">
                <div class="h-2 w-2 rounded-full bg-yellow-400"></div>
              </div>
              <div class="flex-1 min-w-0">
                <p class="text-sm text-gray-900 dark:text-gray-100">Updated profile</p>
                <p class="text-xs text-gray-500 dark:text-gray-400">1 hour ago</p>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- Quick Actions -->
      <div class="mt-6 bg-white dark:bg-gray-800 shadow rounded-lg">
        <div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
          <h3 class="text-lg font-medium text-gray-900 dark:text-white">Quick Actions</h3>
        </div>
        <div class="px-6 py-4">
          <div class="space-y-3">
            <a href="/adminx" class="block w-full text-left px-4 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 rounded-md">
              <svg class="w-4 h-4 inline mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2H5a2 2 0 00-2-2z"/>
              </svg>
              Go to Dashboard
            </a>
            
            <a href="/adminx/stats" class="block w-full text-left px-4 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 rounded-md">
              <svg class="w-4 h-4 inline mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
              </svg>
              View Statistics
            </a>

            <form method="post" action="/adminx/logout" class="block">
              <button type="submit" class="w-full text-left px-4 py-2 text-sm text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900 dark:hover:bg-opacity-20 rounded-md">
                <svg class="w-4 h-4 inline mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/>
                </svg>
                Logout
              </button>
            </form>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
{% endblock content %}