xmbohx
xmbohx

Reputation: 69

How to make my calendar table display a guest stay as a single 'entry' in a row instead of two separate entries

I am trying to make a room availability chart or calendar, with the expected result as follows:

Room availability chart

Each date has two columns with AM and PM as headers. AM indicates Check-In while PM indicates Check-out. I made this two columns because there will be cases where a room will have a check-out guest and continue with a different check-in guest.

Now I need to render the table to see the period of guest stays by spanning the cells based on the stay's date and the stay's number of nights.

Here is my $guest data and the full code:

<?php
// Room data
$rooms = [
    ['room' => '1001', 'type' => 'King'],
    ['room' => '1002', 'type' => 'Hollywood'],
    ['room' => '1003', 'type' => 'Queen'],
    ['room' => '1004', 'type' => 'Queen'],
    ['room' => '1005', 'type' => 'Queen'],
];

// Generate all dates for December 2024
$dates = [];
$start = new DateTime('2024-12-01');
$end = new DateTime('2025-01-01'); // 1 day after the last day of December 2024

while ($start < $end) {
    $dates[] = $start->format('Y-m-d'); // Add date in 'Y-m-d' format
    $start->add(new DateInterval('P1D')); // Increment by 1 day
}

// Guest data

 $guests = [
    ['room' => '1001', 'stays' => [['guest' => 'Juna', 'checkin' => '2024-12-05', 'checkout' => '2024-12-06', 'nights' => '1']]],
    ['room' => '1001', 'stays' => [['guest' => 'Mila', 'checkin' => '2024-12-06', 'checkout' => '2024-12-08', 'nights' => '2']]],
    ['room' => '1001', 'stays' => [['guest' => 'Tom', 'checkin' => '2024-12-08', 'checkout' => '2024-12-12', 'nights' => '4']]],
    ['room' => '1001', 'stays' => [['guest' => 'Aman', 'checkin' => '2024-12-01', 'checkout' => '2024-12-04', 'nights' => '3']]],
    ['room' => '1002', 'stays' => [['guest' => 'Tina', 'checkin' => '2024-12-01', 'checkout' => '2024-12-03', 'nights' => '2']]],
    ['room' => '1002', 'stays' => [['guest' => 'Dina', 'checkin' => '2024-12-03', 'checkout' => '2024-12-06', 'nights' => '3']]],
]

?>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Stay Table</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
        }

        table {
            width: 800px;
            border-collapse: collapse;
            margin-top: 20px;
        }

        th,
        td {
            border: 1px solid #ddd;
            padding: 10px;
            text-align: center;
            width: 80px;
        }

        th {
            background-color: #f2f2f2;
            font-weight: bold;
        }

        .date-header {
            background-color: #f2f2f2;
            font-weight: bold;
        }

        .stay-cell-1 {
            background-color: #e0f7fa;
        }

        .stay-cell-2 {
            background-color: #ffebee;
        }

        .stay-cell-a,
        .stay-cell-b {
            border: none;
            padding: 0;
        }

        .internal-table {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            border-collapse: collapse;
        }

        .internal-table td {
            background-color: #80deea;
            height: 25px;
            border: none;
            text-align: center;
        }
    </style>
</head>

<body>

    <table>
        <!-- Header Row -->
        <tr>
            <th class="left-header">Room</th>
            <th class="left-header">Type</th>
            <?php foreach ($dates as $date): ?>
                <th class="date-header" colspan="2"><?= date('d-M', strtotime($date)) ?></th>
            <?php endforeach; ?>
        </tr>

        <!-- Data Rows -->
        <?php foreach ($rooms as $room): ?>
            <tr>
                <td class="left-header"><?= $room['room'] ?></td>
                <td class="left-header"><?= $room['type'] ?></td>
                <?php
                $skipUntil = null;
                foreach ($dates as $date):
                    if ($skipUntil && $date <= $skipUntil) {
                        continue;
                    }
                    $guestCI = '';
                    $guestCO = '';
                    $colspan = 1;
                    $isOccupied = false;
                    foreach ($guests as $guest) {
                        if ($guest['room'] == $room['room']) {
                            foreach ($guest['stays'] as $stay) {
                                if ($date == $stay['checkin']) {
                                    $guestCI = $stay['guest'];
                                    $colspan = ($stay['nights'] * 2) - 1;
                                    $skipUntil = date('Y-m-d', strtotime("$date +" . ($stay['nights'] - 1) . " days"));
                                    $isOccupied = true;
                                }
                                if ($date == $stay['checkout']) {
                                    $guestCO = $stay['guest'];
                                    $isOccupied = true;
                                }
                            }
                        }
                    }
                ?>
                    <td class="stay-cell-1"> <?= $guestCO ?: '&nbsp;' ?> </td>
                    <?php if ($guestCI) : ?>
                        <td class="stay-cell-2" colspan="<?= $colspan ?>"> <?= $guestCI ?> </td>
                    <?php elseif (!$isOccupied) : ?>
                        <td>&nbsp;</td>
                    <?php else: ?>
                        <td></td>
                    <?php endif; ?>
                <?php endforeach; ?>
            </tr>
        <?php endforeach; ?>
    </table>
</body>
</html>

Taking this example: ['room' => '1001', 'stays' => [['guest' => 'Aman', 'checkin' => '2024-12-01', 'checkout' => '2024-12-04', 'nights' => '3']]], the period of stay is supposed to be rendered from 1-Dec PM cell to 4-Dec AM cell.

enter image description here

How can I achieve the desired outcome where Aman's stay is showing as one entry instead of two as shown in the chart above? And so on for the others (compare this image to the correct display shown in the spreadsheet image at the top of the question).

If an HTML table is not correct, I am OK if there is another approach.

Upvotes: 1

Views: 102

Answers (0)

Related Questions