Przykładowa strona

Przykładowa strona. Strony są inne niż wpisy na blogu, ponieważ nie tylko znajdują się zawsze w jednym miejscu, ale także pojawiają się w menu witryny (w większości motywów). Większość użytkowników zaczyna od strony z informacjami o sobie, która zapozna ich przed odwiedzającymi witrynę. Taka strona może zawierać na przykład taką treść:

Cześć! Za dnia jestem kurierem rowerowym, nocą próbuję swoich sił w aktorstwie, a to jest moja witryna. Mieszkam w Krakowie, mam wspaniałego psa który wabi się Reks i lubię piña coladę (oraz spacery, gdy pada deszcz).

…albo coś takiego:

Firma XYZ Doohickey została założona w 1971 roku i od tamtej pory dostarcza społeczeństwu dobrej jakości gadżety. Znajdująca się w Gotham City XYZ zatrudnia ponad 2000 osób i robi niesamowite rzeczy dla społeczności Gotham.

Jako nowy użytkownik WordPressa, powinieneś przejść do swojego kokpitu aby usunąć tę stronę i stworzyć nowe z własną treścią. Dobrej zabawy!

[kalendarz_resjestracji]
				
					console.log( 'Code is Poetry' );<?php
/*
Plugin Name: Rezerwacje Kalendarz
Description: Prosty system rezerwacji godzinowych z widocznością dla innych użytkowników i anulacją tylko przez właściciela.
Version: 1.0
Author: OpenAI
*/

