@anker-in/campaign-ui 0.0.33-alpha4 → 0.0.33-alpha6

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 (35) hide show
  1. package/dist/cjs/components/chat/action.d.ts +4 -2
  2. package/dist/cjs/components/chat/action.js +1 -1
  3. package/dist/cjs/components/chat/action.js.map +3 -3
  4. package/dist/cjs/components/chat/button.d.ts +1 -1
  5. package/dist/cjs/components/chat/button.js +1 -1
  6. package/dist/cjs/components/chat/button.js.map +3 -3
  7. package/dist/cjs/components/chat/index.d.ts +13 -7
  8. package/dist/cjs/components/chat/index.js +1 -1
  9. package/dist/cjs/components/chat/index.js.map +3 -3
  10. package/dist/cjs/components/chat/props.d.ts +1 -2
  11. package/dist/cjs/components/chat/props.js +1 -1
  12. package/dist/cjs/components/chat/props.js.map +1 -1
  13. package/dist/cjs/stories/chat.stories.js +1 -1
  14. package/dist/cjs/stories/chat.stories.js.map +2 -2
  15. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  16. package/dist/esm/components/chat/action.d.ts +4 -2
  17. package/dist/esm/components/chat/action.js +1 -1
  18. package/dist/esm/components/chat/action.js.map +3 -3
  19. package/dist/esm/components/chat/button.d.ts +1 -1
  20. package/dist/esm/components/chat/button.js +1 -1
  21. package/dist/esm/components/chat/button.js.map +3 -3
  22. package/dist/esm/components/chat/index.d.ts +13 -7
  23. package/dist/esm/components/chat/index.js +1 -1
  24. package/dist/esm/components/chat/index.js.map +3 -3
  25. package/dist/esm/components/chat/props.d.ts +1 -2
  26. package/dist/esm/components/chat/props.js.map +1 -1
  27. package/dist/esm/stories/chat.stories.js +1 -1
  28. package/dist/esm/stories/chat.stories.js.map +2 -2
  29. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  30. package/package.json +1 -1
  31. package/src/components/chat/action.tsx +19 -7
  32. package/src/components/chat/button.tsx +2 -9
  33. package/src/components/chat/index.tsx +49 -38
  34. package/src/components/chat/props.ts +1 -2
  35. package/src/stories/chat.stories.tsx +5 -5
