app-tutor-ai-consumer 1.33.0 → 1.34.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 +37 -0
- package/config/vitest/__mocks__/sparkie.tsx +1 -1
- package/package.json +1 -1
- package/src/bootstrap.ts +40 -0
- package/src/config/tests/handlers.ts +5 -4
- package/src/config/theme/init-theme.ts +11 -5
- package/src/index.tsx +22 -12
- package/src/lib/components/dropdown-actions/dropdown-actions.tsx +87 -0
- package/src/lib/components/dropdown-actions/dropdownActions.builder.ts +58 -0
- package/src/lib/components/dropdown-actions/dropdownActions.spec.tsx +76 -0
- package/src/lib/components/dropdown-actions/index.ts +1 -0
- package/src/lib/components/dropdown-actions/types.ts +16 -0
- package/src/lib/components/errors/generic/generic-error.tsx +11 -8
- package/src/lib/components/icons/document.svg +3 -0
- package/src/lib/components/icons/file.svg +3 -0
- package/src/lib/components/icons/icon-names.d.ts +8 -0
- package/src/lib/components/icons/image.svg +3 -0
- package/src/lib/components/icons/pdf.svg +3 -0
- package/src/lib/components/icons/plus.svg +3 -0
- package/src/lib/components/icons/retry.svg +3 -0
- package/src/lib/components/icons/spreadsheet.svg +3 -0
- package/src/lib/components/icons/tutor-logo.svg +9 -0
- package/src/lib/components/index.ts +1 -0
- package/src/lib/components/markdownrenderer/markdownrenderer.tsx +1 -3
- package/src/lib/hooks/index.ts +1 -0
- package/src/lib/hooks/use-chat-file-upload/constants.ts +11 -0
- package/src/lib/hooks/use-chat-file-upload/index.ts +1 -0
- package/src/lib/hooks/use-chat-file-upload/types.ts +14 -0
- package/src/lib/hooks/use-chat-file-upload/use-chat-file-upload.spec.ts +59 -0
- package/src/lib/hooks/use-chat-file-upload/use-chat-file-upload.ts +28 -0
- package/src/lib/hooks/use-click-outside/index.ts +1 -0
- package/src/lib/hooks/use-click-outside/use-click-outside.tsx +23 -0
- package/src/lib/hooks/use-click-outside/useClickOutside.spec.ts +102 -0
- package/src/lib/utils/index.ts +1 -0
- package/src/lib/utils/is-theme-dark.ts +21 -0
- package/src/main/hooks/use-initial-store/index.ts +1 -0
- package/src/main/hooks/use-initial-store/use-initial-store.tsx +64 -0
- package/src/main/hooks/use-initial-tab/index.ts +1 -0
- package/src/main/hooks/use-initial-tab/use-initial-tab.tsx +84 -0
- package/src/main/index.ts +1 -0
- package/src/main/main-content.tsx +14 -0
- package/src/main/main-wrapper.tsx +16 -0
- package/src/main/main.spec.tsx +5 -3
- package/src/main/main.tsx +7 -16
- package/src/main/types.ts +5 -0
- package/src/modules/global-providers/global-providers.tsx +1 -15
- package/src/modules/messages/__tests__/signed-urls.builder.ts +42 -0
- package/src/modules/messages/components/chat-file-preview/chat-file-preview.builder.ts +121 -0
- package/src/modules/messages/components/chat-file-preview/chat-file-preview.spec.tsx +107 -0
- package/src/modules/messages/components/chat-file-preview/chat-file-preview.tsx +45 -0
- package/src/modules/messages/components/chat-file-preview/components/close-button/close-button.tsx +31 -0
- package/src/modules/messages/components/chat-file-preview/components/close-button/index.ts +1 -0
- package/src/modules/messages/components/chat-file-preview/components/close-button/types.ts +4 -0
- package/src/modules/messages/components/chat-file-preview/components/document-preview/document-preview.tsx +63 -0
- package/src/modules/messages/components/chat-file-preview/components/document-preview/index.ts +1 -0
- package/src/modules/messages/components/chat-file-preview/components/document-preview/types.ts +10 -0
- package/src/modules/messages/components/chat-file-preview/components/error-preview/error-preview.tsx +37 -0
- package/src/modules/messages/components/chat-file-preview/components/error-preview/index.ts +1 -0
- package/src/modules/messages/components/chat-file-preview/components/error-preview/types.ts +4 -0
- package/src/modules/messages/components/chat-file-preview/components/image-preview/image-preview.tsx +32 -0
- package/src/modules/messages/components/chat-file-preview/components/image-preview/index.ts +1 -0
- package/src/modules/messages/components/chat-file-preview/components/image-preview/types.ts +6 -0
- package/src/modules/messages/components/chat-file-preview/constants.ts +22 -0
- package/src/modules/messages/components/chat-file-preview/index.ts +1 -0
- package/src/modules/messages/components/chat-file-preview/types.ts +13 -0
- package/src/modules/messages/components/chat-file-preview/utils.spec.ts +38 -0
- package/src/modules/messages/components/chat-file-preview/utils.ts +13 -0
- package/src/modules/messages/components/chat-file-uploader/chat-file-uploader.builder.ts +19 -0
- package/src/modules/messages/components/chat-file-uploader/chat-file-uploader.spec.tsx +58 -0
- package/src/modules/messages/components/chat-file-uploader/chat-file-uploader.tsx +80 -0
- package/src/modules/messages/components/chat-file-uploader/index.ts +1 -0
- package/src/modules/messages/components/chat-file-uploader/types.ts +4 -0
- package/src/modules/messages/components/chat-input/chat-input.tsx +1 -1
- package/src/modules/messages/components/index.ts +1 -0
- package/src/modules/messages/components/message-item/message-item.tsx +1 -2
- package/src/modules/messages/constants.ts +2 -1
- package/src/modules/messages/hooks/use-get-signed-urls/index.ts +1 -0
- package/src/modules/messages/hooks/use-get-signed-urls/use-get-signed-urls.spec.tsx +27 -0
- package/src/modules/messages/hooks/use-get-signed-urls/use-get-signed-urls.tsx +38 -0
- package/src/modules/messages/hooks/use-infinite-get-messages/use-infinite-get-messages.spec.tsx +1 -2
- package/src/modules/messages/hooks/use-infinite-get-messages/use-infinite-get-messages.tsx +3 -8
- package/src/modules/messages/hooks/use-prefetch-messages/index.ts +1 -0
- package/src/modules/messages/hooks/use-prefetch-messages/use-prefetch-messages.tsx +28 -0
- package/src/modules/messages/hooks/use-subscribe-message-received-event/use-subscribe-message-received-event.tsx +54 -119
- package/src/modules/messages/hooks/use-suspense-messages/index.ts +2 -0
- package/src/modules/messages/hooks/use-suspense-messages/types.ts +4 -0
- package/src/modules/messages/hooks/use-suspense-messages/use-suspense-messages.tsx +21 -0
- package/src/modules/messages/service.direct.ts +18 -0
- package/src/modules/messages/service.ts +1 -2
- package/src/modules/messages/store/messages-max-count.atom.ts +2 -2
- package/src/modules/messages/types.ts +14 -0
- package/src/modules/profile/hooks/use-get-profile/use-get-profile.tsx +7 -6
- package/src/modules/sparkie/__tests__/sparkie.mock.ts +1 -4
- package/src/modules/sparkie/hooks/use-init-sparkie/use-init-sparkie.tsx +30 -38
- package/src/modules/sparkie/service.ts +2 -1
- package/src/modules/widget/__tests__/widget-settings-props.builder.ts +20 -1
- package/src/modules/widget/components/ai-disclaimer/ai-disclaimer.tsx +19 -0
- package/src/modules/widget/components/ai-disclaimer/index.ts +1 -0
- package/src/modules/widget/components/chat-page/chat-page.tsx +30 -71
- package/src/modules/widget/components/container/container.tsx +14 -0
- package/src/modules/widget/components/greetings-card/greetings-card.tsx +9 -2
- package/src/modules/widget/components/loading-page/loading-page.tsx +9 -15
- package/src/modules/widget/components/starter-page/starter-page-actions/starter-page-actions.spec.tsx +4 -4
- package/src/modules/widget/components/starter-page/starter-page-actions/starter-page-actions.tsx +3 -2
- package/src/modules/widget/components/starter-page/starter-page-content/starter-page-content.spec.tsx +0 -46
- package/src/modules/widget/components/starter-page/starter-page-content/starter-page-content.tsx +1 -30
- package/src/modules/widget/components/starter-page/starter-page-header/starter-page-header.spec.tsx +8 -4
- package/src/modules/widget/components/starter-page/starter-page-header/starter-page-header.tsx +15 -13
- package/src/modules/widget/components/starter-page/starter-page.spec.tsx +13 -3
- package/src/modules/widget/components/starter-page/starter-page.tsx +22 -87
- package/src/modules/widget/hooks/index.ts +0 -1
- package/src/modules/widget/hooks/use-listen-to-theme-change-event/use-listen-to-theme-change-event.tsx +8 -6
- package/src/modules/widget/store/create-store.ts +7 -0
- package/src/modules/widget/store/index.ts +1 -0
- package/src/modules/widget/store/widget-settings-config.atom.ts +1 -6
- package/src/modules/widget/store/widget-tabs.atom.ts +18 -37
- package/src/types.ts +1 -0
- package/src/wrapper.tsx +39 -19
- package/src/lib/hooks/use-response-timeout/index.ts +0 -1
- package/src/lib/hooks/use-response-timeout/use-response-timeout.tsx +0 -42
- package/src/modules/widget/hooks/use-init-widget/index.ts +0 -1
- package/src/modules/widget/hooks/use-init-widget/use-init-widget.tsx +0 -56
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,40 @@
|
|
|
1
|
+
# [1.34.0](https://github.com/Hotmart-Org/app-tutor-ai-consumer/compare/v1.33.1...v1.34.0) (2025-11-04)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
- fix aria label ([5aa714d](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/5aa714da552e93349c1c030c026ecb4a14c132ba))
|
|
6
|
+
- fix base branch ([96db93a](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/96db93a53c4a93d6e0800af9547ea81d118a6bb5))
|
|
7
|
+
- fix chat input ([d686bc5](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/d686bc530cecb84fc80cbf2a8b9ff029a3572e53))
|
|
8
|
+
- fix file types ([ee12680](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/ee12680db8c36307c4b067cb6460009c0509018e))
|
|
9
|
+
- fix file uploader ([1110f11](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/1110f116a0276f3d34ebec6eea81aaa59e50e993))
|
|
10
|
+
- fix pr request ([6ad4870](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/6ad4870cd2bd03f788eb10f00a65616d48c1087f))
|
|
11
|
+
- fix pr request ([1556154](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/155615476be3fb61994a790dd4464b9f53968f78))
|
|
12
|
+
- fix pr request ([17cd695](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/17cd69506c21b793ea05f634a07f987a125e3102))
|
|
13
|
+
- fix svg ([c9165f7](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/c9165f74d2f592e0fccf27176768e2ae6a782fd0))
|
|
14
|
+
- pr issues ([3f5b8ad](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/3f5b8ad54a657a4d95c66728c12559cd321b088d))
|
|
15
|
+
- refactor code ([1b7b5cf](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/1b7b5cfafe6c8f902bf3514fd4e36996f2e705c8))
|
|
16
|
+
- refactor component name ([a6c2a16](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/a6c2a16ab29733dd831bc88e3a6452c9e225af70))
|
|
17
|
+
- remove console.log ([66645dc](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/66645dc72dac1bd667c5440cf59e45aecc9b321a))
|
|
18
|
+
- update file uploader ([c12f347](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/c12f3472450a4afa214ebf87234e7eb3464c3f7d))
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
- add chat loading if is user message without response ([8ffe2a7](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/8ffe2a7bbf1d814f341855ec1efebd6e00f5cb65))
|
|
23
|
+
- add default store ([75a07c4](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/75a07c451c99b526aea896b6f94b7deb1f0f1888))
|
|
24
|
+
- change sparkie call to messages history page ([f5f3e73](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/f5f3e73d7ec147b7f5a4a5e76293cf29b2d0dd93))
|
|
25
|
+
- create chat file preview ([885b744](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/885b744d76b62a7e387d2e820e8e8030f6e17f9a))
|
|
26
|
+
- implement signed URLs functionality with hooks and service integration ([ff845fa](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/ff845fa34be2c28f55ec04b9a70522f3100a7bec))
|
|
27
|
+
- refactor dropdown ([88bba02](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/88bba02ec9021f5294450eecfd6d6c92097d6690))
|
|
28
|
+
- release branch for changing widget to support product agent ([ab39962](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/ab39962a5e2a35ee29056c329fe8a4038291ceaa))
|
|
29
|
+
- update feature flag file upload ([bd3313b](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/bd3313b634b53ac5dfda2737155e718d570fb099))
|
|
30
|
+
- update icon size ([2d77927](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/2d7792724ed1a1166b012da118b5ce3c44d9ad74))
|
|
31
|
+
|
|
32
|
+
## [1.33.1](https://github.com/Hotmart-Org/app-tutor-ai-consumer/compare/v1.33.0...v1.33.1) (2025-10-22)
|
|
33
|
+
|
|
34
|
+
### Bug Fixes
|
|
35
|
+
|
|
36
|
+
- markdownrenderer ([ae8c08a](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/ae8c08a0620cd95a54a787ac00ddab78640d3f45))
|
|
37
|
+
|
|
1
38
|
# [1.33.0](https://github.com/Hotmart-Org/app-tutor-ai-consumer/compare/v1.32.3...v1.33.0) (2025-10-16)
|
|
2
39
|
|
|
3
40
|
### Features
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from '@/src/modules/sparkie/__tests__/sparkie.mock'
|
|
7
7
|
import MessageService from '@hotmart-org-ca/sparkie/dist/MessageService'
|
|
8
8
|
|
|
9
|
-
vi.mock('@hotmart/sparkie', () => ({ default: SparkieMock }))
|
|
9
|
+
vi.mock('@hotmart-org-ca/sparkie', () => ({ default: SparkieMock }))
|
|
10
10
|
|
|
11
11
|
beforeEach(() => {
|
|
12
12
|
vi.spyOn(SparkieService, 'getMessageService').mockResolvedValue(
|
package/package.json
CHANGED
package/src/bootstrap.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { QueryClient } from '@tanstack/react-query'
|
|
2
|
+
|
|
3
|
+
import { initTheme } from '@/src/config/theme'
|
|
4
|
+
|
|
5
|
+
import { DataHubStore } from './config/datahub'
|
|
6
|
+
import { initDayjs } from './config/dayjs'
|
|
7
|
+
import { initLanguage } from './config/i18n'
|
|
8
|
+
import { initAxios } from './config/request/api'
|
|
9
|
+
import { getProfileQuery } from './modules/profile'
|
|
10
|
+
import type { Theme, WidgetSettingProps } from './types'
|
|
11
|
+
|
|
12
|
+
type BootstrapProps = {
|
|
13
|
+
settings: WidgetSettingProps
|
|
14
|
+
queryClient: QueryClient
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function bootstrap({ queryClient, settings }: BootstrapProps) {
|
|
18
|
+
initAxios(settings.hotmartToken)
|
|
19
|
+
initTheme(settings.config?.theme as Theme)
|
|
20
|
+
|
|
21
|
+
const promises = [
|
|
22
|
+
initLanguage(settings.locale),
|
|
23
|
+
queryClient.prefetchQuery(getProfileQuery()),
|
|
24
|
+
initDayjs(settings.locale)
|
|
25
|
+
] as const
|
|
26
|
+
|
|
27
|
+
await Promise.all(promises)
|
|
28
|
+
|
|
29
|
+
DataHubStore.initData({
|
|
30
|
+
ucode: settings.user?.ucode ?? '',
|
|
31
|
+
membershipId: settings.membershipId ?? '',
|
|
32
|
+
membershipSlug: settings.membershipSlug ?? '',
|
|
33
|
+
sessionId: settings.sessionId,
|
|
34
|
+
userId: Number(settings.userId),
|
|
35
|
+
product: {
|
|
36
|
+
id: Number(settings.productId) || 0,
|
|
37
|
+
category: settings.productType ?? ''
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { http, HttpResponse } from 'msw'
|
|
2
2
|
|
|
3
|
-
import type { IMessageWithSenderData } from '@/src/modules/messages'
|
|
4
3
|
import { MessagesEndpoints, MSG_MAX_COUNT } from '@/src/modules/messages'
|
|
5
4
|
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,13 +19,14 @@ 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())
|
|
24
|
+
}),
|
|
22
25
|
http.all(MessagesEndpoints.getAll(':conversationId'), ({ request }) => {
|
|
23
26
|
const limit = Number(new URL(request.url)?.searchParams?.get?.('limit'))
|
|
24
27
|
|
|
25
28
|
return HttpResponse.json(
|
|
26
|
-
new IMessageWithSenderDataMock().getMany(
|
|
27
|
-
isNaN(limit) ? MSG_MAX_COUNT : limit
|
|
28
|
-
) as IMessageWithSenderData[]
|
|
29
|
+
new IMessageWithSenderDataMock().getMany(isNaN(limit) ? MSG_MAX_COUNT : limit)
|
|
29
30
|
)
|
|
30
31
|
})
|
|
31
32
|
]
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getTheme } from '@/src/lib/utils'
|
|
1
2
|
import type { Theme } from '@/src/types'
|
|
2
3
|
|
|
3
4
|
export function initTheme(theme: Theme) {
|
|
@@ -5,11 +6,16 @@ export function initTheme(theme: Theme) {
|
|
|
5
6
|
|
|
6
7
|
if (!rootElement) return
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
const currentTheme = getTheme(theme)
|
|
10
|
+
|
|
11
|
+
const darkClasses = ['dark', 'bg-ai-dark']
|
|
12
|
+
const lightClasses = ['bg-neutral-100']
|
|
13
|
+
|
|
14
|
+
rootElement.classList.remove(...darkClasses, ...lightClasses)
|
|
15
|
+
|
|
16
|
+
if (currentTheme === 'dark') {
|
|
17
|
+
return rootElement.classList.add(...darkClasses)
|
|
11
18
|
}
|
|
12
19
|
|
|
13
|
-
rootElement.classList.
|
|
14
|
-
return rootElement.classList.add('bg-neutral-100')
|
|
20
|
+
return rootElement.classList.add(...lightClasses)
|
|
15
21
|
}
|
package/src/index.tsx
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import './config/styles/global.css'
|
|
2
2
|
import './config/styles/index.css'
|
|
3
3
|
|
|
4
|
-
import { StrictMode } from 'react'
|
|
5
4
|
import { createRoot } from 'react-dom/client'
|
|
6
5
|
|
|
7
|
-
import { queryClient
|
|
8
|
-
import { initTheme } from '@/src/config/theme'
|
|
6
|
+
import { queryClient } from '@/src/config/tanstack'
|
|
9
7
|
import { version } from '../package.json'
|
|
10
8
|
|
|
11
|
-
import {
|
|
9
|
+
import { bootstrap } from './bootstrap'
|
|
10
|
+
import { initTheme } from './config/theme'
|
|
12
11
|
import { devMode, productionMode } from './lib/utils'
|
|
13
12
|
import { SparkieService } from './modules/sparkie'
|
|
13
|
+
import { createStore } from './modules/widget/store'
|
|
14
14
|
import type { Theme, WidgetSettingProps } from './types'
|
|
15
15
|
import Wrapper from './wrapper'
|
|
16
16
|
|
|
@@ -48,22 +48,32 @@ window.startChatWidget = async (
|
|
|
48
48
|
|
|
49
49
|
container.setAttribute('id', 'hotmart-app-tutor-ai-consumer-root')
|
|
50
50
|
const theme = (container.getAttribute('data-theme') ?? 'dark') as Theme
|
|
51
|
+
initTheme(theme)
|
|
51
52
|
|
|
52
53
|
const root = createRoot(container)
|
|
54
|
+
const widgetSettings = { ...settings, config: { ...settings.config, theme } }
|
|
55
|
+
const store = createStore()
|
|
53
56
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
root.render(
|
|
58
|
+
<Wrapper settings={widgetSettings} store={store} queryClient={queryClient} state={'LOADING'} />
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
await bootstrap({ queryClient, settings })
|
|
57
63
|
|
|
58
64
|
root.render(
|
|
59
|
-
<
|
|
60
|
-
<QueryProvider queryClient={queryClient} showDevTools={false}>
|
|
61
|
-
<Wrapper settings={{ ...settings, config: { ...settings.config, theme } }} />
|
|
62
|
-
</QueryProvider>
|
|
63
|
-
</StrictMode>
|
|
65
|
+
<Wrapper settings={widgetSettings} store={store} queryClient={queryClient} state={'READY'} />
|
|
64
66
|
)
|
|
65
67
|
|
|
66
68
|
window.__CHAT_WIDGET_INSTANCE__ = { root, container, queryClient }
|
|
69
|
+
} catch (error) {
|
|
70
|
+
root.render(
|
|
71
|
+
<Wrapper settings={widgetSettings} store={store} queryClient={queryClient} state={'ERROR'} />
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
console.error('ERROR:Initializing Chat Widget', error)
|
|
75
|
+
|
|
76
|
+
window.__CHAT_WIDGET_INSTANCE__ = undefined
|
|
67
77
|
}
|
|
68
78
|
}
|
|
69
79
|
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { useRef, useState } from 'react'
|
|
2
|
+
import clsx from 'clsx'
|
|
3
|
+
import { useTranslation } from 'react-i18next'
|
|
4
|
+
|
|
5
|
+
import { Button, Icon } from '@/src/lib/components'
|
|
6
|
+
import ButtonDefault from '@/src/lib/components/button/button-default'
|
|
7
|
+
import type { ValidIconNames } from '@/src/lib/components/icons/icon-names'
|
|
8
|
+
import { useClickOutside } from '@/src/lib/hooks'
|
|
9
|
+
|
|
10
|
+
import type { DropdownActionsProps } from './types'
|
|
11
|
+
|
|
12
|
+
function DropdownActions({
|
|
13
|
+
triggerIcon,
|
|
14
|
+
items,
|
|
15
|
+
disabled = false,
|
|
16
|
+
triggerClassName,
|
|
17
|
+
triggerIconClassName
|
|
18
|
+
}: DropdownActionsProps) {
|
|
19
|
+
const { t } = useTranslation()
|
|
20
|
+
const [visible, setVisibile] = useState(false)
|
|
21
|
+
const dropdownRef = useRef<HTMLDivElement>(null)
|
|
22
|
+
useClickOutside(dropdownRef, handleCloseDropdown)
|
|
23
|
+
|
|
24
|
+
function handleCloseDropdown() {
|
|
25
|
+
setVisibile(false)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function handleToggleVisibility() {
|
|
29
|
+
setVisibile((prevState) => !prevState)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function handleClick(event: React.MouseEvent<HTMLButtonElement>) {
|
|
33
|
+
event.preventDefault()
|
|
34
|
+
event.stopPropagation()
|
|
35
|
+
handleToggleVisibility()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function handleDropdownItemClick(
|
|
39
|
+
event: React.MouseEvent<HTMLButtonElement>,
|
|
40
|
+
callback: () => void
|
|
41
|
+
) {
|
|
42
|
+
event.preventDefault()
|
|
43
|
+
event.stopPropagation()
|
|
44
|
+
handleCloseDropdown()
|
|
45
|
+
callback()
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<div ref={dropdownRef} className='relative'>
|
|
50
|
+
<Button
|
|
51
|
+
onClick={handleClick}
|
|
52
|
+
disabled={disabled}
|
|
53
|
+
aria-label={t('general.buttons.open_options')}
|
|
54
|
+
className={clsx(
|
|
55
|
+
triggerClassName,
|
|
56
|
+
'bg-neutral-100 p-0 hover:bg-neutral-200 focus:bg-neutral-200'
|
|
57
|
+
)}>
|
|
58
|
+
<Icon
|
|
59
|
+
name={triggerIcon as ValidIconNames}
|
|
60
|
+
className={clsx(triggerIconClassName, 'text-neutral-900')}
|
|
61
|
+
/>
|
|
62
|
+
</Button>
|
|
63
|
+
|
|
64
|
+
{visible && (
|
|
65
|
+
<div className='absolute bottom-full mb-2 flex flex-col rounded-md border border-neutral-300 bg-neutral-100 shadow-lg'>
|
|
66
|
+
{items.map((item) => {
|
|
67
|
+
if (!item.visible) return null
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<ButtonDefault
|
|
71
|
+
key={item.label}
|
|
72
|
+
onClick={(event) => handleDropdownItemClick(event, item.callback)}
|
|
73
|
+
className='flex flex-row items-center justify-start rounded-md px-4 py-3 text-sm font-normal transition-colors duration-150 hover:bg-neutral-200'>
|
|
74
|
+
{item.icon && <Icon name={item.icon} className='mr-4 h-4 w-4 text-neutral-500' />}
|
|
75
|
+
<span className='line-clamp-1 min-w-[5rem] max-w-[10rem] break-words text-left text-neutral-700'>
|
|
76
|
+
{t(item.label)}
|
|
77
|
+
</span>
|
|
78
|
+
</ButtonDefault>
|
|
79
|
+
)
|
|
80
|
+
})}
|
|
81
|
+
</div>
|
|
82
|
+
)}
|
|
83
|
+
</div>
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export default DropdownActions
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { chance } from '@/src/config/tests'
|
|
2
|
+
|
|
3
|
+
import type { DropdownActionsProps } from './types'
|
|
4
|
+
|
|
5
|
+
export class DropdownActionsBuilder implements DropdownActionsProps {
|
|
6
|
+
items: DropdownActionsProps['items']
|
|
7
|
+
triggerIcon?: DropdownActionsProps['triggerIcon']
|
|
8
|
+
disabled?: boolean
|
|
9
|
+
className?: string
|
|
10
|
+
triggerClassName?: string
|
|
11
|
+
dropdownClassName?: string
|
|
12
|
+
|
|
13
|
+
constructor() {
|
|
14
|
+
this.items = [
|
|
15
|
+
{
|
|
16
|
+
label: chance.word(),
|
|
17
|
+
visible: true,
|
|
18
|
+
callback: vi.fn() as () => void
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
this.triggerIcon = 'plus'
|
|
22
|
+
this.disabled = false
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
withTriggerIcon(triggerIcon: DropdownActionsProps['triggerIcon']) {
|
|
26
|
+
this.triggerIcon = triggerIcon
|
|
27
|
+
return this
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
withItems(items: DropdownActionsProps['items']) {
|
|
31
|
+
this.items = items
|
|
32
|
+
return this
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
withDisabled(disabled: boolean) {
|
|
36
|
+
this.disabled = disabled
|
|
37
|
+
return this
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
withClassName(className: string) {
|
|
41
|
+
this.className = className
|
|
42
|
+
return this
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
withTriggerClassName(triggerClassName: string) {
|
|
46
|
+
this.triggerClassName = triggerClassName
|
|
47
|
+
return this
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
withDropdownClassName(dropdownClassName: string) {
|
|
51
|
+
this.dropdownClassName = dropdownClassName
|
|
52
|
+
return this
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
build() {
|
|
56
|
+
return this
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { chance, render, screen } from '@/src/config/tests'
|
|
2
|
+
import { DropdownActions } from '../dropdown-actions'
|
|
3
|
+
|
|
4
|
+
import { DropdownActionsBuilder } from './dropdownActions.builder'
|
|
5
|
+
import type { DropdownActionsProps } from './types'
|
|
6
|
+
|
|
7
|
+
const defaultProps = new DropdownActionsBuilder().build()
|
|
8
|
+
|
|
9
|
+
const renderComponent = (props: DropdownActionsProps = defaultProps) => {
|
|
10
|
+
return render(<DropdownActions {...props} />)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
describe('DropdownActions', () => {
|
|
14
|
+
it('should render with success', async () => {
|
|
15
|
+
const { items } = defaultProps
|
|
16
|
+
|
|
17
|
+
const { user } = renderComponent()
|
|
18
|
+
|
|
19
|
+
const dropdown = screen.getByRole('button', { name: /general.buttons.open_options/i })
|
|
20
|
+
|
|
21
|
+
await user.click(dropdown)
|
|
22
|
+
|
|
23
|
+
expect(screen.getByText(items[0].label)).toBeInTheDocument()
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
describe('when `visible` is `false`', () => {
|
|
27
|
+
it('should not render dropdown item', async () => {
|
|
28
|
+
const label = chance.word()
|
|
29
|
+
const items = [
|
|
30
|
+
{
|
|
31
|
+
label,
|
|
32
|
+
visible: false,
|
|
33
|
+
callback: vi.fn() as () => void
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
const props = new DropdownActionsBuilder().withItems(items).build()
|
|
38
|
+
|
|
39
|
+
const { user } = renderComponent(props)
|
|
40
|
+
|
|
41
|
+
const dropdown = screen.getByRole('button', { name: /general.buttons.open_options/i })
|
|
42
|
+
|
|
43
|
+
await user.click(dropdown)
|
|
44
|
+
|
|
45
|
+
expect(screen.queryByText(label)).not.toBeInTheDocument()
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
describe('when item has icon', () => {
|
|
50
|
+
it('should render label with icon', async () => {
|
|
51
|
+
const label = chance.word()
|
|
52
|
+
const items = [
|
|
53
|
+
{
|
|
54
|
+
label,
|
|
55
|
+
visible: true,
|
|
56
|
+
icon: 'file' as const,
|
|
57
|
+
callback: vi.fn() as () => void
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
const props = new DropdownActionsBuilder().withItems(items).build()
|
|
62
|
+
|
|
63
|
+
const { user } = renderComponent(props)
|
|
64
|
+
|
|
65
|
+
const dropdown = screen.getByRole('button', { name: /general.buttons.open_options/i })
|
|
66
|
+
|
|
67
|
+
await user.click(dropdown)
|
|
68
|
+
|
|
69
|
+
expect(screen.getByText(label)).toBeInTheDocument()
|
|
70
|
+
|
|
71
|
+
await user.click(screen.getByText(label))
|
|
72
|
+
|
|
73
|
+
expect(props.items[0].callback).toHaveBeenCalledTimes(1)
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as DropdownActions } from './dropdown-actions'
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ValidIconNames } from '@/src/lib/components/icons/icon-names'
|
|
2
|
+
|
|
3
|
+
export type DropdownItem = {
|
|
4
|
+
label: string
|
|
5
|
+
callback: () => void
|
|
6
|
+
icon?: ValidIconNames
|
|
7
|
+
visible?: boolean
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type DropdownActionsProps = {
|
|
11
|
+
items: DropdownItem[]
|
|
12
|
+
disabled?: boolean
|
|
13
|
+
triggerClassName?: string
|
|
14
|
+
triggerIcon?: ValidIconNames
|
|
15
|
+
triggerIconClassName?: string
|
|
16
|
+
}
|
|
@@ -3,11 +3,12 @@ import { useTranslation } from 'react-i18next'
|
|
|
3
3
|
import ErrorDarkSVG from '@/public/assets/svg/error-dark.svg?url'
|
|
4
4
|
import ErrorLightSVG from '@/public/assets/svg/error-light.svg?url'
|
|
5
5
|
import { Button } from '@/src/lib/components'
|
|
6
|
-
import { PageLayout, TutorWidgetEvents } from '@/src/modules/widget'
|
|
6
|
+
import { PageLayout, TutorWidgetEvents, useIsAgentParentAtomValue } from '@/src/modules/widget'
|
|
7
7
|
import { WidgetHeader } from '@/src/modules/widget/components/header'
|
|
8
8
|
|
|
9
9
|
function GenericError({ isDarkMode = false }: { isDarkMode?: boolean }) {
|
|
10
10
|
const { t } = useTranslation()
|
|
11
|
+
const isAgentMode = useIsAgentParentAtomValue()
|
|
11
12
|
|
|
12
13
|
return (
|
|
13
14
|
<PageLayout className='p-5'>
|
|
@@ -36,13 +37,15 @@ function GenericError({ isDarkMode = false }: { isDarkMode?: boolean }) {
|
|
|
36
37
|
{t('general.buttons.try_again')}
|
|
37
38
|
</Button>
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
{!isAgentMode && (
|
|
41
|
+
<Button
|
|
42
|
+
variant='secondary'
|
|
43
|
+
className='mx-auto w-full max-w-max rounded-lg !px-9 py-2 !font-light'
|
|
44
|
+
onClick={() => TutorWidgetEvents['c3po-app-widget-hide'].dispatch()}
|
|
45
|
+
aria-label='Close Button'>
|
|
46
|
+
{t('general.buttons.close')}
|
|
47
|
+
</Button>
|
|
48
|
+
)}
|
|
46
49
|
</div>
|
|
47
50
|
</div>
|
|
48
51
|
</PageLayout>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M13 16C13.5312 16 14 15.5625 14 15V7H10.5C9.65625 7 9 6.34375 9 5.5V2H5C4.4375 2 4 2.46875 4 3V15C4 15.5625 4.4375 16 5 16H13ZM10.5 6H13.9688C13.9375 5.9375 13.9062 5.84375 13.8438 5.78125L10.2188 2.15625C10.1562 2.09375 10.0625 2.0625 10 2.03125V5.5C10 5.78125 10.2188 6 10.5 6ZM5 1H9.875C10.25 1 10.6562 1.1875 10.9375 1.46875L14.5312 5.0625C14.8125 5.34375 15 5.75 15 6.125V15C15 16.125 14.0938 17 13 17H5C3.875 17 3 16.125 3 15V3C3 1.90625 3.875 1 5 1ZM6.5 9H11.5C11.75 9 12 9.25 12 9.5C12 9.78125 11.75 10 11.5 10H6.5C6.21875 10 6 9.78125 6 9.5C6 9.25 6.21875 9 6.5 9ZM6.5 11H11.5C11.75 11 12 11.25 12 11.5C12 11.7812 11.75 12 11.5 12H6.5C6.21875 12 6 11.7812 6 11.5C6 11.25 6.21875 11 6.5 11ZM6.5 13H11.5C11.75 13 12 13.25 12 13.5C12 13.7812 11.75 14 11.5 14H6.5C6.21875 14 6 13.7812 6 13.5C6 13.25 6.21875 13 6.5 13Z" fill="#F5F3EF"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M13 14.5V6.5H9.5C8.65625 6.5 8 5.84375 8 5V1.5H4C3.4375 1.5 3 1.96875 3 2.5V14.5C3 15.0625 3.4375 15.5 4 15.5H12C12.5312 15.5 13 15.0625 13 14.5ZM12.9688 5.5C12.9375 5.4375 12.9062 5.34375 12.8438 5.28125L9.21875 1.65625C9.15625 1.59375 9.0625 1.5625 9 1.53125V5C9 5.28125 9.21875 5.5 9.5 5.5H12.9688ZM2 2.5C2 1.40625 2.875 0.5 4 0.5H8.875C9.25 0.5 9.65625 0.6875 9.9375 0.96875L13.5312 4.5625C13.8125 4.84375 14 5.25 14 5.625V14.5C14 15.625 13.0938 16.5 12 16.5H4C2.875 16.5 2 15.625 2 14.5V2.5Z" fill="currentColor"/>
|
|
3
|
+
</svg>
|
|
@@ -6,22 +6,30 @@ export type ValidIconNames =
|
|
|
6
6
|
| 'arrow-left'
|
|
7
7
|
| 'arrow-up'
|
|
8
8
|
| 'book'
|
|
9
|
+
| 'retry'
|
|
9
10
|
| 'chevron-down'
|
|
10
11
|
| 'clone'
|
|
11
12
|
| 'close'
|
|
12
13
|
| 'copy-solid'
|
|
13
14
|
| 'copy'
|
|
15
|
+
| 'document'
|
|
14
16
|
| 'double-check'
|
|
15
17
|
| 'expand'
|
|
18
|
+
| 'file'
|
|
16
19
|
| 'gallery'
|
|
20
|
+
| 'image'
|
|
17
21
|
| 'info'
|
|
18
22
|
| 'interrogation'
|
|
19
23
|
| 'like-solid'
|
|
20
24
|
| 'like'
|
|
21
25
|
| 'paste'
|
|
26
|
+
| 'pdf'
|
|
27
|
+
| 'plus'
|
|
22
28
|
| 'send'
|
|
23
29
|
| 'sparkle-tutor-light'
|
|
24
30
|
| 'sparkle-tutor'
|
|
31
|
+
| 'spreadsheet'
|
|
25
32
|
| 'stop'
|
|
33
|
+
| 'tutor-logo'
|
|
26
34
|
| 'warning'
|
|
27
35
|
| 'waveforms'
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M2 2.5C1.4375 2.5 1 2.96875 1 3.5V10.8125L3.09375 8.6875C3.59375 8.21875 4.375 8.21875 4.875 8.6875L7 10.8125L11.0938 6.6875C11.5938 6.21875 12.375 6.21875 12.875 6.6875L15 8.8125V3.5C15 2.96875 14.5312 2.5 14 2.5H2ZM1 12.2188V13.5C1 14.0625 1.4375 14.5 2 14.5H3.28125L6.28125 11.5L4.15625 9.40625C4.0625 9.3125 3.90625 9.3125 3.8125 9.40625L1 12.2188ZM12.1562 7.40625C12.0625 7.3125 11.9062 7.3125 11.8125 7.40625L4.6875 14.5H14C14.5312 14.5 15 14.0625 15 13.5V10.2188L12.1562 7.40625ZM0 3.5C0 2.40625 0.875 1.5 2 1.5H14C15.0938 1.5 16 2.40625 16 3.5V13.5C16 14.625 15.0938 15.5 14 15.5H2C0.875 15.5 0 14.625 0 13.5V3.5ZM5 5C5 4.75 4.75 4.5 4.5 4.5C4.21875 4.5 4 4.75 4 5C4 5.28125 4.21875 5.5 4.5 5.5C4.75 5.5 5 5.28125 5 5ZM3 5C3 4.46875 3.28125 4 3.75 3.71875C4.1875 3.4375 4.78125 3.4375 5.25 3.71875C5.6875 4 6 4.46875 6 5C6 5.5625 5.6875 6.03125 5.25 6.3125C4.78125 6.59375 4.1875 6.59375 3.75 6.3125C3.28125 6.03125 3 5.5625 3 5Z" fill="currentColor"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M14 15V7H10.5C9.65625 7 9 6.34375 9 5.5V2H5C4.4375 2 4 2.46875 4 3V15C4 15.5625 4.4375 16 5 16H13C13.5312 16 14 15.5625 14 15ZM13.9688 6C13.9375 5.9375 13.9062 5.84375 13.8438 5.78125L10.2188 2.15625C10.1562 2.09375 10.0625 2.0625 10 2.03125V5.5C10 5.78125 10.2188 6 10.5 6H13.9688ZM3 3C3 1.90625 3.875 1 5 1H9.875C10.25 1 10.6562 1.1875 10.9375 1.46875L14.5312 5.0625C14.8125 5.34375 15 5.75 15 6.125V15C15 16.125 14.0938 17 13 17H5C3.875 17 3 16.125 3 15V3Z" fill="#F5F3EF"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M7.5 1.17993V6.67993H13C13.25 6.67993 13.5 6.92993 13.5 7.17993C13.5 7.46118 13.25 7.67993 13 7.67993H7.5V13.1799C7.5 13.4612 7.25 13.6799 7 13.6799C6.71875 13.6799 6.5 13.4612 6.5 13.1799V7.67993H1C0.71875 7.67993 0.5 7.46118 0.5 7.17993C0.5 6.92993 0.71875 6.67993 1 6.67993H6.5V1.17993C6.5 0.929932 6.71875 0.679932 7 0.679932C7.25 0.679932 7.5 0.929932 7.5 1.17993Z" fill="currentColor"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="14" height="19" viewBox="0 0 14 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M12.5312 4.1875C12.6719 4.1875 12.8125 4.32812 12.8125 4.46875V8.21875C12.8125 8.38281 12.6719 8.5 12.5312 8.5H8.78125C8.61719 8.5 8.5 8.38281 8.5 8.21875V7.98438C8.5 7.84375 8.61719 7.70312 8.78125 7.70312H11.4531C10.6094 6.10938 8.92188 4.98438 7 4.98438C4.21094 4.98438 1.98438 7.25781 1.98438 10C1.98438 12.7891 4.23438 15.0156 7 15.0156C8.28906 15.0156 9.46094 14.5469 10.3516 13.75C10.4453 13.6328 10.6328 13.6562 10.7266 13.75L10.8906 13.9141C11.0078 14.0312 11.0078 14.2188 10.8906 14.3359C9.85938 15.25 8.47656 15.8125 7 15.8125C3.78906 15.8125 1.1875 13.2344 1.1875 10.0234C1.16406 6.83594 3.76562 4.21094 6.97656 4.21094C9.10938 4.1875 10.9844 5.35938 12.0156 7.07031V4.46875C12.0156 4.32812 12.1328 4.1875 12.2969 4.1875H12.5312Z" fill="currentColor"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M3 3C2.4375 3 2 3.46875 2 4V6H16V4C16 3.46875 15.5312 3 15 3H3ZM2 7V10.5H8.5V7H2ZM9.5 7V10.5H16V7H9.5ZM8.5 11.5H2V14C2 14.5625 2.4375 15 3 15H8.5V11.5ZM9.5 15H15C15.5312 15 16 14.5625 16 14V11.5H9.5V15ZM1 4C1 2.90625 1.875 2 3 2H15C16.0938 2 17 2.90625 17 4V14C17 15.125 16.0938 16 15 16H3C1.875 16 1 15.125 1 14V4Z" fill="#F5F3EF"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M0.896914 6.12971C0.779441 6.10837 0.779442 5.89161 0.896914 5.87028C5.07103 5.11209 5.67461 2.64887 5.90592 0.812118C5.92066 0.695019 6.07934 0.695018 6.09408 0.812117C6.32539 2.64887 6.92897 5.11209 11.1031 5.87028C11.2206 5.89161 11.2206 6.10837 11.1031 6.12971C6.92897 6.8879 6.32539 9.35112 6.09408 11.1879C6.07934 11.305 5.92066 11.305 5.90592 11.1879C5.67461 9.35112 5.07103 6.8879 0.896914 6.12971Z" fill="url(#paint0_linear_7672_1716)"/>
|
|
3
|
+
<defs>
|
|
4
|
+
<linearGradient id="paint0_linear_7672_1716" x1="1.125" y1="-0.0649467" x2="10.634" y2="12.0859" gradientUnits="userSpaceOnUse">
|
|
5
|
+
<stop stop-color="#44D0FF"/>
|
|
6
|
+
<stop offset="1" stop-color="#B48EFF"/>
|
|
7
|
+
</linearGradient>
|
|
8
|
+
</defs>
|
|
9
|
+
</svg>
|
|
@@ -71,9 +71,7 @@ const mdComponents: Partial<Components> = {
|
|
|
71
71
|
},
|
|
72
72
|
blockquote({ children, ...props }) {
|
|
73
73
|
return (
|
|
74
|
-
<blockquote
|
|
75
|
-
className='my-2 border-l-4 border-primary-500 pl-4 italic text-neutral-100'
|
|
76
|
-
{...props}>
|
|
74
|
+
<blockquote className='my-2 border-l-4 border-primary-500 pl-4 italic' {...props}>
|
|
77
75
|
{children}
|
|
78
76
|
</blockquote>
|
|
79
77
|
)
|
package/src/lib/hooks/index.ts
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const FILE_TYPES = {
|
|
2
|
+
document: ['.doc', '.docx', '.txt'],
|
|
3
|
+
spreadsheet: ['.xls', '.xlsx', '.csv'],
|
|
4
|
+
pdf: ['.pdf'],
|
|
5
|
+
image: ['.jpg', '.jpeg', '.png']
|
|
6
|
+
} as const
|
|
7
|
+
|
|
8
|
+
export const FILE_TYPES_KEYS = {
|
|
9
|
+
DOCUMENT: 'document',
|
|
10
|
+
IMAGE: 'image'
|
|
11
|
+
} as const
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useChatFileUpload } from './use-chat-file-upload'
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type FileType = 'document' | 'image'
|
|
2
|
+
|
|
3
|
+
export type SelectedFile = {
|
|
4
|
+
file: File
|
|
5
|
+
type: FileType
|
|
6
|
+
name: string
|
|
7
|
+
size: number
|
|
8
|
+
previewUrl?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type UseFileUploadReturn = {
|
|
12
|
+
selectedFile: SelectedFile | null
|
|
13
|
+
handleSelectFile: (file: File, type: FileType) => void
|
|
14
|
+
}
|