feat: redesign tickets main view and basket view with improved styles and layout
- Updated SCSS for tickets main view and basket view, enhancing visual design and responsiveness. - Added new calendar functionality in the admin panel for managing ticket availability. - Implemented error handling for ticket availability in the basket view. - Introduced a new calendar availability table in the database for tracking ticket dates. - Added a new link to the calendar in the logged-in user navigation. - Improved ticket selection logic to disable unavailable tickets in the main view. - Created guidelines for code standards in AGENTS.md.
This commit is contained in:
@@ -1,6 +1,203 @@
|
||||
<?php
|
||||
namespace factory;
|
||||
class Tickets {
|
||||
private static $calendarTableReady = false;
|
||||
private static $allowedDateCache = [];
|
||||
|
||||
static public function getCalendarDefinitions()
|
||||
{
|
||||
return [
|
||||
'park-rozrywki' => [
|
||||
'label' => 'Park rozrywki i dinozaurów + bilety prezentowe',
|
||||
'ticket_ids' => [
|
||||
'plac-zabaw-ulgowy',
|
||||
'plac-zabaw-normalny',
|
||||
'gift-plac-zabaw-ulgowy',
|
||||
'gift-plac-zabaw-normalny',
|
||||
],
|
||||
],
|
||||
'park-wodny' => [
|
||||
'label' => 'Park wodny',
|
||||
'ticket_ids' => [
|
||||
'park-wodny-ulgowy',
|
||||
'park-wodny-normalny',
|
||||
],
|
||||
],
|
||||
'all-open' => [
|
||||
'label' => 'All Open + bilety prezentowe',
|
||||
'ticket_ids' => [
|
||||
'bilet-all-open-ulgowy',
|
||||
'bilet-all-open-normalny',
|
||||
'gift-bilet-all-open-ulgowy',
|
||||
'gift-bilet-all-open-normalny',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
static public function ensureCalendarTable()
|
||||
{
|
||||
global $mdb;
|
||||
|
||||
if (self::$calendarTableReady) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sql = "CREATE TABLE IF NOT EXISTS ticket_calendar_availability (
|
||||
ticket_group VARCHAR(64) NOT NULL,
|
||||
available_date DATE NOT NULL,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (ticket_group, available_date)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8";
|
||||
|
||||
$mdb->pdo->exec($sql);
|
||||
self::$calendarTableReady = true;
|
||||
}
|
||||
|
||||
static public function normalizeDateFromPicker($date)
|
||||
{
|
||||
$date = trim((string) $date);
|
||||
if ($date === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$formats = ['d-m-Y', 'Y-m-d'];
|
||||
foreach ($formats as $format) {
|
||||
$parsedDate = \DateTime::createFromFormat($format, $date);
|
||||
if ($parsedDate && $parsedDate->format($format) === $date) {
|
||||
return $parsedDate->format('Y-m-d');
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static public function getCalendarGroupForTicket($ticketId)
|
||||
{
|
||||
foreach (self::getCalendarDefinitions() as $groupKey => $group) {
|
||||
if (in_array($ticketId, $group['ticket_ids'], true)) {
|
||||
return $groupKey;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static public function getEnabledDatesByGroup($groupKey)
|
||||
{
|
||||
global $mdb;
|
||||
|
||||
self::ensureCalendarTable();
|
||||
$definitions = self::getCalendarDefinitions();
|
||||
|
||||
if (!isset($definitions[$groupKey])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$statement = $mdb->pdo->prepare(
|
||||
"SELECT available_date
|
||||
FROM ticket_calendar_availability
|
||||
WHERE ticket_group = :ticket_group
|
||||
ORDER BY available_date ASC"
|
||||
);
|
||||
$statement->execute([':ticket_group' => $groupKey]);
|
||||
|
||||
$rows = $statement->fetchAll(\PDO::FETCH_ASSOC);
|
||||
if (!is_array($rows)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return array_values(array_filter(array_map(static function ($row) {
|
||||
return $row['available_date'] ?? null;
|
||||
}, $rows)));
|
||||
}
|
||||
|
||||
static public function saveEnabledDatesForGroup($groupKey, array $dates)
|
||||
{
|
||||
global $mdb;
|
||||
|
||||
self::ensureCalendarTable();
|
||||
$definitions = self::getCalendarDefinitions();
|
||||
|
||||
if (!isset($definitions[$groupKey])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$normalizedDates = [];
|
||||
foreach ($dates as $date) {
|
||||
$normalizedDate = self::normalizeDateFromPicker($date);
|
||||
if (!$normalizedDate) {
|
||||
continue;
|
||||
}
|
||||
$normalizedDates[$normalizedDate] = $normalizedDate;
|
||||
}
|
||||
|
||||
$normalizedDates = array_values($normalizedDates);
|
||||
|
||||
$mdb->pdo->beginTransaction();
|
||||
try {
|
||||
$deleteStatement = $mdb->pdo->prepare(
|
||||
"DELETE FROM ticket_calendar_availability WHERE ticket_group = :ticket_group"
|
||||
);
|
||||
$deleteStatement->execute([':ticket_group' => $groupKey]);
|
||||
|
||||
if (!empty($normalizedDates)) {
|
||||
$insertStatement = $mdb->pdo->prepare(
|
||||
"INSERT INTO ticket_calendar_availability (ticket_group, available_date)
|
||||
VALUES (:ticket_group, :available_date)"
|
||||
);
|
||||
|
||||
foreach ($normalizedDates as $date) {
|
||||
$insertStatement->execute([
|
||||
':ticket_group' => $groupKey,
|
||||
':available_date' => $date,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$mdb->pdo->commit();
|
||||
} catch (\Exception $exception) {
|
||||
$mdb->pdo->rollBack();
|
||||
return false;
|
||||
}
|
||||
|
||||
self::$allowedDateCache = [];
|
||||
return true;
|
||||
}
|
||||
|
||||
static public function canBuyTicketOnDate($ticketId, $date)
|
||||
{
|
||||
$groupKey = self::getCalendarGroupForTicket($ticketId);
|
||||
if (!$groupKey) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$normalizedDate = self::normalizeDateFromPicker($date);
|
||||
if (!$normalizedDate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cacheKey = $groupKey . '|' . $normalizedDate;
|
||||
if (array_key_exists($cacheKey, self::$allowedDateCache)) {
|
||||
return self::$allowedDateCache[$cacheKey];
|
||||
}
|
||||
|
||||
$enabledDates = self::getEnabledDatesByGroup($groupKey);
|
||||
$isAllowed = in_array($normalizedDate, $enabledDates, true);
|
||||
self::$allowedDateCache[$cacheKey] = $isAllowed;
|
||||
|
||||
return $isAllowed;
|
||||
}
|
||||
|
||||
static public function getTicketAvailabilityForDate(array $ticketIds, $date)
|
||||
{
|
||||
$availability = [];
|
||||
foreach ($ticketIds as $ticketId) {
|
||||
$availability[$ticketId] = self::canBuyTicketOnDate($ticketId, $date);
|
||||
}
|
||||
|
||||
return $availability;
|
||||
}
|
||||
|
||||
static public function recalculate_ticket_protection( $basket ) {
|
||||
global $settings;
|
||||
@@ -110,4 +307,4 @@ class Tickets {
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user