Mobile-friendly UI: hamburger nav, responsive layouts, restyle login/admin pages, fix iOS upload
This commit is contained in:
+14
-1
@@ -12,7 +12,10 @@
|
||||
<nav class="navbar">
|
||||
<div class="nav-container">
|
||||
<a class="nav-brand" href="/">🏠 سجل العقارات</a>
|
||||
<div class="nav-links">
|
||||
<button class="nav-toggle" id="navToggle" aria-label="القائمة">
|
||||
<span></span><span></span><span></span>
|
||||
</button>
|
||||
<div class="nav-links" id="navLinks">
|
||||
<a href="/" class="nav-link">رفع وثائق</a>
|
||||
<a href="/review/next" class="nav-link">مراجعة</a>
|
||||
<a href="/search" class="nav-link">بحث</a>
|
||||
@@ -28,6 +31,16 @@
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
|
||||
<script>
|
||||
const navToggle = document.getElementById('navToggle');
|
||||
const navLinks = document.getElementById('navLinks');
|
||||
if (navToggle) {
|
||||
navToggle.addEventListener('click', () => {
|
||||
navLinks.classList.toggle('open');
|
||||
navToggle.classList.toggle('active');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{% block scripts %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -23,12 +23,12 @@
|
||||
|
||||
<div class="upload-card">
|
||||
<form id="uploadForm" action="/upload" method="post" enctype="multipart/form-data">
|
||||
<div class="drop-zone" id="dropZone">
|
||||
<input type="file" name="files" id="fileInput" multiple accept=".jpg,.jpeg,.png,.webp,.pdf" class="file-input">
|
||||
<label for="fileInput" class="drop-zone" id="dropZone">
|
||||
<div class="drop-icon">📄</div>
|
||||
<p class="drop-text">اسحب الملفات هنا أو انقر للاختيار</p>
|
||||
<p class="drop-hint">JPG، PNG، PDF — يمكن رفع عدة ملفات دفعة واحدة</p>
|
||||
<input type="file" name="files" id="fileInput" multiple accept=".jpg,.jpeg,.png,.webp,.pdf" class="file-input">
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<div id="fileList" class="file-list hidden"></div>
|
||||
|
||||
@@ -77,7 +77,7 @@ const fileInput = document.getElementById('fileInput');
|
||||
const fileList = document.getElementById('fileList');
|
||||
const uploadActions = document.getElementById('uploadActions');
|
||||
|
||||
dropZone.addEventListener('click', () => fileInput.click());
|
||||
// label[for] natively triggers the file input on all platforms including iOS
|
||||
|
||||
dropZone.addEventListener('dragover', e => {
|
||||
e.preventDefault();
|
||||
|
||||
+13
-13
@@ -5,25 +5,25 @@
|
||||
{% block navbar %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="login-container" style="max-width: 400px; margin: 50px auto; padding: 20px; border: 1px solid #ccc; border-radius: 8px;">
|
||||
<h2>تسجيل الدخول</h2>
|
||||
|
||||
<div class="login-card">
|
||||
<h2>🏠 تسجيل الدخول</h2>
|
||||
|
||||
{% if error %}
|
||||
<div style="color: red; margin-bottom: 10px;">{{ error }}</div>
|
||||
<div class="login-error">{{ error }}</div>
|
||||
{% endif %}
|
||||
|
||||
<form method="post" action="/auth/login">
|
||||
<div style="margin-bottom: 15px;">
|
||||
<label for="username" style="display: block; margin-bottom: 5px;">اسم المستخدم:</label>
|
||||
<input type="text" id="username" name="username" required style="width: 100%; padding: 8px;">
|
||||
<div class="form-group">
|
||||
<label for="username">اسم المستخدم</label>
|
||||
<input type="text" id="username" name="username" required placeholder="أدخل اسم المستخدم">
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 15px;">
|
||||
<label for="password" style="display: block; margin-bottom: 5px;">كلمة المرور:</label>
|
||||
<input type="password" id="password" name="password" required style="width: 100%; padding: 8px;">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">كلمة المرور</label>
|
||||
<input type="password" id="password" name="password" required placeholder="أدخل كلمة المرور">
|
||||
</div>
|
||||
|
||||
<button type="submit" style="width: 100%; padding: 10px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer;">
|
||||
|
||||
<button type="submit" class="btn btn-primary btn-large" style="width:100%; justify-content:center; margin-top:.5rem;">
|
||||
دخول
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
</div>
|
||||
<div>
|
||||
{% set scopes = documents | selectattr('search_scope') | map(attribute='search_scope') | unique | list %}
|
||||
<div class="export-dropdown" style="position: relative; display: inline-block;">
|
||||
<div class="export-dropdown">
|
||||
<button class="btn btn-primary" onclick="this.nextElementSibling.classList.toggle('show')">📥 تصدير كملف إكسل ▾</button>
|
||||
<div class="export-menu" style="display:none; position:absolute; left:0; top:100%; background:#fff; border:1px solid #ddd; border-radius:8px; box-shadow:0 4px 12px rgba(0,0,0,.15); z-index:100; min-width:220px; margin-top:4px;">
|
||||
<a href="/persons/{{ person.id }}/export" class="export-option" download style="display:block; padding:10px 16px; text-decoration:none; color:#333; border-bottom:1px solid #eee;">📥 تصدير الكل</a>
|
||||
<div class="export-menu">
|
||||
<a href="/persons/{{ person.id }}/export" class="export-option" download>📥 تصدير الكل</a>
|
||||
{% for scope in scopes %}
|
||||
{% if scope %}
|
||||
<a href="/persons/{{ person.id }}/export?qaza={{ scope|urlencode }}" class="export-option" download style="display:block; padding:10px 16px; text-decoration:none; color:#333;">📥 {{ scope }}</a>
|
||||
<a href="/persons/{{ person.id }}/export?qaza={{ scope|urlencode }}" class="export-option" download>📥 {{ scope }}</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
@@ -75,7 +75,7 @@
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div style="margin: 1rem 0; padding: 15px; background-color: #fff3f3; border: 1px solid #ffcaca; border-radius: 8px; color: #dc3545; font-weight: bold; text-align: center;">
|
||||
<div class="error-banner" style="justify-content:center;">
|
||||
⚠️ نتيجة البحث: لا يملك أي عقار في نطاق البحث المذكور.
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@@ -64,13 +64,13 @@
|
||||
<div style="margin-top:1rem">
|
||||
<a href="/persons/{{ selected_person.person.id }}" class="btn btn-secondary">عرض التفاصيل كاملة</a>
|
||||
{% set scopes = selected_person.documents | selectattr('search_scope') | map(attribute='search_scope') | unique | list %}
|
||||
<div class="export-dropdown" style="position: relative; display: inline-block;">
|
||||
<div class="export-dropdown">
|
||||
<button class="btn btn-primary" onclick="this.nextElementSibling.classList.toggle('show')">📥 تصدير كملف إكسل ▾</button>
|
||||
<div class="export-menu" style="display:none; position:absolute; left:0; top:100%; background:#fff; border:1px solid #ddd; border-radius:8px; box-shadow:0 4px 12px rgba(0,0,0,.15); z-index:100; min-width:220px; margin-top:4px;">
|
||||
<a href="/persons/{{ selected_person.person.id }}/export" class="export-option" download style="display:block; padding:10px 16px; text-decoration:none; color:#333; border-bottom:1px solid #eee;">📥 تصدير الكل</a>
|
||||
<div class="export-menu">
|
||||
<a href="/persons/{{ selected_person.person.id }}/export" class="export-option" download>📥 تصدير الكل</a>
|
||||
{% for scope in scopes %}
|
||||
{% if scope %}
|
||||
<a href="/persons/{{ selected_person.person.id }}/export?qaza={{ scope|urlencode }}" class="export-option" download style="display:block; padding:10px 16px; text-decoration:none; color:#333;">📥 {{ scope }}</a>
|
||||
<a href="/persons/{{ selected_person.person.id }}/export?qaza={{ scope|urlencode }}" class="export-option" download>📥 {{ scope }}</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
@@ -112,7 +112,7 @@
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div style="margin-top: 1rem; padding: 15px; background-color: #fff3f3; border: 1px solid #ffcaca; border-radius: 8px; color: #dc3545; font-weight: bold; text-align: center;">
|
||||
<div class="error-banner" style="margin-top:1rem; justify-content:center;">
|
||||
⚠️ نتيجة البحث: لا يملك أي عقار في القضاء المذكور.
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
+51
-49
@@ -3,62 +3,64 @@
|
||||
{% block title %}إدارة المستخدمين - سجل العقارات اللبناني{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="users-container" style="max-width: 800px; margin: 20px auto; padding: 20px;">
|
||||
<h2>إدارة النظام والمستخدمين</h2>
|
||||
|
||||
{% if backup_msg %}
|
||||
<div style="padding: 10px; background-color: #d4edda; color: #155724; border-radius: 4px; margin-bottom: 15px;">
|
||||
{{ backup_msg }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div style="margin-bottom: 30px; padding: 15px; border: 1px solid #ddd; border-radius: 8px;">
|
||||
<h3>نسخ احتياطي لقاعدة البيانات</h3>
|
||||
<p>قم بإنشاء نسخة احتياطية من قاعدة البيانات الحالية.</p>
|
||||
<a href="/auth/backup" style="display: inline-block; padding: 8px 15px; background-color: #28a745; color: white; text-decoration: none; border-radius: 4px;">إنشاء نسخة احتياطية</a>
|
||||
<div class="admin-container">
|
||||
<div class="page-header">
|
||||
<h1>إدارة النظام والمستخدمين</h1>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 30px; padding: 15px; border: 1px solid #ddd; border-radius: 8px;">
|
||||
<h3>إضافة مستخدم جديد</h3>
|
||||
<form method="post" action="/auth/users/create" style="display: flex; gap: 10px; align-items: flex-end;">
|
||||
<div>
|
||||
<label for="username" style="display: block; margin-bottom: 5px;">اسم المستخدم</label>
|
||||
<input type="text" id="username" name="username" required style="padding: 8px;">
|
||||
{% if backup_msg %}
|
||||
<div class="success-banner">{{ backup_msg }}</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="admin-section">
|
||||
<h3>💾 نسخ احتياطي لقاعدة البيانات</h3>
|
||||
<p>قم بإنشاء نسخة احتياطية من قاعدة البيانات الحالية.</p>
|
||||
<a href="/auth/backup" class="btn btn-success">إنشاء نسخة احتياطية</a>
|
||||
</div>
|
||||
|
||||
<div class="admin-section">
|
||||
<h3>➕ إضافة مستخدم جديد</h3>
|
||||
<form method="post" action="/auth/users/create" class="add-user-form">
|
||||
<div class="form-group">
|
||||
<label for="username">اسم المستخدم</label>
|
||||
<input type="text" id="username" name="username" required>
|
||||
</div>
|
||||
<div>
|
||||
<label for="password" style="display: block; margin-bottom: 5px;">كلمة المرور</label>
|
||||
<input type="password" id="password" name="password" required style="padding: 8px;">
|
||||
<div class="form-group">
|
||||
<label for="password">كلمة المرور</label>
|
||||
<input type="password" id="password" name="password" required>
|
||||
</div>
|
||||
<button type="submit" style="padding: 9px 15px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer;">إضافة</button>
|
||||
<button type="submit" class="btn btn-primary">إضافة</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div style="padding: 15px; border: 1px solid #ddd; border-radius: 8px;">
|
||||
<h3>المستخدمين</h3>
|
||||
<table style="width: 100%; border-collapse: collapse; margin-top: 10px;">
|
||||
<thead>
|
||||
<tr style="background-color: #f8f9fa;">
|
||||
<th style="padding: 10px; border-bottom: 2px solid #dee2e6; text-align: right;">الرقم</th>
|
||||
<th style="padding: 10px; border-bottom: 2px solid #dee2e6; text-align: right;">اسم المستخدم</th>
|
||||
<th style="padding: 10px; border-bottom: 2px solid #dee2e6; text-align: right;">تاريخ الإنشاء</th>
|
||||
<th style="padding: 10px; border-bottom: 2px solid #dee2e6; text-align: right;">إجراءات</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in users %}
|
||||
<tr>
|
||||
<td style="padding: 10px; border-bottom: 1px solid #dee2e6;">{{ user.id }}</td>
|
||||
<td style="padding: 10px; border-bottom: 1px solid #dee2e6;">{{ user.username }}</td>
|
||||
<td style="padding: 10px; border-bottom: 1px solid #dee2e6;">{{ user.created_at }}</td>
|
||||
<td style="padding: 10px; border-bottom: 1px solid #dee2e6;">
|
||||
<form method="post" action="/auth/users/delete/{{ user.id }}" onsubmit="return confirm('هل أنت متأكد من حذف هذا المستخدم؟');" style="display: inline;">
|
||||
<button type="submit" style="padding: 5px 10px; background-color: #dc3545; color: white; border: none; border-radius: 4px; cursor: pointer;">حذف</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="admin-section">
|
||||
<h3>👥 المستخدمين</h3>
|
||||
<div class="table-wrapper">
|
||||
<table class="results-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>الرقم</th>
|
||||
<th>اسم المستخدم</th>
|
||||
<th>تاريخ الإنشاء</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in users %}
|
||||
<tr>
|
||||
<td>{{ user.id }}</td>
|
||||
<td>{{ user.username }}</td>
|
||||
<td>{{ user.created_at }}</td>
|
||||
<td>
|
||||
<form method="post" action="/auth/users/delete/{{ user.id }}" onsubmit="return confirm('هل أنت متأكد من حذف هذا المستخدم؟');" style="display:inline;">
|
||||
<button type="submit" class="btn btn-sm btn-danger">حذف</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user