| {% extends "admin/base.html" %} |
|
|
| {% block title %}Gestion des Utilisateurs{% endblock %} |
| {% block page_title %}Gestion des Utilisateurs{% endblock %} |
|
|
| {% block content %} |
| |
| <div class="flex flex-col md:flex-row md:items-center md:justify-between gap-4 mb-6"> |
| <div> |
| <h1 class="text-2xl font-bold text-white"> |
| <i class="fas fa-users mr-3 text-yellow-400"></i> |
| Liste des Utilisateurs |
| </h1> |
| <p class="</div>text-gray-400 text-sm mt-1"> |
| {{ users.total }} utilisateur(s) au total |
| </p> |
| </div> |
|
|
| |
| <form method="GET" class="flex items-center space-x-2"> |
| <div class="relative"> |
| <input type="text" |
| name="search" |
| value="{{ request.args.get('search', '') }}" |
| placeholder="Rechercher par téléphone..." |
| class="w-64 px-4 py-2 pl-10 bg-gray-700 border border-gray-600 rounded-lg text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-yellow-500 focus:border-yellow-500"> |
| <i class="fas fa-search absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i> |
| </div> |
| <button type="submit" class="px-4 py-2 bg-yellow-600 hover:bg-yellow-700 text-white font-medium rounded-lg transition-colors"> |
| Rechercher |
| </button> |
| </form> |
| </div> |
|
|
| |
| <div class="bg-gray-800 rounded-xl border border-gray-700 overflow-hidden"> |
| <div class="overflow-x-auto"> |
| <table class="w-full"> |
| <thead class="bg-gray-900/50"> |
| <tr> |
| <th class="px-6 py-4 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">ID</th> |
| <th class="px-6 py-4 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">Utilisateur</th> |
| <th class="px-6 py-4 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">Téléphone</th> |
| <th class="px-6 py-4 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">Solde</th> |
| <th class="px-6 py-4 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">Bonus Bloqué</th> |
| <th class="px-6 py-4 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">Code Parrainage</th> |
| <th class="px-6 py-4 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">Statut</th> |
| <th class="px-6 py-4 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">Inscrit le</th> |
| <th class="px-6 py-4 text-center text-xs font-medium text-gray-400 uppercase tracking-wider">Actions</th> |
| </tr> |
| </thead> |
| <tbody class="divide-y divide-gray-700"> |
| {% for user in users.items %} |
| <tr class="hover:bg-gray-700/50 transition-colors"> |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-400"> |
| #{{ user.id }} |
| </td> |
| <td class="px-6 py-4 whitespace-nowrap"> |
| <div class="flex items-center"> |
| <div class="w-10 h-10 bg-gradient-to-br from-yellow-400 to-yellow-600 rounded-full flex items-center justify-center"> |
| <span class="text-white font-bold text-sm">{{ user.name[0].upper() if user.name else '?' }}</span> |
| </div> |
| <div class="ml-3"> |
| <p class="text-white font-medium">{{ user.name }}</p> |
| {% if user.is_admin %} |
| <span class="text-xs text-yellow-400"><i class="fas fa-crown mr-1"></i>Admin</span> |
| {% endif %} |
| </div> |
| </div> |
| </td> |
| <td class="px-6 py-4 whitespace-nowrap"> |
| <span class="text-gray-300">{{ user.country_code }}{{ user.phone }}</span> |
| </td> |
| <td class="px-6 py-4 whitespace-nowrap"> |
| <span class="text-green-400 font-medium">{{ "{:,.0f}".format(user.balance) }} FCFA</span> |
| </td> |
| <td class="px-6 py-4 whitespace-nowrap"> |
| {% if user.locked_bonus > 0 %} |
| <span class="text-yellow-400 font-medium"> |
| <i class="fas fa-lock mr-1 text-xs"></i> |
| {{ "{:,.0f}".format(user.locked_bonus) }} FCFA |
| </span> |
| {% else %} |
| <span class="text-gray-500">-</span> |
| {% endif %} |
| </td> |
| <td class="px-6 py-4 whitespace-nowrap"> |
| <code class="bg-gray-700 px-2 py-1 rounded text-yellow-400 text-sm">{{ user.referral_code }}</code> |
| </td> |
| <td class="px-6 py-4 whitespace-nowrap"> |
| {% if user.account_active %} |
| <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-500/20 text-green-400"> |
| <i class="fas fa-check-circle mr-1"></i> Actif |
| </span> |
| {% else %} |
| <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-500/20 text-red-400"> |
| <i class="fas fa-times-circle mr-1"></i> Inactif |
| </span> |
| {% endif %} |
| </td> |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-400"> |
| {{ user.created_at.strftime('%d/%m/%Y') }} |
| </td> |
| <td class="px-6 py-4 whitespace-nowrap text-center"> |
| <div class="flex items-center justify-center space-x-2"> |
| |
| <a href="{{ url_for('admin_panel.toggle_user', user_id=user.id) }}" |
| class="p-2 rounded-lg {% if user.account_active %}bg-red-500/20 text-red-400 hover:bg-red-500/30{% else %}bg-green-500/20 text-green-400 hover:bg-green-500/30{% endif %} transition-colors" |
| title="{% if user.account_active %}Désactiver{% else %}Activer{% endif %} le compte"> |
| <i class="fas {% if user.account_active %}fa-user-slash{% else %}fa-user-check{% endif %}"></i> |
| </a> |
|
|
| |
| <a href="{{ url_for('admin_panel.adjust_balance', user_id=user.id) }}" |
| class="p-2 rounded-lg bg-yellow-500/20 text-yellow-400 hover:bg-yellow-500/30 transition-colors" |
| title="Ajuster le solde"> |
| <i class="fas fa-coins"></i> |
| </a> |
|
|
| |
| <a href="{{ url_for('admin_panel.user_detail', user_id=user.id) }}" |
| class="p-2 rounded-lg bg-blue-500/20 text-blue-400 hover:bg-blue-500/30 transition-colors" |
| title="Voir les détails"> |
| <i class="fas fa-eye"></i> |
| </a> |
| </div> |
| </td> |
| </tr> |
| {% else %} |
| <tr> |
| <td colspan="9" class="px-6 py-12 text-center text-gray-500"> |
| <i class="fas fa-users-slash text-4xl mb-3"></i> |
| <p class="text-lg">Aucun utilisateur trouvé</p> |
| {% if request.args.get('search') %} |
| <p class="text-sm mt-1">Essayez avec d'autres termes de recherche</p> |
| {% endif %} |
| </td> |
| </tr> |
| {% endfor %} |
| </tbody> |
| </table> |
| </div> |
|
|
| |
| {% if users.pages > 1 %} |
| <div class="px-6 py-4 border-t border-gray-700 flex items-center justify-between"> |
| <div class="text-sm text-gray-400"> |
| Affichage de {{ users.items|length }} sur {{ users.total }} utilisateurs |
| </div> |
| <div class="flex items-center space-x-2"> |
| {% if users.has_prev %} |
| <a href="{{ url_for('admin_panel.users', page=users.prev_num, search=request.args.get('search', '')) }}" |
| class="px-3 py-2 bg-gray-700 hover:bg-gray-600 text-white rounded-lg transition-colors"> |
| <i class="fas fa-chevron-left mr-1"></i> Précédent |
| </a> |
| {% endif %} |
|
|
| <div class="flex items-center space-x-1"> |
| {% for page_num in users.iter_pages(left_edge=1, left_current=1, right_current=2, right_edge=1) %} |
| {% if page_num %} |
| {% if page_num == users.page %} |
| <span class="px-3 py-2 bg-yellow-600 text-white rounded-lg font-medium">{{ page_num }}</span> |
| {% else %} |
| <a href="{{ url_for('admin_panel.users', page=page_num, search=request.args.get('search', '')) }}" |
| class="px-3 py-2 bg-gray-700 hover:bg-gray-600 text-white rounded-lg transition-colors">{{ page_num }}</a> |
| {% endif %} |
| {% else %} |
| <span class="px-2 text-gray-500">...</span> |
| {% endif %} |
| {% endfor %} |
| </div> |
|
|
| {% if users.has_next %} |
| <a href="{{ url_for('admin_panel.users', page=users.next_num, search=request.args.get('search', '')) }}" |
| class="px-3 py-2 bg-gray-700 hover:bg-gray-600 text-white rounded-lg transition-colors"> |
| Suivant <i class="fas fa-chevron-right ml-1"></i> |
| </a> |
| {% endif %} |
| </div> |
| </div> |
| {% endif %} |
| </div> |
|
|
| |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-6"> |
| <div class="bg-gray-800 rounded-lg border border-gray-700 p-4"> |
| <div class="flex items-center"> |
| <div class="w-10 h-10 bg-green-500/20 rounded-lg flex items-center justify-center mr-3"> |
| <i class="fas fa-user-check text-green-400"></i> |
| </div> |
| <div> |
| <p class="text-2xl font-bold text-white">{{ users.items|selectattr('account_active')|list|length }}</p> |
| <p class="text-sm text-gray-400">Comptes actifs sur cette page</p> |
| </div> |
| </div> |
| </div> |
| <div class="bg-gray-800 rounded-lg border border-gray-700 p-4"> |
| <div class="flex items-center"> |
| <div class="w-10 h-10 bg-yellow-500/20 rounded-lg flex items-center justify-center mr-3"> |
| <i class="fas fa-crown text-yellow-400"></i> |
| </div> |
| <div> |
| <p class="text-2xl font-bold text-white">{{ users.items|selectattr('is_admin')|list|length }}</p> |
| <p class="text-sm text-gray-400">Administrateurs sur cette page</p> |
| </div> |
| </div> |
| </div> |
| <div class="bg-gray-800 rounded-lg border border-gray-700 p-4"> |
| <div class="flex items-center"> |
| <div class="w-10 h-10 bg-blue-500/20 rounded-lg flex items-center justify-center mr-3"> |
| <i class="fas fa-wallet text-blue-400"></i> |
| </div> |
| <div> |
| <p class="text-2xl font-bold text-white">{{ "{:,.0f}".format(users.items|sum(attribute='balance')) }}</p> |
| <p class="text-sm text-gray-400">FCFA total sur cette page</p> |
| </div> |
| </div> |
| </div> |
| </div> |
| {% endblock %} |
|
|