diff --git a/app/Http/Controllers/ProductController.php b/app/Http/Controllers/ProductController.php index 4c4a52e5..4ee4d34e 100644 --- a/app/Http/Controllers/ProductController.php +++ b/app/Http/Controllers/ProductController.php @@ -3,15 +3,20 @@ namespace App\Http\Controllers; use App\Models\Product; +use Illuminate\Http\RedirectResponse; use Illuminate\Support\Facades\Auth; use Illuminate\View\View; class ProductController extends Controller { - public function show(Product $product): View + public function show(Product $product): View|RedirectResponse { abort_unless($product->isActive(), 404); + if ($product->slug === 'nativephp-masterclass') { + return redirect()->route('course'); + } + $user = Auth::user(); if (! $product->hasAccessiblePriceFor($user)) { diff --git a/resources/views/course.blade.php b/resources/views/course.blade.php index 6d8c1d8e..6c69d5c0 100644 --- a/resources/views/course.blade.php +++ b/resources/views/course.blade.php @@ -112,30 +112,39 @@ class="mx-auto mt-6 max-w-2xl text-lg text-gray-600 dark:text-gray-400" " class="mt-8 flex flex-col items-center gap-4 sm:flex-row" > - - Get Early Bird Access — $101 - + + + + You Own This Course + + @else + - - - - - or join the waitlist - + Get Early Bird Access — $101 + + + + + + or join the waitlist + + @endif @@ -573,14 +582,28 @@ class="mx-auto mt-10 max-w-lg" The NativePHP Masterclass -
- - $101 - - - one-time payment - -
+ @if ($alreadyOwned) +
+
+ + + +
+

You Own This Course

+

+ You'll be notified when the course launches. +

+
+ @else +
+ + $101 + + + one-time payment + +
+ @endif -
- @csrf - -
+ Get Early Bird Access + + + + + -

- Early bird pricing won't last forever. Lock in the lowest price today. -

+

+ Early bird pricing won't last forever. Lock in the lowest price today. +

+ @endunless @@ -755,7 +780,7 @@ class="rounded-xl bg-gray-900 px-6 py-3 text-sm font-semibold text-white transit @auth - @if (request('checkout')) + @if (request('checkout') && ! $alreadyOwned) diff --git a/routes/web.php b/routes/web.php index 952e3726..93566425 100644 --- a/routes/web.php +++ b/routes/web.php @@ -64,7 +64,15 @@ Route::view('/', 'welcome')->name('welcome'); Route::redirect('pricing', 'blog/nativephp-for-mobile-is-now-free')->name('pricing'); Route::view('alt-pricing', 'alt-pricing')->name('alt-pricing')->middleware('signed'); -Route::view('course', 'course')->name('course'); +Route::get('course', function () { + $user = auth()->user(); + $product = \App\Models\Product::where('slug', 'nativephp-masterclass')->first(); + $alreadyOwned = $user && $product && $product->isOwnedBy($user); + + return view('course', [ + 'alreadyOwned' => $alreadyOwned, + ]); +})->name('course'); Route::post('course/checkout', function (\Illuminate\Http\Request $request) { $user = $request->user(); diff --git a/tests/Feature/ProductPageTest.php b/tests/Feature/ProductPageTest.php new file mode 100644 index 00000000..090dfbcd --- /dev/null +++ b/tests/Feature/ProductPageTest.php @@ -0,0 +1,87 @@ +first(); + + $this + ->get(route('products.show', $product)) + ->assertRedirect(route('course')); + } + + #[Test] + public function non_masterclass_product_page_loads_normally(): void + { + $product = Product::factory()->active()->create([ + 'slug' => 'plugin-dev-kit', + ]); + + ProductPrice::factory()->for($product)->create(); + + $this + ->withoutVite() + ->get(route('products.show', $product)) + ->assertStatus(200) + ->assertSee($product->name); + } + + #[Test] + public function course_page_shows_purchase_form_for_guests(): void + { + $this + ->withoutVite() + ->get(route('course')) + ->assertStatus(200) + ->assertSee('Get Early Bird Access') + ->assertDontSee('You Own This Course'); + } + + #[Test] + public function course_page_shows_purchase_form_for_users_without_purchase(): void + { + $user = User::factory()->create(); + + $this + ->withoutVite() + ->actingAs($user) + ->get(route('course')) + ->assertStatus(200) + ->assertSee('Get Early Bird Access') + ->assertDontSee('You Own This Course'); + } + + #[Test] + public function course_page_shows_owned_state_for_purchasers(): void + { + $user = User::factory()->create(); + $product = Product::where('slug', 'nativephp-masterclass')->first(); + + ProductLicense::factory()->create([ + 'user_id' => $user->id, + 'product_id' => $product->id, + ]); + + $this + ->withoutVite() + ->actingAs($user) + ->get(route('course')) + ->assertStatus(200) + ->assertSee('You Own This Course') + ->assertDontSee('Get Early Bird Access'); + } +}