Updated logo API

This commit is contained in:
2026-04-23 21:32:25 +10:00
parent 110ed5b984
commit 678096b463
22 changed files with 638 additions and 146 deletions
@@ -8,7 +8,7 @@ use App\Models\Airline;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class LogoController extends ApiController
class AirlineApiController extends ApiController
{
const array CONDOR_LOGOS = ['BEACH', 'ISLAND', 'PASSION', 'SEA', 'SUNSHINE'];
@@ -47,4 +47,30 @@ class LogoController extends ApiController
return $this->getAirlineLogo($airline);
}
function parseAirlineData(Airline $airline){
$countryCode = $airline->country->code;
$result = $airline->toArray();
unset($result['id']);
unset($result['logo']);
unset($result['country_id']);
unset($result['country']);
$result['slug'] = $result['internal_name'];
unset($result['internal_name']);
$result['country_code'] = $countryCode;
return $result;
}
function getByCode(string $code){
$lookupColumn = strlen($code) === 3 ? 'ICAO_code' : 'IATA_code';
$airlines = Airline::where($lookupColumn, strtoupper($code))->get()->map(fn($airline) => $this->parseAirlineData($airline));
return response()->json($airlines);
}
function get(string $internalName){
$airline = Airline::where('internal_name', $internalName)->first();
return response()->json($this->parseAirlineData($airline));
}
}
@@ -0,0 +1,60 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\ApiController;
use App\Models\User;
use App\Models\UserFlight;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
class UserApiController extends ApiController
{
public function nextFlight(string $username): JsonResponse
{
$user = User::where('name', 'ilike', $username)->first();
if (!$user) {
return response()->json(['message' => 'User not found'], 404);
}
$flight = UserFlight::with(['departureAirport', 'arrivalAirport', 'airline', 'aircraft'])
->where('user_id', $user->id)
->where('departure_date', '>', now()->utc())
->orderBy('departure_date', 'asc')
->first();
if (!$flight) {
return response()->json(['message' => 'No upcoming flights found'], 404);
}
$departure = Carbon::parse($flight->departure_date)->setTimezone($flight->departureAirport->timezone);
$arrival = Carbon::parse($flight->arrival_date)->setTimezone($flight->arrivalAirport->timezone);
return response()->json([
'departureAirportCode' => $flight->departureAirport->iata_code,
'departureCity' => $flight->departureAirport->municipality,
'departureDateReadable' => $departure->format('F j'),
'departureTime' => $departure->format('H:i'),
'arrivalAirportCode' => $flight->arrivalAirport->iata_code,
'arrivalCity' => $flight->arrivalAirport->municipality,
'arrivalDateReadable' => $arrival->format('F j'),
'arrivalTime' => $arrival->format('H:i'),
'flightNumber' => $flight->flight_number,
'airlineName' => $flight->airline->name,
'aircraftType' => $flight->aircraft->manufacturer_code . ' ' . $flight->aircraft->model_full_name,
'logoUrl' => $flight->airline?->logo_url ?? 'undefined',
]);
}
public function flights(string $username): JsonResponse
{
$user = User::where('name', 'ilike', $username)->first();
if (!$user) {
return response()->json(['message' => 'User not found'], 404);
}
return response()->json($user->FlightController()->flights());
}
}
@@ -1,50 +0,0 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\ApiController;
use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\UserFlight;
use Carbon\Carbon;
use DB;
use Illuminate\Http\Request;
class UserController extends ApiController
{
function nextFlight(string $username): ?array
{
$user = User::where('name' ,'ilike', $username)->first();
if(!$user) return [
'message' => 'User not found',
];
$flight = UserFlight::with(['departureAirport', 'arrivalAirport', 'airline', 'aircraft'])
->where('user_id', $user->id)
->where('departure_date', '>', now()->utc())
->orderBy('departure_date', 'asc')
->first();
$departure = Carbon::parse($flight->departure_date)->setTimezone($flight->departureAirport->timezone);
$arrival = Carbon::parse($flight->arrival_date)->setTimezone($flight->arrivalAirport->timezone);
return [
'departureAirportCode' => $flight->departureAirport->iata_code,
'departureCity' => $flight->departureAirport->municipality,
'departureDateReadable' => $departure->format('F j'),
'departureTime' => $departure->format('H:i'),
'arrivalAirportCode' => $flight->arrivalAirport->iata_code,
'arrivalCity' => $flight->arrivalAirport->municipality,
'arrivalDateReadable' => $arrival->format('F j'),
'arrivalTime' => $arrival->format('H:i'),
'flightNumber' => $flight->flight_number,
'airlineName' => $flight->airline->name,
'aircraftType' => $flight->aircraft->manufacturer_code . ' ' . $flight->aircraft->model_full_name,
'logoUrl' => $flight->airline->logo_url,
];
}
function flights(string $username){
}
}
+70 -2
View File
@@ -2,12 +2,14 @@
namespace App\Http\Controllers;
use App\Models\Aircraft;
use App\Models\Airline;
use App\Models\Airport;
use App\Models\CrewType;
use App\Models\FlightClass;
use App\Models\FlightReason;
use App\Models\SeatType;
use App\Models\UserAction;
use App\Models\UserFlight;
use Carbon\Carbon;
use Illuminate\Http\Request;
@@ -72,6 +74,70 @@ class FlightController extends Controller
];
}
private function recordChanges(UserFlight $flight): void
{
$dirty = $flight->getDirty();
if (empty($dirty)) {
return;
}
$actions = [];
foreach ($dirty as $field => $newValue) {
$original = $flight->getOriginal($field);
$actions[] = [
'user_id' => $flight->user_id,
'user_flight_id' => $flight->id,
'message' => $this->formatChange($field, $original, $newValue),
'created_at' => now(),
'updated_at' => now(),
];
}
UserAction::insert($actions);
}
private array $labelCache = [];
private function resolveLabel(string $field, mixed $value): string
{
if (is_null($value)) {
return 'none';
}
$cacheKey = "{$field}:{$value}";
if (isset($this->labelCache[$cacheKey])) {
return $this->labelCache[$cacheKey];
}
$label = match($field) {
'airline_id' => Airline::find($value)?->display_name ?? $value,
'departure_airport_id',
'arrival_airport_id' => Airport::find($value)?->display_name ?? $value,
'aircraft_id' => Aircraft::find($value)?->display_name_short ?? $value,
'seat_type_id' => SeatType::find($value)?->name ?? $value,
'flight_class_id' => FlightClass::find($value)?->name ?? $value,
'flight_reason_id' => FlightReason::find($value)?->name ?? $value,
'crew_type_id' => CrewType::find($value)?->name ?? $value,
'departure_date',
'arrival_date' => Carbon::parse($value)->format('j F Y \a\t H:iA'),
default => (string) $value,
};
return $this->labelCache[$cacheKey] = $label;
}
private function formatChange(string $field, mixed $from, mixed $to): string
{
$label = str($field)->replace('_id', '')->replace('_', ' ')->title();
$fromLabel = $this->resolveLabel($field, $from);
$toLabel = $this->resolveLabel($field, $to);
return "{$label} changed from {$fromLabel} to {$toLabel}";
}
private function flightPayload(array $validated): array
{
[$departureUtc, $arrivalUtc] = $this->convertedDates($validated);
@@ -111,7 +177,9 @@ class FlightController extends Controller
$validated = $request->validate($this->rules());
$flight->update($this->flightPayload($validated));
$flight->fill($this->flightPayload($validated));
$this->recordChanges($flight);
$flight->save();
return redirect()->route('profile.departure-board', [Auth::user()->name, $flight->id]);
}
@@ -147,7 +215,7 @@ class FlightController extends Controller
'crew_type' => $flight->crewType?->toArray() ?? [],
'flight_reason' => $flight->flightReason->toArray(),
'airline_options' => $flight->airline
? [['value' => $flight->airline->id, 'title' => $flight->airline->display_name]]
? [['value' => $flight->airline->id, 'title' => $flight->airline->display_name, 'logo_url' => $flight->airline->logo_url]]
: [],
'from_options' => [['value' => $flight->departureAirport->id, 'title' => $flight->departureAirport->display_name, 'country_code' => strtolower($flight->departureAirport->region->country->code)]],
'to_options' => [['value' => $flight->arrivalAirport->id, 'title' => $flight->arrivalAirport->display_name, 'country_code' => strtolower($flight->arrivalAirport->region->country->code)]],
@@ -10,51 +10,35 @@ use Inertia\Inertia;
class FlightProfileController extends Controller
{
public function profileData(string $username, string $view, ?int $selectedFlightId = null) : array {
$user = User::whereRaw(DB::raw('LOWER(name) = ?'), [strtolower($username)])->firstOrFail();
$flights = UserFlight::where('user_id', $user->id)
->with([
'departureAirport.region.country',
'departureAirport.region.continent',
'arrivalAirport.region.country',
'arrivalAirport.region.continent',
'airline.country',
'aircraft',
'seatType',
'flightReason',
'flightClass',
'crewType'
])
->orderBy('departure_date', 'desc')
->get();
public function profileData(User $user, string $view, ?int $selectedFlightId = null) : array {
$flights = $user->FlightController()->flights();
return [
'user' => $user,
'canEdit' => auth()->check() && auth()->id() === $user->id,
'flights' => UserFlightResource::collection($flights)->resolve(),
'initialView' => $view,
'selectedFlightId' => $selectedFlightId,
'isFollowing' => auth()->check() && auth()->user()->isFollowing($user),
];
}
public function departureBoard(string $username, ?UserFlight $flight = null){
$profileData = $this->profileData($username, 'board', $flight?->id);
public function departureBoard(User $user, ?UserFlight $flight = null){
$profileData = $this->profileData($user, 'board', $flight?->id);
return Inertia::render('UserProfile', $profileData);
}
public function map(string $username){
$profileData = $this->profileData($username, 'map');
public function map(User $user){
$profileData = $this->profileData($user, 'map');
return Inertia::render('UserProfile', $profileData);
}
public function boardingPasses(string $username){
$profileData = $this->profileData($username, 'passes');
public function boardingPasses(User $user){
$profileData = $this->profileData($user, 'passes');
return Inertia::render('UserProfile', $profileData);
}
public function view(string $username)
public function view(User $user)
{
return $this->departureBoard($username);
return $this->departureBoard($user);
}
}
+31
View File
@@ -0,0 +1,31 @@
<?php
namespace App\Http\Controllers;
use App\Models\Followee;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function follow(User $user): JsonResponse
{
$existing = Followee::where('user_id', auth()->id())
->where('followee_id', $user->id)
->first();
if ($existing) {
$existing->delete();
return response()->json(['following' => false]);
}
Followee::create([
'user_id' => auth()->id(),
'followee_id' => $user->id,
]);
return response()->json(['following' => true]);
}
}
@@ -0,0 +1,35 @@
<?php
namespace App\Http\Controllers;
use App\Models\User;
use App\Models\UserFlight;
use Illuminate\Http\Request;
class UserFlightController extends Controller
{
protected User $user;
function __construct(User $user){
$this->user = $user;
}
public function flights(){
return UserFlight::where('user_id', $this->user->id)
->with([
'departureAirport.region.country',
'departureAirport.region.continent',
'arrivalAirport.region.country',
'arrivalAirport.region.continent',
'airline.country',
'aircraft',
'seatType',
'flightReason',
'flightClass',
'crewType'
])
->orderBy('departure_date', 'desc')
->get();
}
}