diff --git a/app/Http/Controllers/FeedsController.php b/app/Http/Controllers/FeedsController.php index 88599d4..c23040d 100644 --- a/app/Http/Controllers/FeedsController.php +++ b/app/Http/Controllers/FeedsController.php @@ -29,7 +29,7 @@ public function store(Request $request): RedirectResponse 'name' => 'required|string|max:255', 'url' => 'required|url|unique:feeds,url', 'type' => 'required|in:website,rss', - 'language' => 'required|string|size:2', + 'language_id' => 'required|exists:languages,id', 'description' => 'nullable|string', 'is_active' => 'boolean' ]); @@ -39,6 +39,13 @@ public function store(Request $request): RedirectResponse Feed::create($validated); + // Check if there's a redirect_to parameter for onboarding flow + $redirectTo = $request->input('redirect_to'); + if ($redirectTo) { + return redirect($redirectTo) + ->with('success', 'Feed created successfully!'); + } + return redirect()->route('feeds.index') ->with('success', 'Feed created successfully!'); } @@ -59,7 +66,7 @@ public function update(Request $request, Feed $feed): RedirectResponse 'name' => 'required|string|max:255', 'url' => 'required|url|unique:feeds,url,' . $feed->id, 'type' => 'required|in:website,rss', - 'language' => 'required|string|size:2', + 'language_id' => 'required|exists:languages,id', 'description' => 'nullable|string', 'is_active' => 'boolean' ]); diff --git a/app/Http/Controllers/OnboardingController.php b/app/Http/Controllers/OnboardingController.php new file mode 100644 index 0000000..3c37e59 --- /dev/null +++ b/app/Http/Controllers/OnboardingController.php @@ -0,0 +1,96 @@ +needsOnboarding()) { + return redirect()->route('feeds.index'); + } + + return view('onboarding.welcome'); + } + + public function platform(): View|RedirectResponse + { + if (!$this->needsOnboarding()) { + return redirect()->route('feeds.index'); + } + + return view('onboarding.platform'); + } + + public function feed(): View|RedirectResponse + { + if (!$this->needsOnboarding()) { + return redirect()->route('feeds.index'); + } + + if (!$this->hasPlatformAccount()) { + return redirect()->route('onboarding.platform'); + } + + return view('onboarding.feed'); + } + + public function channel(): View|RedirectResponse + { + if (!$this->needsOnboarding()) { + return redirect()->route('feeds.index'); + } + + if (!$this->hasPlatformAccount()) { + return redirect()->route('onboarding.platform'); + } + + if (!$this->hasFeed()) { + return redirect()->route('onboarding.feed'); + } + + return view('onboarding.channel'); + } + + public function complete(): View|RedirectResponse + { + if (!$this->needsOnboarding()) { + return redirect()->route('feeds.index'); + } + + if (!$this->hasPlatformAccount() || !$this->hasFeed() || !$this->hasChannel()) { + return redirect()->route('onboarding.index'); + } + + return view('onboarding.complete'); + } + + private function needsOnboarding(): bool + { + return !$this->hasPlatformAccount() || !$this->hasFeed() || !$this->hasChannel(); + } + + private function hasPlatformAccount(): bool + { + return PlatformAccount::where('is_active', true)->exists(); + } + + private function hasFeed(): bool + { + return Feed::where('is_active', true)->exists(); + } + + private function hasChannel(): bool + { + return PlatformChannel::where('is_active', true)->exists(); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/PlatformAccountsController.php b/app/Http/Controllers/PlatformAccountsController.php index 029f6fa..2d3870c 100644 --- a/app/Http/Controllers/PlatformAccountsController.php +++ b/app/Http/Controllers/PlatformAccountsController.php @@ -3,6 +3,8 @@ namespace App\Http\Controllers; use App\Models\PlatformAccount; +use App\Models\PlatformInstance; +use App\Enums\PlatformEnum; use Illuminate\Http\Request; use Illuminate\Contracts\View\View; use Illuminate\Http\RedirectResponse; @@ -31,6 +33,17 @@ public function store(Request $request): RedirectResponse 'settings' => 'nullable|array', ]); + // Create or find platform instance + $platformEnum = PlatformEnum::from($validated['platform']); + $instance = PlatformInstance::firstOrCreate([ + 'platform' => $platformEnum, + 'url' => $validated['instance_url'], + ], [ + 'name' => parse_url($validated['instance_url'], PHP_URL_HOST), + 'description' => ucfirst($validated['platform']) . ' instance', + 'is_active' => true, + ]); + $account = PlatformAccount::create($validated); // If this is the first account for this platform, make it active @@ -38,6 +51,13 @@ public function store(Request $request): RedirectResponse $account->setAsActive(); } + // Check if there's a redirect_to parameter for onboarding flow + $redirectTo = $request->input('redirect_to'); + if ($redirectTo) { + return redirect($redirectTo) + ->with('success', 'Platform account created successfully!'); + } + return redirect()->route('platforms.index') ->with('success', 'Platform account created successfully!'); } diff --git a/app/Http/Controllers/PlatformChannelsController.php b/app/Http/Controllers/PlatformChannelsController.php index 6816d21..7658421 100644 --- a/app/Http/Controllers/PlatformChannelsController.php +++ b/app/Http/Controllers/PlatformChannelsController.php @@ -34,13 +34,28 @@ public function store(Request $request): RedirectResponse $validated = $request->validate([ 'platform_instance_id' => 'required|exists:platform_instances,id', 'name' => 'required|string|max:255', - 'display_name' => 'required|string|max:255', - 'channel_id' => 'required|string|max:255', + 'display_name' => 'nullable|string|max:255', + 'channel_id' => 'nullable|string|max:255', 'description' => 'nullable|string', + 'language_id' => 'required|exists:languages,id', + 'is_active' => 'boolean', ]); + // Default is_active to true if not provided + $validated['is_active'] = $validated['is_active'] ?? true; + + // Set display_name to name if not provided + $validated['display_name'] = $validated['display_name'] ?? $validated['name']; + PlatformChannel::create($validated); + // Check if there's a redirect_to parameter for onboarding flow + $redirectTo = $request->input('redirect_to'); + if ($redirectTo) { + return redirect($redirectTo) + ->with('success', 'Channel created successfully!'); + } + return redirect()->route('channels.index') ->with('success', 'Channel created successfully!'); } diff --git a/resources/views/onboarding/channel.blade.php b/resources/views/onboarding/channel.blade.php new file mode 100644 index 0000000..5367e37 --- /dev/null +++ b/resources/views/onboarding/channel.blade.php @@ -0,0 +1,110 @@ +@extends('layouts.app') + +@section('content') +
+
+
+

