base.html.twig 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. <!DOCTYPE html>
  2. <html lang="{{ current_lang|default('el') }}">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  6. <title>{% block title %}{{ site_title|default('Hockey CMS') }}{% endblock %}</title>
  7. <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
  8. <style>
  9. :root {
  10. /* --- DARK THEME PALETTE --- */
  11. --primary: #f97316; /* Δυναμικό Πορτοκαλί */
  12. --primary-hover: #ea580c;
  13. --bg-color: #0b1120; /* Βαθύ σκοτεινό Slate */
  14. --panel-bg: #1e293b; /* Χρώμα για κάρτες και header */
  15. --border-color: #334155;
  16. --text-main: #f8fafc;
  17. --text-muted: #94a3b8;
  18. --accent-green: #10b981;
  19. --accent-blue: #3b82f6;
  20. --shadow-sm: 0 4px 6px -1px rgba(0,0,0,0.3);
  21. --shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.5);
  22. --border-radius: 8px; /* Λιγότερο στρογγυλεμένες γωνίες για σπορ ύφος */
  23. }
  24. body { font-family: 'Inter', sans-serif; background-color: var(--bg-color); margin: 0; color: var(--text-main); line-height: 1.5; }
  25. /* --- HEADER --- */
  26. header { background: rgba(30, 41, 59, 0.85); backdrop-filter: blur(10px); padding: 15px 0; border-bottom: 1px solid var(--border-color); position: sticky; top: 0; z-index: 100; box-shadow: var(--shadow-sm); }
  27. .header-inner { max-width: 1400px; margin: 0 auto; padding: 0 30px; display: flex; justify-content: space-between; align-items: center; }
  28. .logo { font-size: 24px; font-weight: 900; color: var(--text-main); text-decoration: none; display: flex; align-items: center; gap: 10px; letter-spacing: -0.5px; text-transform: uppercase; }
  29. .logo span { color: var(--primary); }
  30. .header-actions { display: flex; align-items: center; gap: 25px; }
  31. .search-form { display: flex; background: #0f172a; border-radius: 30px; padding: 4px; border: 1px solid var(--border-color); flex-grow: 1; transition: border-color 0.3s; }
  32. .search-form:focus-within { border-color: var(--primary); box-shadow: 0 0 0 2px rgba(249, 115, 22, 0.2); }
  33. .search-form input { padding: 8px 15px; border: none; background: transparent; outline: none; width: 280px; font-family: 'Inter', sans-serif; color: var(--text-main); }
  34. .search-form input::placeholder { color: var(--text-muted); }
  35. .search-form button { padding: 8px 25px; border: none; background: var(--primary); color: white; border-radius: 30px; cursor: pointer; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; transition: 0.2s; }
  36. .search-form button:hover { background: var(--primary-hover); }
  37. /* --- LANGUAGE SWITCHER --- */
  38. .lang-switch { font-size: 13px; font-weight: 700; display: flex; gap: 5px; align-items: center; background: #0f172a; padding: 4px; border-radius: 20px; border: 1px solid var(--border-color); }
  39. .lang-switch a { color: var(--text-muted); text-decoration: none; padding: 4px 10px; border-radius: 15px; transition: 0.2s; }
  40. .lang-switch a:hover { color: var(--text-main); }
  41. .lang-switch a.active { color: #fff; background: var(--border-color); }
  42. /* --- USER MENU --- */
  43. .user-menu { display: flex; gap: 12px; align-items: center; margin-left: 10px; }
  44. .cart-link { background: transparent; border: 2px solid var(--primary); color: var(--primary); padding: 8px 20px; border-radius: 30px; font-weight: 700; text-decoration: none; display: flex; align-items: center; gap: 5px; white-space: nowrap; transition: 0.2s; text-transform: uppercase; font-size: 14px; }
  45. .cart-link:hover { background: var(--primary); color: white; }
  46. .btn-seller { background: var(--accent-blue); color: white; padding: 10px 18px; border-radius: 30px; text-decoration: none; font-weight: 700; font-size: 13px; text-transform: uppercase; letter-spacing: 0.5px; transition: 0.2s; }
  47. .btn-seller:hover { background: #2563eb; box-shadow: 0 0 10px rgba(59, 130, 246, 0.5); }
  48. .btn-profile { background: #334155; color: var(--text-main); padding: 10px 18px; border-radius: 30px; text-decoration: none; font-weight: 600; font-size: 14px; transition: 0.2s; }
  49. .btn-profile:hover { background: #475569; }
  50. .btn-logout-icon { color: #fca5a5; font-size: 16px; font-weight: bold; text-decoration: none; padding: 5px 10px; border-radius: 50%; display: flex; align-items: center; justify-content: center; width: 38px; height: 38px; background: rgba(239, 68, 68, 0.1); border: 1px solid rgba(239, 68, 68, 0.2); transition: all 0.2s; }
  51. .btn-logout-icon:hover { background: #ef4444; color: white; }
  52. /* --- GUEST LOGIN/REGISTER BUTTONS --- */
  53. .btn-login {
  54. background: transparent;
  55. color: var(--text-main);
  56. border: 1px solid var(--border-color);
  57. padding: 8px 18px;
  58. border-radius: 30px;
  59. font-weight: 700;
  60. text-decoration: none;
  61. font-size: 13px;
  62. text-transform: uppercase;
  63. letter-spacing: 0.5px;
  64. transition: 0.2s;
  65. }
  66. .btn-login:hover {
  67. background: rgba(255, 255, 255, 0.05);
  68. border-color: var(--text-muted);
  69. }
  70. .btn-register {
  71. background: var(--primary);
  72. color: white;
  73. padding: 8px 18px;
  74. border-radius: 30px;
  75. font-weight: 700;
  76. text-decoration: none;
  77. font-size: 13px;
  78. text-transform: uppercase;
  79. letter-spacing: 0.5px;
  80. transition: 0.2s;
  81. border: 1px solid var(--primary);
  82. }
  83. .btn-register:hover {
  84. background: var(--primary-hover);
  85. border-color: var(--primary-hover);
  86. }
  87. /* --- LAYOUT --- */
  88. .main-container { max-width: 1400px; margin: 40px auto; padding: 0 30px; display: flex; gap: 40px; align-items: flex-start; }
  89. .content-area { flex-grow: 1; min-width: 0; }
  90. /* --- MOBILE TOGGLE BUTTON --- */
  91. .mobile-menu-toggle { display: none; width: 100%; padding: 14px; background: var(--panel-bg); border: 1px solid var(--border-color); color: var(--text-main); border-radius: var(--border-radius); font-weight: 700; cursor: pointer; margin-bottom: 20px; font-size: 15px; text-align: center; text-transform: uppercase; letter-spacing: 1px; }
  92. /* --- SIDEBAR --- */
  93. .sidebar { width: 280px; flex-shrink: 0; background: var(--panel-bg); padding: 25px 0; border-radius: var(--border-radius); box-shadow: var(--shadow-lg); border: 1px solid var(--border-color); }
  94. .sidebar h3 { margin: 0 0 20px 25px; font-size: 13px; text-transform: uppercase; letter-spacing: 1.5px; font-weight: 800; color: var(--primary); }
  95. .tree-menu { list-style: none; padding: 0; margin: 0; }
  96. .menu-item { position: relative; border-bottom: 1px solid rgba(255,255,255,0.03); }
  97. .menu-item:last-child { border-bottom: none; }
  98. .parent-cat { text-decoration: none; color: var(--text-main); display: flex; justify-content: space-between; align-items: center; padding: 14px 25px; font-weight: 600; font-size: 15px; border-left: 3px solid transparent; transition: 0.2s; }
  99. .parent-cat:hover { background-color: rgba(255,255,255,0.03); color: var(--primary); border-left: 3px solid var(--primary); }
  100. .has-children::after { content: '›'; font-size: 18px; color: var(--text-muted); }
  101. /* Submenu (Desktop) */
  102. .tree-submenu { list-style: none; padding: 0; margin: 0; position: absolute; left: 100%; top: -1px; width: 240px; background: var(--panel-bg); border-radius: var(--border-radius); box-shadow: var(--shadow-lg); border: 1px solid var(--border-color); opacity: 0; visibility: hidden; transform: translateX(10px); transition: all 0.2s; z-index: 50; }
  103. .menu-item:hover .tree-submenu { opacity: 1; visibility: visible; transform: translateX(0); }
  104. .tree-submenu li a { text-decoration: none; color: var(--text-muted); display: block; padding: 12px 20px; font-size: 14px; font-weight: 500; border-bottom: 1px solid rgba(255,255,255,0.03); transition: 0.2s; }
  105. .tree-submenu li a:hover { color: var(--primary); background-color: rgba(255,255,255,0.02); padding-left: 25px; }
  106. /* --- FOOTER --- */
  107. footer { background: var(--panel-bg); color: var(--text-muted); text-align: center; padding: 40px 30px; margin-top: 80px; border-top: 1px solid var(--border-color); font-size: 14px; font-weight: 500; }
  108. @media (max-width: 992px) {
  109. .main-container { flex-direction: column; }
  110. .sidebar { width: 100%; display: none; margin-bottom: 30px; }
  111. .sidebar.active { display: block; }
  112. .mobile-menu-toggle { display: block; }
  113. .menu-item:hover .tree-submenu { display: none; }
  114. .tree-submenu { position: relative; left: 0; top: 0; width: 100%; opacity: 1; visibility: visible; transform: none; box-shadow: none; border: none; border-top: 1px solid var(--border-color); border-radius: 0; display: block; background: rgba(0,0,0,0.2); }
  115. .tree-submenu li a { padding: 12px 15px 12px 35px; }
  116. .has-children::after { content: '▼'; font-size: 12px; }
  117. }
  118. @media (max-width: 768px) {
  119. .header-inner { flex-direction: column; padding: 15px; gap: 20px; }
  120. .header-actions { flex-direction: column; width: 100%; gap: 15px; }
  121. .search-form { width: 100%; }
  122. .search-form input { width: 100%; }
  123. .user-menu { flex-wrap: wrap; justify-content: center; width: 100%; margin-left: 0; gap: 10px; }
  124. .cart-link, .btn-seller, .btn-profile { flex: 1; justify-content: center; text-align: center; font-size: 12px; padding: 10px; }
  125. .btn-login, .btn-register { flex: 1; text-align: center; }
  126. }
  127. {% block extra_css %}{% endblock %}
  128. </style>
  129. </head>
  130. <body>
  131. <header>
  132. <div class="header-inner">
  133. <a href="index.php" class="logo">
  134. {% if site_logo %}
  135. <img src="{{ site_logo }}" alt="Logo" style="max-height: 65px; width: auto; max-width: 250px; object-fit: contain; display: block;">
  136. {% else %}
  137. 🏒 <span>{{ text.header_logo_text|default('TradeHockey') }}</span>
  138. {% endif %}
  139. </a>
  140. <div class="header-actions">
  141. <div class="lang-switch">
  142. <a href="javascript:void(0);" onclick="changeShopLanguage('el');" class="{% if current_lang == 'el' %}active{% endif %}">GR</a>
  143. <a href="javascript:void(0);" onclick="changeShopLanguage('en');" class="{% if current_lang == 'en' %}active{% endif %}">EN</a>
  144. </div>
  145. <script>
  146. function changeShopLanguage(lang) {
  147. var url = new URL(window.location.href);
  148. url.searchParams.set('lang', lang);
  149. window.location.href = url.toString();
  150. }
  151. </script>
  152. <form action="index.php" method="GET" class="search-form">
  153. <input type="text" name="q" placeholder="{{ text.header_search_placeholder|default('Αναζήτηση εξοπλισμού...') }}" value="{{ search_query|default('') }}" required>
  154. <button type="submit">{{ text.header_search_btn|default('Αναζήτηση') }}</button>
  155. </form>
  156. <div class="user-menu">
  157. {% if session.user_id %}
  158. <a href="cart.php" class="cart-link">🛒 {{ text.header_cart_btn|default('Καλάθι') }}</a>
  159. {% if session.role_id == 2 or session.is_seller == 1 %}
  160. <a href="seller_dashboard.php" class="btn-seller">
  161. 🏪 {% if current_lang == 'en' %}Seller Panel{% else %}Πωλητής{% endif %}
  162. </a>
  163. {% endif %}
  164. <a href="profile.php" title="Το Προφίλ μου" class="btn-profile">👤 {{ session.username }}</a>
  165. <a href="logout.php" title="Αποσύνδεση" class="btn-logout-icon">
  166. <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
  167. <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path>
  168. <polyline points="16 17 21 12 16 7"></polyline>
  169. <line x1="21" y1="12" x2="9" y2="12"></line>
  170. </svg>
  171. </a>
  172. {% else %}
  173. {% if current_lang == 'en' %}
  174. <a href="login.php" class="btn-login">{{ text.header_login_btn|default('Login') }}</a>
  175. <a href="register.php" class="btn-register">{{ text.header_register_btn|default('Register') }}</a>
  176. {% else %}
  177. <a href="login.php" class="btn-login">{{ text.header_login_btn|default('Σύνδεση') }}</a>
  178. <a href="register.php" class="btn-register">{{ text.header_register_btn|default('Εγγραφή') }}</a>
  179. {% endif %}
  180. {% endif %}
  181. </div>
  182. </div>
  183. </div>
  184. </header>
  185. <div class="main-container">
  186. <button id="mobileMenuBtn" class="mobile-menu-toggle">☰ {% if current_lang == "en" %}Show Categories{% else %}Εμφάνιση Κατηγοριών{% endif %}</button>
  187. <aside class="sidebar" id="sidebarMenu">
  188. <h3>{{ text.sidebar_categories_title|default('ΚΑΤΗΓΟΡΙΕΣ') }}</h3>
  189. <ul class="tree-menu">
  190. <!-- ΚΟΥΜΠΙ "ΑΡΧΙΚΗ ΣΕΛΙΔΑ" -->
  191. <li class="menu-item" style="border-bottom: 2px solid rgba(255,255,255,0.05);">
  192. <a href="index.php" class="parent-cat" style="color: var(--text-main); font-weight: 700;">
  193. <span style="display:flex; align-items:center; gap:8px;">
  194. <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
  195. <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path>
  196. <polyline points="9 22 9 12 15 12 15 22"></polyline>
  197. </svg>
  198. {% if current_lang == 'en' %}Home{% else %}Αρχική Σελίδα{% endif %}
  199. </span>
  200. </a>
  201. </li>
  202. {% for cat in categories %}
  203. {% if cat.parent_id is empty %}
  204. {% set has_children = false %}
  205. {% for subcat in categories %}
  206. {% if subcat.parent_id == cat.id %}
  207. {% set has_children = true %}
  208. {% endif %}
  209. {% endfor %}
  210. <li class="menu-item">
  211. <a href="index.php?category_id={{ cat.id }}" class="parent-cat {% if has_children %}has-children{% endif %}">
  212. {{ cat.display_name }}
  213. </a>
  214. {% if has_children %}
  215. <ul class="tree-submenu">
  216. {% for subcat in categories %}
  217. {% if subcat.parent_id == cat.id %}
  218. <li><a href="index.php?category_id={{ subcat.id }}">{{ subcat.display_name }}</a></li>
  219. {% endif %}
  220. {% endfor %}
  221. </ul>
  222. {% endif %}
  223. </li>
  224. {% endif %}
  225. {% endfor %}
  226. </ul>
  227. </aside>
  228. <main class="content-area">
  229. {% block content %}{% endblock %}
  230. </main>
  231. </div>
  232. <footer>
  233. <p>&copy; {{ "now"|date("Y") }} <strong>{{ site_title|default('Hockey CMS') }}</strong>. All rights reserved.</p>
  234. </footer>
  235. <script>
  236. document.addEventListener('DOMContentLoaded', function() {
  237. const menuBtn = document.getElementById('mobileMenuBtn');
  238. const sidebar = document.getElementById('sidebarMenu');
  239. if(menuBtn && sidebar) {
  240. menuBtn.addEventListener('click', function() {
  241. sidebar.classList.toggle('active');
  242. if(sidebar.classList.contains('active')) {
  243. menuBtn.innerHTML = '✕ {% if current_lang == "en" %}Hide Categories{% else %}Απόκρυψη Κατηγοριών{% endif %}';
  244. } else {
  245. menuBtn.innerHTML = '☰ {% if current_lang == "en" %}Show Categories{% else %}Εμφάνιση Κατηγοριών{% endif %}';
  246. }
  247. });
  248. }
  249. });
  250. </script>
  251. {% block extra_js %}{% endblock %}
  252. </body>
  253. </html>