feat: VivesPOS landing on Winter CMS 1.2 — theme + plugin + Dockerfile
Some checks are pending
Module sub-split / Sub-split (push) Waiting to run

- Base: wintercms/winter branch 1.2 (full framework)
- Theme vivespos: Canvas 7 + Bootstrap 5 CDN, custom CSS
- Layout: deferred GTM/GA4 tracking, JSON-LD SoftwareApplication
- Partials: hero (offline-first), features, modes (offline/nube toggle),
  screenshots, pricing (3 planes), comparison, FAQ, CTA
- Plugin VivesPOS.Site with ContactForm
- Dockerfile: PHP 8.2 Apache, port 80, healthcheck
- Added winter/wn-pages, blog, sitemap, seo plugins
- Active theme set to vivespos
This commit is contained in:
2026-08-21 19:29:00 -06:00
commit 1f72193a64
3266 changed files with 531480 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
<div class="field-repeater"
data-control="fieldrepeater"
<?= $titleFrom ? 'data-title-from="'.$titleFrom.'"' : '' ?>
<?= $minItems ? 'data-min-items="'.$minItems.'"' : '' ?>
<?= $maxItems ? 'data-max-items="'.$maxItems.'"' : '' ?>
<?= $style ? 'data-style="'.$style.'"' : '' ?>
data-mode="<?= $mode ?>"
<?php if ($mode === 'grid'): ?>
data-columns="<?= $columns ?>"
<?php endif ?>
<?php if ($sortable): ?>
data-sortable="true"
data-sortable-container="#<?= $this->getId('items') ?>"
data-sortable-handle=".<?= $this->getId('items') ?>-handle"
<?php endif; ?>
>
<?php if (!$this->previewMode): ?>
<input type="hidden" name="<?= $this->getFieldName(); ?>">
<?php endif ?>
<ul id="<?= $this->getId('items') ?>" class="field-repeater-items">
<?php foreach ($formWidgets as $index => $widget): ?>
<?= $this->makePartial('repeater_item', [
'widget' => $widget,
'indexValue' => $index,
]) ?>
<?php endforeach ?>
<?= $this->makePartial('repeater_add_item') ?>
</ul>
<?php if (!$this->previewMode): ?>
<input type="hidden" name="<?= $this->alias; ?>_loaded" value="1">
<?php endif ?>
<script type="text/template" data-group-palette-template>
<div class="popover-head">
<h3><?= e(trans($prompt)) ?></h3>
<button type="button" class="close"
data-dismiss="popover"
aria-hidden="true">&times;</button>
</div>
<div class="repeater-group-search-container">
<div>
<label for="repeater-group-search-<?= $this->getId() ?>" class="sr-only">Search items</label>
<i class="icon-search"></i>
<input type="text"
id="repeater-group-search-<?= $this->getId() ?>"
class="form-control repeater-group-search"
placeholder="Search items..."
autocomplete="off">
<button type="button" class="repeater-group-search-clear">
<i class="icon-close"></i>
</button>
</div>
</div>
<div class="repeater-group-no-results">
No items found
</div>
<div class="popover-fixed-height repeater-group-items-container">
<div class="control-scrollpad" data-control="scrollpad">
<div class="scroll-wrapper">
<div class="control-filelist filelist-hero repeater-group-grid" data-control="filelist">
<?php foreach ($groupDefinitions as $item): ?>
<div class="repeater-group-item">
<a
href="javascript:;"
data-repeater-add
data-request="<?= $this->getEventHandler('onAddItem') ?>"
data-request-data="_repeater_group: '<?= $item['code'] ?>'">
<i class="<?= $item['icon'] ?>"></i>
<div>
<span class="title"><?= e(trans($item['name'])) ?></span>
<span class="description"><?= e(trans($item['description'])) ?></span>
</div>
</a>
</div>
<?php endforeach ?>
</div>
</div>
</div>
</div>
</script>
</div>

View File

@@ -0,0 +1,26 @@
<?php if (!$this->previewMode): ?>
<li
id="<?= $this->getId('add-item') ?>"
class="field-repeater-add-item loading-indicator-container indicator-center"
<?php if ($mode === 'grid'): ?>
style="min-height: <?= $rowHeight ?>px"
<?php endif ?>
>
<?php if ($useGroups): ?>
<a
href="javascript:;"
data-repeater-add-group
data-load-indicator>
<span><?= e(trans($prompt)) ?></span>
</a>
<?php else: ?>
<a
href="javascript:;"
data-repeater-add
data-request="<?= $this->getEventHandler('onAddItem') ?>"
data-load-indicator>
<span><?= e(trans($prompt)) ?></span>
</a>
<?php endif ?>
</li>
<?php endif ?>

View File

@@ -0,0 +1,56 @@
<?php
$groupCode = $useGroups ? $this->getGroupCodeFromIndex($indexValue) : '';
$itemTitle = $useGroups ? $this->getGroupTitle($groupCode) : null;
?>
<li
<?= $itemTitle ? 'data-collapse-title="'.e(trans($itemTitle)).'"' : '' ?>
class="field-repeater-item"
<?php if ($mode === 'grid'): ?>
style="min-height: <?= $rowHeight ?>px"
<?php endif ?>
>
<?php if (!$this->previewMode): ?>
<?php if ($sortable): ?>
<div class="repeater-item-handle <?= $this->getId('items') ?>-handle">
<i class="icon-bars"></i>
</div>
<?php endif; ?>
<div class="repeater-item-remove">
<button
type="button"
class="close"
aria-label="Remove"
data-repeater-remove
data-request="<?= $this->getEventHandler('onRemoveItem') ?>"
data-request-data="'_repeater_index': '<?= $indexValue ?>', '_repeater_group': '<?= $groupCode ?>'"
data-request-confirm="<?= e(trans('backend::lang.form.action_confirm')) ?>">
<span aria-hidden="true">&times;</span>
</button>
</div>
<?php endif ?>
<?php if ($mode !== 'grid'): ?>
<div class="repeater-item-collapse">
<a href="javascript:;" class="repeater-item-collapse-one">
<i class="icon-chevron-up"></i>
</a>
</div>
<div class="repeater-item-collapsed-title"></div>
<?php endif ?>
<div class="field-repeater-form"
data-control="formwidget"
data-refresh-handler="<?= $this->getEventHandler('onRefresh') ?>"
data-refresh-data="'_repeater_index': '<?= $indexValue ?>', '_repeater_group': '<?= $groupCode ?>'">
<?php foreach ($widget->getFields() as $field): ?>
<?= $widget->renderField($field) ?>
<?php endforeach ?>
<?php if ($useGroups): ?>
<input type="hidden" name="<?= $widget->arrayName ?>[_group]" value="<?= $groupCode ?>" />
<?php endif ?>
</div>
</li>