Configure Your Channel

+

+ Set up a Lemmy community where articles will be posted +

+ + +
+
+
+
3
+
4
+
+
+ +
+ @csrf + +
+ + +

Enter the community name (without the @ or instance)

+ @error('name') +

{{ $message }}

+ @enderror +
+ +
+ + + @error('platform_instance_id') +

{{ $message }}

+ @enderror +
+ +
+ + + @error('language_id') +

{{ $message }}

+ @enderror +
+ +
+ + + @error('description') +

{{ $message }}

+ @enderror +
+ + + + +
+ + ← Back + + +
+
+
+
+@endsection \ No newline at end of file diff --git a/resources/views/onboarding/complete.blade.php b/resources/views/onboarding/complete.blade.php new file mode 100644 index 0000000..ed6c368 --- /dev/null +++ b/resources/views/onboarding/complete.blade.php @@ -0,0 +1,64 @@ +@extends('layouts.app') + +@section('content') +
+
+
+
+
+ + + +
+

Setup Complete!

+

+ Great! You've successfully configured Lemmy Poster. Your feeds will now be monitored and articles will be automatically posted to your configured channels. +

+
+ + +
+
+
+
+
+
+ +
+
+

What happens next?

+
    +
  • • Your feeds will be checked regularly for new articles
  • +
  • • New articles will be automatically posted to your channels
  • +
  • • You can monitor activity in the Articles and Logs sections
  • +
