Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add gameshard api #70

Merged
merged 11 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions app/Http/ExternalApi/GameshardApi.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace App\Http\ExternalApi;

use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Http;

class GameshardApi
{
private string $gameshardToken;

public function __construct()
{
$this->gameshardToken = config('services.gameshard.api_key');
}

/**
* @throws RequestException
*/
public function pullRoundsIds(string $tournamentId, string $phaseId): Collection
{
$rounds = Http::acceptJson()
->withToken($this->gameshardToken)
->get("https://gameshard.io/api/tournaments/$tournamentId/phases/$phaseId/rounds")
->throw()
->json('data');

return collect($rounds)->pluck('id');
}

/**
* @throws RequestException
*/
public function pullMatchesFromRoundId(string $roundId)
{
return Http::withToken($this->gameshardToken)
->get("https://gameshard.io/api/matches?filter[round_id]=$roundId")
->throw()
->json('data');
}

/**
* @throws RequestException
*/
public function pullMatchesIdsFromRoundId(string $roundId): Collection
{
$matches = $this->pullMatchesFromRoundId($roundId);

return collect($matches)->pluck('id');
}

/**
* @throws RequestException
*/
public function pullGames(string $matchId): Collection
{
$games = Http::acceptJson()
->withToken($this->gameshardToken)
->get("https://gameshard.io/api/matches/$matchId/games")
->throw()
->json('data');

return collect($games);
}
}
61 changes: 31 additions & 30 deletions app/Livewire/Rankings.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,57 +2,51 @@

namespace App\Livewire;

use App\Http\ExternalApi\GameshardApi;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Livewire\Component;

