@pichetch08/trip-ui 0.1.0 → 0.2.1

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.
Files changed (167) hide show
  1. package/dist/{accordion.js → components/shared/accordion.js} +1 -1
  2. package/dist/{agreement-modal.js → components/shared/agreement-modal.js} +1 -1
  3. package/dist/{alert.js → components/shared/alert.js} +1 -1
  4. package/dist/{auth-hero.js → components/shared/auth-hero.js} +1 -1
  5. package/dist/{avatar.js → components/shared/avatar.js} +1 -1
  6. package/dist/{badge.js → components/shared/badge.js} +1 -1
  7. package/dist/{banner.js → components/shared/banner.js} +1 -1
  8. package/dist/{breadcrumb.js → components/shared/breadcrumb.js} +1 -1
  9. package/dist/{button.js → components/shared/button.js} +1 -1
  10. package/dist/{card.js → components/shared/card.js} +1 -1
  11. package/dist/{change-summary-modal.js → components/shared/change-summary-modal.js} +1 -1
  12. package/dist/{channel-badge.js → components/shared/channel-badge.js} +1 -1
  13. package/dist/{checkbox.js → components/shared/checkbox.js} +1 -1
  14. package/dist/{color-picker.js → components/shared/color-picker.js} +1 -1
  15. package/dist/{confirm-dialog.js → components/shared/confirm-dialog.js} +1 -1
  16. package/dist/{copy-button.js → components/shared/copy-button.js} +1 -1
  17. package/dist/{dashed-add-button.js → components/shared/dashed-add-button.js} +1 -1
  18. package/dist/{data-table.js → components/shared/data-table.js} +1 -1
  19. package/dist/{date-picker.js → components/shared/date-picker.js} +1 -1
  20. package/dist/{date-range-picker.js → components/shared/date-range-picker.js} +1 -1
  21. package/dist/{dev-auto-fill.js → components/shared/dev-auto-fill.js} +1 -1
  22. package/dist/{divider.js → components/shared/divider.js} +1 -1
  23. package/dist/{drawer.js → components/shared/drawer.js} +1 -1
  24. package/dist/{dropdown-menu.js → components/shared/dropdown-menu.js} +1 -1
  25. package/dist/{empty-state.js → components/shared/empty-state.js} +1 -1
  26. package/dist/{file-upload.js → components/shared/file-upload.js} +1 -1
  27. package/dist/{filter-tabs.js → components/shared/filter-tabs.js} +1 -1
  28. package/dist/{footer-action-bar.js → components/shared/footer-action-bar.js} +1 -1
  29. package/dist/{form-input.js → components/shared/form-input.js} +1 -1
  30. package/dist/{form-textarea.js → components/shared/form-textarea.js} +1 -1
  31. package/dist/{icon-button.js → components/shared/icon-button.js} +1 -1
  32. package/dist/{icon-picker.js → components/shared/icon-picker.js} +1 -1
  33. package/dist/{icon-wrapper.js → components/shared/icon-wrapper.js} +1 -1
  34. package/dist/{image-upload.js → components/shared/image-upload.js} +1 -1
  35. package/dist/{index.d.ts → components/shared/index.d.ts} +11 -0
  36. package/dist/{index.js → components/shared/index.js} +51 -1
  37. package/dist/{kbd.js → components/shared/kbd.js} +1 -1
  38. package/dist/{mobile-preview.js → components/shared/mobile-preview.js} +1 -1
  39. package/dist/{modal.js → components/shared/modal.js} +1 -1
  40. package/dist/{multi-select.js → components/shared/multi-select.js} +1 -1
  41. package/dist/{number-input.js → components/shared/number-input.js} +1 -1
  42. package/dist/{otp-input.js → components/shared/otp-input.js} +1 -1
  43. package/dist/{page-header.js → components/shared/page-header.js} +1 -1
  44. package/dist/{page-state.js → components/shared/page-state.js} +1 -1
  45. package/dist/{pagination.js → components/shared/pagination.js} +1 -1
  46. package/dist/{popover.js → components/shared/popover.js} +1 -1
  47. package/dist/{preview-drawer.js → components/shared/preview-drawer.js} +1 -1
  48. package/dist/{progress-bar.js → components/shared/progress-bar.js} +1 -1
  49. package/dist/{qr-code-display.js → components/shared/qr-code-display.js} +1 -1
  50. package/dist/{radio-group.js → components/shared/radio-group.js} +1 -1
  51. package/dist/{rating.js → components/shared/rating.js} +1 -1
  52. package/dist/{rich-editor.js → components/shared/rich-editor.js} +1 -1
  53. package/dist/{search-bar.js → components/shared/search-bar.js} +1 -1
  54. package/dist/{section-header.js → components/shared/section-header.js} +1 -1
  55. package/dist/{segmented-control.js → components/shared/segmented-control.js} +1 -1
  56. package/dist/{select-picker.js → components/shared/select-picker.js} +1 -1
  57. package/dist/{skeleton.js → components/shared/skeleton.js} +1 -1
  58. package/dist/{slider.js → components/shared/slider.js} +1 -1
  59. package/dist/{spinner.js → components/shared/spinner.js} +1 -1
  60. package/dist/{stat-card.js → components/shared/stat-card.js} +1 -1
  61. package/dist/{stats-summary.js → components/shared/stats-summary.js} +1 -1
  62. package/dist/{status-badge.js → components/shared/status-badge.js} +1 -1
  63. package/dist/{stepper.js → components/shared/stepper.js} +1 -1
  64. package/dist/{tabs.js → components/shared/tabs.js} +1 -1
  65. package/dist/{tag.js → components/shared/tag.js} +1 -1
  66. package/dist/{time-picker.js → components/shared/time-picker.js} +1 -1
  67. package/dist/{timeline.js → components/shared/timeline.js} +1 -1
  68. package/dist/{toast.js → components/shared/toast.js} +1 -1
  69. package/dist/{toggle-switch.js → components/shared/toggle-switch.js} +1 -1
  70. package/dist/{tooltip.js → components/shared/tooltip.js} +1 -1
  71. package/dist/{trip-day-map-lazy.d.ts → components/shared/trip-day-map-lazy.d.ts} +6 -0
  72. package/dist/{trip-day-map-lazy.js → components/shared/trip-day-map-lazy.js} +2 -2
  73. package/dist/components/shared/trip-day-map.d.ts +28 -0
  74. package/dist/components/shared/trip-day-map.js +146 -0
  75. package/dist/components/trip/acknowledge-banner.d.ts +9 -0
  76. package/dist/components/trip/acknowledge-banner.js +47 -0
  77. package/dist/components/trip/activity-item.d.ts +8 -0
  78. package/dist/components/trip/activity-item.js +174 -0
  79. package/dist/components/trip/company-footer.d.ts +9 -0
  80. package/dist/components/trip/company-footer.js +99 -0
  81. package/dist/components/trip/countdown-badge.d.ts +7 -0
  82. package/dist/components/trip/countdown-badge.js +39 -0
  83. package/dist/components/trip/day-card.d.ts +8 -0
  84. package/dist/components/trip/day-card.js +62 -0
  85. package/dist/components/trip/emergency-card.d.ts +8 -0
  86. package/dist/components/trip/emergency-card.js +34 -0
  87. package/dist/components/trip/index.d.ts +9 -0
  88. package/dist/components/trip/index.js +19 -0
  89. package/dist/components/trip/info-badge.d.ts +8 -0
  90. package/dist/components/trip/info-badge.js +21 -0
  91. package/dist/components/trip/sticky-day-nav.d.ts +10 -0
  92. package/dist/components/trip/sticky-day-nav.js +36 -0
  93. package/dist/types/trip.d.ts +111 -0
  94. package/dist/types/trip.js +0 -0
  95. package/dist/utils/trip-utils.d.ts +29 -0
  96. package/dist/utils/trip-utils.js +166 -0
  97. package/package.json +17 -8
  98. package/dist/trip-day-map.d.ts +0 -15
  99. package/dist/trip-day-map.js +0 -62
  100. /package/dist/{accordion.d.ts → components/shared/accordion.d.ts} +0 -0
  101. /package/dist/{agreement-modal.d.ts → components/shared/agreement-modal.d.ts} +0 -0
  102. /package/dist/{alert.d.ts → components/shared/alert.d.ts} +0 -0
  103. /package/dist/{auth-hero.d.ts → components/shared/auth-hero.d.ts} +0 -0
  104. /package/dist/{avatar.d.ts → components/shared/avatar.d.ts} +0 -0
  105. /package/dist/{badge.d.ts → components/shared/badge.d.ts} +0 -0
  106. /package/dist/{banner.d.ts → components/shared/banner.d.ts} +0 -0
  107. /package/dist/{breadcrumb.d.ts → components/shared/breadcrumb.d.ts} +0 -0
  108. /package/dist/{button.d.ts → components/shared/button.d.ts} +0 -0
  109. /package/dist/{card.d.ts → components/shared/card.d.ts} +0 -0
  110. /package/dist/{change-summary-modal.d.ts → components/shared/change-summary-modal.d.ts} +0 -0
  111. /package/dist/{channel-badge.d.ts → components/shared/channel-badge.d.ts} +0 -0
  112. /package/dist/{checkbox.d.ts → components/shared/checkbox.d.ts} +0 -0
  113. /package/dist/{color-picker.d.ts → components/shared/color-picker.d.ts} +0 -0
  114. /package/dist/{confirm-dialog.d.ts → components/shared/confirm-dialog.d.ts} +0 -0
  115. /package/dist/{copy-button.d.ts → components/shared/copy-button.d.ts} +0 -0
  116. /package/dist/{dashed-add-button.d.ts → components/shared/dashed-add-button.d.ts} +0 -0
  117. /package/dist/{data-table.d.ts → components/shared/data-table.d.ts} +0 -0
  118. /package/dist/{date-picker.d.ts → components/shared/date-picker.d.ts} +0 -0
  119. /package/dist/{date-range-picker.d.ts → components/shared/date-range-picker.d.ts} +0 -0
  120. /package/dist/{dev-auto-fill.d.ts → components/shared/dev-auto-fill.d.ts} +0 -0
  121. /package/dist/{divider.d.ts → components/shared/divider.d.ts} +0 -0
  122. /package/dist/{drawer.d.ts → components/shared/drawer.d.ts} +0 -0
  123. /package/dist/{dropdown-menu.d.ts → components/shared/dropdown-menu.d.ts} +0 -0
  124. /package/dist/{empty-state.d.ts → components/shared/empty-state.d.ts} +0 -0
  125. /package/dist/{file-upload.d.ts → components/shared/file-upload.d.ts} +0 -0
  126. /package/dist/{filter-tabs.d.ts → components/shared/filter-tabs.d.ts} +0 -0
  127. /package/dist/{footer-action-bar.d.ts → components/shared/footer-action-bar.d.ts} +0 -0
  128. /package/dist/{form-input.d.ts → components/shared/form-input.d.ts} +0 -0
  129. /package/dist/{form-textarea.d.ts → components/shared/form-textarea.d.ts} +0 -0
  130. /package/dist/{icon-button.d.ts → components/shared/icon-button.d.ts} +0 -0
  131. /package/dist/{icon-picker.d.ts → components/shared/icon-picker.d.ts} +0 -0
  132. /package/dist/{icon-wrapper.d.ts → components/shared/icon-wrapper.d.ts} +0 -0
  133. /package/dist/{image-upload.d.ts → components/shared/image-upload.d.ts} +0 -0
  134. /package/dist/{kbd.d.ts → components/shared/kbd.d.ts} +0 -0
  135. /package/dist/{mobile-preview.d.ts → components/shared/mobile-preview.d.ts} +0 -0
  136. /package/dist/{modal.d.ts → components/shared/modal.d.ts} +0 -0
  137. /package/dist/{multi-select.d.ts → components/shared/multi-select.d.ts} +0 -0
  138. /package/dist/{number-input.d.ts → components/shared/number-input.d.ts} +0 -0
  139. /package/dist/{otp-input.d.ts → components/shared/otp-input.d.ts} +0 -0
  140. /package/dist/{page-header.d.ts → components/shared/page-header.d.ts} +0 -0
  141. /package/dist/{page-state.d.ts → components/shared/page-state.d.ts} +0 -0
  142. /package/dist/{pagination.d.ts → components/shared/pagination.d.ts} +0 -0
  143. /package/dist/{popover.d.ts → components/shared/popover.d.ts} +0 -0
  144. /package/dist/{preview-drawer.d.ts → components/shared/preview-drawer.d.ts} +0 -0
  145. /package/dist/{progress-bar.d.ts → components/shared/progress-bar.d.ts} +0 -0
  146. /package/dist/{qr-code-display.d.ts → components/shared/qr-code-display.d.ts} +0 -0
  147. /package/dist/{radio-group.d.ts → components/shared/radio-group.d.ts} +0 -0
  148. /package/dist/{rating.d.ts → components/shared/rating.d.ts} +0 -0
  149. /package/dist/{rich-editor.d.ts → components/shared/rich-editor.d.ts} +0 -0
  150. /package/dist/{search-bar.d.ts → components/shared/search-bar.d.ts} +0 -0
  151. /package/dist/{section-header.d.ts → components/shared/section-header.d.ts} +0 -0
  152. /package/dist/{segmented-control.d.ts → components/shared/segmented-control.d.ts} +0 -0
  153. /package/dist/{select-picker.d.ts → components/shared/select-picker.d.ts} +0 -0
  154. /package/dist/{skeleton.d.ts → components/shared/skeleton.d.ts} +0 -0
  155. /package/dist/{slider.d.ts → components/shared/slider.d.ts} +0 -0
  156. /package/dist/{spinner.d.ts → components/shared/spinner.d.ts} +0 -0
  157. /package/dist/{stat-card.d.ts → components/shared/stat-card.d.ts} +0 -0
  158. /package/dist/{stats-summary.d.ts → components/shared/stats-summary.d.ts} +0 -0
  159. /package/dist/{status-badge.d.ts → components/shared/status-badge.d.ts} +0 -0
  160. /package/dist/{stepper.d.ts → components/shared/stepper.d.ts} +0 -0
  161. /package/dist/{tabs.d.ts → components/shared/tabs.d.ts} +0 -0
  162. /package/dist/{tag.d.ts → components/shared/tag.d.ts} +0 -0
  163. /package/dist/{time-picker.d.ts → components/shared/time-picker.d.ts} +0 -0
  164. /package/dist/{timeline.d.ts → components/shared/timeline.d.ts} +0 -0
  165. /package/dist/{toast.d.ts → components/shared/toast.d.ts} +0 -0
  166. /package/dist/{toggle-switch.d.ts → components/shared/toggle-switch.d.ts} +0 -0
  167. /package/dist/{tooltip.d.ts → components/shared/tooltip.d.ts} +0 -0
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import "./chunk-ORMEWXMH.js";
2
+ import "../../chunk-ORMEWXMH.js";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
  function Tabs({
5
5
  items,
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import "./chunk-ORMEWXMH.js";
2
+ import "../../chunk-ORMEWXMH.js";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
  import { useState, useRef } from "react";
5
5
  const TAG_BG = {
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import "./chunk-ORMEWXMH.js";
2
+ import "../../chunk-ORMEWXMH.js";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
  import { useState, useRef, useEffect, useCallback } from "react";
5
5
  const QUICK_TIMES = [
@@ -1,4 +1,4 @@
1
- import "./chunk-ORMEWXMH.js";
1
+ import "../../chunk-ORMEWXMH.js";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  const colorClasses = {
4
4
  primary: "bg-primary/10 text-primary",
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  __spreadProps,
4
4
  __spreadValues
5
- } from "./chunk-ORMEWXMH.js";
5
+ } from "../../chunk-ORMEWXMH.js";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
7
  import { createContext, useCallback, useContext, useMemo, useState, useRef } from "react";
8
8
  const ToastContext = createContext(null);
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import "./chunk-ORMEWXMH.js";
2
+ import "../../chunk-ORMEWXMH.js";
3
3
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
4
  function ToggleSwitch({
5
5
  checked,
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import "./chunk-ORMEWXMH.js";
2
+ import "../../chunk-ORMEWXMH.js";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
  import { useRef, useState } from "react";
5
5
  function Tooltip({
@@ -5,10 +5,16 @@ interface MapActivity {
5
5
  lat: number;
6
6
  lng: number;
7
7
  time?: string | null;
8
+ type?: string | null;
9
+ description?: string | null;
10
+ placeName?: string | null;
11
+ mapsLink?: string | null;
12
+ imageUrl?: string | null;
8
13
  }
9
14
  interface TripDayMapLazyProps {
10
15
  activities: MapActivity[];
11
16
  height?: string;
17
+ apiKey: string;
12
18
  }
13
19
  declare function TripDayMapLazy(props: TripDayMapLazyProps): react_jsx_runtime.JSX.Element;
14
20
 
@@ -1,12 +1,12 @@
1
1
  "use client";
2
2
  import {
3
3
  __spreadValues
4
- } from "./chunk-ORMEWXMH.js";
4
+ } from "../../chunk-ORMEWXMH.js";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  import dynamic from "next/dynamic";
7
7
  const TripDayMapInner = dynamic(
8
8
  () => import("./trip-day-map").then((m) => ({ default: m.TripDayMap })),
9
- { ssr: false, loading: () => /* @__PURE__ */ jsx("div", { className: "w-full h-[280px] rounded-2xl bg-surface-variant animate-pulse" }) }
9
+ { ssr: false, loading: () => /* @__PURE__ */ jsx("div", { className: "w-full h-full bg-surface-variant animate-pulse" }) }
10
10
  );
11
11
  function TripDayMapLazy(props) {
12
12
  return /* @__PURE__ */ jsx(TripDayMapInner, __spreadValues({}, props));
@@ -0,0 +1,28 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface MapActivity {
4
+ name: string;
5
+ lat: number;
6
+ lng: number;
7
+ time?: string | null;
8
+ type?: string | null;
9
+ description?: string | null;
10
+ placeName?: string | null;
11
+ mapsLink?: string | null;
12
+ imageUrl?: string | null;
13
+ }
14
+ interface TripDayMapProps {
15
+ activities: MapActivity[];
16
+ height?: string;
17
+ apiKey: string;
18
+ }
19
+ type GoogleMaps = any;
20
+ declare global {
21
+ interface Window {
22
+ google: GoogleMaps;
23
+ _gmapsLoading?: Promise<void>;
24
+ }
25
+ }
26
+ declare function TripDayMap({ activities, height, apiKey }: TripDayMapProps): react_jsx_runtime.JSX.Element | null;
27
+
28
+ export { type MapActivity, TripDayMap };
@@ -0,0 +1,146 @@
1
+ "use client";
2
+ import "../../chunk-ORMEWXMH.js";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { useEffect, useRef } from "react";
5
+ function loadGoogleMaps(apiKey) {
6
+ var _a;
7
+ if ((_a = window.google) == null ? void 0 : _a.maps) return Promise.resolve();
8
+ if (window._gmapsLoading) return window._gmapsLoading;
9
+ window._gmapsLoading = new Promise((resolve) => {
10
+ const existing = document.getElementById("gmaps-script");
11
+ if (existing) {
12
+ existing.addEventListener("load", () => resolve());
13
+ return;
14
+ }
15
+ const script = document.createElement("script");
16
+ script.id = "gmaps-script";
17
+ script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places&language=th`;
18
+ script.async = true;
19
+ script.defer = true;
20
+ script.onload = () => resolve();
21
+ document.head.appendChild(script);
22
+ });
23
+ return window._gmapsLoading;
24
+ }
25
+ function markerSvg(color, label) {
26
+ const svg = `
27
+ <svg xmlns="http://www.w3.org/2000/svg" width="36" height="44" viewBox="0 0 36 44">
28
+ <path d="M18 0C8.06 0 0 8.06 0 18c0 13.5 18 26 18 26S36 31.5 36 18C36 8.06 27.94 0 18 0z" fill="${color}"/>
29
+ <circle cx="18" cy="18" r="11" fill="white"/>
30
+ <text x="18" y="23" text-anchor="middle" font-size="12" font-weight="700" font-family="sans-serif" fill="${color}">${label}</text>
31
+ </svg>`.trim();
32
+ return "data:image/svg+xml;charset=UTF-8," + encodeURIComponent(svg);
33
+ }
34
+ function TripDayMap({ activities, height = "100%", apiKey }) {
35
+ const ref = useRef(null);
36
+ useEffect(() => {
37
+ if (!ref.current || activities.length === 0) return;
38
+ const container = ref.current;
39
+ loadGoogleMaps(apiKey).then(() => {
40
+ const bounds = new window.google.maps.LatLngBounds();
41
+ const map = new window.google.maps.Map(container, {
42
+ center: { lat: activities[0].lat, lng: activities[0].lng },
43
+ zoom: 13,
44
+ mapTypeControl: true,
45
+ mapTypeControlOptions: { position: window.google.maps.ControlPosition.TOP_RIGHT },
46
+ streetViewControl: false,
47
+ fullscreenControl: false,
48
+ gestureHandling: "greedy",
49
+ zoomControlOptions: { position: window.google.maps.ControlPosition.RIGHT_CENTER }
50
+ });
51
+ if (activities.length > 1) {
52
+ new window.google.maps.Polyline({
53
+ path: activities.map((a) => ({ lat: a.lat, lng: a.lng })),
54
+ geodesic: true,
55
+ strokeColor: "#1e3a5f",
56
+ strokeOpacity: 0.6,
57
+ strokeWeight: 3,
58
+ map
59
+ });
60
+ }
61
+ const placesService = new window.google.maps.places.PlacesService(map);
62
+ const photoCache = /* @__PURE__ */ new Map();
63
+ const buildContent = (act, idx, color, photoUrl) => {
64
+ const mb2 = act.description ? "8px" : "0";
65
+ return `
66
+ <div style="font-family:'Noto Sans Thai',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;min-width:220px;max-width:300px;overflow:hidden;border-radius:4px">
67
+ ${photoUrl ? `<div style="width:100%;height:130px;overflow:hidden"><img src="${photoUrl}" alt="${act.name}" style="width:100%;height:100%;object-fit:cover;display:block"/></div>` : ""}
68
+ <div style="background:${color};padding:10px 14px;display:flex;align-items:center;gap:8px">
69
+ <span style="background:rgba(255,255,255,0.25);color:#fff;font-size:12px;font-weight:800;border-radius:50%;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0">${idx + 1}</span>
70
+ <div style="flex:1;min-width:0">
71
+ ${act.time ? `<div style="font-size:11px;color:rgba(255,255,255,0.8);font-weight:600;margin-bottom:1px">${act.time}</div>` : ""}
72
+ <div style="font-size:13px;font-weight:700;color:#fff;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">${act.name}</div>
73
+ </div>
74
+ </div>
75
+ <div style="padding:12px 14px">
76
+ ${act.placeName && act.placeName !== act.name ? `
77
+ <div style="display:flex;align-items:center;gap:4px;margin-bottom:${mb2}">
78
+ <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#94a3b8" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>
79
+ <span style="font-size:11px;color:#64748b;font-weight:500">${act.placeName}</span>
80
+ </div>` : ""}
81
+ ${act.description ? `<p style="font-size:12px;color:#475569;margin:0 0 10px;line-height:1.6;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden">${act.description}</p>` : ""}
82
+ ${act.mapsLink ? `
83
+ <a href="${act.mapsLink}" target="_blank" rel="noreferrer"
84
+ style="display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;color:#fff;text-decoration:none;background:#4285F4;padding:5px 10px;border-radius:6px">
85
+ <svg width="11" height="11" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"/></svg>
86
+ \u0E40\u0E1B\u0E34\u0E14 Google Maps
87
+ </a>` : ""}
88
+ </div>
89
+ </div>`;
90
+ };
91
+ let openInfo = null;
92
+ activities.forEach((act, i) => {
93
+ var _a, _b, _c, _d;
94
+ const pos = { lat: act.lat, lng: act.lng };
95
+ bounds.extend(pos);
96
+ const colorMap = {
97
+ restaurant: "#E53935",
98
+ hotel: "#8E24AA",
99
+ transport: "#1E88E5",
100
+ shopping: "#FB8C00",
101
+ attraction: "#00897B",
102
+ other: "#546E7A"
103
+ };
104
+ const color = (_c = colorMap[(_b = (_a = act.type) == null ? void 0 : _a.toLowerCase()) != null ? _b : "other"]) != null ? _c : colorMap.other;
105
+ const marker = new window.google.maps.Marker({
106
+ position: pos,
107
+ map,
108
+ icon: { url: markerSvg(color, String(i + 1)), scaledSize: new window.google.maps.Size(36, 44), anchor: new window.google.maps.Point(18, 44) },
109
+ title: act.name,
110
+ zIndex: i
111
+ });
112
+ const info = new window.google.maps.InfoWindow({
113
+ content: buildContent(act, i, color, (_d = act.imageUrl) != null ? _d : void 0)
114
+ });
115
+ marker.addListener("click", () => {
116
+ if (openInfo) openInfo.close();
117
+ info.open(map, marker);
118
+ openInfo = info;
119
+ if (act.imageUrl || photoCache.has(act.name)) return;
120
+ const query = act.placeName && act.placeName !== act.name ? act.placeName : act.name;
121
+ placesService.findPlaceFromQuery(
122
+ { query, fields: ["photos"], locationBias: { lat: act.lat, lng: act.lng } },
123
+ (results, status) => {
124
+ var _a2, _b2;
125
+ if (status !== "OK" || !((_b2 = (_a2 = results == null ? void 0 : results[0]) == null ? void 0 : _a2.photos) == null ? void 0 : _b2[0])) return;
126
+ const photoUrl = results[0].photos[0].getUrl({ maxWidth: 400, maxHeight: 200 });
127
+ photoCache.set(act.name, photoUrl);
128
+ info.setContent(buildContent(act, i, color, photoUrl));
129
+ }
130
+ );
131
+ });
132
+ });
133
+ if (activities.length > 1) {
134
+ map.fitBounds(bounds, { top: 48, right: 48, bottom: 48, left: 48 });
135
+ } else {
136
+ map.setCenter({ lat: activities[0].lat, lng: activities[0].lng });
137
+ map.setZoom(15);
138
+ }
139
+ });
140
+ }, [JSON.stringify(activities), apiKey]);
141
+ if (activities.length === 0) return null;
142
+ return /* @__PURE__ */ jsx("div", { ref, style: { height, width: "100%" } });
143
+ }
144
+ export {
145
+ TripDayMap
146
+ };
@@ -0,0 +1,9 @@
1
+ import { PendingChange } from '../../types/trip.js';
2
+
3
+ type AcknowledgeBannerProps = {
4
+ pendingChange: PendingChange;
5
+ onAcknowledge: (changelogId: string) => void;
6
+ };
7
+ declare function AcknowledgeBanner({ pendingChange, onAcknowledge, }: AcknowledgeBannerProps): React.JSX.Element | null;
8
+
9
+ export { AcknowledgeBanner };
@@ -0,0 +1,47 @@
1
+ "use client";
2
+ import "../../chunk-ORMEWXMH.js";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import { useState } from "react";
5
+ function AcknowledgeBanner({
6
+ pendingChange,
7
+ onAcknowledge
8
+ }) {
9
+ const [isAcknowledged, setIsAcknowledged] = useState(false);
10
+ const [isVisible, setIsVisible] = useState(true);
11
+ function handleAcknowledge() {
12
+ setIsAcknowledged(true);
13
+ onAcknowledge(pendingChange.changelogId);
14
+ setTimeout(() => setIsVisible(false), 3e3);
15
+ }
16
+ if (!isVisible) return null;
17
+ if (isAcknowledged) {
18
+ return /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-50 border-b border-success/30 bg-success/10 px-4 py-3 text-center transition-all", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-2 text-sm font-medium text-success", children: [
19
+ /* @__PURE__ */ jsx("span", { className: "material-symbols-outlined text-sm", children: "check" }),
20
+ "\u0E23\u0E31\u0E1A\u0E17\u0E23\u0E32\u0E1A\u0E41\u0E25\u0E49\u0E27 \u2014 \u0E02\u0E2D\u0E1A\u0E04\u0E38\u0E13\u0E04\u0E48\u0E30 \u{1F64F}"
21
+ ] }) });
22
+ }
23
+ return /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-50 border-b border-warning/30 bg-warning-light px-4 py-3", children: /* @__PURE__ */ jsx("div", { className: "mx-auto max-w-2xl", children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
24
+ /* @__PURE__ */ jsx("span", { className: "material-symbols-outlined mt-0.5 shrink-0 text-lg text-warning", children: "warning" }),
25
+ /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
26
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-bold text-foreground", children: "\u0E21\u0E35\u0E01\u0E32\u0E23\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07!" }),
27
+ /* @__PURE__ */ jsx("ul", { className: "mt-1 space-y-0.5", children: pendingChange.changes.map((change, i) => /* @__PURE__ */ jsxs("li", { className: "text-xs text-muted-foreground", children: [
28
+ "\u2022 ",
29
+ change.description
30
+ ] }, i)) })
31
+ ] }),
32
+ /* @__PURE__ */ jsxs(
33
+ "button",
34
+ {
35
+ onClick: handleAcknowledge,
36
+ className: "shrink-0 rounded-full bg-primary px-4 py-2 text-xs font-bold text-white shadow-md transition-all hover:scale-105 hover:bg-primary-dark active:scale-95",
37
+ children: [
38
+ /* @__PURE__ */ jsx("span", { className: "material-symbols-outlined mr-1 inline text-xs", children: "check" }),
39
+ "\u0E23\u0E31\u0E1A\u0E17\u0E23\u0E32\u0E1A\u0E41\u0E25\u0E49\u0E27"
40
+ ]
41
+ }
42
+ )
43
+ ] }) }) });
44
+ }
45
+ export {
46
+ AcknowledgeBanner
47
+ };
@@ -0,0 +1,8 @@
1
+ import { Activity } from '../../types/trip.js';
2
+
3
+ type ActivityItemProps = {
4
+ activity: Activity;
5
+ };
6
+ declare function ActivityItem({ activity }: ActivityItemProps): React.JSX.Element;
7
+
8
+ export { ActivityItem };
@@ -0,0 +1,174 @@
1
+ "use client";
2
+ import "../../chunk-ORMEWXMH.js";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ import { useState, useCallback, useEffect } from "react";
5
+ import { cn, detectMapProvider, getMapButtonLabel, getActivityTypeStyle } from "../../utils/trip-utils";
6
+ function ActivityGallery({ images, name }) {
7
+ const [lightboxIndex, setLightboxIndex] = useState(null);
8
+ const open = (i) => setLightboxIndex(i);
9
+ const close = useCallback(() => setLightboxIndex(null), []);
10
+ const prev = useCallback(() => setLightboxIndex((i) => i != null ? (i - 1 + images.length) % images.length : null), [images.length]);
11
+ const next = useCallback(() => setLightboxIndex((i) => i != null ? (i + 1) % images.length : null), [images.length]);
12
+ useEffect(() => {
13
+ if (lightboxIndex == null) return;
14
+ const onKey = (e) => {
15
+ if (e.key === "Escape") close();
16
+ if (e.key === "ArrowLeft") prev();
17
+ if (e.key === "ArrowRight") next();
18
+ };
19
+ window.addEventListener("keydown", onKey);
20
+ return () => window.removeEventListener("keydown", onKey);
21
+ }, [lightboxIndex, close, prev, next]);
22
+ if (images.length === 0) return null;
23
+ const thumbnails = images.slice(0, 6);
24
+ const overflow = images.length - 6;
25
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
26
+ /* @__PURE__ */ jsx("div", { className: "no-scrollbar mt-3 flex gap-2 overflow-x-auto", children: thumbnails.map((url, i) => /* @__PURE__ */ jsxs(
27
+ "button",
28
+ {
29
+ onClick: () => open(i),
30
+ className: "relative shrink-0 overflow-hidden rounded-lg focus:outline-none focus-visible:ring-2 focus-visible:ring-primary",
31
+ "aria-label": `\u0E14\u0E39\u0E23\u0E39\u0E1B\u0E17\u0E35\u0E48 ${i + 1}`,
32
+ children: [
33
+ /* @__PURE__ */ jsx(
34
+ "img",
35
+ {
36
+ src: url,
37
+ alt: `${name} \u0E23\u0E39\u0E1B\u0E17\u0E35\u0E48 ${i + 1}`,
38
+ className: "h-20 w-20 object-cover transition-transform duration-300 hover:scale-105 sm:h-24 sm:w-24"
39
+ }
40
+ ),
41
+ i === 5 && overflow > 0 && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ jsxs("span", { className: "text-sm font-bold text-white", children: [
42
+ "+",
43
+ overflow
44
+ ] }) })
45
+ ]
46
+ },
47
+ url
48
+ )) }),
49
+ lightboxIndex != null && /* @__PURE__ */ jsxs(
50
+ "div",
51
+ {
52
+ className: "fixed inset-0 z-50 flex items-center justify-center bg-black/90",
53
+ onClick: close,
54
+ children: [
55
+ /* @__PURE__ */ jsxs("div", { className: "absolute top-4 left-1/2 -translate-x-1/2 rounded-full bg-black/50 px-3 py-1 text-sm text-white", children: [
56
+ lightboxIndex + 1,
57
+ " / ",
58
+ images.length
59
+ ] }),
60
+ /* @__PURE__ */ jsx(
61
+ "button",
62
+ {
63
+ onClick: close,
64
+ className: "absolute top-4 right-4 rounded-full bg-black/50 p-2 text-white hover:bg-black/70",
65
+ "aria-label": "\u0E1B\u0E34\u0E14",
66
+ children: /* @__PURE__ */ jsx("span", { className: "material-symbols-outlined text-xl", children: "close" })
67
+ }
68
+ ),
69
+ images.length > 1 && /* @__PURE__ */ jsx(
70
+ "button",
71
+ {
72
+ onClick: (e) => {
73
+ e.stopPropagation();
74
+ prev();
75
+ },
76
+ className: "absolute left-3 rounded-full bg-black/50 p-2 text-white hover:bg-black/70 sm:left-6",
77
+ "aria-label": "\u0E01\u0E48\u0E2D\u0E19\u0E2B\u0E19\u0E49\u0E32",
78
+ children: /* @__PURE__ */ jsx("span", { className: "material-symbols-outlined text-2xl", children: "chevron_left" })
79
+ }
80
+ ),
81
+ /* @__PURE__ */ jsx(
82
+ "img",
83
+ {
84
+ src: images[lightboxIndex],
85
+ alt: `${name} \u0E23\u0E39\u0E1B\u0E17\u0E35\u0E48 ${lightboxIndex + 1}`,
86
+ className: "max-h-[85dvh] max-w-[90vw] rounded-xl object-contain shadow-2xl",
87
+ onClick: (e) => e.stopPropagation()
88
+ }
89
+ ),
90
+ images.length > 1 && /* @__PURE__ */ jsx(
91
+ "button",
92
+ {
93
+ onClick: (e) => {
94
+ e.stopPropagation();
95
+ next();
96
+ },
97
+ className: "absolute right-3 rounded-full bg-black/50 p-2 text-white hover:bg-black/70 sm:right-6",
98
+ "aria-label": "\u0E16\u0E31\u0E14\u0E44\u0E1B",
99
+ children: /* @__PURE__ */ jsx("span", { className: "material-symbols-outlined text-2xl", children: "chevron_right" })
100
+ }
101
+ ),
102
+ images.length > 1 && images.length <= 10 && /* @__PURE__ */ jsx("div", { className: "absolute bottom-5 flex gap-1.5", children: images.map((_, i) => /* @__PURE__ */ jsx(
103
+ "button",
104
+ {
105
+ onClick: (e) => {
106
+ e.stopPropagation();
107
+ setLightboxIndex(i);
108
+ },
109
+ className: cn(
110
+ "h-1.5 rounded-full transition-all",
111
+ i === lightboxIndex ? "w-4 bg-white" : "w-1.5 bg-white/40"
112
+ ),
113
+ "aria-label": `\u0E23\u0E39\u0E1B\u0E17\u0E35\u0E48 ${i + 1}`
114
+ },
115
+ i
116
+ )) })
117
+ ]
118
+ }
119
+ )
120
+ ] });
121
+ }
122
+ function ActivityItem({ activity }) {
123
+ var _a;
124
+ const typeStyle = getActivityTypeStyle(activity.type);
125
+ const galleryImages = ((_a = activity.imageUrls) == null ? void 0 : _a.length) ? activity.imageUrls : activity.imageUrl ? [activity.imageUrl] : [];
126
+ const hasGallery = galleryImages.length > 0;
127
+ return /* @__PURE__ */ jsxs(
128
+ "div",
129
+ {
130
+ className: cn(
131
+ "relative flex flex-col gap-3 rounded-xl border bg-white p-4 transition-all",
132
+ activity.isNew && "border-success/50 bg-success/5",
133
+ activity.isChanged && "border-warning/50 bg-warning-light/30",
134
+ (activity.isNew || activity.isChanged) && "activity-highlight"
135
+ ),
136
+ children: [
137
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-3", children: [
138
+ /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 flex-col items-center", children: [
139
+ /* @__PURE__ */ jsx("span", { className: "text-2xl", children: activity.emoji }),
140
+ /* @__PURE__ */ jsx("span", { className: cn("mt-1 rounded-md px-2 py-0.5 text-xs font-bold", typeStyle.bg, typeStyle.text), children: activity.time })
141
+ ] }),
142
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
143
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-2", children: [
144
+ /* @__PURE__ */ jsx("h4", { className: "font-semibold text-foreground", children: activity.name }),
145
+ /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 gap-1", children: [
146
+ activity.isNew && /* @__PURE__ */ jsx("span", { className: "rounded-full bg-success px-2 py-0.5 text-[10px] font-bold text-white", children: "NEW" }),
147
+ activity.isChanged && /* @__PURE__ */ jsx("span", { className: "rounded-full bg-warning px-2 py-0.5 text-[10px] font-bold text-white", children: "\u0E41\u0E01\u0E49\u0E44\u0E02" })
148
+ ] })
149
+ ] }),
150
+ activity.description && /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-sm text-muted-foreground", children: activity.description }),
151
+ activity.mapsLink && /* @__PURE__ */ jsxs(
152
+ "a",
153
+ {
154
+ href: activity.mapsLink,
155
+ target: "_blank",
156
+ rel: "noopener noreferrer",
157
+ className: "mt-2 inline-flex items-center gap-1 text-xs font-medium text-primary hover:underline",
158
+ children: [
159
+ /* @__PURE__ */ jsx("span", { className: "material-symbols-outlined text-xs", children: "location_on" }),
160
+ getMapButtonLabel(detectMapProvider(activity.mapsLink))
161
+ ]
162
+ }
163
+ )
164
+ ] }),
165
+ !hasGallery && activity.imageUrl && /* @__PURE__ */ jsx("div", { className: "hidden shrink-0 sm:block", children: /* @__PURE__ */ jsx("img", { src: activity.imageUrl, alt: activity.name, className: "h-20 w-20 rounded-lg object-cover" }) })
166
+ ] }),
167
+ hasGallery && /* @__PURE__ */ jsx(ActivityGallery, { images: galleryImages, name: activity.name })
168
+ ]
169
+ }
170
+ );
171
+ }
172
+ export {
173
+ ActivityItem
174
+ };
@@ -0,0 +1,9 @@
1
+ import { Company } from '../../types/trip.js';
2
+
3
+ type CompanyFooterProps = {
4
+ company: Company;
5
+ showWatermark?: boolean;
6
+ };
7
+ declare function CompanyFooter({ company, showWatermark }: CompanyFooterProps): React.JSX.Element;
8
+
9
+ export { CompanyFooter };
@@ -0,0 +1,99 @@
1
+ import "../../chunk-ORMEWXMH.js";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ function CompanyFooter({ company, showWatermark }) {
4
+ return /* @__PURE__ */ jsxs("div", { className: "rounded-2xl border border-border bg-white p-5", children: [
5
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
6
+ /* @__PURE__ */ jsx("img", { src: company.logoUrl, alt: company.name, className: "h-14 w-14 rounded-full object-cover" }),
7
+ /* @__PURE__ */ jsxs("div", { children: [
8
+ /* @__PURE__ */ jsx("h4", { className: "font-bold text-foreground", children: company.name }),
9
+ company.tatLicense && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
10
+ "TAT License: ",
11
+ company.tatLicense
12
+ ] })
13
+ ] })
14
+ ] }),
15
+ /* @__PURE__ */ jsxs("div", { className: "mt-4 grid grid-cols-2 gap-2", children: [
16
+ company.phone && /* @__PURE__ */ jsxs(
17
+ "a",
18
+ {
19
+ href: `tel:${company.phone}`,
20
+ className: "flex items-center gap-2 rounded-lg bg-muted px-3 py-2 text-xs font-medium text-foreground transition-colors hover:bg-primary-100",
21
+ children: [
22
+ /* @__PURE__ */ jsx("span", { className: "material-symbols-outlined text-sm text-primary", children: "call" }),
23
+ company.phone
24
+ ]
25
+ }
26
+ ),
27
+ company.lineId && /* @__PURE__ */ jsxs(
28
+ "a",
29
+ {
30
+ href: `https://line.me/R/ti/p/${company.lineId}`,
31
+ target: "_blank",
32
+ rel: "noopener noreferrer",
33
+ className: "flex items-center gap-2 rounded-lg bg-muted px-3 py-2 text-xs font-medium text-foreground transition-colors hover:bg-[#06c755]/10",
34
+ children: [
35
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-[#06c755]", children: "\u{1F49A}" }),
36
+ "LINE ",
37
+ company.lineId
38
+ ]
39
+ }
40
+ ),
41
+ company.facebook && /* @__PURE__ */ jsxs(
42
+ "a",
43
+ {
44
+ href: `https://facebook.com/${company.facebook}`,
45
+ target: "_blank",
46
+ rel: "noopener noreferrer",
47
+ className: "flex items-center gap-2 rounded-lg bg-muted px-3 py-2 text-xs font-medium text-foreground transition-colors hover:bg-primary-100",
48
+ children: [
49
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-[#1877f2]", children: "\u{1F4D8}" }),
50
+ company.facebook
51
+ ]
52
+ }
53
+ ),
54
+ company.instagram && /* @__PURE__ */ jsxs(
55
+ "a",
56
+ {
57
+ href: `https://instagram.com/${company.instagram}`,
58
+ target: "_blank",
59
+ rel: "noopener noreferrer",
60
+ className: "flex items-center gap-2 rounded-lg bg-muted px-3 py-2 text-xs font-medium text-foreground transition-colors hover:bg-pink-50",
61
+ children: [
62
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: "\u{1F4F7}" }),
63
+ "@",
64
+ company.instagram
65
+ ]
66
+ }
67
+ ),
68
+ company.website && /* @__PURE__ */ jsxs(
69
+ "a",
70
+ {
71
+ href: company.website,
72
+ target: "_blank",
73
+ rel: "noopener noreferrer",
74
+ className: "col-span-2 flex items-center gap-2 rounded-lg bg-muted px-3 py-2 text-xs font-medium text-foreground transition-colors hover:bg-primary-100",
75
+ children: [
76
+ /* @__PURE__ */ jsx("span", { className: "material-symbols-outlined text-sm text-primary", children: "language" }),
77
+ company.website.replace(/https?:\/\//, "")
78
+ ]
79
+ }
80
+ )
81
+ ] }),
82
+ showWatermark && /* @__PURE__ */ jsx("div", { className: "mt-4 border-t border-border pt-3 text-center", children: /* @__PURE__ */ jsxs(
83
+ "a",
84
+ {
85
+ href: "https://tripapp.io",
86
+ target: "_blank",
87
+ rel: "noopener noreferrer",
88
+ className: "inline-flex items-center gap-1.5 text-xs text-muted-foreground transition-colors hover:text-primary",
89
+ children: [
90
+ /* @__PURE__ */ jsx("span", { className: "rounded-md bg-primary-50 px-1.5 py-0.5 text-[10px] font-bold text-primary", children: "T" }),
91
+ "Powered by TripApp"
92
+ ]
93
+ }
94
+ ) })
95
+ ] });
96
+ }
97
+ export {
98
+ CompanyFooter
99
+ };
@@ -0,0 +1,7 @@
1
+ type CountdownBadgeProps = {
2
+ startDate: string;
3
+ endDate: string;
4
+ };
5
+ declare function CountdownBadge({ startDate, endDate }: CountdownBadgeProps): React.JSX.Element;
6
+
7
+ export { CountdownBadge };