app-tutor-ai-consumer 1.37.0 → 1.39.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/package.json +1 -1
  3. package/src/config/datahub/actions.ts +3 -2
  4. package/src/config/datahub/constants.ts +1 -0
  5. package/src/config/datahub/entities.ts +2 -1
  6. package/src/config/datahub/schemas/constants.ts +2 -1
  7. package/src/config/datahub/schemas/tutor/__tests__/{try-send-tutor-message.spec.ts → try-send-message.spec.ts} +11 -6
  8. package/src/config/datahub/schemas/tutor/__tests__/{view-tutor-answer-message.spec.ts → view-answer-message.spec.ts} +9 -4
  9. package/src/config/datahub/schemas/tutor/__tests__/view-chat.spec.ts +38 -0
  10. package/src/config/datahub/schemas/tutor/index.ts +2 -2
  11. package/src/config/datahub/schemas/tutor/{try-send-tutor-message.ts → try-send-message.ts} +22 -12
  12. package/src/config/datahub/schemas/tutor/{view-tutor-answer-message.ts → view-answer-message.ts} +20 -7
  13. package/src/config/datahub/schemas/tutor/view-chat.ts +56 -0
  14. package/src/config/datahub/types.ts +5 -0
  15. package/src/config/styles/global.css +3 -0
  16. package/src/config/tests/handlers.ts +3 -3
  17. package/src/modules/messages/__tests__/{signed-urls.builder.ts → files-signed-urls.builder.ts} +3 -3
  18. package/src/modules/messages/components/chat-file-preview/chat-file-preview.tsx +0 -1
  19. package/src/modules/messages/components/chat-file-preview/components/document-preview/document-preview.tsx +4 -3
  20. package/src/modules/messages/components/chat-file-preview/components/document-preview/types.ts +0 -3
  21. package/src/modules/messages/components/chat-file-preview/utils.ts +17 -0
  22. package/src/modules/messages/components/chat-file-uploader/chat-file-uploader.builder.ts +4 -7
  23. package/src/modules/messages/components/chat-file-uploader/chat-file-uploader.spec.tsx +0 -20
  24. package/src/modules/messages/components/chat-file-uploader/chat-file-uploader.tsx +16 -14
  25. package/src/modules/messages/components/chat-file-uploader-wrapper/chat-file-uploader-wrapper.tsx +34 -0
  26. package/src/modules/messages/components/chat-file-uploader-wrapper/index.ts +1 -0
  27. package/src/modules/messages/components/message-item/message-item.tsx +10 -0
  28. package/src/modules/messages/constants.ts +1 -1
  29. package/src/{lib → modules/messages}/hooks/use-chat-file-upload/constants.ts +2 -0
  30. package/src/modules/messages/hooks/use-chat-file-upload/use-chat-file-upload.spec.ts +19 -0
  31. package/src/modules/messages/hooks/use-chat-file-upload/use-chat-file-upload.ts +102 -0
  32. package/src/modules/messages/hooks/use-get-files-signed-urls/index.ts +1 -0
  33. package/src/modules/messages/hooks/{use-get-signed-urls/use-get-signed-urls.spec.tsx → use-get-files-signed-urls/use-get-files-signed-urls.spec.ts} +7 -7
  34. package/src/modules/messages/hooks/use-get-files-signed-urls/use-get-files-signed-urls.ts +25 -0
  35. package/src/modules/messages/hooks/use-send-text-message/use-send-text-message.spec.tsx +1 -1
  36. package/src/modules/messages/hooks/use-send-text-message/use-send-text-message.tsx +31 -19
  37. package/src/modules/messages/hooks/use-subscribe-message-received-event/use-subscribe-message-received-event.tsx +9 -5
  38. package/src/modules/messages/hooks/use-upload-file/index.ts +1 -0
  39. package/src/modules/messages/hooks/use-upload-file/use-upload-file.ts +15 -0
  40. package/src/modules/messages/service.direct.ts +27 -10
  41. package/src/modules/messages/store/attached-file.atom.ts +7 -0
  42. package/src/modules/messages/types.ts +30 -2
  43. package/src/modules/widget/components/chat-page/chat-page.tsx +26 -11
  44. package/src/modules/widget/hooks/index.ts +1 -0
  45. package/src/modules/widget/hooks/use-send-view-chat-event/index.ts +1 -0
  46. package/src/modules/widget/hooks/use-send-view-chat-event/use-send-view-chat-event.tsx +28 -0
  47. package/src/lib/hooks/use-chat-file-upload/types.ts +0 -14
  48. package/src/lib/hooks/use-chat-file-upload/use-chat-file-upload.spec.ts +0 -59
  49. package/src/lib/hooks/use-chat-file-upload/use-chat-file-upload.ts +0 -28
  50. package/src/modules/messages/components/chat-file-uploader/types.ts +0 -4
  51. package/src/modules/messages/hooks/use-get-signed-urls/index.ts +0 -1
  52. package/src/modules/messages/hooks/use-get-signed-urls/use-get-signed-urls.tsx +0 -38
  53. /package/src/{lib → modules/messages}/hooks/use-chat-file-upload/index.ts +0 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,36 @@
