@instockng/storefront-ui 1.0.108 → 1.0.109

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 (198) hide show
  1. package/dist/components/ProductAssistantChips.d.ts +9 -8
  2. package/dist/components/ProductAssistantChips.d.ts.map +1 -1
  3. package/dist/index100.mjs +27 -52
  4. package/dist/index101.mjs +8 -5
  5. package/dist/index102.mjs +74 -4
  6. package/dist/index103.mjs +3 -178
  7. package/dist/index104.mjs +2 -53
  8. package/dist/index105.mjs +82 -68
  9. package/dist/index106.mjs +54 -2
  10. package/dist/index107.mjs +5 -5
  11. package/dist/index108.mjs +4 -1133
  12. package/dist/index109.mjs +177 -18
  13. package/dist/index110.mjs +50 -52
  14. package/dist/index111.mjs +69 -33
  15. package/dist/index112.mjs +2 -2
  16. package/dist/index113.mjs +28 -2
  17. package/dist/index114.mjs +18 -2
  18. package/dist/index115.mjs +213 -26
  19. package/dist/index116.mjs +175 -13
  20. package/dist/index117.mjs +17 -210
  21. package/dist/index118.mjs +17 -174
  22. package/dist/index119.mjs +25 -14
  23. package/dist/index120.mjs +150 -17
  24. package/dist/index121.mjs +13 -26
  25. package/dist/index122.mjs +24 -149
  26. package/dist/index123.mjs +77 -13
  27. package/dist/index124.mjs +27 -20
  28. package/dist/index125.mjs +137 -76
  29. package/dist/index126.mjs +50 -33
  30. package/dist/index127.mjs +19 -141
  31. package/dist/index128.mjs +22 -50
  32. package/dist/index129.mjs +14 -14
  33. package/dist/index130.mjs +18 -20
  34. package/dist/index131.mjs +14 -16
  35. package/dist/index132.mjs +14 -17
  36. package/dist/index133.mjs +12 -12
  37. package/dist/index134.mjs +58 -15
  38. package/dist/index135.mjs +11 -14
  39. package/dist/index136.mjs +30 -56
  40. package/dist/index137.mjs +15 -9
  41. package/dist/index138.mjs +26 -31
  42. package/dist/index139.mjs +16 -13
  43. package/dist/index140.mjs +11 -26
  44. package/dist/index141.mjs +12 -18
  45. package/dist/index142.mjs +40 -12
  46. package/dist/index143.mjs +16 -14
  47. package/dist/index144.mjs +263 -42
  48. package/dist/index145.mjs +62 -15
  49. package/dist/index146.mjs +7 -267
  50. package/dist/index147.mjs +2 -70
  51. package/dist/index148.mjs +2 -8
  52. package/dist/index149.mjs +33 -2
  53. package/dist/index150.mjs +2 -2
  54. package/dist/index151.mjs +37 -33
  55. package/dist/index152.mjs +43 -2
  56. package/dist/index153.mjs +2 -21
  57. package/dist/index154.mjs +19 -54
  58. package/dist/index155.mjs +55 -28
  59. package/dist/index156.mjs +28 -6
  60. package/dist/index157.mjs +6 -51
  61. package/dist/index158.mjs +51 -5
  62. package/dist/index159.mjs +6 -12
  63. package/dist/index160.mjs +12 -7
  64. package/dist/index161.mjs +6 -27
  65. package/dist/index162.mjs +28 -2
  66. package/dist/index163.mjs +2 -70
  67. package/dist/index164.mjs +67 -164
  68. package/dist/index165.mjs +167 -2
  69. package/dist/index169.mjs +1 -1
  70. package/dist/index170.mjs +1 -1
  71. package/dist/index171.mjs +1 -1
  72. package/dist/index172.mjs +1 -1
  73. package/dist/index173.mjs +1 -1
  74. package/dist/index175.mjs +3 -3
  75. package/dist/index176.mjs +1 -1
  76. package/dist/index178.mjs +3 -3
  77. package/dist/index179.mjs +1 -1
  78. package/dist/index184.mjs +2 -2
  79. package/dist/index186.mjs +1 -1
  80. package/dist/index188.mjs +2 -2
  81. package/dist/index189.mjs +5 -5
  82. package/dist/index192.mjs +1 -1
  83. package/dist/index195.mjs +1 -1
  84. package/dist/index198.mjs +3 -3
  85. package/dist/index199.mjs +1 -1
  86. package/dist/index203.mjs +2 -2
  87. package/dist/index205.mjs +2 -2
  88. package/dist/index209.mjs +1 -1
  89. package/dist/index211.mjs +2 -2
  90. package/dist/index22.mjs +1 -1
  91. package/dist/index220.mjs +2 -2
  92. package/dist/index224.mjs +2 -31
  93. package/dist/index225.mjs +107 -10
  94. package/dist/index226.mjs +2 -4
  95. package/dist/index227.mjs +2 -4
  96. package/dist/index228.mjs +2 -13
  97. package/dist/index229.mjs +2 -7
  98. package/dist/index23.mjs +13 -12
  99. package/dist/index230.mjs +2 -12
  100. package/dist/index231.mjs +2 -5
  101. package/dist/index232.mjs +2 -33
  102. package/dist/index233.mjs +2 -31
  103. package/dist/index234.mjs +2 -28
  104. package/dist/index235.mjs +34 -58
  105. package/dist/index236.mjs +2 -2
  106. package/dist/index237.mjs +233 -97
  107. package/dist/index238.mjs +2 -2
  108. package/dist/index239.mjs +33 -2
  109. package/dist/index240.mjs +65 -2
  110. package/dist/index241.mjs +25 -2
  111. package/dist/index243.mjs +2 -2
  112. package/dist/index245.mjs +2 -2
  113. package/dist/index246.mjs +2 -2
  114. package/dist/index247.mjs +2 -37
  115. package/dist/index248.mjs +2 -2
  116. package/dist/index249.mjs +2 -2
  117. package/dist/index250.mjs +2 -244
  118. package/dist/index251.mjs +13 -2
  119. package/dist/index252.mjs +7 -33
  120. package/dist/index253.mjs +30 -64
  121. package/dist/index254.mjs +10 -24
  122. package/dist/index255.mjs +4 -2
  123. package/dist/index256.mjs +4 -2
  124. package/dist/index257.mjs +2 -2
  125. package/dist/index258.mjs +4 -2
  126. package/dist/index259.mjs +12 -2
  127. package/dist/index260.mjs +5 -2
  128. package/dist/index261.mjs +33 -2
  129. package/dist/index262.mjs +31 -2
  130. package/dist/index263.mjs +28 -2
  131. package/dist/index264.mjs +61 -4
  132. package/dist/index267.mjs +2 -3
  133. package/dist/index268.mjs +2 -2
  134. package/dist/index269.mjs +18 -2
  135. package/dist/index270.mjs +46 -16
  136. package/dist/index271.mjs +2 -13
  137. package/dist/index272.mjs +2 -6
  138. package/dist/index273.mjs +2 -30
  139. package/dist/index275.mjs +91 -2
  140. package/dist/index276.mjs +2 -18
  141. package/dist/index277.mjs +3 -47
  142. package/dist/index278.mjs +2 -2
  143. package/dist/index279.mjs +2 -2
  144. package/dist/index280.mjs +17 -2
  145. package/dist/index281.mjs +13 -2
  146. package/dist/index282.mjs +6 -91
  147. package/dist/index283.mjs +30 -2
  148. package/dist/index43.mjs +1 -1
  149. package/dist/index44.mjs +1 -1
  150. package/dist/index45.mjs +1 -1
  151. package/dist/index46.mjs +1 -1
  152. package/dist/index47.mjs +1 -1
  153. package/dist/index48.mjs +2 -2
  154. package/dist/index50.mjs +1 -1
  155. package/dist/index54.mjs +3 -3
  156. package/dist/index58.mjs +1 -1
  157. package/dist/index63.mjs +17 -17
  158. package/dist/index64.mjs +2 -2
  159. package/dist/index65.mjs +1 -1
  160. package/dist/index66.mjs +1 -1
  161. package/dist/index67.mjs +1 -1
  162. package/dist/index68.mjs +1 -1
  163. package/dist/index69.mjs +1 -1
  164. package/dist/index70.mjs +1 -1
  165. package/dist/index71.mjs +1 -1
  166. package/dist/index72.mjs +1 -1
  167. package/dist/index73.mjs +1 -1
  168. package/dist/index74.mjs +1 -1
  169. package/dist/index75.mjs +1 -1
  170. package/dist/index76.mjs +1 -1
  171. package/dist/index77.mjs +1 -1
  172. package/dist/index78.mjs +1 -1
  173. package/dist/index79.mjs +23 -4
  174. package/dist/index80.mjs +2 -24
  175. package/dist/index81.mjs +23 -2
  176. package/dist/index82.mjs +7 -7
  177. package/dist/index83.mjs +73 -21
  178. package/dist/index84.mjs +14 -74
  179. package/dist/index85.mjs +62 -14
  180. package/dist/index86.mjs +4 -62
  181. package/dist/index87.mjs +2 -37
  182. package/dist/index88.mjs +5 -42
  183. package/dist/index89.mjs +1129 -230
  184. package/dist/index90.mjs +19 -5
  185. package/dist/index91.mjs +48 -127
  186. package/dist/index92.mjs +32 -67
  187. package/dist/index93.mjs +2 -87
  188. package/dist/index94.mjs +2 -29
  189. package/dist/index95.mjs +235 -9
  190. package/dist/index96.mjs +5 -74
  191. package/dist/index97.mjs +133 -3
  192. package/dist/index98.mjs +68 -2
  193. package/dist/index99.mjs +83 -79
  194. package/package.json +2 -2
  195. package/src/components/AssistantDrawer.stories.tsx +20 -41
  196. package/src/components/AssistantDrawer.tsx +1 -1
  197. package/src/components/ProductAssistantChips.stories.tsx +11 -6
  198. package/src/components/ProductAssistantChips.tsx +13 -8
