Skip to content

Commit

Permalink
feat(setRequestList): add new filter and update filters UX (#1574)
Browse files Browse the repository at this point in the history
  • Loading branch information
wescopeland authored Jun 30, 2023
1 parent 469c07d commit df6483c
Show file tree
Hide file tree
Showing 7 changed files with 207 additions and 53 deletions.
21 changes: 21 additions & 0 deletions app/Community/Enums/RequestStatus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace App\Community\Enums;

abstract class RequestStatus
{
public const Any = 0;
public const Claimed = 1;
public const Unclaimed = 2;

public static function cases(): array
{
return [
self::Any,
self::Claimed,
self::Unclaimed,
];
}
}
29 changes: 23 additions & 6 deletions app/Helpers/database/set-request.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

use App\Community\Enums\ClaimStatus;
use App\Community\Enums\RequestStatus;
use App\Community\Models\UserGameListEntry;
use App\Platform\Enums\AchievementType;
use App\Site\Models\User;
Expand Down Expand Up @@ -232,7 +233,7 @@ function getSetRequestorsList(int $gameID, bool $getEmailInfo = false): array
/**
* Gets a list of the most requested sets without core achievements.
*/
function getMostRequestedSetsList(array|int|null $console, int $offset, int $count): array
function getMostRequestedSetsList(array|int|null $console, int $offset, int $count, int $requestStatus = RequestStatus::Any): array
{
sanitize_sql_inputs($offset, $count);

Expand All @@ -249,7 +250,7 @@ function getMostRequestedSetsList(array|int|null $console, int $offset, int $cou
FROM
SetRequest sr
LEFT JOIN
SetClaim sc ON (sr.GameID = sc.GameID)
SetClaim sc ON (sr.GameID = sc.GameID AND sc.Status = " . ClaimStatus::Active . ")
LEFT JOIN
GameData gd ON (sr.GameID = gd.ID)
LEFT JOIN
Expand All @@ -264,6 +265,12 @@ function getMostRequestedSetsList(array|int|null $console, int $offset, int $cou
$query .= " AND c.ID = $console ";
}

if ($requestStatus === RequestStatus::Claimed) {
$query .= " AND sc.ID IS NOT NULL ";
} elseif ($requestStatus === RequestStatus::Unclaimed) {
$query .= " AND sc.ID IS NULL ";
}

$query .= "
GROUP BY
sr.GameID
Expand All @@ -288,7 +295,7 @@ function getMostRequestedSetsList(array|int|null $console, int $offset, int $cou
/**
* Gets the number of set-less games with at least one set request.
*/
function getGamesWithRequests(array|int|null $console): int
function getGamesWithRequests(array|int|null $console, int $requestStatus = RequestStatus::Any): int
{
$query = "
SELECT
Expand All @@ -300,9 +307,13 @@ function getGamesWithRequests(array|int|null $console): int
LEFT JOIN
GameData gd ON (sr.GameID = gd.ID)
LEFT JOIN
Console c ON (gd.ConsoleID = c.ID)
WHERE
GameID NOT IN (SELECT DISTINCT(GameID) FROM Achievements where Flags = '3') ";
Console c ON (gd.ConsoleID = c.ID) ";

if ($requestStatus !== RequestStatus::Any) {
$query .= "LEFT OUTER JOIN SetClaim sc ON (sr.GameID = sc.GameID AND sc.Status = " . ClaimStatus::Active . ") ";
}

$query .= "WHERE sr.GameID NOT IN (SELECT DISTINCT(GameID) FROM Achievements where Flags = '3') ";

if (is_array($console)) {
$query .= ' AND c.ID IN (' . implode(',', $console) . ') ';
Expand All @@ -311,6 +322,12 @@ function getGamesWithRequests(array|int|null $console): int
$query .= " AND c.ID = $console ";
}

if ($requestStatus === RequestStatus::Claimed) {
$query .= " AND sc.ID IS NOT NULL ";
} elseif ($requestStatus === RequestStatus::Unclaimed) {
$query .= " AND sc.ID IS NULL ";
}

$dbResult = s_mysql_query($query);

if (!$dbResult) {
Expand Down
82 changes: 35 additions & 47 deletions public/setRequestList.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

$username = requestInputSanitized('u');
$selectedConsoleId = (int) request()->input('s');
$selectedRequestStatus = (int) request()->input('x');
$count = (int) request()->input('c', $maxCount);
$offset = (int) request()->input('o', $offset);
$flag = (int) request()->input('f', 0); // 0 - display only active user set requests, else display all user set requests
Expand All @@ -33,14 +34,14 @@
$validConsoles[] = $console['ID'];
}
}
$setRequestList = getMostRequestedSetsList($validConsoles, $offset, $count);
$totalRequestedGames = getGamesWithRequests($validConsoles);
$setRequestList = getMostRequestedSetsList($validConsoles, $offset, $count, $selectedRequestStatus);
$totalRequestedGames = getGamesWithRequests($validConsoles, $selectedRequestStatus);
} elseif ($selectedConsoleId == -1) {
$setRequestList = getMostRequestedSetsList(null, $offset, $count);
$totalRequestedGames = getGamesWithRequests(null);
$setRequestList = getMostRequestedSetsList(null, $offset, $count, $selectedRequestStatus);
$totalRequestedGames = getGamesWithRequests(null, $selectedRequestStatus);
} else {
$setRequestList = getMostRequestedSetsList($selectedConsoleId, $offset, $count);
$totalRequestedGames = getGamesWithRequests($selectedConsoleId);
$setRequestList = getMostRequestedSetsList($selectedConsoleId, $offset, $count, $selectedRequestStatus);
$totalRequestedGames = getGamesWithRequests($selectedConsoleId, $selectedRequestStatus);
}
} else {
$setRequestList = getUserRequestList($username);
Expand All @@ -61,45 +62,31 @@
} else {
echo "Most Requested Sets";
}
echo "</h2><div style='float:left'>$totalRequestedGames Requested Sets</div>";

echo "<div align='right'>";
echo "Filter by console: ";
echo "<td><select class='gameselector' onchange='window.location = \"/setRequestList.php\" + this.options[this.selectedIndex].value'>";
if ($selectedConsoleId == null) {
echo "<option selected>-- Supported Systems --</option>";
} else {
echo "<option value=''>-- Supported Systems --</option>";
}
if ($selectedConsoleId == -1) {
echo "<option selected>-- All Systems --</option>";
} else {
echo "<option value='?s=-1'>-- All Systems --</option>";
}

/** @var System $console */
foreach ($consoles as $console) {
$consoleName = $console->Name;
sanitize_outputs($consoleName);
if ($selectedConsoleId == $console['ID']) {
echo "<option selected>" . $consoleName . "</option>";
} else {
echo "<option value='?s=" . $console['ID'] . "'>" . $consoleName . "</option>";
echo "<a href=\"/setRequestList.php\">" . $consoleName . "</a><br>";
}
}

echo "</td>";
echo "</select>";
echo "</h2>";

echo "<div class='mb-4'>";
echo Blade::render(
'<x-request-list.meta-panel
:consoles="$consoles"
:requestedSetsCount="$totalRequestedGames"
:selectedConsoleId="$selectedConsoleId"
:selectedRequestStatus="$selectedRequestStatus"
/>', [
'consoles' => $consoles,
'totalRequestedGames' => $totalRequestedGames,
'selectedConsoleId' => $selectedConsoleId,
'selectedRequestStatus' => $selectedRequestStatus,
]
);
echo "</div>";

echo "</br><div class='table-wrapper'><table class='table-highlight'><tbody>";
echo "<div class='table-wrapper'><table class='table-highlight'><tbody>";

// Create table headers
echo "<tr class='do-not-highlight'>";
echo "<th>Game</th>";
echo "<th>Claimed By</th>";
echo "<th>Requests</th>";
echo "<th class='text-right'>Requests</th>";
echo "</tr>";

// Loop through each set request and display its information
Expand All @@ -115,30 +102,31 @@
echo "</br>";
}
echo "</td>";
echo "<td><a href='/setRequestors.php?g=" . $request['GameID'] . "'>" . $request['Requests'] . "</a></td>";
echo "<td class='text-right'><a href='/setRequestors.php?g=" . $request['GameID'] . "'>" . $request['Requests'] . "</a></td>";
}
echo "</tbody></table></div>";

