feature(tags): added tags to pois

This commit is contained in:
Uther
2024-08-21 18:57:36 +02:00
parent 32fafa370c
commit 9a00582d44
5 changed files with 116 additions and 9 deletions

View File

@@ -4,6 +4,59 @@ namespace App\Data;
use Carbon\Carbon;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Collection;
enum AttractionTypeTag: string
{
case Children = 'ATTRACTION_TYPE_CHILDREN';
case MindTheSizeChart = 'ATTRACTION_TYPE_MIND_THE_SIZE_CHART';
case Family = 'ATTRACTION_TYPE_FAMILY';
case Roofed = 'ATTRACTION_TYPE_ROOFED';
case Pictures = 'ATTRACTION_TYPE_PICTURES';
case QuickPass = 'ATTRACTION_TYPE_QUICK_PASS';
case Action = 'ATTRACTION_TYPE_ACTION';
case QuickPassPlus = 'ATTRACTION_TYPE_QUICK_PASS_PLUS';
case SingleRiderLine = 'ATTRACTION_TYPE_SINGLE_RIDER_LINE';
case Water = 'ATTRACTION_TYPE_WATER';
case NoOperationSubNegative5 = 'ATTRACTION_NO_OPERATION_SUB_NEGATIVE_5';
case NoOperationSubZero = 'ATTRACTION_NO_OPERATION_SUB_ZERO';
case ChildrenMayScare = 'ATTRACTION_TYPE_CHILDREN_MAY_SCARE';
}
enum AttractionTypeEmote: string
{
case Children = '👶';
case MindTheSizeChart = '📏';
case Family = '👨‍👩‍👧‍👦';
case Roofed = '🏠';
case Pictures = '📸';
case QuickPass = '🎟️';
case Action = '🔥';
case QuickPassPlus = '🎟️+';
case SingleRiderLine = '🚶‍♂️';
case Water = '💧';
case NoOperationSubNegative5 = '🚫 -5';
case NoOperationSubZero = '🚫 0';
case ChildrenMayScare = '👻';
}
enum AttractionTypeTagDescription: string
{
case Children = 'Attraktion für Kinder';
case MindTheSizeChart = 'Achtung Größenbeschränkung';
case Family = 'Attraktion für die ganze Familie';
case Roofed = 'Überdachte Attraktion';
case Pictures = 'Attraktion mit Fotomöglichkeit';
case QuickPass = 'Attraktion mit Quick Pass';
case Action = 'Actionreiche Attraktion';
case QuickPassPlus = 'Attraktion mit Quick Pass Plus';
case SingleRiderLine = 'Attraktion mit Single Rider Line';
case Water = 'Wasserattraktion';
case NoOperationSubNegative5 = 'Attraktion hat bei -5°C oder kälter geschlossen';
case NoOperationSubZero = 'Attraktion hat bei 0°C oder kälter geschlossen';
case ChildrenMayScare = 'Attraktion könnte Kinder erschrecken';
}
readonly class PointOfInterest implements Arrayable
{
@@ -60,6 +113,32 @@ readonly class PointOfInterest implements Arrayable
return Carbon::parse($this->info['opening'], 'Europe/Berlin');
}
public function hasTag(AttractionTypeTag $tag): bool
{
return in_array($tag, $this->tags);
}
public function getTagEmote(AttractionTypeTag $tag): AttractionTypeEmote
{
$emotes = collect(AttractionTypeEmote::cases());
$emote = $emotes->first(fn($emote) => $emote->name === $tag->name);
return $emote;
}
public function getTags(): Collection
{
return collect($this->tags)->map(function ($tag) {
return AttractionTypeTag::from($tag);
});
}
public function getTagDescription(AttractionTypeTag $tag): string
{
$descriptions = collect(AttractionTypeTagDescription::cases());
$description = $descriptions->first(fn($description) => $description->name === $tag->name);
return $description->value;
}
public function toArray()
{
return [

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Http\Services;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;
class CaptianCosterApi
{
private readonly string $uri;
private readonly PendingRequest $client;
function __construct()
{
if(!($apiKey = env('CAPTAIN_COASTER_API_KEY'))) {
throw new \Exception('No API key found for Captain Coaster API');
}
$this->uri = 'https://captaincoaster.com/api/';
$this->client = Http::baseUrl($this->uri)->withHeaders([
'Authorization' => $apiKey
]);
}
}

View File

@@ -7,7 +7,6 @@ use App\Models\ThemeParkUser;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Http;
use Psr\Http\Message\RequestInterface;
class PhantasialandApi
{
@@ -33,7 +32,9 @@ class PhantasialandApi
// NOTE: we filter everything out that is adminOnly = true
$pois = $pois->filter(function ($poi) {
return $poi['category'] === 'ATTRACTIONS' && $poi['adminOnly'] === false &&
$poi['poiNumber'] !== null;
$poi['poiNumber'] !== null &&
$poi["parkMonitorReferenceName"] !== null &&
in_array('SUMMER', $poi['seasons']);
});
// sort by parkMonitorReferenceName

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PhantaApp lul 3000</title>
<title>PhantaApp</title>
@vite('resources/css/app.css')
</head>
<body class="bg-gray-500">

View File

@@ -27,12 +27,15 @@
{{ $poi->description }}
</p>
</div>
<div class="p-6 pt-0">
<!-- <button
class="align-middle select-none font-sans font-bold text-center uppercase transition-all disabled:opacity-50 disabled:shadow-none disabled:pointer-events-none text-xs py-3 px-6 rounded-lg bg-gray-900 text-white shadow-md shadow-gray-900/10 hover:shadow-lg hover:shadow-gray-900/20 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none"
type="button">
Read More
</button> -->
<div class="p-6 pt-0 flex text-sm items-end flex-1 gap-1">
@foreach($poi->getTags() as $tag)
<span class="relative group px-2 py-1 text-xs font-bold text-white bg-blue-500 rounded-full">
{{ $poi->getTagEmote($tag) }}
<span class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 hidden group-hover:block px-2 py-1 text-xs text-white bg-black rounded">
{{ $poi->getTagDescription($tag) }}
</span>
</span>
@endforeach
</div>
</div>
@endforeach