@forgebuild/hotal-ui 0.8.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/hotal-ui.js CHANGED
@@ -13023,8 +13023,242 @@ var Fh, Ih, Lh, Rh, zh, Bh, Vh, Hh, Uh, Wh, Gh, Kh, qh, Jh, Yh = o((() => {
13023
13023
  requestCancel: { type: "Object" },
13024
13024
  confirmCancel: { type: "Object" }
13025
13025
  }, [], [], { mode: "open" }));
13026
+ })), Xh = /* @__PURE__ */ c({ default: () => Zh });
13027
+ function Zh(e, t) {
13028
+ dt(t, !0), Ea(e, cg);
13029
+ let n = (e) => {
13030
+ var t = $h();
13031
+ let n;
13032
+ var r = H(t), i = (e) => {
13033
+ X(e, wi("Connecting…"));
13034
+ }, a = (e) => {
13035
+ X(e, wi("Live updates unavailable — showing loaded reservations only."));
13036
+ }, o = (e) => {
13037
+ var t = Qh();
13038
+ Ye(), X(e, t);
13039
+ };
13040
+ Q(r, (e) => {
13041
+ K(f) === "connecting" ? e(i) : K(f) === "error" ? e(a, 1) : e(o, -1);
13042
+ }), P(t), W(() => n = Ia(t, 1, "lrf-status svelte-1d6cuoy", null, n, { "lrf-status-error": K(f) === "error" })), X(e, t);
13043
+ }, r = $(t, "heading", 7), i = $(t, "channelName", 7), a = $(t, "ablyAuthUrl", 7), o = $(t, "fetchReservations", 7), s = $(t, "restaurants", 7), c = $(t, "maxItems", 7, 30), l = $(t, "emptyLabel", 7, "No reservations yet."), d = /* @__PURE__ */ B(Un([])), f = /* @__PURE__ */ B("connecting"), p = /* @__PURE__ */ nn(() => new Map((s() ?? []).map((e) => [e.id, e.name])));
13044
+ function m(e) {
13045
+ let t = K(d).filter((t) => t.id !== e.id);
13046
+ V(d, [e, ...t].slice(0, c()), !0);
13047
+ }
13048
+ function h(e) {
13049
+ try {
13050
+ return (/* @__PURE__ */ new Date(`${e}T00:00:00`)).toLocaleDateString(void 0, {
13051
+ month: "short",
13052
+ day: "numeric",
13053
+ year: "numeric"
13054
+ });
13055
+ } catch {
13056
+ return e;
13057
+ }
13058
+ }
13059
+ function g(e) {
13060
+ let [t, n] = e.split(":"), r = Number(t);
13061
+ if (Number.isNaN(r) || n === void 0) return e;
13062
+ let i = r >= 12 ? "PM" : "AM";
13063
+ return `${r % 12 == 0 ? 12 : r % 12}:${n} ${i}`;
13064
+ }
13065
+ function _(e) {
13066
+ try {
13067
+ return new Date(e).toLocaleString(void 0, {
13068
+ month: "short",
13069
+ day: "numeric",
13070
+ hour: "numeric",
13071
+ minute: "2-digit"
13072
+ });
13073
+ } catch {
13074
+ return e;
13075
+ }
13076
+ }
13077
+ fr(() => {
13078
+ if (typeof window > "u" || !i() || !a()) return;
13079
+ let e, t = !1;
13080
+ return (async () => {
13081
+ if (o()) try {
13082
+ let e = await o()();
13083
+ t || V(d, e.slice(0, c()), !0);
13084
+ } catch (e) {
13085
+ console.error("live-reservations-feed: failed to load existing reservations", e);
13086
+ }
13087
+ try {
13088
+ let { default: n } = await Promise.resolve().then(() => /* @__PURE__ */ u(th()));
13089
+ if (t) return;
13090
+ e = new n.Realtime({ authUrl: a() });
13091
+ let r = e.channels.get(i());
13092
+ e.connection.on("connected", () => {
13093
+ t || V(f, "connected");
13094
+ }), e.connection.on("failed", () => {
13095
+ t || V(f, "error");
13096
+ }), await r.subscribe("new-reservation", (e) => {
13097
+ t || m(e.data);
13098
+ }), await r.subscribe("reservation-status-changed", (e) => {
13099
+ t || m(e.data);
13100
+ });
13101
+ } catch (e) {
13102
+ console.error("live-reservations-feed: Ably connection failed", e), t || V(f, "error");
13103
+ }
13104
+ })(), () => {
13105
+ t = !0, e?.close();
13106
+ };
13107
+ });
13108
+ var v = {
13109
+ get heading() {
13110
+ return r();
13111
+ },
13112
+ set heading(e) {
13113
+ r(e), R();
13114
+ },
13115
+ get channelName() {
13116
+ return i();
13117
+ },
13118
+ set channelName(e) {
13119
+ i(e), R();
13120
+ },
13121
+ get ablyAuthUrl() {
13122
+ return a();
13123
+ },
13124
+ set ablyAuthUrl(e) {
13125
+ a(e), R();
13126
+ },
13127
+ get fetchReservations() {
13128
+ return o();
13129
+ },
13130
+ set fetchReservations(e) {
13131
+ o(e), R();
13132
+ },
13133
+ get restaurants() {
13134
+ return s();
13135
+ },
13136
+ set restaurants(e) {
13137
+ s(e), R();
13138
+ },
13139
+ get maxItems() {
13140
+ return c();
13141
+ },
13142
+ set maxItems(e = 30) {
13143
+ c(e), R();
13144
+ },
13145
+ get emptyLabel() {
13146
+ return l();
13147
+ },
13148
+ set emptyLabel(e = "No reservations yet.") {
13149
+ l(e), R();
13150
+ }
13151
+ }, y = sg(), b = H(y), x = (e) => {
13152
+ var t = eg(), i = H(t), a = H(i, !0);
13153
+ P(i);
13154
+ var o = U(i, 2);
13155
+ n(o), P(t), W(() => Z(a, r())), X(e, t);
13156
+ }, S = (e) => {
13157
+ n(e);
13158
+ };
13159
+ Q(b, (e) => {
13160
+ r() ? e(x) : e(S, -1);
13161
+ });
13162
+ var C = U(b, 2), w = (e) => {
13163
+ var t = tg(), n = H(t, !0);
13164
+ P(t), W(() => Z(n, l())), X(e, t);
13165
+ }, T = (e) => {
13166
+ var t = og();
13167
+ ua(t, 21, () => K(d), (e) => e.id, (e, t) => {
13168
+ var n = ag(), r = H(n), i = H(r), a = H(i, !0);
13169
+ P(i);
13170
+ var o = U(i, 2), s = H(o);
13171
+ let c;
13172
+ var l = H(s, !0);
13173
+ P(s);
13174
+ var u = U(s, 2), d = H(u);
13175
+ P(u), P(o), P(r);
13176
+ var f = U(r, 2), m = H(f), v = U(H(m));
13177
+ P(m);
13178
+ var y = U(m, 2), b = U(H(y));
13179
+ P(y);
13180
+ var x = U(y, 2), S = U(H(x));
13181
+ P(x);
13182
+ var C = U(x, 2), w = (e) => {
13183
+ var n = ng(), r = H(n, !0);
13184
+ P(n), W((e) => Z(r, e), [() => K(p).get(K(t).restaurant_id)]), X(e, n);
13185
+ }, T = /* @__PURE__ */ nn(() => K(t).restaurant_id && K(p).get(K(t).restaurant_id));
13186
+ Q(C, (e) => {
13187
+ K(T) && e(w);
13188
+ });
13189
+ var E = U(C, 2), D = (e) => {
13190
+ var n = ng(), r = H(n);
13191
+ P(n), W(() => Z(r, `Table ${K(t).table_number ?? ""}`)), X(e, n);
13192
+ };
13193
+ Q(E, (e) => {
13194
+ K(t).table_number && e(D);
13195
+ }), P(f);
13196
+ var ee = U(f, 2), O = (e) => {
13197
+ var n = ig(), r = H(n), i = (e) => {
13198
+ var n = rg(), r = H(n, !0);
13199
+ P(n), W(() => {
13200
+ Ua(n, "href", `mailto:${K(t).contact_email}`), Z(r, K(t).contact_email);
13201
+ }), X(e, n);
13202
+ };
13203
+ Q(r, (e) => {
13204
+ K(t).contact_email && e(i);
13205
+ });
13206
+ var a = U(r, 2), o = (e) => {
13207
+ var n = ng(), r = H(n, !0);
13208
+ P(n), W(() => Z(r, K(t).contact_phone)), X(e, n);
13209
+ };
13210
+ Q(a, (e) => {
13211
+ K(t).contact_phone && e(o);
13212
+ }), P(n), X(e, n);
13213
+ };
13214
+ Q(ee, (e) => {
13215
+ (K(t).contact_email || K(t).contact_phone) && e(O);
13216
+ }), P(n), W((e, n, r) => {
13217
+ Z(a, K(t).contact_name), c = Ia(s, 1, "lrf-item-status svelte-1d6cuoy", null, c, {
13218
+ "lrf-status-cancelled": K(t).status === "cancelled",
13219
+ "lrf-status-confirmed": K(t).status === "confirmed"
13220
+ }), Z(l, K(t).status), Z(d, `Booked ${e ?? ""}`), Z(v, ` ${n ?? ""}`), Z(b, ` ${r ?? ""}`), Z(S, ` ${K(t).party_size ?? ""} guests`);
13221
+ }, [
13222
+ () => _(K(t).created_at),
13223
+ () => h(K(t).reservation_date),
13224
+ () => g(K(t).start_time)
13225
+ ]), X(e, n);
13226
+ }), P(t), X(e, t);
13227
+ };
13228
+ return Q(C, (e) => {
13229
+ K(d).length === 0 ? e(w) : e(T, -1);
13230
+ }), P(y), X(e, y), I(v);
13231
+ }
13232
+ var Qh, $h, eg, tg, ng, rg, ig, ag, og, sg, cg, lg = o((() => {
13233
+ f(), Do(), Qh = /* @__PURE__ */ Y("<span class=\"lrf-live-dot svelte-1d6cuoy\" aria-hidden=\"true\"></span> Live", 1), $h = /* @__PURE__ */ Y("<div><!></div>"), eg = /* @__PURE__ */ Y("<div class=\"lrf-header svelte-1d6cuoy\"><h2 class=\"lrf-heading svelte-1d6cuoy\"> </h2> <!></div>"), tg = /* @__PURE__ */ Y("<p class=\"lrf-empty svelte-1d6cuoy\"> </p>"), ng = /* @__PURE__ */ Y("<span class=\"svelte-1d6cuoy\"> </span>"), rg = /* @__PURE__ */ Y("<a class=\"svelte-1d6cuoy\"> </a>"), ig = /* @__PURE__ */ Y("<div class=\"lrf-item-contact svelte-1d6cuoy\"><!> <!></div>"), ag = /* @__PURE__ */ Y("<li class=\"lrf-item svelte-1d6cuoy\"><div class=\"lrf-item-header svelte-1d6cuoy\"><span class=\"lrf-item-name svelte-1d6cuoy\"> </span> <div class=\"lrf-item-header-right svelte-1d6cuoy\"><span> </span> <span class=\"lrf-item-received svelte-1d6cuoy\"> </span></div></div> <div class=\"lrf-item-meta svelte-1d6cuoy\"><span class=\"lrf-meta-item svelte-1d6cuoy\"><svg class=\"lrf-meta-icon svelte-1d6cuoy\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" aria-hidden=\"true\"><rect x=\"3\" y=\"5\" width=\"18\" height=\"16\" rx=\"2\" class=\"svelte-1d6cuoy\"></rect><path d=\"M3 10h18M8 3v4M16 3v4\" stroke-linecap=\"round\" class=\"svelte-1d6cuoy\"></path></svg> </span> <span class=\"lrf-meta-item svelte-1d6cuoy\"><svg class=\"lrf-meta-icon svelte-1d6cuoy\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"9\" class=\"svelte-1d6cuoy\"></circle><path d=\"M12 7v5l3.5 2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"svelte-1d6cuoy\"></path></svg> </span> <span class=\"lrf-meta-item svelte-1d6cuoy\"><svg class=\"lrf-meta-icon svelte-1d6cuoy\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" aria-hidden=\"true\"><circle cx=\"9\" cy=\"8\" r=\"3\" class=\"svelte-1d6cuoy\"></circle><path d=\"M2 20c0-3.3 3.1-6 7-6s7 2.7 7 6\" stroke-linecap=\"round\" class=\"svelte-1d6cuoy\"></path><path d=\"M16 9a3 3 0 1 0 0-6\" stroke-linecap=\"round\" class=\"svelte-1d6cuoy\"></path><path d=\"M22 20c0-2.6-1.9-4.8-4.5-5.6\" stroke-linecap=\"round\" class=\"svelte-1d6cuoy\"></path></svg> </span> <!> <!></div> <!></li>"), og = /* @__PURE__ */ Y("<ul class=\"lrf-list svelte-1d6cuoy\"></ul>"), sg = /* @__PURE__ */ Y("<section class=\"lrf-root svelte-1d6cuoy\"><!> <!></section>"), cg = {
13234
+ hash: "svelte-1d6cuoy",
13235
+ code: ".lrf-root.svelte-1d6cuoy {display:block;font-family:inherit;color:var(--lrf-text-color, #1a1a1a);}.lrf-header.svelte-1d6cuoy {display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:1rem;}.lrf-heading.svelte-1d6cuoy {margin:0;font-size:1.125rem;font-weight:700;}.lrf-status.svelte-1d6cuoy {display:flex;justify-content:flex-end;align-items:center;gap:0.375rem;margin-bottom:1rem;font-size:0.75rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;color:var(--lrf-live-color, #1a7d3a);}.lrf-header.svelte-1d6cuoy .lrf-status:where(.svelte-1d6cuoy) {margin-bottom:0;}.lrf-status-error.svelte-1d6cuoy {color:var(--lrf-error-color, #b3261e);}.lrf-live-dot.svelte-1d6cuoy {position:relative;width:0.5rem;height:0.5rem;flex-shrink:0;border-radius:9999px;background:currentColor;}.lrf-live-dot.svelte-1d6cuoy::before {content:'';position:absolute;inset:0;border-radius:9999px;background:currentColor;\n animation: svelte-1d6cuoy-lrf-pulse 1.8s ease-out infinite;}\n @media (prefers-reduced-motion: reduce) {.lrf-live-dot.svelte-1d6cuoy::before {\n animation: none;}\n }\n @keyframes svelte-1d6cuoy-lrf-pulse {\n 0% {\n transform: scale(1);\n opacity: 0.6;\n }\n 100% {\n transform: scale(2.5);\n opacity: 0;\n }\n }.lrf-empty.svelte-1d6cuoy {opacity:0.6;font-size:0.875rem;}.lrf-list.svelte-1d6cuoy {display:flex;flex-direction:column;gap:0.75rem;margin:0;padding:0;list-style:none;}.lrf-item.svelte-1d6cuoy {border:1px solid var(--lrf-border-color, rgba(0, 0, 0, 0.1));border-radius:4px;padding:0.875rem 1rem;background:var(--lrf-item-bg, #fff);}.lrf-item-header.svelte-1d6cuoy {display:flex;align-items:flex-start;justify-content:space-between;gap:0.5rem;}.lrf-item-name.svelte-1d6cuoy {font-weight:700;}.lrf-item-header-right.svelte-1d6cuoy {display:flex;flex-direction:column;align-items:flex-end;gap:0.25rem;flex-shrink:0;}.lrf-item-status.svelte-1d6cuoy {font-size:0.6875rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;padding:0.125rem 0.5rem;border-radius:2px;background:var(--lrf-status-bg, rgba(0, 0, 0, 0.06));}.lrf-status-confirmed.svelte-1d6cuoy {background:var(--lrf-status-confirmed-bg, #dcf5e3);color:var(--lrf-status-confirmed-text, #146c2e);}.lrf-status-cancelled.svelte-1d6cuoy {background:var(--lrf-status-cancelled-bg, #fbdcdc);color:var(--lrf-status-cancelled-text, #8a1c1c);}.lrf-item-received.svelte-1d6cuoy {font-size:0.6875rem;font-weight:400;text-transform:none;letter-spacing:normal;white-space:nowrap;opacity:0.55;}.lrf-item-meta.svelte-1d6cuoy,\n .lrf-item-contact.svelte-1d6cuoy {display:flex;flex-wrap:wrap;gap:0.5rem 0.75rem;margin-top:0.375rem;font-size:0.8125rem;opacity:0.75;}.lrf-item-contact.svelte-1d6cuoy a:where(.svelte-1d6cuoy) {color:inherit;}.lrf-meta-item.svelte-1d6cuoy {display:inline-flex;align-items:center;gap:0.3125rem;}.lrf-meta-icon.svelte-1d6cuoy {width:0.875rem;height:0.875rem;flex-shrink:0;opacity:0.8;}"
13236
+ }, customElements.define("live-reservations-feed", Co(Zh, {
13237
+ heading: {
13238
+ attribute: "heading",
13239
+ type: "String"
13240
+ },
13241
+ channelName: {
13242
+ attribute: "channel-name",
13243
+ type: "String"
13244
+ },
13245
+ ablyAuthUrl: {
13246
+ attribute: "ably-auth-url",
13247
+ type: "String"
13248
+ },
13249
+ maxItems: {
13250
+ attribute: "max-items",
13251
+ type: "Number"
13252
+ },
13253
+ emptyLabel: {
13254
+ attribute: "empty-label",
13255
+ type: "String"
13256
+ },
13257
+ fetchReservations: {},
13258
+ restaurants: {}
13259
+ }, [], [], { mode: "open" }));
13026
13260
  }));
