Files
FlightsAPI/app/Http/Controllers/UserProfileController.php
T
2026-06-20 22:21:17 +10:00

195 lines
7.6 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\Achievement;
use App\Models\Aircraft;
use App\Models\Alliance;
use App\Models\Continent;
use App\Models\Country;
use App\Models\User;
use App\Models\UserFlight;
use App\Http\Resources\UserFlightResource;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Gate;
use Inertia\Inertia;
class UserProfileController extends Controller
{
public function index(){
if (auth()->check()) {
$user = auth()->user();
$defaultPage = $user->resolved_settings['default_login_page'];
$route = match ($defaultPage) {
'feed_first' => $user->following()->count() > 0 ? 'feed' : 'profile.view',
'feed' => 'feed',
'profile' => 'profile.view',
'dashboard' => 'dashboard',
};
$args = $route == 'profile.view' ? $user->name : null;
return redirect()->route($route, $args);
}
return redirect()->route('login');
}
public static function getUserFlightApiURL(User $user){
return '/data/user/'.$user->name.'/flights';
}
public function profileData(User $user, string $view, ?int $selectedFlightId = null) : array {
return [
'user' => $user,
'canView' => Gate::allows('viewProfileData', $user),
'canEdit' => auth()->check() && (auth()->id() === $user->id || auth()->user()->hasRole('admin')),
'initialView' => $view,
'selectedFlightId' => $selectedFlightId,
'flight_api_url' => self::getUserFlightApiURL($user),
'followStatus' => auth()->check() ? auth()->user()->followStatus($user) : 'none',
'flightCount' => $user->departedFlights()->count(),
];
}
public function departureBoard(User $user, ?UserFlight $flight = null){
$profileData = $this->profileData($user, 'board', $flight?->id);
return Inertia::render('UserProfile', $profileData);
}
public function map(User $user){
$profileData = $this->profileData($user, 'map');
return Inertia::render('UserProfile', $profileData);
}
public function boardingPasses(User $user){
$profileData = $this->profileData($user, 'passes');
return Inertia::render('UserProfile', $profileData);
}
public function view(User $user, ?string $page = null)
{
$loggedInUser = auth()->user();
$defaultView = $page ?: ($loggedInUser ? $loggedInUser->resolved_settings['default_profile_view'] : 'map');
return match($defaultView) {
'boarding-passes' => $this->boardingPasses($user),
'map' => $this->map($user),
'departure-board' => $this->departureBoard($user),
'achievements' => redirect()->route('profile.achievements', $user->name),
};
}
public function flight(User $user, UserFlight $userFlight)
{
if($userFlight->user_id !== $user->id){
abort(404);
}
return Inertia::render('UserFlight', [
'flightCount' => $user->departedFlights()->count(),
'flight' => $userFlight->snapshot($userFlight->id),
'canEdit' => auth()->check() && auth()->id() === $user->id,
'canView' => Gate::allows('viewProfileData', $user),
'user' => $user,
'followStatus' => auth()->check() ? auth()->user()->followStatus($user) : 'none',
]);
}
public function achievements(User $user)
{
$canView = Gate::allows('viewProfileData', $user);
$achievements = Achievement::with(['category', 'difficulty'])
->get()
->groupBy(fn(Achievement $a) => $a->category->name)
->map(fn($group) => $group->sortBy('sort_order')->values());
$userAchievements = $user->achievements()
->with('achievement')
->select(['achievement_id', 'progress'])
->orderBy('achievement_id')
->get()
->keyBy('achievement_id');
$unlockedByCategory = $achievements->map(fn($group) =>
$group->filter(fn($a) => $userAchievements->get($a->id)?->unlocked)->count()
);
$unlockedCount = $userAchievements->filter(fn($ua) => $ua->unlocked)->count();
return Inertia::render('UserAchievements', [
'canView' => $canView,
'user' => $user,
'canEdit' => auth()->id() === $user->id,
'followStatus' => auth()->check() ? auth()->user()->followStatus($user) : 'none',
'achievements' => $canView ? $achievements : [],
'userAchievements' => $canView ? $userAchievements : [],
'loggedInUser' => auth()->user(),
'unlockedCount' => $unlockedCount,
'unlockedByCategory' => $unlockedByCategory,
'totalAchievements' => $achievements->flatten()->count(),
]);
}
public function achievement(User $user, Achievement $achievement)
{
$regions = match($achievement->internal_name){
'fun_challenges.australian_states' => Country::whereCode('AU')->first()->sortedRegions(),
'fun_challenges.chinese_provinces' => Country::whereCode('CN')->first()->sortedRegions(),
'fun_challenges.canadian_provinces' => Country::whereCode('CA')->first()->sortedRegions(),
'fun_challenges.brazilian_states' => Country::whereCode('BR')->first()->sortedRegions(),
'fun_challenges.us_states' => Country::whereCode('US')->first()->sortedRegions(),
default => [],
};
$allianceInternalName = match($achievement->internal_name){
'airlines_alliances.all_star_alliance' => 'star_alliance',
'airlines_alliances.all_oneworld' => 'oneworld',
'airlines_alliances.all_skyteam' => 'skyteam',
'airlines_alliances.all_vanilla_alliance' => 'vanilla_alliance',
default => null,
};
$continents = match($achievement->internal_name){
'countries_continents.all_continent_pairs_one_way', 'countries_continents.all_continent_pairs_both_ways' => Continent::all()->toArray(),
default => [],
};
$alliance = null;
$airlines = [];
if ($allianceInternalName) {
$alliance = Alliance::where('internal_name', $allianceInternalName)
->with('airlines')
->firstOrFail();
$airlines = $alliance->airlines()->with('country')->orderBy('name')->get();
}
$aircraftFamilies = match($achievement->internal_name){
'aircraft.all_boeing_7x7' => Aircraft::BOEING_FAMILIES,
'aircraft.all_airbus_a3xx' => Aircraft::AIRBUS_FAMILIES,
default => [],
};
$canView = Gate::allows('viewProfileData', $user);
return Inertia::render('Profile/UserAchievement', [
'user' => $user,
'achievement' => $achievement,
'loggedInUser' => auth()->user(),
'userAchievement' => $canView ? $user->achievements()->where('achievement_id', $achievement->id)->first() : null,
'followStatus' => auth()->check() ? auth()->user()->followStatus($user) : 'none',
'flight_api_url' => UserProfileController::getUserFlightApiURL($user),
'regions' => $regions,
'alliance' => $alliance,
'airlines' => $airlines,
'continents' => $continents,
'aircraft_families' => $aircraftFamilies,
'achievementCount' => $user->unlockedAchievements()->count(),
'canView' => $canView,
]);
}
}