diff --git a/app/Filament/Resources/PluginResource.php b/app/Filament/Resources/PluginResource.php index 80434eb6..96ba3290 100644 --- a/app/Filament/Resources/PluginResource.php +++ b/app/Filament/Resources/PluginResource.php @@ -242,6 +242,11 @@ public static function table(Table $table): Table }) ->sortable(), + Tables\Columns\TextColumn::make('mobile_min_version') + ->label('Mobile SDK') + ->placeholder('-') + ->toggleable(isToggledHiddenByDefault: true), + Tables\Columns\ToggleColumn::make('featured') ->sortable(), diff --git a/app/Services/PluginSyncService.php b/app/Services/PluginSyncService.php index d7199c55..c929db84 100644 --- a/app/Services/PluginSyncService.php +++ b/app/Services/PluginSyncService.php @@ -89,6 +89,10 @@ public function sync(Plugin $plugin): bool $updateData['android_version'] = $this->extractAndroidVersion($nativephpData); } + if ($composerData) { + $updateData['mobile_min_version'] = $composerData['require']['nativephp/mobile'] ?? null; + } + if ($readme) { $updateData['readme_html'] = CommonMark::convertToHtml($readme); } diff --git a/database/migrations/2026_03_30_135919_add_mobile_min_version_to_plugins_table.php b/database/migrations/2026_03_30_135919_add_mobile_min_version_to_plugins_table.php new file mode 100644 index 00000000..8a6fdfd2 --- /dev/null +++ b/database/migrations/2026_03_30_135919_add_mobile_min_version_to_plugins_table.php @@ -0,0 +1,28 @@ +string('mobile_min_version')->nullable()->after('android_version'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('plugins', function (Blueprint $table) { + $table->dropColumn('mobile_min_version'); + }); + } +}; diff --git a/package-lock.json b/package-lock.json index 3a761fe2..0d04291b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "golden-poodle", + "name": "cyan-salmon", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/resources/views/components/layout.blade.php b/resources/views/components/layout.blade.php index 2500b684..f5360382 100644 --- a/resources/views/components/layout.blade.php +++ b/resources/views/components/layout.blade.php @@ -121,6 +121,9 @@ class="mx-auto w-full max-w-5xl px-5 lg:px-3 xl:max-w-7xl 2xl:max-w-360" + + + @livewireScriptConfig @fluxScripts @vite('resources/js/app.js') diff --git a/resources/views/customer/ultra/index.blade.php b/resources/views/customer/ultra/index.blade.php index 06edbe1e..bfae9a1c 100644 --- a/resources/views/customer/ultra/index.blade.php +++ b/resources/views/customer/ultra/index.blade.php @@ -149,7 +149,7 @@ @endif -
+
{{ $plugin->name }} diff --git a/resources/views/livewire/customer/dashboard.blade.php b/resources/views/livewire/customer/dashboard.blade.php index 18e4620f..2d9716fd 100644 --- a/resources/views/livewire/customer/dashboard.blade.php +++ b/resources/views/livewire/customer/dashboard.blade.php @@ -35,7 +35,7 @@ Upgrade to NativePHP Ultra

- Get all first-party plugins for free, premium support, team management, and more. + Access all first-party plugins at no extra cost, premium support, team management, and more.

-
All first-party plugins for free
+
All first-party plugins at no extra cost
+
NativePHP Mobile
+
+ {{ $plugin->mobile_min_version ?? '—' }} +
+
+ {{-- iOS Version --}}
iOS
diff --git a/tests/Feature/PluginShowMobileVersionTest.php b/tests/Feature/PluginShowMobileVersionTest.php new file mode 100644 index 00000000..c28408ba --- /dev/null +++ b/tests/Feature/PluginShowMobileVersionTest.php @@ -0,0 +1,44 @@ +approved()->create([ + 'mobile_min_version' => '^3.0.0', + ]); + + $this->get(route('plugins.show', $plugin->routeParams())) + ->assertStatus(200) + ->assertSee('NativePHP Mobile') + ->assertSee('^3.0.0'); + } + + public function test_plugin_show_displays_dash_when_mobile_min_version_is_null(): void + { + $plugin = Plugin::factory()->approved()->create([ + 'mobile_min_version' => null, + ]); + + $this->get(route('plugins.show', $plugin->routeParams())) + ->assertStatus(200) + ->assertSee('NativePHP Mobile'); + } +} diff --git a/tests/Feature/PluginSyncServiceTest.php b/tests/Feature/PluginSyncServiceTest.php new file mode 100644 index 00000000..8c24b11e --- /dev/null +++ b/tests/Feature/PluginSyncServiceTest.php @@ -0,0 +1,80 @@ + 'acme/test-plugin', + 'require' => [ + 'nativephp/mobile' => '^3.0.0', + ], + ]); + + Http::fake([ + 'api.github.com/repos/acme/test-plugin/contents/composer.json' => Http::response([ + 'content' => base64_encode($composerJson), + ]), + 'api.github.com/repos/acme/test-plugin/contents/nativephp.json' => Http::response([], 404), + 'raw.githubusercontent.com/*' => Http::response('', 404), + 'api.github.com/repos/acme/test-plugin/releases/latest' => Http::response([], 404), + 'api.github.com/repos/acme/test-plugin/tags*' => Http::response([]), + 'api.github.com/repos/acme/test-plugin/contents/LICENSE*' => Http::response([], 404), + ]); + + $plugin = Plugin::factory()->create([ + 'name' => 'acme/test-plugin', + 'repository_url' => 'https://github.com/acme/test-plugin', + 'mobile_min_version' => null, + ]); + + $service = new PluginSyncService; + $result = $service->sync($plugin); + + $this->assertTrue($result); + $this->assertEquals('^3.0.0', $plugin->fresh()->mobile_min_version); + } + + public function test_sync_sets_mobile_min_version_to_null_when_not_in_composer_data(): void + { + $composerJson = json_encode([ + 'name' => 'acme/test-plugin', + 'require' => [ + 'php' => '^8.2', + ], + ]); + + Http::fake([ + 'api.github.com/repos/acme/test-plugin/contents/composer.json' => Http::response([ + 'content' => base64_encode($composerJson), + ]), + 'api.github.com/repos/acme/test-plugin/contents/nativephp.json' => Http::response([], 404), + 'raw.githubusercontent.com/*' => Http::response('', 404), + 'api.github.com/repos/acme/test-plugin/releases/latest' => Http::response([], 404), + 'api.github.com/repos/acme/test-plugin/tags*' => Http::response([]), + 'api.github.com/repos/acme/test-plugin/contents/LICENSE*' => Http::response([], 404), + ]); + + $plugin = Plugin::factory()->create([ + 'name' => 'acme/test-plugin', + 'repository_url' => 'https://github.com/acme/test-plugin', + 'mobile_min_version' => '^2.0.0', + ]); + + $service = new PluginSyncService; + $result = $service->sync($plugin); + + $this->assertTrue($result); + $this->assertNull($plugin->fresh()->mobile_min_version); + } +}