| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- {% extends "base.html.twig" %}
- {% block title %}{{ t.seller_panel }} - {{ site_title }}{% endblock %}
- {% block extra_css %}
- <style>
- /* --- SELLER DASHBOARD STYLES --- */
- .dashboard-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 25px; border-bottom: 2px solid var(--border-color); padding-bottom: 15px; }
- .dashboard-header h2 { margin: 0; color: var(--primary); font-size: 24px; text-transform: uppercase; letter-spacing: 1px; font-weight: 800; display: flex; align-items: center; gap: 10px; }
-
- .dashboard-nav { display: flex; gap: 10px; }
- .nav-btn { padding: 10px 15px; border-radius: 6px; text-decoration: none; font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; transition: 0.2s; border: 1px solid transparent; }
- .nav-btn.active { background: rgba(249, 115, 22, 0.1); color: var(--primary); border-color: rgba(249, 115, 22, 0.2); }
- .nav-btn:not(.active) { background: rgba(255,255,255,0.05); color: var(--text-main); border-color: var(--border-color); }
- .nav-btn:hover { background: rgba(255,255,255,0.1); }
- .dashboard-grid { display: grid; grid-template-columns: 1.2fr 2fr; gap: 30px; }
-
- .panel-card { background: var(--panel-bg); padding: 30px; border-radius: var(--border-radius); box-shadow: var(--shadow-sm); border: 1px solid var(--border-color); }
- .panel-card h3 { margin-top: 0; border-bottom: 1px solid rgba(255,255,255,0.05); padding-bottom: 15px; color: var(--text-main); font-size: 18px; text-transform: uppercase; letter-spacing: 1px; }
-
- .form-group { margin-bottom: 20px; }
- .form-group label { display: block; margin-bottom: 8px; font-weight: 700; font-size: 13px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px;}
- .form-group input[type="text"], .form-group input[type="number"], .form-group select, .form-group textarea { width: 100%; padding: 12px; background: #0f172a; border: 1px solid var(--border-color); border-radius: 6px; box-sizing: border-box; font-family: 'Inter', sans-serif; color: var(--text-main); outline: none; transition: 0.2s; }
- .form-group input:focus, .form-group select:focus, .form-group textarea:focus { border-color: var(--primary); box-shadow: 0 0 0 2px rgba(249, 115, 22, 0.2); }
- .form-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; }
-
- .btn-submit { padding: 14px 20px; background: var(--primary); color: #fff; border: none; border-radius: 6px; cursor: pointer; font-weight: 800; width: 100%; font-size: 15px; text-transform: uppercase; letter-spacing: 1px; transition: 0.2s; }
- .btn-submit:hover { background: var(--primary-hover); transform: translateY(-1px); box-shadow: 0 4px 15px rgba(249, 115, 22, 0.3); }
-
- .btn-cancel { background: rgba(255,255,255,0.05); border: 1px solid var(--border-color); color: var(--text-main); padding: 14px 20px; border-radius: 6px; display: block; text-align: center; font-weight: 700; margin-top: 10px; text-decoration: none; text-transform: uppercase; transition: 0.2s;}
- .btn-cancel:hover { background: rgba(255,255,255,0.1); }
-
- .alert { padding: 15px; border-radius: 6px; margin-bottom: 20px; font-weight: 600; font-size: 14px;}
- .success { background: rgba(16, 185, 129, 0.1); color: var(--accent-green); border: 1px solid rgba(16, 185, 129, 0.2); }
- .error { background: rgba(239, 68, 68, 0.1); color: #ef4444; border: 1px solid rgba(239, 68, 68, 0.2); }
-
- .tags-input-container { display: flex; flex-wrap: wrap; gap: 5px; padding: 8px 10px; border: 1px solid var(--border-color); border-radius: 6px; background: #0f172a; align-items: center; cursor: text; }
- .tags-input-container input { border: none; outline: none; flex-grow: 1; padding: 4px; min-width: 150px; font-family: 'Inter', sans-serif; font-size: 14px; background: transparent; color: var(--text-main); }
- .tag-chip { background: rgba(255,255,255,0.1); color: var(--text-main); padding: 4px 10px; border-radius: 16px; font-size: 12px; font-weight: 600; display: flex; align-items: center; gap: 6px; border: 1px solid rgba(255,255,255,0.05);}
- .tag-chip span { cursor: pointer; color: var(--text-muted); font-weight: bold; font-size: 15px; line-height: 1; transition: 0.2s;}
- .tag-chip span:hover { color: #ef4444; }
- /* LISTINGS */
- .prod-list { list-style: none; padding: 0; margin: 0; }
- .prod-item { display: flex; gap: 15px; align-items: center; padding: 20px 0; border-bottom: 1px solid rgba(255,255,255,0.05); }
- .prod-item:last-child { border-bottom: none; }
- .prod-info-wrap { display: flex; gap: 15px; flex-grow: 1; align-items: center; }
- .prod-thumb { width: 75px; height: 75px; object-fit: cover; border-radius: 6px; background: #0f172a; flex-shrink: 0; border: 1px solid var(--border-color); }
-
- .prod-info { flex-grow: 1; min-width: 0; }
- .prod-info h4 { margin: 0 0 4px 0; color: var(--text-main); font-size: 16px; font-weight: 700;}
- .prod-info p { margin: 0; font-size: 13px; color: var(--text-muted); }
- .prod-info p strong { color: var(--accent-green); font-size: 15px;}
-
- .prod-info .tags-display { font-size: 11px; margin-top: 8px; display: flex; flex-wrap: wrap; gap: 6px; }
- .prod-info .tags-display span { background: rgba(59, 130, 246, 0.1); color: var(--accent-blue); border-radius: 12px; padding: 3px 8px; border: 1px solid rgba(59, 130, 246, 0.2); font-weight: 600;}
-
- .badge { padding: 4px 10px; border-radius: 20px; font-size: 11px; font-weight: 800; color: #fff; text-transform: uppercase; display: inline-block; margin-top: 8px; letter-spacing: 0.5px;}
- .badge-available { background: var(--accent-green); }
- .badge-sold { background: #ef4444; }
- .badge-hidden { background: var(--text-muted); color: #0b1120; }
- .actions { display: flex; gap: 8px; flex-shrink: 0; }
- .act-btn { padding: 8px 15px; border-radius: 6px; font-size: 12px; text-decoration: none; font-weight: 700; cursor: pointer; border: none; text-align: center; text-transform: uppercase; transition: 0.2s;}
- .act-edit { background: rgba(249, 115, 22, 0.1); color: var(--primary); border: 1px solid rgba(249, 115, 22, 0.2); }
- .act-edit:hover { background: var(--primary); color: white; }
- .act-del { background: rgba(239, 68, 68, 0.1); color: #ef4444; border: 1px solid rgba(239, 68, 68, 0.2); }
- .act-del:hover { background: #ef4444; color: white; }
- @media (max-width: 992px) {
- .dashboard-grid { grid-template-columns: 1fr; }
- .dashboard-header { flex-direction: column; gap: 15px; text-align: center; }
- }
- </style>
- {% endblock %}
- {% block content %}
- <div class="dashboard-header">
- <h2>🏪 {{ t.seller_panel }}</h2>
- <div class="dashboard-nav">
- <a href="seller_dashboard.php" class="nav-btn active">{{ t.my_listings }}</a>
- <a href="seller_orders.php" class="nav-btn">{{ t.customer_orders }}</a>
- </div>
- </div>
- <div class="dashboard-grid">
- <!-- ΑΡΙΣΤΕΡΑ: Φόρμα Ανάρτησης -->
- <div class="panel-card">
- <h3>{% if edit_product %}{{ t.edit_listing }}{% else %}{{ t.add_listing }}{% endif %}</h3>
-
- {% if message %}
- {{ message|raw }}
- {% endif %}
-
- <form method="POST" enctype="multipart/form-data">
- <input type="hidden" name="action" value="{% if edit_product %}edit_product{% else %}add_product{% endif %}">
- {% if edit_product %}
- <input type="hidden" name="product_id" value="{{ edit_product.id }}">
- {% endif %}
-
- <div class="form-group">
- <label>{{ t.title }}</label>
- <input type="text" name="title" value="{{ edit_product.title|default('') }}" required>
- </div>
- <!-- ΝΕΟ ΠΕΔΙΟ: SKU / Αύξων Αριθμός -->
- <div class="form-group">
- <label>{{ t.sku|default('Κωδικός / Αύξων Αριθμός (SKU)') }}</label>
- <input type="text" name="sku" value="{{ edit_product.sku|default('') }}" placeholder="π.χ. 001, 002...">
- </div>
- <div class="form-group">
- <label>{{ t.category }}</label>
- <select name="category_id" id="category_select" required onchange="loadAttributes(this.value); generateSku(this.value);">
- <option value="">{{ t.select_cat }}</option>
- {% for cat in categories %}
- <option value="{{ cat.id }}" {% if edit_product and edit_product.category_id == cat.id %}selected{% endif %}>
- {{ cat.display_name }}
- </option>
- {% endfor %}
- </select>
- </div>
- <div class="form-cols">
- <div class="form-group">
- <label>{{ t.price }}</label>
- <input type="number" step="0.01" name="price" value="{{ edit_product.price|default('') }}" required>
- </div>
- <div class="form-group">
- <label>{{ t.stock }}</label>
- <input type="number" name="quantity" value="{{ edit_product.quantity|default(1) }}" min="1" required>
- </div>
- </div>
-
- <div class="form-group">
- <label>{{ t.tags }}</label>
- <div class="tags-input-container" id="tags_container">
- <input type="text" id="tag_input_field" placeholder="{{ t.tags_placeholder }}">
- </div>
- <input type="hidden" name="search_tags" id="hidden_search_tags" value="{{ edit_product.search_tags|default('') }}">
- </div>
- <div id="dynamic-attributes-container" style="background: rgba(0,0,0,0.1); padding: 5px 20px; border-radius: 8px; border: 1px solid var(--border-color); margin-bottom: 20px; display: none;"></div>
- <div class="form-group">
- <label>{{ t.description }}</label>
- <textarea name="description" rows="4">{{ edit_product.description|default('') }}</textarea>
- </div>
- <div class="form-group">
- <label>{{ t.listing_status }}</label>
- <select name="status">
- <option value="available" {% if edit_product and edit_product.status == 'available' %}selected{% endif %}>{{ t.status_opt_available }}</option>
- <option value="hidden" {% if edit_product and edit_product.status == 'hidden' %}selected{% endif %}>{{ t.status_opt_hidden }}</option>
- <option value="sold" {% if edit_product and edit_product.status == 'sold' %}selected{% endif %}>{{ t.status_opt_sold }}</option>
- </select>
- </div>
- <div class="form-group" style="background: rgba(0,0,0,0.15); padding: 15px; border-radius: 6px; border: 1px dashed var(--border-color);">
- <label style="color: var(--text-main); margin-bottom: 10px;">{{ t.photo }} <span style="color: var(--text-muted); font-size: 11px;">{% if edit_product %}{{ t.photo_opt }}{% else %}{{ t.photo_req }}{% endif %}</span></label>
- <input type="file" name="image" accept="image/jpeg, image/png, image/gif" style="background: transparent; border: none; padding: 0;">
- </div>
-
- <button type="submit" class="btn-submit">{% if edit_product %}{{ t.btn_save }}{% else %}{{ t.btn_upload }}{% endif %}</button>
-
- {% if edit_product %}
- <a href="seller_dashboard.php" class="btn-cancel">{{ t.btn_cancel }}</a>
- {% endif %}
- </form>
- </div>
- <!-- ΔΕΞΙΑ: Οι αγγελίες μου -->
- <div class="panel-card">
- <h3>{{ t.my_listings|default('Οι Αγγελίες Μου') }} ({{ my_products|length }})</h3>
-
- {% if my_products|length > 0 %}
- <ul class="prod-list">
- {% for prod in my_products %}
- {% set disp_cat = (current_lang == 'en' and prod.cat_name_en) ? prod.cat_name_en : prod.cat_name_el %}
-
- <li class="prod-item">
- <div class="prod-info-wrap">
- {% if prod.image_path %}
- <img src="{{ prod.image_path }}" class="prod-thumb">
- {% else %}
- <div class="prod-thumb" style="display:flex; align-items:center; justify-content:center; font-size:11px; color:var(--text-muted); font-weight: bold;">{{ t.no_img }}</div>
- {% endif %}
-
- <div class="prod-info">
- <h4>
- {{ prod.title }}
- </h4>
- {% if prod.sku %}
- <p style="margin-bottom: 4px; font-size: 12px; color: var(--text-muted);">
- {{ t.sku|default('SKU') }}: <strong style="color: var(--text-main); font-size: 12px;">{{ prod.sku }}</strong>
- </p>
- {% endif %}
- <p>{{ disp_cat }} | <strong>{{ prod.price }} €</strong> | {{ t.stock_short }} {{ prod.quantity }}</p>
-
- {% if prod.search_tags %}
- <div class="tags-display">
- {% for tag in prod.search_tags|split(',') %}
- <span>{{ tag|trim }}</span>
- {% endfor %}
- </div>
- {% endif %}
-
- {% set status_class = 'badge-available' %}
- {% set status_label = t.status_active %}
- {% if prod.status == 'sold' %}
- {% set status_class = 'badge-sold' %}
- {% set status_label = t.status_sold %}
- {% elseif prod.status == 'hidden' %}
- {% set status_class = 'badge-hidden' %}
- {% set status_label = t.status_hidden %}
- {% endif %}
-
- <span class="badge {{ status_class }}">
- {{ status_label }}
- </span>
- </div>
- </div>
-
- <div class="actions">
- <a href="seller_dashboard.php?edit={{ prod.id }}" class="act-btn act-edit">Edit</a>
- <form method="POST" onsubmit="return confirm('{{ t.confirm_delete }}');" style="margin:0;">
- <input type="hidden" name="action" value="delete_product">
- <input type="hidden" name="product_id" value="{{ prod.id }}">
- <button type="submit" class="act-btn act-del">Del</button>
- </form>
- </div>
- </li>
- {% endfor %}
- </ul>
- {% else %}
- <div style="text-align: center; padding: 60px 20px; color: var(--text-muted);">
- <span style="font-size: 50px; display: block; margin-bottom: 15px; opacity: 0.5;">📦</span>
- <strong style="font-size: 16px; color: var(--text-main);">{{ t.no_listings }}</strong><br><br>
- {{ t.use_form }}
- </div>
- {% endif %}
- </div>
- </div>
- {% endblock %}
- {% block extra_js %}
- <script>
- document.addEventListener('DOMContentLoaded', function() {
- const tagContainer = document.getElementById('tags_container');
- const tagInput = document.getElementById('tag_input_field');
- const hiddenTagsInput = document.getElementById('hidden_search_tags');
- let tags = [];
-
- if (hiddenTagsInput.value.trim() !== '') {
- tags = hiddenTagsInput.value.split(',').map(t => t.trim()).filter(t => t !== '');
- renderTags();
- }
- tagContainer.addEventListener('click', () => tagInput.focus());
- tagInput.addEventListener('keydown', function(e) {
- if (e.key === 'Enter' || e.key === ',') {
- e.preventDefault();
- addTag(tagInput.value);
- } else if (e.key === 'Backspace' && tagInput.value === '' && tags.length > 0) {
- removeTag(tags.length - 1);
- }
- });
- function addTag(tag) {
- tag = tag.replace(/,/g, '').trim();
- if (tag !== '' && !tags.includes(tag)) {
- tags.push(tag);
- updateHiddenAndRender();
- }
- tagInput.value = '';
- }
- window.removeTagEl = function(index) {
- tags.splice(index, 1);
- updateHiddenAndRender();
- }
- function removeTag(index) { window.removeTagEl(index); }
- function updateHiddenAndRender() {
- hiddenTagsInput.value = tags.join(', ');
- renderTags();
- }
- function renderTags() {
- tagContainer.querySelectorAll('.tag-chip').forEach(chip => chip.remove());
- tags.forEach((tag, index) => {
- const chip = document.createElement('div');
- chip.className = 'tag-chip';
- chip.innerHTML = `${tag} <span onclick="window.removeTagEl(${index})">×</span>`;
- tagContainer.insertBefore(chip, tagInput);
- });
- }
- });
- function loadAttributes(categoryId, productId = 0) {
- const container = document.getElementById('dynamic-attributes-container');
- if (!categoryId) {
- container.style.display = 'none';
- container.innerHTML = '';
- return;
- }
-
- let url = 'seller_dashboard.php?ajax_get_attributes=1&category_id=' + categoryId;
- if (productId > 0) { url += '&product_id=' + productId; }
-
- fetch(url)
- .then(response => response.text())
- .then(html => {
- html = html.replace("grid-template-columns: 1fr 1fr;", "");
- if (html.trim() !== '') {
- container.innerHTML = html;
- container.style.display = 'block';
- } else {
- container.style.display = 'none';
- container.innerHTML = '';
- }
- })
- .catch(error => console.error('Error:', error));
- }
- {% if edit_product %}
- window.addEventListener('DOMContentLoaded', () => {
- loadAttributes({{ edit_product.category_id }}, {{ edit_product.id }});
- });
- {% endif %}
- </script>
- {% endblock %}
|