Merge branch 'profile-data' into user-profile-info

This commit is contained in:
Refringe 2024-09-17 17:32:46 +00:00
commit 579a26a360
49 changed files with 43 additions and 291 deletions

View File

@ -8,8 +8,6 @@ trait PasswordValidationRules
{ {
/** /**
* Get the validation rules used to validate passwords. * Get the validation rules used to validate passwords.
*
* @return array<int, \Illuminate\Contracts\Validation\Rule|array<mixed>|string>
*/ */
protected function passwordRules(): array protected function passwordRules(): array
{ {

View File

@ -13,8 +13,6 @@ class ResetUserPassword implements ResetsUserPasswords
/** /**
* Validate and reset the user's forgotten password. * Validate and reset the user's forgotten password.
*
* @param array<string, string> $input
*/ */
public function reset(User $user, array $input): void public function reset(User $user, array $input): void
{ {

View File

@ -13,8 +13,6 @@ class UpdateUserPassword implements UpdatesUserPasswords
/** /**
* Validate and update the user's password. * Validate and update the user's password.
*
* @param array<string, string> $input
*/ */
public function update(User $user, array $input): void public function update(User $user, array $input): void
{ {

View File

@ -12,8 +12,6 @@ class UpdateUserProfileInformation implements UpdatesUserProfileInformation
{ {
/** /**
* Validate and update the given user's profile information. * Validate and update the given user's profile information.
*
* @param array<string, mixed> $input
*/ */
public function update(User $user, array $input): void public function update(User $user, array $input): void
{ {

View File

@ -12,8 +12,6 @@ class ApiController extends Controller
/** /**
* Determine if the given relationship should be included in the request. If more than one relationship is provided, * Determine if the given relationship should be included in the request. If more than one relationship is provided,
* only one needs to be present in the request for this method to return true. * only one needs to be present in the request for this method to return true.
*
* @param string|string[] $relationships
*/ */
public static function shouldInclude(string|array $relationships): bool public static function shouldInclude(string|array $relationships): bool
{ {

View File

@ -38,8 +38,6 @@ class ModController extends ApiController
return ModResource::collection(Mod::filter($filters)->paginate()); return ModResource::collection(Mod::filter($filters)->paginate());
} }
//public function store(StoreModRequest $request): void {}
/** /**
* Get Mod * Get Mod
* *
@ -53,8 +51,4 @@ class ModController extends ApiController
{ {
return new ModResource($mod); return new ModResource($mod);
} }
//public function update(UpdateModRequest $request, Mod $mod): void {}
//public function destroy(Mod $mod): void {}
} }

View File

@ -29,8 +29,6 @@ class UsersController extends ApiController
return UserResource::collection(User::filter($filters)->paginate()); return UserResource::collection(User::filter($filters)->paginate());
} }
//public function store(StoreUserRequest $request): void {}
/** /**
* Get User * Get User
* *
@ -43,8 +41,4 @@ class UsersController extends ApiController
{ {
return new UserResource($user); return new UserResource($user);
} }
//public function update(UpdateUserRequest $request, User $user): void {}
//public function destroy(User $user): void {}
} }

View File

@ -10,22 +10,16 @@ class ModFilter
{ {
/** /**
* The query builder instance for the mod model. * The query builder instance for the mod model.
*
* @var Builder<Mod>
*/ */
protected Builder $builder; protected Builder $builder;
/** /**
* The filters to apply. * The filters to apply.
*
* @var array<string, mixed>
*/ */
protected array $filters; protected array $filters;
/** /**
* Constructor. * Create a new ModFilter instance.
*
* @param array<string, mixed> $filters
*/ */
public function __construct(array $filters) public function __construct(array $filters)
{ {
@ -35,8 +29,6 @@ class ModFilter
/** /**
* The base query for the mod listing. * The base query for the mod listing.
*
* @return Builder<Mod>
*/ */
private function baseQuery(): Builder private function baseQuery(): Builder
{ {
@ -59,8 +51,6 @@ class ModFilter
/** /**
* Filter the results by the given search term. * Filter the results by the given search term.
*
* @return Builder<Mod>
*/ */
private function query(string $term): Builder private function query(string $term): Builder
{ {
@ -69,8 +59,6 @@ class ModFilter
/** /**
* Apply the filters to the query. * Apply the filters to the query.
*
* @return Builder<Mod>
*/ */
public function apply(): Builder public function apply(): Builder
{ {
@ -85,8 +73,6 @@ class ModFilter
/** /**
* Order the query by the given type. * Order the query by the given type.
*
* @return Builder<Mod>
*/ */
private function order(string $type): Builder private function order(string $type): Builder
{ {
@ -99,8 +85,6 @@ class ModFilter
/** /**
* Filter the results by the featured status. * Filter the results by the featured status.
*
* @return Builder<Mod>
*/ */
private function featured(string $option): Builder private function featured(string $option): Builder
{ {
@ -113,9 +97,6 @@ class ModFilter
/** /**
* Filter the results to specific SPT versions. * Filter the results to specific SPT versions.
*
* @param array<int, string> $versions
* @return Builder<Mod>
*/ */
private function sptVersions(array $versions): Builder private function sptVersions(array $versions): Builder
{ {

View File

@ -12,8 +12,6 @@ class ModFilter extends QueryFilter
{ {
/** /**
* The sortable fields. * The sortable fields.
*
* @var array<string>
*/ */
protected array $sortable = [ protected array $sortable = [
'name', 'name',
@ -30,8 +28,6 @@ class ModFilter extends QueryFilter
/** /**
* Filter by ID. * Filter by ID.
*
* @return Builder<Mod>
*/ */
public function id(string $value): Builder public function id(string $value): Builder
{ {
@ -40,8 +36,6 @@ class ModFilter extends QueryFilter
/** /**
* Filter by hub ID. * Filter by hub ID.
*
* @return Builder<Mod>
*/ */
public function hub_id(string $value): Builder public function hub_id(string $value): Builder
{ {
@ -50,8 +44,6 @@ class ModFilter extends QueryFilter
/** /**
* Filter by name. * Filter by name.
*
* @return Builder<Mod>
*/ */
public function name(string $value): Builder public function name(string $value): Builder
{ {
@ -60,8 +52,6 @@ class ModFilter extends QueryFilter
/** /**
* Filter by slug. * Filter by slug.
*
* @return Builder<Mod>
*/ */
public function slug(string $value): Builder public function slug(string $value): Builder
{ {
@ -70,8 +60,6 @@ class ModFilter extends QueryFilter
/** /**
* Filter by teaser. * Filter by teaser.
*
* @return Builder<Mod>
*/ */
public function teaser(string $value): Builder public function teaser(string $value): Builder
{ {
@ -80,8 +68,6 @@ class ModFilter extends QueryFilter
/** /**
* Filter by source code link. * Filter by source code link.
*
* @return Builder<Mod>
*/ */
public function source_code_link(string $value): Builder public function source_code_link(string $value): Builder
{ {
@ -90,8 +76,6 @@ class ModFilter extends QueryFilter
/** /**
* Filter by created at date. * Filter by created at date.
*
* @return Builder<Mod>
*/ */
public function created_at(string $value): Builder public function created_at(string $value): Builder
{ {
@ -100,8 +84,6 @@ class ModFilter extends QueryFilter
/** /**
* Filter by updated at date. * Filter by updated at date.
*
* @return Builder<Mod>
*/ */
public function updated_at(string $value): Builder public function updated_at(string $value): Builder
{ {
@ -110,8 +92,6 @@ class ModFilter extends QueryFilter
/** /**
* Filter by published at date. * Filter by published at date.
*
* @return Builder<Mod>
*/ */
public function published_at(string $value): Builder public function published_at(string $value): Builder
{ {
@ -120,8 +100,6 @@ class ModFilter extends QueryFilter
/** /**
* Filter by featured. * Filter by featured.
*
* @return Builder<Mod>
*/ */
public function featured(string $value): Builder public function featured(string $value): Builder
{ {
@ -130,8 +108,6 @@ class ModFilter extends QueryFilter
/** /**
* Filter by contains ads. * Filter by contains ads.
*
* @return Builder<Mod>
*/ */
public function contains_ads(string $value): Builder public function contains_ads(string $value): Builder
{ {
@ -140,8 +116,6 @@ class ModFilter extends QueryFilter
/** /**
* Filter by contains AI content. * Filter by contains AI content.
*
* @return Builder<Mod>
*/ */
public function contains_ai_content(string $value): Builder public function contains_ai_content(string $value): Builder
{ {

View File

@ -4,25 +4,17 @@ namespace App\Http\Filters\V1;
use App\Traits\V1\FilterMethods; use App\Traits\V1\FilterMethods;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request; use Illuminate\Http\Request;
/**
* @template TModelClass of Model
*/
abstract class QueryFilter abstract class QueryFilter
{ {
/** /**
* Include general filter methods. * Include general filter methods.
*
* @use FilterMethods<TModelClass>
*/ */
use FilterMethods; use FilterMethods;
/** /**
* The query builder instance. * The query builder instance.
*
* @var Builder<TModelClass>
*/ */
protected Builder $builder; protected Builder $builder;
@ -33,8 +25,6 @@ abstract class QueryFilter
/** /**
* The sortable fields. * The sortable fields.
*
* @var array<string>
*/ */
protected array $sortable = []; protected array $sortable = [];
@ -48,9 +38,6 @@ abstract class QueryFilter
/** /**
* Iterate over each of the filter options and call the appropriate method if it exists. * Iterate over each of the filter options and call the appropriate method if it exists.
*
* @param array<string, string> $filters
* @return Builder<TModelClass>
*/ */
public function filter(array $filters): Builder public function filter(array $filters): Builder
{ {
@ -65,9 +52,6 @@ abstract class QueryFilter
/** /**
* Iterate over all request data and call the appropriate method if it exists. * Iterate over all request data and call the appropriate method if it exists.
*
* @param Builder<TModelClass> $builder
* @return Builder<TModelClass>
*/ */
public function apply(Builder $builder): Builder public function apply(Builder $builder): Builder
{ {

View File

@ -12,8 +12,6 @@ class UserFilter extends QueryFilter
{ {
/** /**
* The sortable fields. * The sortable fields.
*
* @var array<string>
*/ */
protected array $sortable = [ protected array $sortable = [
'name', 'name',
@ -23,8 +21,6 @@ class UserFilter extends QueryFilter
/** /**
* Filter by ID. * Filter by ID.
*
* @return Builder<User>
*/ */
public function id(string $value): Builder public function id(string $value): Builder
{ {
@ -33,8 +29,6 @@ class UserFilter extends QueryFilter
/** /**
* Filter by name. * Filter by name.
*
* @return Builder<User>
*/ */
public function name(string $value): Builder public function name(string $value): Builder
{ {
@ -43,8 +37,6 @@ class UserFilter extends QueryFilter
/** /**
* Filter by created at date. * Filter by created at date.
*
* @return Builder<User>
*/ */
public function created_at(string $value): Builder public function created_at(string $value): Builder
{ {
@ -53,8 +45,6 @@ class UserFilter extends QueryFilter
/** /**
* Filter by updated at date. * Filter by updated at date.
*
* @return Builder<User>
*/ */
public function updated_at(string $value): Builder public function updated_at(string $value): Builder
{ {

View File

@ -16,8 +16,6 @@ class LoginUserRequest extends FormRequest
/** /**
* Get the validation rules that apply to the request. * Get the validation rules that apply to the request.
*
* @return array<string, mixed>
*/ */
public function rules(): array public function rules(): array
{ {

View File

@ -16,8 +16,6 @@ class StoreModRequest extends FormRequest
/** /**
* Get the validation rules that apply to the request. * Get the validation rules that apply to the request.
*
* @return array<string, mixed>
*/ */
public function rules(): array public function rules(): array
{ {

View File

@ -16,8 +16,6 @@ class StoreUserRequest extends FormRequest
/** /**
* Get the validation rules that apply to the request. * Get the validation rules that apply to the request.
*
* @return array<string, mixed>
*/ */
public function rules(): array public function rules(): array
{ {

View File

@ -16,8 +16,6 @@ class UpdateModRequest extends FormRequest
/** /**
* Get the validation rules that apply to the request. * Get the validation rules that apply to the request.
*
* @return array<string, mixed>
*/ */
public function rules(): array public function rules(): array
{ {

View File

@ -16,8 +16,6 @@ class UpdateUserRequest extends FormRequest
/** /**
* Get the validation rules that apply to the request. * Get the validation rules that apply to the request.
*
* @return array<string, mixed>
*/ */
public function rules(): array public function rules(): array
{ {

View File

@ -8,8 +8,6 @@ class ModRequest extends FormRequest
{ {
/** /**
* Get the validation rules that apply to the request. * Get the validation rules that apply to the request.
*
* @return array<string, mixed>
*/ */
public function rules(): array public function rules(): array
{ {

View File

@ -11,8 +11,6 @@ class LicenseResource extends JsonResource
{ {
/** /**
* Transform the resource into an array. * Transform the resource into an array.
*
* @return array<string, mixed>
*/ */
public function toArray(Request $request): array public function toArray(Request $request): array
{ {

View File

@ -12,8 +12,6 @@ class ModResource extends JsonResource
{ {
/** /**
* Transform the resource into an array. * Transform the resource into an array.
*
* @return array<string, mixed>
*/ */
public function toArray(Request $request): array public function toArray(Request $request): array
{ {

View File

@ -11,8 +11,6 @@ class ModVersionResource extends JsonResource
{ {
/** /**
* Transform the resource into an array. * Transform the resource into an array.
*
* @return array<string, mixed>
*/ */
public function toArray(Request $request): array public function toArray(Request $request): array
{ {

View File

@ -12,8 +12,6 @@ class UserResource extends JsonResource
{ {
/** /**
* Transform the resource into an array. * Transform the resource into an array.
*
* @return array<string, mixed>
*/ */
public function toArray(Request $request): array public function toArray(Request $request): array
{ {

View File

@ -11,8 +11,6 @@ class UserRoleResource extends JsonResource
{ {
/** /**
* Transform the resource into an array. * Transform the resource into an array.
*
* @return array<string, mixed>
*/ */
public function toArray(Request $request): array public function toArray(Request $request): array
{ {

View File

@ -11,8 +11,6 @@ class LicenseResource extends JsonResource
{ {
/** /**
* Transform the resource into an array. * Transform the resource into an array.
*
* @return array<string, mixed>
*/ */
public function toArray(Request $request): array public function toArray(Request $request): array
{ {

View File

@ -11,8 +11,6 @@ class ModResource extends JsonResource
{ {
/** /**
* Transform the resource into an array. * Transform the resource into an array.
*
* @return array<string, mixed>
*/ */
public function toArray(Request $request): array public function toArray(Request $request): array
{ {

View File

@ -11,8 +11,6 @@ class ModVersionResource extends JsonResource
{ {
/** /**
* Transform the resource into an array. * Transform the resource into an array.
*
* @return array<string, mixed>
*/ */
public function toArray(Request $request): array public function toArray(Request $request): array
{ {

View File

@ -11,8 +11,6 @@ class SptVersionResource extends JsonResource
{ {
/** /**
* Transform the resource into an array. * Transform the resource into an array.
*
* @return array<string, mixed>
*/ */
public function toArray(Request $request): array public function toArray(Request $request): array
{ {

View File

@ -348,8 +348,6 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
/** /**
* Build an array of user data ready to be inserted into the local database. * Build an array of user data ready to be inserted into the local database.
*
* @return array<string, mixed>
*/ */
protected function collectUserData(CurlHandle $curl, HubUser $hubUser): array protected function collectUserData(CurlHandle $curl, HubUser $hubUser): array
{ {
@ -464,8 +462,6 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
/** /**
* Build an array of banned user data ready to be inserted into the local database. * Build an array of banned user data ready to be inserted into the local database.
*
* @return array<string, mixed>|null
*/ */
protected function collectBannedUserData(HubUser $hubUser): ?array protected function collectBannedUserData(HubUser $hubUser): ?array
{ {
@ -522,8 +518,6 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
/** /**
* Build an array of user rank data ready to be inserted into the local database. * Build an array of user rank data ready to be inserted into the local database.
*
* @return array<string, mixed>|null
*/ */
protected function collectUserRankData(HubUser $hubUser): ?array protected function collectUserRankData(HubUser $hubUser): ?array
{ {
@ -539,8 +533,6 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
/** /**
* Insert or update the users in the local database. * Insert or update the users in the local database.
*
* @param array<array<string, mixed>> $usersData
*/ */
protected function upsertUsers(array $usersData): void protected function upsertUsers(array $usersData): void
{ {
@ -557,8 +549,6 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
/** /**
* Fetch the hub-banned users from the local database and ban them locally. * Fetch the hub-banned users from the local database and ban them locally.
*
* @param array<array<string, mixed>> $bannedUsers
*/ */
protected function handleBannedUsers(array $bannedUsers): void protected function handleBannedUsers(array $bannedUsers): void
{ {
@ -573,8 +563,6 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
/** /**
* Fetch or create the user ranks in the local database and assign them to the users. * Fetch or create the user ranks in the local database and assign them to the users.
*
* @param array<array<string, mixed>> $userRanks
*/ */
protected function handleUserRoles(array $userRanks): void protected function handleUserRoles(array $userRanks): void
{ {
@ -591,8 +579,6 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
/** /**
* Build the user role data based on the role name. * Build the user role data based on the role name.
*
* @return array<string, string>
*/ */
protected function buildUserRoleData(string $name): array protected function buildUserRoleData(string $name): array
{ {
@ -710,8 +696,6 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
/** /**
* Get the latest current version from the response data. * Get the latest current version from the response data.
*
* @param array<string, array<string, string>> $versions
*/ */
protected function getLatestVersion(array $versions): string protected function getLatestVersion(array $versions): string
{ {

View File

@ -35,8 +35,6 @@ class GlobalSearch extends Component
/** /**
* Execute the search against each of the searchable models. * Execute the search against each of the searchable models.
*
* @return array<string, array<array<string, mixed>>>
*/ */
protected function executeSearch(string $query): array protected function executeSearch(string $query): array
{ {
@ -51,16 +49,13 @@ class GlobalSearch extends Component
$results['total'] = $this->countTotalResults($results['data']); $results['total'] = $this->countTotalResults($results['data']);
} }
$this->showDropdown = Str::length($query) > 0; $this->noResults = $results['total'] === 0;
$this->noResults = $results['total'] === 0 && $this->showDropdown;
return $results; return $results;
} }
/** /**
* Fetch the user search results. * Fetch the user search results.
*
* @return Collection<int, array<string, mixed>>
*/ */
protected function fetchUserResults(string $query): Collection protected function fetchUserResults(string $query): Collection
{ {
@ -72,8 +67,6 @@ class GlobalSearch extends Component
/** /**
* Fetch the mod search results. * Fetch the mod search results.
*
* @return Collection<int, array<string, mixed>>
*/ */
protected function fetchModResults(string $query): Collection protected function fetchModResults(string $query): Collection
{ {
@ -85,8 +78,6 @@ class GlobalSearch extends Component
/** /**
* Count the total number of results across all models. * Count the total number of results across all models.
*
* @param array<string, Collection<int, array<string, mixed>>> $results
*/ */
protected function countTotalResults(array $results): int protected function countTotalResults(array $results): int
{ {
@ -94,14 +85,4 @@ class GlobalSearch extends Component
return $carry + $result->count(); return $carry + $result->count();
}, 0); }, 0);
} }
/**
* Clear the search query and hide the dropdown.
*/
public function clearSearch(): void
{
$this->query = '';
$this->showDropdown = false;
$this->noResults = false;
}
} }

View File

@ -3,7 +3,6 @@
namespace App\Livewire\Mod; namespace App\Livewire\Mod;
use App\Http\Filters\ModFilter; use App\Http\Filters\ModFilter;
use App\Models\Mod;
use App\Models\SptVersion; use App\Models\SptVersion;
use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Contracts\View\View; use Illuminate\Contracts\View\View;
@ -32,8 +31,6 @@ class Listing extends Component
/** /**
* The SPT versions filter value. * The SPT versions filter value.
*
* @var array<string>
*/ */
#[Url] #[Url]
public array $sptVersions = []; public array $sptVersions = [];
@ -65,8 +62,6 @@ class Listing extends Component
/** /**
* Get all patch versions of the latest minor SPT version. * Get all patch versions of the latest minor SPT version.
*
* @return Collection<int, SptVersion>
*/ */
public function getLatestMinorVersions(): Collection public function getLatestMinorVersions(): Collection
{ {
@ -96,8 +91,6 @@ class Listing extends Component
/** /**
* Check if the current page is greater than the last page. Redirect if it is. * Check if the current page is greater than the last page. Redirect if it is.
*
* @param LengthAwarePaginator<Mod> $mods
*/ */
private function redirectOutOfBoundsPage(LengthAwarePaginator $mods): void private function redirectOutOfBoundsPage(LengthAwarePaginator $mods): void
{ {

View File

@ -12,8 +12,6 @@ class UpdateProfileForm extends UpdateProfileInformationForm
{ {
/** /**
* The new cover photo for the user. * The new cover photo for the user.
*
* @var mixed
*/ */
public $cover; public $cover;

View File

@ -2,7 +2,6 @@
namespace App\Models; namespace App\Models;
use Database\Factories\LicenseFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
@ -10,9 +9,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
class License extends Model class License extends Model
{ {
/** @use HasFactory<LicenseFactory> */
use HasFactory; use HasFactory;
use SoftDeletes; use SoftDeletes;
/** /**

View File

@ -96,8 +96,6 @@ class Mod extends Model
/** /**
* The data that is searchable by Scout. * The data that is searchable by Scout.
*
* @return array<string, mixed>
*/ */
public function toSearchableArray(): array public function toSearchableArray(): array
{ {
@ -173,8 +171,6 @@ class Mod extends Model
/** /**
* Build the URL to the mod's thumbnail. * Build the URL to the mod's thumbnail.
*
* @return Attribute<string, never>
*/ */
public function thumbnailUrl(): Attribute public function thumbnailUrl(): Attribute
{ {
@ -198,10 +194,6 @@ class Mod extends Model
/** /**
* Scope a query by applying QueryFilter filters. * Scope a query by applying QueryFilter filters.
*
* @param Builder<Mod> $builder
* @param QueryFilter<Mod> $filters
* @return Builder<Mod>
*/ */
public function scopeFilter(Builder $builder, QueryFilter $filters): Builder public function scopeFilter(Builder $builder, QueryFilter $filters): Builder
{ {
@ -218,8 +210,6 @@ class Mod extends Model
/** /**
* The attributes that should be cast to native types. * The attributes that should be cast to native types.
*
* @return array<string, string>
*/ */
protected function casts(): array protected function casts(): array
{ {

View File

@ -2,7 +2,6 @@
namespace App\Models; namespace App\Models;
use Database\Factories\ModDependencyFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -10,7 +9,6 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
class ModDependency extends Model class ModDependency extends Model
{ {
/** @use HasFactory<ModDependencyFactory> */
use HasFactory; use HasFactory;
/** /**

View File

@ -6,7 +6,6 @@ use App\Exceptions\InvalidVersionNumberException;
use App\Models\Scopes\DisabledScope; use App\Models\Scopes\DisabledScope;
use App\Models\Scopes\PublishedScope; use App\Models\Scopes\PublishedScope;
use App\Support\Version; use App\Support\Version;
use Database\Factories\ModFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -17,15 +16,11 @@ use Illuminate\Database\Eloquent\SoftDeletes;
class ModVersion extends Model class ModVersion extends Model
{ {
/** @use HasFactory<ModFactory> */
use HasFactory; use HasFactory;
use SoftDeletes; use SoftDeletes;
/** /**
* Update the parent mod's updated_at timestamp when the mod version is updated. * Update the parent mod's updated_at timestamp when the mod version is updated.
*
* @var array<string>
*/ */
protected $touches = ['mod']; protected $touches = ['mod'];

View File

@ -6,15 +6,10 @@ use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope; use Illuminate\Database\Eloquent\Scope;
/**
* @template TModelClass of Model
*/
class DisabledScope implements Scope class DisabledScope implements Scope
{ {
/** /**
* Apply the scope to a given Eloquent query builder. * Apply the scope to a given Eloquent query builder.
*
* @param Builder<TModelClass> $builder
*/ */
public function apply(Builder $builder, Model $model): void public function apply(Builder $builder, Model $model): void
{ {

View File

@ -6,15 +6,10 @@ use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope; use Illuminate\Database\Eloquent\Scope;
/**
* @template TModelClass of Model
*/
class PublishedScope implements Scope class PublishedScope implements Scope
{ {
/** /**
* Apply the scope to a given Eloquent query builder. * Apply the scope to a given Eloquent query builder.
*
* @param Builder<TModelClass> $builder
*/ */
public function apply(Builder $builder, Model $model): void public function apply(Builder $builder, Model $model): void
{ {

View File

@ -4,7 +4,6 @@ namespace App\Models;
use App\Exceptions\InvalidVersionNumberException; use App\Exceptions\InvalidVersionNumberException;
use App\Support\Version; use App\Support\Version;
use Database\Factories\SptVersionFactory;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
@ -14,15 +13,11 @@ use Illuminate\Support\Facades\Cache;
class SptVersion extends Model class SptVersion extends Model
{ {
/** @use HasFactory<SptVersionFactory> */
use HasFactory; use HasFactory;
use SoftDeletes; use SoftDeletes;
/** /**
* Get all versions for the last three minor versions. * Get all versions for the last three minor versions.
*
* @return Collection<int, SptVersion>
*/ */
public static function getVersionsForLastThreeMinors(): Collection public static function getVersionsForLastThreeMinors(): Collection
{ {
@ -51,8 +46,6 @@ class SptVersion extends Model
/** /**
* Get the last three minor versions (major.minor format). * Get the last three minor versions (major.minor format).
*
* @return array<int, array{major: int, minor: int}>
*/ */
public static function getLastThreeMinorVersions(): array public static function getLastThreeMinorVersions(): array
{ {
@ -75,8 +68,6 @@ class SptVersion extends Model
/** /**
* Extract the version sections from the version string. * Extract the version sections from the version string.
* *
* @return array{major: int, minor: int, patch: int, pre_release: string}
*
* @throws InvalidVersionNumberException * @throws InvalidVersionNumberException
*/ */
public static function extractVersionSections(string $version): array public static function extractVersionSections(string $version): array

View File

@ -6,7 +6,6 @@ use App\Http\Filters\V1\QueryFilter;
use App\Notifications\ResetPassword; use App\Notifications\ResetPassword;
use App\Notifications\VerifyEmail; use App\Notifications\VerifyEmail;
use App\Traits\HasCoverPhoto; use App\Traits\HasCoverPhoto;
use Database\Factories\UserFactory;
use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
@ -26,10 +25,7 @@ class User extends Authenticatable implements MustVerifyEmail
use Bannable; use Bannable;
use HasApiTokens; use HasApiTokens;
use HasCoverPhoto; use HasCoverPhoto;
/** @use HasFactory<UserFactory> */
use HasFactory; use HasFactory;
use HasProfilePhoto; use HasProfilePhoto;
use Notifiable; use Notifiable;
use Searchable; use Searchable;
@ -103,8 +99,6 @@ class User extends Authenticatable implements MustVerifyEmail
/** /**
* The data that is searchable by Scout. * The data that is searchable by Scout.
*
* @return array<string, mixed>
*/ */
public function toSearchableArray(): array public function toSearchableArray(): array
{ {
@ -195,10 +189,6 @@ class User extends Authenticatable implements MustVerifyEmail
/** /**
* Scope a query by applying QueryFilter filters. * Scope a query by applying QueryFilter filters.
*
* @param Builder<User> $builder
* @param QueryFilter<User> $filters
* @return Builder<User>
*/ */
public function scopeFilter(Builder $builder, QueryFilter $filters): Builder public function scopeFilter(Builder $builder, QueryFilter $filters): Builder
{ {
@ -215,8 +205,6 @@ class User extends Authenticatable implements MustVerifyEmail
/** /**
* The attributes that should be cast to native types. * The attributes that should be cast to native types.
*
* @return array<string, string>
*/ */
protected function casts(): array protected function casts(): array
{ {

View File

@ -2,14 +2,12 @@
namespace App\Models; namespace App\Models;
use Database\Factories\UserFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
class UserRole extends Model class UserRole extends Model
{ {
/** @use HasFactory<UserFactory> */
use HasFactory; use HasFactory;
/** /**

View File

@ -20,8 +20,6 @@ class ResetPassword extends OriginalResetPassword implements ShouldQueue
/** /**
* Get the array representation of the notification. * Get the array representation of the notification.
*
* @return array<mixed>
*/ */
public function toArray(object $notifiable): array public function toArray(object $notifiable): array
{ {

View File

@ -15,8 +15,6 @@ class VerifyEmail extends OriginalVerifyEmail implements ShouldQueue
/** /**
* Get the array representation of the notification. * Get the array representation of the notification.
*
* @return array<mixed>
*/ */
public function toArray(object $notifiable): array public function toArray(object $notifiable): array
{ {

View File

@ -18,8 +18,6 @@ class DependencyVersionService
/** /**
* Satisfies all dependency constraints of a ModVersion. * Satisfies all dependency constraints of a ModVersion.
*
* @return array<int, array<string, int>>
*/ */
private function satisfyConstraint(ModVersion $modVersion): array private function satisfyConstraint(ModVersion $modVersion): array
{ {

View File

@ -19,8 +19,6 @@ class SptVersionService
/** /**
* Satisfies the version constraint of a given ModVersion. Returns the ID of the satisfying SptVersion. * Satisfies the version constraint of a given ModVersion. Returns the ID of the satisfying SptVersion.
*
* @return array<int>
*/ */
private function satisfyConstraint(ModVersion $modVersion): array private function satisfyConstraint(ModVersion $modVersion): array
{ {

View File

@ -52,8 +52,6 @@ trait HasCoverPhoto
/** /**
* Get the cover photo URL for the user. * Get the cover photo URL for the user.
*
* @return Attribute<string, never>
*/ */
public function coverPhotoUrl(): Attribute public function coverPhotoUrl(): Attribute
{ {

View File

@ -2,93 +2,63 @@
namespace App\Traits\V1; namespace App\Traits\V1;
use App\Http\Filters\V1\QueryFilter;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str; use Illuminate\Support\Str;
/**
* @template TModelClass of Model
*
* @mixin QueryFilter<TModelClass>
*/
trait FilterMethods trait FilterMethods
{ {
/** /**
* Filter using a whereIn clause. * Filter using a whereIn clause.
*
* @return Builder<TModelClass>
*/ */
public function filterWhereIn(string $column, string $value): Builder public function filterWhereIn(string $column, string $value): Builder
{ {
$ids = array_map('trim', explode(',', $value)); $ids = array_map('trim', explode(',', $value));
$result = $this->builder->whereIn($column, $ids); return $this->builder->whereIn($column, $ids);
/** @var Builder<TModelClass> $result */
return $result;
} }
/** /**
* Filter using a LIKE clause with a wildcard characters. * Filter using a LIKE clause with a wildcard characters.
*
* @return Builder<TModelClass>
*/ */
public function filterByWildcardLike(string $column, string $value): Builder public function filterByWildcardLike(string $column, string $value): Builder
{ {
$like = Str::replace('*', '%', $value); $like = Str::replace('*', '%', $value);
$result = $this->builder->where($column, 'like', $like); return $this->builder->where($column, 'like', $like);
/** @var Builder<TModelClass> $result */
return $result;
} }
/** /**
* Filter by date range or specific date. * Filter by date range or specific date.
*
* @return Builder<TModelClass>
*/ */
public function filterByDate(string $column, string $value): Builder public function filterByDate(string $column, string $value): Builder
{ {
$dates = array_map('trim', explode(',', $value)); $dates = array_map('trim', explode(',', $value));
if (count($dates) > 1) { if (count($dates) > 1) {
$result = $this->builder->whereBetween($column, $dates); return $this->builder->whereBetween($column, $dates);
} else {
$result = $this->builder->whereDate($column, $dates[0]);
} }
/** @var Builder<TModelClass> $result */ return $this->builder->whereDate($column, $dates[0]);
return $result;
} }
/** /**
* Filter by boolean value. * Filter by boolean value.
*
* @return Builder<TModelClass>
*/ */
public function filterByBoolean(string $column, string $value): Builder public function filterByBoolean(string $column, string $value): Builder
{ {
$value = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); $value = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
if ($value === null) { if ($value === null) {
$result = $this->builder; // The unmodified builder return $this->builder; // The unmodified builder
} else {
$result = $this->builder->where($column, $value);
} }
/** @var Builder<TModelClass> $result */ return $this->builder->where($column, $value);
return $result;
} }
/** /**
* Apply the sort type to the query. * Apply the sort type to the query.
*
* @return Builder<TModelClass>
*/ */
protected function sort(string $values): Builder protected function sort(string $values): Builder
{ {
$result = $this->builder;
$sortables = array_map('trim', explode(',', $values)); $sortables = array_map('trim', explode(',', $values));
foreach ($sortables as $sortable) { foreach ($sortables as $sortable) {
@ -96,11 +66,10 @@ trait FilterMethods
$column = Str::of($sortable)->remove('-')->value(); $column = Str::of($sortable)->remove('-')->value();
if (in_array($column, $this->sortable)) { if (in_array($column, $this->sortable)) {
$result = $this->builder->orderBy($column, $direction); $this->builder->orderBy($column, $direction);
} }
} }
/** @var Builder<TModelClass> $result */ return $this->builder;
return $result;
} }
} }

View File

@ -33,8 +33,6 @@ class HomepageMods extends Component
/** /**
* Fetches the featured mods homepage listing. * Fetches the featured mods homepage listing.
*
* @return Collection<int, Mod>
*/ */
private function fetchFeaturedMods(): Collection private function fetchFeaturedMods(): Collection
{ {
@ -54,8 +52,6 @@ class HomepageMods extends Component
/** /**
* Fetches the latest mods homepage listing. * Fetches the latest mods homepage listing.
*
* @return Collection<int, Mod>
*/ */
private function fetchLatestMods(): Collection private function fetchLatestMods(): Collection
{ {
@ -74,8 +70,6 @@ class HomepageMods extends Component
/** /**
* Fetches the recently updated mods homepage listing. * Fetches the recently updated mods homepage listing.
*
* @return Collection<int, Mod>
*/ */
private function fetchUpdatedMods(): Collection private function fetchUpdatedMods(): Collection
{ {

View File

@ -1,5 +1,11 @@
<div id="search-results" aria-live="polite" class="{{ $showDropdown ? 'block' : 'hidden' }} absolute z-10 top-11 w-full mx-auto max-w-2xl transform overflow-hidden rounded-md bg-white dark:bg-gray-900 shadow-2xl border border-gray-300 dark:border-gray-700 transition-all"> <div id="search-results"
@if($showDropdown) x-cloak
x-show="showDropdown && query.length"
x-transition
aria-live="polite"
class="{{ $showDropdown ? 'block' : 'hidden' }} absolute z-10 top-11 w-full mx-auto max-w-2xl transform overflow-hidden rounded-md bg-white dark:bg-gray-900 shadow-2xl border border-gray-300 dark:border-gray-700 transition-all"
>
@if ($showDropdown)
<h2 class="sr-only">{{ __('Search Results') }}</h2> <h2 class="sr-only">{{ __('Search Results') }}</h2>
<div class="max-h-96 scroll-py-2 overflow-y-auto" role="list"> <div class="max-h-96 scroll-py-2 overflow-y-auto" role="list">
@foreach($results['data'] as $typeName => $typeResults) @foreach($results['data'] as $typeName => $typeResults)

View File

@ -1,5 +1,13 @@
<div class="flex flex-1 justify-center px-2 lg:ml-6 lg:justify-end"> <div x-data="{ query: $wire.entangle('query'), showDropdown: $wire.entangle('showDropdown'), noResults: $wire.entangle('noResults') }"
<div class="w-full max-w-lg lg:max-w-md"> @keydown.esc.window="showDropdown = false"
class="flex flex-1 justify-center px-2 lg:ml-6 lg:justify-end"
>
<div class="w-full max-w-lg lg:max-w-md"
x-trap="showDropdown && query.length"
@click.away="showDropdown = false"
@keydown.down.prevent="$focus.wrap().next()"
@keydown.up.prevent="$focus.wrap().previous()"
>
<label for="search" class="sr-only">{{ __('Search') }}</label> <label for="search" class="sr-only">{{ __('Search') }}</label>
<search class="relative group" role="search"> <search class="relative group" role="search">
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3"> <div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
@ -10,10 +18,11 @@
<input id="global-search" <input id="global-search"
type="search" type="search"
wire:model.live="query" wire:model.live="query"
@keydown.escape.window="$wire.clearSearch()" @focus="showDropdown = true"
@keydown.escape.window="$wire.query = ''; showDropdown = false; $wire.$refresh()"
placeholder="{{ __('Search') }}" placeholder="{{ __('Search') }}"
aria-controls="search-results" aria-controls="search-results"
aria-expanded="{{ $showDropdown ? 'true' : 'false' }}" :aria-expanded="showDropdown"
aria-label="{{ __('Search') }}" aria-label="{{ __('Search') }}"
class="block w-full rounded-md border-0 bg-white dark:bg-gray-700 py-1.5 pl-10 pr-3 text-gray-900 dark:text-gray-300 ring-1 ring-inset ring-gray-300 dark:ring-gray-700 placeholder:text-gray-400 dark:placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-gray-600 dark:focus:bg-gray-200 dark:focus:text-black dark:focus:ring-0 sm:text-sm sm:leading-6" class="block w-full rounded-md border-0 bg-white dark:bg-gray-700 py-1.5 pl-10 pr-3 text-gray-900 dark:text-gray-300 ring-1 ring-inset ring-gray-300 dark:ring-gray-700 placeholder:text-gray-400 dark:placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-gray-600 dark:focus:bg-gray-200 dark:focus:text-black dark:focus:ring-0 sm:text-sm sm:leading-6"
/> />

View File

@ -46,7 +46,10 @@
@auth @auth
{{-- Profile Dropdown --}} {{-- Profile Dropdown --}}
<div x-data="{ profileDropdownOpen: false, openedWithKeyboard: false }" @keydown.esc.window="profileDropdownOpen = false, openedWithKeyboard = false" class="relative"> <div x-data="{ profileDropdownOpen: false, openedWithKeyboard: false }"
@keydown.esc.window="profileDropdownOpen = false, openedWithKeyboard = false"
class="relative"
>
<button id="user-menu-button" type="button" @click="profileDropdownOpen = ! profileDropdownOpen" @keydown.space.prevent="openedWithKeyboard = true" @keydown.enter.prevent="openedWithKeyboard = true" @keydown.down.prevent="openedWithKeyboard = true" class="relative flex rounded-full bg-gray-800 text-sm text-white focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800" :class="profileDropdownOpen || openedWithKeyboard ? 'text-black dark:text-white' : 'text-slate-700 dark:text-slate-300'" :aria-expanded="profileDropdownOpen || openedWithKeyboard" aria-haspopup="true"> <button id="user-menu-button" type="button" @click="profileDropdownOpen = ! profileDropdownOpen" @keydown.space.prevent="openedWithKeyboard = true" @keydown.enter.prevent="openedWithKeyboard = true" @keydown.down.prevent="openedWithKeyboard = true" class="relative flex rounded-full bg-gray-800 text-sm text-white focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800" :class="profileDropdownOpen || openedWithKeyboard ? 'text-black dark:text-white' : 'text-slate-700 dark:text-slate-300'" :aria-expanded="profileDropdownOpen || openedWithKeyboard" aria-haspopup="true">
<span class="absolute -inset-1.5"></span> <span class="absolute -inset-1.5"></span>
<span class="sr-only">{{ __('Open user menu') }}</span> <span class="sr-only">{{ __('Open user menu') }}</span>
@ -60,7 +63,8 @@
@keydown.down.prevent="$focus.wrap().next()" @keydown.down.prevent="$focus.wrap().next()"
@keydown.up.prevent="$focus.wrap().previous()" @keydown.up.prevent="$focus.wrap().previous()"
class="absolute top-11 right-0 z-10 flex w-full min-w-[12rem] flex-col divide-y divide-slate-300 overflow-hidden rounded-xl border border-gray-300 bg-gray-100 dark:divide-gray-700 dark:border-gray-700 dark:bg-gray-800" class="absolute top-11 right-0 z-10 flex w-full min-w-[12rem] flex-col divide-y divide-slate-300 overflow-hidden rounded-xl border border-gray-300 bg-gray-100 dark:divide-gray-700 dark:border-gray-700 dark:bg-gray-800"
role="menu"> role="menu"
>
<div class="flex flex-col py-1.5"> <div class="flex flex-col py-1.5">
<a href="{{ route('dashboard') }}" class="flex items-center gap-2 bg-slate-100 px-4 py-2 text-sm text-slate-700 hover:bg-slate-800/5 hover:text-black focus-visible:bg-slate-800/10 focus-visible:text-black focus-visible:outline-none dark:bg-slate-800 dark:text-slate-300 dark:hover:bg-slate-100/5 dark:hover:text-white dark:focus-visible:bg-slate-100/10 dark:focus-visible:text-white" role="menuitem"> <a href="{{ route('dashboard') }}" class="flex items-center gap-2 bg-slate-100 px-4 py-2 text-sm text-slate-700 hover:bg-slate-800/5 hover:text-black focus-visible:bg-slate-800/10 focus-visible:text-black focus-visible:outline-none dark:bg-slate-800 dark:text-slate-300 dark:hover:bg-slate-100/5 dark:hover:text-white dark:focus-visible:bg-slate-100/10 dark:focus-visible:text-white" role="menuitem">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-4 h-4"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-4 h-4">