@@ -14,17 +14,20 @@ interface Message {
14
14
  export interface ActionProps {
15
15
  start?: string
16
16
  history: Message[]
17
+ addtocartHandler?: (_args: any) => Promise<any>
17
18
  gotocheckoutRender?: string | ((_props: any) => React.ReactElement)
18
19
  gotocartRender?: string | ((_props: any) => React.ReactElement)
19
20
  addtocartRender?: string | ((_props: any) => React.ReactElement)
20
- productRender?: string | ((_props: any) => React.ReactElement)
21
21
  signupRender?: string | ((_props: any) => React.ReactElement)
22
+ productRender?: string | ((_props: any) => React.ReactElement)
23
+ productRenderTipMessage?: string
22
24
  children?: React.ReactNode
23
25
  }
24
26
 
25
27
  export const CopilotAction = ({
26
28
  start,
27
29
  history,
30
+ addtocartHandler,
28
31
  gotocheckoutRender,
29
32
  gotocartRender,
30
33
  addtocartRender,
@@ -32,16 +35,17 @@ export const CopilotAction = ({
32
35
  signupRender,
33
36
  children,
34
37
  }: ActionProps) => {
35
- const { setMessages } = useCopilotChat()
38
+ const { setMessages, appendMessage, isLoading } = useCopilotChat()
36
39
 
37
40
  useEffect(() => {
38
41
  const originhistory = history?.filter(value => value?.content || value?.arguments)
39
42
  if (originhistory?.length > 0) {
40
43
  const content = originhistory?.map(value => {
41
44
  if (value?.name && value?.arguments) {
45
+ const args = value?.arguments?.map((item: any) => (item ? { ...item, ishistory: true } : {}))
42
46
  return new ActionExecutionMessage({
43
47
  name: value?.name,
44
- arguments: value?.arguments,
48
+ arguments: args,
45
49
  scope: value?.scope,
46
50
  })
47
51
  }
@@ -79,8 +83,8 @@ export const CopilotAction = ({
79
83
  description: 'add to cart',
80
84
  parameters: [{ sku: '', handle: '' }] as any,
81
85
  render: addtocartRender || (props => <div className="hidden">{JSON.stringify(props)}</div>),
82
- handler: function () {
83
- // console.log('buynow-props', props)
86
+ handler: function (props) {
87
+ addtocartHandler && addtocartHandler(props)
84
88
  },
85
89
  })
86
90
 
@@ -89,8 +93,16 @@ export const CopilotAction = ({
89
93
  description: 'product card',
90
94
  parameters: [{ sku: '', handle: '' }] as any,
91
95
  render: productRender || (props => <div className="hidden">{JSON.stringify(props)}</div>),
92
- handler: function () {
93
- // console.log('buynow-props', props)
96
+ handler: function (props) {
97
+ console.log('show_product_card-props', props)
98
+ // const ishistory = props?.find((item: { ishistory: any }) => item?.ishistory)
99
+ // if (!ishistory) {
100
+ // const content = new TextMessage({
101
+ // content: 'show product card',
102
+ // role: Role.Assistant,
103
+ // })
104
+ // appendMessage(content)
105
+ // }
94
106
  },
95
107
  })
96
108
 
@@ -2,18 +2,11 @@ import { useChatContext } from '@copilotkit/react-ui'
2
2
 
3
3
  import type { ButtonProps } from './props.js'
4
4
 
5
- const DefaultButton = ({ setOpen, setOpenTip }: ButtonProps) => {
5
+ const DefaultButton = ({ setOpen }: ButtonProps) => {
6
6
  const context = useChatContext()
7
7
 
8
8
  return (
9
- <button
10
- onClick={() => {
11
- setOpen(true)
12
- setOpenTip(false)
13
- }}
14
- className="copilotKitButton "
15
- aria-label="Open Chat"
16
- >
9
+ <button onClick={() => setOpen()} className="copilotKitButton " aria-label="Open Chat">
17
10
  <div className="copilotKitButtonIcon copilotKitButtonIconOpen">{context.icons.openIcon}</div>
18
11
  <div className="copilotKitButtonIcon copilotKitButtonIconClose">{context.icons.closeIcon}</div>
19
12
  </button>
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable react-hooks/exhaustive-deps */
2
- import React from 'react'
2
+ import React, { useMemo } from 'react'
3
3
  import { useCallback, useState, useEffect } from 'react'
4
4
  import { CopilotKit } from '@copilotkit/react-core'
5
5
  import { CopilotPopup } from '@copilotkit/react-ui'
@@ -13,16 +13,19 @@ import fetcher from '../../helpers/fetcher.js'
13
13
  export interface ChatProps {
14
14
  title: string
15
15
  runtimeUrl: string
16
- shopify_domain: string
16
+ shopifyDomain: string
17
17
  /** GA 的 client id
18
18
  */
19
- user_id: string
19
+ userId: string
20
20
  /** 是否登陆用户 0 or 1
21
21
  */
22
22
  account?: string
23
23
  /** 用户浏览器语言
24
24
  */
25
25
  locale?: string
26
+ /** 开场白
27
+ */
28
+ prologue?: string
26
29
  /** ?a=1&b=2
27
30
  */
28
31
  query?: string
@@ -39,21 +42,24 @@ export interface ChatProps {
39
42
  * 后端接口文档:https://anker-in.feishu.cn/wiki/DOYJwE9oxipWmYk072ncnJNznBb
40
43
  */
41
44
  gotocartRender?: string | ((_props: any) => React.ReactElement)
45
+ /** 打开购物车 action 的触发事件
46
+ */
47
+ addtocartHandler?: (_args: any) => Promise<any>
42
48
  /** 加购卡片,接受参数: {"status":"complete","args":[{"sku":["A3936031"],"handle":"space-a40-a3936031"}],"result":""}
43
49
  * 后端接口文档:https://anker-in.feishu.cn/wiki/DOYJwE9oxipWmYk072ncnJNznBb
44
50
  */
45
51
  addtocartRender?: string | ((_props: any) => React.ReactElement)
46
- /** 产品卡片,接受参数: {"status":"complete","args":[{"sku":["A3936031"],"handle":"space-a40-a3936031"}],"result":""}
47
- * 后端接口文档:https://anker-in.feishu.cn/wiki/DOYJwE9oxipWmYk072ncnJNznBb
48
- */
49
- productRender?: string | ((_props: any) => React.ReactElement)
50
52
  /** 订阅卡片,接受参数: {"status":"complete","args":[{"sku":["A3936031"],"handle":"space-a40-a3936031"}],"result":""}
51
53
  * 后端接口文档:https://anker-in.feishu.cn/wiki/DOYJwE9oxipWmYk072ncnJNznBb
52
54
  */
53
55
  signupRender?: string | ((_props: any) => React.ReactElement)
56
+ /** 产品卡片,接受参数: {"status":"complete","args":[{"sku":["A3936031"],"handle":"space-a40-a3936031"}],"result":""}
57
+ * 后端接口文档:https://anker-in.feishu.cn/wiki/DOYJwE9oxipWmYk072ncnJNznBb
58
+ */
59
+ productRender?: string | ((_props: any) => React.ReactElement)
54
60
  /** CopilotPopup 自定义参数,参考:https://docs.copilotkit.ai/reference/components/CopilotPopup */
55
61
  popup?: any
56
- /** 文案,{"popupTip": "Hi ! Welcome to soundcore Innovations live chat!", "popupTipTimeout": [3000, 6000]} */
62
+ /** 文案,{"productRenderTipMessage": "","popupTip": "Hi ! Welcome to soundcore Innovations live chat!", "popupTipTimeout": [3000, 6000]} */
57
63
  lang?: any
58
64
  /** 参考此文档:https://docs.copilotkit.ai/concepts/customize-look-and-feel */
59
65
  style?: any
@@ -65,9 +71,10 @@ const Chat = (props: ChatProps) => {
65
71
  title,
66
72
  runtimeUrl,
67
73
  popup,
68
- shopify_domain,
69
- user_id = '',
74
+ shopifyDomain,
75
+ userId = '',
70
76
  account = '',
77
+ prologue = '',
71
78
  locale = '',
72
79
  query = '',
73
80
  showResponseButton,
@@ -76,6 +83,7 @@ const Chat = (props: ChatProps) => {
76
83
  addtocartRender,
77
84
  productRender,
78
85
  signupRender,
86
+ addtocartHandler,
79
87
  style,
80
88
  className = '',
81
89
  lang,
@@ -84,33 +92,43 @@ const Chat = (props: ChatProps) => {
84
92
 
85
93
  const [openTip, setOpenTip] = useState(false)
86
94
  const [openPopup, setOpenPopup] = useState(false)
87
- const [start, setstart] = useState('')
95
+ const [start, setstart] = useState(prologue)
88
96
  const [currentSuggestions, setCurrentSuggestions] = useState([])
89
97
  const [history, sethistory] = useState<[{ content: string; role: string }] | []>([])
90
98
 
99
+ const headers = useMemo(
100
+ () => ({
101
+ 'x-user-id': userId || '',
102
+ 'x-shopify-domain': shopifyDomain,
103
+ 'x-member-ship': account,
104
+ 'x-user-locale': locale,
105
+ }),
106
+ [userId, shopifyDomain, account, locale]
107
+ )
108
+
91
109
  const getStart = useCallback(async () => {
92
110
  const result = await fetcher({
93
111
  url: `${runtimeUrl}/copilotkit/start${query}`,
94
112
  method: 'GET',
95
- headers: { user_id: user_id || '', shopify_domain, account, locale },
113
+ headers,
96
114
  })
97
115
 
98
116
  setCurrentSuggestions(result?.suggested_questions?.map((item: string) => ({ message: item, title: item })) || [])
99
117
  setstart(result?.opening_statement || '')
100
118
  sethistory(result?.history || [])
101
- }, [user_id, shopify_domain, account, locale])
119
+ }, [userId, shopifyDomain, account, locale])
102
120
 
103
121
  const getSuggestions = useCallback(async () => {
104
122
  const result = await fetcher({
105
123
  url: `${runtimeUrl}/copilotkit/suggested_questions${query}`,
106
124
  method: 'GET',
107
- headers: { user_id: user_id || '', shopify_domain, account, locale },
125
+ headers,
108
126
  })
109
127
 
110
128
  setCurrentSuggestions(
111
129
  result?.suggested_questions?.data?.map((item: string) => ({ message: item, title: item })) || []
112
130
  )
113
- }, [user_id, shopify_domain, account, locale])
131
+ }, [userId, shopifyDomain, account, locale])
114
132
 
115
133
  const setOpenTipFn = () => {
116
134
  if (!openTip) setOpenTip(true)
@@ -129,20 +147,10 @@ const Chat = (props: ChatProps) => {
129
147
  }
130
148
  }, [])
131
149
 
132
- useEffect(() => {
133
- if (!start) {
134
- getStart()
135
- }
136
- }, [])
137
-
138
150
  return (
139
151
  <div className={className} style={style || {}}>
140
- {user_id && runtimeUrl && (
141
- <CopilotKit
142
- runtimeUrl={`${runtimeUrl}/copilotkit/chat${query}`}
143
- showDevConsole={false}
144
- headers={{ user_id: user_id || '', shopify_domain: shopify_domain, account, locale }}
145
- >
152
+ {userId && runtimeUrl && (
153
+ <CopilotKit runtimeUrl={`${runtimeUrl}/copilotkit/chat${query}`} showDevConsole={false} headers={headers}>
146
154
  <CopilotPopup
147
155
  {...popup}
148
156
  showResponseButton={showResponseButton !== 'follow'}
@@ -164,29 +172,30 @@ const Chat = (props: ChatProps) => {
164
172
  <Suggestions currentSuggestions={currentSuggestions} />
165
173
  </Messages>
166
174
  )}
167
- Button={({ open, setOpen }) => {
175
+ Button={({ open, setOpen: setOpenDefault }) => {
168
176
  const Button = popup?.Button || DefaultButton
169
177
  // eslint-disable-next-line react-hooks/rules-of-hooks
170
178
  useEffect(() => {
171
179
  setOpenPopup(open)
172
180
  }, [open])
181
+
182
+ // eslint-disable-next-line react-hooks/rules-of-hooks
183
+ const setOpen = useCallback(() => {
184
+ setOpenDefault(!open)
185
+ setOpenTip(false)
186
+ if (!start || !history?.length) getStart()
187
+ }, [start])
188
+
173
189
  return (
174
190
  <>
175
191
  {lang?.popupTip && openTip && !openPopup && (
176
192
  <div className="copilotKitPopup copilotKitPopupTip">
177
- <button
178
- onClick={() => {
179
- setOpen(true)
180
- setOpenTip(false)
181
- }}
182
- aria-label="Open Chat"
183
- className="copilotKitPopupTipContent"
184
- >
193
+ <button onClick={setOpen} aria-label="Open Chat" className="copilotKitPopupTipContent">
185
194
  {lang?.popupTip}
186
195
  </button>
187
196
  </div>
188
197
  )}
189
- <Button open={open} setOpen={setOpen} setOpenTip={setOpenTip} />
198
+ <Button open={open} setOpen={setOpen} />
190
199
  </>
191
200
  )
192
201
  }}
@@ -197,8 +206,10 @@ const Chat = (props: ChatProps) => {
197
206
  gotocartRender={gotocartRender}
198
207
  gotocheckoutRender={gotocheckoutRender}
199
208
  addtocartRender={addtocartRender}
200
- productRender={productRender}
201
209
  signupRender={signupRender}
210
+ productRender={productRender}
211
+ addtocartHandler={addtocartHandler}
212
+ productRenderTipMessage={lang?.productRenderTipMessage}
202
213
  />
203
214
  </CopilotPopup>
204
215
  </CopilotKit>
@@ -3,8 +3,7 @@ import { Message } from '@copilotkit/runtime-client-gql'
3
3
 
4
4
  export interface ButtonProps {
5
5
  open: boolean
6
- setOpen: (open: boolean) => void
7
- setOpenTip: (open: boolean) => void
6
+ setOpen: () => void
8
7
  }
9
8
 
10
9
  export interface WindowProps {
@@ -12,8 +12,8 @@ const meta: Meta<typeof Chat> = {
12
12
  component: Chat,
13
13
  args: {
14
14
  title: 'DTC Live Chat',
15
- runtimeUrl: 'https://beta-dtcapi.anker.com',
16
- shopify_domain: 'soundcoreusa.myshopify.com',
15
+ runtimeUrl: 'https://beta-api-livechat.anker.com',
16
+ shopifyDomain: 'soundcoreusa.myshopify.com',
17
17
  },
18
18
  // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
19
19
  tags: ['autodocs'],
@@ -32,9 +32,9 @@ export default meta
32
32
  export const Default: Story = {
33
33
  args: {
34
34
  title: 'DTC Live Chat',
35
- runtimeUrl: 'https://beta-dtcapi.anker.com',
36
- shopify_domain: 'soundcoreusa.myshopify.com',
37
- user_id: 'arno6',
35
+ runtimeUrl: 'https://beta-api-livechat.anker.com',
36
+ shopifyDomain: 'soundcoreusa.myshopify.com',
37
+ userId: 'arno7',
38
38
  showResponseButton: 'follow',
39
39
  lang: { popupTip: 'Hi ! Welcome to soundcore Innovations live chat!', popupTipTimeout: [3000, 6000] },
40
40
  },