149 lines
12 KiB
PHP
149 lines
12 KiB
PHP
<?php
|
|
|
|
namespace Modules\Content\Console;
|
|
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Modules\Content\Models\ContentDocument;
|
|
use Modules\Content\Models\ContentType;
|
|
use Modules\Content\Models\PageContent;
|
|
|
|
final class InstallSaaslandContent extends Command
|
|
{
|
|
protected $signature = 'content:install-saasland {--force : Replace the existing home composition}';
|
|
protected $description = 'Install editable Saasland header, body and footer content documents.';
|
|
|
|
public function handle(): int
|
|
{
|
|
$requiredTables = ['content_types', 'content_documents', 'page_content'];
|
|
$missingTables = array_values(array_filter($requiredTables, static fn (string $table): bool => ! Schema::hasTable($table)));
|
|
|
|
if ($missingTables !== []) {
|
|
$this->components->error('Content composition tables are missing: '.implode(', ', $missingTables).'.');
|
|
$this->components->info('Run php artisan migrate before installing the Saasland composition.');
|
|
return self::FAILURE;
|
|
}
|
|
|
|
DB::transaction(function (): void {
|
|
if ($this->option('force')) {
|
|
PageContent::query()->where('page_key', 'home')->delete();
|
|
}
|
|
|
|
$order = [
|
|
'site-header' => ['header', 10], 'hero' => ['body', 10], 'feature-grid' => ['body', 20],
|
|
'product-feed' => ['body', 30], 'testimonial-feed' => ['body', 40], 'team-feed' => ['body', 50],
|
|
'blog-feed' => ['body', 60], 'news-feed' => ['body', 70], 'faq-feed' => ['body', 80],
|
|
'newsletter-form' => ['body', 90], 'call-to-action' => ['body', 100], 'site-footer' => ['footer', 10],
|
|
];
|
|
|
|
foreach ($this->definitions() as $key => $definition) {
|
|
$type = ContentType::query()->updateOrCreate(['key' => $key], $definition['type']);
|
|
$document = ContentDocument::query()->firstOrCreate(
|
|
['slug' => 'saasland-'.$key],
|
|
[
|
|
'content_type_id' => $type->id,
|
|
'title' => $definition['title'],
|
|
'data' => $definition['data'],
|
|
'status' => 'published',
|
|
'published_at' => now(),
|
|
]
|
|
);
|
|
|
|
if ((int) $document->content_type_id !== (int) $type->id) {
|
|
$document->forceFill(['content_type_id' => $type->id])->save();
|
|
}
|
|
[$region, $sort] = $order[$key];
|
|
PageContent::query()->updateOrCreate(
|
|
['page_key' => 'home', 'region' => $region, 'sort_order' => $sort],
|
|
['content_document_id' => $document->id, 'is_enabled' => true]
|
|
);
|
|
}
|
|
});
|
|
|
|
$this->components->info('Saasland content composition installed with editable schemas.');
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
private function definitions(): array
|
|
{
|
|
$field = static fn (string $key, string $label, string $type = 'text', array $extra = []): array => array_merge(compact('key', 'label', 'type'), $extra);
|
|
$type = static fn (string $name, string $renderer, array $regions, array $schema): array => [
|
|
'name' => $name, 'renderer' => $renderer, 'allowed_regions' => $regions,
|
|
'is_system' => true, 'is_active' => true, 'schema' => $schema,
|
|
];
|
|
$section = [$field('enabled', 'Show this section', 'boolean', ['default' => true])];
|
|
$feed = array_merge($section, [
|
|
$field('eyebrow', 'Eyebrow'), $field('heading', 'Heading'), $field('description', 'Description', 'textarea'),
|
|
$field('limit', 'Maximum items', 'number', ['min' => 1, 'max' => 50]),
|
|
$field('include_ids', 'Only show record IDs', 'csv', ['help' => 'Optional comma-separated IDs. Leave blank to use the latest records.']),
|
|
$field('exclude_ids', 'Exclude record IDs', 'csv', ['help' => 'Optional comma-separated IDs to hide from this section.']),
|
|
]);
|
|
|
|
return [
|
|
'site-header' => [
|
|
'title' => 'Main website header',
|
|
'type' => $type('Site header', 'site-header', ['header'], [
|
|
...$section, $field('show_navigation', 'Show navigation', 'boolean', ['default' => true]), $field('show_login', 'Show login', 'boolean', ['default' => true]),
|
|
$field('show_registration', 'Show registration', 'boolean', ['default' => true]), $field('login_label', 'Login label'),
|
|
$field('registration_label', 'Registration label'), $field('sticky', 'Sticky header', 'boolean', ['default' => true]),
|
|
]),
|
|
'data' => ['enabled' => true, 'show_navigation' => true, 'show_login' => true, 'show_registration' => true, 'login_label' => 'Log in', 'registration_label' => 'Get started', 'sticky' => true],
|
|
],
|
|
'hero' => [
|
|
'title' => 'Homepage hero',
|
|
'type' => $type('Hero', 'hero', ['body'], [
|
|
...$section, $field('eyebrow', 'Eyebrow'), $field('heading', 'Heading'), $field('description', 'Description', 'textarea'),
|
|
$field('primary_label', 'Primary button label'), $field('primary_url', 'Primary button URL', 'url'),
|
|
$field('secondary_label', 'Secondary button label'), $field('secondary_url', 'Secondary button URL', 'url'),
|
|
$field('show_metrics', 'Show metrics panel', 'boolean', ['default' => true]),
|
|
$field('metrics', 'Metrics', 'repeater', ['fields' => [
|
|
$field('enabled', 'Show item', 'boolean', ['default' => true]), $field('label', 'Label'), $field('value', 'Value'), $field('change', 'Change'), $field('height', 'Chart height (%)', 'number', ['min' => 0, 'max' => 100]),
|
|
]]),
|
|
]),
|
|
'data' => ['enabled' => true, 'eyebrow' => 'A better way to run your business', 'heading' => 'Transform Your Business With Our SaaS Solution', 'description' => 'Streamline operations, boost productivity, and improve customer satisfaction with one connected platform built for modern teams.', 'primary_label' => 'Get started free', 'primary_url' => '/register', 'secondary_label' => 'Book demo', 'secondary_url' => '#contact', 'show_metrics' => true, 'metrics' => [
|
|
['enabled' => true, 'label' => 'Monthly revenue', 'value' => '£48,240', 'change' => '+18.4%', 'height' => 62],
|
|
['enabled' => true, 'label' => 'Active users', 'value' => '12,842', 'change' => '+9.2%', 'height' => 78],
|
|
['enabled' => true, 'label' => 'Conversion', 'value' => '7.8%', 'change' => '+2.1%', 'height' => 92],
|
|
]],
|
|
],
|
|
'feature-grid' => [
|
|
'title' => 'Core features',
|
|
'type' => $type('Feature grid', 'feature-grid', ['body'], [
|
|
...$section, $field('eyebrow', 'Eyebrow'), $field('heading', 'Heading'), $field('description', 'Description', 'textarea'),
|
|
$field('items', 'Features', 'repeater', ['fields' => [$field('enabled', 'Show item', 'boolean', ['default' => true]), $field('title', 'Title'), $field('description', 'Description', 'textarea')]]),
|
|
]),
|
|
'data' => ['enabled' => true, 'eyebrow' => 'Powerful features', 'heading' => 'Everything your team needs to grow', 'description' => 'Planning, collaboration, reporting, publishing, commerce and customer insight in one extensible platform.', 'items' => [
|
|
['enabled' => true, 'title' => 'Smart automation', 'description' => 'Remove repetitive work and delays.'],
|
|
['enabled' => true, 'title' => 'Real-time analytics', 'description' => 'Turn activity into useful business insight.'],
|
|
['enabled' => true, 'title' => 'Content operations', 'description' => 'Create, review and publish confidently.'],
|
|
['enabled' => true, 'title' => 'Secure by design', 'description' => 'Protect users and data with dependable controls.'],
|
|
['enabled' => true, 'title' => 'Flexible integrations', 'description' => 'Connect the tools your organisation already uses.'],
|
|
['enabled' => true, 'title' => 'Modular architecture', 'description' => 'Activate only the capabilities each site needs.'],
|
|
]],
|
|
],
|
|
'product-feed' => ['title' => 'Pricing plans', 'type' => $type('Product feed', 'product-feed', ['body'], $feed), 'data' => ['enabled' => true, 'eyebrow' => 'Simple pricing', 'heading' => 'Choose a plan that fits', 'description' => 'Plans are managed from Products & Pricing in the CMS.', 'limit' => 6, 'include_ids' => '', 'exclude_ids' => '']],
|
|
'testimonial-feed' => ['title' => 'Customer stories', 'type' => $type('Testimonial feed', 'testimonial-feed', ['body'], $feed), 'data' => ['enabled' => true, 'eyebrow' => 'Customer stories', 'heading' => 'Trusted by ambitious teams', 'description' => '', 'limit' => 6, 'include_ids' => '', 'exclude_ids' => '']],
|
|
'team-feed' => ['title' => 'Team', 'type' => $type('Team feed', 'team-feed', ['body'], $feed), 'data' => ['enabled' => true, 'eyebrow' => 'Our team', 'heading' => 'People behind the platform', 'description' => '', 'limit' => 8, 'include_ids' => '', 'exclude_ids' => '']],
|
|
'blog-feed' => ['title' => 'Latest blog posts', 'type' => $type('Blog feed', 'blog-feed', ['body'], $feed), 'data' => ['enabled' => true, 'eyebrow' => 'Insights', 'heading' => 'Latest from the blog', 'description' => '', 'limit' => 3, 'include_ids' => '', 'exclude_ids' => '']],
|
|
'news-feed' => ['title' => 'Latest news', 'type' => $type('News feed', 'news-feed', ['body'], $feed), 'data' => ['enabled' => true, 'eyebrow' => 'Newsroom', 'heading' => 'Latest news', 'description' => '', 'limit' => 3, 'include_ids' => '', 'exclude_ids' => '']],
|
|
'faq-feed' => ['title' => 'Frequently asked questions', 'type' => $type('FAQ feed', 'faq-feed', ['body'], $feed), 'data' => ['enabled' => true, 'eyebrow' => 'FAQ', 'heading' => 'Answers before you begin', 'description' => '', 'limit' => 12, 'include_ids' => '', 'exclude_ids' => '']],
|
|
'newsletter-form' => [
|
|
'title' => 'Newsletter signup',
|
|
'type' => $type('Newsletter form', 'newsletter-form', ['body'], [...$section, $field('eyebrow', 'Eyebrow'), $field('heading', 'Heading'), $field('description', 'Description', 'textarea'), $field('placeholder', 'Email placeholder'), $field('button_label', 'Button label')]),
|
|
'data' => ['enabled' => true, 'eyebrow' => 'Newsletter', 'heading' => 'Useful updates, no noise', 'description' => 'Receive product news, publishing guidance, and practical platform updates.', 'placeholder' => 'you@example.com', 'button_label' => 'Subscribe'],
|
|
],
|
|
'call-to-action' => [
|
|
'title' => 'Homepage final call to action',
|
|
'type' => $type('Call to action', 'call-to-action', ['body'], [...$section, $field('anchor', 'Section anchor'), $field('heading', 'Heading'), $field('description', 'Description', 'textarea'), $field('button_label', 'Button label'), $field('button_url', 'Button URL', 'url')]),
|
|
'data' => ['enabled' => true, 'anchor' => 'contact', 'heading' => 'Ready to transform your business?', 'description' => 'Start building a faster, more connected operation today.', 'button_label' => 'Get started free', 'button_url' => '/register'],
|
|
],
|
|
'site-footer' => [
|
|
'title' => 'Main website footer',
|
|
'type' => $type('Site footer', 'site-footer', ['footer'], [...$section, $field('description', 'Description', 'textarea'), $field('show_navigation', 'Show footer navigation', 'boolean'), $field('show_account_links', 'Show account links', 'boolean', ['default' => true]), $field('show_social_links', 'Show social links', 'boolean', ['default' => true]), $field('show_back_to_top', 'Show back-to-top link', 'boolean', ['default' => true]), $field('copyright', 'Copyright text')]),
|
|
'data' => ['enabled' => true, 'description' => 'One connected platform for modern teams.', 'show_navigation' => true, 'show_account_links' => true, 'show_social_links' => true, 'show_back_to_top' => true, 'copyright' => 'All rights reserved.'],
|
|
],
|
|
];
|
|
}
|
|
}
|