files = $files; } /** * Execute the console command. */ public function handle(): int { $name = $this->argument('name'); $className = Str::studly($name); $kebabName = Str::kebab($name); $this->info("🚀 Generating ThrillWiki Livewire Component: {$className}"); // Generate the component class $this->generateComponent($className, $kebabName); // Generate the view file $this->generateView($className, $kebabName); // Generate tests if requested if ($this->option('with-tests')) { $this->generateTest($className); } $this->displaySummary($className, $kebabName); return Command::SUCCESS; } protected function generateComponent(string $className, string $kebabName): void { $componentPath = app_path("Livewire/{$className}.php"); if ($this->files->exists($componentPath) && !$this->option('force')) { $this->error("Component {$className} already exists! Use --force to overwrite."); return; } $stub = $this->getComponentStub(); $content = $this->replaceStubPlaceholders($stub, $className, $kebabName); $this->files->ensureDirectoryExists(dirname($componentPath)); $this->files->put($componentPath, $content); $this->info("✅ Component created: app/Livewire/{$className}.php"); } protected function generateView(string $className, string $kebabName): void { $viewPath = resource_path("views/livewire/{$kebabName}.blade.php"); if ($this->files->exists($viewPath) && !$this->option('force')) { $this->error("View {$kebabName}.blade.php already exists! Use --force to overwrite."); return; } $stub = $this->getViewStub(); $content = $this->replaceViewPlaceholders($stub, $className, $kebabName); $this->files->ensureDirectoryExists(dirname($viewPath)); $this->files->put($viewPath, $content); $this->info("✅ View created: resources/views/livewire/{$kebabName}.blade.php"); } protected function generateTest(string $className): void { $testPath = base_path("tests/Feature/Livewire/{$className}Test.php"); if ($this->files->exists($testPath) && !$this->option('force')) { $this->error("Test {$className}Test already exists! Use --force to overwrite."); return; } $stub = $this->getTestStub(); $content = $this->replaceTestPlaceholders($stub, $className); $this->files->ensureDirectoryExists(dirname($testPath)); $this->files->put($testPath, $content); $this->info("✅ Test created: tests/Feature/Livewire/{$className}Test.php"); } protected function getComponentStub(): string { $traits = []; $imports = ['use Livewire\Component;']; $properties = []; $methods = []; // Add pagination if requested if ($this->option('paginated')) { $imports[] = 'use Livewire\WithPagination;'; $traits[] = 'WithPagination'; $properties[] = ' protected $paginationTheme = \'tailwind\';'; } // Add caching optimization if requested if ($this->option('cached') || $this->option('reusable')) { $imports[] = 'use Illuminate\Support\Facades\Cache;'; $methods[] = $this->getCachingMethods(); } // Build traits string $traitsString = empty($traits) ? '' : "\n use " . implode(', ', $traits) . ";\n"; // Build properties string $propertiesString = empty($properties) ? '' : "\n" . implode("\n", $properties) . "\n"; // Build methods string $methodsString = implode("\n\n", $methods); return <<option('reusable')) { return << {{-- Component Header --}}

{CLASS_NAME}

{{-- Component Content --}}

ThrillWiki component content goes here.

{{-- Example interactive element --}}
{{-- Loading State --}}
BLADE; } return <<

{CLASS_NAME}

ThrillWiki component content goes here.

BLADE; } protected function getTestStub(): string { return <<assertStatus(200) ->assertSee('{CLASS_NAME}'); } /** @test */ public function component_can_mount_successfully(): void { Livewire::test({CLASS_NAME}::class) ->assertStatus(200); } /** @test */ public function component_follows_thrillwiki_patterns(): void { Livewire::test({CLASS_NAME}::class) ->assertViewIs('livewire.{VIEW_NAME}'); } } PHP; } protected function getCachingMethods(): string { return <<getCacheKey(\$key), \$ttl, \$callback); } /** * Invalidate component cache */ protected function invalidateCache(string \$key = null): void { if (\$key) { Cache::forget(\$this->getCacheKey(\$key)); } else { // Clear all cache for this component Cache::flush(); } } PHP; } protected function replaceStubPlaceholders(string $stub, string $className, string $kebabName): string { $imports = ['use Livewire\Component;']; $traits = []; if ($this->option('paginated')) { $imports[] = 'use Livewire\WithPagination;'; $traits[] = 'WithPagination'; } if ($this->option('cached') || $this->option('reusable')) { $imports[] = 'use Illuminate\Support\Facades\Cache;'; } $traitsString = empty($traits) ? '' : "\n use " . implode(', ', $traits) . ";\n"; $importsString = implode("\n", $imports); $methodsString = ''; if ($this->option('cached') || $this->option('reusable')) { $methodsString = "\n\n" . $this->getCachingMethods(); } return str_replace( ['{IMPORTS}', '{CLASS_NAME}', '{VIEW_NAME}', '{TRAITS}', '{PROPERTIES}', '{METHODS}'], [$importsString, $className, $kebabName, $traitsString, '', $methodsString], $stub ); } protected function replaceViewPlaceholders(string $stub, string $className, string $kebabName): string { return str_replace( ['{CLASS_NAME}', '{VIEW_NAME}'], [$className, $kebabName], $stub ); } protected function replaceTestPlaceholders(string $stub, string $className): string { return str_replace( ['{CLASS_NAME}', '{VIEW_NAME}'], [$className, Str::kebab($className)], $stub ); } protected function displaySummary(string $className, string $kebabName): void { $this->newLine(); $this->info("🎉 ThrillWiki Livewire Component '{$className}' created successfully!"); $this->newLine(); $this->comment("📁 Files Generated:"); $this->line(" • app/Livewire/{$className}.php"); $this->line(" • resources/views/livewire/{$kebabName}.blade.php"); if ($this->option('with-tests')) { $this->line(" • tests/Feature/Livewire/{$className}Test.php"); } $this->newLine(); $this->comment("🚀 Features Added:"); if ($this->option('reusable')) { $this->line(" • Reusable component patterns with optimization traits"); } if ($this->option('cached')) { $this->line(" • Caching optimization methods"); } if ($this->option('paginated')) { $this->line(" • Pagination support with Tailwind theme"); } if ($this->option('with-tests')) { $this->line(" • Automated test suite with ThrillWiki patterns"); } $this->newLine(); $this->comment("📝 Next Steps:"); $this->line(" 1. Customize the component logic in app/Livewire/{$className}.php"); $this->line(" 2. Update the view template in resources/views/livewire/{$kebabName}.blade.php"); $this->line(" 3. Include the component in your templates with "); if ($this->option('with-tests')) { $this->line(" 4. Run tests with: php artisan test --filter {$className}Test"); } $this->newLine(); $this->info("✨ Happy coding with ThrillWiki acceleration patterns!"); } }