app-tutor-ai-consumer 1.53.0 → 1.55.0
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/CHANGELOG.md +16 -0
- package/package.json +1 -1
- package/src/config/datahub/actions.ts +2 -1
- package/src/config/datahub/schemas/agent/tryCreateThreadSchema.ts +60 -0
- package/src/config/datahub/schemas/base-try-schema.ts +4 -1
- package/src/main/hooks/use-initial-store/use-initial-store.tsx +8 -1
- package/src/modules/messages/hooks/use-send-first-message/use-send-first-message.spec.tsx +68 -19
- package/src/modules/messages/hooks/use-send-first-message/use-send-first-message.tsx +38 -4
- package/src/modules/widget/components/greetings-card/greetings-card.tsx +11 -10
- package/src/modules/widget/components/greetings-card/types.ts +7 -0
- package/src/modules/widget/components/greetings-card/utils.ts +25 -0
- package/src/modules/widget/store/widget-settings-config.atom.ts +5 -0
- package/src/types.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
# [1.55.0](https://github.com/Hotmart-Org/app-tutor-ai-consumer/compare/v1.54.0...v1.55.0) (2026-01-30)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
- add concierge labels ([f845eb5](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/f845eb5a3016d582ae9687f569764b14bca00d15))
|
|
6
|
+
|
|
7
|
+
# [1.54.0](https://github.com/Hotmart-Org/app-tutor-ai-consumer/compare/v1.53.0...v1.54.0) (2026-01-28)
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
- code review issues ([6d0a17a](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/6d0a17a8874001b7d30d889152a432fbf5046467))
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
- add create thread datahub event ([3f8fa1e](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/3f8fa1e5e98f9bef7201a7835a56252943a35122))
|
|
16
|
+
|
|
1
17
|
# [1.53.0](https://github.com/Hotmart-Org/app-tutor-ai-consumer/compare/v1.52.1...v1.53.0) (2026-01-27)
|
|
2
18
|
|
|
3
19
|
### Features
|
package/package.json
CHANGED
|
@@ -23,5 +23,6 @@ export const ActionNames = {
|
|
|
23
23
|
CLOSE_TUTOR_ONBOARDING: `${DataHubActions.CLOSE}_tutor_onboarding`,
|
|
24
24
|
VIEW_PRODUCT_TUTOR: `${DataHubActions.VIEW}_product_tutor`,
|
|
25
25
|
VIEW_ANSWER_MESSAGE: `${DataHubActions.VIEW}_answer_message`,
|
|
26
|
-
VIEW_CHAT: `${DataHubActions.VIEW}_chat
|
|
26
|
+
VIEW_CHAT: `${DataHubActions.VIEW}_chat`,
|
|
27
|
+
TRY_CREATE_THREAD: `${DataHubActions.TRY}_create_thread`
|
|
27
28
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import HttpCodes from '@/src/lib/utils/http-codes'
|
|
2
|
+
import { ActionNames } from '../../actions'
|
|
3
|
+
import { DataHubEntities } from '../../entities'
|
|
4
|
+
import type { ActionNamesType, DataHubEntityTypes } from '../../types'
|
|
5
|
+
import BaseTrySchema from '../base-try-schema'
|
|
6
|
+
import { ProductCategories } from '../constants'
|
|
7
|
+
|
|
8
|
+
type Result = 'SUCCESSFUL' | 'FAILURE'
|
|
9
|
+
|
|
10
|
+
type ConstructorParams = {
|
|
11
|
+
title: string
|
|
12
|
+
componentName: string
|
|
13
|
+
conversationId: string
|
|
14
|
+
entity?: DataHubEntityTypes
|
|
15
|
+
result?: Result
|
|
16
|
+
statusCode?: number
|
|
17
|
+
failureDescription?: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class TryCreateThreadSchema extends BaseTrySchema {
|
|
21
|
+
action: ActionNamesType
|
|
22
|
+
|
|
23
|
+
private agent: 'HOTMART_TUTOR' | 'PRODUCT_AGENT'
|
|
24
|
+
private conversationId: string
|
|
25
|
+
private title: string
|
|
26
|
+
|
|
27
|
+
constructor({
|
|
28
|
+
title,
|
|
29
|
+
componentName,
|
|
30
|
+
conversationId,
|
|
31
|
+
entity = DataHubEntities.CONVERSATIONAL_AGENT,
|
|
32
|
+
result = 'SUCCESSFUL',
|
|
33
|
+
statusCode = HttpCodes.OK,
|
|
34
|
+
failureDescription = 'NOT_FAILURE_RESULT_EVENT'
|
|
35
|
+
}: ConstructorParams) {
|
|
36
|
+
super({
|
|
37
|
+
result,
|
|
38
|
+
componentName,
|
|
39
|
+
statusCode,
|
|
40
|
+
failureDescription,
|
|
41
|
+
componentSource: 'CONTENT_LESSON',
|
|
42
|
+
productType: ProductCategories.ConversationalAgent
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
this.entity = entity
|
|
46
|
+
this.action = ActionNames.TRY_CREATE_THREAD
|
|
47
|
+
this.agent = 'PRODUCT_AGENT'
|
|
48
|
+
this.conversationId = conversationId
|
|
49
|
+
this.title = title
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
getDataHubEventData(): Record<string, unknown> {
|
|
53
|
+
return {
|
|
54
|
+
...super.prepare(),
|
|
55
|
+
agent: this.agent,
|
|
56
|
+
conversationId: this.conversationId,
|
|
57
|
+
title: this.title
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -4,6 +4,7 @@ import { DataHubEntities } from '../entities'
|
|
|
4
4
|
import type { DataHubEntityTypes, ResultType, ScreenNamesType } from '../types'
|
|
5
5
|
|
|
6
6
|
import BaseProductSchema from './base-product-schema'
|
|
7
|
+
import type { ProductCategoriesType } from './types'
|
|
7
8
|
|
|
8
9
|
export type BaseTrySchemaConstructorArgs = {
|
|
9
10
|
componentName: string
|
|
@@ -14,6 +15,7 @@ export type BaseTrySchemaConstructorArgs = {
|
|
|
14
15
|
statusCode?: number
|
|
15
16
|
failureDescription?: string
|
|
16
17
|
screenName?: ScreenNamesType
|
|
18
|
+
productType?: ProductCategoriesType
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
abstract class BaseTrySchema extends BaseProductSchema {
|
|
@@ -31,6 +33,7 @@ abstract class BaseTrySchema extends BaseProductSchema {
|
|
|
31
33
|
const {
|
|
32
34
|
componentName,
|
|
33
35
|
componentSource,
|
|
36
|
+
productType,
|
|
34
37
|
entity = DataHubEntities.HOME,
|
|
35
38
|
failureDescription = Result.FAILURE_DESCRIPTION,
|
|
36
39
|
isLogged = true,
|
|
@@ -39,7 +42,7 @@ abstract class BaseTrySchema extends BaseProductSchema {
|
|
|
39
42
|
screenName = ScreenNames.HOME_CONSUMER
|
|
40
43
|
} = args
|
|
41
44
|
|
|
42
|
-
super()
|
|
45
|
+
super({ productType })
|
|
43
46
|
|
|
44
47
|
this.componentName = componentName
|
|
45
48
|
this.componentSource = componentSource
|
|
@@ -11,6 +11,7 @@ import type { WidgetTabsProps } from '@/src/modules/widget'
|
|
|
11
11
|
import {
|
|
12
12
|
widgetSettingsAtom,
|
|
13
13
|
widgetSettingsConfigAgentParentAtom,
|
|
14
|
+
widgetSettingsConfigConciergeParentAtom,
|
|
14
15
|
widgetTabsAtom
|
|
15
16
|
} from '@/src/modules/widget'
|
|
16
17
|
import type { WidgetSettingProps } from '@/src/types'
|
|
@@ -50,12 +51,18 @@ const useInitialStore = ({ settings }: UseInitialStoreProps) => {
|
|
|
50
51
|
[settings?.config?.metadata?.parent]
|
|
51
52
|
)
|
|
52
53
|
|
|
54
|
+
const isConciergeMode = useMemo(
|
|
55
|
+
() => settings?.config?.metadata?.parent === 'CONCIERGE',
|
|
56
|
+
[settings?.config?.metadata?.parent]
|
|
57
|
+
)
|
|
58
|
+
|
|
53
59
|
useHydrateAtoms(
|
|
54
60
|
[
|
|
55
61
|
[widgetSettingsAtom, getDefaultSettings(settings)],
|
|
56
62
|
[messagesMaxCountAtom, MSG_MAX_COUNT],
|
|
57
63
|
[widgetTabsAtom, initialTab],
|
|
58
|
-
[widgetSettingsConfigAgentParentAtom, isAgentMode]
|
|
64
|
+
[widgetSettingsConfigAgentParentAtom, isAgentMode],
|
|
65
|
+
[widgetSettingsConfigConciergeParentAtom, isConciergeMode]
|
|
59
66
|
],
|
|
60
67
|
{ store }
|
|
61
68
|
)
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { DataHubService } from '@/src/config/datahub'
|
|
2
|
+
import { TryCreateThreadSchema } from '@/src/config/datahub/schemas/agent/tryCreateThreadSchema'
|
|
1
3
|
import { renderHook } from '@/src/config/tests'
|
|
4
|
+
import HttpCodes from '@/src/lib/utils/http-codes'
|
|
2
5
|
import { useUpdateConversationTitle } from '@/src/modules/conversation/hooks/update-conversation-title'
|
|
3
|
-
import { useWidgetSettingsAtomValue } from '@/src/modules/widget/store'
|
|
6
|
+
import { useIsAgentParentAtomValue, useWidgetSettingsAtomValue } from '@/src/modules/widget/store'
|
|
4
7
|
import { useMessagesCountAtomValue } from '../../store/messages-count.atom'
|
|
5
8
|
import { useSendTextMessage } from '../use-send-text-message'
|
|
6
9
|
|
|
@@ -11,7 +14,8 @@ vi.mock('@/src/modules/conversation/hooks/update-conversation-title', () => ({
|
|
|
11
14
|
}))
|
|
12
15
|
|
|
13
16
|
vi.mock('@/src/modules/widget/store', () => ({
|
|
14
|
-
useWidgetSettingsAtomValue: vi.fn()
|
|
17
|
+
useWidgetSettingsAtomValue: vi.fn(),
|
|
18
|
+
useIsAgentParentAtomValue: vi.fn()
|
|
15
19
|
}))
|
|
16
20
|
|
|
17
21
|
vi.mock('../../store/messages-count.atom', () => ({
|
|
@@ -25,6 +29,19 @@ vi.mock('../use-send-text-message', () => ({
|
|
|
25
29
|
describe('useSendFirstMessage', () => {
|
|
26
30
|
const mockSendMessage = vi.fn()
|
|
27
31
|
const mockUpdateTitle = vi.fn()
|
|
32
|
+
const mockMessage = { id: 'msg-1', content: 'Hello' }
|
|
33
|
+
const mockSettings = {
|
|
34
|
+
conversationId: 'conv-123',
|
|
35
|
+
productId: 'prod-456',
|
|
36
|
+
config: {
|
|
37
|
+
metadata: {
|
|
38
|
+
agentProductId: 'agent-prod-42',
|
|
39
|
+
agentName: 'Agent Name',
|
|
40
|
+
courseName: 'Course Name',
|
|
41
|
+
source: 'Source'
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
28
45
|
|
|
29
46
|
beforeEach(() => {
|
|
30
47
|
vi.clearAllMocks()
|
|
@@ -47,35 +64,55 @@ describe('useSendFirstMessage', () => {
|
|
|
47
64
|
} as never)
|
|
48
65
|
|
|
49
66
|
vi.mocked(useMessagesCountAtomValue).mockReturnValue(0)
|
|
67
|
+
|
|
68
|
+
vi.mocked(useIsAgentParentAtomValue).mockReturnValue(true)
|
|
50
69
|
})
|
|
51
70
|
|
|
52
71
|
describe('when sending first message', () => {
|
|
53
|
-
it('should
|
|
54
|
-
vi.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
config: {
|
|
58
|
-
metadata: {
|
|
59
|
-
agentProductId: 'agent-prod-42',
|
|
60
|
-
agentName: 'Agent Name',
|
|
61
|
-
courseName: 'Course Name',
|
|
62
|
-
source: 'Source'
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
} as never)
|
|
66
|
-
const mockMessage = { id: 'msg-1', content: 'Hello' }
|
|
72
|
+
it('should not dispatch create thread event when in Tutor Mode', async () => {
|
|
73
|
+
vi.spyOn(DataHubService, 'sendEvent').mockImplementationOnce(() => null)
|
|
74
|
+
vi.mocked(useIsAgentParentAtomValue).mockReturnValue(false)
|
|
75
|
+
vi.mocked(useWidgetSettingsAtomValue).mockReturnValue(mockSettings as never)
|
|
67
76
|
mockSendMessage.mockResolvedValue(mockMessage)
|
|
68
77
|
mockUpdateTitle.mockResolvedValue({})
|
|
69
78
|
|
|
79
|
+
const expectedResult = {
|
|
80
|
+
conversationId: 'conv-123',
|
|
81
|
+
productId: 'agent-prod-42',
|
|
82
|
+
subject: 'Hello world'
|
|
83
|
+
}
|
|
84
|
+
|
|
70
85
|
const { result } = renderHook(() => useSendFirstMessage())
|
|
71
86
|
|
|
72
|
-
await result.current.sendFirstMessage(
|
|
87
|
+
await result.current.sendFirstMessage(expectedResult.subject)
|
|
73
88
|
|
|
74
|
-
expect(
|
|
75
|
-
|
|
89
|
+
expect(DataHubService.sendEvent).not.toHaveBeenCalled()
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it('should send message and update conversation title', async () => {
|
|
93
|
+
vi.spyOn(DataHubService, 'sendEvent').mockImplementation(() => null)
|
|
94
|
+
vi.mocked(useWidgetSettingsAtomValue).mockReturnValue(mockSettings as never)
|
|
95
|
+
mockSendMessage.mockResolvedValue(mockMessage)
|
|
96
|
+
mockUpdateTitle.mockResolvedValue({})
|
|
97
|
+
|
|
98
|
+
const expectedResult = {
|
|
76
99
|
conversationId: 'conv-123',
|
|
77
100
|
productId: 'agent-prod-42',
|
|
78
101
|
subject: 'Hello world'
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const { result } = renderHook(() => useSendFirstMessage())
|
|
105
|
+
|
|
106
|
+
await result.current.sendFirstMessage(expectedResult.subject)
|
|
107
|
+
|
|
108
|
+
expect(mockSendMessage).toHaveBeenCalledWith(expectedResult.subject, undefined)
|
|
109
|
+
expect(mockUpdateTitle).toHaveBeenCalledWith(expectedResult)
|
|
110
|
+
expect(DataHubService.sendEvent).toHaveBeenCalledExactlyOnceWith({
|
|
111
|
+
schema: new TryCreateThreadSchema({
|
|
112
|
+
title: expectedResult.subject,
|
|
113
|
+
componentName: 'AGENT_CREATE_THREAD',
|
|
114
|
+
conversationId: expectedResult.conversationId
|
|
115
|
+
})
|
|
79
116
|
})
|
|
80
117
|
})
|
|
81
118
|
})
|
|
@@ -112,6 +149,7 @@ describe('useSendFirstMessage', () => {
|
|
|
112
149
|
|
|
113
150
|
describe('error handling', () => {
|
|
114
151
|
it('should throw error when send message fails', async () => {
|
|
152
|
+
vi.mocked(useWidgetSettingsAtomValue).mockReturnValue(mockSettings as never)
|
|
115
153
|
vi.spyOn(console, 'error').mockImplementationOnce(() => {})
|
|
116
154
|
const error = new Error('Send failed')
|
|
117
155
|
mockSendMessage.mockRejectedValue(error)
|
|
@@ -119,6 +157,17 @@ describe('useSendFirstMessage', () => {
|
|
|
119
157
|
const { result } = renderHook(() => useSendFirstMessage())
|
|
120
158
|
|
|
121
159
|
await expect(result.current.sendFirstMessage('Hello')).rejects.toThrow('Send failed')
|
|
160
|
+
|
|
161
|
+
expect(DataHubService.sendEvent).toHaveBeenCalledExactlyOnceWith({
|
|
162
|
+
schema: new TryCreateThreadSchema({
|
|
163
|
+
title: mockMessage.content,
|
|
164
|
+
componentName: 'AGENT_CREATE_THREAD',
|
|
165
|
+
conversationId: mockSettings.conversationId,
|
|
166
|
+
result: 'FAILURE',
|
|
167
|
+
statusCode: HttpCodes.BAD_REQUEST,
|
|
168
|
+
failureDescription: 'Send failed'
|
|
169
|
+
})
|
|
170
|
+
})
|
|
122
171
|
})
|
|
123
172
|
})
|
|
124
173
|
|
|
@@ -2,8 +2,11 @@ import { useCallback } from 'react'
|
|
|
2
2
|
import type { Message } from '@hotmart-org-ca/sparkie/dist/MessageService'
|
|
3
3
|
import type { MutateOptions } from '@tanstack/react-query'
|
|
4
4
|
|
|
5
|
+
import { DataHubService } from '@/src/config/datahub'
|
|
6
|
+
import { TryCreateThreadSchema } from '@/src/config/datahub/schemas/agent/tryCreateThreadSchema'
|
|
7
|
+
import HttpCodes from '@/src/lib/utils/http-codes'
|
|
5
8
|
import { useUpdateConversationTitle } from '@/src/modules/conversation/hooks/update-conversation-title'
|
|
6
|
-
import { useWidgetSettingsAtomValue } from '@/src/modules/widget/store'
|
|
9
|
+
import { useIsAgentParentAtomValue, useWidgetSettingsAtomValue } from '@/src/modules/widget/store'
|
|
7
10
|
import { useMessagesCountAtomValue } from '../../store/messages-count.atom'
|
|
8
11
|
import { excerptMessage } from '../../utils'
|
|
9
12
|
import { useSendTextMessage } from '../use-send-text-message'
|
|
@@ -13,10 +16,12 @@ function useSendFirstMessage() {
|
|
|
13
16
|
const sendMessageMutation = useSendTextMessage()
|
|
14
17
|
const updateTitleMutation = useUpdateConversationTitle()
|
|
15
18
|
const settings = useWidgetSettingsAtomValue()
|
|
19
|
+
const isAgent = useIsAgentParentAtomValue()
|
|
16
20
|
|
|
17
21
|
const sendFirstMessage = useCallback(
|
|
18
22
|
async (message: string, options?: MutateOptions<Message, Error, string, void>) => {
|
|
19
23
|
const isFirstMessage = messagesCount === 0
|
|
24
|
+
const subject = excerptMessage({ message })
|
|
20
25
|
|
|
21
26
|
try {
|
|
22
27
|
const messageResult = await sendMessageMutation.mutateAsync(message, options)
|
|
@@ -29,17 +34,46 @@ function useSendFirstMessage() {
|
|
|
29
34
|
await updateTitleMutation.mutateAsync({
|
|
30
35
|
conversationId: settings.conversationId,
|
|
31
36
|
productId: settings?.config?.metadata?.agentProductId,
|
|
32
|
-
subject
|
|
37
|
+
subject
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (isAgent) {
|
|
42
|
+
DataHubService.sendEvent({
|
|
43
|
+
schema: new TryCreateThreadSchema({
|
|
44
|
+
title: subject,
|
|
45
|
+
componentName: 'AGENT_CREATE_THREAD',
|
|
46
|
+
conversationId: settings?.conversationId || ''
|
|
47
|
+
})
|
|
33
48
|
})
|
|
34
49
|
}
|
|
35
50
|
|
|
36
51
|
return messageResult
|
|
37
52
|
} catch (error) {
|
|
38
|
-
|
|
53
|
+
if (isAgent) {
|
|
54
|
+
DataHubService.sendEvent({
|
|
55
|
+
schema: new TryCreateThreadSchema({
|
|
56
|
+
title: subject,
|
|
57
|
+
componentName: 'AGENT_CREATE_THREAD',
|
|
58
|
+
conversationId: settings?.conversationId || '',
|
|
59
|
+
result: 'FAILURE',
|
|
60
|
+
statusCode: HttpCodes.BAD_REQUEST,
|
|
61
|
+
failureDescription: error instanceof Error ? error?.message : String(error)
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
|
|
39
66
|
throw error
|
|
40
67
|
}
|
|
41
68
|
},
|
|
42
|
-
[
|
|
69
|
+
[
|
|
70
|
+
messagesCount,
|
|
71
|
+
sendMessageMutation,
|
|
72
|
+
settings?.conversationId,
|
|
73
|
+
settings?.config?.metadata?.agentProductId,
|
|
74
|
+
isAgent,
|
|
75
|
+
updateTitleMutation
|
|
76
|
+
]
|
|
43
77
|
)
|
|
44
78
|
|
|
45
79
|
return {
|
|
@@ -3,7 +3,9 @@ import { useTranslation } from 'react-i18next'
|
|
|
3
3
|
|
|
4
4
|
import { AiIconCircle } from '@/src/lib/components'
|
|
5
5
|
import { useMembershipColor } from '../../hooks'
|
|
6
|
-
import { useIsAgentParentAtomValue } from '../../store'
|
|
6
|
+
import { useIsAgentParentAtomValue, useIsConciergeParentAtomValue } from '../../store'
|
|
7
|
+
|
|
8
|
+
import { getGreetingsLabels } from './utils'
|
|
7
9
|
|
|
8
10
|
export type GreetingsCardProps = {
|
|
9
11
|
tutorName: string
|
|
@@ -13,8 +15,12 @@ export type GreetingsCardProps = {
|
|
|
13
15
|
|
|
14
16
|
function GreetingsCard({ author, tutorName, isDarkTheme = false }: GreetingsCardProps) {
|
|
15
17
|
const { t } = useTranslation()
|
|
16
|
-
const isAgentMode = useIsAgentParentAtomValue()
|
|
17
18
|
const membershipColor = useMembershipColor()
|
|
19
|
+
const isAgentMode = useIsAgentParentAtomValue()
|
|
20
|
+
const isConciergeMode = useIsConciergeParentAtomValue()
|
|
21
|
+
|
|
22
|
+
const chatMode = isConciergeMode ? 'CONCIERGE' : isAgentMode ? 'AGENT' : 'TUTOR'
|
|
23
|
+
const labels = getGreetingsLabels(chatMode)
|
|
18
24
|
|
|
19
25
|
return (
|
|
20
26
|
<div className='flex flex-col items-center justify-center'>
|
|
@@ -28,19 +34,14 @@ function GreetingsCard({ author, tutorName, isDarkTheme = false }: GreetingsCard
|
|
|
28
34
|
'text-white': isDarkTheme,
|
|
29
35
|
'text-gray-900': !isDarkTheme
|
|
30
36
|
})}>
|
|
31
|
-
{t(
|
|
37
|
+
{t(labels.hello, { name: author })}
|
|
32
38
|
</span>
|
|
33
39
|
<h3
|
|
34
40
|
className={clsx('text-xl font-bold', {
|
|
35
41
|
'text-white': isDarkTheme,
|
|
36
42
|
'text-gray-900': !isDarkTheme
|
|
37
43
|
})}>
|
|
38
|
-
{t(
|
|
39
|
-
isAgentMode
|
|
40
|
-
? 'general.greetings.agentFirstMessage'
|
|
41
|
-
: 'general.greetings.firstMessage',
|
|
42
|
-
{ tutorName }
|
|
43
|
-
)}
|
|
44
|
+
{t(labels.firstMessage, { tutorName })}
|
|
44
45
|
</h3>
|
|
45
46
|
</div>
|
|
46
47
|
<p
|
|
@@ -48,7 +49,7 @@ function GreetingsCard({ author, tutorName, isDarkTheme = false }: GreetingsCard
|
|
|
48
49
|
'text-gray-400': isDarkTheme,
|
|
49
50
|
'text-neutral-600': !isDarkTheme
|
|
50
51
|
})}>
|
|
51
|
-
{t(
|
|
52
|
+
{t(labels.description)}
|
|
52
53
|
</p>
|
|
53
54
|
</div>
|
|
54
55
|
</div>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { GreetingsLabels, WidgetMode } from './types'
|
|
2
|
+
|
|
3
|
+
export const getGreetingsLabels = (mode: WidgetMode, isFirstTime = false): GreetingsLabels => {
|
|
4
|
+
const interaction = isFirstTime ? 'first_interaction' : 'other_interactions'
|
|
5
|
+
|
|
6
|
+
const greetingsMap = {
|
|
7
|
+
AGENT: {
|
|
8
|
+
hello: 'general.greetings.hello',
|
|
9
|
+
firstMessage: 'general.greetings.agentFirstMessage',
|
|
10
|
+
description: 'general.greetings.agentDescription'
|
|
11
|
+
},
|
|
12
|
+
CONCIERGE: {
|
|
13
|
+
hello: `concierge.welcome.${interaction}.hello`,
|
|
14
|
+
firstMessage: `concierge.welcome.${interaction}.title`,
|
|
15
|
+
description: 'concierge.welcome.description'
|
|
16
|
+
},
|
|
17
|
+
TUTOR: {
|
|
18
|
+
hello: 'general.greetings.hello',
|
|
19
|
+
firstMessage: 'general.greetings.firstMessage',
|
|
20
|
+
description: 'general.greetings.description'
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return greetingsMap[mode]
|
|
25
|
+
}
|
|
@@ -3,3 +3,8 @@ import { atom, useAtomValue } from 'jotai'
|
|
|
3
3
|
export const widgetSettingsConfigAgentParentAtom = atom(false)
|
|
4
4
|
|
|
5
5
|
export const useIsAgentParentAtomValue = () => useAtomValue(widgetSettingsConfigAgentParentAtom)
|
|
6
|
+
|
|
7
|
+
export const widgetSettingsConfigConciergeParentAtom = atom(false)
|
|
8
|
+
|
|
9
|
+
export const useIsConciergeParentAtomValue = () =>
|
|
10
|
+
useAtomValue(widgetSettingsConfigConciergeParentAtom)
|