templates/admin/product_form.html.twig line 1

Open in your IDE?
  1. {% extends 'admin/base.html.twig' %}
  2. {% block title %}{{ mode == 'new' ? 'Новый товар' : 'Редактирование товара' }}{% endblock %}
  3. {% block heading %}{{ mode == 'new' ? 'Новый товар' : product.name }}{% endblock %}
  4. {% block page_actions %}
  5.   <div class="text-sm-end">
  6.     <a class="btn btn-light me-1" href="{{ path('admin_dashboard') }}#products">Назад</a>
  7.     {% if mode == 'edit' %}
  8.       <a class="btn btn-outline-primary" href="{{ product.product_url }}" target="_blank" rel="noreferrer">Открыть товар</a>
  9.     {% endif %}
  10.   </div>
  11. {% endblock %}
  12. {% block content %}
  13.   <form method="post">
  14.     <div class="row">
  15.       <div class="col-xl-8">
  16.         <div class="card">
  17.           <div class="card-body">
  18.             <div class="d-flex justify-content-between align-items-start flex-wrap gap-2 mb-3">
  19.               <div>
  20.                 <p class="text-muted mb-1">{{ mode == 'new' ? 'Manual' : product.external_code }}</p>
  21.                 <h5 class="mb-0">Основное</h5>
  22.               </div>
  23.               <button class="btn btn-primary" type="submit"><i class="mdi mdi-content-save-outline me-1"></i>Сохранить</button>
  24.             </div>
  25.             <div class="row g-3">
  26.               <div class="col-12">
  27.                 <label class="form-label">Название</label>
  28.                 <input class="form-control" name="name" value="{{ product.name }}" required />
  29.               </div>
  30.               <div class="col-md-3">
  31.                 <label class="form-label">Цена</label>
  32.                 <input class="form-control" name="price_amount" type="number" step="0.01" min="0" value="{{ product.price_amount }}" />
  33.               </div>
  34.               <div class="col-md-3">
  35.                 <label class="form-label">Валюта</label>
  36.                 <select class="form-select" name="price_currency">
  37.                   {% for currency in ['USD', 'RUB', 'EUR', 'KZT'] %}
  38.                     <option value="{{ currency }}" {{ product.price_currency == currency ? 'selected' : '' }}>{{ currency }}</option>
  39.                   {% endfor %}
  40.                 </select>
  41.               </div>
  42.               <div class="col-md-3">
  43.                 <label class="form-label">Скидка, %</label>
  44.                 <input class="form-control" name="discount_percent" type="number" step="0.01" min="0" max="100" value="{{ product.discount_percent }}" placeholder="нет" />
  45.               </div>
  46.               <div class="col-md-3">
  47.                 <label class="form-label">Количество</label>
  48.                 <input class="form-control" name="stock_quantity" type="number" min="0" value="{{ product.stock_quantity }}" placeholder="не задано" />
  49.               </div>
  50.               <div class="col-md-3">
  51.                 <label class="form-label">Регион</label>
  52.                 <input class="form-control" name="region" value="{{ product.region }}" placeholder="RU" />
  53.               </div>
  54.               <div class="col-md-3">
  55.                 <label class="form-label">Steam appid</label>
  56.                 <input class="form-control" name="appid" value="{{ product.appid }}" placeholder="365590" />
  57.               </div>
  58.               <div class="col-md-3">
  59.                 <label class="form-label">Источник</label>
  60.                 <select class="form-select" name="source_id">
  61.                   <option value="">Manual</option>
  62.                   {% for source in sources %}
  63.                     <option value="{{ source.id }}" {{ product.source_id == source.id ? 'selected' : '' }}>{{ source.name }}</option>
  64.                   {% endfor %}
  65.                 </select>
  66.               </div>
  67.               <div class="col-md-3">
  68.                 <label class="form-label">Категория</label>
  69.                 <select class="form-select" name="category_id">
  70.                   <option value="">Ручные товары</option>
  71.                   {% for category in categories %}
  72.                     <option value="{{ category.id }}" {{ product.category_id == category.id ? 'selected' : '' }}>{{ category.name }}</option>
  73.                   {% endfor %}
  74.                 </select>
  75.               </div>
  76.               <div class="col-md-4">
  77.                 <label class="form-label">Provider</label>
  78.                 <input class="form-control" name="provider" value="{{ product.provider }}" />
  79.               </div>
  80.               <div class="col-md-4">
  81.                 <label class="form-label">Provider type</label>
  82.                 <input class="form-control" name="provider_type" value="{{ product.provider_type }}" />
  83.               </div>
  84.               <div class="col-md-4">
  85.                 <label class="form-label">Категория поставщика</label>
  86.                 <input class="form-control" name="provider_category_code" value="{{ product.provider_category_code }}" />
  87.               </div>
  88.               <div class="col-md-6">
  89.                 <label class="form-label">Внешний код</label>
  90.                 {% if mode == 'new' %}
  91.                   <input class="form-control" name="external_code" value="{{ product.external_code }}" placeholder="создастся автоматически" />
  92.                 {% else %}
  93.                   <input class="form-control" value="{{ product.external_code }}" disabled />
  94.                 {% endif %}
  95.               </div>
  96.               <div class="col-md-3 d-flex align-items-end">
  97.                 <div class="form-check form-switch mb-2">
  98.                   <input class="form-check-input" name="is_active" type="checkbox" value="1" id="productActive" {{ product.is_active ? 'checked' : '' }} />
  99.                   <label class="form-check-label" for="productActive">Показывать</label>
  100.                 </div>
  101.               </div>
  102.               <div class="col-md-3 d-flex align-items-end">
  103.                 <div class="form-check form-switch mb-2">
  104.                   <input class="form-check-input" name="in_stock" type="checkbox" value="1" id="productStock" {{ product.in_stock ? 'checked' : '' }} />
  105.                   <label class="form-check-label" for="productStock">В наличии</label>
  106.                 </div>
  107.               </div>
  108.             </div>
  109.           </div>
  110.         </div>
  111.       </div>
  112.       <div class="col-xl-4">
  113.         <div class="card">
  114.           <div class="card-body">
  115.             <p class="text-muted mb-1">Preview</p>
  116.             <h5 class="mb-3">Витрина</h5>
  117.             <div class="admin-preview-product">
  118.               <img src="{{ product.image_url ?: '/assets/product-pubg.png' }}" alt="" />
  119.               <h5>{{ product.name ?: 'Новый товар' }}</h5>
  120.               <div class="d-flex align-items-center gap-2 flex-wrap">
  121.                 <span class="fs-20 fw-semibold text-success">{{ product.price_label }}</span>
  122.                 {% if product.discount_label %}<span class="badge bg-success-subtle text-success">{{ product.discount_label }}</span>{% endif %}
  123.               </div>
  124.               <p class="text-muted mb-0">{{ product.delivery_label }}</p>
  125.             </div>
  126.             <div class="border rounded-2 mt-3">
  127.               <div class="d-flex justify-content-between p-2 border-bottom"><span class="text-muted">Slug</span><strong class="text-truncate ms-2">{{ product.slug ?: 'создастся автоматически' }}</strong></div>
  128.               <div class="d-flex justify-content-between p-2 border-bottom"><span class="text-muted">Галерея</span><strong>{{ product.gallery_count }} фото</strong></div>
  129.               <div class="d-flex justify-content-between p-2 border-bottom"><span class="text-muted">Формы заказа</span><strong>{{ product.forms_count }}</strong></div>
  130.               <div class="d-flex justify-content-between p-2"><span class="text-muted">Raw/manual</span><strong>{{ product.is_manual ? 'manual' : 'provider' }}</strong></div>
  131.             </div>
  132.           </div>
  133.         </div>
  134.       </div>
  135.     </div>
  136.     <div class="row">
  137.       <div class="col-xl-6">
  138.         <div class="card">
  139.           <div class="card-body">
  140.             <p class="text-muted mb-1">Контент</p>
  141.             <h5 class="mb-3">Описание и медиа</h5>
  142.             <div class="mb-3">
  143.               <label class="form-label">Главная картинка</label>
  144.               <input class="form-control" name="image_url" value="{{ product.image_url }}" placeholder="https://..." />
  145.             </div>
  146.             <div class="mb-3">
  147.               <label class="form-label">Короткое описание HTML</label>
  148.               <textarea class="form-control admin-codearea" name="short_description_html" rows="4">{{ product.short_description_html }}</textarea>
  149.             </div>
  150.             <div class="mb-3">
  151.               <label class="form-label">Полное описание HTML</label>
  152.               <textarea class="form-control admin-codearea" name="description_html" rows="10">{{ product.description_html }}</textarea>
  153.             </div>
  154.             <div>
  155.               <label class="form-label">Галерея JSON</label>
  156.               <textarea class="form-control admin-codearea" name="gallery_json" rows="8">{{ product.gallery_json ?: '[]' }}</textarea>
  157.             </div>
  158.           </div>
  159.         </div>
  160.       </div>
  161.       <div class="col-xl-6">
  162.         <div class="card">
  163.           <div class="card-body">
  164.             <p class="text-muted mb-1">Поставщик</p>
  165.             <h5 class="mb-3">Формы и метаданные</h5>
  166.             <div class="mb-3">
  167.               <label class="form-label">Forms JSON</label>
  168.               <textarea class="form-control admin-codearea" name="forms_json" rows="5">{{ product.forms_json ?: '[]' }}</textarea>
  169.             </div>
  170.             <div class="mb-3">
  171.               <label class="form-label">Metadata JSON</label>
  172.               <textarea class="form-control admin-codearea" name="metadata_json" rows="7">{{ product.metadata_json ?: '[]' }}</textarea>
  173.             </div>
  174.             {% if product.raw_json is defined %}
  175.               <div>
  176.                 <label class="form-label">Raw JSON поставщика</label>
  177.                 <textarea class="form-control admin-codearea" rows="8" readonly>{{ product.raw_json }}</textarea>
  178.               </div>
  179.             {% endif %}
  180.           </div>
  181.         </div>
  182.       </div>
  183.     </div>
  184.     {% if variants %}
  185.       <div class="row">
  186.         <div class="col-12">
  187.           <div class="card">
  188.             <div class="card-body">
  189.               <p class="text-muted mb-1">Steam appid {{ product.appid }}</p>
  190.               <h5 class="mb-3">Другие варианты этой игры</h5>
  191.               <div class="table-responsive">
  192.                 <table class="table table-hover align-middle mb-0">
  193.                   <thead>
  194.                     <tr>
  195.                       <th>ID</th>
  196.                       <th>Название</th>
  197.                       <th>Цена</th>
  198.                       <th>Скидка</th>
  199.                       <th>Статус</th>
  200.                       <th class="text-end">Действие</th>
  201.                     </tr>
  202.                   </thead>
  203.                   <tbody>
  204.                     {% for variant in variants %}
  205.                       <tr>
  206.                         <td>{{ variant.id }}</td>
  207.                         <td>
  208.                           <h6 class="mb-0">{{ variant.name }}</h6>
  209.                           <small class="text-muted">{{ variant.external_code }}</small>
  210.                         </td>
  211.                         <td>{{ variant.price_label }}</td>
  212.                         <td>{{ variant.discount_label ?: 'нет' }}</td>
  213.                         <td>{{ variant.is_active ? 'активен' : 'скрыт' }} · {{ variant.in_stock ? 'в наличии' : 'нет' }}</td>
  214.                         <td class="text-end"><a class="btn btn-sm btn-light" href="{{ path('admin_product_edit', {'id': variant.id}) }}">Открыть</a></td>
  215.                       </tr>
  216.                     {% endfor %}
  217.                   </tbody>
  218.                 </table>
  219.               </div>
  220.             </div>
  221.           </div>
  222.         </div>
  223.       </div>
  224.     {% endif %}
  225.     <div class="card sticky-bottom admin-sticky-actions">
  226.       <div class="card-body py-2 d-flex justify-content-end gap-2">
  227.         <a class="btn btn-light" href="{{ path('admin_dashboard') }}#products">Назад</a>
  228.         <button class="btn btn-primary" type="submit">Сохранить товар</button>
  229.       </div>
  230.     </div>
  231.   </form>
  232. {% endblock %}