+
+ +
+

Want more control?

+

+ Set up routing rules to control which articles get posted where based on keywords, titles, or content. +

+ + Configure Routing → + +
+
+ + +
+
+
+@endsection \ No newline at end of file diff --git a/resources/views/onboarding/feed.blade.php b/resources/views/onboarding/feed.blade.php new file mode 100644 index 0000000..46f0ef8 --- /dev/null +++ b/resources/views/onboarding/feed.blade.php @@ -0,0 +1,123 @@ +@extends('layouts.app') + +@section('content') +
+
+
+

Add Your First Feed

+

+ Add a RSS feed or website to monitor for new articles +

+ + +
+
+
2
+
3
+
4
+
+
+ +
+ @csrf + +
+ + + @error('name') +

{{ $message }}

+ @enderror +
+ +
+ + + @error('url') +

{{ $message }}

+ @enderror +
+ +
+ + + @error('type') +

{{ $message }}

+ @enderror +
+ +
+ + + @error('language_id') +

{{ $message }}

+ @enderror +
+ +
+ + + @error('description') +

{{ $message }}

+ @enderror +
+ + + + +
+ + ← Back + + +
+
+
+
+@endsection \ No newline at end of file diff --git a/resources/views/onboarding/platform.blade.php b/resources/views/onboarding/platform.blade.php new file mode 100644 index 0000000..6c1424e --- /dev/null +++ b/resources/views/onboarding/platform.blade.php @@ -0,0 +1,86 @@ +@extends('layouts.app') + +@section('content') +
+
+
+

Connect Your Lemmy Account

+

+ Enter your Lemmy instance details and login credentials +

+ + +
+
1
+
2
+
3
+
4
+
+
+ +
+ @csrf + +
+ + + @error('instance_url') +

{{ $message }}

+ @enderror +
+ +
+ + + @error('username') +

{{ $message }}

+ @enderror +
+ +
+ + + @error('password') +

{{ $message }}

+ @enderror +
+ + + + + +
+ + ← Back + + +
+
+
+
+@endsection \ No newline at end of file diff --git a/resources/views/onboarding/welcome.blade.php b/resources/views/onboarding/welcome.blade.php new file mode 100644 index 0000000..44d345f --- /dev/null +++ b/resources/views/onboarding/welcome.blade.php @@ -0,0 +1,40 @@ +@extends('layouts.app') + +@section('content') +
+
+
+

Welcome to Lemmy Poster

+

+ Let's get you set up! We'll help you configure your Lemmy account, add your first feed, and create a channel for posting. +

+ +
+
+
1
+ Connect your Lemmy account +
+
+
2
+ Add your first feed +
+
+
3
+ Configure a channel +
+
+
4
+ You're ready to go! +
+
+ + +
+
+
+@endsection \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 4221fd6..9da2ade 100644 --- a/routes/web.php +++ b/routes/web.php @@ -2,8 +2,16 @@ use App\Http\Controllers\ArticlesController; use App\Http\Controllers\LogsController; +use App\Http\Controllers\OnboardingController; use Illuminate\Support\Facades\Route; +// Onboarding routes +Route::get('/', [OnboardingController::class, 'index'])->name('onboarding.index'); +Route::get('/onboarding/platform', [OnboardingController::class, 'platform'])->name('onboarding.platform'); +Route::get('/onboarding/feed', [OnboardingController::class, 'feed'])->name('onboarding.feed'); +Route::get('/onboarding/channel', [OnboardingController::class, 'channel'])->name('onboarding.channel'); +Route::get('/onboarding/complete', [OnboardingController::class, 'complete'])->name('onboarding.complete'); + Route::get('/articles', ArticlesController::class)->name('articles'); Route::get('/logs', LogsController::class)->name('logs');