@anker-in/ui 0.1.8 → 0.1.10

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/index.mjs CHANGED
@@ -61,7 +61,10 @@ var StudioCard = ({
61
61
  "div",
62
62
  {
63
63
  ...props,
64
- className: cn("p-6 cursor-pointer transition-colors duration-200", className),
64
+ className: cn(
65
+ "p-6 cursor-pointer transition-colors duration-200",
66
+ className
67
+ ),
65
68
  style: {
66
69
  backgroundColor: isHovered ? "#f3f4f6" : "transparent",
67
70
  ...style
@@ -83,7 +86,7 @@ var StudioCard = ({
83
86
  pageData.away
84
87
  ] })
85
88
  ] }),
86
- /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 mb-3", children: [
89
+ availableTime && /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 mb-3", children: [
87
90
  /* @__PURE__ */ jsxs(
88
91
  "svg",
89
92
  {
@@ -137,7 +140,7 @@ var StudioCard = ({
137
140
  }
138
141
  ),
139
142
  /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-600", children: [
140
- pageData.available,
143
+ availableTime === pageData.noAvailableTime ? "" : pageData.available,
141
144
  " ",
142
145
  availableTime
143
146
  ] }) })
@@ -346,18 +349,22 @@ var StudioMap = ({
346
349
  validLocations.forEach((location) => {
347
350
  const lat = Number(location.lat);
348
351
  const lng = Number(location.lng);
352
+ const svgIcon = {
353
+ url: `data:image/svg+xml;charset=UTF-8,${encodeURIComponent(`
354
+ <svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
355
+ <circle cx="24" cy="24" r="22" fill="#00000010"/>
356
+ <circle cx="24" cy="24" r="10" fill="#000000"/>
357
+ <circle cx="24" cy="24" r="5" fill="#3ADB67"/>
358
+ </svg>
359
+ `)}`,
360
+ scaledSize: { width: 48, height: 48 },
361
+ anchor: { x: 24, y: 24 }
362
+ };
349
363
  const marker = new google.maps.Marker({
350
364
  position: { lat, lng },
351
365
  map: googleMapRef.current,
352
366
  title: location.name,
353
- icon: {
354
- path: google.maps.SymbolPath.CIRCLE,
355
- scale: 10,
356
- fillColor: "#000000",
357
- fillOpacity: 1,
358
- strokeColor: "#ffffff",
359
- strokeWeight: 2
360
- }
367
+ icon: svgIcon
361
368
  });
362
369
  marker.addListener("click", () => {
363
370
  setSelectedLocation(location);
@@ -368,7 +375,7 @@ var StudioMap = ({
368
375
  <svg style="display: inline-block; width: 16px; height: 16px; margin-right: 4px; vertical-align: middle;" fill="currentColor" viewBox="0 0 20 20">
369
376
  <path d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z"/>
370
377
  </svg>
371
- <span style="vertical-align: middle;">${pageData.available} ${location.availableTime}</span>
378
+ <span style="vertical-align: middle;"> ${location.availableTime === pageData?.noAvailableTime ? "" : pageData.available} ${location.availableTime}</span>
372
379
  </div>` : ""}
373
380
  <div style="margin-bottom: 8px; color: #666;">
374
381
  <svg style="display: inline-block; width: 16px; height: 16px; margin-right: 4px; vertical-align: middle;" fill="currentColor" viewBox="0 0 20 20">
@@ -1069,6 +1076,7 @@ var defaultPageData = {
1069
1076
  title: "Find a Studio Near You",
1070
1077
  loadingText: "Loading demo rooms...",
1071
1078
  errorTitle: "Failed to load demo rooms",
1079
+ machine: "eufymake E1",
1072
1080
  locationFilter: {
1073
1081
  allLocations: "All Locations",
1074
1082
  clear: "Clear",
@@ -1251,13 +1259,13 @@ var RoomsList = ({
1251
1259
  state,
1252
1260
  zipCode: "",
1253
1261
  country,
1254
- lat: Number(room.latitude) || 34.0522,
1255
- lng: Number(room.longitude) || -118.2437,
1262
+ lat: Number(room.latitude) || 0,
1263
+ lng: Number(room.longitude) || 0,
1256
1264
  availableTime: nextAvailableTimeslot ? `${nextAvailableTimeslot.start_time}` : mergedPageData.noAvailableTime,
1257
1265
  euifyMakeModel: room?.description
1258
1266
  };
1259
1267
  });
1260
- }, [demoRooms]);
1268
+ }, [demoRooms, mergedPageData.defaultCountry, mergedPageData.noAvailableTime]);
1261
1269
  const filteredStudioLocations = useMemo(() => {
1262
1270
  if (!selectedLocation) return studioLocations;
1263
1271
  return studioLocations.filter((location) => {
@@ -1339,7 +1347,7 @@ var RoomsList = ({
1339
1347
  }
1340
1348
  ),
1341
1349
  /* @__PURE__ */ jsxs("div", { className: "flex text-[#767880] cursor-not-allowed", children: [
1342
- "eufymake E1",
1350
+ mergedPageData.machine,
1343
1351
  /* @__PURE__ */ jsx(
1344
1352
  "svg",
1345
1353
  {
@@ -1379,7 +1387,10 @@ var RoomsList = ({
1379
1387
  onSchedule,
1380
1388
  onMouseEnter: () => setHoveredRoomId(item.id),
1381
1389
  onMouseLeave: () => setHoveredRoomId(null),
1382
- pageData: mergedPageData.studioCard
1390
+ pageData: {
1391
+ ...mergedPageData.studioCard,
1392
+ noAvailableTime: mergedPageData?.noAvailableTime
1393
+ }
1383
1394
  },
1384
1395
  item.id
1385
1396
  );
@@ -1412,7 +1423,10 @@ var RoomsList = ({
1412
1423
  hoveredLocationId: hoveredRoomId,
1413
1424
  onSchedule,
1414
1425
  mapHeight: "794px",
1415
- pageData: mergedPageData.map
1426
+ pageData: {
1427
+ ...mergedPageData.map,
1428
+ noAvailableTime: pageData?.noAvailableTime
1429
+ }
1416
1430
  }
1417
1431
  ) })
1418
1432
  ] })
@@ -1627,6 +1641,21 @@ var QuestionnaireForm = ({
1627
1641
  const [errors, setErrors] = useState({});
1628
1642
  const [agreements, setAgreements] = useState({});
1629
1643
  const [agreementError, setAgreementError] = useState("");
1644
+ const [phoneCountryCodes, setPhoneCountryCodes] = useState({});
1645
+ const defaultCountryCodes = [
1646
+ { code: "+1", country: "US/CA" },
1647
+ { code: "+86", country: "CN" },
1648
+ { code: "+44", country: "UK" },
1649
+ { code: "+81", country: "JP" },
1650
+ { code: "+82", country: "KR" },
1651
+ { code: "+65", country: "SG" },
1652
+ { code: "+852", country: "HK" },
1653
+ { code: "+886", country: "TW" },
1654
+ { code: "+61", country: "AU" },
1655
+ { code: "+49", country: "DE" },
1656
+ { code: "+33", country: "FR" }
1657
+ ];
1658
+ const countryCodes = pageData?.countryCodes || defaultCountryCodes;
1630
1659
  const getQuestionId = (question) => {
1631
1660
  return question.id || question.key || "";
1632
1661
  };
@@ -1643,6 +1672,22 @@ var QuestionnaireForm = ({
1643
1672
  });
1644
1673
  }
1645
1674
  };
1675
+ const handleEmailBlur = (questionId, value) => {
1676
+ if (!value) return;
1677
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1678
+ if (!emailRegex.test(value)) {
1679
+ setErrors((prev) => ({
1680
+ ...prev,
1681
+ [questionId]: "Please enter a valid email address"
1682
+ }));
1683
+ }
1684
+ };
1685
+ const handleCountryCodeChange = (questionId, code) => {
1686
+ setPhoneCountryCodes((prev) => ({
1687
+ ...prev,
1688
+ [questionId]: code
1689
+ }));
1690
+ };
1646
1691
  const handleCheckboxChange = (questionId, optionValue, checked) => {
1647
1692
  const currentValues = responses[questionId] || [];
1648
1693
  const newValues = checked ? [...currentValues, optionValue] : currentValues.filter((v) => v !== optionValue);
@@ -1688,7 +1733,22 @@ var QuestionnaireForm = ({
1688
1733
  const handleSubmit = (e) => {
1689
1734
  e.preventDefault();
1690
1735
  if (validateForm()) {
1691
- onSubmit?.(responses);
1736
+ const finalResponses = { ...responses };
1737
+ questions.forEach((question) => {
1738
+ if (question.type === "tel" || question.type === "phone") {
1739
+ const questionId = getQuestionId(question);
1740
+ const countryCode = phoneCountryCodes[questionId] || "+1";
1741
+ const phoneNumber = responses[questionId];
1742
+ if (phoneNumber) {
1743
+ finalResponses[questionId] = phoneNumber;
1744
+ if (questionId === "phone" || questionId === "customer_phone_number") {
1745
+ finalResponses["phone_code"] = countryCode;
1746
+ finalResponses["customer_phone_code"] = countryCode;
1747
+ }
1748
+ }
1749
+ }
1750
+ });
1751
+ onSubmit?.(finalResponses);
1692
1752
  }
1693
1753
  };
1694
1754
  const renderQuestion = (question) => {
@@ -1696,8 +1756,6 @@ var QuestionnaireForm = ({
1696
1756
  const hasError = !!errors[questionId];
1697
1757
  switch (question.type) {
1698
1758
  case "text":
1699
- case "email":
1700
- case "tel":
1701
1759
  return /* @__PURE__ */ jsx(
1702
1760
  "input",
1703
1761
  {
@@ -1712,6 +1770,76 @@ var QuestionnaireForm = ({
1712
1770
  )
1713
1771
  }
1714
1772
  );
1773
+ case "email":
1774
+ return /* @__PURE__ */ jsx(
1775
+ "input",
1776
+ {
1777
+ type: "email",
1778
+ value: responses[questionId] || "",
1779
+ onChange: (e) => handleChange(questionId, e.target.value),
1780
+ onBlur: (e) => handleEmailBlur(questionId, e.target.value),
1781
+ placeholder: question.placeholder,
1782
+ className: cn(
1783
+ "w-full px-4 py-3 rounded-lg border text-base",
1784
+ "focus:outline-none focus:ring-2 focus:ring-[#3ADB67] focus:border-transparent",
1785
+ hasError ? "border-red-500" : "border-[#E4E5E6]"
1786
+ )
1787
+ }
1788
+ );
1789
+ case "tel":
1790
+ case "phone":
1791
+ return /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
1792
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
1793
+ /* @__PURE__ */ jsx(
1794
+ "select",
1795
+ {
1796
+ value: phoneCountryCodes[questionId] || "+1",
1797
+ onChange: (e) => handleCountryCodeChange(questionId, e.target.value),
1798
+ className: cn(
1799
+ "appearance-none pl-3 pr-8 py-3 rounded-lg border text-base",
1800
+ "focus:outline-none focus:ring-2 focus:ring-[#3ADB67] focus:border-transparent",
1801
+ "bg-white cursor-pointer w-[80px]",
1802
+ hasError ? "border-red-500" : "border-[#E4E5E6]"
1803
+ ),
1804
+ children: countryCodes.map((item) => /* @__PURE__ */ jsx("option", { value: item.code, children: item.code }, item.code))
1805
+ }
1806
+ ),
1807
+ /* @__PURE__ */ jsx("div", { className: "absolute right-2 top-1/2 -translate-y-1/2 pointer-events-none", children: /* @__PURE__ */ jsx(
1808
+ "svg",
1809
+ {
1810
+ width: "12",
1811
+ height: "8",
1812
+ viewBox: "0 0 12 8",
1813
+ fill: "none",
1814
+ xmlns: "http://www.w3.org/2000/svg",
1815
+ children: /* @__PURE__ */ jsx(
1816
+ "path",
1817
+ {
1818
+ d: "M1 1.5L6 6.5L11 1.5",
1819
+ stroke: "#9CA3AF",
1820
+ strokeWidth: "1.5",
1821
+ strokeLinecap: "round",
1822
+ strokeLinejoin: "round"
1823
+ }
1824
+ )
1825
+ }
1826
+ ) })
1827
+ ] }),
1828
+ /* @__PURE__ */ jsx(
1829
+ "input",
1830
+ {
1831
+ type: "tel",
1832
+ value: responses[questionId] || "",
1833
+ onChange: (e) => handleChange(questionId, e.target.value),
1834
+ placeholder: question.placeholder,
1835
+ className: cn(
1836
+ "flex-1 px-4 py-3 rounded-lg border text-base",
1837
+ "focus:outline-none focus:ring-2 focus:ring-[#3ADB67] focus:border-transparent",
1838
+ hasError ? "border-red-500" : "border-[#E4E5E6]"
1839
+ )
1840
+ }
1841
+ )
1842
+ ] });
1715
1843
  case "textarea":
1716
1844
  return /* @__PURE__ */ jsx(
1717
1845
  "textarea",
@@ -1817,7 +1945,8 @@ var QuestionnaireForm = ({
1817
1945
  question.label,
1818
1946
  question.required && /* @__PURE__ */ jsx("span", { className: "text-red-500 ml-1", children: "*" })
1819
1947
  ] }),
1820
- question.description && /* @__PURE__ */ jsx("span", { className: "block text-sm text-gray-600 mt-1", children: question.description })
1948
+ question.description && /* @__PURE__ */ jsx("span", { className: "block text-sm text-gray-600 mt-1", children: question.description }),
1949
+ question.type === "email" && questionId === "email" && pageData?.emailDescription && /* @__PURE__ */ jsx("span", { className: "block text-sm text-gray-600 mt-1", children: pageData.emailDescription })
1821
1950
  ] }),
1822
1951
  renderQuestion(question),
1823
1952
  question.hint && !errors[questionId] && /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: question.hint }),
@@ -1891,11 +2020,12 @@ var DateTimePicker = ({
1891
2020
  onBookingSuccess
1892
2021
  }) => {
1893
2022
  const { token } = theme.useToken();
1894
- const [selectMonth, setSelectMonth] = useState("");
1895
- const [selectedDate, setSelectedDate] = useState(dayjs());
2023
+ const [selectedDate, setSelectedDate] = useState(null);
2024
+ const [calendarValue, setCalendarValue] = useState(dayjs());
1896
2025
  const [selectedTimeslotId, setSelectedTimeslotId] = useState(
1897
2026
  null
1898
2027
  );
2028
+ const [isInitialized, setIsInitialized] = useState(false);
1899
2029
  const {
1900
2030
  createBooking,
1901
2031
  loading: bookingLoading,
@@ -1914,8 +2044,8 @@ var DateTimePicker = ({
1914
2044
  locale,
1915
2045
  { enabled: !!demoRoomCode && !!demoRoom?.questionnaire_id }
1916
2046
  );
1917
- const startDate = selectedDate.startOf("month").format("YYYY-MM-DD");
1918
- const endDate = selectedDate.endOf("month").format("YYYY-MM-DD");
2047
+ const startDate = calendarValue.startOf("month").format("YYYY-MM-DD");
2048
+ const endDate = calendarValue.endOf("month").format("YYYY-MM-DD");
1919
2049
  const {
1920
2050
  data: timeslotsData,
1921
2051
  loading: timeslotsLoading,
@@ -1931,30 +2061,81 @@ var DateTimePicker = ({
1931
2061
  { enabled: !!demoRoomCode }
1932
2062
  );
1933
2063
  const dayTimeslots = useMemo(() => {
1934
- if (!timeslotsData?.timeslots) return [];
2064
+ if (!timeslotsData?.timeslots || !selectedDate) return [];
1935
2065
  const selectedDateStr = selectedDate.format("YYYY-MM-DD");
1936
2066
  return timeslotsData.timeslots.filter((slot) => {
1937
2067
  const slotDate = dayjs(slot.start_time).format("YYYY-MM-DD");
1938
2068
  return slotDate === selectedDateStr;
1939
2069
  });
1940
2070
  }, [timeslotsData, selectedDate]);
2071
+ const availableDates = useMemo(() => {
2072
+ if (!timeslotsData?.timeslots) return /* @__PURE__ */ new Set();
2073
+ const dates = /* @__PURE__ */ new Set();
2074
+ timeslotsData.timeslots.forEach((slot) => {
2075
+ if (slot.status === "available") {
2076
+ const dateStr = dayjs(slot.start_time).format("YYYY-MM-DD");
2077
+ dates.add(dateStr);
2078
+ }
2079
+ });
2080
+ return dates;
2081
+ }, [timeslotsData]);
2082
+ useEffect(() => {
2083
+ if (!timeslotsData?.timeslots || isInitialized) return;
2084
+ const now = dayjs();
2085
+ const availableTimeslots = timeslotsData.timeslots.filter(
2086
+ (slot) => slot.status === "available" && dayjs(slot.start_time).isAfter(now)
2087
+ );
2088
+ if (availableTimeslots.length > 0) {
2089
+ const sortedSlots = [...availableTimeslots].sort(
2090
+ (a, b) => dayjs(a.start_time).unix() - dayjs(b.start_time).unix()
2091
+ );
2092
+ const nearestSlot = sortedSlots[0];
2093
+ const nearestDate = dayjs(nearestSlot.start_time);
2094
+ setSelectedDate(nearestDate);
2095
+ setCalendarValue(nearestDate);
2096
+ setSelectedTimeslotId(nearestSlot.id);
2097
+ setIsInitialized(true);
2098
+ } else if (!selectedDate) {
2099
+ setSelectedDate(now);
2100
+ setCalendarValue(now);
2101
+ setIsInitialized(true);
2102
+ }
2103
+ }, [timeslotsData, isInitialized, selectedDate]);
2104
+ useEffect(() => {
2105
+ if (!timeslotsData?.timeslots || !isInitialized) return;
2106
+ if (selectedDate && selectedDate.isSame(calendarValue, "month")) {
2107
+ return;
2108
+ }
2109
+ const currentMonthStart = calendarValue.startOf("month");
2110
+ const currentMonthEnd = calendarValue.endOf("month");
2111
+ const now = dayjs();
2112
+ const availableTimeslots = timeslotsData.timeslots.filter((slot) => {
2113
+ const slotDate = dayjs(slot.start_time);
2114
+ return slot.status === "available" && slotDate.isAfter(now) && (slotDate.isAfter(currentMonthStart) || slotDate.isSame(currentMonthStart, "day")) && (slotDate.isBefore(currentMonthEnd) || slotDate.isSame(currentMonthEnd, "day"));
2115
+ });
2116
+ if (availableTimeslots.length > 0) {
2117
+ const sortedSlots = [...availableTimeslots].sort(
2118
+ (a, b) => dayjs(a.start_time).unix() - dayjs(b.start_time).unix()
2119
+ );
2120
+ const firstSlot = sortedSlots[0];
2121
+ const firstDate = dayjs(firstSlot.start_time);
2122
+ setSelectedDate(firstDate);
2123
+ setSelectedTimeslotId(firstSlot.id);
2124
+ }
2125
+ }, [calendarValue, timeslotsData, isInitialized, selectedDate]);
1941
2126
  const formatTimeslot = (slot) => {
1942
2127
  const start = dayjs(slot.start_time).format("h:mm A");
1943
2128
  const end = dayjs(slot.end_time).format("h:mm A");
1944
2129
  return `${start} - ${end}`;
1945
2130
  };
1946
- const onPanelChange = (value, mode) => {
1947
- console.log(value.format("YYYY-MM-DD"), mode);
1948
- };
1949
2131
  const wrapperStyle = {
1950
- width: 824,
1951
2132
  background: "#fff",
1952
2133
  border: `1px solid ${token.colorBorderSecondary}`,
1953
2134
  borderRadius: token.borderRadiusLG
1954
2135
  };
1955
2136
  return /* @__PURE__ */ jsxs("div", { children: [
1956
- /* @__PURE__ */ jsx("div", { className: "text-[48px] py-[64px] font-bold text-center", children: pageData.scheduleYourVisit }),
1957
- /* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
2137
+ /* @__PURE__ */ jsx("div", { className: "text-[48px] l:text-[32px] py-[64px] l:py-[24px] font-bold text-center", children: pageData.scheduleYourVisit }),
2138
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-4 l:flex-col", children: [
1958
2139
  /* @__PURE__ */ jsx(
1959
2140
  ConfigProvider,
1960
2141
  {
@@ -1970,34 +2151,79 @@ var DateTimePicker = ({
1970
2151
  }
1971
2152
  }
1972
2153
  },
1973
- children: /* @__PURE__ */ jsxs("div", { style: wrapperStyle, className: "calendar-custom-cell", children: [
1974
- /* @__PURE__ */ jsx("style", { children: `
2154
+ children: /* @__PURE__ */ jsxs(
2155
+ "div",
2156
+ {
2157
+ style: wrapperStyle,
2158
+ className: "calendar-custom-cell w-[calc(824/1920*100vw)] min-l:max-w-[824px] l:w-full",
2159
+ children: [
2160
+ /* @__PURE__ */ jsx("style", { children: `
1975
2161
  .calendar-custom-cell .ant-picker-cell {
1976
2162
  padding: 6px !important;
2163
+ text-align: center !important;
2164
+ }
2165
+ .calendar-custom-cell .ant-picker-cell .ant-picker-cell-inner {
2166
+ margin: 0 auto !important;
1977
2167
  }
1978
2168
  .calendar-custom-cell .ant-picker-cell-inner {
1979
- width: 100px !important;
1980
- height: 100px !important;
2169
+ width: 38px !important;
2170
+ height: 38px !important;
1981
2171
  display: flex !important;
1982
2172
  align-items: center !important;
1983
2173
  justify-content: center !important;
1984
- border-radius: 20px !important;
2174
+ border-radius: 8px !important;
1985
2175
  border: 1px solid #E4E5E6 !important;
2176
+ aspect-ratio: 1 / 1 !important;
2177
+ }
2178
+ @media (min-width: 1024px) and (max-width: 1919px) {
2179
+ .calendar-custom-cell .ant-picker-cell-inner {
2180
+ width: 54px !important;
2181
+ height: 54px !important;
2182
+ border-radius: 12px !important;
2183
+ }
2184
+ .calendar-custom-cell .ant-picker-calendar-date-value {
2185
+ line-height: 54px !important;
2186
+ }
2187
+ }
2188
+ @media (min-width: 1920px) {
2189
+ .calendar-custom-cell .ant-picker-cell-inner {
2190
+ width: 100px !important;
2191
+ height: 100px !important;
2192
+ border-radius: 20px !important;
2193
+ }
2194
+ .calendar-custom-cell .ant-picker-calendar-date-value {
2195
+ line-height: 100px !important;
2196
+ }
1986
2197
  }
1987
- .calendar-custom-cell .ant-picker-cell-selected .ant-picker-cell-inner {
2198
+ .calendar-custom-cell .ant-picker-cell-selected .ant-picker-cell-inner,
2199
+ .calendar-custom-cell .ant-picker-cell-selected:not(.ant-picker-cell-disabled) .ant-picker-cell-inner {
1988
2200
  background-color: #3ADB67 !important;
1989
2201
  color: white !important;
1990
2202
  border-color: #3ADB67 !important;
1991
2203
  }
2204
+ .calendar-custom-cell .ant-picker-cell-in-view.ant-picker-cell-selected .ant-picker-cell-inner {
2205
+ background-color: #3ADB67 !important;
2206
+ color: white !important;
2207
+ }
1992
2208
  .calendar-custom-cell .ant-picker-cell-today .ant-picker-cell-inner {
1993
2209
  border-color: #3ADB67 !important;
1994
- border-radius: 20px !important;
2210
+ border-radius: 8px !important;
2211
+ }
2212
+ @media (min-width: 1024px) and (max-width: 1919px) {
2213
+ .calendar-custom-cell .ant-picker-cell-today .ant-picker-cell-inner {
2214
+ border-radius: 12px !important;
2215
+ }
2216
+ }
2217
+ @media (min-width: 1920px) {
2218
+ .calendar-custom-cell .ant-picker-cell-today .ant-picker-cell-inner {
2219
+ border-radius: 20px !important;
2220
+ }
1995
2221
  }
1996
2222
  .calendar-custom-cell .ant-picker-cell-today .ant-picker-cell-inner::before {
1997
2223
  display: none !important;
1998
2224
  }
1999
2225
  .calendar-custom-cell .ant-picker-calendar-date-value {
2000
- line-height: 100px !important;
2226
+ line-height: 38px !important;
2001
2227
  }
2002
2228
  .calendar-custom-cell .ant-picker-content {
2003
2229
  width: 100% !important;
@@ -2005,135 +2231,181 @@ var DateTimePicker = ({
2005
2231
  .calendar-custom-cell .ant-picker-content thead tr th {
2006
2232
  line-height: 48px !important;
2007
2233
  }
2234
+ .calendar-custom-cell .ant-picker-cell-disabled .ant-picker-cell-inner {
2235
+ background-color: #F5F5F5 !important;
2236
+ color: #BDBDBD !important;
2237
+ border-color: #E4E5E6 !important;
2238
+ cursor: not-allowed !important;
2239
+ box-shadow: none !important;
2240
+ }
2241
+ .calendar-custom-cell .ant-picker-cell-disabled:hover .ant-picker-cell-inner {
2242
+ background-color: #F5F5F5 !important;
2243
+ border-color: #E4E5E6 !important;
2244
+ box-shadow: none !important;
2245
+ }
2246
+ .calendar-custom-cell .ant-picker-cell-disabled::before {
2247
+ display: none !important;
2248
+ }
2249
+ .calendar-custom-cell .ant-picker-cell-disabled::after {
2250
+ display: none !important;
2251
+ }
2008
2252
  ` }),
2009
- /* @__PURE__ */ jsx(
2010
- Calendar,
2011
- {
2012
- fullscreen: false,
2013
- value: selectedDate,
2014
- onChange: (date) => setSelectedDate(date),
2015
- headerRender: ({ value, onChange }) => {
2016
- const year = value.year();
2017
- const month = value.month();
2018
- const yearOptions = Array.from({ length: 20 }, (_, i) => {
2019
- const label = year - 10 + i;
2020
- return { label, value: label };
2021
- });
2022
- const monthOptions = value.localeData().months().map((label, index) => ({
2023
- label,
2024
- value: index
2025
- }));
2026
- const monthText = monthOptions?.find((item) => {
2027
- return item?.value === month;
2028
- });
2029
- setSelectMonth(monthText?.label || "");
2030
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [
2031
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
2032
- /* @__PURE__ */ jsx(
2033
- Select,
2253
+ /* @__PURE__ */ jsx(
2254
+ Calendar,
2255
+ {
2256
+ fullscreen: false,
2257
+ value: calendarValue,
2258
+ onSelect: (date) => {
2259
+ setSelectedDate(date);
2260
+ setCalendarValue(date);
2261
+ },
2262
+ onPanelChange: (date) => {
2263
+ setCalendarValue(date);
2264
+ },
2265
+ disabledDate: (current) => {
2266
+ if (!current) return false;
2267
+ if (current.isSame(dayjs(), "day")) return false;
2268
+ if (current.isBefore(dayjs(), "day")) return true;
2269
+ const dateStr = current.format("YYYY-MM-DD");
2270
+ return !availableDates.has(dateStr);
2271
+ },
2272
+ fullCellRender: (date) => {
2273
+ const isSelected = selectedDate && date.isSame(selectedDate, "day");
2274
+ const isToday = date.isSame(dayjs(), "day");
2275
+ const dateStr = date.format("YYYY-MM-DD");
2276
+ const isDisabled = !isToday && (date.isBefore(dayjs(), "day") || !availableDates.has(dateStr));
2277
+ return /* @__PURE__ */ jsx(
2278
+ "div",
2034
2279
  {
2035
- value: month,
2036
- options: monthOptions,
2037
- onChange: (newMonth) => {
2038
- const now = value.clone().month(newMonth);
2039
- onChange(now);
2040
- },
2041
- variant: "borderless",
2042
- className: "text-2xl font-medium",
2043
- popupMatchSelectWidth: false,
2280
+ className: `ant-picker-cell-inner ${isSelected ? "ant-picker-cell-inner-selected" : ""} ${isToday ? "ant-picker-cell-inner-today" : ""}`,
2044
2281
  style: {
2045
- fontSize: "24px",
2046
- fontWeight: 500
2047
- }
2048
- }
2049
- ),
2050
- /* @__PURE__ */ jsx(
2051
- Select,
2052
- {
2053
- value: year,
2054
- options: yearOptions,
2055
- onChange: (newYear) => {
2056
- const now = value.clone().year(newYear);
2057
- onChange(now);
2282
+ backgroundColor: isSelected ? "#3ADB67" : void 0,
2283
+ color: isSelected ? "white" : isDisabled ? "#BDBDBD" : void 0,
2284
+ borderColor: isSelected ? "#3ADB67" : isToday ? "#3ADB67" : void 0
2058
2285
  },
2059
- variant: "borderless",
2060
- className: "text-2xl font-medium",
2061
- popupMatchSelectWidth: false,
2062
- style: {
2063
- fontSize: "24px",
2064
- fontWeight: 500
2065
- }
2286
+ children: /* @__PURE__ */ jsx("div", { className: "ant-picker-calendar-date-value", children: date.date() })
2066
2287
  }
2067
- )
2068
- ] }),
2069
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
2070
- /* @__PURE__ */ jsx(
2071
- "button",
2072
- {
2073
- onClick: () => {
2074
- const newDate = value.subtract(1, "month");
2075
- onChange(newDate);
2076
- },
2077
- className: "w-10 h-10 flex items-center justify-center hover:bg-gray-100 rounded-lg transition-colors",
2078
- children: /* @__PURE__ */ jsx(
2079
- "svg",
2288
+ );
2289
+ },
2290
+ headerRender: ({ value, onChange }) => {
2291
+ const year = value.year();
2292
+ const month = value.month();
2293
+ const yearOptions = Array.from({ length: 20 }, (_, i) => {
2294
+ const label = year - 10 + i;
2295
+ return { label, value: label };
2296
+ });
2297
+ const monthOptions = value.localeData().months().map((label, index) => ({
2298
+ label,
2299
+ value: index
2300
+ }));
2301
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [
2302
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
2303
+ /* @__PURE__ */ jsx(
2304
+ Select,
2080
2305
  {
2081
- width: "20",
2082
- height: "20",
2083
- viewBox: "0 0 20 20",
2084
- fill: "none",
2085
- xmlns: "http://www.w3.org/2000/svg",
2306
+ value: month,
2307
+ options: monthOptions,
2308
+ onChange: (newMonth) => {
2309
+ const now = value.clone().month(newMonth);
2310
+ onChange(now);
2311
+ },
2312
+ variant: "borderless",
2313
+ className: "text-2xl font-medium",
2314
+ popupMatchSelectWidth: false,
2315
+ style: {
2316
+ fontSize: "24px",
2317
+ fontWeight: 500
2318
+ }
2319
+ }
2320
+ ),
2321
+ /* @__PURE__ */ jsx(
2322
+ Select,
2323
+ {
2324
+ value: year,
2325
+ options: yearOptions,
2326
+ onChange: (newYear) => {
2327
+ const now = value.clone().year(newYear);
2328
+ onChange(now);
2329
+ },
2330
+ variant: "borderless",
2331
+ className: "text-2xl font-medium",
2332
+ popupMatchSelectWidth: false,
2333
+ style: {
2334
+ fontSize: "24px",
2335
+ fontWeight: 500
2336
+ }
2337
+ }
2338
+ )
2339
+ ] }),
2340
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
2341
+ /* @__PURE__ */ jsx(
2342
+ "button",
2343
+ {
2344
+ onClick: () => {
2345
+ const newDate = value.subtract(1, "month");
2346
+ onChange(newDate);
2347
+ },
2348
+ className: "w-10 h-10 flex items-center justify-center hover:bg-gray-100 rounded-lg transition-colors",
2086
2349
  children: /* @__PURE__ */ jsx(
2087
- "path",
2350
+ "svg",
2088
2351
  {
2089
- d: "M12 16L6 10L12 4",
2090
- stroke: "currentColor",
2091
- strokeWidth: "2",
2092
- strokeLinecap: "round",
2093
- strokeLinejoin: "round"
2352
+ width: "20",
2353
+ height: "20",
2354
+ viewBox: "0 0 20 20",
2355
+ fill: "none",
2356
+ xmlns: "http://www.w3.org/2000/svg",
2357
+ children: /* @__PURE__ */ jsx(
2358
+ "path",
2359
+ {
2360
+ d: "M12 16L6 10L12 4",
2361
+ stroke: "currentColor",
2362
+ strokeWidth: "2",
2363
+ strokeLinecap: "round",
2364
+ strokeLinejoin: "round"
2365
+ }
2366
+ )
2094
2367
  }
2095
2368
  )
2096
2369
  }
2097
- )
2098
- }
2099
- ),
2100
- /* @__PURE__ */ jsx(
2101
- "button",
2102
- {
2103
- onClick: () => {
2104
- const newDate = value.add(1, "month");
2105
- onChange(newDate);
2106
- },
2107
- className: "w-10 h-10 flex items-center justify-center hover:bg-gray-100 rounded-lg transition-colors",
2108
- children: /* @__PURE__ */ jsx(
2109
- "svg",
2370
+ ),
2371
+ /* @__PURE__ */ jsx(
2372
+ "button",
2110
2373
  {
2111
- width: "20",
2112
- height: "20",
2113
- viewBox: "0 0 20 20",
2114
- fill: "none",
2115
- xmlns: "http://www.w3.org/2000/svg",
2374
+ onClick: () => {
2375
+ const newDate = value.add(1, "month");
2376
+ onChange(newDate);
2377
+ },
2378
+ className: "w-10 h-10 flex items-center justify-center hover:bg-gray-100 rounded-lg transition-colors",
2116
2379
  children: /* @__PURE__ */ jsx(
2117
- "path",
2380
+ "svg",
2118
2381
  {
2119
- d: "M8 4L14 10L8 16",
2120
- stroke: "currentColor",
2121
- strokeWidth: "2",
2122
- strokeLinecap: "round",
2123
- strokeLinejoin: "round"
2382
+ width: "20",
2383
+ height: "20",
2384
+ viewBox: "0 0 20 20",
2385
+ fill: "none",
2386
+ xmlns: "http://www.w3.org/2000/svg",
2387
+ children: /* @__PURE__ */ jsx(
2388
+ "path",
2389
+ {
2390
+ d: "M8 4L14 10L8 16",
2391
+ stroke: "currentColor",
2392
+ strokeWidth: "2",
2393
+ strokeLinecap: "round",
2394
+ strokeLinejoin: "round"
2395
+ }
2396
+ )
2124
2397
  }
2125
2398
  )
2126
2399
  }
2127
2400
  )
2128
- }
2129
- )
2130
- ] })
2131
- ] });
2132
- },
2133
- onPanelChange
2134
- }
2135
- )
2136
- ] })
2401
+ ] })
2402
+ ] });
2403
+ }
2404
+ }
2405
+ )
2406
+ ]
2407
+ }
2408
+ )
2137
2409
  }