// Add page traversal links
echo "<div class='float-right row'>";
$requestStatusParam = "&x=" . $selectedRequestStatus;
if ($offset > 0) {
$prevOffset = $offset - $maxCount;
if (!empty($selectedConsoleId)) {
echo "<a href='/setRequestList.php?s=$selectedConsoleId'>First</a> - ";
echo "<a href='/setRequestList.php?o=$prevOffset&s=$selectedConsoleId'>&lt; Previous $maxCount</a> - ";
echo "<a href='/setRequestList.php?s=$selectedConsoleId$requestStatusParam'>First</a> - ";
echo "<a href='/setRequestList.php?o=$prevOffset&s=$selectedConsoleId$requestStatusParam'>&lt; Previous $maxCount</a> - ";
} else {
echo "<a href='/setRequestList.php'>First</a> - ";
echo "<a href='/setRequestList.php?o=$prevOffset'>&lt; Previous $maxCount</a> - ";
echo "<a href='/setRequestList.php?$requestStatusParam'>First</a> - ";
echo "<a href='/setRequestList.php?o=$prevOffset$requestStatusParam'>&lt; Previous $maxCount</a> - ";
}
}
if ($gameCounter == $maxCount && $offset != $totalRequestedGames - $maxCount) {
$nextOffset = $offset + $maxCount;
if (!empty($selectedConsoleId)) {
echo "<a href='/setRequestList.php?o=$nextOffset&s=$selectedConsoleId'>Next $maxCount &gt;</a>";
echo " - <a href='/setRequestList.php?o=" . ($totalRequestedGames - $maxCount) . "&s=$selectedConsoleId'>Last</a>";
echo "<a href='/setRequestList.php?o=$nextOffset&s=$selectedConsoleId$requestStatusParam'>Next $maxCount &gt;</a>";
echo " - <a href='/setRequestList.php?o=" . ($totalRequestedGames - $maxCount) . "&s=$selectedConsoleId$requestStatusParam'>Last</a>";
} else {
echo "<a href='/setRequestList.php?o=$nextOffset'>Next $maxCount &gt;</a>";
echo " - <a href='/setRequestList.php?o=" . ($totalRequestedGames - $maxCount) . "'>Last</a>";
echo "<a href='/setRequestList.php?o=$nextOffset$requestStatusParam'>Next $maxCount &gt;</a>";
echo " - <a href='/setRequestList.php?o=" . ($totalRequestedGames - $maxCount) . "$requestStatusParam'>Last</a>";
}
}
echo "</div>";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<label class="text-xs font-bold" for="filter-by-console-select">Console</label>
<select id="filter-by-console-id" class="w-full sm:max-w-[240px]" @change="handleConsoleChanged">
@if ($selectedConsoleId === null)
<option selected>Only supported systems</option>
@else
<option value=''>Only supported systems</option>
@endif