13027
13261
  //#endregion
13028
13262
  //#region src/index.ts
13029
- typeof customElements < "u" && (Promise.resolve().then(() => (Pc(), Ec)), Promise.resolve().then(() => (xl(), sl)), Promise.resolve().then(() => (eh(), Pm)), Promise.resolve().then(() => (hh(), nh)), Promise.resolve().then(() => (Mh(), gh)), Promise.resolve().then(() => (Yh(), Nh)));
13263
+ typeof customElements < "u" && (Promise.resolve().then(() => (Pc(), Ec)), Promise.resolve().then(() => (xl(), sl)), Promise.resolve().then(() => (eh(), Pm)), Promise.resolve().then(() => (hh(), nh)), Promise.resolve().then(() => (Mh(), gh)), Promise.resolve().then(() => (Yh(), Nh)), Promise.resolve().then(() => (lg(), Xh)));
13030
13264
  //#endregion
package/dist/index.d.ts CHANGED
@@ -152,6 +152,36 @@ export interface ReservationCancelElement extends HTMLElement {
152
152
  confirmCancel?: (payload: { token: string }) => Promise<CancelActionResult>;
153
153
  }
154
154
 
155
+ export interface LiveReservation {
156
+ id: string;
157
+ restaurant_id?: string | null;
158
+ reservation_date: string;
159
+ start_time: string;
160
+ party_size: number;
161
+ status: string;
162
+ contact_name: string;
163
+ contact_email?: string | null;
164
+ contact_phone?: string | null;
165
+ table_number?: string | null;
166
+ location?: string | null;
167
+ created_at: string;
168
+ }
169
+
170
+ export interface LiveReservationRestaurantRef {
171
+ id: string;
172
+ name: string;
173
+ }
174
+
175
+ export interface LiveReservationsFeedElement extends HTMLElement {
176
+ heading?: string;
177
+ channelName?: string;
178
+ ablyAuthUrl?: string;
179
+ fetchReservations?: () => Promise<LiveReservation[]>;
180
+ restaurants?: LiveReservationRestaurantRef[];
181
+ maxItems?: number;
182
+ emptyLabel?: string;
183
+ }
184
+
155
185
  declare global {
156
186
  interface HTMLElementTagNameMap {
157
187
  'reservation-bar': ReservationBarElement;
@@ -160,6 +190,7 @@ declare global {
160
190
  'event-inquiries-feed': EventInquiriesFeedElement;
161
191
  'event-contact-form': EventContactFormElement;
162
192
  'reservation-cancel': ReservationCancelElement;
193
+ 'live-reservations-feed': LiveReservationsFeedElement;
163
194
  }
164
195
 
165
196
  interface HTMLElementEventMap {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgebuild/hotal-ui",
3
- "version": "0.8.2",
3
+ "version": "0.9.0",
4
4
  "description": "Reusable Svelte UI components for booking and reservation experiences.",
5
5
  "type": "module",
6
6
  "license": "MIT",