package/dist/index99.mjs CHANGED
@@ -1,86 +1,90 @@
1
1
  'use client';
2
- import t from "./index89.mjs";
3
- import E from "./index100.mjs";
4
- function B(i) {
5
- return t.isPlainObject(i) || t.isArray(i);
6
- }
7
- function h(i) {
8
- return t.endsWith(i, "[]") ? i.slice(0, -2) : i;
9
- }
10
- function O(i, e, s) {
11
- return i ? i.concat(e).map(function(o, d) {
12
- return o = h(o), !s && d ? "[" + o + "]" : o;
13
- }).join(s ? "." : "") : e;
14
- }
15
- function T(i) {
16
- return t.isArray(i) && !i.some(B);
2
+ import t from "./index95.mjs";
3
+ import c from "./index106.mjs";
4
+ import u from "./index159.mjs";
5
+ import S from "./index105.mjs";
6
+ import h from "./index160.mjs";
7
+ import a from "./index161.mjs";
8
+ import O from "./index100.mjs";
9
+ function y(i, r, e) {
10
+ if (t.isString(i))
11
+ try {
12
+ return (r || JSON.parse)(i), t.trim(i);
13
+ } catch (n) {
14
+ if (n.name !== "SyntaxError")
15
+ throw n;
16
+ }
17
+ return (e || JSON.stringify)(i);
17
18
  }
18
- const S = t.toFlatObject(t, {}, null, function(e) {
19
- return /^is[A-Z]/.test(e);
20
- });
21
- function W(i, e, s) {
22
- if (!t.isObject(i))
23
- throw new TypeError("target must be an object");
24
- e = e || new FormData(), s = t.toFlatObject(s, {
25
- metaTokens: !0,
26
- dots: !1,
27
- indexes: !1
28
- }, !1, function(n, u) {
29
- return !t.isUndefined(u[n]);
30
- });
31
- const p = s.metaTokens, o = s.visitor || j, d = s.dots, m = s.indexes, w = (s.Blob || typeof Blob < "u" && Blob) && t.isSpecCompliantForm(e);
32
- if (!t.isFunction(o))
33
- throw new TypeError("visitor must be a function");
34
- function l(r) {
35
- if (r === null) return "";
36
- if (t.isDate(r))
37
- return r.toISOString();
38
- if (t.isBoolean(r))
39
- return r.toString();
40
- if (!w && t.isBlob(r))
41
- throw new E("Blob is not supported. Use a Buffer instead.");
42
- return t.isArrayBuffer(r) || t.isTypedArray(r) ? w && typeof Blob == "function" ? new Blob([r]) : Buffer.from(r) : r;
43
- }
44
- function j(r, n, u) {
45
- let f = r;
46
- if (r && !u && typeof r == "object") {
47
- if (t.endsWith(n, "{}"))
48
- n = p ? n : n.slice(0, -2), r = JSON.stringify(r);
49
- else if (t.isArray(r) && T(r) || (t.isFileList(r) || t.endsWith(n, "[]")) && (f = t.toArray(r)))
50
- return n = h(n), f.forEach(function(b, x) {
51
- !(t.isUndefined(b) || b === null) && e.append(
52
- // eslint-disable-next-line no-nested-ternary
53
- m === !0 ? O([n], x, d) : m === null ? n : n + "[]",
54
- l(b)
55
- );
56
- }), !1;
19
+ const l = {
20
+ transitional: u,
21
+ adapter: ["xhr", "http", "fetch"],
22
+ transformRequest: [function(r, e) {
23
+ const n = e.getContentType() || "", s = n.indexOf("application/json") > -1, f = t.isObject(r);
24
+ if (f && t.isHTMLForm(r) && (r = new FormData(r)), t.isFormData(r))
25
+ return s ? JSON.stringify(O(r)) : r;
26
+ if (t.isArrayBuffer(r) || t.isBuffer(r) || t.isStream(r) || t.isFile(r) || t.isBlob(r) || t.isReadableStream(r))
27
+ return r;
28
+ if (t.isArrayBufferView(r))
29
+ return r.buffer;
30
+ if (t.isURLSearchParams(r))
31
+ return e.setContentType("application/x-www-form-urlencoded;charset=utf-8", !1), r.toString();
32
+ let o;
33
+ if (f) {
34
+ if (n.indexOf("application/x-www-form-urlencoded") > -1)
35
+ return h(r, this.formSerializer).toString();
36
+ if ((o = t.isFileList(r)) || n.indexOf("multipart/form-data") > -1) {
37
+ const p = this.env && this.env.FormData;
38
+ return S(
39
+ o ? { "files[]": r } : r,
40
+ p && new p(),
41
+ this.formSerializer
42
+ );
43
+ }
57
44
  }
58
- return B(r) ? !0 : (e.append(O(u, n, d), l(r)), !1);
59
- }
60
- const a = [], F = Object.assign(S, {
61
- defaultVisitor: j,
62
- convertValue: l,
63
- isVisitable: B
64
- });
65
- function A(r, n) {
66
- if (!t.isUndefined(r)) {
67
- if (a.indexOf(r) !== -1)
68
- throw Error("Circular reference detected in " + n.join("."));
69
- a.push(r), t.forEach(r, function(f, c) {
70
- (!(t.isUndefined(f) || f === null) && o.call(
71
- e,
72
- f,
73
- t.isString(c) ? c.trim() : c,
74
- n,
75
- F
76
- )) === !0 && A(f, n ? n.concat(c) : [c]);
77
- }), a.pop();
45
+ return f || s ? (e.setContentType("application/json", !1), y(r)) : r;
46
+ }],
47
+ transformResponse: [function(r) {
48
+ const e = this.transitional || l.transitional, n = e && e.forcedJSONParsing, s = this.responseType === "json";
49
+ if (t.isResponse(r) || t.isReadableStream(r))
50
+ return r;
51
+ if (r && t.isString(r) && (n && !this.responseType || s)) {
52
+ const m = !(e && e.silentJSONParsing) && s;
53
+ try {
54
+ return JSON.parse(r, this.parseReviver);
55
+ } catch (o) {
56
+ if (m)
57
+ throw o.name === "SyntaxError" ? c.from(o, c.ERR_BAD_RESPONSE, this, null, this.response) : o;
58
+ }
59
+ }
60
+ return r;
61
+ }],
62
+ /**
63
+ * A timeout in milliseconds to abort a request. If set to 0 (default) a
64
+ * timeout is not created.
65
+ */
66
+ timeout: 0,
67
+ xsrfCookieName: "XSRF-TOKEN",
68
+ xsrfHeaderName: "X-XSRF-TOKEN",
69
+ maxContentLength: -1,
70
+ maxBodyLength: -1,
71
+ env: {
72
+ FormData: a.classes.FormData,
73
+ Blob: a.classes.Blob
74
+ },
75
+ validateStatus: function(r) {
76
+ return r >= 200 && r < 300;
77
+ },
78
+ headers: {
79
+ common: {
80
+ Accept: "application/json, text/plain, */*",
81
+ "Content-Type": void 0
78
82
  }
79
83
  }
80
- if (!t.isObject(i))
81
- throw new TypeError("data must be an object");
82
- return A(i), e;
83
- }
84
+ };
85
+ t.forEach(["delete", "get", "head", "post", "put", "patch"], (i) => {
86
+ l.headers[i] = {};
87
+ });
84
88
  export {
85
- W as default
89
+ l as default
86
90
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instockng/storefront-ui",
3
- "version": "1.0.108",
3
+ "version": "1.0.109",
4
4
  "description": "Pre-built UI components for OMS e-commerce sites",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -24,7 +24,7 @@
24
24
  "type-check": "tsc --noEmit",
25
25
  "build": "vite build && vite build --config vite.config.css.ts && tsc --project tsconfig.build.json || true",
26
26
  "prepublishOnly": "npm run build",
27
- "postpublish": "gh api repos/ola-wale/toyland/dispatches -f event_type=instockng-publish",
27
+ "postpublish": "sleep 15 && gh api repos/ola-wale/toyland/dispatches -f event_type=instockng-publish",
28
28
  "storybook": "storybook dev -p 6006",
29
29
  "build-storybook": "storybook build"
30
30
  },
@@ -1,7 +1,7 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import { useState, useCallback } from 'react';
3
2
  import { AssistantDrawer } from './AssistantDrawer';
4
3
  import { ProductAssistantChips } from './ProductAssistantChips';
4
+ import { AssistantProvider } from '../contexts/AssistantContext';
5
5
 
6
6
  const meta = {
7
7
  title: 'Components/AssistantDrawer',
@@ -10,7 +10,6 @@ const meta = {
10
10
  layout: 'fullscreen',
11
11
  },
12
12
  decorators: [
13
- // Override the default p-8 decorator — drawer needs full viewport
14
13
  (Story) => (
15
14
  <div style={{ position: 'relative', width: '100vw', height: '100vh', overflow: 'hidden' }}>
16
15
  <Story />
@@ -29,48 +28,28 @@ const mockFaqs = [
29
28
  { question: 'Can they be worn during workouts?', answer: 'Designed for high-intensity workouts.' },
30
29
  ];
31
30
 
32
- function ProductChipsDemo() {
33
- const [isOpen, setIsOpen] = useState(false);
34
- const [question, setQuestion] = useState('');
35
-
36
- const handleAsk = useCallback((q: string) => {
37
- setQuestion(q);
38
- setIsOpen(true);
39
- }, []);
40
-
41
- const handleClose = useCallback(() => {
42
- setIsOpen(false);
43
- }, []);
44
-
45
- return (
46
- <div className="p-8">
47
- <h3 className="text-lg font-semibold mb-4">Product Page</h3>
48
- <div className="max-w-md">
49
- <div className="aspect-[4/3] bg-gray-100 rounded-lg mb-4 flex items-center justify-center text-gray-400">
50
- Product Image
51
- </div>
52
- <ProductAssistantChips faqs={mockFaqs} onAsk={handleAsk} />
53
- </div>
54
-
55
- <AssistantDrawer
56
- isOpen={isOpen}
57
- onClose={handleClose}
58
- apiUrl="https://oms-api.instock.ng"
59
- brandSlug="demo-brand"
60
- productSlug="maternity-leggings"
61
- initialQuestion={question}
62
- assistantName="AI Assistant"
63
- disablePortal
64
- />
65
- </div>
66
- );
67
- }
68
-
69
31
  /**
70
- * Interactive demo: FAQ chips → click → drawer opens with streaming answer
32
+ * Interactive demo: FAQ chips → click → drawer opens with streaming answer.
33
+ * Uses AssistantProvider (same as production) so ProductAssistantChips can call useAssistant().
71
34
  */
72
35
  export const WithProductChips: Story = {
73
- render: () => <ProductChipsDemo />,
36
+ render: () => (
37
+ <AssistantProvider
38
+ apiUrl="https://oms-api.instock.ng"
39
+ brandSlug="demo-brand"
40
+ assistantName="AI Assistant"
41
+ >
42
+ <div className="p-8">
43
+ <h3 className="text-lg font-semibold mb-4">Product Page</h3>
44
+ <div className="max-w-md">
45
+ <div className="aspect-[4/3] bg-gray-100 rounded-lg mb-4 flex items-center justify-center text-gray-400">
46
+ Product Image
47
+ </div>
48
+ <ProductAssistantChips product={{ slug: 'maternity-leggings', faqs: mockFaqs }} />
49
+ </div>
50
+ </div>
51
+ </AssistantProvider>
52
+ ),
74
53
  args: {} as any,
75
54
  };
76
55
 
@@ -116,7 +116,7 @@ export function AssistantDrawer({
116
116
  }
117
117
  }, []);
118
118
 
119
- const sendMessageRef = useRef<(question: string) => Promise<void>>();
119
+ const sendMessageRef = useRef<(question: string) => Promise<void>>(null);
120
120
  const sendMessage = useCallback(
121
121
  async (question: string) => {
122
122
  if (!question.trim()) return;
@@ -1,5 +1,6 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite';
2
2
  import { ProductAssistantChips } from './ProductAssistantChips';
3
+ import { AssistantProvider } from '../contexts/AssistantContext';
3
4
 
4
5
  const meta = {
5
6
  title: 'Components/ProductAssistantChips',
@@ -7,6 +8,13 @@ const meta = {
7
8
  parameters: {
8
9
  layout: 'centered',
9
10
  },
11
+ decorators: [
12
+ (Story) => (
13
+ <AssistantProvider apiUrl="https://oms-api.instock.ng" brandSlug="demo-brand">
14
+ <Story />
15
+ </AssistantProvider>
16
+ ),
17
+ ],
10
18
  tags: ['autodocs'],
11
19
  } satisfies Meta<typeof ProductAssistantChips>;
12
20
 
@@ -22,21 +30,18 @@ const mockFaqs = [
22
30
 
23
31
  export const Default: Story = {
24
32
  args: {
25
- faqs: mockFaqs,
26
- onAsk: (question) => console.log('Asked:', question),
33
+ product: { slug: 'maternity-leggings', faqs: mockFaqs },
27
34
  },
28
35
  };
29
36
 
30
37
  export const FewQuestions: Story = {
31
38
  args: {
32
- faqs: mockFaqs.slice(0, 2),
33
- onAsk: (question) => console.log('Asked:', question),
39
+ product: { slug: 'maternity-leggings', faqs: mockFaqs.slice(0, 2) },
34
40
  },
35
41
  };
36
42
 
37
43
  export const NoFaqs: Story = {
38
44
  args: {
39
- faqs: [],
40
- onAsk: (question) => console.log('Asked:', question),
45
+ product: { slug: 'maternity-leggings', faqs: [] },
41
46
  },
42
47
  };
@@ -9,21 +9,26 @@
9
9
 
10
10
  import { Sparkles } from 'lucide-react';
11
11
  import { cn } from '../lib/utils';
12
+ import { useAssistant } from '../contexts/AssistantContext';
12
13
 
13
14
  export interface ProductAssistantChipsProps {
14
- /** FAQ questions to display as chips */
15
- faqs?: Array<{ question: string; answer: string }>;
16
- /** Callback when a chip is clicked — should open the drawer with this question */
17
- onAsk: (question: string) => void;
15
+ /** Product with faqs and slug */
16
+ product: {
17
+ slug: string;
18
+ faqs?: Array<{ question: string; answer: string }> | null;
19
+ };
18
20
  /** Custom class name */
19
21
  className?: string;
20
22
  }
21
23
 
22
24
  export function ProductAssistantChips({
23
- faqs = [],
24
- onAsk,
25
+ product,
25
26
  className,
26
27
  }: ProductAssistantChipsProps) {
28
+ const { ask } = useAssistant();
29
+ const faqs = product.faqs || [];
30
+ const productSlug = product.slug;
31
+
27
32
  if (faqs.length === 0) return null;
28
33
 
29
34
  return (
@@ -37,7 +42,7 @@ export function ProductAssistantChips({
37
42
  <button
38
43
  key={i}
39
44
  type="button"
40
- onClick={() => onAsk(faq.question)}
45
+ onClick={() => ask(faq.question, productSlug)}
41
46
  className={cn(
42
47
  'rounded-full border border-gray-200 bg-blue-50/60 px-3 py-1.5 text-sm text-gray-700',
43
48
  'hover:bg-blue-100 hover:border-blue-200 transition-colors',
@@ -49,7 +54,7 @@ export function ProductAssistantChips({
49
54
  ))}
50
55
  <button
51
56
  type="button"
52
- onClick={() => onAsk('')}
57
+ onClick={() => ask('', productSlug)}
53
58
  className={cn(
54
59
  'rounded-full border border-gray-300 bg-gray-800 px-3 py-1.5 text-sm text-white font-medium',
55
60
  'hover:bg-gray-700 transition-colors',