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 +2 -0
- package/package.json +1 -1
- package/public/index.html +1 -1
- package/src/development-bootstrap.tsx +1 -1
- package/src/lib/hooks/use-ref-client-height/use-ref-client-height.tsx +5 -5
- package/src/modules/messages/components/messages-list/messages-list.tsx +1 -8
- package/src/modules/widget/components/chat-page/chat-page.tsx +6 -6
- package/src/modules/widget/components/container/container.tsx +2 -4
- package/src/modules/widget/components/index.ts +1 -0
- package/src/modules/widget/components/onboarding-page/onboarding-page.tsx +4 -3
- package/src/modules/widget/components/page-layout/index.ts +2 -0
- package/src/modules/widget/components/page-layout/page-layout.tsx +27 -0
- package/src/modules/widget/components/starter-page/starter-page.tsx +7 -6
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
package/public/index.html
CHANGED
|
@@ -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('
|
|
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 =
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
11
|
-
|
|
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
|
}
|
|
@@ -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,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
|
-
|
|
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
|
|