optimizations
This commit is contained in:
@@ -2,6 +2,9 @@
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Database\Seeders\NovaCardCategorySeeder;
|
||||
use Database\Seeders\NovaCardDemoSeeder;
|
||||
use Database\Seeders\NovaCardTemplateSeeder;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
@@ -17,6 +20,12 @@ class DatabaseSeeder extends Seeder
|
||||
{
|
||||
// User::factory(10)->create();
|
||||
|
||||
$this->call([
|
||||
NovaCardCategorySeeder::class,
|
||||
NovaCardTemplateSeeder::class,
|
||||
NovaCardDemoSeeder::class,
|
||||
]);
|
||||
|
||||
User::factory()->create([
|
||||
'name' => 'Test User',
|
||||
'email' => 'test@example.com',
|
||||
|
||||
40
database/seeders/NovaCardCategorySeeder.php
Normal file
40
database/seeders/NovaCardCategorySeeder.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\NovaCardCategory;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class NovaCardCategorySeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$categories = [
|
||||
['slug' => 'motivation', 'name' => 'Motivation'],
|
||||
['slug' => 'love', 'name' => 'Love'],
|
||||
['slug' => 'life', 'name' => 'Life'],
|
||||
['slug' => 'happiness', 'name' => 'Happiness'],
|
||||
['slug' => 'healing', 'name' => 'Healing'],
|
||||
['slug' => 'friendship', 'name' => 'Friendship'],
|
||||
['slug' => 'aesthetic', 'name' => 'Aesthetic'],
|
||||
['slug' => 'minimal', 'name' => 'Minimal'],
|
||||
['slug' => 'dark-mood', 'name' => 'Dark Mood'],
|
||||
['slug' => 'poetry', 'name' => 'Poetry'],
|
||||
['slug' => 'wallpaper-quotes', 'name' => 'Wallpaper Quotes'],
|
||||
];
|
||||
|
||||
foreach ($categories as $index => $category) {
|
||||
NovaCardCategory::query()->updateOrCreate(
|
||||
['slug' => $category['slug']],
|
||||
[
|
||||
'name' => $category['name'],
|
||||
'description' => sprintf('%s cards and shareable quote visuals.', $category['name']),
|
||||
'active' => true,
|
||||
'order_num' => $index,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
357
database/seeders/NovaCardDemoSeeder.php
Normal file
357
database/seeders/NovaCardDemoSeeder.php
Normal file
@@ -0,0 +1,357 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\NovaCard;
|
||||
use App\Models\NovaCardAsset;
|
||||
use App\Models\NovaCardAssetPack;
|
||||
use App\Models\NovaCardCategory;
|
||||
use App\Models\NovaCardChallenge;
|
||||
use App\Models\NovaCardChallengeEntry;
|
||||
use App\Models\NovaCardCollection;
|
||||
use App\Models\NovaCardCollectionItem;
|
||||
use App\Models\NovaCardTag;
|
||||
use App\Models\NovaCardTemplate;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class NovaCardDemoSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
if (! (bool) config('nova_cards.seed_demo_cards.enabled', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$userConfig = (array) config('nova_cards.seed_demo_cards.user', []);
|
||||
$user = User::query()->firstOrCreate(
|
||||
['email' => (string) Arr::get($userConfig, 'email', 'nova-cards-demo@skinbase.test')],
|
||||
[
|
||||
'username' => (string) Arr::get($userConfig, 'username', 'nova.cards'),
|
||||
'name' => (string) Arr::get($userConfig, 'name', 'Nova Cards'),
|
||||
'password' => (string) Arr::get($userConfig, 'password', 'password'),
|
||||
'role' => 'user',
|
||||
]
|
||||
);
|
||||
|
||||
$cards = [
|
||||
[
|
||||
'slug' => 'official-spark',
|
||||
'title' => 'Official Spark',
|
||||
'quote_text' => 'Small moments of focus turn into visible momentum.',
|
||||
'quote_author' => 'Skinbase Nova',
|
||||
'quote_source' => 'Launch Collection',
|
||||
'description' => 'An official Nova Cards demo card for featured browse surfaces.',
|
||||
'category_slug' => 'motivation',
|
||||
'template_slug' => 'neon-nova',
|
||||
'format' => NovaCard::FORMAT_SQUARE,
|
||||
'featured' => true,
|
||||
'tags' => ['focus', 'launch'],
|
||||
'project_json' => [
|
||||
'layout' => ['layout' => 'quote_heavy', 'position' => 'center', 'alignment' => 'center', 'padding' => 'comfortable', 'max_width' => 'balanced'],
|
||||
'typography' => ['font_preset' => 'bold-poster', 'text_color' => '#e0f2fe', 'accent_color' => '#ffffff', 'quote_size' => 80, 'author_size' => 24, 'letter_spacing' => 1, 'line_height' => 1.05, 'shadow_preset' => 'strong'],
|
||||
'background' => ['type' => 'gradient', 'gradient_preset' => 'midnight-nova', 'gradient_colors' => ['#0f172a', '#1d4ed8'], 'solid_color' => '#111827', 'overlay_style' => 'dark-strong', 'focal_position' => 'center', 'blur_level' => 0, 'opacity' => 65],
|
||||
],
|
||||
],
|
||||
[
|
||||
'slug' => 'soft-breath',
|
||||
'title' => 'Soft Breath',
|
||||
'quote_text' => 'Rest is not a pause from growth. It is part of it.',
|
||||
'quote_author' => 'Skinbase Nova',
|
||||
'quote_source' => 'Healing Notes',
|
||||
'description' => 'A calm demo card showing the softer side of Nova Cards.',
|
||||
'category_slug' => 'healing',
|
||||
'template_slug' => 'soft-pastel',
|
||||
'format' => NovaCard::FORMAT_PORTRAIT,
|
||||
'featured' => false,
|
||||
'tags' => ['healing', 'calm'],
|
||||
'project_json' => [
|
||||
'layout' => ['layout' => 'centered', 'position' => 'center', 'alignment' => 'center', 'padding' => 'airy', 'max_width' => 'compact'],
|
||||
'typography' => ['font_preset' => 'soft-handwritten', 'text_color' => '#1f2937', 'accent_color' => '#6d28d9', 'quote_size' => 72, 'author_size' => 24, 'letter_spacing' => 0, 'line_height' => 1.2, 'shadow_preset' => 'none'],
|
||||
'background' => ['type' => 'gradient', 'gradient_preset' => 'soft-pastel', 'gradient_colors' => ['#f9a8d4', '#c4b5fd'], 'solid_color' => '#f5d0fe', 'overlay_style' => 'light-soft', 'focal_position' => 'center', 'blur_level' => 0, 'opacity' => 35],
|
||||
],
|
||||
],
|
||||
[
|
||||
'slug' => 'night-echo',
|
||||
'title' => 'Night Echo',
|
||||
'quote_text' => 'Not every quiet room is empty. Some are full of answers.',
|
||||
'quote_author' => 'Skinbase Nova',
|
||||
'quote_source' => 'Dark Mood Study',
|
||||
'description' => 'A darker official demo card for mood-oriented discovery blocks.',
|
||||
'category_slug' => 'dark-mood',
|
||||
'template_slug' => 'cinematic-dark',
|
||||
'format' => NovaCard::FORMAT_LANDSCAPE,
|
||||
'featured' => false,
|
||||
'tags' => ['night', 'mood'],
|
||||
'project_json' => [
|
||||
'layout' => ['layout' => 'minimal', 'position' => 'lower-middle', 'alignment' => 'left', 'padding' => 'comfortable', 'max_width' => 'wide'],
|
||||
'typography' => ['font_preset' => 'modern-sans', 'text_color' => '#f8fafc', 'accent_color' => '#93c5fd', 'quote_size' => 68, 'author_size' => 20, 'letter_spacing' => 1, 'line_height' => 1.2, 'shadow_preset' => 'soft'],
|
||||
'background' => ['type' => 'gradient', 'gradient_preset' => 'deep-cinema', 'gradient_colors' => ['#020617', '#334155'], 'solid_color' => '#020617', 'overlay_style' => 'dark-strong', 'focal_position' => 'center', 'blur_level' => 0, 'opacity' => 80],
|
||||
],
|
||||
],
|
||||
[
|
||||
'slug' => 'editorial-glow',
|
||||
'title' => 'Editorial Glow',
|
||||
'quote_text' => 'Design with restraint, then let one accent do the speaking.',
|
||||
'quote_author' => 'Skinbase Nova',
|
||||
'quote_source' => 'Editorial Kit',
|
||||
'description' => 'A crisp editorial-format demo card for official collections.',
|
||||
'category_slug' => 'motivation',
|
||||
'template_slug' => 'golden-serif',
|
||||
'format' => NovaCard::FORMAT_PORTRAIT,
|
||||
'featured' => true,
|
||||
'tags' => ['editorial', 'gold'],
|
||||
'project_json' => [
|
||||
'layout' => ['layout' => 'author_emphasis', 'position' => 'center', 'alignment' => 'center', 'padding' => 'comfortable', 'max_width' => 'compact'],
|
||||
'typography' => ['font_preset' => 'elegant-serif', 'text_color' => '#fffbeb', 'accent_color' => '#fbbf24', 'quote_size' => 76, 'author_size' => 24, 'letter_spacing' => 1, 'line_height' => 1.15, 'shadow_preset' => 'soft'],
|
||||
'background' => ['type' => 'gradient', 'gradient_preset' => 'amber-glow', 'gradient_colors' => ['#451a03', '#b45309'], 'solid_color' => '#451a03', 'overlay_style' => 'dark-soft', 'focal_position' => 'center', 'blur_level' => 0, 'opacity' => 70],
|
||||
],
|
||||
],
|
||||
[
|
||||
'slug' => 'story-bloom',
|
||||
'title' => 'Story Bloom',
|
||||
'quote_text' => 'If the layout breathes, the words can reach further.',
|
||||
'quote_author' => 'Skinbase Nova',
|
||||
'quote_source' => 'Story Vertical Pack',
|
||||
'description' => 'A vertical story-oriented demo card for public browsing and challenges.',
|
||||
'category_slug' => 'healing',
|
||||
'template_slug' => 'story-vertical',
|
||||
'format' => NovaCard::FORMAT_STORY,
|
||||
'featured' => false,
|
||||
'tags' => ['story', 'vertical'],
|
||||
'project_json' => [
|
||||
'layout' => ['layout' => 'centered', 'position' => 'center', 'alignment' => 'center', 'padding' => 'airy', 'max_width' => 'balanced'],
|
||||
'typography' => ['font_preset' => 'modern-sans', 'text_color' => '#ecfdf5', 'accent_color' => '#6ee7b7', 'quote_size' => 82, 'author_size' => 24, 'letter_spacing' => 0, 'line_height' => 1.18, 'shadow_preset' => 'soft'],
|
||||
'background' => ['type' => 'gradient', 'gradient_preset' => 'emerald-bloom', 'gradient_colors' => ['#064e3b', '#10b981'], 'solid_color' => '#022c22', 'overlay_style' => 'dark-soft', 'focal_position' => 'center', 'blur_level' => 0, 'opacity' => 65],
|
||||
],
|
||||
],
|
||||
[
|
||||
'slug' => 'remix-launch-variant',
|
||||
'title' => 'Remix Launch Variant',
|
||||
'quote_text' => 'Take the spark and give it a new rhythm.',
|
||||
'quote_author' => 'Skinbase Nova',
|
||||
'quote_source' => 'Remix Lab',
|
||||
'description' => 'A seeded remix showing lineage in demo content.',
|
||||
'category_slug' => 'motivation',
|
||||
'template_slug' => 'bold-statement',
|
||||
'format' => NovaCard::FORMAT_SQUARE,
|
||||
'featured' => false,
|
||||
'tags' => ['remix', 'launch'],
|
||||
'project_json' => [
|
||||
'layout' => ['layout' => 'quote_heavy', 'position' => 'center', 'alignment' => 'left', 'padding' => 'comfortable', 'max_width' => 'wide'],
|
||||
'typography' => ['font_preset' => 'bold-poster', 'text_color' => '#ffffff', 'accent_color' => '#38bdf8', 'quote_size' => 80, 'author_size' => 22, 'letter_spacing' => 1, 'line_height' => 1.05, 'shadow_preset' => 'strong'],
|
||||
'background' => ['type' => 'gradient', 'gradient_preset' => 'midnight-nova', 'gradient_colors' => ['#082f49', '#1d4ed8'], 'solid_color' => '#0f172a', 'overlay_style' => 'dark-strong', 'focal_position' => 'center', 'blur_level' => 0, 'opacity' => 75],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$seededCards = collect();
|
||||
|
||||
foreach ($cards as $index => $definition) {
|
||||
$category = NovaCardCategory::query()->where('slug', $definition['category_slug'])->first();
|
||||
$template = NovaCardTemplate::query()->where('slug', $definition['template_slug'])->first();
|
||||
|
||||
$card = NovaCard::query()->updateOrCreate(
|
||||
['slug' => $definition['slug']],
|
||||
[
|
||||
'uuid' => NovaCard::query()->where('slug', $definition['slug'])->value('uuid') ?: (string) Str::uuid(),
|
||||
'user_id' => $user->id,
|
||||
'category_id' => $category?->id,
|
||||
'template_id' => $template?->id,
|
||||
'title' => $definition['title'],
|
||||
'quote_text' => $definition['quote_text'],
|
||||
'quote_author' => $definition['quote_author'],
|
||||
'quote_source' => $definition['quote_source'],
|
||||
'description' => $definition['description'],
|
||||
'format' => $definition['format'],
|
||||
'project_json' => [
|
||||
'content' => [
|
||||
'title' => $definition['title'],
|
||||
'quote_text' => $definition['quote_text'],
|
||||
'quote_author' => $definition['quote_author'],
|
||||
'quote_source' => $definition['quote_source'],
|
||||
],
|
||||
...$definition['project_json'],
|
||||
'decorations' => [],
|
||||
],
|
||||
'render_version' => 1,
|
||||
'background_type' => 'gradient',
|
||||
'visibility' => NovaCard::VISIBILITY_PUBLIC,
|
||||
'status' => NovaCard::STATUS_PUBLISHED,
|
||||
'moderation_status' => NovaCard::MOD_APPROVED,
|
||||
'featured' => (bool) $definition['featured'],
|
||||
'allow_download' => true,
|
||||
'views_count' => 25 - ($index * 4),
|
||||
'shares_count' => 6 - $index,
|
||||
'downloads_count' => 3 - min($index, 2),
|
||||
'likes_count' => max(1, 8 - $index),
|
||||
'favorites_count' => max(0, 5 - $index),
|
||||
'saves_count' => max(0, 4 - $index),
|
||||
'published_at' => now()->subDays($index + 1),
|
||||
]
|
||||
);
|
||||
|
||||
$tagIds = collect($definition['tags'])
|
||||
->map(function (string $tag): int {
|
||||
$model = NovaCardTag::query()->firstOrCreate(
|
||||
['slug' => Str::slug($tag)],
|
||||
['name' => Str::title(str_replace('-', ' ', $tag))]
|
||||
);
|
||||
|
||||
return (int) $model->id;
|
||||
})
|
||||
->all();
|
||||
|
||||
$card->tags()->sync($tagIds);
|
||||
$seededCards->push($card->fresh());
|
||||
}
|
||||
|
||||
$source = $seededCards->firstWhere('slug', 'official-spark');
|
||||
$remix = $seededCards->firstWhere('slug', 'remix-launch-variant');
|
||||
|
||||
if ($source && $remix) {
|
||||
$remix->forceFill([
|
||||
'original_card_id' => $source->id,
|
||||
'root_card_id' => $source->id,
|
||||
'remixes_count' => 0,
|
||||
])->save();
|
||||
|
||||
$source->forceFill([
|
||||
'remixes_count' => 1,
|
||||
])->save();
|
||||
}
|
||||
|
||||
foreach (array_merge(
|
||||
(array) config('nova_cards.asset_packs', []),
|
||||
(array) config('nova_cards.template_packs', [])
|
||||
) as $index => $packConfig) {
|
||||
$pack = NovaCardAssetPack::query()->updateOrCreate(
|
||||
['slug' => (string) ($packConfig['slug'] ?? ('pack-' . $index))],
|
||||
[
|
||||
'name' => (string) ($packConfig['name'] ?? 'Nova Card Pack'),
|
||||
'description' => $packConfig['description'] ?? null,
|
||||
'type' => (string) ($packConfig['type'] ?? NovaCardAssetPack::TYPE_ASSET),
|
||||
'manifest_json' => $packConfig['manifest_json'] ?? [],
|
||||
'official' => (bool) ($packConfig['official'] ?? true),
|
||||
'active' => (bool) ($packConfig['active'] ?? true),
|
||||
'order_num' => $index,
|
||||
]
|
||||
);
|
||||
|
||||
foreach ((array) data_get($packConfig, 'manifest_json.items', []) as $itemIndex => $item) {
|
||||
NovaCardAsset::query()->updateOrCreate(
|
||||
['asset_pack_id' => $pack->id, 'asset_key' => (string) ($item['key'] ?? ('asset-' . $itemIndex))],
|
||||
[
|
||||
'label' => (string) ($item['label'] ?? 'Nova Asset'),
|
||||
'type' => (string) ($item['type'] ?? 'glyph'),
|
||||
'preview_image' => $item['preview_image'] ?? null,
|
||||
'data_json' => $item,
|
||||
'official' => true,
|
||||
'active' => true,
|
||||
'order_num' => $itemIndex,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$collection = NovaCardCollection::query()->updateOrCreate(
|
||||
['user_id' => $user->id, 'slug' => 'editorial-favorites'],
|
||||
[
|
||||
'name' => 'Editorial Favorites',
|
||||
'description' => 'Officially curated Nova Cards spotlighting launch visuals, remixes, and story-first layouts.',
|
||||
'visibility' => NovaCardCollection::VISIBILITY_PUBLIC,
|
||||
'official' => true,
|
||||
'featured' => true,
|
||||
'cards_count' => 0,
|
||||
]
|
||||
);
|
||||
|
||||
$challengeCollection = NovaCardCollection::query()->updateOrCreate(
|
||||
['user_id' => $user->id, 'slug' => 'challenge-winners'],
|
||||
[
|
||||
'name' => 'Challenge Winners',
|
||||
'description' => 'Official challenge highlights and standout seeded examples.',
|
||||
'visibility' => NovaCardCollection::VISIBILITY_PUBLIC,
|
||||
'official' => true,
|
||||
'featured' => false,
|
||||
'cards_count' => 0,
|
||||
]
|
||||
);
|
||||
|
||||
foreach ($seededCards->take(4)->values() as $position => $card) {
|
||||
NovaCardCollectionItem::query()->updateOrCreate(
|
||||
['collection_id' => $collection->id, 'card_id' => $card->id],
|
||||
['sort_order' => $position + 1, 'note' => $position === 0 ? 'Launch anchor card for the collection.' : null],
|
||||
);
|
||||
}
|
||||
|
||||
$collection->forceFill(['cards_count' => NovaCardCollectionItem::query()->where('collection_id', $collection->id)->count()])->save();
|
||||
|
||||
foreach ($seededCards->slice(2, 4)->values() as $position => $card) {
|
||||
NovaCardCollectionItem::query()->updateOrCreate(
|
||||
['collection_id' => $challengeCollection->id, 'card_id' => $card->id],
|
||||
['sort_order' => $position + 1, 'note' => $position === 0 ? 'Seeded challenge highlight.' : null],
|
||||
);
|
||||
}
|
||||
|
||||
$challengeCollection->forceFill(['cards_count' => NovaCardCollectionItem::query()->where('collection_id', $challengeCollection->id)->count()])->save();
|
||||
|
||||
$challenge = NovaCardChallenge::query()->updateOrCreate(
|
||||
['slug' => 'launch-remix-run'],
|
||||
[
|
||||
'user_id' => $user->id,
|
||||
'title' => 'Launch Remix Run',
|
||||
'description' => 'A seeded official challenge for remix-ready launch cards.',
|
||||
'prompt' => 'Remix one official card and push the layout into a fresh direction.',
|
||||
'status' => NovaCardChallenge::STATUS_ACTIVE,
|
||||
'official' => true,
|
||||
'featured' => true,
|
||||
'starts_at' => now()->subDays(2),
|
||||
'ends_at' => now()->addDays(10),
|
||||
]
|
||||
);
|
||||
|
||||
$secondaryChallenge = NovaCardChallenge::query()->updateOrCreate(
|
||||
['slug' => 'minimal-poster-week'],
|
||||
[
|
||||
'user_id' => $user->id,
|
||||
'title' => 'Minimal Poster Week',
|
||||
'description' => 'A seeded editorial challenge focused on restraint and poster typography.',
|
||||
'prompt' => 'Build a bold quote poster with minimal decoration and strong hierarchy.',
|
||||
'status' => NovaCardChallenge::STATUS_COMPLETED,
|
||||
'official' => true,
|
||||
'featured' => false,
|
||||
'starts_at' => now()->subDays(14),
|
||||
'ends_at' => now()->subDays(3),
|
||||
]
|
||||
);
|
||||
|
||||
foreach ($seededCards->take(3)->values() as $position => $card) {
|
||||
NovaCardChallengeEntry::query()->updateOrCreate(
|
||||
['challenge_id' => $challenge->id, 'card_id' => $card->id],
|
||||
['user_id' => $user->id, 'status' => $position === 0 ? 'featured' : 'active', 'note' => $position === 0 ? 'Seeded featured entry.' : null],
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($seededCards->slice(3, 3)->values() as $position => $card) {
|
||||
NovaCardChallengeEntry::query()->updateOrCreate(
|
||||
['challenge_id' => $secondaryChallenge->id, 'card_id' => $card->id],
|
||||
['user_id' => $user->id, 'status' => $position === 0 ? 'winner' : 'active', 'note' => $position === 0 ? 'Seeded winner entry.' : null],
|
||||
);
|
||||
}
|
||||
|
||||
$challenge->forceFill([
|
||||
'entries_count' => NovaCardChallengeEntry::query()->where('challenge_id', $challenge->id)->count(),
|
||||
'winner_card_id' => $seededCards->first()?->id,
|
||||
])->save();
|
||||
|
||||
$secondaryChallenge->forceFill([
|
||||
'entries_count' => NovaCardChallengeEntry::query()->where('challenge_id', $secondaryChallenge->id)->count(),
|
||||
'winner_card_id' => $seededCards->get(3)?->id,
|
||||
])->save();
|
||||
}
|
||||
}
|
||||
117
database/seeders/NovaCardTemplateSeeder.php
Normal file
117
database/seeders/NovaCardTemplateSeeder.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\NovaCardTemplate;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class NovaCardTemplateSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$templates = [
|
||||
[
|
||||
'slug' => 'minimal-black-white',
|
||||
'name' => 'Minimal Black / White',
|
||||
'description' => 'High-contrast minimalist typography.',
|
||||
'formats' => ['square', 'portrait', 'landscape'],
|
||||
'config' => ['font_preset' => 'minimal-editorial', 'gradient_preset' => 'deep-cinema', 'text_align' => 'left', 'layout' => 'minimal', 'text_color' => '#ffffff', 'overlay_style' => 'dark-soft'],
|
||||
],
|
||||
[
|
||||
'slug' => 'neon-nova',
|
||||
'name' => 'Neon Nova',
|
||||
'description' => 'Bright accents with deep night gradients.',
|
||||
'formats' => ['square', 'portrait', 'story'],
|
||||
'config' => ['font_preset' => 'bold-poster', 'gradient_preset' => 'midnight-nova', 'text_align' => 'center', 'layout' => 'centered', 'text_color' => '#e0f2fe', 'overlay_style' => 'dark-strong'],
|
||||
],
|
||||
[
|
||||
'slug' => 'soft-pastel',
|
||||
'name' => 'Soft Pastel',
|
||||
'description' => 'Soft pastel tones for uplifting cards.',
|
||||
'formats' => ['square', 'portrait'],
|
||||
'config' => ['font_preset' => 'soft-handwritten', 'gradient_preset' => 'soft-pastel', 'text_align' => 'center', 'layout' => 'quote_heavy', 'text_color' => '#1f2937', 'overlay_style' => 'light-soft'],
|
||||
],
|
||||
[
|
||||
'slug' => 'romantic',
|
||||
'name' => 'Romantic',
|
||||
'description' => 'Warm romantic quote treatments.',
|
||||
'formats' => ['square', 'portrait', 'story'],
|
||||
'config' => ['font_preset' => 'elegant-serif', 'gradient_preset' => 'romantic-dusk', 'text_align' => 'center', 'layout' => 'author_emphasis', 'text_color' => '#fff1f2', 'overlay_style' => 'dark-soft'],
|
||||
],
|
||||
[
|
||||
'slug' => 'cinematic-dark',
|
||||
'name' => 'Cinematic Dark',
|
||||
'description' => 'Moody cinematic composition.',
|
||||
'formats' => ['square', 'portrait', 'landscape'],
|
||||
'config' => ['font_preset' => 'modern-sans', 'gradient_preset' => 'deep-cinema', 'text_align' => 'left', 'layout' => 'quote_heavy', 'text_color' => '#f8fafc', 'overlay_style' => 'dark-strong'],
|
||||
],
|
||||
[
|
||||
'slug' => 'golden-serif',
|
||||
'name' => 'Golden Serif',
|
||||
'description' => 'Elegant serif layout with warm highlights.',
|
||||
'formats' => ['square', 'portrait', 'landscape'],
|
||||
'config' => ['font_preset' => 'elegant-serif', 'gradient_preset' => 'amber-glow', 'text_align' => 'center', 'layout' => 'author_emphasis', 'text_color' => '#fffbeb', 'overlay_style' => 'dark-soft'],
|
||||
],
|
||||
[
|
||||
'slug' => 'nature-calm',
|
||||
'name' => 'Nature Calm',
|
||||
'description' => 'Fresh greens and sky tones.',
|
||||
'formats' => ['square', 'portrait', 'story'],
|
||||
'config' => ['font_preset' => 'dreamy-aesthetic', 'gradient_preset' => 'nature-calm', 'text_align' => 'left', 'layout' => 'centered', 'text_color' => '#ecfeff', 'overlay_style' => 'dark-soft'],
|
||||
],
|
||||
[
|
||||
'slug' => 'bold-statement',
|
||||
'name' => 'Bold Statement',
|
||||
'description' => 'Large statement typography.',
|
||||
'formats' => ['square', 'portrait', 'landscape'],
|
||||
'config' => ['font_preset' => 'bold-poster', 'gradient_preset' => 'midnight-nova', 'text_align' => 'left', 'layout' => 'quote_heavy', 'text_color' => '#ffffff', 'overlay_style' => 'dark-strong'],
|
||||
],
|
||||
[
|
||||
'slug' => 'wallpaper-style',
|
||||
'name' => 'Wallpaper Style',
|
||||
'description' => 'Spacious wallpaper-like composition.',
|
||||
'formats' => ['portrait', 'story', 'landscape'],
|
||||
'config' => ['font_preset' => 'dreamy-aesthetic', 'gradient_preset' => 'dream-glow', 'text_align' => 'center', 'layout' => 'minimal', 'text_color' => '#fdf4ff', 'overlay_style' => 'dark-soft'],
|
||||
],
|
||||
[
|
||||
'slug' => 'story-vertical',
|
||||
'name' => 'Story Vertical',
|
||||
'description' => 'Tall mobile-first story layout.',
|
||||
'formats' => ['story'],
|
||||
'config' => ['font_preset' => 'modern-sans', 'gradient_preset' => 'emerald-bloom', 'text_align' => 'center', 'layout' => 'centered', 'text_color' => '#ecfdf5', 'overlay_style' => 'dark-soft'],
|
||||
],
|
||||
[
|
||||
'slug' => 'dream-glow',
|
||||
'name' => 'Dream Glow',
|
||||
'description' => 'Glowing dreamy aesthetic template.',
|
||||
'formats' => ['square', 'portrait', 'story'],
|
||||
'config' => ['font_preset' => 'dreamy-aesthetic', 'gradient_preset' => 'dream-glow', 'text_align' => 'center', 'layout' => 'quote_heavy', 'text_color' => '#faf5ff', 'overlay_style' => 'dark-soft'],
|
||||
],
|
||||
[
|
||||
'slug' => 'classic-typography',
|
||||
'name' => 'Classic Typography',
|
||||
'description' => 'Classic bookish quote treatment.',
|
||||
'formats' => ['square', 'portrait', 'landscape'],
|
||||
'config' => ['font_preset' => 'elegant-serif', 'gradient_preset' => 'amber-glow', 'text_align' => 'left', 'layout' => 'author_emphasis', 'text_color' => '#fff7ed', 'overlay_style' => 'dark-soft'],
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($templates as $index => $template) {
|
||||
NovaCardTemplate::query()->updateOrCreate(
|
||||
['slug' => $template['slug']],
|
||||
[
|
||||
'name' => $template['name'],
|
||||
'description' => $template['description'],
|
||||
'preview_image' => null,
|
||||
'config_json' => $template['config'],
|
||||
'supported_formats' => $template['formats'],
|
||||
'active' => true,
|
||||
'official' => true,
|
||||
'order_num' => $index,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user