diff --git a/Modules/Stylist/Http/Controllers/StylistController.php b/Modules/Stylist/Http/Controllers/StylistController.php index 0318c6d..219359e 100644 --- a/Modules/Stylist/Http/Controllers/StylistController.php +++ b/Modules/Stylist/Http/Controllers/StylistController.php @@ -7,14 +7,17 @@ use Modules\Stylist\Services\ThemeAccessibilityValidator; use Modules\Stylist\Services\ThemeSettings; use Modules\Stylist\Theme\Stylist; use Modules\Stylist\Theme\UrlGenerator; +use Modules\Settings\Services\SettingsRepository; final class StylistController extends Controller { - public function __invoke(Stylist $stylist, ThemeSettings $settings, ThemeAccessibilityValidator $accessibility, UrlGenerator $urls) + public function __invoke(Stylist $stylist, ThemeSettings $settings, ThemeAccessibilityValidator $accessibility, UrlGenerator $urls, SettingsRepository $siteSettings) { return view('stylist::index', [ 'theme' => $stylist->current(), 'themes' => $stylist->all(), 'variables' => $stylist->variables(), 'settingsService' => $settings, 'accessibility' => $accessibility, 'urls' => $urls, + 'activeFrontendTheme' => $siteSettings->get('frontend_theme', config('stylist.default_frontend_theme', 'saasland'), 'site'), + 'activeBackendTheme' => $siteSettings->get('backend_theme', config('stylist.default_backend_theme', 'admin'), 'site'), ]); } } diff --git a/Modules/Stylist/Http/Controllers/ThemeManagementController.php b/Modules/Stylist/Http/Controllers/ThemeManagementController.php index 8918072..3c4f12f 100644 --- a/Modules/Stylist/Http/Controllers/ThemeManagementController.php +++ b/Modules/Stylist/Http/Controllers/ThemeManagementController.php @@ -4,14 +4,36 @@ namespace Modules\Stylist\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Routing\Controller; +use Modules\Settings\Services\SettingsRepository; use Modules\Stylist\Services\ThemeAccessibilityValidator; use Modules\Stylist\Services\ThemeOptimizer; use Modules\Stylist\Services\ThemePackageManager; use Modules\Stylist\Services\ThemeSettings; use Modules\Stylist\Theme\Loader; +use Modules\Stylist\View\ThemeViewResolver; final class ThemeManagementController extends Controller { + public function activate(string $theme, Loader $loader, SettingsRepository $settings) + { + $item = $loader->find($theme); + abort_unless(in_array($item->type(), ['frontend', 'backend'], true), 422, 'Only frontend and backend themes can be activated.'); + + $settings->put($item->type().'_theme', $item->key(), 'site', 'string', true); + + return back()->with('status', $item->name().' is now the active '.$item->type().' theme.'); + } + + public function preview(string $theme, Loader $loader, ThemeViewResolver $views) + { + $item = $loader->find($theme); + + return $views->makeForTheme($item->key(), $item->entryView(), [ + 'themePreview' => true, + 'previewTheme' => $item, + ]); + } + public function settings(Request $request, string $theme, Loader $loader, ThemeSettings $settings) { $item = $loader->find($theme); diff --git a/Modules/Stylist/Resources/views/index.blade.php b/Modules/Stylist/Resources/views/index.blade.php index 4123783..19ffd23 100644 --- a/Modules/Stylist/Resources/views/index.blade.php +++ b/Modules/Stylist/Resources/views/index.blade.php @@ -21,7 +21,7 @@ @php($issues = $accessibility->validate($item)) @php($appearance = $settingsService->appearance($item)) @php($accent = $settingsService->accent($item)) -
+
@if ($item->preview() && $item->has($item->preview())) {{ $item->name() }} theme preview @@ -30,10 +30,14 @@ @endif
-

{{ $item->name() }}

v{{ $item->version() }}@if($item->author()) · {{ $item->author() }}@endif

@if($item->key() === $theme->key())Active@endif
+

{{ $item->name() }}

v{{ $item->version() }}@if($item->author()) · {{ $item->author() }}@endif

@if(($item->type() === 'frontend' && $item->key() === $activeFrontendTheme) || ($item->type() === 'backend' && $item->key() === $activeBackendTheme))Active {{ ucfirst($item->type()) }}@endif
@if($item->description())

{{ $item->description() }}

@endif @if($item->parent())

Child of {{ $item->parent() }}

@endif
+ @if(in_array($item->type(), ['frontend', 'backend'], true)) +
@csrf
+ Preview + @endif Export ZIP
@csrf
@if(str_starts_with(realpath($item->path()) ?: '', realpath(config('stylist.themes_path')) ?: '/__never__')) @@ -55,8 +59,12 @@ @foreach($item->settingsSchema() as $key => $definition) @php($definition = is_array($definition) ? $definition : ['default' => $definition]) @endforeach diff --git a/Modules/Stylist/Routes/web.php b/Modules/Stylist/Routes/web.php index 0285862..c39ec85 100644 --- a/Modules/Stylist/Routes/web.php +++ b/Modules/Stylist/Routes/web.php @@ -4,10 +4,14 @@ use Illuminate\Support\Facades\Route; use Modules\Stylist\Http\Controllers\StylistController; use Modules\Stylist\Http\Controllers\ThemeManagementController; -Route::get('/', StylistController::class)->name('index'); -Route::post('/install', [ThemeManagementController::class, 'install'])->name('install'); -Route::put('/{theme}/settings', [ThemeManagementController::class, 'settings'])->name('settings'); -Route::delete('/{theme}', [ThemeManagementController::class, 'uninstall'])->name('uninstall'); -Route::get('/{theme}/export', [ThemeManagementController::class, 'export'])->name('export'); -Route::post('/{theme}/optimize', [ThemeManagementController::class, 'optimize'])->name('optimize'); -Route::get('/{theme}/accessibility', [ThemeManagementController::class, 'validateTheme'])->name('accessibility'); +Route::middleware(['auth', 'verified'])->group(function (): void { + Route::get('/', StylistController::class)->name('index'); + Route::post('/install', [ThemeManagementController::class, 'install'])->name('install'); + Route::put('/{theme}/settings', [ThemeManagementController::class, 'settings'])->name('settings'); + Route::post('/{theme}/activate', [ThemeManagementController::class, 'activate'])->name('activate'); + Route::get('/{theme}/preview', [ThemeManagementController::class, 'preview'])->name('preview'); + Route::delete('/{theme}', [ThemeManagementController::class, 'uninstall'])->name('uninstall'); + Route::get('/{theme}/export', [ThemeManagementController::class, 'export'])->name('export'); + Route::post('/{theme}/optimize', [ThemeManagementController::class, 'optimize'])->name('optimize'); + Route::get('/{theme}/accessibility', [ThemeManagementController::class, 'validateTheme'])->name('accessibility'); +}); diff --git a/Modules/Stylist/Services/ThemePackageManager.php b/Modules/Stylist/Services/ThemePackageManager.php index 0319b03..56d1a4a 100644 --- a/Modules/Stylist/Services/ThemePackageManager.php +++ b/Modules/Stylist/Services/ThemePackageManager.php @@ -6,12 +6,13 @@ use Illuminate\Filesystem\Filesystem; use Illuminate\Http\UploadedFile; use Modules\Stylist\Theme\Loader; use Modules\Stylist\Theme\Theme; +use Modules\Settings\Services\SettingsRepository; use RuntimeException; use ZipArchive; final class ThemePackageManager { - public function __construct(private readonly Filesystem $files, private readonly Loader $loader, private readonly ThemeValidator $validator) {} + public function __construct(private readonly Filesystem $files, private readonly Loader $loader, private readonly ThemeValidator $validator, private readonly SettingsRepository $settings) {} public function install(UploadedFile $upload): Theme { @@ -60,6 +61,12 @@ final class ThemePackageManager public function uninstall(Theme $theme): void { + $active = $theme->type() === 'frontend' + ? $this->settings->get('frontend_theme', config('stylist.default_frontend_theme'), 'site') + : $this->settings->get('backend_theme', config('stylist.default_backend_theme'), 'site'); + if ($active === $theme->key()) { + throw new RuntimeException('The active theme cannot be uninstalled. Activate another theme first.'); + } $projectRoot = realpath((string) config('stylist.themes_path')); $themePath = realpath($theme->path()); if (! $projectRoot || ! $themePath || ! str_starts_with($themePath, $projectRoot.DIRECTORY_SEPARATOR)) { diff --git a/Modules/Stylist/Theme/ManifestValidator.php b/Modules/Stylist/Theme/ManifestValidator.php index 3e33821..cc75998 100644 --- a/Modules/Stylist/Theme/ManifestValidator.php +++ b/Modules/Stylist/Theme/ManifestValidator.php @@ -29,6 +29,9 @@ final class ManifestValidator if (isset($manifest['version']) && (! is_string($manifest['version']) || ! preg_match('/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/', $manifest['version']))) { $errors[] = 'The version must use semantic versioning, for example 1.2.0.'; } + if (isset($manifest['type']) && ! in_array($manifest['type'], ['frontend', 'backend', 'common'], true)) { + $errors[] = 'The type must be frontend, backend, or common.'; + } $parent = $manifest['extends'] ?? $manifest['parent'] ?? null; if ($parent !== null && (! is_string($parent) || ! preg_match('/^[a-z0-9][a-z0-9_-]*$/', $parent))) { $errors[] = 'The extends/parent value must be a valid theme key.'; diff --git a/resources/themes/admin/theme.json b/resources/themes/admin/theme.json index 821d113..e958c33 100644 --- a/resources/themes/admin/theme.json +++ b/resources/themes/admin/theme.json @@ -1,19 +1,23 @@ { + "manifest_version": 2, "name": "Dashboard", "slug": "admin", - "extends": "common", "version": "1.0.0", "author": "ABSDEV", "description": "Backend-only Laravel Livewire and Flux dashboard theme.", + "type": "backend", + "extends": "common", "entry_view": "dashboard", "stylesheet": "css/theme.css", "script": "js/app.js", - "type": "backend", + "preview": "images/preview.webp", "views": true, "livewire_views": true, "supports": { "dark_mode": true, "animations": false, + "privacy": false, + "terms": false, "auth": false, "preview": true, "variants": true, @@ -23,7 +27,6 @@ "accessibility_validation": true }, "variables": {}, - "preview": "images/preview.webp", "variants": { "light": { "label": "Light", @@ -38,6 +41,10 @@ } } }, + "appearances": {}, + "accents": {}, + "default_appearance": null, + "default_accent": null, "settings": { "site_title": { "type": "text", @@ -54,5 +61,6 @@ "label": "Primary colour", "default": "#2563eb" } - } + }, + "seo": {} } diff --git a/resources/themes/common/theme.json b/resources/themes/common/theme.json index 55861b4..0ce8c4e 100644 --- a/resources/themes/common/theme.json +++ b/resources/themes/common/theme.json @@ -1,19 +1,37 @@ { + "manifest_version": 2, "name": "Common Application Theme", "slug": "common", "version": "1.0.0", "author": "ABSDEV", "description": "Application-wide layouts, authentication, settings and shared Blade components.", - "entry_view": "livewire.auth.login", "type": "common", + "extends": null, + "entry_view": "livewire.auth.login", + "stylesheet": "css/theme.css", + "script": "js/app.js", + "preview": null, "views": true, "livewire_views": true, "supports": { - "auth": true, - "settings": true, "dark_mode": true, - "preview": false + "animations": false, + "privacy": false, + "terms": false, + "auth": true, + "preview": false, + "variants": false, + "settings": true, + "seo": false, + "export": true, + "accessibility_validation": true }, "variables": {}, - "settings": {} + "variants": {}, + "appearances": {}, + "accents": {}, + "default_appearance": null, + "default_accent": null, + "settings": {}, + "seo": {} } diff --git a/resources/themes/corporate/theme.json b/resources/themes/corporate/theme.json index 705f325..6a08d89 100644 --- a/resources/themes/corporate/theme.json +++ b/resources/themes/corporate/theme.json @@ -1,7 +1,37 @@ { - "name": "Corporate", - "slug": "corporate", - "version": "1.0.0", - "parent": "common", - "type": "backend" + "manifest_version": 2, + "name": "Corporate", + "slug": "corporate", + "version": "1.0.0", + "author": "ABSDEV", + "description": "Corporate backend theme extending the common application theme.", + "type": "backend", + "extends": "common", + "entry_view": "dashboard", + "stylesheet": "css/theme.css", + "script": "js/app.js", + "preview": null, + "views": true, + "livewire_views": true, + "supports": { + "dark_mode": false, + "animations": false, + "privacy": false, + "terms": false, + "auth": false, + "preview": false, + "variants": false, + "settings": false, + "seo": false, + "export": true, + "accessibility_validation": true + }, + "variables": {}, + "variants": {}, + "appearances": {}, + "accents": {}, + "default_appearance": null, + "default_accent": null, + "settings": {}, + "seo": {} } diff --git a/resources/themes/saasland/theme.json b/resources/themes/saasland/theme.json index 4635f36..138ebf6 100644 --- a/resources/themes/saasland/theme.json +++ b/resources/themes/saasland/theme.json @@ -1,186 +1,192 @@ { - "name": "Saasland", - "slug": "saasland", - "version": "1.3.0", - "author": "ABSDEV", - "description": "Premium dark SaaS frontend with compact section spacing, responsive dashboard hero, CMS-driven content and an expanded lead-generation footer.", - "entry_view": "home", - "stylesheet": "css/theme.css", - "script": "js/app.js", - "preview": "images/preview.webp", - "type": "frontend", - "views": true, - "livewire_views": true, - "supports": { - "dark_mode": true, - "animations": true, - "privacy": true, - "terms": true, - "auth": true, - "preview": true, - "variants": true, - "settings": true, - "seo": true, - "export": true, - "accessibility_validation": true + "manifest_version": 2, + "name": "Saasland", + "slug": "saasland", + "version": "1.3.0", + "author": "ABSDEV", + "description": "Premium dark SaaS frontend with compact section spacing, responsive dashboard hero, CMS-driven content and an expanded lead-generation footer.", + "type": "frontend", + "extends": null, + "entry_view": "home", + "stylesheet": "css/theme.css", + "script": "js/app.js", + "preview": "images/preview.webp", + "views": true, + "livewire_views": true, + "supports": { + "dark_mode": true, + "animations": true, + "privacy": true, + "terms": true, + "auth": true, + "preview": true, + "variants": true, + "settings": true, + "seo": true, + "export": true, + "accessibility_validation": true + }, + "variables": { + "brand-primary": "#f97316", + "brand-secondary": "#111111", + "brand-accent": "#fb923c", + "surface": "#0f0e0d", + "surface-muted": "#191714", + "text-primary": "#f7f3ef" + }, + "variants": { + "light": { + "label": "Light", + "variables": {} }, - "variables": { - "brand-primary": "#f97316", - "brand-secondary": "#111111", - "brand-accent": "#fb923c", - "surface": "#0f0e0d", - "surface-muted": "#191714", - "text-primary": "#f7f3ef" - }, - "variants": { - "light": { - "label": "Light", - "variables": {} - }, - "dark": { - "label": "Dark", - "variables": { - "surface": "#0f172a", - "surface-muted": "#111827", - "text-primary": "#f8fafc" - } - } - }, - "settings": { - "site_title": { - "type": "text", - "label": "Site title", - "default": "Abbey Software Development" - }, - "site_description": { - "type": "text", - "label": "Site description", - "default": "Dark SaaS marketing theme with integrated feature, pricing, privacy and terms sections." - }, - "logo_url": { - "type": "url", - "label": "Logo URL", - "default": "" - }, - "--brand-primary": { - "type": "color", - "label": "Primary colour", - "default": "#f97316" - }, - "hero_title": { - "type": "text", - "label": "Hero title", - "default": "" - }, - "facebook_url": { - "type": "url", - "label": "Facebook URL", - "default": "" - }, - "x_url": { - "type": "url", - "label": "X URL", - "default": "" - }, - "linkedin_url": { - "type": "url", - "label": "LinkedIn URL", - "default": "" - }, - "hero_eyebrow": { - "type": "text", - "label": "Hero eyebrow", - "default": "A better way to run your business" - }, - "hero_description": { - "type": "textarea", - "label": "Hero description", - "default": "Streamline operations, boost productivity, and improve customer satisfaction with one connected platform built for modern teams." - }, - "primary_cta_label": { - "type": "text", - "label": "Primary button label", - "default": "Get started free" - }, - "primary_cta_url": { - "type": "text", - "label": "Primary button URL", - "default": "/register" - }, - "secondary_cta_label": { - "type": "text", - "label": "Secondary button label", - "default": "Book demo" - }, - "secondary_cta_url": { - "type": "text", - "label": "Secondary button URL", - "default": "#contact" - }, - "show_metrics": { - "type": "checkbox", - "label": "Show performance preview", - "default": true - }, - "show_features": { - "type": "checkbox", - "label": "Show features", - "default": true - }, - "show_pricing": { - "type": "checkbox", - "label": "Show pricing", - "default": true - }, - "show_testimonials": { - "type": "checkbox", - "label": "Show testimonials", - "default": true - }, - "show_team": { - "type": "checkbox", - "label": "Show team", - "default": false - }, - "show_blog": { - "type": "checkbox", - "label": "Show blog", - "default": true - }, - "show_news": { - "type": "checkbox", - "label": "Show news", - "default": true - }, - "show_faq": { - "type": "checkbox", - "label": "Show FAQ", - "default": true - }, - "show_newsletter": { - "type": "checkbox", - "label": "Show newsletter signup", - "default": true - }, - "cta_title": { - "type": "text", - "label": "Final CTA title", - "default": "Ready to transform your business?" - }, - "cta_description": { - "type": "text", - "label": "Final CTA description", - "default": "Start building a faster, more connected operation today." - } - }, - "seo": { - "title": "Saasland", - "description": "Dark SaaS marketing theme with integrated feature, pricing, privacy and terms sections.", - "image": "images/preview.webp", - "json_ld": { - "@context": "https://schema.org", - "@type": "WebSite", - "name": "Saasland" - } + "dark": { + "label": "Dark", + "variables": { + "surface": "#0f172a", + "surface-muted": "#111827", + "text-primary": "#f8fafc" + } } + }, + "appearances": {}, + "accents": {}, + "default_appearance": null, + "default_accent": null, + "settings": { + "site_title": { + "type": "text", + "label": "Site title", + "default": "Abbey Software Development" + }, + "site_description": { + "type": "text", + "label": "Site description", + "default": "Dark SaaS marketing theme with integrated feature, pricing, privacy and terms sections." + }, + "logo_url": { + "type": "url", + "label": "Logo URL", + "default": "" + }, + "--brand-primary": { + "type": "color", + "label": "Primary colour", + "default": "#f97316" + }, + "hero_title": { + "type": "text", + "label": "Hero title", + "default": "" + }, + "facebook_url": { + "type": "url", + "label": "Facebook URL", + "default": "" + }, + "x_url": { + "type": "url", + "label": "X URL", + "default": "" + }, + "linkedin_url": { + "type": "url", + "label": "LinkedIn URL", + "default": "" + }, + "hero_eyebrow": { + "type": "text", + "label": "Hero eyebrow", + "default": "A better way to run your business" + }, + "hero_description": { + "type": "textarea", + "label": "Hero description", + "default": "Streamline operations, boost productivity, and improve customer satisfaction with one connected platform built for modern teams." + }, + "primary_cta_label": { + "type": "text", + "label": "Primary button label", + "default": "Get started free" + }, + "primary_cta_url": { + "type": "text", + "label": "Primary button URL", + "default": "/register" + }, + "secondary_cta_label": { + "type": "text", + "label": "Secondary button label", + "default": "Book demo" + }, + "secondary_cta_url": { + "type": "text", + "label": "Secondary button URL", + "default": "#contact" + }, + "show_metrics": { + "type": "checkbox", + "label": "Show performance preview", + "default": true + }, + "show_features": { + "type": "checkbox", + "label": "Show features", + "default": true + }, + "show_pricing": { + "type": "checkbox", + "label": "Show pricing", + "default": true + }, + "show_testimonials": { + "type": "checkbox", + "label": "Show testimonials", + "default": true + }, + "show_team": { + "type": "checkbox", + "label": "Show team", + "default": false + }, + "show_blog": { + "type": "checkbox", + "label": "Show blog", + "default": true + }, + "show_news": { + "type": "checkbox", + "label": "Show news", + "default": true + }, + "show_faq": { + "type": "checkbox", + "label": "Show FAQ", + "default": true + }, + "show_newsletter": { + "type": "checkbox", + "label": "Show newsletter signup", + "default": true + }, + "cta_title": { + "type": "text", + "label": "Final CTA title", + "default": "Ready to transform your business?" + }, + "cta_description": { + "type": "text", + "label": "Final CTA description", + "default": "Start building a faster, more connected operation today." + } + }, + "seo": { + "title": "Saasland", + "description": "Dark SaaS marketing theme with integrated feature, pricing, privacy and terms sections.", + "image": "images/preview.webp", + "json_ld": { + "@context": "https://schema.org", + "@type": "WebSite", + "name": "Saasland" + } + } } diff --git a/resources/themes/swiss/theme.json b/resources/themes/swiss/theme.json index af24bfd..f70325f 100644 --- a/resources/themes/swiss/theme.json +++ b/resources/themes/swiss/theme.json @@ -1,101 +1,107 @@ { - "name": "Swiss", - "slug": "swiss", - "version": "1.1.0", - "author": "ABSDEV", - "description": "Dark Marketing Theme with integrated feature, pricing, privacy and terms sections.", - "entry_view": "home", - "stylesheet": "css/theme.css", - "script": "js/app.js", - "preview": "images/preview.webp", - "type": "frontend", - "views": true, - "livewire_views": true, - "supports": { - "dark_mode": true, - "animations": true, - "privacy": true, - "terms": true, - "auth": false, - "preview": true, - "variants": true, - "settings": true, - "seo": true, - "export": true, - "accessibility_validation": true + "manifest_version": 2, + "name": "Swiss", + "slug": "swiss", + "version": "1.1.0", + "author": "ABSDEV", + "description": "Dark Marketing Theme with integrated feature, pricing, privacy and terms sections.", + "type": "frontend", + "extends": null, + "entry_view": "home", + "stylesheet": "css/theme.css", + "script": "js/app.js", + "preview": "images/preview.webp", + "views": true, + "livewire_views": true, + "supports": { + "dark_mode": true, + "animations": true, + "privacy": true, + "terms": true, + "auth": false, + "preview": true, + "variants": true, + "settings": true, + "seo": true, + "export": true, + "accessibility_validation": true + }, + "variables": { + "brand-primary": "#f97316", + "brand-secondary": "#111111", + "brand-accent": "#fb923c", + "surface": "#0f0e0d", + "surface-muted": "#191714", + "text-primary": "#f7f3ef" + }, + "variants": { + "light": { + "label": "Light", + "variables": {} }, - "variables": { - "brand-primary": "#f97316", - "brand-secondary": "#111111", - "brand-accent": "#fb923c", - "surface": "#0f0e0d", - "surface-muted": "#191714", - "text-primary": "#f7f3ef" - }, - "variants": { - "light": { - "label": "Light", - "variables": {} - }, - "dark": { - "label": "Dark", - "variables": { - "surface": "#0f172a", - "surface-muted": "#111827", - "text-primary": "#f8fafc" - } - } - }, - "settings": { - "site_title": { - "type": "text", - "label": "Site title", - "default": "Saasland" - }, - "site_description": { - "type": "text", - "label": "Site description", - "default": "Dark SaaS marketing theme with integrated feature, pricing, privacy and terms sections." - }, - "logo_url": { - "type": "url", - "label": "Logo URL", - "default": "" - }, - "--brand-primary": { - "type": "color", - "label": "Primary colour", - "default": "#f97316" - }, - "hero_title": { - "type": "text", - "label": "Hero title", - "default": "" - }, - "facebook_url": { - "type": "url", - "label": "Facebook URL", - "default": "" - }, - "x_url": { - "type": "url", - "label": "X URL", - "default": "" - }, - "linkedin_url": { - "type": "url", - "label": "LinkedIn URL", - "default": "" - } - }, - "seo": { - "title": "Saasland", - "description": "Dark SaaS marketing theme with integrated feature, pricing, privacy and terms sections.", - "image": "images/preview.webp", - "json_ld": { - "@context": "https://schema.org", - "@type": "WebSite", - "name": "Saasland" - } + "dark": { + "label": "Dark", + "variables": { + "surface": "#0f172a", + "surface-muted": "#111827", + "text-primary": "#f8fafc" + } } + }, + "appearances": {}, + "accents": {}, + "default_appearance": null, + "default_accent": null, + "settings": { + "site_title": { + "type": "text", + "label": "Site title", + "default": "Saasland" + }, + "site_description": { + "type": "text", + "label": "Site description", + "default": "Dark SaaS marketing theme with integrated feature, pricing, privacy and terms sections." + }, + "logo_url": { + "type": "url", + "label": "Logo URL", + "default": "" + }, + "--brand-primary": { + "type": "color", + "label": "Primary colour", + "default": "#f97316" + }, + "hero_title": { + "type": "text", + "label": "Hero title", + "default": "" + }, + "facebook_url": { + "type": "url", + "label": "Facebook URL", + "default": "" + }, + "x_url": { + "type": "url", + "label": "X URL", + "default": "" + }, + "linkedin_url": { + "type": "url", + "label": "LinkedIn URL", + "default": "" + } + }, + "seo": { + "title": "Saasland", + "description": "Dark SaaS marketing theme with integrated feature, pricing, privacy and terms sections.", + "image": "images/preview.webp", + "json_ld": { + "@context": "https://schema.org", + "@type": "WebSite", + "name": "Saasland" + } + } } diff --git a/resources/themes/welcome/theme.json b/resources/themes/welcome/theme.json index 27f7e20..a4fc459 100644 --- a/resources/themes/welcome/theme.json +++ b/resources/themes/welcome/theme.json @@ -1,19 +1,23 @@ { + "manifest_version": 2, "name": "Welcome", "slug": "welcome", - "extends": "common", "version": "1.1.2", "author": "ABSDEV", "description": "Laravel 13 welcome theme.", + "type": "frontend", + "extends": "common", "entry_view": "welcome", "stylesheet": "css/theme.css", "script": "js/app.js", - "type": "frontend", + "preview": "images/preview.webp", "views": true, "livewire_views": true, "supports": { "dark_mode": false, "animations": false, + "privacy": false, + "terms": false, "auth": false, "preview": true, "variants": true, @@ -30,7 +34,6 @@ "surface-muted": "#f8fafc", "text-primary": "#0f172a" }, - "preview": "images/preview.webp", "variants": { "light": { "label": "Light", @@ -45,6 +48,10 @@ } } }, + "appearances": {}, + "accents": {}, + "default_appearance": null, + "default_accent": null, "settings": { "site_title": { "type": "text",