1
+ # [1.39.0](https://github.com/Hotmart-Org/app-tutor-ai-consumer/compare/v1.38.0...v1.39.0) (2025-11-11)
2
+
3
+ ### Features
4
+
5
+ - changing file extension ([60d395b](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/60d395b9a34a49c1e7935dec0593ee75d23be8fe))
6
+ - code improvement ([e539ba3](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/e539ba3882c06dba661a7056476497fb929cd5be))
7
+ - code improvement ([b17de7b](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/b17de7b39bc5bfc13f7dbffbb322934e4c8d1973))
8
+ - code improvements ([ecf54e6](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/ecf54e6be8676890b67f8b4cfecb21dbc6f2b981))
9
+ - error i18n messages ([823ea93](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/823ea93bb38d3777fda686a47e60ab8c94738dfd))
10
+ - fixing productId parameter ([45a1d8c](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/45a1d8c277d6e43f698f90b32f53a87ade1b234d))
11
+ - fixing test ([6309da8](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/6309da8a97cce96543488f8689f1851677bf6a0d))
12
+ - fixing toast type ([71a23e8](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/71a23e8c1d1bfd48d2581d0425a525fb57fe7e38))
13
+ - integrate ChatFileUploaderWrapper with ChatFilePreview ([1b8cf1a](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/1b8cf1a5492b7b57f7303ec4172cc555c6f7fbbc))
14
+ - linking the ChatFileUploaderWrapper display to the showFileUpload parameter ([7826d85](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/7826d8590d304dc30c016ef4e0849ba74e8a6160))
15
+ - preview file on chat history ([aa09c31](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/aa09c317b2299cd9ced9cbe65822838778aabdae))
16
+ - refactoring ([890838b](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/890838b2f79b31797fa593eb5f2218b0d8c5115c))
17
+ - refactoring ([665ff74](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/665ff741df81e2b4dcecedbddc0e0912dac40f89))
18
+ - removing temporary component ([e4bfbf0](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/e4bfbf08b44a20d744b7f0e7c0ab18e2ff5b2519))
19
+ - removing tests ([fa4b836](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/fa4b83631f0aa7542e12f39cbe06c17007a6cc18))
20
+ - removing tooltip ([8e4450e](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/8e4450e87d89cca21855e3270e046817187defda))
21
+ - sending file data to conversation api ([40fe90e](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/40fe90edc4c5f67cd3f527cc33738e1dea0839bc))
22
+ - tooltip refactoring ([df0a66a](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/df0a66ac6d469aea33dbede90fbccce24f6e631a))
23
+ - typing fix ([4ab00a0](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/4ab00a082dbb29d5d848350231f38f79d44d1684))
24
+ - undoing tooltip refactoring ([26c1072](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/26c10722dab2d5669ff972cfbe1aefaeb05b8850))
25
+ - update file size ([bf92561](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/bf92561945896a01dc5032e1b9c2dbcc78110d7d))
26
+ - wip ([3160ab4](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/3160ab4c6d2ea5417213fbbe8ce031b97de853c4))
27
+
28
+ # [1.38.0](https://github.com/Hotmart-Org/app-tutor-ai-consumer/compare/v1.37.0...v1.38.0) (2025-11-10)
29
+
30
+ ### Features
31
+
32
+ - add chat interaction datahub events ([e3df5bb](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/e3df5bb4223579128edb0511b718f74fb4d1bf79))
33
+
1
34
  # [1.37.0](https://github.com/Hotmart-Org/app-tutor-ai-consumer/compare/v1.36.0...v1.37.0) (2025-11-10)
2
35
 
3
36
  ### Features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "app-tutor-ai-consumer",