class Rankings extends Component
{
public Collection $rankings;

public string $year = '2021';
public string $year = '2023';

public bool $killcache = false;

protected $queryString = [
'killcache' => ['except' => false],
];

public function mount()
public function mount(GameshardApi $gameShardApi): void
{
if ($this->killcache) {
Cache::forget('rankings' . $this->year);
}

$tournamentLink = match ($this->year) {
default => 'https://gameshard.io/api/tournaments/75/phases/47/rounds'
[$tournamentUuid, $phaseUuid] = match ($this->year) {
'2020' => ['f6d9cf5f-9c31-44c6-8693-b99d769b929c', 'ef76c5d2-757b-4ff3-8109-41ea0c1dbb3b'],
'2021' => ['1f13aad9-0459-448a-b14b-537bbf4cfc6f', 'a64424d6-f061-4e12-bc28-2d967040c2c3'],
'2022' => ['b873126e-ad58-48e0-8a39-e43b2adf35e6', '7c786925-e76e-4b85-b6fb-91c148fa8a1b'],
default => ['98bfa269-4fce-4bb1-84c7-7ba0ed4d1da0', '98bfa734-0f8c-4949-a352-c7e8654f50d3']
};

/** @var Collection $rankings */
$rankings = Cache::rememberForever('rankings' . $this->year, function () use ($tournamentLink) {
$playday = Http::withHeaders([
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . config('services.gameshard.api_key'),
])->get($tournamentLink);

$playdayIds = collect($playday->json('data'))->pluck('id');

$matchesIds = collect([]);
$playdayIds->each(fn ($playday) => $matchesIds->push(collect(Http::withHeaders([
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . config('services.gameshard.api_key'),
])->get("https://gameshard.io/api/matches?filter[round_id]=$playday")->json('data'))->pluck('id')));

$gameIds = collect([]);
$matchesIds->flatten()->each(fn ($match) => $gameIds->push(collect(Http::withHeaders([
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . config('services.gameshard.api_key'),
])->get("https://gameshard.io/api/matches/$match/games")->json('data'))));
$rankings = Cache::rememberForever('rankings' . $this->year, function () use ($gameShardApi, $tournamentUuid, $phaseUuid) {

$playDaysIds = $gameShardApi->pullRoundsIds($tournamentUuid, $phaseUuid);

$matchesIds = collect();
$playDaysIds->each(fn (string $playDayId) => $matchesIds->push($gameShardApi->pullMatchesIdsFromRoundId($playDayId)));

$allGames = collect();
$matchesIds->flatten()->each(fn ($matchId) => $allGames->push($gameShardApi->pullGames($matchId)));

// Inizializzo rankings a 0
$games = $gameIds->filter(fn (Collection $game) => $game->first()['played_at']);
$games = $allGames->filter(fn (Collection $game) => $game->first()['played_at']);
$rankings = [];
foreach ($games as $game) {
$game = $game->first();
Expand All @@ -77,8 +71,14 @@ public function mount()
*/
foreach ($games as $game) {
$game = $game->first();
$homeContestant = $game['contestants'][0];
$awayContestant = $game['contestants'][1];
$homeContestant = Arr::get($game['contestants'], 0, null);
if (! $homeContestant) {
continue;
}
$awayContestant = Arr::get($game['contestants'], 1, null);
if (! $awayContestant) {
continue;
}
if ((int) $homeContestant['score'] + (int) $awayContestant['score'] > 12) {
// Overt Time
if ($homeContestant['score'] > $awayContestant['score']) {
Expand All @@ -101,8 +101,8 @@ public function mount()
}

/**
* tempi regolamentari +3 punti alla squadra vincitrice e +0 alla squadra perdente
* tempi supplementari +2 punti alla squadra vincitrice e +1 punto alla squadra perdente.
* Tempi regolamentari +3 punti alla squadra vincitrice e +0 alla squadra perdente
* Tempi supplementari +2 punti alla squadra vincitrice e +1 punto alla squadra perdente.
*/
foreach ($rankings as $index => $ranking) {
$rankings[$index]['points'] = ($ranking['win'] * 3) + ($ranking['loss'] * 0) + ($ranking['ot_win'] * 2) + ($ranking['ot_loss'] * 1);
Expand Down Expand Up @@ -130,6 +130,7 @@ public function getTrophyColor(int $position): string

public function render(): View
{
return view('livewire.rankings');
return view('livewire.rankings')
->layout('layouts.guest');
}
}
2 changes: 1 addition & 1 deletion resources/views/campionato.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<div class="space-y-12">
<div class="space-y-5 sm:space-y-4 md:max-w-xl lg:max-w-3xl xl:max-w-none">
<h2 class="text-3xl font-extrabold tracking-tight sm:text-4xl">Teams</h2>
<p class="text-xl text-gray-500">Scopri chi fa parte del BeSerious 2022</p>
<p class="text-xl text-gray-500">Scopri chi fa parte del BeSerious 2023</p>
</div>
<ul
class="space-y-12 sm:grid sm:grid-cols-2 sm:gap-x-6 sm:gap-y-12 sm:space-y-0 lg:grid-cols-4 lg:gap-x-8">
Expand Down
71 changes: 66 additions & 5 deletions resources/views/components/hero.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,40 @@ class="inline-flex items-center justify-center rounded-md bg-gray-50 p-2 text-gr
<a class="font-medium text-gray-500 hover:text-gray-900" href="{{ route('chi-siamo') }}">Chi
Siamo</a>

<a class="font-medium text-gray-500 hover:text-gray-900" href="{{ route('campionato.2022') }}">Be
Serious 2022</a>
<a class="font-medium text-gray-500 hover:text-gray-900"
href="{{ route('campionato-corrente') }}">Be
Serious 2023</a>

<div class="relative" x-data="{ open: false }" @click.outside="open = false">
<button
class="inline-flex items-center gap-x-1 font-medium leading-6 text-gray-500 hover:text-gray-900"
type="button" aria-expanded="false" @click="open =! open">
<span>Campionati Precedenti</span>
<svg class="h-5 w-5" aria-hidden="true" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd"
d="M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z"
clip-rule="evenodd" />
</svg>
</button>

<div class="absolute left-1/2 z-10 mt-5 flex w-screen max-w-min -translate-x-1/2 px-4"
x-show="open" x-cloak x-transition:enter="transition ease-out duration-200"
x-transition:enter-start="opacity-0 translate-y-1"
x-transition:enter-end="opacity-100 translate-y-0"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="opacity-100 translate-y-0"
x-transition:leave-end="opacity-0 translate-y-1">
<div
class="w-56 shrink rounded-xl bg-white p-4 text-sm font-semibold leading-6 text-gray-500 shadow-lg ring-1 ring-gray-900/5">
<a class="block p-2 hover:text-gray-900"
href="{{ route('campionato-anno', 2022) }}">BeSerious 2022</a>
<a class="block p-2 hover:text-gray-900"
href="{{ route('campionato-anno', 2021) }}">BeSerious 2021</a>
<a class="block p-2 hover:text-gray-900"
href="{{ route('campionato-anno', 2020) }}">BeSerious 2020</a>
</div>
</div>
</div>

<a class="font-medium text-gray-500 hover:text-gray-900" href="{{ route('twitch') }}">Twitch</a>
</div>
Expand Down Expand Up @@ -121,7 +153,36 @@ class="inline-flex items-center justify-center rounded-md bg-white p-2 text-gray
href="{{ route('chi-siamo') }}">Chi Siamo</a>

<a class="block rounded-md px-3 py-2 text-base font-medium text-gray-700 hover:bg-gray-50 hover:text-gray-900"
href="{{ route('campionato.2022') }}">Be Serious 2022</a>
href="{{ route('campionato-corrente') }}">Be Serious 2023</a>

<div x-data="{ campionatiIsOpen: false }">
<button
class="flex w-full items-center justify-between rounded-md py-2 pl-3 pr-3.5 text-base font-medium leading-7 text-gray-700 hover:bg-gray-50 hover:text-gray-900"
type="button" aria-controls="disclosure-1" aria-expanded="false"
@click="campionatiIsOpen =! campionatiIsOpen">
Campionati precedenti
<!--
Expand/collapse icon, toggle classes based on menu open state.

Open: "rotate-180", Closed: ""
-->
<svg class="h-5 w-5 flex-none" aria-hidden="true"
:class="campionatiIsOpen ? 'rotate-180' : ''" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd"
d="M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z"
clip-rule="evenodd" />
</svg>
</button>
<!-- 'Campionati precedenti' sub-menu, show/hide based on menu state. -->
<div class="mt-2 space-y-2" id="disclosure-1" x-show="campionatiIsOpen" x-cloak>
<a class="block rounded-lg py-2 pl-6 pr-3 text-sm font-medium text-gray-700 hover:bg-gray-50 hover:text-gray-900"
href="{{ route('campionato-anno', 2022) }}">BeSerious 2022</a>
<a class="block rounded-lg py-2 pl-6 pr-3 text-sm font-medium text-gray-700 hover:bg-gray-50 hover:text-gray-900"
href="{{ route('campionato-anno', 2021) }}">BeSerious 2021</a>
<a class="block rounded-lg py-2 pl-6 pr-3 text-sm font-medium text-gray-700 hover:bg-gray-50 hover:text-gray-900"
href="{{ route('campionato-anno', 2020) }}">BeSerious 2020</a>
</div>
</div>

<a class="block rounded-md px-3 py-2 text-base font-medium text-gray-700 hover:bg-gray-50 hover:text-gray-900"
href="{{ route('twitch') }}">Twitch</a>
Expand Down Expand Up @@ -169,8 +230,8 @@ class="inline-flex items-center justify-center rounded-md bg-white p-2 text-gray
</div>
<div class="mt-3 rounded-md shadow sm:ml-3 sm:mt-0">
<a class="flex w-full items-center justify-center rounded-md border border-transparent bg-white px-8 py-3 text-base font-medium text-red-600 hover:bg-gray-50 md:px-10 md:py-4 md:text-lg"
href="{{ route('campionato.2022') }}">
Campionato 2022
href="{{ route('campionato-corrente') }}">
Campionato 2023
</a>
</div>
</div>
Expand Down
Loading