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,39 @@
.relation-behavior {
margin-bottom: 20px;
}
.relation-behavior .control-list {
border: 1px solid #eeeeee;
}
.relation-behavior .control-list thead > tr > th {
border-top: none !important;
border-color: #eeeeee;
}
.relation-behavior .control-toolbar {
padding: 0 20px 20px 20px;
}
.relation-behavior .control-toolbar .toolbar-item .form-control.search {
padding-top: 5px;
padding-bottom: 5px;
}
.relation-behavior .control-toolbar .loading-indicator-container.size-input-text {
min-height: 0;
}
.relation-behavior .control-toolbar .loading-indicator-container.size-input-text .loading-indicator > span {
top: 4px;
}
.relation-behavior .list-header {
padding: 0;
}
.relation-behavior .control-list:last-child > table {
margin-bottom: 0;
}
.relation-flush .control-list {
border-top: none;
}
.relation-inset {
margin-left: -20px;
margin-right: -20px;
}
.form-group > .relation-behavior .control-toolbar {
padding: 0 0 10px 0;
}

View File

@@ -0,0 +1,100 @@
/*
* Scripts for the Relation controller behavior.
*/
+function ($) { "use strict";
var RelationBehavior = function() {
this.toggleListCheckbox = function(el) {
$(el).closest('.control-list').listWidget('toggleChecked', [el])
}
this.clickViewListRecord = function(recordId, relationId, sessionKey) {
var newPopup = $('<a />'),
$container = $('#'+relationId),
requestData = paramToObj('data-request-data', $container.data('request-data'))
newPopup.popup({
handler: 'onRelationClickViewList',
size: 'huge',
extraData: $.extend({}, requestData, {
'manage_id': recordId,
'_session_key': sessionKey
})
})
}
this.clickManageListRecord = function(recordId, relationId, sessionKey) {
var oldPopup = $('#relationManagePopup'),
$container = $('#'+relationId),
requestData = paramToObj('data-request-data', $container.data('request-data'))
$.request('onRelationClickManageList', {
data: $.extend({}, requestData, {
'record_id': recordId,
'_session_key': sessionKey
})
})
oldPopup.popup('hide')
}
this.clickManagePivotListRecord = function(foreignId, relationId, sessionKey) {
var oldPopup = $('#relationManagePivotPopup'),
newPopup = $('<a />'),
$container = $('#'+relationId),
requestData = paramToObj('data-request-data', $container.data('request-data'))
if (oldPopup.length) {
oldPopup.popup('hide')
}
newPopup.popup({
handler: 'onRelationClickManageListPivot',
size: 'huge',
extraData: $.extend({}, requestData, {
'foreign_id': foreignId,
'_session_key': sessionKey
})
})
}
/*
* This function is called every time a record is created, added, removed
* or deleted using the relation widget. It triggers the change.oc.formwidget
* event to notify other elements on the page about the changed form state.
*/
this.changed = function(relationId, event) {
$('[data-field-name="' + relationId + '"]').trigger('change.oc.formwidget', {event: event});
}
/*
* This function transfers the supplied variables as hidden form inputs,
* to any popup that is spawned within the supplied container. The spawned
* popup must contain a form element.
*/
this.bindToPopups = function(container, vars) {
$(container).on('show.oc.popup', function(event, $trigger, $modal){
var $form = $('form', $modal)
$.each(vars, function(name, value){
$form.prepend($('<input />').attr({ type: 'hidden', name: name, value: value }))
})
})
}
function paramToObj(name, value) {
if (value === undefined) value = ''
if (typeof value == 'object') return value
try {
return ocJSON("{" + value + "}")
}
catch (e) {
throw new Error('Error parsing the '+name+' attribute value. '+e)
}
}
}
$.wn.relationBehavior = new RelationBehavior;
}(window.jQuery);

View File

@@ -0,0 +1,60 @@
@import "../../../../assets/less/core/boot.less";
@color-relation-border: #eeeeee;
.relation-behavior {
margin-bottom: 20px;
.control-list {
border: 1px solid @color-relation-border;
thead > tr > th {
border-top: none !important;
border-color: @color-relation-border;
}
}
.control-toolbar {
padding: 0 20px 20px 20px;
.toolbar-item .form-control.search {
padding-top: 5px;
padding-bottom: 5px;
}
.loading-indicator-container.size-input-text {
min-height: 0;
.loading-indicator > span {
top: 4px;
}
}
}
.list-header {
padding: 0;
}
.control-list:last-child > table {
margin-bottom: 0;
}
}
// Relation manager to sit flush to the element above
.relation-flush {
.control-list {
border-top: none;
}
}
// Relation manager to sit inset the standard padding (20px)
.relation-inset {
margin-left: -20px;
margin-right: -20px;
}
// Displayed in a form field
.form-group > .relation-behavior {
.control-toolbar {
padding: 0 0 10px 0;
}
}