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 @@
<?php
namespace System\Console\Asset\Npm;
use Symfony\Component\Process\Exception\ProcessSignaledException;
use Symfony\Component\Process\Process;
use System\Classes\Asset\PackageJson;
use System\Classes\Asset\PackageManager;
use Winter\Storm\Console\Command;
use Winter\Storm\Exception\SystemException;
abstract class NpmCommand extends Command
{
/**
* Gets a package config and its PackageJson file based on the `package` argument.
* @throws SystemException
* @throws \JsonException
*/
protected function getPackage(): ?array
{
$compilableAssets = PackageManager::instance();
$compilableAssets->fireCallbacks();
$name = $this->argument('package');
if (!$name) {
return null;
}
if (!$compilableAssets->hasPackage($name, true)) {
throw new SystemException(sprintf('Package "%s" is not a registered package.', $name));
}
$package = $compilableAssets->getPackage($name, true)[0] ?? [];
// Assume that packages with matching names have matching package.json files
$packageJson = new PackageJson($package['package'] ?? null);
return [$package, $packageJson];
}
/**
* Starts a npm process with the command and cwd provided
*/
protected function npmRun(array $command, string $path): int
{
$process = new Process(
$command,
base_path($path),
['NODE_ENV' => $this->getNodeEnv()],
null,
null
);
if (!$this->option('disable-tty') && !$this->option('silent')) {
try {
$process->setTty(true);
} catch (ProcessSignaledException $e) {
if (extension_loaded('pcntl') && $e->getSignal() !== SIGINT) {
throw $e;
}
return 1;
} catch (\Throwable $e) {
// This will fail on unsupported systems
}
}
return $process->run(function ($status, $stdout) {
if (!$this->option('silent')) {
$this->getOutput()->write($stdout);
}
});
}
/**
* Get the env env to provide to node
*/
protected function getNodeEnv(): string
{
if (!$this->hasOption('production')) {
return 'development';
}
return $this->option('production', false) ? 'production' : 'development';
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace System\Console\Asset\Npm;
use System\Console\Asset\Npm\NpmCommand;
use Winter\Storm\Exception\SystemException;
class NpmInstall extends NpmCommand
{
/**
* @var string|null The default command name for lazy loading.
*/
protected static $defaultName = 'npm:install';
/**
* @inheritDoc
*/
protected $description = 'Install Node.js dependencies for a package';
/**
* @inheritDoc
*/
protected $signature = 'npm:install
{package? : The package name to add configuration for}
{npmArgs?* : Arguments to pass through to the "npm" binary}
{--npm= : Defines a custom path to the "npm" binary}
{--d|dev : Install packages in devDependencies}
{--s|silent : Silent mode.}
{--disable-tty : Disable tty mode}';
/**
* Execute the console command.
*/
public function handle(): int
{
$command = ($this->argument('npmArgs')) ?? [];
try {
[$package, $packageJson] = $this->getPackage();
} catch (SystemException $e) {
if (!str_contains($e->getMessage(), 'is not a registered package.')) {
throw $e;
}
array_unshift($command, $this->argument('package'));
}
array_unshift($command, 'npm', 'install');
if ($this->option('dev')) {
$command[] = '--save-dev';
}
return $this->npmRun($command, $package['path'] ?? '');
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace System\Console\Asset\Npm;
use System\Console\Asset\Npm\NpmCommand;
class NpmRun extends NpmCommand
{
/**
* @var string|null The default command name for lazy loading.
*/
protected static $defaultName = 'npm:run';
/**
* @var string The name and signature of this command.
*/
protected $signature = 'npm:run
{package : Defines the package where the script is located.}
{script : The name of the script to run, as defined in the package.json "scripts" config.}
{additionalArgs?* : Arguments to pass through to the script being run.}
{--f|production : Runs the script in "production" mode.}
{--s|silent : Silent mode.}
{--disable-tty : Disable tty mode}';
/**
* @var string The console command description.
*/
protected $description = 'Runs a script in a given package.';
/**
* @var array List of commands that this command replaces (aliases)
*/
protected $replaces = [
'mix:run'
];
/**
* Execute the console command.
*/
public function handle(): int
{
[$package, $packageJson] = $this->getPackage();
$script = $this->argument('script');
if (!$packageJson->hasScript($script)) {
$this->error(
sprintf('Script "%s" is not defined in package "%s".', $script, $this->argument('package'))
);
return 1;
}
if (!$this->option('silent')) {
$this->info(sprintf('Running script "%s" in package "%s"', $script, $this->argument('package')));
}
$command = ($this->argument('additionalArgs')) ?? [];
if (count($command)) {
array_unshift($command, 'npm', 'run', $script, '--');
} else {
array_unshift($command, 'npm', 'run', $script);
}
return $this->npmRun($command, $package['path']);
}
}

View File

@@ -0,0 +1,68 @@
<?php
namespace System\Console\Asset\Npm;
use System\Console\Asset\Npm\NpmCommand;
use Winter\Storm\Exception\SystemException;
class NpmUpdate extends NpmCommand
{
/**
* @var string|null The default command name for lazy loading.
*/
protected static $defaultName = 'npm:update';
/**
* @inheritDoc
*/
protected $description = 'Update Node.js dependencies required for mixed assets';
/**
* @inheritDoc
*/
protected $signature = 'npm:update
{package? : The package name to add configuration for.}
{npmArgs?* : Arguments to pass through to the "npm" binary.}
{--npm= : Defines a custom path to the "npm" binary.}
{--a|save : Tell npm to update package.json.}
{--s|silent : Silent mode.}
{--disable-tty : Disable tty mode}';
/**
* @inheritDoc
*/
public $replaces = [
'mix:update'
];
/**
* Execute the console command.
*/
public function handle(): int
{
$command = ($this->argument('npmArgs')) ?? [];
try {
[$package, $packageJson] = $this->getPackage();
} catch (SystemException $e) {
if (!str_contains($e->getMessage(), 'is not a registered package.')) {
throw $e;
}
array_unshift($command, $this->argument('package'));
}
$args = ['npm', 'update'];
if ($this->option('save')) {
$args[] = '--save';
}
if (count($command)) {
$args[] = '--';
}
array_unshift($command, ...$args);
return $this->npmRun($command, $package['path'] ?? '');
}
}

View File

@@ -0,0 +1,74 @@
<?php
namespace System\Console\Asset\Npm;
use Symfony\Component\Process\Process;
use System\Console\Asset\Npm\NpmCommand;
class NpmVersion extends NpmCommand
{
const NPM_MINIMUM_SUPPORTED_VERSION = '7.0';
/**
* @var string|null The default command name for lazy loading.
*/
protected static $defaultName = 'npm:version';
/**
* @var string The name and signature of this command.
*/
protected $signature = 'npm:version
{--c|compatible : Report compatible version via exit code.}
{--s|silent : Silent mode.}
{--disable-tty : Disable tty mode}';
/**
* @var string The console command description.
*/
protected $description = 'Runs a script in a given package.';
/**
* Execute the console command.
*/
public function handle(): int
{
$process = new Process(
['npm', '--version'],
base_path(),
['NODE_ENV' => $this->getNodeEnv()],
null,
null
);
$output = '';
$exit = $process->run(function ($status, $stdout) use (&$output) {
$output .= $stdout;
});
$output = trim($output);
// Npm failed for some reason, report to user
if ($exit !== 0) {
$this->error('NPM exited with error: ' . $output);
return $exit;
}
// Report the version to user
if (!$this->option('silent')) {
$this->info($output);
}
// If the user has not requested a compatibility check, then return 0
if (!$this->option('compatible')) {
return 0;
}
// If the version of npm is less than the required minimum, then return fail
if (version_compare($output, static::NPM_MINIMUM_SUPPORTED_VERSION, '<')) {
return 1;
}
return 0;
}
}