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,97 @@
<?php namespace Cms\FormWidgets;
use Backend\Classes\FormWidgetBase;
use Cms\Classes\ComponentManager;
use Cms\Classes\ComponentHelpers;
use Cms\Components\SoftComponent;
use Cms\Components\UnknownComponent;
use Exception;
/**
* Component Builder
* Builds a collection of Cms components and configures them.
*
* @package winter\wn-cms-module
* @author Alexey Bobkov, Samuel Georges
*/
class Components extends FormWidgetBase
{
/**
* @inheritDoc
*/
public function render()
{
$components = $this->listComponents();
return $this->makePartial('formcomponents', ['components' => $components]);
}
protected function listComponents()
{
$result = [];
if (!isset($this->model->settings['components'])) {
return $result;
}
$manager = ComponentManager::instance();
$manager->listComponents();
foreach ($this->model->settings['components'] as $name => $properties) {
list($name, $alias) = strpos($name, ' ') ? explode(' ', $name) : [$name, $name];
try {
$componentObj = $manager->makeComponent($name, null, $properties);
$componentObj->alias = ((starts_with($name, '@') && $alias !== $name) ? '@' : '') . $alias;
$componentObj->pluginIcon = 'icon-puzzle-piece';
/*
* Look up the plugin hosting this component
*/
$plugin = $manager->findComponentPlugin($componentObj);
if ($plugin) {
$pluginDetails = $plugin->pluginDetails();
if (isset($pluginDetails['icon'])) {
$componentObj->pluginIcon = $pluginDetails['icon'];
}
}
}
catch (Exception $ex) {
if (starts_with($name, '@')) {
$componentObj = new SoftComponent($properties);
$componentObj->name = $name;
$componentObj->alias = (($alias !== $name) ? '@' : '') . $alias;
$componentObj->pluginIcon = 'icon-flag';
} else {
$componentObj = new UnknownComponent(null, $properties, $ex->getMessage());
$componentObj->alias = $alias;
$componentObj->pluginIcon = 'icon-bug';
}
}
$result[] = $componentObj;
}
return $result;
}
protected function getComponentName($component)
{
return ComponentHelpers::getComponentName($component);
}
protected function getComponentDescription($component)
{
return ComponentHelpers::getComponentDescription($component);
}
protected function getComponentsPropertyConfig($component)
{
return ComponentHelpers::getComponentsPropertyConfig($component);
}
protected function getComponentPropertyValues($component)
{
return ComponentHelpers::getComponentPropertyValues($component);
}
}

View File

@@ -0,0 +1,32 @@
<?php namespace Cms\FormWidgets;
use Backend\FormWidgets\MediaFinder as BackendMediaFinder;
/**
* Media Finder
* Renders a record finder field.
*
* image:
* label: Some image
* type: media
* prompt: Click the %s button to find a user
*
* @package winter\wn-cms-module
* @author Alexey Bobkov, Samuel Georges
* @deprecated Use Backend\FormWidgets\MediaFinder. Remove if year >= 2020.
*/
class MediaFinder extends BackendMediaFinder
{
/**
* Constructor.
*/
public function __construct()
{
traceLog('FormWidget Cms\FormWidgets\MediaFinder has been deprecated, use ' . BackendMediaFinder::class . ' instead.');
$this->assetPath = '/modules/backend/formwidgets/mediafinder/assets';
$this->viewPath = base_path('/modules/backend/formwidgets/mediafinder/partials');
parent::__construct(...func_get_args());
}
}

View File

@@ -0,0 +1,20 @@
<div class="layout-cell <?= e($component->componentCssClass) ?> <?= $component->isHidden ? 'hidden' : null ?>">
<div
class="<?= 'wn-'.$component->pluginIcon ?> layout-relative"
<?php if ($component->inspectorEnabled): ?>
data-inspectable
<?php endif ?>
data-inspector-title="<?= $name = e($this->getComponentName($component)) ?>"
data-inspector-description="<?= $description = e($this->getComponentDescription($component)) ?>"
data-inspector-config="<?= e($this->getComponentsPropertyConfig($component)) ?>"
data-inspector-class="<?= get_class($component) ?>"
>
<span class="name"><?= $name ?></span>
<span class="description"><?= $description ?></span>
<span class="alias wn-icon-code"><?= e($component->alias) ?></span>
<input type="hidden" name="component_properties[]" data-inspector-values value="<?= e($this->getComponentPropertyValues($component)) ?>" />
<input type="hidden" name="component_names[]" value="<?= e($component->name) ?>" />
<input type="hidden" name="component_aliases[]" value="<?= e($component->alias) ?>" />
<a href="#" class="remove">&times;</a>
</div>
</div>

View File

@@ -0,0 +1,17 @@
<div class="control-componentlist bg-s">
<?php foreach ($components as $component): ?>
<?php if ($component->isHidden): ?>
<?= $this->makePartial('component', ['component' => $component]) ?>
<?php endif ?>
<?php endforeach ?>
<div class="components" data-control="toolbar">
<div class="layout">
<?php foreach ($components as $component): ?>
<?php if (!$component->isHidden): ?>
<?= $this->makePartial('component', ['component' => $component]) ?>
<?php endif ?>
<?php endforeach ?>
</div>
</div>
</div>