115 lines
6.2 KiB
HTML
115 lines
6.2 KiB
HTML
{% extends 'dashboard.html' %}
|
|
|
|
{% block page %}
|
|
<div class="p-6 max-w-6xl mx-auto">
|
|
<!-- Settings Navigation -->
|
|
<div class="mb-6 border-b border-gray-200 dark:border-gray-700">
|
|
<nav class="-mb-px flex space-x-8">
|
|
<a hx-get="{{ url_for('settings.api_keys') }}" hx-target="#container" hx-swap="innerHTML" hx-push-url="true"
|
|
class="border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300 py-4 px-1 text-sm font-medium cursor-pointer">
|
|
API Keys
|
|
</a>
|
|
<a hx-get="{{ url_for('settings.export') }}" hx-target="#container" hx-swap="innerHTML" hx-push-url="true"
|
|
class="border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300 py-4 px-1 text-sm font-medium cursor-pointer">
|
|
Export Data
|
|
</a>
|
|
<a hx-get="{{ url_for('settings.database_schema') }}" hx-target="#container" hx-swap="innerHTML"
|
|
hx-push-url="true"
|
|
class="border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300 py-4 px-1 text-sm font-medium cursor-pointer">
|
|
Database Schema
|
|
</a>
|
|
<a hx-get="{{ url_for('settings.login_history') }}" hx-target="#container" hx-swap="innerHTML"
|
|
hx-push-url="true"
|
|
class="border-b-2 border-blue-500 text-blue-600 dark:text-blue-400 py-4 px-1 text-sm font-medium cursor-pointer">
|
|
Login History
|
|
</a>
|
|
</nav>
|
|
</div>
|
|
|
|
<div class="mb-6">
|
|
<h1 class="text-2xl font-bold text-gray-900 dark:text-white mb-2">Login History</h1>
|
|
<p class="text-gray-600 dark:text-gray-400">View your recent login activity and security events</p>
|
|
</div>
|
|
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg shadow">
|
|
{% if history %}
|
|
<div class="overflow-x-auto">
|
|
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
|
|
<thead class="bg-gray-50 dark:bg-gray-900">
|
|
<tr>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
Date & Time
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
IP Address
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
Browser / Device
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
Status
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
|
|
{% for entry in history %}
|
|
<tr>
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-white">
|
|
<div>{{ entry.login_time.strftime('%b %d, %Y') }}</div>
|
|
<div class="text-xs text-gray-500 dark:text-gray-400">
|
|
{{ entry.login_time.strftime('%I:%M %p') }}
|
|
</div>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-white">
|
|
{{ entry.ip_address or 'N/A' }}
|
|
</td>
|
|
<td class="px-6 py-4 text-sm text-gray-900 dark:text-white">
|
|
<div class="max-w-xs truncate" title="{{ entry.user_agent }}">
|
|
{{ entry.user_agent or 'Unknown' }}
|
|
</div>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
{% if entry.success %}
|
|
<span
|
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200">
|
|
Success
|
|
</span>
|
|
{% else %}
|
|
<span
|
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200"
|
|
title="{{ entry.failure_reason }}">
|
|
Failed
|
|
</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div class="p-8 text-center">
|
|
<svg class="mx-auto h-12 w-12 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
<h3 class="mt-2 text-sm font-medium text-gray-900 dark:text-white">No login history</h3>
|
|
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
|
Your login activity will appear here
|
|
</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if history %}
|
|
<div class="mt-4 text-sm text-gray-600 dark:text-gray-400">
|
|
<p>Showing last {{ history|length }} login{% if history|length != 1 %}s{% endif %}. Login history is kept for
|
|
security purposes.</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endblock %} |