@swift-food-services/catering-widget 0.2.0-beta.2 → 0.2.0-beta.3

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.cjs CHANGED
@@ -12518,7 +12518,15 @@ function useChatSession(options = {}) {
12518
12518
  };
12519
12519
  return [...historicMessages, newLive];
12520
12520
  }
12521
- return existingLive ? [...historicMessages, existingLive] : historicMessages;
12521
+ if (!existingLive) return historicMessages;
12522
+ const carriedParts = existingLive.parts.filter(
12523
+ (p) => p.type !== "menu_preview" && p.type !== "restaurant_info"
12524
+ );
12525
+ if (carriedParts.length === 0) return historicMessages;
12526
+ return [
12527
+ ...historicMessages,
12528
+ { ...existingLive, parts: carriedParts }
12529
+ ];
12522
12530
  });
12523
12531
  if (markLive && newLiveParts.length > 0) {
12524
12532
  const previewIdx = finalLiveParts.findIndex(
@@ -12983,7 +12991,6 @@ function mergeAdaptedMealParts(data) {
12983
12991
  for (let i = 0; i < meals.length; i++) {
12984
12992
  const meal = meals[i];
12985
12993
  const blocks = meal.intentBlocks ?? [];
12986
- if (blocks.length === 0) continue;
12987
12994
  synthesized.push({
12988
12995
  type: "meal_session",
12989
12996
  mealSessionIndex: i,
@@ -13057,7 +13064,7 @@ function findLatestMealSessionParts(messages) {
13057
13064
  (a, b) => a.mealSessionIndex - b.mealSessionIndex
13058
13065
  );
13059
13066
  }
13060
- var STORAGE_KEY_PREFIX = "swift-food-cart-v2-";
13067
+ var STORAGE_KEY_PREFIX = "swift-food-cart-v3-";
13061
13068
  var emptyIntent = () => ({
13062
13069
  selectedRestaurantId: null,
13063
13070
  qtyOverrides: {},
@@ -13595,7 +13602,7 @@ function DraftItemRow({
13595
13602
  marginTop: 8,
13596
13603
  alignItems: "center",
13597
13604
  flexWrap: "wrap",
13598
- paddingLeft: showCheckbox ? 102 : 68
13605
+ paddingLeft: showCheckbox ? 168 : 132
13599
13606
  },
13600
13607
  children: [
13601
13608
  onSwap && /* @__PURE__ */ jsxRuntime.jsx(
@@ -13729,9 +13736,9 @@ function ItemPhoto({
13729
13736
  "div",
13730
13737
  {
13731
13738
  style: {
13732
- width: 56,
13733
- height: 56,
13734
- borderRadius: 10,
13739
+ width: 120,
13740
+ height: 120,
13741
+ borderRadius: 14,
13735
13742
  background: src ? `url(${src}) center/cover` : PLACEHOLDER_BG,
13736
13743
  flexShrink: 0,
13737
13744
  position: "relative",
@@ -13749,7 +13756,7 @@ function ItemPhoto({
13749
13756
  display: "flex",
13750
13757
  alignItems: "center",
13751
13758
  justifyContent: "center",
13752
- fontSize: "1.6rem",
13759
+ fontSize: "2.2rem",
13753
13760
  color: "var(--ink-faint)"
13754
13761
  },
13755
13762
  children: initial
@@ -16663,8 +16670,25 @@ function readUnlocked() {
16663
16670
  return false;
16664
16671
  }
16665
16672
  }
16673
+ var unlockedValue = readUnlocked();
16674
+ var subscribers = /* @__PURE__ */ new Set();
16675
+ function setUnlocked(next) {
16676
+ if (unlockedValue === next) return;
16677
+ unlockedValue = next;
16678
+ subscribers.forEach((cb) => cb());
16679
+ }
16680
+ function subscribe(cb) {
16681
+ subscribers.add(cb);
16682
+ return () => {
16683
+ subscribers.delete(cb);
16684
+ };
16685
+ }
16666
16686
  function useBetaUnlock() {
16667
- const [unlocked, setUnlocked] = react.useState(readUnlocked);
16687
+ const unlocked = react.useSyncExternalStore(
16688
+ subscribe,
16689
+ () => unlockedValue,
16690
+ () => false
16691
+ );
16668
16692
  const tryUnlock = react.useCallback((code) => {
16669
16693
  if (code.trim() !== BETA_CODE) return false;
16670
16694
  setUnlocked(true);
@@ -18065,6 +18089,11 @@ function IntentStepper({
18065
18089
  () => checkMinOrders(orderedMeals, aiMealSessions, cart),
18066
18090
  [orderedMeals, aiMealSessions, cart]
18067
18091
  );
18092
+ const myPos = orderedMeals.findIndex(
18093
+ (m) => m.mealSessionIndex === activeMealSessionIndex
18094
+ );
18095
+ const isFirstMeal = myPos <= 0;
18096
+ const isLastMeal = myPos >= 0 && myPos === orderedMeals.length - 1;
18068
18097
  if (!activeMeal) {
18069
18098
  return /* @__PURE__ */ jsxRuntime.jsxs(
18070
18099
  "div",
@@ -18085,6 +18114,23 @@ function IntentStepper({
18085
18114
  );
18086
18115
  }
18087
18116
  if (blocks.length === 0) {
18117
+ const emptyPrevLabel = !isFirstMeal ? aiMealSessions[orderedMeals[myPos - 1].mealSessionIndex]?.sessionName ?? null : null;
18118
+ const emptyNextLabel = !isLastMeal ? aiMealSessions[orderedMeals[myPos + 1].mealSessionIndex]?.sessionName ?? null : null;
18119
+ const handleEmptyPrev = () => {
18120
+ if (sending || isFirstMeal) return;
18121
+ pendingReviewRef.current = true;
18122
+ onPickMealSession(orderedMeals[myPos - 1].mealSessionIndex);
18123
+ };
18124
+ const handleEmptyNext = () => {
18125
+ if (sending || isLastMeal) return;
18126
+ onPickMealSession(orderedMeals[myPos + 1].mealSessionIndex);
18127
+ };
18128
+ const handleEmptyJumpTo = (targetMealSessionIndex, targetIntentIdx) => {
18129
+ if (sending) return;
18130
+ if (targetMealSessionIndex === activeMealSessionIndex) return;
18131
+ pendingIntentIdxRef.current = targetIntentIdx;
18132
+ onPickMealSession(targetMealSessionIndex);
18133
+ };
18088
18134
  return /* @__PURE__ */ jsxRuntime.jsxs(
18089
18135
  "div",
18090
18136
  {
@@ -18094,11 +18140,34 @@ function IntentStepper({
18094
18140
  flex: 1,
18095
18141
  minHeight: 0,
18096
18142
  marginBottom: 16,
18143
+ // Cluster topSlot + empty card + NavBar as one block centred
18144
+ // vertically — same trick the populated branch uses so the
18145
+ // tabs / nav don't get pinned to the panel's top/bottom
18146
+ // edges when the content above is short.
18097
18147
  justifyContent: "center"
18098
18148
  },
18099
18149
  children: [
18100
18150
  topSlot && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginBottom: 12, flexShrink: 0 }, children: topSlot }),
18101
- /* @__PURE__ */ jsxRuntime.jsx(EmptyStepperState, {})
18151
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flexShrink: 0, marginBottom: 8 }, children: /* @__PURE__ */ jsxRuntime.jsx(EmptyStepperState, { missingFields: activeMealMeta?.missingFields }) }),
18152
+ /* @__PURE__ */ jsxRuntime.jsx(
18153
+ NavBar,
18154
+ {
18155
+ onPrev: handleEmptyPrev,
18156
+ onNext: handleEmptyNext,
18157
+ onJumpTo: handleEmptyJumpTo,
18158
+ prevLabel: emptyPrevLabel,
18159
+ nextLabel: emptyNextLabel,
18160
+ atFinal: false,
18161
+ sending,
18162
+ showPrev: !isFirstMeal,
18163
+ showNext: !isLastMeal,
18164
+ mealSessions: orderedMeals,
18165
+ aiMealSessions,
18166
+ activeMealSessionIndex,
18167
+ currentIntentIndex: 0,
18168
+ cart
18169
+ }
18170
+ )
18102
18171
  ]
18103
18172
  }
18104
18173
  );
@@ -18106,13 +18175,8 @@ function IntentStepper({
18106
18175
  const pickedName = selected?.restaurant.name ?? "\u2014";
18107
18176
  const pickedId = selected?.restaurant.id ?? "";
18108
18177
  const alts = block ? block.restaurantPicks.filter((rp) => rp.restaurant.id !== pickedId) : [];
18109
- const myPos = orderedMeals.findIndex(
18110
- (m) => m.mealSessionIndex === activeMealSessionIndex
18111
- );
18112
18178
  const isFirstIntent = !isReview && safeIntentIdx === 0;
18113
18179
  const isLastIntent = !isReview && safeIntentIdx === blocks.length - 1;
18114
- const isFirstMeal = myPos <= 0;
18115
- const isLastMeal = myPos >= 0 && myPos === orderedMeals.length - 1;
18116
18180
  const atFinal = isReview && isLastMeal;
18117
18181
  const prevLabel = isReview ? capitalize(blocks[blocks.length - 1].intent.phrase) : !isFirstIntent ? capitalize(blocks[safeIntentIdx - 1].intent.phrase) : !isFirstMeal ? aiMealSessions[orderedMeals[myPos - 1].mealSessionIndex]?.sessionName ?? null : null;
18118
18182
  const nextLabel = isReview ? !isLastMeal ? aiMealSessions[orderedMeals[myPos + 1].mealSessionIndex]?.sessionName ?? null : null : !isLastIntent ? capitalize(blocks[safeIntentIdx + 1].intent.phrase) : "Review";
@@ -18579,6 +18643,7 @@ function NavBar({
18579
18643
  atFinal,
18580
18644
  sending,
18581
18645
  showPrev,
18646
+ showNext = true,
18582
18647
  mealSessions,
18583
18648
  aiMealSessions,
18584
18649
  activeMealSessionIndex,
@@ -18665,7 +18730,7 @@ function NavBar({
18665
18730
  {
18666
18731
  type: "button",
18667
18732
  onClick: onNext,
18668
- disabled: sending,
18733
+ disabled: !showNext || sending,
18669
18734
  className: "chip chip-brand",
18670
18735
  style: {
18671
18736
  height: 40,
@@ -18673,6 +18738,7 @@ function NavBar({
18673
18738
  fontSize: atFinal ? "0.95rem" : "0.85rem",
18674
18739
  fontWeight: 500,
18675
18740
  justifyContent: "center",
18741
+ visibility: showNext ? "visible" : "hidden",
18676
18742
  cursor: sending ? "default" : "pointer",
18677
18743
  opacity: sending ? 0.7 : 1
18678
18744
  },
@@ -18700,10 +18766,11 @@ function TimelinePill({
18700
18766
  const activeMeal = mealSessions[activeMealPos];
18701
18767
  if (!activeMeal) return null;
18702
18768
  const activeMealMeta = aiMealSessions[activeMeal.mealSessionIndex];
18703
- const isReviewStep = currentIntentIndex === activeMeal.intentBlocks.length;
18769
+ const isEmptyMeal = activeMeal.intentBlocks.length === 0;
18770
+ const isReviewStep = !isEmptyMeal && currentIntentIndex === activeMeal.intentBlocks.length;
18704
18771
  const currentIntent = activeMeal.intentBlocks[currentIntentIndex];
18705
- if (!isReviewStep && !currentIntent) return null;
18706
- const labelText = isReviewStep ? "Review" : currentIntent.intent.phrase;
18772
+ if (!isEmptyMeal && !isReviewStep && !currentIntent) return null;
18773
+ const labelText = isEmptyMeal ? null : isReviewStep ? "Review" : currentIntent.intent.phrase;
18707
18774
  return /* @__PURE__ */ jsxRuntime.jsxs(
18708
18775
  "div",
18709
18776
  {
@@ -18735,14 +18802,23 @@ function TimelinePill({
18735
18802
  opacity: hovered ? 1 : 0.85,
18736
18803
  transition: "opacity 150ms ease"
18737
18804
  },
18738
- "aria-label": `Step ${currentIntentIndex + 1} of ${activeMeal.intentBlocks.length + 1}: ${labelText}. Click to see the full itinerary.`,
18805
+ "aria-label": isEmptyMeal ? `${activeMealMeta?.sessionName ?? "Meal"}. Click to see the full itinerary.` : `Step ${currentIntentIndex + 1} of ${activeMeal.intentBlocks.length + 1}: ${labelText}. Click to see the full itinerary.`,
18739
18806
  "aria-expanded": hovered,
18740
18807
  children: [
18741
- /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: "var(--ink-faint)" }, children: [
18742
- activeMealMeta?.sessionName ?? `Meal ${activeMeal.mealSessionIndex + 1}`,
18743
- " \xB7 "
18744
- ] }),
18745
- /* @__PURE__ */ jsxRuntime.jsx(
18808
+ /* @__PURE__ */ jsxRuntime.jsxs(
18809
+ "span",
18810
+ {
18811
+ style: {
18812
+ color: isEmptyMeal ? "var(--ink)" : "var(--ink-faint)",
18813
+ fontWeight: isEmptyMeal ? 500 : 400
18814
+ },
18815
+ children: [
18816
+ activeMealMeta?.sessionName ?? `Meal ${activeMeal.mealSessionIndex + 1}`,
18817
+ !isEmptyMeal && " \xB7 "
18818
+ ]
18819
+ }
18820
+ ),
18821
+ !isEmptyMeal && /* @__PURE__ */ jsxRuntime.jsx(
18746
18822
  "span",
18747
18823
  {
18748
18824
  style: {
@@ -19222,7 +19298,23 @@ function EmptyIntentState({ message }) {
19222
19298
  }
19223
19299
  );
19224
19300
  }
19225
- function EmptyStepperState() {
19301
+ var MISSING_FIELD_LABELS = {
19302
+ guestCount: "guest count",
19303
+ sessionDate: "date",
19304
+ eventTime: "time"
19305
+ };
19306
+ function formatMissingFieldList(fields) {
19307
+ const labels = fields.map((f) => MISSING_FIELD_LABELS[f] ?? f);
19308
+ if (labels.length === 0) return "";
19309
+ if (labels.length === 1) return labels[0];
19310
+ if (labels.length === 2) return `${labels[0]} and ${labels[1]}`;
19311
+ return `${labels.slice(0, -1).join(", ")}, and ${labels[labels.length - 1]}`;
19312
+ }
19313
+ function EmptyStepperState({
19314
+ missingFields
19315
+ }) {
19316
+ const hasMissing = !!missingFields && missingFields.length > 0;
19317
+ const label = hasMissing ? formatMissingFieldList(missingFields) : null;
19226
19318
  return /* @__PURE__ */ jsxRuntime.jsx(
19227
19319
  "div",
19228
19320
  {
@@ -19234,7 +19326,11 @@ function EmptyStepperState() {
19234
19326
  textAlign: "center",
19235
19327
  color: "var(--ink-faint)"
19236
19328
  },
19237
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "display-italic", style: { fontSize: "0.95rem" }, children: "No items yet for this meal \u2014 keep chatting on the right." })
19329
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "display-italic", style: { fontSize: "0.95rem" }, children: hasMissing ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
19330
+ "Tell me the ",
19331
+ label,
19332
+ " for this meal and I'll suggest a menu."
19333
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: "No items yet for this meal \u2014 keep chatting on the right." }) })
19238
19334
  }
19239
19335
  );
19240
19336
  }
@@ -26049,17 +26145,8 @@ function useCateringTutorial({
26049
26145
  const [tutorialStep, setTutorialStep] = react.useState(null);
26050
26146
  const [tutorialPhase, setTutorialPhase] = react.useState("navigation");
26051
26147
  react.useEffect(() => {
26052
- const tutorialCompleted = localStorage.getItem(TUTORIAL_STORAGE_KEY);
26053
- if (tutorialCompleted) {
26054
- setTutorialPhase("completed");
26055
- setTutorialStep(null);
26056
- } else if (mealSessions.length === 1 && mealSessions[0].orderItems.length === 0) {
26057
- setTutorialPhase("navigation");
26058
- setTutorialStep(0);
26059
- } else {
26060
- setTutorialPhase("completed");
26061
- setTutorialStep(null);
26062
- }
26148
+ setTutorialPhase("completed");
26149
+ setTutorialStep(null);
26063
26150
  }, []);
26064
26151
  const getTutorialSteps = react.useCallback(() => {
26065
26152
  switch (tutorialPhase) {
@@ -26657,7 +26744,6 @@ function CateringOrderBuilder() {
26657
26744
  handleTutorialNext,
26658
26745
  handleSkipTutorial,
26659
26746
  triggerSessionCreated,
26660
- resetTutorial,
26661
26747
  getTutorialSteps
26662
26748
  } = useCateringTutorial({
26663
26749
  mealSessions,
@@ -26719,6 +26805,7 @@ function CateringOrderBuilder() {
26719
26805
  setExpandedItemId(item.id);
26720
26806
  };
26721
26807
  const { stickyTopOffset = 0, publishableKey, aiEnabled = false } = useCateringConfig();
26808
+ const { unlocked: aiBetaUnlocked, tryUnlock: tryUnlockAiBeta } = useBetaUnlock();
26722
26809
  const effectiveRightPanelTab = aiEnabled ? rightPanelTab : "cart";
26723
26810
  const [overlayVisible, setOverlayVisible] = react.useState(false);
26724
26811
  const basketColumnRef = react.useRef(null);
@@ -27702,40 +27789,6 @@ function CateringOrderBuilder() {
27702
27789
  ]
27703
27790
  }
27704
27791
  ),
27705
- /* @__PURE__ */ jsxRuntime.jsxs(
27706
- "button",
27707
- {
27708
- onClick: () => {
27709
- setIsDesktopCartMenuOpen(false);
27710
- resetTutorial();
27711
- setNavMode("dates");
27712
- setSelectedDayDate(null);
27713
- },
27714
- className: "flex w-full items-center gap-2 px-3 py-2.5 text-left text-sm text-gray-700 transition-colors hover:bg-base-100",
27715
- children: [
27716
- /* @__PURE__ */ jsxRuntime.jsx(
27717
- "svg",
27718
- {
27719
- xmlns: "http://www.w3.org/2000/svg",
27720
- className: "h-4 w-4",
27721
- fill: "none",
27722
- viewBox: "0 0 24 24",
27723
- stroke: "currentColor",
27724
- children: /* @__PURE__ */ jsxRuntime.jsx(
27725
- "path",
27726
- {
27727
- strokeLinecap: "round",
27728
- strokeLinejoin: "round",
27729
- strokeWidth: 2,
27730
- d: "M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
27731
- }
27732
- )
27733
- }
27734
- ),
27735
- "Tutorial"
27736
- ]
27737
- }
27738
- ),
27739
27792
  /* @__PURE__ */ jsxRuntime.jsxs(
27740
27793
  "button",
27741
27794
  {
@@ -27783,16 +27836,16 @@ function CateringOrderBuilder() {
27783
27836
  /* @__PURE__ */ jsxRuntime.jsx(
27784
27837
  "div",
27785
27838
  {
27786
- className: "absolute inset-x-0 top-0 overflow-y-auto bg-white",
27787
- style: { bottom: keyboardOffset + 64 },
27788
- children: mobileChatView === "results" ? /* @__PURE__ */ jsxRuntime.jsx(MobileResultsView, { onBack: () => setMobileChatView("chat") }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 pt-14 pb-4", children: /* @__PURE__ */ jsxRuntime.jsx(ChatMessagesView, {}) })
27839
+ className: `absolute inset-x-0 top-0 overflow-y-auto ${aiBetaUnlocked ? "bg-white" : ""}`,
27840
+ style: { bottom: keyboardOffset + (aiBetaUnlocked ? 64 : 0) },
27841
+ children: !aiBetaUnlocked ? /* @__PURE__ */ jsxRuntime.jsx(AIChatBetaGate, { onUnlock: tryUnlockAiBeta }) : mobileChatView === "results" ? /* @__PURE__ */ jsxRuntime.jsx(MobileResultsView, { onBack: () => setMobileChatView("chat") }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 pt-14 pb-4", children: /* @__PURE__ */ jsxRuntime.jsx(ChatMessagesView, {}) })
27789
27842
  }
27790
27843
  )
27791
27844
  ] }),
27792
27845
  /* @__PURE__ */ jsxRuntime.jsxs(
27793
27846
  "div",
27794
27847
  {
27795
- className: `fixed left-0 right-0 md:hidden z-50 ${keyboardOffset > 100 && !isMobileAIChatOpen ? "hidden" : ""}`,
27848
+ className: `fixed left-0 right-0 md:hidden z-50 ${keyboardOffset > 100 && !isMobileAIChatOpen || isMobileAIChatOpen && !aiBetaUnlocked ? "hidden" : ""}`,
27796
27849
  style: { bottom: keyboardOffset },
27797
27850
  children: [
27798
27851
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -27853,40 +27906,6 @@ function CateringOrderBuilder() {
27853
27906
  ]
27854
27907
  }
27855
27908
  ),
27856
- /* @__PURE__ */ jsxRuntime.jsxs(
27857
- "button",
27858
- {
27859
- onClick: () => {
27860
- setIsMobileCartMenuOpen(false);
27861
- resetTutorial();
27862
- setNavMode("dates");
27863
- setSelectedDayDate(null);
27864
- },
27865
- className: "flex w-full items-center gap-2 px-3 py-2.5 text-left text-sm text-gray-700 transition-colors hover:bg-base-100",
27866
- children: [
27867
- /* @__PURE__ */ jsxRuntime.jsx(
27868
- "svg",
27869
- {
27870
- xmlns: "http://www.w3.org/2000/svg",
27871
- className: "h-4 w-4",
27872
- fill: "none",
27873
- viewBox: "0 0 24 24",
27874
- stroke: "currentColor",
27875
- children: /* @__PURE__ */ jsxRuntime.jsx(
27876
- "path",
27877
- {
27878
- strokeLinecap: "round",
27879
- strokeLinejoin: "round",
27880
- strokeWidth: 2,
27881
- d: "M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
27882
- }
27883
- )
27884
- }
27885
- ),
27886
- "Tutorial"
27887
- ]
27888
- }
27889
- ),
27890
27909
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-3 border-t border-base-200" }),
27891
27910
  /* @__PURE__ */ jsxRuntime.jsxs(
27892
27911
  "button",
@@ -27910,15 +27929,21 @@ function CateringOrderBuilder() {
27910
27929
  "button",
27911
27930
  {
27912
27931
  type: "button",
27913
- onClick: () => setIsAIMobileUnavailableOpen(true),
27914
- title: "Coming Soon",
27932
+ onClick: () => {
27933
+ if (aiEnabled) {
27934
+ setIsMobileAIChatOpen(true);
27935
+ } else {
27936
+ setIsAIMobileUnavailableOpen(true);
27937
+ }
27938
+ },
27939
+ title: aiEnabled ? void 0 : "Coming Soon",
27915
27940
  className: `absolute inset-0 flex items-center justify-center gap-1.5 px-4 py-1 transition duration-[250ms] ease-out ${isMobileSearchOpen || isMobileAIChatOpen ? "pointer-events-none -translate-y-full opacity-0" : "translate-y-0 opacity-100"}`,
27916
27941
  "aria-hidden": isMobileSearchOpen || isMobileAIChatOpen,
27917
27942
  tabIndex: isMobileSearchOpen || isMobileAIChatOpen ? -1 : 0,
27918
27943
  children: [
27919
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "h-4 w-4 text-gray-400" }),
27920
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold text-gray-400", children: "Ask AI" }),
27921
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 rounded-full bg-primary px-1.5 py-0.5 text-[8px] font-bold uppercase tracking-wider text-white shadow-sm whitespace-nowrap", children: "Coming Soon" })
27944
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: `h-4 w-4 ${aiEnabled ? "text-primary" : "text-gray-400"}` }),
27945
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-sm font-semibold ${aiEnabled ? "text-gray-800" : "text-gray-400"}`, children: "Ask AI" }),
27946
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 rounded-full bg-primary px-1.5 py-0.5 text-[8px] font-bold uppercase tracking-wider text-white shadow-sm whitespace-nowrap", children: aiEnabled ? "Beta" : "Soon" })
27922
27947
  ]
27923
27948
  }
27924
27949
  ),
@@ -28146,13 +28171,12 @@ function CateringOrderBuilder() {
28146
28171
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "h-5 w-5 text-primary" }) }),
28147
28172
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
28148
28173
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-bold text-gray-900", children: "Plan your menu with AI" }),
28149
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-500", children: "Not yet available on mobile" })
28174
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-500", children: "Coming soon" })
28150
28175
  ] })
28151
28176
  ] }),
28152
28177
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6 space-y-2 text-sm text-gray-600", children: [
28153
28178
  /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Chat with our AI to plan the perfect menu \u2014 tell it your guest count, dietary needs, and budget." }),
28154
- /* @__PURE__ */ jsxRuntime.jsx("p", { children: "It's ready to use on the web. Open this page on a desktop or laptop to try it." }),
28155
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-500", children: "Mobile support is coming soon." })
28179
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-500", children: "We're putting the finishing touches on it. Check back soon." })
28156
28180
  ] }),
28157
28181
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex", children: /* @__PURE__ */ jsxRuntime.jsx(
28158
28182
  "button",