@if ($selectedConsoleId == -1)
<option selected>All systems</option>
@else
<option value="-1">All systems</option>
@endif

@foreach ($consoles as $console)
@if ($selectedConsoleId == $console['ID'])
<option selected>{{ $console->Name }}</option>
@else
<option value="{{ $console['ID'] }}">{{ $console->Name }}</option>
@endif
@endforeach
</select>
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<script>
/**
* Updates a query parameter in the current URL and navigates to the new URL.
*
* @param {string} paramName - The name of the query parameter to update.
* @param {string} newQueryParamValue - The new value for the query parameter.
*/
function updateUrlParameter(paramName, newQueryParamValue) {
const url = new URL(window.location.href);
const params = new URLSearchParams(url.search);
params.set(paramName, newQueryParamValue);
url.search = params.toString();
window.location.href = url.toString();
}
/**
* Event handler for 'Filter by console' selection change event.
* Updates 's' query parameter in the URL based on selected option.
*
* @param {Event} event - The select change event.
*/
function handleConsoleChanged(event) {
const newQueryParamValue = event.target.value;
updateUrlParameter('s', newQueryParamValue);
}
/**
* Event handler for 'Filter by request status' selection change event.
* Updates 'x' query parameter in the URL based on selected option.
*
* @param {Event} event - The select change event.
*/
function handleRequestStatusChanged(event) {
const newQueryParamValue = event.target.value;
updateUrlParameter('x', newQueryParamValue);
}
</script>

@props([
'consoles' => [],
'requestedSetsCount' => 0,
'selectedConsoleId' => null,
'selectedRequestStatus' => null,
])

<div x-init="{}">
<p class="text-lg mb-2">{{ localized_number($requestedSetsCount) }} Requested Sets</p>

<div class="embedded p-4 my-4 w-full">
<p class="sr-only">Filters</p>

<div class="grid sm:flex gap-y-4 sm:divide-x-2 divide-embed-highlight">
<div class="grid gap-y-1 sm:pr-[40px]">
<x-request-list.meta-console-filter
:consoles="$consoles"
:selectedConsoleId="$selectedConsoleId"
/>
</div>

<div class="grid gap-y-1 sm:px-8">
<x-request-list.meta-request-status-filter
:selectedRequestStatus="$selectedRequestStatus"
/>
</div>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
use App\Community\Enums\RequestStatus;
$any = RequestStatus::Any;
?>

@props([
'selectedRequestStatus' => $any,
'value' => $any,
])

<label class="transition lg:active:scale-95 cursor-pointer flex items-center gap-x-1 text-xs">
<input type="radio" class="cursor-pointer" name="request-status" value="{{ $value }}" {{ $selectedRequestStatus == $value ? 'checked' : '' }} @change="handleRequestStatusChanged">
{{ $slot }}
</label>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
use App\Community\Enums\RequestStatus;
$any = RequestStatus::Any;
$claimed = RequestStatus::Claimed;
$unclaimed = RequestStatus::Unclaimed;
?>

<label class="text-xs font-bold sm:-mb-6">Request status</label>
<div class="space-x-4 flex" id="filter-by-request-status">
<x-request-list.meta-request-status-filter-radio value="{{ $any }}" :selectedRequestStatus="$selectedRequestStatus">
Any
</x-request-list.meta-request-status-filter-radio>

<x-request-list.meta-request-status-filter-radio value="{{ $claimed }}" :selectedRequestStatus="$selectedRequestStatus">
Claimed
</x-request-list.meta-request-status-filter-radio>

<x-request-list.meta-request-status-filter-radio value="{{ $unclaimed }}" :selectedRequestStatus="$selectedRequestStatus">
Unclaimed
</x-request-list.meta-request-status-filter-radio>
</div>

0 comments on commit df6483c

Please sign in to comment.