diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php
index 000dcfb..9274b2c 100644
--- a/app/Http/Controllers/AdminController.php
+++ b/app/Http/Controllers/AdminController.php
@@ -7,6 +7,7 @@ use App\Models\IgnoredMissingLivery;
use App\Models\User;
use App\Models\UserFlight;
use App\Services\AdminService;
+use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Inertia\Inertia;
@@ -66,4 +67,17 @@ class AdminController extends Controller
return back();
}
+ public function ignoreMissingAirline(Request $request): JsonResponse
+ {
+ $validated = $request->validate([
+ 'flight_id' => ['required', 'integer', 'exists:user_flights,id'],
+ ]);
+
+ $flight = UserFlight::findOrFail($validated['flight_id']);
+
+ $flight->ignoreMissingAirline()->firstOrCreate([]);
+
+ return response()->json(['status' => 'ok']);
+ }
+
}
diff --git a/app/Models/UserFlight.php b/app/Models/UserFlight.php
index 0f4a584..4ecc3b2 100644
--- a/app/Models/UserFlight.php
+++ b/app/Models/UserFlight.php
@@ -9,6 +9,7 @@ use Illuminate\Database\Eloquent\Casts\Attribute;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;
@@ -271,6 +272,16 @@ class UserFlight extends Model
}
+ public function ignoreMissingAirline(): HasOne
+ {
+ return $this->hasOne(UserFlightIgnoreMissingAirline::class);
+ }
+
+ public function isIgnoringMissingAirline(): bool
+ {
+ return $this->ignoreMissingAirline()->exists();
+ }
+
public function aircraft(): BelongsTo
{
return $this->belongsTo(Aircraft::class);
diff --git a/app/Models/UserFlightIgnoreMissingAirline.php b/app/Models/UserFlightIgnoreMissingAirline.php
new file mode 100644
index 0000000..aed3b9e
--- /dev/null
+++ b/app/Models/UserFlightIgnoreMissingAirline.php
@@ -0,0 +1,20 @@
+belongsTo(UserFlight::class);
+ }
+}
diff --git a/app/Services/AdminService.php b/app/Services/AdminService.php
index 2b70761..6b16969 100644
--- a/app/Services/AdminService.php
+++ b/app/Services/AdminService.php
@@ -51,26 +51,28 @@ class AdminService
{
$flights = UserFlight::whereNotNull('flight_number')
->whereNull('airline_id')
- ->with('user:id,name') // adjust to your actual user relation/columns
+ ->whereDoesntHave('ignoreMissingAirline')
+ ->with('user:id,name')
->get(['id', 'flight_number', 'user_id']);
return $flights
->map(function ($flight) {
- // Extract the 2-character IATA-style prefix (letters and/or digits)
preg_match('/^([A-Za-z0-9]{2})\d+/', trim($flight->flight_number), $matches);
return [
+ 'id' => $flight->id,
'code' => $matches[1] ?? null,
'flight_number' => $flight->flight_number,
'link' => "/u/{$flight->user->name}/flight/{$flight->id}",
];
})
- ->filter(fn ($f) => $f['code'] !== null) // drop any that didn't match the pattern
+ ->filter(fn ($f) => $f['code'] !== null)
->groupBy('code')
->map(function ($group, $code) {
return [
'code' => $code,
'flights' => $group->map(fn ($f) => [
+ 'id' => $f['id'],
'flight_number' => $f['flight_number'],
'link' => $f['link'],
])->values()->all(),
diff --git a/database/migrations/2026_08_21_122451_add_ignore_user_flight_airlines.php b/database/migrations/2026_08_21_122451_add_ignore_user_flight_airlines.php
new file mode 100644
index 0000000..69619dd
--- /dev/null
+++ b/database/migrations/2026_08_21_122451_add_ignore_user_flight_airlines.php
@@ -0,0 +1,26 @@
+id();
+ $table->foreignId('user_flight_id')
+ ->constrained('user_flights')
+ ->cascadeOnDelete();
+ $table->timestamps();
+
+ $table->unique('user_flight_id');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::dropIfExists('user_flights_ignore_missing_airlines');
+ }
+};
diff --git a/resources/js/Components/Admin/MissingAirlineCard.vue b/resources/js/Components/Admin/MissingAirlineCard.vue
index bff6252..ccadde2 100644
--- a/resources/js/Components/Admin/MissingAirlineCard.vue
+++ b/resources/js/Components/Admin/MissingAirlineCard.vue
@@ -1,25 +1,63 @@
@@ -62,30 +100,23 @@ defineProps<{
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
- list-style: none;
- padding: 0;
- margin: 0;
}
-.flight-item {
- display: flex;
-}
-
-.flight-link {
+.flight-chip {
font-family: 'Share Tech Mono', monospace;
font-size: 0.72rem;
letter-spacing: 0.06em;
+ background: rgba(255, 255, 255, 0.04) !important;
+ border: 1px solid rgba(255, 255, 255, 0.06);
+}
+
+.flight-link {
color: #9fb3c8;
text-decoration: none;
- background: rgba(255, 255, 255, 0.04);
- border: 1px solid rgba(255, 255, 255, 0.06);
- border-radius: 4px;
- padding: 0.25rem 0.5rem;
- transition: color 0.15s ease, border-color 0.15s ease;
+ transition: color 0.15s ease;
}
.flight-link:hover {
color: #ffc107;
- border-color: rgba(255, 193, 7, 0.4);
}
diff --git a/resources/js/Pages/Admin/AdminSidebar.vue b/resources/js/Pages/Admin/AdminSidebar.vue
index f07bc10..15f5d36 100644
--- a/resources/js/Pages/Admin/AdminSidebar.vue
+++ b/resources/js/Pages/Admin/AdminSidebar.vue
@@ -19,7 +19,7 @@ defineProps<{
Reconcile Missing Liveries
{{ missingLiveryCount }}
-
+
Reconcile Missing Airlines
{{ missingAirlineCount }}
diff --git a/resources/js/Types/types.d.ts b/resources/js/Types/types.d.ts
index f9b7dcb..26ea0d3 100644
--- a/resources/js/Types/types.d.ts
+++ b/resources/js/Types/types.d.ts
@@ -334,6 +334,7 @@ export interface MissingAirline{
flights: {
flight_number: string;
link: string;
+ id: number;
}[]
}
diff --git a/routes/web.php b/routes/web.php
index 359725b..f4ef151 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -42,6 +42,8 @@ use Inertia\Inertia;
Route::post('/ignore-missing-livery', [AdminController::class, 'ignoreMissingLivery'])->name('ignore-missing-livery');
Route::get('/missing-airlines', [AdminController::class, 'reconcileMissingAirlines'])->name('reconcile-missing-airlines')->middleware('permission:reconcile_missing_liveries');
+ Route::post('/ignore-missing-airline', [AdminController::class, 'ignoreMissingAirline'])->name('admin.ignore-missing-airline');
+
});