app-tutor-ai-consumer 1.24.1 → 1.24.3

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 CHANGED
@@ -1,3 +1,11 @@
1
+ ## [1.24.3](https://github.com/Hotmart-Org/app-tutor-ai-consumer/compare/v1.24.2...v1.24.3) (2025-08-12)
2
+
3
+ ### Bug Fixes
4
+
5
+ - qa issues ([32bf6f9](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/32bf6f951b4b769a2ee2a90a566ebbcc0aded6c6))
6
+
7
+ ## [1.24.2](https://github.com/Hotmart-Org/app-tutor-ai-consumer/compare/v1.24.1...v1.24.2) (2025-08-11)
8
+
1
9
  ## [1.24.1](https://github.com/Hotmart-Org/app-tutor-ai-consumer/compare/v1.24.0...v1.24.1) (2025-08-11)
2
10
 
3
11
  ### Bug Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "app-tutor-ai-consumer",
3
- "version": "1.24.1",
3
+ "version": "1.24.3",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "dev": "rspack serve --env=development --config config/rspack/rspack.config.js",
package/src/index.tsx CHANGED
@@ -5,6 +5,7 @@ import { StrictMode } from 'react'
5
5
  import { createRoot } from 'react-dom/client'
6
6
 
7
7
  import { initTheme } from '@/src/config/theme'
8
+ import { version } from '../package.json'
8
9
 
9
10
  import { initLanguage } from './config/i18n'
10
11
  import { devMode, productionMode } from './lib/utils'
