| <!doctype html> |
| <html lang="fr"> |
| <head> |
| <meta charset="UTF-8" /> |
| <meta |
| name="viewport" |
| content="width=device-width, initial-scale=1.0, user-scalable=no, viewport-fit=cover" |
| /> |
| <title>{% block title %}{% endblock %} - {{ app_name }}</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <link |
| rel="stylesheet" |
| href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" |
| /> |
|
|
| |
| <script> |
| tailwind.config = { |
| theme: { |
| extend: { |
| fontFamily: { |
| sans: ["DM Sans", "sans-serif"], |
| }, |
| colors: { |
| bg: "#111827", |
| card: "#1F2937", |
| cardLight: "#374151", |
| primary: "#10B981", |
| primaryDark: "#059669", |
| accent: "#FBBF24", |
| danger: "#EF4444", |
| textMuted: "#9CA3AF", |
| }, |
| boxShadow: { |
| glow: "0 0 20px rgba(16, 185, 129, 0.15)", |
| float: "0 10px 30px -10px rgba(0, 0, 0, 0.5)", |
| }, |
| animation: { |
| pop: "pop 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275)", |
| "slide-up": "slideUp 0.3s ease-out", |
| }, |
| keyframes: { |
| pop: { |
| "0%": { transform: "scale(0.95)" }, |
| "100%": { transform: "scale(1)" }, |
| }, |
| slideUp: { |
| "0%": { transform: "translateY(100%)" }, |
| "100%": { transform: "translateY(0)" }, |
| }, |
| }, |
| }, |
| }, |
| }; |
| </script> |
| <link |
| href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&display=swap" |
| rel="stylesheet" |
| /> |
|
|
| <style> |
| body { |
| font-family: "DM Sans", sans-serif; |
| background-color: #111827; |
| color: white; |
| -webkit-tap-highlight-color: transparent; |
| } |
| |
| |
| .no-scrollbar::-webkit-scrollbar { |
| display: none; |
| } |
| |
| |
| .btn-press:active { |
| transform: scale(0.96); |
| transition: transform 0.1s; |
| } |
| |
| |
| .nav-link.active { |
| color: white; |
| } |
| .nav-link.active i { |
| color: #fbbf24; |
| transform: translateY(-2px); |
| } |
| |
| |
| #toast-box { |
| position: fixed; |
| top: 20px; |
| left: 50%; |
| transform: translateX(-50%); |
| z-index: 100; |
| width: 90%; |
| max-width: 400px; |
| pointer-events: none; |
| } |
| .toast { |
| background: #374151; |
| color: white; |
| padding: 12px 16px; |
| border-radius: 12px; |
| margin-bottom: 8px; |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3); |
| display: flex; |
| align-items: center; |
| gap: 12px; |
| border-left: 4px solid; |
| animation: slideDown 0.3s; |
| pointer-events: auto; |
| } |
| @keyframes slideDown { |
| from { |
| opacity: 0; |
| transform: translateY(-20px); |
| } |
| to { |
| opacity: 1; |
| transform: translateY(0); |
| } |
| } |
| </style> |
| {% block extra_css %}{% endblock %} |
| </head> |
| <body class="overflow-x-hidden"> |
| |
| <div id="toast-box"></div> |
|
|
| |
| {% if current_user.is_authenticated %} |
| <header |
| class="px-6 pt-8 pb-4 flex justify-between items-center bg-bg sticky top-0 z-30" |
| > |
| <div class="flex flex-col"> |
| <span |
| class="text-textMuted text-xs font-bold uppercase tracking-wider" |
| >Espace Membre</span |
| > |
| <span class="text-xl font-bold text-white tracking-tight" |
| >Apex Ores<span class="text-accent">.</span></span |
| > |
| </div> |
| <a |
| href="{{ url_for('main.referral') }}" |
| class="w-10 h-10 bg-card rounded-full flex items-center justify-center border border-gray-700 cursor-pointer hover:border-accent transition" |
| > |
| <span class="font-bold text-gray-300 text-sm"> |
| {% if current_user.name %} {{ current_user.name[:2].upper() |
| }} {% else %} U {% endif %} |
| </span> |
| </a> |
| </header> |
| {% endif %} |
|
|
| |
| <div class="px-5 mt-4"> |
| {% with messages = get_flashed_messages(with_categories=true) %} {% |
| if messages %} {% for category, message in messages %} |
| <div |
| class="mb-4 p-4 rounded-xl flex items-center gap-3 animate-pop {% if category == 'success' %}bg-primary/10 border-l-4 border-primary text-primary{% elif category == 'error' %}bg-danger/10 border-l-4 border-danger text-danger{% else %}bg-cardLight border-l-4 border-accent text-accent{% endif %}" |
| > |
| <i |
| class="fa-solid {% if category == 'success' %}fa-circle-check{% elif category == 'error' %}fa-circle-xmark{% else %}fa-circle-info{% endif %}" |
| ></i> |
| <p class="text-sm font-medium">{{ message }}</p> |
| </div> |
| {% endfor %} {% endif %} {% endwith %} |
| </div> |
|
|
| |
| <main class="pb-32">{% block content %}{% endblock %}</main> |
|
|
| |
| {% if current_user.is_authenticated %} |
| <nav |
| class="fixed bottom-6 left-4 right-4 h-16 bg-card/90 backdrop-blur-xl border border-gray-700/50 rounded-full shadow-float z-40 px-2 flex justify-between items-center max-w-md mx-auto" |
| > |
| <a |
| href="{{ url_for('main.dashboard') }}" |
| class="nav-link flex-1 h-full flex flex-col items-center justify-center gap-1 text-gray-500 transition-colors {% if request.endpoint == 'main.dashboard' %}active{% endif %}" |
| > |
| <i class="fa-solid fa-house text-lg"></i> |
| <span class="text-[10px] font-medium">Accueil</span> |
| </a> |
|
|
| <a |
| href="{{ url_for('main.notifications') }}" |
| class="nav-link flex-1 h-full flex flex-col items-center justify-center gap-1 text-gray-500 transition-colors {% if request.endpoint == 'main.notifications' %}active{% endif %}" |
| > |
| <i class="fa-solid fa-clock-rotate-left text-lg"></i> |
| <span class="text-[10px] font-medium">Notifs</span> |
| </a> |
|
|
| |
| <div class="relative w-16 flex justify-center"> |
| <a |
| href="{{ url_for('main.market') }}" |
| class="absolute -top-6 w-14 h-14 bg-accent text-gray-900 rounded-full flex items-center justify-center shadow-lg shadow-amber-500/30 border-4 border-bg transform active:scale-95 transition-transform" |
| > |
| <i class="fa-solid fa-cart-shopping text-xl"></i> |
| </a> |
| </div> |
|
|
| <div |
| class="flex-1 h-full flex flex-col items-center justify-center gap-1 text-gray-500" |
| > |
| <span class="text-[10px] font-medium mt-6">Marché</span> |
| </div> |
|
|
| <a |
| href="{{ url_for('main.referral') }}" |
| class="nav-link flex-1 h-full flex flex-col items-center justify-center gap-1 text-gray-500 transition-colors {% if request.endpoint == 'main.referral' %}active{% endif %}" |
| > |
| <i class="fa-solid fa-user text-lg"></i> |
| <span class="text-[10px] font-medium">Profil</span> |
| </a> |
| </nav> |
| {% endif %} |
|
|
| <script> |
| function showToast(message, type = "info") { |
| const box = document.getElementById("toast-box"); |
| const toast = document.createElement("div"); |
| toast.className = "toast"; |
| |
| let color = |
| type === "error" |
| ? "#EF4444" |
| : type === "success" |
| ? "#10B981" |
| : "#FBBF24"; |
| let icon = |
| type === "error" |
| ? "fa-circle-xmark" |
| : type === "success" |
| ? "fa-circle-check" |
| : "fa-info-circle"; |
| |
| toast.style.borderColor = color; |
| toast.innerHTML = `<i class="fa-solid ${icon}" style="color:${color}"></i> <span>${message}</span>`; |
| |
| box.appendChild(toast); |
| setTimeout(() => { |
| toast.style.opacity = "0"; |
| toast.style.transform = "translateY(-20px)"; |
| setTimeout(() => toast.remove(), 300); |
| }, 3000); |
| } |
| </script> |
| {% block extra_js %}{% endblock %} |
| </body> |
| </html> |
|
|