app-tutor-ai-consumer 1.8.0 → 1.8.1

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,5 @@
1
+ ## [1.8.1](https://github.com/Hotmart-Org/app-tutor-ai-consumer/compare/v1.8.0...v1.8.1) (2025-07-15)
2
+
1
3
  # [1.8.0](https://github.com/Hotmart-Org/app-tutor-ai-consumer/compare/v1.7.0...v1.8.0) (2025-07-14)
2
4
 
3
5
  ### Features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "app-tutor-ai-consumer",
3
- "version": "1.8.0",
3
+ "version": "1.8.1",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "dev": "rspack serve --env=development --config config/rspack/rspack.config.js",
package/public/index.html CHANGED
@@ -12,6 +12,6 @@
12
12
  </head>
13
13
 
14
14
  <body class="bg-ai-dark">
15
- <div id="root"></div>
15
+ <div id="c3po-app-widget"></div>
16
16
  </body>
17
17
  </html>
@@ -8,7 +8,7 @@ import { devMode } from './lib/utils'
8
8
  if (devMode) {
9
9
  window.TOKEN = process.env.TOKEN ?? ''
10
10
  void (async () => {
11
- await window.startChatWidget('root', {
11
+ await window.startChatWidget('c3po-app-widget', {
12
12
  hotmartToken: window.TOKEN,
13
13
  locale: LANGUAGES.PT_BR,
14
14
  conversationId: '21506473-a93c-4b38-9c32-68a5ca37ce73', // OWNER
@@ -1,18 +1,18 @@
1
- import { type RefObject, useEffect, useState } from 'react'
1
+ import { type RefObject, useEffect, useMemo, useState } from 'react'
2
2
 
3
3
  import { useThrottle } from '@/src/lib/hooks'
4
4
 
5
5
  function useRefClientHeight<T extends HTMLElement>(
6
6
  refElement: RefObject<T | null>,
7
- defaultHeight = '100vh'
7
+ defaultHeight = 0
8
8
  ) {
9
- const [clientHeight, setClientHeight] = useState(defaultHeight)
9
+ const [clientHeight, setClientHeight] = useState<number>(defaultHeight)
10
10
 
11
11
  const { throttledCallback: resizeHandler } = useThrottle({
12
12
  callback: () => {
13
13
  if (!refElement?.current?.clientHeight) return
14
14
 
15
- setClientHeight(`${refElement?.current.clientHeight}px`)
15
+ setClientHeight(refElement.current.clientHeight)
16
16
  },
17
17
  delay: 650
18
18
  })
@@ -32,7 +32,7 @@ function useRefClientHeight<T extends HTMLElement>(
32
32
  }
33
33
  }, [refElement, resizeHandler])
34
34
 
35
- return clientHeight
35
+ return useMemo(() => clientHeight, [clientHeight])
36
36
  }
37
37
 
38
38
  export default useRefClientHeight
@@ -1,7 +1,6 @@
1
1
  import { lazy, useCallback, useRef } from 'react'
2
2
  import clsx from 'clsx'
3
3
 
4
- import { useRefClientHeight } from '@/src/lib/hooks'
5
4
  import { useWidgetLoadingAtomValue } from '@/src/modules/widget'
6
5
  import { useAllMessages, useManageScroll } from '../../hooks'
7
6
  import { useSkeletonRef } from '../../hooks/use-skeleton-ref'
@@ -22,7 +21,6 @@ const ScrollToBottomButton = lazy(
22
21
 
23
22
  function MessagesList() {
24
23
  const scrollerRef = useRef<HTMLDivElement>(null)
25
- const scrollerClientHeight = useRefClientHeight(scrollerRef)
26
24
  const scrollToButtonRef = useRef<HTMLButtonElement>(null)
27
25
  const { allMessages, messagesQuery } = useAllMessages()
28
26
  const widgetIsLoading = useWidgetLoadingAtomValue()
@@ -41,12 +39,7 @@ function MessagesList() {
41
39
  }, [])
42
40
 
43
41
  return (
44
- <div
45
- ref={scrollerRef}
46
- className={clsx(
47
- 'relative mx-2 flex flex-col gap-2 overflow-auto p-4',
48
- `h-[${scrollerClientHeight}]`
49
- )}>
42
+ <div ref={scrollerRef} className='relative mx-2 my-4 flex flex-col gap-2 overflow-auto px-4'>
50
43
  <MessageItemLoading show={messagesQuery.isFetching} />
51
44
 
52
45
  <MessageItemEndOfScroll
@@ -4,6 +4,7 @@ import { isTextEmpty } from '@/src/lib/utils/is-text-empty'
4
4
  import { ChatInput, MessagesList, useChatInputValueAtom } from '@/src/modules/messages/components'
5
5
  import { useAllMessages, useSendTextMessage } from '@/src/modules/messages/hooks'
6
6
  import { useWidgetLoadingAtomValue, useWidgetTabsValueAtom } from '../../store'
7
+ import { PageLayout } from '../page-layout'
7
8
 
8
9
  function ChatPage() {
9
10
  const widgetTabs = useWidgetTabsValueAtom()
@@ -27,9 +28,8 @@ function ChatPage() {
27
28
  }
28
29
 
29
30
  return (
30
- <>
31
- <MessagesList />
32
- <div className='border-t border-t-neutral-700 px-5 py-4'>
31
+ <PageLayout
32
+ asideChild={
33
33
  <ChatInput
34
34
  name='new-chat-msg-input'
35
35
  ref={chatInputRef}
@@ -38,9 +38,9 @@ function ChatPage() {
38
38
  inputDisabled={messagesQuery?.isLoading}
39
39
  buttonDisabled={messagesQuery?.isLoading || !value.trim()}
40
40
  />
41
- </div>
42
- </>
41
+ }>
42
+ <MessagesList />
43
+ </PageLayout>
43
44
  )
44
45
  }
45
-
46
46
  export default ChatPage
@@ -7,10 +7,8 @@ function WidgetContainer() {
7
7
  useSubscribeMessageReceivedEvent()
8
8
 
9
9
  return (
10
- <div className='flex min-h-svh flex-col items-center justify-center'>
11
- <div className='grid h-svh w-full grid-rows-[1fr_max-content]'>
12
- {WIDGET_TABS[widgetTabs.currentTab]}
13
- </div>
10
+ <div className='flex h-full flex-col items-center justify-stretch overflow-hidden'>
11
+ {WIDGET_TABS[widgetTabs.currentTab]}
14
12
  </div>
15
13
  )
16
14
  }
@@ -2,4 +2,5 @@ export * from './ai-avatar'
2
2
  export * from './chat-page'
3
3
  export * from './container'
4
4
  export * from './greetings-card'
5
+ export * from './page-layout'
5
6
  export * from './scroll-to-bottom-button'
@@ -4,6 +4,7 @@ import { useTranslation } from 'react-i18next'
4
4
  import TutorOnboardingSVG from '@/public/assets/svg/tutor-onboarding.svg?url'
5
5
  import { Button } from '@/src/lib/components'
6
6
  import { useWidgetTabsAtom } from '../../store'
7
+ import { PageLayout } from '../page-layout'
7
8
 
8
9
  import styles from './styles.module.css'
9
10
 
@@ -12,8 +13,8 @@ function WidgetOnboardingPage() {
12
13
  const { t } = useTranslation()
13
14
 
14
15
  return (
15
- <>
16
- <div className={styles.bg}>
16
+ <PageLayout>
17
+ <div className={clsx('flex-1', styles.bg)}>
17
18
  <div className='mx-4 flex h-full flex-col justify-center gap-6 px-0.5'>
18
19
  <div className='mx-auto max-w-[67%]'>
19
20
  <img src={TutorOnboardingSVG} aria-hidden />
@@ -33,7 +34,7 @@ function WidgetOnboardingPage() {
33
34
  {t('general.buttons.start')}
34
35
  </Button>
35
36
  </div>
36
- </>
37
+ </PageLayout>
37
38
  )
38
39
  }
39
40
 
@@ -0,0 +1,2 @@
1
+ export * from './page-layout'
2
+ export { default as PageLayout } from './page-layout'
@@ -0,0 +1,27 @@
1
+ import clsx from 'clsx'
2
+ import type { PropsWithChildren, ReactNode } from 'react'
3
+
4
+ export type PageLayoutProps = PropsWithChildren<{
5
+ asideChild?: ReactNode
6
+ className?: string
7
+ }>
8
+ function PageLayout({ asideChild, children, className }: PageLayoutProps) {
9
+ return (
10
+ <div
11
+ className={clsx(
12
+ 'grid-areas-[main_aside] grid h-full min-h-0 w-full grid-cols-1 grid-rows-[1fr_auto]',
13
+ className
14
+ )}>
15
+ <div className='grid-area-[main] flex min-h-0 flex-col overflow-y-auto overflow-x-hidden'>
16
+ {children}
17
+ </div>
18
+ {asideChild && (
19
+ <div className='grid-area-[aside] flex-shrink-0 border-t border-t-neutral-700 px-5 py-4'>
20
+ {asideChild}
21
+ </div>
22
+ )}
23
+ </div>
24
+ )
25
+ }
26
+
27
+ export default PageLayout
@@ -4,6 +4,7 @@ import { useRefEventListener } from '@/src/lib/hooks'
4
4
  import { ChatInput, useChatInputValueAtom } from '@/src/modules/messages/components'
5
5
  import { useWidgetSettingsAtom, useWidgetTabsAtom } from '../../store'
6
6
  import { GreetingsCard } from '../greetings-card'
7
+ import { PageLayout } from '../page-layout'
7
8
 
8
9
  function WidgetStarterPage() {
9
10
  const [settings] = useWidgetSettingsAtom()
@@ -23,18 +24,18 @@ function WidgetStarterPage() {
23
24
  })
24
25
 
25
26
  return (
26
- <>
27
- <div className='flex flex-col justify-center px-5 py-4'>
28
- <GreetingsCard author={settings?.author ?? ''} tutorName={settings?.tutorName ?? ''} />
29
- </div>
30
- <div className='border-t border-t-neutral-700 px-5 py-4'>
27
+ <PageLayout
28
+ asideChild={
31
29
  <ChatInput
32
30
  name='new-chat-msg-input'
33
31
  ref={chatInputRef}
34
32
  onSend={() => setWidgetTabs('chat')}
35
33
  />
34
+ }>
35
+ <div className='flex flex-col justify-center px-5 py-4'>
36
+ <GreetingsCard author={settings?.author ?? ''} tutorName={settings?.tutorName ?? ''} />
36
37
  </div>
37
- </>
38
+ </PageLayout>
38
39
  )
39
40
  }
40
41