@@ -18,7 +19,7 @@ const loadMainStyles = () => {
18
19
  ? `${process.env.BUNDLE_PATH}/`
19
20
  : `${process.env.BUNDLE_PATH}/${process.env.APP_NAME}/_current/`
20
21
 
21
- const cssPath = `${bundlePath}app-tutor-ai-consumer.css`
22
+ const cssPath = `${bundlePath}app-tutor-ai-consumer.css?v=${version}`
22
23
 
23
24
  if (!document.querySelector(`link[href="${cssPath}"]`)) {
24
25
  const linkElement = document.createElement('link')
@@ -9,6 +9,7 @@ function useMediaQuery({ maxSize }: { maxSize: keyof typeof SCREEN_SIZES }) {
9
9
  const mediaquery = window.matchMedia(`(max-width: ${SCREEN_SIZES[maxSize]}px)`)
10
10
  const listener = () => setMatches(mediaquery.matches)
11
11
 
12
+ listener()
12
13
  mediaquery.addEventListener('change', listener)
13
14
 
14
15
  return () => mediaquery.removeEventListener('change', listener)
@@ -4,4 +4,6 @@ export * from './extract-text-from-react-nodes'
4
4
  export { default as HttpCodes } from './http-codes'
5
5
  export * from './languages'
6
6
  export * from './message-types'
7
+ export * from './toast'
8
+ export { default as ToastUtils } from './toast'
7
9
  export { default as URLutils } from './urls'
@@ -0,0 +1,37 @@
1
+ export const ToastPosition = {
2
+ TOP_RIGHT: 'top right',
3
+ TOP_LEFT: 'top left',
4
+ BOTTOM_LEFT: 'bottom left',
5
+ BOTTOM_RIGHT: 'bottom right'
6
+ } as const
7
+
8
+ export const Toast = {
9
+ SUCCESS: 'success',
10
+ DANGER: 'danger',
11
+ WARNING: 'warning',
12
+ INFO: 'info'
13
+ } as const
14
+
15
+ export type DispatchToastParams = {
16
+ message: string
17
+ type?: (typeof Toast)[keyof typeof Toast]
18
+ position?: (typeof ToastPosition)[keyof typeof ToastPosition]
19
+ }
20
+
21
+ export const TOAST_EVENT_NAME = 'toasted'
22
+
23
+ class ToastUtils {
24
+ dispatch({
25
+ message,
26
+ type = Toast.SUCCESS,
27
+ position = ToastPosition.TOP_RIGHT
28
+ }: DispatchToastParams) {
29
+ window.dispatchEvent(
30
+ new CustomEvent(TOAST_EVENT_NAME, {
31
+ detail: { message, type, position }
32
+ })
33
+ )
34
+ }
35
+ }
36
+
37
+ export default new ToastUtils()
@@ -7,6 +7,7 @@ import { DataHubService } from '@/src/config/datahub'
7
7
  import type { ButtonReactionsType } from '@/src/config/datahub/schemas/tutor'
8
8
  import { ButtonReactions, ClickHotmartTutor } from '@/src/config/datahub/schemas/tutor'
9
9
  import { Button, Icon } from '@/src/lib/components'
10
+ import { ToastUtils } from '@/src/lib/utils'
10
11
  import type { ParsedMessage } from '../../types'
11
12
 
12
13
  export type MessageActionsProps = {
@@ -28,9 +29,14 @@ function MessageActions({ message, className, showActions = false }: MessageActi
28
29
 
29
30
  navigator.clipboard
30
31
  .writeText(message.text)
31
- .then(() => setCopied(true))
32
+ .then(() => {
33
+ setCopied(true)
34
+ ToastUtils.dispatch({ message: t('general.buttons.copied') })
35
+ })
32
36
  .catch((err) => {
33
- console.error('Failed to copy text: ', err)
37
+ const errorMessage = t('generic_error.title')
38
+ console.error(`${errorMessage}: `, err)
39
+ ToastUtils.dispatch({ message: errorMessage })
34
40
  })
35
41
  .finally(() => {
36
42
  setTimeout(() => setCopying(false), 1000)
@@ -25,7 +25,7 @@ function ChatPage() {
25
25
  const sendTextMessageMutation = useSendTextMessage()
26
26
  const limit = useMessagesMaxCount()
27
27
  const [value, setValue] = useChatInputValueAtom()
28
- const [, setWidgetLoading] = useWidgetLoadingAtom()
28
+ const [widgetLoading, setWidgetLoading] = useWidgetLoadingAtom()
29
29
  const isMobile = useMediaQuery({ maxSize: 'md' })
30
30
 
31
31
  const conversationId = useMemo(() => settings?.conversationId, [settings?.conversationId])
@@ -70,7 +70,7 @@ function ChatPage() {
70
70
  onSend={widgetTabs.currentTab === 'chat' ? handleSendMessage : undefined}
71
71
  loading={sendTextMessageMutation.isPending}
72
72
  inputDisabled={messagesQuery?.isLoading}
73
- buttonDisabled={messagesQuery?.isLoading || !value.trim()}
73
+ buttonDisabled={widgetLoading || messagesQuery?.isLoading || !value.trim()}
74
74
  />
75
75
  }>
76
76
  <div className='max-md:px-[1.125rem] max-md:pt-[1.125rem] md:px-5 md:pt-5'>
@@ -8,7 +8,7 @@ import { getAllMessagesQuery, useSendTextMessage } from '@/src/modules/messages/
8
8
  import { useMessagesMaxCount } from '@/src/modules/messages/store'
9
9
  import { useGetProfile } from '@/src/modules/profile'
10
10
  import { useInitSparkie } from '@/src/modules/sparkie/hooks/use-init-sparkie'
11
- import { useWidgetSettingsAtom, useWidgetTabsAtom } from '../../store'
11
+ import { useWidgetLoadingAtomValue, useWidgetSettingsAtom, useWidgetTabsAtom } from '../../store'
12
12
  import { GreetingsCard } from '../greetings-card'
13
13
  import { WidgetHeader } from '../header'
14
14
  import { PageLayout } from '../page-layout'
@@ -28,6 +28,7 @@ function WidgetStarterPage() {
28
28
  const isDarkTheme = settings?.config?.theme === 'dark'
29
29
  const isSparkieReady = useInitSparkie()
30
30
  const isMobile = useMediaQuery({ maxSize: 'md' })
31
+ const widgetLoading = useWidgetLoadingAtomValue()
31
32
 
32
33
  useRefEventListener<HTMLTextAreaElement>({
33
34
  config: {
@@ -83,7 +84,7 @@ function WidgetStarterPage() {
83
84
  name='new-chat-msg-input'
84
85
  ref={chatInputRef}
85
86
  onSend={handleSend}
86
- buttonDisabled={!chatInputValue.trim() || !isSparkieReady}
87
+ buttonDisabled={widgetLoading || !chatInputValue.trim() || !isSparkieReady}
87
88
  />
88
89
  }>
89
90
  <div className='grid-areas-[a_b] grid h-full grid-cols-1 grid-rows-[1fr_auto]'>