add_shortcode('rezerwacje_kalendarz', 'rezerwacje_kalendarz_shortcode');
function rezerwacje_kalendarz_shortcode() {
    if (!is_user_logged_in()) {
        return '<p>Musisz być <a href="' . wp_login_url() . '">zalogowany</a>, aby dokonać rezerwacji.</p>';
    }

    ob_start();
    ?>
    <style>
      #calendar-container { overflow-x: auto; white-space: nowrap; font-family: Arial, sans-serif; }
      table { border-collapse: collapse; margin-top: 10px; }
      th, td { border: 1px solid #ccc; text-align: center; min-width: 100px; height: 35px; }
      th { background-color: #4682b4; position: sticky; top: 0; z-index: 1; }
      td.time { background-color: #eee; font-weight: bold; }
      td.slot:hover { cursor: pointer; background-color: #e0f7fa; }
      td.slot.selected, td.taken.mine { background-color: #4caf50; color: white; }
      td.taken { background-color: #999; color: white; }
      td.locked { pointer-events: none; opacity: 0.5; }
      #controls { margin-bottom: 10px; }
      .input_date {
          border: 2px solid #B5B5B5; !important;
          float: left;
          font-size: 14px;
          display: inline-block;
          height: 38px;
          padding: 7px;
          background-color: #ffffff;
          box-shadow: inset 0 1px 3px #dddddd;
          border-radius: 6px;
          box-sizing: border-box;
          margin-right: 20px;
      }
      .button_show {
          background-color: #B5B5B5;
          border: 2px solid #B5B5B5;
          padding: 9px 30px;
          color: #FFFFFF;
          border-radius: 6px;
          font-weight: bold;
          font-size: 14px;
          text-align: center;
          cursor: pointer; }
      .button_show:hover {
          color: #B5B5B5;
          background-color: #FFFFFF;}
    </style>

    <div id="controls">
      <input class="input_date" type="date" id="date-start" value="<?php echo date('Y-m-d'); ?>" min="<?php echo date('Y-m-d'); ?>" max="<?php echo date('Y-m-d', strtotime('+2 years')); ?>">
      <button class="button_show" onclick="generateCalendar()">Pokaż</button>
    </div>

    <div id="calendar-container"></div>

    <script>
      const ajaxurl = '<?php echo admin_url("admin-ajax.php"); ?>';
      const currentUserId = <?php echo get_current_user_id(); ?>;

      const timeSlots = (() => {
        const slots = [];
        let hour = 8, minute = 0;
        while (hour < 24) {
          const h = String(hour).padStart(2, '0');
          const m = String(minute).padStart(2, '0');
          slots.push(`${h}:${m}`);
          minute += 30;
          if (minute >= 60) { hour++; minute = 0; }
        }
        return slots;
      })();

      function generateCalendar() {
        const container = document.getElementById('calendar-container');
        container.innerHTML = "";

        const startDate = new Date(document.getElementById('date-start').value);
        const daysToShow = 7;

        const table = document.createElement('table');
        const headerRow = document.createElement('tr');

        const emptyHeader = document.createElement('th');
        headerRow.appendChild(emptyHeader);

        for (let i = 0; i < daysToShow; i++) {
          const date = new Date(startDate);
          date.setDate(startDate.getDate() + i);
          const key = date.toISOString().slice(0,10);
          const label = date.toLocaleDateString('pl-PL', {day: '2-digit', month: '2-digit'});
          const th = document.createElement('th');
          th.textContent = label;
          th.dataset.key = key;
          headerRow.appendChild(th);
        }
        table.appendChild(headerRow);

        for (const time of timeSlots) {
          const row = document.createElement('tr');
          const timeCell = document.createElement('td');
          timeCell.className = "time";
          timeCell.textContent = time;
          row.appendChild(timeCell);

          for (let i = 0; i < daysToShow; i++) {
            const date = new Date(startDate);
            date.setDate(startDate.getDate() + i);
            const key = date.toISOString().slice(0,10);
            const cell = document.createElement('td');
            cell.className = "slot";
            cell.dataset.time = time;
            cell.dataset.day = key;
            row.appendChild(cell);
          }
          table.appendChild(row);
        }

        container.appendChild(table);
        loadReservations().then(setupClickHandlers);
      }

      async function loadReservations() {
        const res = await fetch(ajaxurl + '?action=load_reservations');
        const json = await res.json();
        if (!json.success) return;
        const data = json.data;
        document.querySelectorAll('.slot').forEach(cell => {
          const day = cell.dataset.day;
          const time = cell.dataset.time;
          const key = `${day}_${time}`;
          if (data[key]) {
            cell.classList.add('taken');
            cell.dataset.owner = data[key];
            if (data[key] == currentUserId) {
              cell.classList.add('mine');
            } else {
              cell.classList.add('locked');
            }
          }
        });
      }

      function setupClickHandlers() {
        document.querySelectorAll('.slot').forEach(cell => {
          cell.addEventListener('click', async () => {
            const day = cell.dataset.day;
            const time = cell.dataset.time;
            if (cell.classList.contains('locked')) return;
            const action_type = cell.classList.contains('taken') ? 'remove' : 'add';

            const formData = new FormData();
            formData.append('action', 'save_reservation');
            formData.append('day', day);
            formData.append('time', time);
            formData.append('action_type', action_type);

            const res = await fetch(ajaxurl, { method: 'POST', body: formData });
            const json = await res.json();
            if (json.success) {
              if (action_type === 'add') {
                cell.classList.add('taken', 'mine');
              } else {
                cell.classList.remove('taken', 'mine');
              }
            }
          });
        });
      }

      document.addEventListener('DOMContentLoaded', generateCalendar);
    </script>
    <?php
    return ob_get_clean();
}

add_action('wp_ajax_save_reservation', 'save_reservation');
add_action('wp_ajax_nopriv_save_reservation', 'not_logged_in');

add_action('wp_ajax_load_reservations', 'load_reservations');
add_action('wp_ajax_nopriv_load_reservations', 'not_logged_in');

function not_logged_in() {
    wp_send_json_error('Musisz być zalogowany.');
}

function save_reservation() {
    if (!is_user_logged_in()) return not_logged_in();

    $user_id = get_current_user_id();
    $day = sanitize_text_field($_POST['day']);
    $time = sanitize_text_field($_POST['time']);
    $action = $_POST['action_type'];

    $key = "reservation_{$day}_{$time}";

    if ($action === 'add') {
        update_option($key, $user_id);
    } elseif ($action === 'remove') {
        $current = get_option($key);
        if ($current == $user_id) delete_option($key);
    }

    wp_send_json_success();
}

function load_reservations() {
    $results = [];
    $options = wp_load_alloptions();
    foreach ($options as $key => $value) {
        if (str_starts_with($key, 'reservation_')) {
            $parts = explode('_', $key);
            if (count($parts) >= 3) {
                $day = $parts[1];
                $time = $parts[2];
                $results["{$day}_{$time}"] = intval($value);
            }
        }
    }
    wp_send_json_success($results);
}
?>