UNPKG

vue-hotel-booking-calendar

Version:

A Vue 3 calendar component suite featuring hotel booking calendars, dashboard management, and resource scheduler with yearly/monthly/weekly/daily/hourly views. Includes price calculation, recurring events, event categories, working hours, and full interna

2,188 lines 91.9 kB
import { defineComponent as he, ref as ue, computed as b, onMounted as pe, watch as ke, createElementBlock as d, openBlock as c, normalizeClass as V, createElementVNode as t, createCommentVNode as N, toDisplayString as m, Fragment as B, renderList as F, withKeys as be, withModifiers as me, createTextVNode as De, renderSlot as $e, nextTick as fe, normalizeStyle as Q, createBlock as ye } from "vue";
const _e = { class: "calendar-header" }, Se = ["disabled", "aria-label"], Ce = { class: "month-year" }, Te = ["disabled", "aria-label"], Me = {
  key: 0,
  class: "selection-error"
}, Ie = { class: "error-content" }, He = { class: "error-message" }, Ee = {
  key: 0,
  class: "blocked-dates"
}, Oe = ["aria-label"], Be = { class: "calendar-body" }, Fe = { class: "calendar-grid-container" }, We = ["onClick", "onMouseenter", "tabindex", "aria-label", "onKeydown"], Ve = { class: "day-content" }, Ne = { class: "day-number" }, Pe = {
  key: 0,
  class: "day-price"
}, Le = {
  key: 1,
  class: "price-summary"
}, Ye = { class: "price-summary-header" }, xe = ["aria-label"], ze = { class: "price-content" }, Ae = { class: "stay-info" }, Re = { class: "nights" }, Ue = { class: "dates" }, Ge = {
  key: 0,
  class: "breakdown"
}, je = { class: "breakdown-toggle" }, qe = { class: "daily-list" }, Ke = { class: "totals" }, Je = { class: "subtotal" }, Qe = { class: "total" }, Xe = ["disabled"], Ze = {
  key: 2,
  class: "calendar-legend"
}, et = { class: "legend-item" }, tt = { class: "legend-item" }, nt = { class: "legend-item" }, at = /* @__PURE__ */ he({
  __name: "HotelBookingCalendar",
  props: {
    modelValue: { default: () => ({ checkIn: null, checkOut: null }) },
    availabilityData: { default: () => [] },
    minDate: {},
    maxDate: {},
    locale: { default: "en-GB" },
    disablePastDates: { type: Boolean, default: !0 },
    allowPreviousMonthNavigation: { type: Boolean, default: !0 },
    showPrices: { type: Boolean, default: !1 },
    allowSingleDay: { type: Boolean, default: !1 },
    theme: { default: "light" },
    basePrice: { default: 85 },
    currency: { default: "GBP" },
    showPriceCalculation: { type: Boolean, default: !0 },
    showSelectionErrors: { type: Boolean, default: !0 },
    textLabels: { default: () => ({}) }
  },
  emits: ["update:modelValue", "date-click", "date-select", "selection-change", "selection-error", "price-calculation", "book-now"],
  setup(J, { emit: oe }) {
    const e = J, p = oe, w = ue(/* @__PURE__ */ new Date()), _ = ue(null), U = ue(!1), P = ue(null), x = b(() => {
      if (!e.minDate) {
        if (e.disablePastDates) {
          const r = /* @__PURE__ */ new Date();
          return r.setHours(0, 0, 0, 0), r;
        }
        return null;
      }
      return typeof e.minDate == "string" ? new Date(e.minDate) : e.minDate;
    }), ne = b(() => e.maxDate ? typeof e.maxDate == "string" ? new Date(e.maxDate) : e.maxDate : null), Y = b(() => {
      const r = /* @__PURE__ */ new Map();
      return e.availabilityData.forEach((k) => {
        r.set(k.date, k);
      }), r;
    }), X = b(() => {
      const r = new Intl.DateTimeFormat(e.locale, { weekday: "short" }), k = [];
      for (let T = 0; T < 7; T++) {
        const H = new Date(2023, 0, T + 1);
        k.push(r.format(H));
      }
      return k;
    }), se = b(() => {
      const r = w.value.getFullYear(), k = w.value.getMonth(), T = new Date(r, k, 1), H = new Date(r, k + 1, 0), z = new Date(T), $ = new Date(H), q = z.getDay();
      z.setDate(z.getDate() - q);
      const ae = 6 - $.getDay();
      $.setDate($.getDate() + ae);
      const re = [], K = new Date(z);
      for (; K <= $; ) {
        const ie = S(K), ve = {
          date: new Date(K),
          dateString: ie,
          isToday: ie === S(/* @__PURE__ */ new Date()),
          isCurrentMonth: K.getMonth() === k,
          isPreviousMonth: K.getMonth() < k,
          isNextMonth: K.getMonth() > k,
          availability: Y.value.get(ie)
        };
        re.push(ve), K.setDate(K.getDate() + 1);
      }
      return re;
    }), j = b(() => {
      if (e.allowPreviousMonthNavigation || !x.value) return !0;
      const r = new Date(w.value);
      r.setMonth(r.getMonth() - 1), r.setDate(1);
      const k = new Date(x.value);
      return k.setDate(1), r >= k;
    }), ee = b(() => {
      if (!ne.value) return !0;
      const r = new Date(w.value);
      r.setMonth(r.getMonth() + 1), r.setDate(1);
      const k = new Date(ne.value);
      return k.setDate(1), r <= k;
    }), W = b(() => {
      var r, k, T, H, z, $, q, ae, re, K, ie, ve, ce;
      return {
        previousMonth: ((r = e.textLabels) == null ? void 0 : r.previousMonth) || "Previous month",
        nextMonth: ((k = e.textLabels) == null ? void 0 : k.nextMonth) || "Next month",
        bookingSummary: ((T = e.textLabels) == null ? void 0 : T.bookingSummary) || "Booking Summary",
        nights: ((H = e.textLabels) == null ? void 0 : H.nights) || "nights",
        night: ((z = e.textLabels) == null ? void 0 : z.night) || "night",
        priceBreakdown: (($ = e.textLabels) == null ? void 0 : $.priceBreakdown) || "Price breakdown",
        total: ((q = e.textLabels) == null ? void 0 : q.total) || "Total",
        bookNow: ((ae = e.textLabels) == null ? void 0 : ae.bookNow) || "Book Now",
        available: ((re = e.textLabels) == null ? void 0 : re.available) || "Available",
        checkoutOnly: ((K = e.textLabels) == null ? void 0 : K.checkoutOnly) || "Checkout Only",
        blocked: ((ie = e.textLabels) == null ? void 0 : ie.blocked) || "Blocked",
        clearSelection: ((ve = e.textLabels) == null ? void 0 : ve.clearSelection) || "Clear selection",
        dismissError: ((ce = e.textLabels) == null ? void 0 : ce.dismissError) || "Dismiss error"
      };
    }), L = b(() => {
      const { checkIn: r, checkOut: k } = e.modelValue;
      if (!r || !k) return null;
      const T = new Date(r), H = new Date(k), z = Math.ceil((H.getTime() - T.getTime()) / (1e3 * 60 * 60 * 24));
      if (z <= 0) return null;
      const $ = [];
      let q = 0;
      const ae = new Date(T);
      for (; ae < H; ) {
        const re = S(ae), K = Y.value.get(re), ie = (K == null ? void 0 : K.price) || e.basePrice || 85;
        $.push({ date: re, price: ie }), q += ie, ae.setDate(ae.getDate() + 1);
      }
      return {
        basePrice: e.basePrice || 85,
        nights: z,
        dailyPrices: $,
        totalPrice: q,
        currency: e.currency || "GBP",
        averagePerNight: q / z
      };
    }), S = (r) => {
      const k = r.getFullYear(), T = String(r.getMonth() + 1).padStart(2, "0"), H = String(r.getDate()).padStart(2, "0");
      return `${k}-${T}-${H}`;
    }, v = (r) => new Intl.DateTimeFormat(e.locale, {
      month: "long",
      year: "numeric"
    }).format(r), l = (r) => new Intl.NumberFormat(e.locale, {
      style: "currency",
      currency: e.currency || "GBP"
    }).format(r), a = (r, k) => {
      const T = new Date(r), H = new Date(k), z = new Intl.DateTimeFormat(e.locale, {
        month: "short",
        day: "numeric"
      });
      return `${z.format(T)} - ${z.format(H)}`;
    }, o = (r) => new Intl.DateTimeFormat(e.locale, {
      month: "short",
      day: "numeric"
    }).format(new Date(r)), u = (r) => r.map((k) => o(k)).join(", "), y = (r) => {
      var k;
      return ((k = r.availability) == null ? void 0 : k.price) || e.basePrice || 0;
    }, O = (r) => {
      if (!r.isCurrentMonth) return !0;
      if (e.disablePastDates) {
        const k = /* @__PURE__ */ new Date();
        k.setHours(0, 0, 0, 0);
        const T = new Date(r.date);
        if (T.setHours(0, 0, 0, 0), T < k) return !0;
      }
      return !!(x.value && r.date < x.value || ne.value && r.date > ne.value);
    }, D = (r) => !!(O(r) || f(r) === "blocked"), f = (r) => {
      var k;
      return ((k = r.availability) == null ? void 0 : k.status) || "available";
    }, C = (r) => {
      var k, T;
      return ((T = (k = P.value) == null ? void 0 : k.blockedDates) == null ? void 0 : T.includes(r)) || !1;
    }, M = (r, k, T = !1) => {
      const H = new Date(r), z = new Date(k), $ = new Date(H), q = [], ae = [];
      for ($.setDate($.getDate() + 1); $ < z || T && $.getTime() === z.getTime(); ) {
        const re = S($), K = Y.value.get(re);
        (K == null ? void 0 : K.status) === "checkout-only" && (!T || $ < z) ? ae.push(re) : (K == null ? void 0 : K.status) === "blocked" && q.push(re), $.setDate($.getDate() + 1);
      }
      return { blockedDates: q, checkoutOnlyDates: ae };
    }, R = (r) => r === e.modelValue.checkIn || r === e.modelValue.checkOut, Z = (r) => {
      const { checkIn: k, checkOut: T } = e.modelValue;
      return !k || !T ? !1 : r > k && r < T;
    }, le = (r) => r === e.modelValue.checkIn, n = (r) => r === e.modelValue.checkOut, E = (r) => {
      const k = r.date.toLocaleDateString(e.locale, {
        weekday: "long",
        year: "numeric",
        month: "long",
        day: "numeric"
      }), T = f(r), H = y(r);
      return `${k}, ${T}${H ? `, ${l(H)}` : ""}`;
    }, s = () => {
      P.value = null;
    }, g = (r, k) => {
      const T = {
        "blocked-dates-in-range": "Selected dates include unavailable periods. Please choose different dates.",
        "min-stay-not-met": "Minimum stay requirement not met for selected dates.",
        "max-stay-exceeded": "Selected stay exceeds maximum allowed duration.",
        "invalid-range": (k == null ? void 0 : k[0]) || "Invalid date range selected.",
        "checkout-only-in-range": "Cannot include checkout-only dates within your stay. These dates can only be used as the final checkout date."
      };
      return {
        type: r,
        message: T[r],
        blockedDates: r === "blocked-dates-in-range" || r === "checkout-only-in-range" ? k : void 0
      };
    }, i = () => {
      const r = { checkIn: null, checkOut: null };
      p("update:modelValue", r), p("selection-change", r), s(), U.value = !1;
    }, h = () => {
      if (L.value && e.modelValue.checkIn && e.modelValue.checkOut) {
        const r = {
          selection: {
            checkIn: e.modelValue.checkIn,
            checkOut: e.modelValue.checkOut
          },
          calculation: L.value
        };
        p("book-now", r);
      }
    }, I = (r) => {
      var $;
      if (D(r)) return;
      s();
      const { checkIn: k, checkOut: T } = e.modelValue, H = r.dateString, z = f(r);
      if (p("date-click", H, z), !k || k && T) {
        if (z === "checkout-only") {
          const ae = g("invalid-range", ["Checkout-only dates cannot be used as check-in dates"]);
          P.value = ae, p("selection-error", ae);
          return;
        }
        const q = { checkIn: H, checkOut: null };
        p("update:modelValue", q), p("selection-change", q), U.value = !0;
      } else if (k && !T) {
        if (H === k && !e.allowSingleDay)
          return;
        const q = H < k ? H : k, ae = H < k ? k : H;
        if (H < k && z === "checkout-only") {
          const ce = g("invalid-range", ["Checkout-only dates cannot be used as check-in dates"]);
          P.value = ce, p("selection-error", ce);
          return;
        }
        if (H > k && (($ = Y.value.get(q)) == null ? void 0 : $.status) === "checkout-only") {
          const de = g("invalid-range", ["Checkout-only dates cannot be used as check-in dates"]);
          P.value = de, p("selection-error", de);
          return;
        }
        const { blockedDates: re, checkoutOnlyDates: K } = M(q, ae, !0), ie = f({});
        if (re.length > 0 || ie === "blocked") {
          const ce = [...re];
          ie === "blocked" && ce.push(ae);
          const de = g("blocked-dates-in-range", ce);
          P.value = de, p("selection-error", de);
          const we = { checkIn: H, checkOut: null };
          p("update:modelValue", we), p("selection-change", we), U.value = !0;
          return;
        }
        if (K.length > 0) {
          const ce = g("checkout-only-in-range", K);
          P.value = ce, p("selection-error", ce);
          const de = { checkIn: H, checkOut: null };
          p("update:modelValue", de), p("selection-change", de), U.value = !0;
          return;
        }
        const ve = { checkIn: q, checkOut: ae };
        p("update:modelValue", ve), p("selection-change", ve), U.value = !1;
      }
    }, A = (r) => {
      O(r) || (_.value = r.dateString);
    }, G = () => {
      if (!j.value) return;
      const r = new Date(w.value);
      r.setMonth(r.getMonth() - 1), w.value = r;
    }, te = () => {
      if (!ee.value) return;
      const r = new Date(w.value);
      r.setMonth(r.getMonth() + 1), w.value = r;
    };
    return pe(() => {
      if (e.modelValue.checkIn) {
        const r = new Date(e.modelValue.checkIn);
        w.value = new Date(r.getFullYear(), r.getMonth(), 1);
      }
    }), ke(() => e.modelValue, (r, k) => {
      if (r.checkIn && !r.checkOut ? U.value = !0 : U.value = !1, r.checkIn && r.checkIn !== (k == null ? void 0 : k.checkIn)) {
        const T = new Date(r.checkIn);
        w.value = new Date(T.getFullYear(), T.getMonth(), 1);
      }
    }, { deep: !0 }), ke(L, (r) => {
      p("price-calculation", r);
    }, { immediate: !0 }), (r, k) => {
      var T, H, z;
      return c(), d("div", {
        class: V(["hotel-booking-calendar", [
          `theme-${r.theme}`,
          { "show-prices": r.showPrices },
          { "has-selection-error": P.value }
        ]])
      }, [
        t("div", _e, [
          t("button", {
            type: "button",
            class: "nav-button prev",
            onClick: G,
            disabled: !j.value,
            "aria-label": W.value.previousMonth
          }, " ‹ ", 8, Se),
          t("div", Ce, [
            t("h2", null, m(v(w.value)), 1)
          ]),
          t("button", {
            type: "button",
            class: "nav-button next",
            onClick: te,
            disabled: !ee.value,
            "aria-label": W.value.nextMonth
          }, " › ", 8, Te)
        ]),
        P.value && r.showSelectionErrors ? (c(), d("div", Me, [
          k[0] || (k[0] = t("div", { class: "error-icon" }, "⚠️", -1)),
          t("div", Ie, [
            t("div", He, m(P.value.message), 1),
            (T = P.value.blockedDates) != null && T.length ? (c(), d("div", Ee, " Blocked dates: " + m(u(P.value.blockedDates)), 1)) : N("", !0)
          ]),
          t("button", {
            onClick: s,
            class: "error-dismiss",
            "aria-label": W.value.dismissError
          }, "✕", 8, Oe)
        ])) : N("", !0),
        t("div", Be, [
          t("div", Fe, [
            (c(!0), d(B, null, F(X.value, ($) => (c(), d("div", {
              key: $,
              class: "weekday"
            }, m($), 1))), 128)),
            (c(!0), d(B, null, F(se.value, ($) => (c(), d("div", {
              key: $.dateString,
              class: V(["day-cell", {
                "other-month": !$.isCurrentMonth,
                today: $.isToday,
                selected: R($.dateString),
                "in-range": Z($.dateString),
                "range-start": le($.dateString),
                "range-end": n($.dateString),
                available: f($) === "available",
                blocked: f($) === "blocked",
                "checkout-only": f($) === "checkout-only",
                disabled: O($),
                "click-disabled": D($),
                "error-blocked": C($.dateString)
              }]),
              onClick: (q) => I($),
              onMouseenter: (q) => A($),
              role: "button",
              tabindex: D($) ? -1 : 0,
              "aria-label": E($),
              onKeydown: [
                be((q) => I($), ["enter"]),
                be(me((q) => I($), ["prevent"]), ["space"])
              ]
            }, [
              t("div", Ve, [
                t("span", Ne, m($.date.getDate()), 1),
                r.showPrices && y($) ? (c(), d("div", Pe, m(l(y($))), 1)) : N("", !0)
              ])
            ], 42, We))), 128))
          ])
        ]),
        r.showPriceCalculation && L.value ? (c(), d("div", Le, [
          t("div", Ye, [
            t("h4", null, m(W.value.bookingSummary), 1),
            t("button", {
              onClick: i,
              class: "clear-btn",
              "aria-label": W.value.clearSelection
            }, "✕", 8, xe)
          ]),
          t("div", ze, [
            t("div", Ae, [
              t("span", Re, m(L.value.nights) + " " + m(L.value.nights === 1 ? W.value.night : W.value.nights), 1),
              t("span", Ue, m((H = r.modelValue) != null && H.checkIn && ((z = r.modelValue) != null && z.checkOut) ? a(
                r.modelValue.checkIn,
                r.modelValue.checkOut
              ) : ""), 1)
            ]),
            L.value.dailyPrices.length > 1 ? (c(), d("div", Ge, [
              t("details", je, [
                t("summary", null, [
                  De(m(W.value.priceBreakdown) + " ", 1),
                  k[1] || (k[1] = t("span", { class: "arrow" }, "▼", -1))
                ]),
                t("div", qe, [
                  (c(!0), d(B, null, F(L.value.dailyPrices, ($) => (c(), d("div", {
                    key: $.date,
                    class: "daily-row"
                  }, [
                    t("span", null, m(o($.date)), 1),
                    t("span", null, m(l($.price)), 1)
                  ]))), 128))
                ])
              ])
            ])) : N("", !0),
            t("div", Ke, [
              t("div", Je, [
                t("span", null, m(L.value.nights) + " × " + m(l(L.value.averagePerNight)), 1),
                t("span", null, m(l(L.value.totalPrice)), 1)
              ]),
              t("div", Qe, [
                t("span", null, m(W.value.total), 1),
                t("strong", null, m(l(L.value.totalPrice)), 1)
              ])
            ]),
            t("button", {
              onClick: h,
              class: "book-btn",
              disabled: !L.value
            }, m(W.value.bookNow), 9, Xe)
          ])
        ])) : N("", !0),
        (r.$slots.legend, c(), d("div", Ze, [
          $e(r.$slots, "legend", {}, () => [
            t("div", et, [
              k[2] || (k[2] = t("div", { class: "legend-indicator available" }, null, -1)),
              t("span", null, m(W.value.available), 1)
            ]),
            t("div", tt, [
              k[3] || (k[3] = t("div", { class: "legend-indicator checkout-only" }, null, -1)),
              t("span", null, m(W.value.checkoutOnly), 1)
            ]),
            t("div", nt, [
              k[4] || (k[4] = t("div", { class: "legend-indicator blocked" }, null, -1)),
              t("span", null, m(W.value.blocked), 1)
            ])
          ], !0)
        ]))
      ], 2);
    };
  }
}), ge = (J, oe) => {
  const e = J.__vccOpts || J;
  for (const [p, w] of oe)
    e[p] = w;
  return e;
}, ot = /* @__PURE__ */ ge(at, [["__scopeId", "data-v-405ca090"]]), st = { class: "dashboard-header" }, lt = ["aria-label"], rt = { class: "nav-text" }, it = { class: "current-month" }, ct = ["aria-label"], ut = { class: "nav-text" }, dt = { class: "calendar-container desktop-view" }, ht = { class: "calendar-grid" }, gt = { class: "grid-header" }, vt = { class: "room-header" }, kt = { class: "date-number" }, mt = { class: "date-weekday" }, yt = { class: "room-name" }, Dt = ["onClick", "title"], ft = { class: "span-content" }, wt = { class: "span-text" }, bt = ["onClick", "title"], pt = {
  key: 0,
  class: "booking-indicator"
}, $t = { class: "guest-initials" }, _t = { class: "calendar-container mobile-view" }, St = { class: "mobile-view-toggle" }, Ct = {
  key: 0,
  class: "vertical-mobile-view"
}, Tt = { class: "mobile-room-header" }, Mt = { class: "mobile-calendar-grid" }, It = { class: "mobile-weekdays" }, Ht = { class: "mobile-days" }, Et = ["onClick"], Ot = { class: "mobile-date-number" }, Bt = {
  key: 0,
  class: "mobile-booking-indicator"
}, Ft = { class: "mobile-guest-initials" }, Wt = {
  key: 1,
  class: "horizontal-mobile-view"
}, Vt = { class: "horizontal-calendar-container" }, Nt = { class: "horizontal-calendar-grid" }, Pt = { class: "horizontal-grid-header" }, Lt = { class: "horizontal-room-header" }, Yt = { class: "horizontal-date-number" }, xt = { class: "horizontal-date-weekday" }, zt = { class: "horizontal-room-name" }, At = ["onClick", "title"], Rt = { class: "horizontal-span-content" }, Ut = { class: "horizontal-span-text" }, Gt = ["onClick", "title"], jt = {
  key: 0,
  class: "horizontal-booking-indicator"
}, qt = { class: "horizontal-guest-initials" }, Kt = { class: "legend" }, Jt = /* @__PURE__ */ he({
  __name: "HotelDashboardCalendar",
  props: {
    rooms: {},
    bookings: {},
    selectedMonth: { default: () => /* @__PURE__ */ new Date() },
    theme: { default: "light" },
    statusConfig: {},
    allowPreviousMonthNavigation: { type: Boolean, default: !1 },
    textLabels: { default: () => ({}) }
  },
  emits: ["update:selectedMonth", "booking-click", "booking-create"],
  setup(J, { emit: oe }) {
    const e = J, p = oe, w = ue(new Date(e.selectedMonth)), _ = ue(!1), U = [
      {
        key: "available",
        label: "Available",
        color: "#666",
        backgroundColor: "#f9f9f9",
        darkBackgroundColor: "#2a2a2a"
      },
      {
        key: "confirmed",
        label: "Confirmed",
        color: "#166534",
        backgroundColor: "#dcf8c6",
        darkBackgroundColor: "#1a4d14"
      },
      {
        key: "pending",
        label: "Pending",
        color: "#92400e",
        backgroundColor: "#fef3c7",
        darkBackgroundColor: "#4a3c00"
      },
      {
        key: "checked-in",
        label: "Checked In",
        color: "#1e40af",
        backgroundColor: "#dbeafe",
        darkBackgroundColor: "#1e3a8a"
      },
      {
        key: "checked-out",
        label: "Checked Out",
        color: "#7c3aed",
        backgroundColor: "#f3e8ff",
        darkBackgroundColor: "#5b21b6"
      },
      {
        key: "cancelled",
        label: "Cancelled",
        color: "#dc2626",
        backgroundColor: "#fee2e2",
        darkBackgroundColor: "#7f1d1d"
      }
    ], P = b(
      () => e.statusConfig || U
    ), x = b(() => {
      var s, g, i, h, I, A;
      return {
        previousMonth: ((s = e.textLabels) == null ? void 0 : s.previousMonth) || "← Previous",
        nextMonth: ((g = e.textLabels) == null ? void 0 : g.nextMonth) || "Next →",
        room: ((i = e.textLabels) == null ? void 0 : i.room) || "Room",
        available: ((h = e.textLabels) == null ? void 0 : h.available) || "Available",
        createBooking: ((I = e.textLabels) == null ? void 0 : I.createBooking) || "Click to create booking",
        clickForDetails: ((A = e.textLabels) == null ? void 0 : A.clickForDetails) || "Click for details"
      };
    }), ne = b(() => {
      const s = new Intl.DateTimeFormat("en-US", { weekday: "short" }), g = [];
      for (let i = 0; i < 7; i++) {
        const h = new Date(2023, 0, i + 1);
        g.push(s.format(h));
      }
      return g;
    }), Y = b(() => {
      const s = w.value.getFullYear(), g = w.value.getMonth(), i = new Date(s, g + 1, 0).getDate(), h = /* @__PURE__ */ new Date();
      h.setHours(0, 0, 0, 0);
      const I = [];
      for (let A = 1; A <= i; A++) {
        const G = new Date(s, g, A), te = `${s}-${String(g + 1).padStart(2, "0")}-${String(A).padStart(2, "0")}`;
        I.push({
          day: A,
          dateString: te,
          date: G,
          isToday: G.getTime() === h.getTime(),
          isWeekend: G.getDay() === 0 || G.getDay() === 6,
          weekday: new Intl.DateTimeFormat("en-US", { weekday: "short" }).format(G)
        });
      }
      return I;
    }), X = b(() => {
      const s = {};
      return e.rooms.forEach((g) => {
        s[g.id] = [], e.bookings.filter(
          (h) => h.roomNumber === g.number
        ).forEach((h) => {
          const I = new Date(h.checkIn), A = new Date(h.checkOut), G = w.value.getFullYear(), te = w.value.getMonth(), r = new Date(G, te, 1), k = new Date(G, te + 1, 0);
          if (I <= k && A > r) {
            let T, H;
            if (I >= r ? T = I.getDate() : T = 1, A <= k ? H = A.getDate() - 1 : H = k.getDate(), H = Math.max(T, H), T >= 1 && H <= k.getDate() && T <= H) {
              const z = v(h.status);
              s[g.id].push({
                booking: h,
                startDay: T,
                endDay: H,
                length: H - T + 1,
                statusConfig: z
              });
            }
          }
        }), s[g.id].sort((h, I) => h.startDay - I.startDay);
      }), s;
    }), se = (s) => new Intl.DateTimeFormat("en-US", {
      year: "numeric",
      month: "long"
    }).format(s), j = (s) => {
      if (s < 0 && !e.allowPreviousMonthNavigation) {
        const i = /* @__PURE__ */ new Date(), h = new Date(w.value.getFullYear(), w.value.getMonth(), 1), I = new Date(i.getFullYear(), i.getMonth(), 1);
        if (h <= I) return;
      }
      const g = new Date(w.value);
      g.setMonth(g.getMonth() + s), w.value = g, p("update:selectedMonth", g);
    }, ee = (s, g) => {
      try {
        return !s || !g ? (console.warn("HotelDashboardCalendar: Invalid room or dateString in hasBooking", { room: s, dateString: g }), !1) : Array.isArray(e.bookings) ? !!e.bookings.find((h) => {
          try {
            if (!h || typeof h != "object")
              return console.warn("HotelDashboardCalendar: Invalid booking object", h), !1;
            if (!h.roomNumber || !h.checkIn || !h.checkOut)
              return console.warn("HotelDashboardCalendar: Missing required booking properties", h), !1;
            const I = h.roomNumber === s.number && W(g, h);
            return h.roomNumber === s.number && !I && console.debug(
              "HotelDashboardCalendar: Date range mismatch",
              {
                room: s.number,
                date: g,
                booking: {
                  checkIn: h.checkIn,
                  checkOut: h.checkOut,
                  normalized: {
                    checkIn: new Date(h.checkIn).toISOString(),
                    checkOut: new Date(h.checkOut).toISOString(),
                    date: new Date(g).toISOString()
                  }
                }
              }
            ), I;
          } catch (I) {
            return console.error("HotelDashboardCalendar: Error processing booking", I, h), !1;
          }
        }) : (console.warn("HotelDashboardCalendar: bookings prop is not an array", e.bookings), !1);
      } catch (i) {
        return console.error("HotelDashboardCalendar: Error in hasBooking", i, { room: s, dateString: g }), !1;
      }
    }, W = (s, g) => {
      try {
        if (!s || !(g != null && g.checkIn) || !(g != null && g.checkOut))
          return console.warn("HotelDashboardCalendar: Invalid date or booking in isDateInBookingRange", { dateString: s, booking: g }), !1;
        let i, h, I;
        try {
          if (i = new Date(s), h = new Date(g.checkIn), I = new Date(g.checkOut), isNaN(i.getTime()) || isNaN(h.getTime()) || isNaN(I.getTime()))
            return console.warn("HotelDashboardCalendar: Invalid date format", {
              date: s,
              checkIn: g.checkIn,
              checkOut: g.checkOut
            }), !1;
        } catch (G) {
          return console.error("HotelDashboardCalendar: Date parsing error", G, { dateString: s, booking: g }), !1;
        }
        i.setHours(0, 0, 0, 0), h.setHours(0, 0, 0, 0), I.setHours(0, 0, 0, 0);
        const A = h.getTime() === I.getTime();
        return !A && I <= h ? (console.warn("HotelDashboardCalendar: Invalid booking dates (checkOut <= checkIn)", {
          checkIn: g.checkIn,
          checkOut: g.checkOut
        }), !1) : A ? i.getTime() === h.getTime() : i >= h && i < I;
      } catch (i) {
        return console.error("HotelDashboardCalendar: Error in isDateInBookingRange", i, { dateString: s, booking: g }), !1;
      }
    }, L = (s, g) => e.bookings.find(
      (i) => i.roomNumber === s.number && W(g, i)
    ) || null, S = (s, g) => {
      const i = L(s, g);
      return i ? i.status : "available";
    }, v = (s) => P.value.find((g) => g.key === s) || P.value[0], l = (s, g) => {
      const i = [], h = Y.value.find((I) => I.dateString === g);
      return h != null && h.isToday && i.push("is-today"), h != null && h.isWeekend && i.push("is-weekend"), ee(s, g) && i.push("has-booking"), i;
    }, a = (s, g) => {
      const i = S(s, g), h = v(i);
      return {
        backgroundColor: e.theme === "dark" && h.darkBackgroundColor ? h.darkBackgroundColor : h.backgroundColor,
        color: h.color
      };
    }, o = (s, g) => {
      const i = L(s, g);
      return i ? i.guestName.split(" ").map((h) => h.charAt(0).toUpperCase()).join("").substring(0, 2) : "";
    }, u = (s, g) => {
      const i = new Date(s), I = new Date(g).getTime() - i.getTime();
      return Math.ceil(I / (1e3 * 60 * 60 * 24));
    }, y = (s, g) => {
      const i = L(s, g);
      if (!i) return `${x.value.room} ${s.number} - ${x.value.available} (${x.value.createBooking})`;
      const h = v(i.status), I = u(i.checkIn, i.checkOut);
      return `${i.guestName} - ${x.value.room} ${s.number} - ${h.label} - ${I} nights (${x.value.clickForDetails})`;
    }, O = (s, g) => {
      const i = L(s, g);
      i ? p("booking-click", i) : p("booking-create", { roomId: s.id, date: g });
    }, D = (s) => {
      var A;
      const g = [], i = X.value[s.id] || [], h = /* @__PURE__ */ new Set(), I = [...i].sort((G, te) => G.startDay - te.startDay);
      for (let G = 1; G <= Y.value.length; G++) {
        if (h.has(G)) continue;
        const te = I.find((r) => r.startDay === G);
        if (te) {
          const r = ((A = Y.value[G - 1]) == null ? void 0 : A.dateString) || "";
          g.push({
            type: "booking-span",
            booking: te.booking,
            startDay: te.startDay,
            endDay: te.endDay,
            length: te.length,
            statusConfig: te.statusConfig,
            startDate: r
          });
          for (let k = te.startDay; k <= te.endDay; k++)
            h.add(k);
        } else {
          const r = Y.value[G - 1];
          r && g.push({
            type: "date-cell",
            dateString: r.dateString,
            day: G
          });
        }
      }
      return g;
    }, f = (s) => ({
      backgroundColor: e.theme === "dark" && s.statusConfig.darkBackgroundColor ? s.statusConfig.darkBackgroundColor : s.statusConfig.backgroundColor,
      color: s.statusConfig.color,
      border: `1px solid ${s.statusConfig.color}`,
      borderRadius: "4px",
      gridColumnStart: (s.startDay + 1).toString(),
      // +1 for room column
      gridColumnEnd: (s.endDay + 2).toString()
      // +2 for room column and exclusive end
    }), C = (s) => {
      const g = u(s.booking.checkIn, s.booking.checkOut), i = s.booking.guestName;
      return s.length === 1 ? i.split(" ").map((h) => h.charAt(0)).join("").substring(0, 2) : s.length <= 3 ? i.split(" ")[0] : s.length <= 6 ? `${i.split(" ")[0]} (${g}n)` : `${i} - ${g} nights`;
    }, M = (s) => {
      const g = u(s.booking.checkIn, s.booking.checkOut), i = e.rooms.find((h) => h.number === s.booking.roomNumber);
      return `${s.booking.guestName} - Room ${i == null ? void 0 : i.number} - ${s.statusConfig.label} - ${g} nights`;
    }, R = (s) => {
      p("booking-click", s);
    }, Z = () => {
      _.value = !1;
    }, le = () => {
      _.value = !0, fe(() => {
        n();
      });
    }, n = () => {
      const s = /* @__PURE__ */ new Date(), g = `${s.getFullYear()}-${String(s.getMonth() + 1).padStart(2, "0")}-${String(s.getDate()).padStart(2, "0")}`, i = Y.value.findIndex((h) => h.dateString === g);
      if (i !== -1) {
        const h = document.querySelector(".horizontal-calendar-container");
        if (h) {
          const G = i * 80 + 60 - h.clientWidth / 2 + 40;
          h.scrollTo({
            left: Math.max(0, G),
            behavior: "smooth"
          });
        }
      }
    }, E = b(() => Y.value.length === 0 ? 0 : new Date(Y.value[0].dateString).getDay());
    return ke(() => e.selectedMonth, (s) => {
      s && (w.value = new Date(s), _.value && fe(() => {
        n();
      }));
    }), ke(_, (s) => {
      s && fe(() => {
        n();
      });
    }), (s, g) => (c(), d("div", {
      class: V(["hotel-dashboard-calendar", `theme-${s.theme}`]),
      style: Q({ "--days-in-month": Y.value.length })
    }, [
      t("div", st, [
        t("button", {
          onClick: g[0] || (g[0] = (i) => j(-1)),
          class: "nav-btn",
          "aria-label": x.value.previousMonth
        }, [
          t("span", rt, m(x.value.previousMonth), 1),
          g[2] || (g[2] = t("span", { class: "nav-arrow" }, "←", -1))
        ], 8, lt),
        t("h2", it, m(se(w.value)), 1),
        t("button", {
          onClick: g[1] || (g[1] = (i) => j(1)),
          class: "nav-btn",
          "aria-label": x.value.nextMonth
        }, [
          t("span", ut, m(x.value.nextMonth), 1),
          g[3] || (g[3] = t("span", { class: "nav-arrow" }, "→", -1))
        ], 8, ct)
      ]),
      t("div", dt, [
        t("div", ht, [
          t("div", gt, [
            t("div", vt, m(x.value.room), 1),
            (c(!0), d(B, null, F(Y.value, (i) => (c(), d("div", {
              key: i.dateString,
              class: V(["date-header", {
                "is-today": i.isToday,
                "is-weekend": i.isWeekend
              }])
            }, [
              t("div", kt, m(i.day), 1),
              t("div", mt, m(i.weekday), 1)
            ], 2))), 128))
          ]),
          (c(!0), d(B, null, F(e.rooms, (i) => (c(), d("div", {
            key: i.id,
            class: "room-row"
          }, [
            t("div", yt, m(i.number), 1),
            (c(!0), d(B, null, F(D(i), (h, I) => (c(), d(B, {
              key: `${i.id}-${I}`
            }, [
              h.type === "booking-span" ? (c(), d("div", {
                key: 0,
                class: V(["booking-span-cell", l(i, h.startDate)]),
                style: Q(f(h)),
                onClick: (A) => R(h.booking),
                title: M(h)
              }, [
                t("div", ft, [
                  t("span", wt, m(C(h)), 1)
                ])
              ], 14, Dt)) : (c(), d("div", {
                key: 1,
                class: V(["date-cell", l(i, h.dateString)]),
                style: Q(a(i, h.dateString)),
                onClick: (A) => O(i, h.dateString),
                title: y(i, h.dateString)
              }, [
                ee(i, h.dateString) ? (c(), d("div", pt, [
                  t("span", $t, m(o(i, h.dateString)), 1)
                ])) : N("", !0)
              ], 14, bt))
            ], 64))), 128))
          ]))), 128))
        ])
      ]),
      t("div", _t, [
        t("div", St, [
          t("button", {
            onClick: Z,
            class: V([{ active: !_.value }, "toggle-btn"])
          }, g[4] || (g[4] = [
            t("span", { class: "toggle-icon" }, "⊞", -1),
            t("span", { class: "toggle-text" }, "Vertical", -1)
          ]), 2),
          t("button", {
            onClick: le,
            class: V([{ active: _.value }, "toggle-btn"])
          }, g[5] || (g[5] = [
            t("span", { class: "toggle-icon" }, "⊟", -1),
            t("span", { class: "toggle-text" }, "Horizontal", -1)
          ]), 2)
        ]),
        _.value ? N("", !0) : (c(), d("div", Ct, [
          (c(!0), d(B, null, F(e.rooms, (i) => (c(), d("div", {
            key: i.id,
            class: "mobile-room-calendar"
          }, [
            t("div", Tt, [
              t("h3", null, m(x.value.room) + " " + m(i.number), 1)
            ]),
            t("div", Mt, [
              t("div", It, [
                (c(!0), d(B, null, F(ne.value, (h) => (c(), d("div", {
                  key: h,
                  class: "mobile-weekday"
                }, m(h), 1))), 128))
              ]),
              t("div", Ht, [
                (c(!0), d(B, null, F(E.value, (h) => (c(), d("div", {
                  key: `empty-${h}`,
                  class: "mobile-date-cell empty"
                }))), 128)),
                (c(!0), d(B, null, F(Y.value, (h) => (c(), d("div", {
                  key: h.dateString,
                  class: V(["mobile-date-cell", [
                    l(i, h.dateString),
                    { "other-month": h.date.getMonth() !== w.value.getMonth() }
                  ]]),
                  style: Q(ee(i, h.dateString) ? a(i, h.dateString) : {}),
                  onClick: (I) => O(i, h.dateString)
                }, [
                  t("div", Ot, m(h.day), 1),
                  ee(i, h.dateString) ? (c(), d("div", Bt, [
                    t("span", Ft, m(o(i, h.dateString)), 1)
                  ])) : N("", !0)
                ], 14, Et))), 128))
              ])
            ])
          ]))), 128))
        ])),
        _.value ? (c(), d("div", Wt, [
          t("div", Vt, [
            t("div", Nt, [
              t("div", Pt, [
                t("div", Lt, m(x.value.room), 1),
                (c(!0), d(B, null, F(Y.value, (i) => (c(), d("div", {
                  key: i.dateString,
                  class: V(["horizontal-date-header", {
                    "is-today": i.isToday,
                    "is-weekend": i.isWeekend
                  }])
                }, [
                  t("div", Yt, m(i.day), 1),
                  t("div", xt, m(i.weekday), 1)
                ], 2))), 128))
              ]),
              (c(!0), d(B, null, F(e.rooms, (i) => (c(), d("div", {
                key: i.id,
                class: "horizontal-room-row"
              }, [
                t("div", zt, m(i.number), 1),
                (c(!0), d(B, null, F(D(i), (h, I) => (c(), d(B, {
                  key: `${i.id}-${I}`
                }, [
                  h.type === "booking-span" ? (c(), d("div", {
                    key: 0,
                    class: V(["horizontal-booking-span-cell", l(i, h.startDate)]),
                    style: Q(f(h)),
                    onClick: (A) => R(h.booking),
                    title: M(h)
                  }, [
                    t("div", Rt, [
                      t("span", Ut, m(C(h)), 1)
                    ])
                  ], 14, At)) : (c(), d("div", {
                    key: 1,
                    class: V(["horizontal-date-cell", l(i, h.dateString)]),
                    style: Q(a(i, h.dateString)),
                    onClick: (A) => O(i, h.dateString),
                    title: y(i, h.dateString)
                  }, [
                    ee(i, h.dateString) ? (c(), d("div", jt, [
                      t("span", qt, m(o(i, h.dateString)), 1)
                    ])) : N("", !0)
                  ], 14, Gt))
                ], 64))), 128))
              ]))), 128))
            ])
          ])
        ])) : N("", !0)
      ]),
      t("div", Kt, [
        (c(!0), d(B, null, F(P.value, (i) => (c(), d("div", {
          key: i.key,
          class: "legend-item"
        }, [
          t("div", {
            class: "legend-color",
            style: Q({
              backgroundColor: i.backgroundColor,
              borderColor: i.color
            })
          }, null, 4),
          t("span", null, m(i.label), 1)
        ]))), 128))
      ])
    ], 6));
  }
}), Qt = /* @__PURE__ */ ge(Jt, [["__scopeId", "data-v-e4727a14"]]), Xt = { class: "months-grid" }, Zt = ["onClick"], en = { class: "month-header" }, tn = { class: "month-name" }, nn = {
  key: 0,
  class: "event-count"
}, an = { class: "mini-calendar" }, on = {
  key: 0,
  class: "mini-day empty"
}, sn = ["onClick"], ln = {
  key: 0,
  class: "category-indicators"
}, rn = ["title"], cn = { class: "year-summary" }, un = { class: "summary-item" }, dn = { class: "summary-value" }, hn = { class: "summary-item" }, gn = { class: "summary-value" }, vn = { class: "summary-item" }, kn = { class: "summary-value" }, mn = { class: "summary-item" }, yn = { class: "summary-value" }, Dn = /* @__PURE__ */ he({
  __name: "YearlyView",
  props: {
    year: {},
    events: {},
    theme: {},
    locale: {},
    categories: {},
    highlightToday: { type: Boolean, default: !0 },
    firstDayOfWeek: { default: 0 }
  },
  emits: ["month-click", "date-click"],
  setup(J, { emit: oe }) {
    const e = J, p = oe, w = b(() => {
      const S = new Intl.DateTimeFormat(e.locale, { weekday: "narrow" }), v = [];
      for (let l = 0; l < 7; l++) {
        const a = (e.firstDayOfWeek + l) % 7, o = new Date(2023, 0, 1 + a);
        v.push(S.format(o));
      }
      return v;
    }), _ = b(() => {
      const S = new Intl.DateTimeFormat(e.locale, { month: "long" }), v = new Intl.DateTimeFormat(e.locale, { month: "short" }), l = /* @__PURE__ */ new Date();
      return Array.from({ length: 12 }, (a, o) => {
        const u = new Date(e.year, o, 1), y = Y(o);
        return {
          date: u,
          month: o,
          year: e.year,
          name: S.format(u),
          shortName: v.format(u),
          eventCount: y,
          hasEvents: y > 0,
          isCurrentMonth: l.getFullYear() === e.year && l.getMonth() === o
        };
      });
    }), U = b(() => _.value.reduce((S, v) => S + v.eventCount, 0)), P = b(() => _.value.reduce((S, v) => !S || v.eventCount > S.eventCount ? v : S, null)), x = b(() => _.value.filter((S) => S.hasEvents).length), ne = b(() => U.value === 0 ? 0 : Math.round(U.value / 12)), Y = (S) => e.events.filter((v) => {
      const l = new Date(v.start), a = new Date(v.end), o = new Date(e.year, S, 1), u = new Date(e.year, S + 1, 0, 23, 59, 59);
      return l <= u && a >= o;
    }).length, X = (S) => {
      const v = new Date(e.year, S.month, 1), a = new Date(e.year, S.month + 1, 0).getDate(), o = v.getDay(), u = [];
      for (let y = 0; y < o; y++)
        u.push(null);
      for (let y = 1; y <= a; y++)
        u.push(y);
      return u;
    }, se = (S) => {
      const v = /* @__PURE__ */ new Set();
      return e.events.forEach((l) => {
        const a = new Date(l.start), o = new Date(l.end), u = new Date(e.year, S.month, 1), y = new Date(e.year, S.month + 1, 0);
        if (a <= y && o >= u) {
          const O = a.getMonth() === S.month && a.getFullYear() === e.year ? a.getDate() : 1, D = o.getMonth() === S.month && o.getFullYear() === e.year ? o.getDate() : y.getDate();
          for (let f = O; f <= D; f++)
            v.add(f);
        }
      }), Array.from(v);
    }, j = (S) => {
      const v = /* @__PURE__ */ new Set();
      return e.events.forEach((l) => {
        const a = new Date(l.start), o = new Date(l.end), u = new Date(e.year, S.month, 1), y = new Date(e.year, S.month + 1, 0);
        a <= y && o >= u && l.categoryId && v.add(l.categoryId);
      }), e.categories.filter((l) => v.has(l.id)).slice(0, 5);
    }, ee = (S, v) => {
      const l = /* @__PURE__ */ new Date(), a = e.highlightToday && l.getFullYear() === e.year && l.getMonth() === S.month && l.getDate() === v, o = se(S).includes(v);
      return {
        "is-today": a,
        "has-event": o
      };
    }, W = (S) => {
      p("month-click", S);
    }, L = (S, v) => {
      const l = `${e.year}-${String(S.month + 1).padStart(2, "0")}-${String(v).padStart(2, "0")}`;
      p("date-click", l);
    };
    return (S, v) => {
      var l;
      return c(), d("div", {
        class: V(["yearly-view", [`theme-${S.theme}`]])
      }, [
        t("div", Xt, [
          (c(!0), d(B, null, F(_.value, (a) => (c(), d("div", {
            key: a.month,
            class: V(["month-card", { "current-month": a.isCurrentMonth, "has-events": a.hasEvents }]),
            onClick: (o) => W(a.month)
          }, [
            t("div", en, [
              t("span", tn, m(a.name), 1),
              a.eventCount > 0 ? (c(), d("span", nn, m(a.eventCount), 1)) : N("", !0)
            ]),
            t("div", an, [
              (c(!0), d(B, null, F(w.value, (o) => (c(), d("div", {
                key: o,
                class: "mini-weekday"
              }, m(o), 1))), 128)),
              (c(!0), d(B, null, F(X(a), (o, u) => (c(), d(B, { key: u }, [
                o === null ? (c(), d("div", on)) : (c(), d("div", {
                  key: 1,
                  class: V(["mini-day", ee(a, o)]),
                  onClick: me((y) => L(a, o), ["stop"])
                }, m(o), 11, sn))
              ], 64))), 128))
            ]),
            j(a).length > 0 ? (c(), d("div", ln, [
              (c(!0), d(B, null, F(j(a), (o, u) => (c(), d("div", {
                key: u,
                class: "category-dot",
                style: Q({ backgroundColor: o.color }),
                title: o.name
              }, null, 12, rn))), 128))
            ])) : N("", !0)
          ], 10, Zt))), 128))
        ]),
        t("div", cn, [
          t("div", un, [
            t("div", dn, m(U.value), 1),
            v[0] || (v[0] = t("div", { class: "summary-label" }, "Total Events", -1))
          ]),
          t("div", hn, [
            t("div", gn, m(((l = P.value) == null ? void 0 : l.shortName) || "-"), 1),
            v[1] || (v[1] = t("div", { class: "summary-label" }, "Busiest Month", -1))
          ]),
          t("div", vn, [
            t("div", kn, m(x.value), 1),
            v[2] || (v[2] = t("div", { class: "summary-label" }, "Active Months", -1))
          ]),
          t("div", mn, [
            t("div", yn, m(ne.value), 1),
            v[3] || (v[3] = t("div", { class: "summary-label" }, "Avg per Month", -1))
          ])
        ])
      ], 2);
    };
  }
}), fn = /* @__PURE__ */ ge(Dn, [["__scopeId", "data-v-02063305"]]), wn = { class: "weekday-headers" }, bn = {
  key: 0,
  class: "weekday-header week-number-header"
}, pn = {
  key: 0,
  class: "week-number-cell"
}, $n = ["onClick"], _n = { class: "day-header" }, Sn = {
  key: 0,
  class: "more-events"
}, Cn = { class: "events-list" }, Tn = ["title", "onClick"], Mn = {
  key: 0,
  class: "event-time"
}, In = /* @__PURE__ */ he({
  __name: "MonthlyView",
  props: {
    currentDate: {},
    events: {},
    theme: {},
    locale: {},
    categories: {},
    firstDayOfWeek: {},
    highlightToday: { type: Boolean, default: !0 },
    highlightWeekends: { type: Boolean, default: !1 },
    maxEventsPerSlot: { default: 3 },
    showWeekNumbers: { type: Boolean, default: !1 }
  },
  emits: ["date-click", "event-click", "slot-click"],
  setup(J, { emit: oe }) {
    const e = J, p = oe, w = b(() => {
      const v = new Intl.DateTimeFormat(e.locale, { weekday: "short" }), l = [];
      for (let a = 0; a < 7; a++) {
        const o = (e.firstDayOfWeek + a) % 7, u = new Date(2023, 0, 1 + o);
        l.push(v.format(u));
      }
      return l;
    }), _ = b(() => {
      const v = e.currentDate.getFullYear(), l = e.currentDate.getMonth(), a = new Date(v, l, 1), o = new Date(a);
      let y = (o.getDay() - e.firstDayOfWeek + 7) % 7;
      o.setDate(o.getDate() - y);
      const O = new Date(o);
      O.setDate(O.getDate() + 41);
      const D = [], f = new Date(o), C = /* @__PURE__ */ new Date();
      for (C.setHours(0, 0, 0, 0); f <= O; ) {
        const M = P(f), R = Y(M);
        D.push({
          date: new Date(f),
          dateString: M,
          isToday: f.getTime() === C.getTime(),
          isCurrentMonth: f.getMonth() === l,
          isCurrentWeek: x(f, C),
          isWeekend: f.getDay() === 0 || f.getDay() === 6,
          isWorkingDay: ne(f),
          events: R
        }), f.setDate(f.getDate() + 1);
      }
      return D;
    }), U = b(() => P(e.currentDate)), P = (v) => {
      const l = v.getFullYear(), a = String(v.getMonth() + 1).padStart(2, "0"), o = String(v.getDate()).padStart(2, "0");
      return `${l}-${a}-${o}`;
    }, x = (v, l) => {
      const a = new Date(v), o = new Date(l);
      a.setHours(0, 0, 0, 0), o.setHours(0, 0, 0, 0);
      const u = new Date(a);
      u.setDate(a.getDate() - (a.getDay() - e.firstDayOfWeek + 7) % 7);
      const y = new Date(o);
      return y.setDate(o.getDate() - (o.getDay() - e.firstDayOfWeek + 7) % 7), u.getTime() === y.getTime();
    }, ne = (v) => {
      const l = v.getDay();
      return l !== 0 && l !== 6;
    }, Y = (v) => e.events.filter((l) => {
      const a = new Date(l.start), o = new Date(l.end), u = new Date(v);
      return a.setHours(0, 0, 0, 0), o.setHours(23, 59, 59, 999), u.setHours(12, 0, 0, 0), u >= a && u <= o;
    }).sort((l, a) => l.allDay && !a.allDay ? -1 : !l.allDay && a.allDay ? 1 : new Date(l.start).getTime() - new Date(a.start).getTime()), X = (v) => Y(v), se = (v) => v === U.value, j = (v) => {
      let l = v.backgroundColor || "#3b82f6", a = v.color || "#ffffff";
      if (v.categoryId) {
        const o = e.categories.find((u) => u.id === v.categoryId);
        o && (l = e.theme === "dark" && o.darkBackgroundColor ? o.darkBackgroundColor : o.backgroundColor, a = o.color);
      }
      return {
        backgroundColor: l,
        color: a,
        borderLeft: `3px solid ${a}`
      };
    }, ee = (v) => {
      const l = new Date(v);
      return new Intl.DateTimeFormat(e.locale, {
        hour: "numeric",
        minute: "2-digit"
      }).format(l);
    }, W = (v) => {
      p("date-click", v.dateString), p("slot-click", {
        start: `${v.dateString}T09:00:00`,
        end: `${v.dateString}T10:00:00`,
        date: v.dateString
      });
    }, L = (v) => {
      p("event-click", v);
    }, S = (v) => {
      const l = new Date(Date.UTC(v.getFullYear(), v.getMonth(), v.getDate())), a = l.getUTCDay() || 7;
      l.setUTCDate(l.getUTCDate() + 4 - a);
      const o = new Date(Date.UTC(l.getUTCFullYear(), 0, 1));
      return Math.ceil(((l.getTime() - o.getTime()) / 864e5 + 1) / 7);
    };
    return (v, l) => (c(), d("div", {
      class: V(["monthly-view", [`theme-${v.theme}`, { "show-week-numbers": v.showWeekNumbers }]])
    }, [
      t("div", wn, [
        v.showWeekNumbers ? (c(), d("div", bn, "Wk")) : N("", !0),
        (c(!0), d(B, null, F(w.value, (a) => (c(), d("div", {
          key: a,
          class: "weekday-header"
        }, m(a), 1))), 128))
      ]),
      t("div", {
        class: V(["calendar-grid", { "with-week-numbers": v.showWeekNumbers }])
      }, [
        (c(!0), d(B, null, F(_.value, (a, o) => (c(), d(B, {
          key: a.dateString
        }, [
          v.showWeekNumbers && o % 7 === 0 ? (c(), d("div", pn, m(S(a.date)), 1)) : N("", !0),
          t("div", {
            class: V(["day-cell", {
              "other-month": !a.isCurrentMonth,
              today: v.highlightToday && a.isToday,
              weekend: v.highlightWeekends && a.isWeekend,
              selected: se(a.dateString)
            }]),
            onClick: (u) => W(a)
          }, [
            t("div", _n, [
              t("span", {
                class: V(["day-number", { "today-number": v.highlightToday && a.isToday }])
              }, m(a.date.getDate()), 3),
              X(a.dateString).length > v.maxEventsPerSlot ? (c(), d("span", Sn, " +" + m(X(a.dateString).length - v.maxEventsPerSlot), 1)) : N("", !0)
            ]),
            t("div", Cn, [
              (c(!0), d(B, null, F(X(a.dateString).slice(0, v.maxEventsPerSlot), (u) => (c(), d("div", {
                key: u.id,
                class: "event-item",
                style: Q(j(u)),
                title: u.title,
                onClick: me((y) => L(u), ["stop"])
              }, [
                u.allDay ? N("", !0) : (c(), d("span", Mn, m(ee(u.start)), 1)),
                De(" " + m(u.title), 1)
              ], 12, Tn))), 128))
            ])
          ], 10, $n)
        ], 64))), 128))
      ], 2)
    ], 2));
  }
}), Hn = /* @__PURE__ */ ge(In, [["__scopeId", "data-v-3ffb4cee"]]), En = { class: "week-header" }, On = { class: "day-name" }, Bn = {
  key: 0,
  class: "all-day-row"
}, Fn = ["onClick"], Wn = ["onClick"], Vn = { class: "time-grid-container" }, Nn = { class: "time-grid" }, Pn = ["onClick"], Ln = ["onClick"], Yn = { class: "event-title" }, xn = { class: "event-time" }, zn = /* @__PURE__ */ he({
  __name: "WeeklyView",
  props: {
    currentDate: {},
    events: {},
    theme: {},
    locale: {},
    categories: {},
    workingHours: {},
    timeInterval: {},
    firstDayOfWeek: {},
    showAllDaySlot: { type: Boolean },
    highlightToday: { type: Boolean, default: !0 },
    highlightWeekends: { type: Boolean, default: !1 },
    showCurrentTimeIndicator: { type: Boolean, default: !0 },
    slotHeight: { default: 48 },
    eventMinHeight: { default: 20 }
  },
  emits: ["date-click", "event-click", "slot-click"],
  setup(J, { emit: oe }) {
    const e = J, p = oe, w = b(() => {
      if (e.slotHeight) return e.slotHeight;
      switch (e.timeInterval) {
        case 15:
          return 20;
        case 30:
          return 30;
        default:
          return 48;
      }
    }), _ = b(() => {
      const l = [], a = P(e.currentDate), o = /* @__PURE__ */ new Date();
      o.setHours(0, 0, 0, 0);
      const u = new Intl.DateTimeFormat(e.locale, { weekday: "short" });
      for (let y = 0; y < 7; y++) {
        const O = new Date(a);
        O.setDate(O.getDate() + y), l.push({
          date: new Date(O),
          dateString: x(O),
          weekdayShort: u.format(O),
          isToday: O.getTime() === o.getTime(),
          isWeekend: O.getDay() === 0 || O.getDay() === 6
        });
      }
      return l;
    }), U = b(() => {
      const l = [];
      for (let a = 0; a < 24; a++)
        l.push(a);
      return l;
    }), P = (l) => {
      const a = new Date(l), o = a.getDay(), u = (o < e.firstDayOfWeek ? 7 : 0) + o - e.firstDayOfWeek;
      return a.setDate(a.getDate() - u), a.setHours(0, 0, 0, 0), a;
    }, x = (l) => {
      const a = l.getFullYear(), o = String(l.getMonth() + 1).padStart(2, "0"), u = String(l.getDate()).padStart(2, "0");
      return `${a}-${o}-${u}`;
    }, ne = (l) => l >= e.workingHours.start && l < e.workingHours.end, Y = (l) => {
      const a = /* @__PURE__ */ new Date();
      return a.setHours(l, 0, 0, 0), new Intl.DateTimeFormat(e.locale, {
        hour: "numeric",
        hour12: !0
      }).format(a);
    }, X = (l) => e.events.filter((a) => {
      if (!a.allDay) return !1;
      const o = new Date(a.start), u = new Date(a.end), y = new Date(l);
      return o.setHours(0, 0, 0, 0), u.setHours(23, 59, 59, 999), y.setHours(12, 0, 0, 0), y >= o && y <= u;
    }), se = (l, a) => e.events.filter((o) => {
      if (o.allDay) return !1;
      const u = new Date(o.start), y = /* @__PURE__ */ new Date(`${l}T${String(a).padStart(2, "0")}:00:00`), O = new Date(y);
      return O.setHours(O.getHours() + 1), u >= y && u < O;
    }), j = (l) => {
      let a = l.backgroundColor || "#3b82f6", o = l.color || "#ffffff";
      if (l.categoryId) {
        const u = e.categories.find((y) => y.id === l.categoryId);
        u && (a = e.theme === "dark" && u.darkBackgroundColor ? u.darkBackgroundColor : u.backgroundColor, o = u.color);
      }
      return {
        backgroundColor: a,
        color: o,
        borderLeft: `3px solid ${o}`
      };
    }, ee = (l) => {
      const a = j(l), o = new Date(l.start), u = new Date(l.end), O = o.getMinutes() / 60 * w.value, f = (u.getTime() - o.getTime()) / (1e3 * 60 * 60), C = Math.max(f * w.value, e.eventMinHeight);
      return {
        ...a,
        top: `${O}px`,
        height: `${C}px`,
        minHeight: "20px"
      };
    }, W = (l) => {
      const a = new Date(l.start), o = new Date(l.end), u = new Intl.DateTimeFormat(e.locale, {
        hour: "numeric",
        minute: "2-digit"
      });
      return `${u.format(a)} - ${u.format(o)}`;
    }, L = (l, a) => {
      const o = `${l.dateString}T${String(a).padStart(2, "0")}:00:00`, u = a + 1, y = `${l.dateString}T${String(u).padStart(2, "0")}:00:00`;
      p("slot-click", { start: o, end: y, date: l.dateString, hour: a });
    }, S = (l) => {
      p("slot-click", {
        start: `${l.dateString}T00:00:00`,
        end: `${l.dateString}T23:59:59`,
        date: l.dateString,
        hour: 0
      });
    }, v = (l) => {
      p("event-click", l);
    };
    return (l, a) => (c(), d("div", {
      class: V(["weekly-view", [`theme-${l.theme}`]]),
      style: Q({ "--slot-height": `${w.value}px`, "--event-min-height": `${l.eventMinHeight}px` })
    }, [
      t("div", En, [
        a[0] || (a[0] = t("div", { class: "time-column-header" }, null, -1)),
        (c(!0), d(B, null, F(_.value, (o) => (c(), d("div", {
          key: o.dateString,
          class: V(["day-column-header", { "is-today": l.highlightToday && o.isToday, "is-weekend": l.highlightWeekends && o.isWeekend }])
        }, [
          t("div", On, m(o.weekdayShort), 1),
          t("div", {
            class: V(["day-number", { "today-number": l.highlightToday && o.isToday }])
          }, m(o.date.getDate()), 3)
        ], 2))), 128))
      ]),
      l.showAllDaySlot ? (c(), d("div", Bn, [
        a[1] || (a[1] = t("div", { class: "time-label all-day-label" }, "All Day", -1)),
        (c(!0), d(B, null, F(_.value, (o) => (c(), d("div", {
          key: `allday-${o.dateString}`,
          class: V(["all-day-cell", { "is-today": l.highlightToday && o.isToday }]),
          onClick: (u) => S(o)
        }, [
          (c(!0), d(B, null, F(X(o.dateString), (u) => (c(), d("div", {
            key: u.id,
            class: "all-day-event",
            style: Q(j(u)),
            onClick: me((y) => v(u), ["stop"])
          }, m(u.title), 13, Wn))), 128))
        ], 10, Fn))), 128))
      ])) : N("", !0),
      t("div", Vn, [
        t("div", Nn, [
          (c(!0), d(B, null, F(U.value, (o) => (c(), d("div", {
            key: o,
            class: "time-row"
          }, [
            t("div", {
              class: V(["time-label", { "working-hour": ne(o) }])
            }, m(Y(o)), 3),
            (c(!0), d(B, null, F(_.value, (u) => (c(), d("div", {
              key: `${u.dateString}-${o}`,
              class: V(["time-slot", {
                "working-hour": ne(o),
                "is-today": l.highlightToday && u.isToday,
                "is-weekend": l.highlightWeekends && u.isWeekend
              }]),
              onClick: (y) => L(u, o)
            }, [
              (c(!0), d(B, null, F(se(u.dateString, o), (y) => (c(), d("div", {
                key: y.id,
                class: "slot-event",
                style: Q(ee(y)),
                onClick: me((O) => v(y), ["stop"])
              }, [
                t("div", Yn, m(y.title), 1),
                t("div", xn, m(W(y)), 1)
              ], 12, Ln))), 128))
            ], 10, Pn))), 128))
          ]))), 128))
        ])
      ])
    ], 6));
  }
}), An = /* @__PURE__ */ ge(zn, [["__scopeId", "data-v-cb3c7540"]]), Rn = { class: "day-header-section" }, Un = { class: "weekday-label" }, Gn = {
  key: 0,
  class: "all-day-section"
}, jn = {
  key: 0,
  class: "no-events"
}, qn = { class: "all-day-events" }, Kn = ["onClick"], Jn = { class: "event-title" }, Qn = {
  key: 0,
  class: "event-description"
}, Xn = { class: "time-grid-wrapper" }, Zn = { class: "time-grid" }, ea = ["onClick"], ta = { class: "hour-events" }, na = ["onClick"], aa = { class: "event-header" }, oa = { class: "event-title" }, sa = { class: "event-time-range" }, la = {
  key: 0,
  class: "event-location"
}, ra = { class: "summary-section" }, ia = { class: "summary-count" }, ca = /* @__PURE__ */ he({
  __name: "DailyView",
  props: {
    currentDate: {},
    events: {},
    theme: {},
    locale: {},
    categories: {},
    workingHours: {},
    timeInterval: {},
    showAllDaySlot: { type: Boolean },
    highlightToday: { type: Boolean, default: !0 },
    showCurrentTimeIndicator: { type: Boolean, default: !0 },
    slotHeight: { default: 48 },
    eventMinHeight: { default: 20 }
  },
  emits: ["event-click", "slot-click"],
  setup(J, { emit: oe }) {
    const e = J, p = oe, w = b(() => Y(e.currentDate)), _ = b(() => {
      const a = /* @__PURE__ */ new Date();
      a.setHours(0, 0, 0, 0);
      const o = new Date(e.currentDate);
      return o.setHours(0, 0, 0, 0), {
        weekday: new Intl.DateTimeFormat(e.locale, { weekday: "long" }).format(e.currentDate),
        dayNumber: e.currentDate.getDate(),
        isToday: o.getTime() === a.getTime()
      };
    }), U = b(() => {
      const a = [];
      for (let o = 0; o < 24; o++)
        a.push(o);
      return a;
    }), P = b(() => e.events.filter((a) => {
      if (!a.allDay) return !1;
      const o = new Date(a.start), u = new Date(a.end), y = new Date(w.value);
      return o.setHours(0, 0, 0, 0), u.setHours(23, 59, 59, 999), y.setHours(12, 0, 0, 0), y >= o && y <= u;
    })), x = b(() => ee().length), ne = b(() => (/* @__PURE__ */ new Date()).getMinutes() / 60 * 100), Y = (a) => {
      const o = a.getFullYear(), u = String(a.getMonth() + 1).padStart(2, "0"), y = String(a.getDate()).padStart(2, "0");
      return `${o}-${u}-${y}`;
    }, X = (a) => a >= e.workingHours.start && a < e.workingHours.end, se = (a) => _.value.isToday ? (/* @__PURE__ */ new Date()).getHours() === a : !1, j = (a) => {
      const o = /* @__PURE__ */ new Date();
      return o.setHours(a, 0, 0, 0), new Intl.DateTimeFormat(e.locale, {
        hour: "numeric",
        minute: "2-digit",
        hour12: !0
      }).format(o);
    }, ee = () => e.events.filter((a) => {
      const o = new Date(a.start), u = new Date(a.end), y = new Date(w.value), O = new Date(y);
      O.setHours(0, 0, 0, 0);
      const D = new Date(y);
      return D.setHours(23, 59, 59, 999), o <= D && u >= O;
    }), W = (a) => e.events.filter((o) => {
      if (o.allDay) return !1;
      const u = new Date(o.start), y = new Date(o.end);
      if (Y(u) !== w.value) return !1;
      const D = u.getHours(), f = y.getHours() + (y.getMinutes() > 0 ? 1 : 0);
      return a >= D && a < f;
    }).sort((o, u) => new Date(o.start).getTime() - new Date(u.start).getTime()), L = (a) => {
      let o = a.backgroundColor || "#3b82f6", u = a.color || "#ffffff";
      if (a.categoryId) {
        const y = e.categories.find((O) => O.id === a.categoryId);
        y && (o = e.theme === "dark" && y.darkBackgroundColor ? y.darkBackgroundColor : y.backgroundColor, u = y.color);
      }
      return {
        backgroundColor: o,
        color: u,
        borderLeft: `3px solid ${u}`
      };
    }, S = (a) => {
      const o = new Date(a.start), u = new Date(a.end), y = new Intl.DateTimeFormat(e.locale, {
        hour: "numeric",
        minute: "2-digit"
      });
      return `${y.format(o)} - ${y.format(u)}`;
    }, v = (a) => {
      const o = `${w.value}T${String(a).padStart(2, "0")}:00:00`, u = a + 1, y = `${w.value}T${String(u).padStart(2, "0")}:00:00`;
      p("slot-click", { start: o, end: y, date: w.value, hour: a });
    }, l = (a) => {
      p("event-click", a);
    };
    return (a, o) => (c(), d("div", {
      class: V(["daily-view", [`theme-${a.theme}`]]),
      style: Q({ "--slot-height": `${a.slotHeight}px`, "--event-min-height": `${a.eventMinHeight}px` })
    }, [
      t("div", Rn, [
        t("div", Un, m(_.value.weekday), 1),
        t("div", {
          class: V(["date-display", { "is-today": a.highlightToday && _.value.isToday }])
        }, m(_.value.dayNumber), 3)
      ]),
      a.showAllDaySlot ? (c(), d("div", Gn, [
        o[0] || (o[0] = t("div", { class: "section-label" }, "All Day Events", -1)),
        P.value.length === 0 ? (c(), d("div", jn, "No all-day events")) : N("", !0),
        t("div", qn, [
          (c(!0), d(B, null, F(P.value, (u) => (c(), d("div", {
            key: u.id,
            class: "all-day-event",
            style: Q(L(u)),
            onClick: (y) => l(u)
          }, [
            t("div", Jn, m(u.title), 1),
            u.description ? (c(), d("div", Qn, m(u.description), 1)) : N("", !0)
          ], 12, Kn))), 128))
        ])
      ])) : N("", !0),
      t("div", Xn, [
        t("div", Zn, [
          (c(!0), d(B, null, F(U.value, (u) => (c(), d("div", {
            key: u,
            class: "hour-row"
          }, [
            t("div", {
              class: V(["hour-label", { "working-hour": X(u) }])
            }, m(j(u)), 3),
            t("div", {
              class: V(["hour-slot", {
                "working-hour": X(u),
                "current-hour": se(u)
              }]),
              onClick: (y) => v(u)
            }, [
              a.showCurrentTimeIndicator && se(u) ? (c(), d("div", {
                key: 0,
                class: "current-time-indicator",
                style: Q({ top: `${ne.value}%` })
              }, o[1] || (o[1] = [
                t("div", { class: "time-dot" }, null, -1)
              ]), 4)) : N("", !0),
              t("div", ta, [
                (c(!0), d(B, null, F(W(u), (y) => (c(), d("div", {
                  key: y.id,
                  class: "hour-event",
                  style: Q(L(y)),
                  onClick: me((O) => l(y), ["stop"])
                }, [
                  t("div", aa, [
                    t("span", oa, m(y.title), 1),
                    t("span", sa, m(S(y)), 1)
                  ]),
                  y.location ? (c(), d("div", la, [
                    o[2] || (o[2] = t("span", { class: "location-icon" }, "📍", -1)),
                    De(" " + m(y.location), 1)
                  ])) : N("", !0)
                ], 12, na))), 128))
              ])
            ], 10, ea)
          ]))), 128))
        ])
      ]),
      t("div", ra, [
        o[3] || (o[3] = t("span", { class: "summary-label" }, "Total events today:", -1)),
        t("span", ia, m(x.value), 1)
      ])
    ], 6));
  }
}), ua = /* @__PURE__ */ ge(ca, [["__scopeId", "data-v-406daf97"]]), da = { class: "day-info-header" }, ha = { class: "date-info" }, ga = { class: "weekday-name" }, va = { class: "full-date" }, ka = { class: "day-status" }, ma = {
  key: 0,
  class: "today-badge"
}, ya = { class: "event-count-label" }, Da = { class: "interval-selector" }, fa = { class: "interval-buttons" }, wa = ["onClick"], ba = { class: "time-slots-container" }, pa = { class: "time-slots" }, $a = ["onClick"], _a = { class: "slot-events" }, Sa = ["onClick"], Ca = { class: "event-main" }, Ta = { class: "event-title" }, Ma = { class: "event-duration" }, Ia = {
  key: 0,
  class: "event-desc"
}, Ha = {
  key: 1,
  class: "event-location"
}, Ea = { class: "stats-section" }, Oa = { class: "stat-item" }, Ba = { class: "stat-value" }, Fa = { class: "stat-item" }, Wa = { class: "stat-value" }, Va = { class: "stat-item" }, Na = { class: "stat-value highlight" }, Pa = /* @__PURE__ */ he({
  __name: "HourlyView",
  props: {
    currentDate: {},
    events: {},
    theme: {},
    locale: {},
    categories: {},
    workingHours: {},
    timeInterval: {},
    showCurrentTimeIndicator: { type: Boolean, default: !0 },
    slotHeight: { default: 60 },
    eventMinHeight: { default: 20 }
  },
  emits: ["event-click", "slot-click"],
  setup(J, { emit: oe }) {
    const e = J, p = oe, w = [15, 30, 60], _ = ue(e.timeInterval), U = b(() => L(e.currentDate)), P = b(() => {
      const D = /* @__PURE__ */ new Date();
      D.setHours(0, 0, 0, 0);
      const f = new Date(e.currentDate);
      return f.setHours(0, 0, 0, 0), {
        weekday: new Intl.DateTimeFormat(e.locale, { weekday: "long" }).format(e.currentDate),
        formattedDate: new Intl.DateTimeFormat(e.locale, {
          month: "long",
          day: "numeric",
          year: "numeric"
        }).format(e.currentDate),
        isToday: f.getTime() === D.getTime()
      };
    }), x = b(() => l().length), ne = b(() => {
      if (e.slotHeight) return e.slotHeight;
      switch (_.value) {
        case 15:
          return 40;
        case 30:
          return 50;
        default:
          return 70;
      }
    }), Y = b(() => {
      const D = [], f = _.value;
      for (let C = 0; C < 24; C++)
        for (let M = 0; M < 60; M += f) {
          const R = `${String(C).padStart(2, "0")}:${String(M).padStart(2, "0")}`, Z = /* @__PURE__ */ new Date();
          Z.setHours(C, M, 0, 0);
          const le = new Intl.DateTimeFormat(e.locale, {
            hour: "numeric",
            minute: "2-digit",
            hour12: !0
          }).format(Z);
          D.push({
            time: R,
            hour: C,
            minute: M,
            formattedTime: le,
            isWorkingHour: S(C)
          });
        }
      return D;
    }), X = b(() => Y.value.filter((D) => D.isWorkingHour)), se = b(() => X.value.filter((D) => a(D).length === 0).length), j = b(() => X.value.filter((D) => a(D).length > 0).length), ee = b(() => {
      const D = X.value.length;
      return D === 0 ? 0 : Math.round(j.value / D * 100);
    }), W = b(() => (/* @__PURE__ */ new Date()).getMinutes() % _.value / _.value * 100), L = (D) => {
      const f = D.getFullYear(), C = String(D.getMonth() + 1).padStart(2, "0"), M = String(D.getDate()).padStart(2, "0");
      return `${f}-${C}-${M}`;
    }, S = (D) => D >= e.workingHours.start && D < e.workingHours.end, v = (D) => {
      if (!P.value.isToday) return !1;
      const f = /* @__PURE__ */ new Date(), C = f.getHours(), M = f.getMinutes(), R = D.minute + _.value;
      return D.hour === C && M >= D.minute && M < R;
    }, l = () => e.events.filter((D) => {
      const f = new Date(D.start), C = new Date(D.end), M = new Date(U.value), R = new Date(M);
      R.setHours(0, 0, 0, 0);
      const Z = new Date(M);
      return Z.setHours(23, 59, 59, 999), f <= Z && C >= R;
    }), a = (D) => e.events.filter((f) => {
      if (f.allDay) return !1;
      const C = new Date(f.start), M = new Date(f.end);
      if (L(C) !== U.value) return !1;
      const Z = new Date(e.currentDate);
      Z.setHours(D.hour, D.minute, 0, 0);
      const le = new Date(Z);
      return le.setMinutes(le.getMinutes() + _.value), C < le && M > Z;
    }), o = (D) => {
      let f = D.backgroundColor || "#3b82f6", C = D.color || "#ffffff";
      if (D.categoryId) {
        const M = e.categories.find((R) => R.id === D.categoryId);
        M && (f = e.theme === "dark" && M.darkBackgroundColor ? M.darkBackgroundColor : M.backgroundColor, C = M.color);
      }
      return {
        backgroundColor: f,
        color: C,
        borderLeft: `3px solid ${C}`
      };
    }, u = (D) => {
      const f = new Date(D.start), M = new Date(D.end).getTime() - f.getTime(), R = Math.round(M / (1e3 * 60));
      if (R < 60)
        return `${R}m`;
      const Z = Math.floor(R / 60), le = R % 60;
      return le > 0 ? `${Z}h ${le}m` : `${Z}h`;
    }, y = (D) => {
      const f = `${U.value}T${D.time}:00`, C = new Date(e.currentDate);
      C.setHours(D.hour, D.minute + _.value, 0, 0);
      const M = `${String(C.getHours()).padStart(2, "0")}:${String(C.getMinutes()).padStart(2, "0")}`, R = `${U.value}T${M}:00`;
      p("slot-click", {
        start: f,
        end: R,
        date: U.value,
        hour: D.hour,
        minute: D.minute
      });
    }, O = (D) => {
      p("event-click", D);
    };
    return (D, f) => (c(), d("div", {
      class: V(["hourly-view", [`theme-${D.theme}`]]),
      style: Q({ "--slot-height": `${ne.value}px`, "--event-min-height": `${D.eventMinHeight}px` })
    }, [
      t("div", da, [
        t("div", ha, [
          t("div", ga, m(P.value.weekday), 1),
          t("div", va, m(P.value.formattedDate), 1)
        ]),
        t("div", ka, [
          P.value.isToday ? (c(), d("span", ma, "Today")) : N("", !0),
          t("span", ya, m(x.value) + " event" + m(x.value !== 1 ? "s" : ""), 1)
        ])
      ]),
      t("div", Da, [
        f[0] || (f[0] = t("span", { class: "interval-label" }, "Interval:", -1)),
        t("div", fa, [
          (c(), d(B, null, F(w, (C) => t("button", {
            key: C,
            type: "button",
            class: V(["interval-btn", { active: _.value === C }]),
            onClick: (M) => _.value = C
          }, m(C) + "min ", 11, wa)), 64))
        ])
      ]),
      t("div", ba, [
        t("div", pa, [
          (c(!0), d(B, null, F(Y.value, (C) => (c(), d("div", {
            key: C.time,
            class: "time-slot-row"
          }, [
            t("div", {
              class: V(["slot-time-label", {
                "working-hour": C.isWorkingHour,
                "hour-start": C.minute === 0
              }])
            }, m(C.formattedTime), 3),
            t("div", {
              class: V(["slot-content", {
                "working-hour": C.isWorkingHour,
                "current-slot": v(C)
              }]),
              onClick: (M) => y(C)
            }, [
              D.showCurrentTimeIndicator && v(C) ? (c(), d("div", {
                key: 0,
                class: "current-time-line",
                style: Q({ top: `${W.value}%` })
              }, f[1] || (f[1] = [
                t("div", { class: "time-marker" }, null, -1)
              ]), 4)) : N("", !0),
              t("div", _a, [
                (c(!0), d(B, null, F(a(C), (M) => (c(), d("div", {
                  key: M.id,
                  class: "slot-event",
                  style: Q(o(M)),
                  onClick: me((R) => O(M), ["stop"])
                }, [
                  t("div", Ca, [
                    t("span", Ta, m(M.title), 1),
                    t("span", Ma, m(u(M)), 1)
                  ]),
                  M.description ? (c(), d("div", Ia, m(M.description), 1)) : N("", !0),
                  M.location ? (c(), d("div", Ha, [
                    f[2] || (f[2] = t("span", { class: "location-icon" }, "📍", -1)),
                    De(" " + m(M.location), 1)
                  ])) : N("", !0)
                ], 12, Sa))), 128))
              ])
            ], 10, $a)
          ]))), 128))
        ])
      ]),
      t("div", Ea, [
        t("div", Oa, [
          t("div", Ba, m(se.value), 1),
          f[3] || (f[3] = t("div", { class: "stat-label" }, "Free Slots", -1))
        ]),
        t("div", Fa, [
          t("div", Wa, m(j.value), 1),
          f[4] || (f[4] = t("div", { class: "stat-label" }, "Busy Slots", -1))
        ]),
        t("div", Va, [
          t("div", Na, m(ee.value) + "%", 1),
          f[5] || (f[5] = t("div", { class: "stat-label" }, "Utilization", -1))
        ])
      ])
    ], 6));
  }
}), La = /* @__PURE__ */ ge(Pa, [["__scopeId", "data-v-79e73dec"]]), Ya = {
  key: 0,
  class: "scheduler-legend legend-top"
}, xa = {
  key: 1,
  class: "scheduler-header"
}, za = {
  key: 0,
  class: "nav-controls"
}, Aa = ["aria-label"], Ra = ["aria-label"], Ua = {
  key: 1,
  class: "period-title"
}, Ga = {
  key: 2,
  class: "view-switcher"
}, ja = ["onClick"], qa = { class: "scheduler-content" }, Ka = {
  key: 2,
  class: "scheduler-legend legend-bottom"
}, Ja = /* @__PURE__ */ he({
  __name: "ResourceSchedulerCalendar",
  props: {
    events: { default: () => [] },
    categories: { default: () => [] },
    selectedDate: { default: () => /* @__PURE__ */ new Date() },
    view: { default: "monthly" },
    theme: { default: "light" },
    locale: { default: "en-US" },
    timeInterval: { default: 60 },
    workingHours: { default: () => ({ start: 9, end: 17, daysOfWeek: [1, 2, 3, 4, 5] }) },
    showWeekNumbers: { type: Boolean, default: !1 },
    showAllDaySlot: { type: Boolean, default: !0 },
    allowEventCreation: { type: Boolean, default: !0 },
    allowEventEditing: { type: Boolean, default: !0 },
    allowEventDeletion: { type: Boolean, default: !0 },
    minDate: {},
    maxDate: {},
    textLabels: { default: () => ({}) },
    firstDayOfWeek: { default: 0 },
    enabledViews: { default: () => ["yearly", "monthly", "weekly", "daily", "hourly"] },
    defaultView: {},
    slotHeight: { default: () => ({ hourly: 60, daily: 48, weekly: 48 }) },
    responsiveBreakpoints: { default: () => ({ mobile: 480, tablet: 768, desktop: 1024 }) },
    headerOptions: { default: () => ({ showNavigation: !0, showToday: !0, showViewSwitcher: !0, showTitle: !0 }) },
    legendOptions: { default: () => ({ show: !0, position: "bottom" }) },
    showCurrentTimeIndicator: { type: Boolean, default: !0 },
    highlightToday: { type: Boolean, default: !0 },
    highlightWeekends: { type: Boolean, default: !1 },
    maxEventsPerSlot: { default: 3 },
    eventMinHeight: { default: 20 },
    compactMode: { type: Boolean, default: !1 }
  },
  emits: ["update:selectedDate", "update:view", "event-click", "event-create", "event-update", "event-delete", "slot-click", "date-click", "view-change", "date-range-change", "conflict-detected"],
  setup(J, { emit: oe }) {
    const e = J, p = oe, w = ue(new Date(e.selectedDate)), _ = ue(e.view), U = b(() => {
      const n = e.headerOptions;
      return (n == null ? void 0 : n.showNavigation) || (n == null ? void 0 : n.showToday) || (n == null ? void 0 : n.showViewSwitcher) || (n == null ? void 0 : n.showTitle);
    }), P = b(() => {
      var n;
      return ((n = e.headerOptions) == null ? void 0 : n.showNavigation) !== !1;
    }), x = b(() => {
      var n;
      return ((n = e.headerOptions) == null ? void 0 : n.showToday) !== !1;
    }), ne = b(() => {
      var n;
      return ((n = e.headerOptions) == null ? void 0 : n.showViewSwitcher) !== !1;
    }), Y = b(() => {
      var n;
      return ((n = e.headerOptions) == null ? void 0 : n.showTitle) !== !1;
    }), X = b(() => {
      var n;
      return ((n = e.legendOptions) == null ? void 0 : n.show) === !1 ? !1 : e.categories && e.categories.length > 0;
    }), se = b(() => {
      var n;
      return ((n = e.legendOptions) == null ? void 0 : n.position) || "bottom";
    }), j = b(() => {
      var n, E, s;
      return {
        hourly: ((n = e.slotHeight) == null ? void 0 : n.hourly) ?? 60,
        daily: ((E = e.slotHeight) == null ? void 0 : E.daily) ?? 48,
        weekly: ((s = e.slotHeight) == null ? void 0 : s.weekly) ?? 48
      };
    }), ee = b(() => {
      var n, E, s;
      return {
        "--breakpoint-mobile": `${((n = e.responsiveBreakpoints) == null ? void 0 : n.mobile) ?? 480}px`,
        "--breakpoint-tablet": `${((E = e.responsiveBreakpoints) == null ? void 0 : E.tablet) ?? 768}px`,
        "--breakpoint-desktop": `${((s = e.responsiveBreakpoints) == null ? void 0 : s.desktop) ?? 1024}px`,
        "--slot-height-hourly": `${j.value.hourly}px`,
        "--slot-height-daily": `${j.value.daily}px`,
        "--slot-height-weekly": `${j.value.weekly}px`,
        "--event-min-height": `${e.eventMinHeight ?? 20}px`
      };
    }), W = b(() => {
      var n, E, s, g, i, h, I, A, G, te, r, k, T, H, z, $, q;
      return {
        today: ((n = e.textLabels) == null ? void 0 : n.today) || "Today",
        previousPeriod: ((E = e.textLabels) == null ? void 0 : E.previousPeriod) || "Previous",
        nextPeriod: ((s = e.textLabels) == null ? void 0 : s.nextPeriod) || "Next",
        yearView: ((g = e.textLabels) == null ? void 0 : g.yearView) || "Year",
        monthView: ((i = e.textLabels) == null ? void 0 : i.monthView) || "Month",
        weekView: ((h = e.textLabels) == null ? void 0 : h.weekView) || "Week",
        dayView: ((I = e.textLabels) == null ? void 0 : I.dayView) || "Day",
        hourView: ((A = e.textLabels) == null ? void 0 : A.hourView) || "Hour",
        allDay: ((G = e.textLabels) == null ? void 0 : G.allDay) || "All Day",
        noEvents: ((te = e.textLabels) == null ? void 0 : te.noEvents) || "No events",
        createEvent: ((r = e.textLabels) == null ? void 0 : r.createEvent) || "Create Event",
        editEvent: ((k = e.textLabels) == null ? void 0 : k.editEvent) || "Edit Event",
        deleteEvent: ((T = e.textLabels) == null ? void 0 : T.deleteEvent) || "Delete Event",
        eventDetails: ((H = e.textLabels) == null ? void 0 : H.eventDetails) || "Event Details",
        conflictWarning: ((z = e.textLabels) == null ? void 0 : z.conflictWarning) || "Time conflict detected",
        cancel: (($ = e.textLabels) == null ? void 0 : $.cancel) || "Cancel",
        save: ((q = e.textLabels) == null ? void 0 : q.save) || "Save"
      };
    }), L = b(() => [
      { value: "yearly", label: W.value.yearView },
      { value: "monthly", label: W.value.monthView },
      { value: "weekly", label: W.value.weekView },
      { value: "daily", label: W.value.dayView },
      { value: "hourly", label: W.value.hourView }
    ]), S = b(() => {
      const n = e.enabledViews || ["yearly", "monthly", "weekly", "daily", "hourly"];
      return L.value.filter((E) => n.includes(E.value));
    }), v = b(() => w.value.getFullYear()), l = b(() => {
      const n = w.value;
      switch (_.value) {
        case "yearly":
          return n.getFullYear().toString();
        case "monthly":
          return new Intl.DateTimeFormat(e.locale, {
            year: "numeric",
            month: "long"
          }).format(n);
        case "weekly": {
          const E = a(n), s = new Date(E);
          s.setDate(s.getDate() + 6);
          const g = new Intl.DateTimeFormat(e.locale, {
            month: "short",
            day: "numeric"
          }).format(E), i = new Intl.DateTimeFormat(e.locale, {
            month: "short",
            day: "numeric",
            year: "numeric"
          }).format(s);
          return `${g} - ${i}`;
        }
        case "daily":
        case "hourly":
          return new Intl.DateTimeFormat(e.locale, {
            weekday: "long",
            year: "numeric",
            month: "long",
            day: "numeric"
          }).format(n);
        default:
          return new Intl.DateTimeFormat(e.locale, {
            year: "numeric",
            month: "long",
            day: "numeric"
          }).format(n);
      }
    }), a = (n) => {
      const E = new Date(n), s = E.getDay(), g = (s < e.firstDayOfWeek ? 7 : 0) + s - e.firstDayOfWeek;
      return E.setDate(E.getDate() - g), E.setHours(0, 0, 0, 0), E;
    }, o = (n) => {
      const E = n.getFullYear(), s = String(n.getMonth() + 1).padStart(2, "0"), g = String(n.getDate()).padStart(2, "0");
      return `${E}-${s}-${g}`;
    }, u = () => {
      const n = new Date(w.value);
      switch (_.value) {
        case "yearly":
          n.setFullYear(n.getFullYear() - 1);
          break;
        case "monthly":
          n.setMonth(n.getMonth() - 1);
          break;
        case "weekly":
          n.setDate(n.getDate() - 7);
          break;
        case "daily":
        case "hourly":
          n.setDate(n.getDate() - 1);
          break;
      }
      w.value = n, p("update:selectedDate", n), f();
    }, y = () => {
      const n = new Date(w.value);
      switch (_.value) {
        case "yearly":
          n.setFullYear(n.getFullYear() + 1);
          break;
        case "monthly":
          n.setMonth(n.getMonth() + 1);
          break;
        case "weekly":
          n.setDate(n.getDate() + 7);
          break;
        case "daily":
        case "hourly":
          n.setDate(n.getDate() + 1);
          break;
      }
      w.value = n, p("update:selectedDate", n), f();
    }, O = () => {
      w.value = /* @__PURE__ */ new Date(), p("update:selectedDate", w.value), f();
    }, D = (n) => {
      (e.enabledViews || ["yearly", "monthly", "weekly", "daily", "hourly"]).includes(n) && (_.value = n, p("update:view", n), p("view-change", n), f());
    }, f = () => {
      const n = C();
      p("date-range-change", n);
    }, C = () => {
      const n = w.value;
      let E, s;
      switch (_.value) {
        case "yearly":
          E = new Date(n.getFullYear(), 0, 1), s = new Date(n.getFullYear(), 11, 31);
          break;
        case "monthly":
          E = new Date(n.getFullYear(), n.getMonth(), 1), s = new Date(n.getFullYear(), n.getMonth() + 1, 0);
          break;
        case "weekly":
          E = a(n), s = new Date(E), s.setDate(s.getDate() + 6);
          break;
        case "daily":
        case "hourly":
        default:
          E = new Date(n), E.setHours(0, 0, 0, 0), s = new Date(n), s.setHours(23, 59, 59, 999);
          break;
      }
      return {
        start: o(E),
        end: o(s)
      };
    }, M = (n) => {
      const E = new Date(w.value);
      E.setMonth(n), w.value = E, (e.enabledViews || ["yearly", "monthly", "weekly", "daily", "hourly"]).includes("monthly") && D("monthly");
    }, R = (n) => {
      w.value = new Date(n), p("date-click", n), p("update:selectedDate", w.value);
    }, Z = (n) => {
      p("event-click", n);
    }, le = (n) => {
      p("slot-click", n), e.allowEventCreation && p("event-create", {
        start: n.start,
        end: n.end,
        allDay: !1
      });
    };
    return ke(() => e.selectedDate, (n) => {
      n && (w.value = new Date(n));
    }), ke(() => e.view, (n) => {
      n && (_.value = n);
    }), ke(() => e.enabledViews, (n) => {
      n && n.length > 0 && !n.includes(_.value) && (_.value = n[0], p("update:view", _.value), p("view-change", _.value));
    }, { immediate: !0 }), (n, E) => (c(), d("div", {
      class: V(["resource-scheduler-calendar", [
        `theme-${n.theme}`,
        { "compact-mode": n.compactMode },
        { "highlight-weekends": n.highlightWeekends }
      ]]),
      style: Q(ee.value)
    }, [
      X.value && se.value === "top" ? (c(), d("div", Ya, [
        (c(!0), d(B, null, F(n.categories, (s) => (c(), d("div", {
          key: s.id,
          class: "legend-item"
        }, [
          t("div", {
            class: "legend-color",
            style: Q({
              backgroundColor: n.theme === "dark" && s.darkBackgroundColor ? s.darkBackgroundColor : s.backgroundColor,
              borderColor: s.color
            })
          }, null, 4),
          t("span", null, m(s.name), 1)
        ]))), 128))
      ])) : N("", !0),
      U.value ? (c(), d("div", xa, [
        P.value ? (c(), d("div", za, [
          t("button", {
            type: "button",
            onClick: u,
            class: "nav-btn",
            "aria-label": W.value.previousPeriod
          }, E[0] || (E[0] = [
            t("span", { class: "nav-arrow" }, "‹", -1)
          ]), 8, Aa),
          x.value ? (c(), d("button", {
            key: 0,
            type: "button",
            onClick: O,
            class: "today-btn"
          }, m(W.value.today), 1)) : N("", !0),
          t("button", {
            type: "button",
            onClick: y,
            class: "nav-btn",
            "aria-label": W.value.nextPeriod
          }, E[1] || (E[1] = [
            t("span", { class: "nav-arrow" }, "›", -1)
          ]), 8, Ra)
        ])) : N("", !0),
        Y.value ? (c(), d("h2", Ua, m(l.value), 1)) : N("", !0),
        ne.value && S.value.length > 1 ? (c(), d("div", Ga, [
          (c(!0), d(B, null, F(S.value, (s) => (c(), d("button", {
            key: s.value,
            type: "button",
            onClick: (g) => D(s.value),
            class: V(["view-btn", { active: _.value === s.value }])
          }, m(s.label), 11, ja))), 128))
        ])) : N("", !0)
      ])) : N("", !0),
      t("div", qa, [
        _.value === "yearly" ? (c(), ye(fn, {
          key: 0,
          year: v.value,
          events: n.events,
          theme: n.theme,
          locale: n.locale,
          categories: n.categories,
          "highlight-today": n.highlightToday,
          "first-day-of-week": n.firstDayOfWeek,
          onMonthClick: M,
          onDateClick: R
        }, null, 8, ["year", "events", "theme", "locale", "categories", "highlight-today", "first-day-of-week"])) : _.value === "monthly" ? (c(), ye(Hn, {
          key: 1,
          "current-date": w.value,
          events: n.events,
          theme: n.theme,
          locale: n.locale,
          categories: n.categories,
          "first-day-of-week": n.firstDayOfWeek,
          "highlight-today": n.highlightToday,
          "highlight-weekends": n.highlightWeekends,
          "max-events-per-slot": n.maxEventsPerSlot,
          "show-week-numbers": n.showWeekNumbers,
          onDateClick: R,
          onEventClick: Z,
          onSlotClick: le
        }, null, 8, ["current-date", "events", "theme", "locale", "categories", "first-day-of-week", "highlight-today", "highlight-weekends", "max-events-per-slot", "show-week-numbers"])) : _.value === "weekly" ? (c(), ye(An, {
          key: 2,
          "current-date": w.value,
          events: n.events,
          theme: n.theme,
          locale: n.locale,
          categories: n.categories,
          "working-hours": n.workingHours,
          "time-interval": n.timeInterval,
          "first-day-of-week": n.firstDayOfWeek,
          "show-all-day-slot": n.showAllDaySlot,
          "highlight-today": n.highlightToday,
          "highlight-weekends": n.highlightWeekends,
          "show-current-time-indicator": n.showCurrentTimeIndicator,
          "slot-height": j.value.weekly,
          "event-min-height": n.eventMinHeight,
          onDateClick: R,
          onEventClick: Z,
          onSlotClick: le
        }, null, 8, ["current-date", "events", "theme", "locale", "categories", "working-hours", "time-interval", "first-day-of-week", "show-all-day-slot", "highlight-today", "highlight-weekends", "show-current-time-indicator", "slot-height", "event-min-height"])) : _.value === "daily" ? (c(), ye(ua, {
          key: 3,
          "current-date": w.value,
          events: n.events,
          theme: n.theme,
          locale: n.locale,
          categories: n.categories,
          "working-hours": n.workingHours,
          "time-interval": n.timeInterval,
          "show-all-day-slot": n.showAllDaySlot,
          "highlight-today": n.highlightToday,
          "show-current-time-indicator": n.showCurrentTimeIndicator,
          "slot-height": j.value.daily,
          "event-min-height": n.eventMinHeight,
          onEventClick: Z,
          onSlotClick: le
        }, null, 8, ["current-date", "events", "theme", "locale", "categories", "working-hours", "time-interval", "show-all-day-slot", "highlight-today", "show-current-time-indicator", "slot-height", "event-min-height"])) : _.value === "hourly" ? (c(), ye(La, {
          key: 4,
          "current-date": w.value,
          events: n.events,
          theme: n.theme,
          locale: n.locale,
          categories: n.categories,
          "working-hours": n.workingHours,
          "time-interval": n.timeInterval,
          "show-current-time-indicator": n.showCurrentTimeIndicator,
          "slot-height": j.value.hourly,
          "event-min-height": n.eventMinHeight,
          onEventClick: Z,
          onSlotClick: le
        }, null, 8, ["current-date", "events", "theme", "locale", "categories", "working-hours", "time-interval", "show-current-time-indicator", "slot-height", "event-min-height"])) : N("", !0)
      ]),
      X.value && se.value === "bottom" ? (c(), d("div", Ka, [
        (c(!0), d(B, null, F(n.categories, (s) => (c(), d("div", {
          key: s.id,
          class: "legend-item"
        }, [
          t("div", {
            class: "legend-color",
            style: Q({
              backgroundColor: n.theme === "dark" && s.darkBackgroundColor ? s.darkBackgroundColor : s.backgroundColor,
              borderColor: s.color
            })
          }, null, 4),
          t("span", null, m(s.name), 1)
        ]))), 128))
      ])) : N("", !0)
    ], 6));
  }
}), Qa = /* @__PURE__ */ ge(Ja, [["__scopeId", "data-v-6cd84d42"]]), Za = {
  install(J) {
    J.component("HotelBookingCalendar", ot), J.component("HotelDashboardCalendar", Qt), J.component("ResourceSchedulerCalendar", Qa);
  }
};
export {
  ot as HotelBookingCalendar,
  Qt as HotelDashboardCalendar,
  Qa as ResourceSchedulerCalendar,
  Za as default
};