diff --git a/app/Http/Controllers/FeedsController.php b/app/Http/Controllers/FeedsController.php new file mode 100644 index 0000000..88599d4 --- /dev/null +++ b/app/Http/Controllers/FeedsController.php @@ -0,0 +1,83 @@ +orderBy('name') + ->get(); + + return view('pages.feeds.index', compact('feeds')); + } + + public function create(): View + { + return view('pages.feeds.create'); + } + + public function store(Request $request): RedirectResponse + { + $validated = $request->validate([ + 'name' => 'required|string|max:255', + 'url' => 'required|url|unique:feeds,url', + 'type' => 'required|in:website,rss', + 'language' => 'required|string|size:2', + 'description' => 'nullable|string', + 'is_active' => 'boolean' + ]); + + // Default is_active to true if not provided + $validated['is_active'] = $validated['is_active'] ?? true; + + Feed::create($validated); + + return redirect()->route('feeds.index') + ->with('success', 'Feed created successfully!'); + } + + public function show(Feed $feed): View + { + return view('pages.feeds.show', compact('feed')); + } + + public function edit(Feed $feed): View + { + return view('pages.feeds.edit', compact('feed')); + } + + public function update(Request $request, Feed $feed): RedirectResponse + { + $validated = $request->validate([ + 'name' => 'required|string|max:255', + 'url' => 'required|url|unique:feeds,url,' . $feed->id, + 'type' => 'required|in:website,rss', + 'language' => 'required|string|size:2', + 'description' => 'nullable|string', + 'is_active' => 'boolean' + ]); + + // Default is_active to current value if not provided + $validated['is_active'] = $validated['is_active'] ?? $feed->is_active; + + $feed->update($validated); + + return redirect()->route('feeds.index') + ->with('success', 'Feed updated successfully!'); + } + + public function destroy(Feed $feed): RedirectResponse + { + $feed->delete(); + + return redirect()->route('feeds.index') + ->with('success', 'Feed deleted successfully!'); + } +} \ No newline at end of file diff --git a/app/Models/Feed.php b/app/Models/Feed.php new file mode 100644 index 0000000..afa55be --- /dev/null +++ b/app/Models/Feed.php @@ -0,0 +1,71 @@ + 'array', + 'is_active' => 'boolean', + 'last_fetched_at' => 'datetime' + ]; + + public function getTypeDisplayAttribute(): string + { + return match ($this->type) { + 'website' => 'Website', + 'rss' => 'RSS Feed', + default => 'Unknown' + }; + } + + public function getStatusAttribute(): string + { + if (!$this->is_active) { + return 'Inactive'; + } + + if (!$this->last_fetched_at) { + return 'Never fetched'; + } + + $hoursAgo = $this->last_fetched_at->diffInHours(now()); + + if ($hoursAgo < 2) { + return 'Recently fetched'; + } elseif ($hoursAgo < 24) { + return "Fetched {$hoursAgo}h ago"; + } else { + return "Fetched " . $this->last_fetched_at->diffForHumans(); + } + } +} diff --git a/database/migrations/2025_07_05_003216_create_feeds_table.php b/database/migrations/2025_07_05_003216_create_feeds_table.php new file mode 100644 index 0000000..4131468 --- /dev/null +++ b/database/migrations/2025_07_05_003216_create_feeds_table.php @@ -0,0 +1,31 @@ +id(); + $table->string('name'); // "VRT News", "Belga News Agency" + $table->string('url'); // "https://vrt.be" or "https://feeds.example.com/rss.xml" + $table->enum('type', ['website', 'rss']); // Feed type + $table->string('language', 5)->default('en'); // Language code (en, nl, etc.) + $table->text('description')->nullable(); + $table->json('settings')->nullable(); // Custom settings per feed type + $table->boolean('is_active')->default(true); + $table->timestamp('last_fetched_at')->nullable(); + $table->timestamps(); + + $table->unique('url'); + }); + } + + public function down(): void + { + Schema::dropIfExists('feeds'); + } +}; \ No newline at end of file diff --git a/resources/views/pages/feeds/create.blade.php b/resources/views/pages/feeds/create.blade.php new file mode 100644 index 0000000..08af8a4 --- /dev/null +++ b/resources/views/pages/feeds/create.blade.php @@ -0,0 +1,109 @@ +@extends('layouts.app') + +@section('content') +
Create a new content feed for articles.
+Update the details for {{ $feed->name }}.
+{{ $feed->type_display }} • {{ strtoupper($feed->language) }}
+Information about this content feed.
+