2138
2410
  ),
2139
2411
  /* @__PURE__ */ jsxs("div", { className: "bg-white p-[24px] rounded-[12px] flex-1", children: [
@@ -2144,10 +2416,16 @@ var DateTimePicker = ({
2144
2416
  "button",
2145
2417
  {
2146
2418
  onClick: () => {
2147
- const newDate = selectedDate.subtract(1, "day");
2148
- setSelectedDate(newDate);
2419
+ if (selectedDate) {
2420
+ const newDate = selectedDate.subtract(1, "day");
2421
+ if (!newDate.isBefore(dayjs(), "day")) {
2422
+ setSelectedDate(newDate);
2423
+ setCalendarValue(newDate);
2424
+ }
2425
+ }
2149
2426
  },
2150
- className: "w-10 h-10 flex items-center justify-center hover:bg-gray-100 rounded-lg transition-colors",
2427
+ disabled: !selectedDate || selectedDate.isSame(dayjs(), "day") || selectedDate.isBefore(dayjs(), "day"),
2428
+ className: "w-10 h-10 flex items-center justify-center hover:bg-gray-100 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
2151
2429
  children: /* @__PURE__ */ jsx(
2152
2430
  "svg",
2153
2431
  {
@@ -2167,15 +2445,19 @@ var DateTimePicker = ({
2167
2445
  )
2168
2446
  }
2169
2447
  ),
2170
- /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center", children: selectMonth }),
2448
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center", children: selectedDate ? selectedDate.format("MMMM D, YYYY") : "" }),
2171
2449
  /* @__PURE__ */ jsx(
2172
2450
  "button",
2173
2451
  {
2174
2452
  onClick: () => {
2175
- const newDate = selectedDate.add(1, "day");
2176
- setSelectedDate(newDate);
2453
+ if (selectedDate) {
2454
+ const newDate = selectedDate.add(1, "day");
2455
+ setSelectedDate(newDate);
2456
+ setCalendarValue(newDate);
2457
+ }
2177
2458
  },
2178
- className: "w-10 h-10 flex items-center justify-center hover:bg-gray-100 rounded-lg transition-colors",
2459
+ disabled: !selectedDate,
2460
+ className: "w-10 h-10 flex items-center justify-center hover:bg-gray-100 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
2179
2461
  children: /* @__PURE__ */ jsx(
2180
2462
  "svg",
2181
2463
  {
@@ -2232,7 +2514,11 @@ var DateTimePicker = ({
2232
2514
  },
2233
2515
  slot.id
2234
2516
  );
2235
- }) })
2517
+ }) }),
2518
+ !timeslotsLoading && dayTimeslots?.length > 0 && /* @__PURE__ */ jsx("div", { className: "py-4 text-right", children: pageData?.timezone?.replace(
2519
+ "{{timezone}}",
2520
+ demoRoom?.timezone || timezone || ""
2521
+ ) })
2236
2522
  ] })