3
- "version": "1.37.0",
3
+ "version": "1.39.0",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "dev": "rspack serve --env=development --config config/rspack/rspack.config.js",
@@ -13,7 +13,7 @@ export const ActionNames = {
13
13
  CLICK_HOTMART_TUTOR: `${DataHubActions.CLICK}_hotmart_tutor`,
14
14
  CLICK_TUTOR_MINIMIZE: `${DataHubActions.CLICK}_tutor_minimize`,
15
15
  TRY_PRODUCT_TUTOR: `${DataHubActions.TRY}_product_tutor`,
16
- TRY_SEND_TUTOR_MESSAGE: `${DataHubActions.TRY}_send_tutor_message`,
16
+ TRY_SEND_MESSAGE: `${DataHubActions.TRY}_send_message`,
17
17
  CLICK_TUTOR_BACK: `${DataHubActions.CLICK}_tutor_back`,
18
18
  CLICK_TUTOR_HISTORY: `${DataHubActions.CLICK}_tutor_history`,
19
19
  CLICK_TUTOR_INFO: `${DataHubActions.CLICK}_tutor_info`,
@@ -22,5 +22,6 @@ export const ActionNames = {
22
22
  CLICK_TUTOR_TEST_KNOWLEDGE: `${DataHubActions.CLICK}_tutor_test_knowledge`,
23
23
  CLOSE_TUTOR_ONBOARDING: `${DataHubActions.CLOSE}_tutor_onboarding`,
24
24
  VIEW_PRODUCT_TUTOR: `${DataHubActions.VIEW}_product_tutor`,
25
- VIEW_TUTOR_ANSWER_MESSAGE: `${DataHubActions.VIEW}_tutor_answer_message`
25
+ VIEW_ANSWER_MESSAGE: `${DataHubActions.VIEW}_answer_message`,
26
+ VIEW_CHAT: `${DataHubActions.VIEW}_chat`
26
27
  }
@@ -28,6 +28,7 @@ export const ComponentNames = {
28
28
  BUTTON_CLOSE_TUTOR_CHAT: 'BUTTON_CLOSE_TUTOR_CHAT',
29
29
  BUTTON_VIEW_AGENT: 'BUTTON_VIEW_AGENT',
30
30
  BUTTON_SEND_MESSAGE: 'BUTTON_SEND_MESSAGE',
31
+ CHAT: 'CHAT',
31
32
  VIEW_ANSWER: 'VIEW_ANSWER',
32
33
  PRODUCT_CONSUME_CLICK_TUTOR_BACK: 'product_consume_click_tutor_back',
33
34
  PRODUCT_CONSUME_CLICK_TUTOR_HISTORY: 'product_consume_click_tutor_history',
@@ -1,5 +1,6 @@
1
1
  export const DataHubEntities = {
2
2
  ADMIN: 'admin',
3
3
  HOME: 'home',
4
- PRODUCT_CONSUME: 'product_consume'
4
+ PRODUCT_CONSUME: 'product_consume',
5
+ CONVERSATIONAL_AGENT: 'conversational_agent'
5
6
  } as const
@@ -11,5 +11,6 @@ export const UserRole = {
11
11
 
12
12
  export const ProductCategories = {
13
13
  OnlineServices: 'category.online_services.name',
14
- Ebook: 'category.ebook.name'
14
+ Ebook: 'category.ebook.name',
15
+ ConversationalAgent: 'category.conversational_agent.name'
15
16
  } as const
@@ -2,21 +2,24 @@ import { chance } from '@/src/config/tests'
2
2
  import { HttpCodes } from '@/src/lib/utils'
3
3
  import { ComponentNames, ComponentSource } from '../../../constants'
4
4
  import { DataHubEntities } from '../../../entities'
5
- import TrySendTutorMessage from '../try-send-tutor-message'
5
+ import { AgentType } from '../../../types'
6
+ import TrySendMessage from '../try-send-message'
6
7
 
7
- describe('TrySendTutorMessage', () => {
8
+ describe('TrySendMessage', () => {
8
9
  it('should send the event with the correct structure', () => {
9
10
  const event = {
10
11
  questionType: 'TEXT',
11
- questionId: chance.guid()
12
+ messageId: chance.guid(),
13
+ conversationId: chance.guid(),
14
+ agent: AgentType.HOTMART_TUTOR
12
15
  }
13
16
 
14
- expect(new TrySendTutorMessage(event).getDataHubEventData()).toMatchObject({
17
+ expect(new TrySendMessage(event).getDataHubEventData()).toMatchObject({
15
18
  appVersion: '',
16
19
  clubVersion: 'MEMBERSHIP',
17
20
  componentName: ComponentNames.BUTTON_SEND_MESSAGE,
18
21
  componentSource: ComponentSource.HOTMART_TUTOR,
19
- entity: DataHubEntities.PRODUCT_CONSUME,
22
+ entity: DataHubEntities.CONVERSATIONAL_AGENT,
20
23
  failureDescription: 'NOT_FAILURE_RESULT_EVENT',
21
24
  isLogged: true,
22
25
  membershipId: 'UNDEFINED',
@@ -24,7 +27,9 @@ describe('TrySendTutorMessage', () => {
24
27
  osVersion: '537.36',
25
28
  platform: 'WEB',
26
29
  platformDetail: 'WebKit',
27
- questionId: event.questionId,
30
+ messageId: event.messageId,
31
+ conversationId: event.conversationId,
32
+ agent: AgentType.HOTMART_TUTOR,
28
33
  questionType: event.questionType,
29
34
  result: 'SUCCESSFUL',
30
35
  sessionId: 'UNDEFINED',
@@ -1,15 +1,18 @@
1
1
  import { chance } from '@/src/config/tests'
2
2
  import { ComponentNames, ComponentSource } from '../../../constants'
3
3
  import { DataHubEntities } from '../../../entities'
4
+ import { AgentType } from '../../../types'
4
5
  import { UserRole } from '../../constants'
5
- import ViewTutorAnswerMessage from '../view-tutor-answer-message'
6
+ import ViewTutorAnswerMessage from '../view-answer-message'
6
7
 
7
- describe('ViewTutorAnswerMessage', () => {
8
+ describe('ViewAnswerMessage', () => {
8
9
  it('should send the event with the correct structure', () => {
9
10
  const event = {
10
11
  messageType: 'TEXT',
11
12
  messageId: chance.guid(),
12
- correlationId: chance.guid()
13
+ correlationId: chance.guid(),
14
+ conversationId: chance.guid(),
15
+ agent: AgentType.HOTMART_TUTOR
13
16
  }
14
17
 
15
18
  expect(new ViewTutorAnswerMessage(event).getDataHubEventData()).toMatchObject({
@@ -19,7 +22,9 @@ describe('ViewTutorAnswerMessage', () => {
19
22
  componentName: ComponentNames.VIEW_ANSWER,
20
23
  componentSource: ComponentSource.HOTMART_TUTOR,
21
24
  correlationId: event.correlationId,
22
- entity: DataHubEntities.PRODUCT_CONSUME,
25
+ conversationId: event.conversationId,
26
+ agent: AgentType.HOTMART_TUTOR,
27
+ entity: DataHubEntities.CONVERSATIONAL_AGENT,
23
28
  isLogged: true,
24
29
  membershipId: 'UNDEFINED',
25
30
  membershipSlug: 'UNDEFINED',
@@ -0,0 +1,38 @@
1
+ import { chance } from '@/src/config/tests'
2
+ import { ComponentNames, ComponentSource } from '../../../constants'
3
+ import { DataHubEntities } from '../../../entities'
4
+ import { AgentType } from '../../../types'
5
+ import { UserRole } from '../../constants'
6
+ import ViewChatSchema from '../view-chat'
7
+
8
+ describe('ViewChatSchema', () => {
9
+ it('should send the event with the correct structure', () => {
10
+ const event = {
11
+ conversationId: chance.guid(),
12
+ agent: AgentType.HOTMART_TUTOR
13
+ }
14
+
15
+ expect(new ViewChatSchema(event).getDataHubEventData()).toMatchObject({
16
+ appVersion: '',
17
+ arrivedFrom: 'HOME_CLASS_CONSUMER',
18
+ clubVersion: 'MEMBERSHIP',
19
+ componentName: ComponentNames.CHAT,
20
+ componentSource: ComponentSource.HOTMART_TUTOR,
21
+ conversationId: event.conversationId,
22
+ agent: AgentType.HOTMART_TUTOR,
23
+ entity: DataHubEntities.CONVERSATIONAL_AGENT,
24
+ isLogged: true,
25
+ membershipId: 'UNDEFINED',
26
+ membershipSlug: 'UNDEFINED',
27
+ osVersion: '537.36',
28
+ platform: 'WEB',
29
+ platformDetail: 'WebKit',
30
+ productType: 'category.online_services.name',
31
+ sessionId: 'UNDEFINED',
32
+ ucode: 'UNDEFINED',
33
+ url: 'http://localhost:3000/',
34
+ userId: 0,
35
+ userRole: UserRole.CONSUMER
36
+ })
37
+ })
38
+ })
@@ -8,6 +8,6 @@ export { default as ClickTutorOnboardingStartSchema } from './click-tutor-onboar
8
8
  export { default as ClickTutorTestKnowledgeSchema } from './click-tutor-test-knowledge'
9
9
  export { default as CloseTutorOnboardingSchema } from './close-tutor-onboarding'
10
10
  export * from './constants'
11
- export { default as TrySendTutorMessageSchema } from './try-send-tutor-message'
11
+ export { default as TrySendMessageSchema } from './try-send-message'
12
12
  export * from './types'
13
- export { default as ViewTutorAnswerMessageSchema } from './view-tutor-answer-message'
13
+ export { default as ViewAnswerMessageSchema } from './view-answer-message'
@@ -2,26 +2,32 @@ import { HttpCodes } from '@/src/lib/utils'
2
2
  import { ActionNames } from '../../actions'
3
3
  import { ComponentNames, ComponentSource } from '../../constants'
4
4
  import { DataHubEntities } from '../../entities'
5
- import type { DataHubEntityTypes } from '../../types'
5
+ import type { AgentType, DataHubEntityTypes } from '../../types'
6
6
  import type { ActionNamesType } from '../../types'
7
7
  import type { BaseTrySchemaConstructorArgs } from '../base-try-schema'
8
8
  import BaseTrySchema from '../base-try-schema'
9
9
 
10
- export type TrySendTutorMessageConstructorArgs = Partial<BaseTrySchemaConstructorArgs> & {
10
+ export type TrySendMessageConstructorArgs = Partial<BaseTrySchemaConstructorArgs> & {
11
11
  questionType?: string
12
- questionId?: string
12
+ messageId?: string
13
+ conversationId?: string
14
+ agent: AgentType
13
15
  }
14
16
 
15
- class TrySendTutorMessageSchema extends BaseTrySchema {
17
+ class TrySendMessageSchema extends BaseTrySchema {
16
18
  action: ActionNamesType
17
19
  entity: DataHubEntityTypes
18
20
  questionType: string
19
- questionId: string
21
+ messageId?: string
22
+ conversationId?: string
23
+ agent?: AgentType
20
24
 
21
- constructor(args?: TrySendTutorMessageConstructorArgs) {
25
+ constructor(args?: TrySendMessageConstructorArgs) {
22
26
  const {
23
27
  questionType = 'TEXT',
24
- questionId = '',
28
+ messageId,
29
+ conversationId,
30
+ agent,
25
31
  componentSource = ComponentSource.HOTMART_TUTOR,
26
32
  componentName = ComponentNames.BUTTON_SEND_MESSAGE,
27
33
  failureDescription = 'NOT_FAILURE_RESULT_EVENT',
@@ -37,19 +43,23 @@ class TrySendTutorMessageSchema extends BaseTrySchema {
37
43
  statusCode
38
44
  })
39
45
 
40
- this.action = ActionNames.TRY_SEND_TUTOR_MESSAGE
41
- this.entity = DataHubEntities.PRODUCT_CONSUME
46
+ this.action = ActionNames.TRY_SEND_MESSAGE
47
+ this.entity = DataHubEntities.CONVERSATIONAL_AGENT
42
48
  this.questionType = questionType
43
- this.questionId = questionId
49
+ this.messageId = messageId
50
+ this.conversationId = conversationId
51
+ this.agent = agent
44
52
  }
45
53
 
46
54
  getDataHubEventData(): Record<string, unknown> {
47
55
  return {
48
56
  ...this.prepare(),
49
57
  questionType: this.questionType,
50
- questionId: this.questionId
58
+ messageId: this.messageId,
59
+ conversationId: this.conversationId,
60
+ agent: this.agent
51
61
  }
52
62
  }
53
63
  }
54
64
 
55
- export default TrySendTutorMessageSchema
65
+ export default TrySendMessageSchema
@@ -1,27 +1,35 @@
1
1
  import { ActionNames } from '../../actions'
2
2
  import { ComponentNames, ComponentSource } from '../../constants'
3
- import type { ActionNamesType } from '../../types'
3
+ import { DataHubEntities } from '../../entities'
4
+ import type { ActionNamesType, AgentType, DataHubEntityTypes } from '../../types'
4
5
  import type { BaseViewSchemaConstructorArgs } from '../base-view-schema'
5
6
  import BaseViewSchema from '../base-view-schema'
6
7
 
7
- export type ViewTutorAnswerMessageConstructorArgs = Partial<BaseViewSchemaConstructorArgs> & {
8
+ export type ViewAnswerMessageConstructorArgs = Partial<BaseViewSchemaConstructorArgs> & {
8
9
  messageType?: string
9
10
  messageId?: string
10
11
  correlationId?: string
12
+ conversationId?: string
13
+ agent?: AgentType
11
14
  }
12
15
 
13
- class ViewTutorAnswerMessageSchema extends BaseViewSchema {
16
+ class ViewAnswerMessageSchema extends BaseViewSchema {
14
17
  private messageType?: string
15
18
  private messageId?: string
16
19
  private correlationId?: string
20
+ private conversationId?: string
21
+ private agent?: AgentType
17
22
 
18
23
  action: ActionNamesType
24
+ entity: DataHubEntityTypes
19
25
 
20
- constructor(args?: ViewTutorAnswerMessageConstructorArgs) {
26
+ constructor(args?: ViewAnswerMessageConstructorArgs) {
21
27
  const {
22
28
  messageType = 'TEXT',
23
29
  messageId,
24
30
  correlationId,
31
+ conversationId,
32
+ agent,
25
33
  arrivedFrom,
26
34
  entity,
27
35
  isLogged,
@@ -39,10 +47,13 @@ class ViewTutorAnswerMessageSchema extends BaseViewSchema {
39
47
  componentSource
40
48
  })
41
49
 
42
- this.action = ActionNames.VIEW_TUTOR_ANSWER_MESSAGE
50
+ this.action = ActionNames.VIEW_ANSWER_MESSAGE
51
+ this.entity = DataHubEntities.CONVERSATIONAL_AGENT
43
52
  this.messageType = messageType
44
53
  this.messageId = messageId
45
54
  this.correlationId = correlationId
55
+ this.conversationId = conversationId
56
+ this.agent = agent
46
57
  }
47
58
 
48
59
  getDataHubEventData(): Record<string, unknown> {
@@ -50,9 +61,11 @@ class ViewTutorAnswerMessageSchema extends BaseViewSchema {
50
61
  ...super.prepare(),
51
62
  messageType: this.messageType,
52
63
  messageId: this.messageId,
53
- correlationId: this.correlationId
64
+ correlationId: this.correlationId,
65
+ conversationId: this.conversationId,
66
+ agent: this.agent
54
67
  }
55
68
  }
56
69
  }
57
70
 
58
- export default ViewTutorAnswerMessageSchema
71
+ export default ViewAnswerMessageSchema
@@ -0,0 +1,56 @@
1
+ import { ActionNames } from '../../actions'
2
+ import { ComponentNames, ComponentSource } from '../../constants'
3
+ import { DataHubEntities } from '../../entities'
4
+ import type { ActionNamesType, AgentType, DataHubEntityTypes } from '../../types'
5
+ import type { BaseViewSchemaConstructorArgs } from '../base-view-schema'
6
+ import BaseViewSchema from '../base-view-schema'
7
+
8
+ export type ViewChatConstructorArgs = Partial<BaseViewSchemaConstructorArgs> & {
9
+ conversationId?: string
10
+ agent?: AgentType
11
+ }
12
+
13
+ class ViewChatSchema extends BaseViewSchema {
14
+ private conversationId?: string
15
+ private agent?: AgentType
16
+
17
+ action: ActionNamesType
18
+ entity: DataHubEntityTypes
19
+
20
+ constructor(args?: ViewChatConstructorArgs) {
21
+ const {
22
+ conversationId,
23
+ agent,
24
+ arrivedFrom,
25
+ entity,
26
+ isLogged,
27
+ productType,
28
+ componentName = ComponentNames.CHAT,
29
+ componentSource = ComponentSource.HOTMART_TUTOR
30
+ } = args ?? {}
31
+
32
+ super({
33
+ arrivedFrom,
34
+ entity,
35
+ isLogged,
36
+ productType,
37
+ componentName,
38
+ componentSource
39
+ })
40
+
41
+ this.action = ActionNames.VIEW_CHAT
42
+ this.entity = DataHubEntities.CONVERSATIONAL_AGENT
43
+ this.conversationId = conversationId
44
+ this.agent = agent
45
+ }
46
+
47
+ getDataHubEventData(): Record<string, unknown> {
48
+ return {
49
+ ...super.prepare(),
50
+ conversationId: this.conversationId,
51
+ agent: this.agent
52
+ }
53
+ }
54
+ }
55
+
56
+ export default ViewChatSchema
@@ -18,6 +18,11 @@ export type ComponentSourceType = (typeof ComponentSource)[keyof typeof Componen
18
18
  export type ScreenNamesType = (typeof ScreenNames)[keyof typeof ScreenNames]
19
19
  export type ResultType = (typeof Result)[keyof typeof Result]
20
20
 
21
+ export enum AgentType {
22
+ HOTMART_TUTOR = 'HOTMART_TUTOR',
23
+ PRODUCT_AGENT = 'PRODUCT_AGENT'
24
+ }
25
+
21
26
  export type SchemaType = {
22
27
  action: ActionNamesType
23
28
  entity: DataHubEntityTypes
@@ -88,6 +88,9 @@
88
88
  --hc-size-spacing-1: 0.25rem;
89
89
  --hc-size-spacing-2: 0.5rem;
90
90
  --hc-size-border-medium: 0.5rem;
91
+
92
+ /* Tooltip */
93
+ --tooltip-bg-color: #191c1f;
91
94
  }
92
95
 
93
96
  #hotmart-app-tutor-ai-consumer-root {
@@ -1,8 +1,8 @@
1
1
  import { http, HttpResponse } from 'msw'
2
2
 
3
3
  import { MessagesEndpoints, MSG_MAX_COUNT } from '@/src/modules/messages'
4
+ import SignedFilesUrlsResponseBuilder from '@/src/modules/messages/__tests__/files-signed-urls.builder'
4
5
  import IMessageWithSenderDataMock from '@/src/modules/messages/__tests__/imessage-with-sender-data.mock'
5
- import SignedUrlsResponseBuilder from '@/src/modules/messages/__tests__/signed-urls.builder'
6
6
  import { ProfileEndpoints } from '@/src/modules/profile'
7
7
  import ProfileAPIPropsBuilder from '@/src/modules/profile/__tests__/profile-api-props.builder'
8
8
 
@@ -19,8 +19,8 @@ export const handlers = [
19
19
  http.all(ProfileEndpoints.getProfile(), () => {
20
20
  return HttpResponse.json(new ProfileAPIPropsBuilder())
21
21
  }),
22
- http.all(MessagesEndpoints.getSignedUrls(), () => {
23
- return HttpResponse.json(new SignedUrlsResponseBuilder())
22
+ http.all(MessagesEndpoints.getFilesSignedUrls(), () => {
23
+ return HttpResponse.json(new SignedFilesUrlsResponseBuilder())
24
24
  }),
25
25
  http.all(MessagesEndpoints.getAll(':conversationId'), ({ request }) => {
26
26
  const limit = Number(new URL(request.url)?.searchParams?.get?.('limit'))
@@ -1,7 +1,7 @@
1
1
  import { chance } from '@/src/config/tests'
2
- import type { IGetSignedUrlsResponse } from '../types'
2
+ import type { IGetFilesSignedUrlsResponse } from '../types'
3
3
 
4
- class SignedUrlsResponseBuilder implements IGetSignedUrlsResponse {
4
+ class FilesSignedUrlsResponseBuilder implements IGetFilesSignedUrlsResponse {
5
5
  uploadUrl: string
6
6
  futureDownloadUrl: string
7
7
  imagePreviewUrl: string
@@ -39,4 +39,4 @@ class SignedUrlsResponseBuilder implements IGetSignedUrlsResponse {
39
39
  }
40
40
  }
41
41
 
42
- export default SignedUrlsResponseBuilder
42
+ export default FilesSignedUrlsResponseBuilder
@@ -34,7 +34,6 @@ function ChatFilePreview({
34
34
  <DocumentPreview
35
35
  name={name}
36
36
  size={size}
37
- type={type}
38
37
  isLoading={isLoading}
39
38
  showCloseButton={showCloseButton}
40
39
  onClose={onClose}
@@ -5,7 +5,7 @@ import { Icon, Spinner } from '@/src/lib/components'
5
5
  import { useMediaQuery } from '@/src/lib/hooks'
6
6
  import { useWidgetSettingsAtom } from '@/src/modules/widget/store'
7
7
  import { CHAT_FILE_PREVIEW_CONFIG } from '../../constants'
8
- import { formatFileSize } from '../../utils'
8
+ import { formatFileSize, getFileTypeFromFileName } from '../../utils'
9
9
  import { CloseButton } from '../close-button'
10
10
 
11
11
  import type { DocumentPreviewProps } from './types'
@@ -13,7 +13,6 @@ import type { DocumentPreviewProps } from './types'
13
13
  export default function DocumentPreview({
14
14
  name,
15
15
  size,
16
- type,
17
16
  isLoading,
18
17
  showCloseButton,
19
18
  onClose
@@ -23,7 +22,9 @@ export default function DocumentPreview({
23
22
  const isMobile = useMediaQuery({ maxSize: 'md' })
24
23
  const formattedSize = formatFileSize(size)
25
24
  const isDarkMode = settings?.config?.theme === 'dark'
26
- const config = CHAT_FILE_PREVIEW_CONFIG[type]
25
+
26
+ const fileType = getFileTypeFromFileName(name)
27
+ const config = CHAT_FILE_PREVIEW_CONFIG[fileType]
27
28
 
28
29
  return (
29
30
  <div
@@ -1,9 +1,6 @@
1
- import type { FilePreviewProps } from '../../types'
2
-
3
1
  export type DocumentPreviewProps = {
4
2
  name: string
5
3
  size: number
6
- type: Exclude<FilePreviewProps['type'], 'image'>
7
4
  isLoading: boolean
8
5
  showCloseButton: boolean
9
6
  onClose?: () => void
@@ -1,4 +1,7 @@
1
+ import { FILE_TYPES } from '../../hooks/use-chat-file-upload/constants'
2
+
1
3
  import { FILE_SIZE_UNITS } from './constants'
4
+ import type { FilePreviewProps } from './types'
2
5
 
3
6
  export function formatFileSize(size: number): string {
4
7
  if (size < FILE_SIZE_UNITS.KB) {
@@ -11,3 +14,17 @@ export function formatFileSize(size: number): string {
11
14
 
12
15
  return `${Math.round((size / FILE_SIZE_UNITS.MB) * 10) / 10}MB`
13
16
  }
17
+
18
+ export function getFileTypeFromFileName(
19
+ fileName: string
20
+ ): Exclude<FilePreviewProps['type'], 'image'> {
21
+ const extension = `.${fileName.split('.').pop()?.toLowerCase() || ''}`
22
+
23
+ for (const [category, extensions] of Object.entries(FILE_TYPES)) {
24
+ if (category !== 'image' && (extensions as readonly string[]).includes(extension)) {
25
+ return category as Exclude<FilePreviewProps['type'], 'image'>
26
+ }
27
+ }
28
+
29
+ return 'document'
30
+ }
@@ -1,18 +1,15 @@
1
- import type { ChatFileUploaderProps } from './types'
1
+ import type { ChatFileUploaderProps } from './chat-file-uploader'
2
2
 
3
3
  export class ChatFileUploaderBuilder {
4
- private props: ChatFileUploaderProps = {}
4
+ private props: ChatFileUploaderProps = {
5
+ onUploadFile: () => {}
6
+ }
5
7
 
6
8
  withDisabled(disabled: boolean): ChatFileUploaderBuilder {
7
9
  this.props.disabled = disabled
8
10
  return this
9
11
  }
10
12
 
11
- withLoading(loading: boolean): ChatFileUploaderBuilder {
12
- this.props.loading = loading
13
- return this
14
- }
15
-
16
13
  build(): ChatFileUploaderProps {
17
14
  return this.props
18
15
  }
@@ -24,26 +24,6 @@ describe('ChatFileUploader', () => {
24
24
  expect(button).toBeDisabled()
25
25
  })
26
26
 
27
- it('should be disabled when loading prop is true', () => {
28
- const props = new ChatFileUploaderBuilder().withLoading(true).build()
29
- renderComponent(props)
30
-
31
- const button = screen.getByRole('button', {
32
- name: /general.buttons.open_options/i
33
- })
34
- expect(button).toBeDisabled()
35
- })
36
-
37
- it('should be enabled when both disabled and loading are false', () => {
38
- const props = new ChatFileUploaderBuilder().withDisabled(false).withLoading(false).build()
39
- renderComponent(props)
40
-
41
- const button = screen.getByRole('button', {
42
- name: /general.buttons.open_options/i
43
- })
44
- expect(button).toBeEnabled()
45
- })
46
-
47
27
  it('should trigger file input when clicking file option', async () => {
48
28
  const { user } = renderComponent()
49
29