2237
2523
  ] }),
2238
2524
  /* @__PURE__ */ jsxs("div", { className: "mt-12", children: [
@@ -2353,12 +2639,9 @@ var DemoRoomDetail = ({
2353
2639
  data: demoRoom,
2354
2640
  loading,
2355
2641
  error
2356
- } = useDemoRoom(
2357
- apiClient,
2358
- demoRoomCode || "",
2359
- locale,
2360
- { enabled: !!apiClient && !!demoRoomCode }
2361
- );
2642
+ } = useDemoRoom(apiClient, demoRoomCode || "", locale, {
2643
+ enabled: !!apiClient && !!demoRoomCode
2644
+ });
2362
2645
  const title = demoRoom?.name || titleProp || "Design District Demo Room";
2363
2646
  const descriptions = demoRoom?.description ? [demoRoom.description] : descriptionsProp || defaultDescriptions;
2364
2647
  const devices = demoRoom?.description || devicesProp || "eufyMake E1, eufyMake M5";
@@ -2387,8 +2670,8 @@ var DemoRoomDetail = ({
2387
2670
  /* @__PURE__ */ jsx("p", { className: "text-sm mt-2", children: error.message })
2388
2671
  ] }) });
2389
2672
  }
2390
- return /* @__PURE__ */ jsx("div", { className: cn("w-full", className), ...props, children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-8 items-start", children: [
2391
- /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
2673
+ return /* @__PURE__ */ jsx("div", { className: cn("w-full", className), ...props, children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-8 l:flex l:flex-col items-start py-[24px]", children: [
2674
+ /* @__PURE__ */ jsxs("div", { className: "space-y-6 py-[24px]", children: [
2392
2675
  /* @__PURE__ */ jsx("h1", { className: "text-[40px] font-bold text-gray-900 leading-tight", children: title }),
2393
2676
  /* @__PURE__ */ jsx("div", { className: "space-y-4", children: descriptions.map((desc, index) => /* @__PURE__ */ jsx(
2394
2677
  "p",
@@ -2515,7 +2798,7 @@ var DemoRoomDetail = ({
2515
2798
  ] })
2516
2799
  ] })
2517
2800
  ] }),
2518
- /* @__PURE__ */ jsx("div", { className: "relative h-[400px] rounded-2xl overflow-hidden", children: images.length > 0 ? /* @__PURE__ */ jsx(
2801
+ /* @__PURE__ */ jsx("div", { className: "relative l:w-full h-[400px] rounded-2xl overflow-hidden", children: images.length > 0 ? /* @__PURE__ */ jsx(
2519
2802
  Swiper,
2520
2803
  {
2521
2804
  ...swiperVersion === "11+" && Navigation && Pagination && Autoplay ? { modules: [Navigation, Pagination, Autoplay] } : {},