app-tutor-ai-consumer 1.4.0 → 1.5.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 (77) hide show
  1. package/.github/workflows/staging-staging.yml +148 -0
  2. package/.github/workflows/staging.yml +1 -2
  3. package/CHANGELOG.md +13 -0
  4. package/config/rspack/rspack.config.js +5 -1
  5. package/config/vitest/__mocks__/icons.tsx +3 -0
  6. package/config/vitest/__mocks__/intersection-observer.ts +10 -0
  7. package/config/vitest/__mocks__/sparkie.tsx +2 -11
  8. package/config/vitest/__mocks__/use-init-sparkie.tsx +14 -0
  9. package/config/vitest/vitest.config.mts +13 -8
  10. package/environments/.env.test +2 -0
  11. package/package.json +3 -3
  12. package/public/index.html +3 -4
  13. package/src/config/styles/global.css +2 -2
  14. package/src/config/tanstack/query-client.ts +2 -1
  15. package/src/config/tests/utils.tsx +3 -2
  16. package/src/config/tests/wrappers.tsx +4 -1
  17. package/src/index.tsx +22 -0
  18. package/src/lib/components/icons/arrow-down.svg +5 -0
  19. package/src/lib/components/icons/chevron-down.svg +4 -0
  20. package/src/lib/components/icons/icon-names.d.ts +1 -1
  21. package/src/lib/components/markdownrenderer/markdownrenderer.tsx +7 -9
  22. package/src/lib/hooks/index.ts +3 -0
  23. package/src/lib/hooks/use-intersection-observer-reverse-scroll/index.ts +2 -0
  24. package/src/lib/hooks/use-intersection-observer-reverse-scroll/use-intersection-observer-reverse-scroll.tsx +147 -0
  25. package/src/lib/hooks/use-ref-client-height/index.ts +2 -0
  26. package/src/lib/hooks/use-ref-client-height/use-ref-client-height.tsx +38 -0
  27. package/src/lib/hooks/use-scroll-to-ref/index.ts +2 -0
  28. package/src/lib/hooks/use-scroll-to-ref/use-scroll-to-ref.tsx +14 -0
  29. package/src/lib/hooks/use-throttle/index.ts +3 -0
  30. package/src/lib/hooks/use-throttle/types.ts +13 -0
  31. package/src/lib/hooks/use-throttle/use-throttle.spec.tsx +296 -0
  32. package/src/lib/hooks/use-throttle/use-throttle.tsx +91 -0
  33. package/src/main/main.spec.tsx +9 -0
  34. package/src/modules/cursor/__tests__/icursor-update.builder.ts +42 -0
  35. package/src/modules/cursor/hooks/index.ts +1 -0
  36. package/src/modules/cursor/hooks/use-update-cursor/index.ts +2 -0
  37. package/src/modules/cursor/hooks/use-update-cursor/use-update-cursor.spec.tsx +23 -0
  38. package/src/modules/cursor/hooks/use-update-cursor/use-update-cursor.ts +11 -0
  39. package/src/modules/cursor/index.ts +2 -0
  40. package/src/modules/cursor/service.ts +15 -0
  41. package/src/modules/cursor/types.ts +9 -0
  42. package/src/modules/global-providers/index.ts +1 -0
  43. package/src/modules/messages/__tests__/parsed-message.builder.ts +164 -0
  44. package/src/modules/messages/components/message-item/message-item.spec.tsx +2 -2
  45. package/src/modules/messages/components/message-item/message-item.tsx +14 -1
  46. package/src/modules/messages/components/message-item-end-of-scroll/index.ts +2 -0
  47. package/src/modules/messages/components/message-item-end-of-scroll/message-item-end-of-scroll.tsx +14 -0
  48. package/src/modules/messages/components/message-item-error/index.ts +2 -0
  49. package/src/modules/messages/components/message-item-error/message-item-error.tsx +25 -0
  50. package/src/modules/messages/components/message-item-loading/index.ts +2 -0
  51. package/src/modules/messages/components/message-item-loading/message-item-loading.tsx +16 -0
  52. package/src/modules/messages/components/messages-list/index.ts +1 -1
  53. package/src/modules/messages/components/messages-list/messages-list.tsx +69 -39
  54. package/src/modules/messages/constants.ts +1 -0
  55. package/src/modules/messages/hooks/index.ts +3 -0
  56. package/src/modules/messages/hooks/use-all-messages/index.ts +2 -0
  57. package/src/modules/messages/hooks/use-all-messages/use-all-messages.tsx +30 -0
  58. package/src/modules/messages/hooks/use-infinite-get-messages/index.ts +2 -0
  59. package/src/modules/messages/hooks/use-infinite-get-messages/use-infinite-get-messages.spec.tsx +58 -0
  60. package/src/modules/messages/hooks/use-infinite-get-messages/use-infinite-get-messages.tsx +97 -0
  61. package/src/modules/messages/hooks/use-manage-scroll/index.ts +2 -0
  62. package/src/modules/messages/hooks/use-manage-scroll/use-manage-scroll.tsx +66 -0
  63. package/src/modules/messages/utils/has-to-update-cursor/has-to-update-cursor.spec.tsx +58 -0
  64. package/src/modules/messages/utils/has-to-update-cursor/has-to-update-cursor.ts +30 -0
  65. package/src/modules/messages/utils/has-to-update-cursor/index.ts +2 -0
  66. package/src/modules/sparkie/__tests__/sparkie.mock.ts +33 -0
  67. package/src/modules/widget/__tests__/widget-settings-props.builder.ts +6 -0
  68. package/src/modules/widget/components/chat-page/chat-page.spec.tsx +28 -0
  69. package/src/modules/widget/components/chat-page/chat-page.tsx +1 -3
  70. package/src/modules/widget/components/container/container.tsx +20 -14
  71. package/src/modules/widget/components/index.ts +1 -0
  72. package/src/modules/widget/components/scroll-to-bottom-button/index.ts +2 -0
  73. package/src/modules/widget/components/scroll-to-bottom-button/scroll-to-bottom-button.tsx +32 -0
  74. package/src/modules/widget/events.ts +4 -0
  75. package/src/modules/widget/hooks/use-init-sparkie/use-init-sparkie.tsx +8 -6
  76. package/src/modules/widget/store/index.ts +1 -0
  77. package/src/modules/widget/store/widget-container-intrinsic-height.atom.ts +13 -0
@@ -0,0 +1,148 @@
1
+ name: Deploy Staging (staging branch)
2
+ run-name: "Staging deployment: ${{ github.ref_type }} ${{ github.ref_name }} by @${{ github.actor }}"
3
+
4
+ concurrency: staging-${{ github.ref }}
5
+
6
+ on:
7
+ push:
8
+ branches:
9
+ - staging/**
10
+
11
+ env:
12
+ APP_NAME: app-tutor-ai-consumer
13
+ BUCKET_NAME: app-club-microfrontends
14
+ AWS_DEFAULT_REGION: us-east-1
15
+ CLOUDFRONT_ACCOUNT_ID: "449466460580"
16
+ CLOUDFRONT_DISTRIBUTION: "E19SXB8YMSF4QX"
17
+ CLOUDFRONT_URL: https://app-club-microfrontends.buildstaging.com
18
+ GH_TOKEN: ${{ secrets.CI_GH_TOKEN }}
19
+ SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
20
+ LANG_ENV: staging
21
+
22
+ jobs:
23
+ deploy-staging:
24
+ name: Deploy Staging
25
+ runs-on: [buildstaging-high-iac]
26
+ steps:
27
+ - name: Checkout
28
+ uses: actions/checkout@v4
29
+ with:
30
+ token: ${{ secrets.CI_GH_TOKEN }}
31
+ fetch-depth: 0
32
+ ref: ${{ env.BRANCH_REF }}
33
+ fetch-tags: true
34
+
35
+ - name: Restore Cache
36
+ uses: Hotmart-Org/actions/cache@master
37
+ with:
38
+ bucket: buildstaging-pipeline-cache
39
+ cache-key: "${{ hashFiles('package.json') }}"
40
+ restore: true
41
+ mount: 'node_modules/'
42
+
43
+ - name: Setup Node.js
44
+ uses: actions/setup-node@v4
45
+ with:
46
+ node-version-file: '.nvmrc'
47
+
48
+ - name: Retrieve .npmrc
49
+ uses: Hotmart-Org/actions/codeartifact@master
50
+ with:
51
+ npmrc: ${{ secrets.NPM_RC }}
52
+ fontawesome-registry-token: ${{ secrets.FONTAWESOME_REGISTRY_TOKEN }}
53
+
54
+ - name: install-dependencies
55
+ run: npm ci --include=optional
56
+
57
+ - name: Rebuild Cache
58
+ uses: Hotmart-Org/actions/cache@master
59
+ with:
60
+ bucket: buildstaging-pipeline-cache
61
+ cache-key: "${{ hashFiles('package.json') }}"
62
+ rebuild: true
63
+ mount: 'node_modules/'
64
+
65
+ - name: pre-build-staging
66
+ run: |
67
+ echo "${{ env.LANG_ENV }}"
68
+ rm -rf public/locales
69
+ mkdir public/locales
70
+ npm run fetch-langs
71
+
72
+ - name: build-staging
73
+ run: npm run build:staging
74
+
75
+ - name: Deploy Microfrontend s3 - ${{ env.APP_NAME }}
76
+ uses: Hotmart-Org/actions/s3/microfrontend/deploy@master
77
+ with:
78
+ bucket-name: ${{ env.BUCKET_NAME }}
79
+ app-name: ${{ env.APP_NAME }}
80
+ package-json-path: ./package.json
81
+ bundle-source: ./dist
82
+ account-id: ${{ env.CLOUDFRONT_ACCOUNT_ID }}
83
+ cdn-distribution: ${{ env.CLOUDFRONT_DISTRIBUTION }}
84
+ cdn-url: ${{ env.CLOUDFRONT_URL }}
85
+
86
+ staging-notification:
87
+ name: 'Staging Notification'
88
+ runs-on: [buildstaging-iac]
89
+ needs: ['deploy-staging']
90
+ steps:
91
+ - name: Checkout
92
+ uses: actions/checkout@v4
93
+
94
+ - name: Extract version from package.json
95
+ run: |
96
+ VERSION=$(cat package.json | jq -r .version)
97
+ echo "Extracted version: $VERSION"
98
+ echo "VERSION=$VERSION" >> $GITHUB_ENV
99
+
100
+ - name: Notify Google Chat
101
+ uses: Hotmart-Org/actions/notification@master
102
+ env:
103
+ VERSION: ${{ env.VERSION }}
104
+ with:
105
+ type: 'Original'
106
+ author: true
107
+ webhook-chat: 'https://chat.googleapis.com/v1/spaces/AAAA1nvOyjo/messages?key=AIzaSyDdI0hCZtE6vySjMm-WEfRq3CPzqKqqsHI&token=uuL7DA8zTxUkJjQa39HIM0TYVZV0DvneZ0mklNhEr5M'
108
+ body: |
109
+ {
110
+ "text": "🚧 *[STAGING] app-tutor-ai-consumer v${{ env.VERSION }}*: staging deploy: ${{ github.ref_name }}",
111
+ "cards": [
112
+ {
113
+ "header": {
114
+ "title": "Started by ${{ github.actor }}"
115
+ },
116
+ "sections": [
117
+ {
118
+ "widgets": [
119
+ {
120
+ "buttons": [
121
+ {
122
+ "textButton": {
123
+ "onClick": {
124
+ "openLink": {
125
+ "url": "${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}"
126
+ }
127
+ },
128
+ "text": "View commit"
129
+ }
130
+ },
131
+ {
132
+ "textButton": {
133
+ "onClick": {
134
+ "openLink": {
135
+ "url": "https://github.com/Hotmart-Org/app-tutor-ai-consumer/actions/runs/${{ github.run_id }}"
136
+ }
137
+ },
138
+ "text": "Follow this deploy"
139
+ }
140
+ }
141
+ ]
142
+ }
143
+ ]
144
+ }
145
+ ]
146
+ }
147
+ ]
148
+ }
@@ -5,7 +5,6 @@ on:
5
5
  push:
6
6
  branches:
7
7
  - main
8
- - staging/*
9
8
 
10
9
  concurrency: staging
11
10
 
@@ -141,7 +140,7 @@ jobs:
141
140
  uses: newrelic/deployment-marker-action@v2.5.1
142
141
  env:
143
142
  VERSION: ${{ env.VERSION }}
144
- NEW_RELIC_API_KEY: NRAK-14TLYFWRA5RCKUGK4A3TJSAPU78
143
+ NEW_RELIC_API_KEY: ${{ secrets.NEW_RELIC_API_KEY }}
145
144
  NEW_RELIC_DEPLOYMENT_ENTITY_GUID: Mjc1MDN8QVBNfEFQUExJQ0FUSU9OfDEwOTE1MDMzMTE
146
145
  with:
147
146
  apiKey: ${{ env.NEW_RELIC_API_KEY }}
package/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ # [1.5.0](https://github.com/Hotmart-Org/app-tutor-ai-consumer/compare/v1.4.0...v1.5.0) (2025-07-10)
2
+
3
+ ### Bug Fixes
4
+
5
+ - scrolling PR issues ([d2a8faa](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/d2a8faac05c79d1b18f793981d69036687fefa0e))
6
+
7
+ ### Features
8
+
9
+ - add infinite scroll UI ([8c86dd8](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/8c86dd8043d0f10e8deae787e6f8870555f5c5f2))
10
+ - adding specific pipiline to staging branch ([bee74d3](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/bee74d37721e8900163409b5cd493a213c92fa8d))
11
+ - adding styles ([2a33e03](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/2a33e035f1e4b146cc7b03ba9f201a2f494bc31b))
12
+ - adding styles file ([ef4d4ec](https://github.com/Hotmart-Org/app-tutor-ai-consumer/commit/ef4d4ec50c010f39dfba154b084cbe0dc9ece05b))
13
+
1
14
  # [1.4.0](https://github.com/Hotmart-Org/app-tutor-ai-consumer/compare/v1.3.0...v1.4.0) (2025-06-26)
2
15
 
3
16
  ### Bug Fixes
@@ -46,7 +46,7 @@ module.exports = async function (env) {
46
46
  path: paths.DIST,
47
47
  publicPath: bundlePath,
48
48
  pathinfo: !productionMode,
49
- filename: `[name].[fullhash].${fileVersion}.js`,
49
+ filename: `remoteEntry.js`,
50
50
  chunkFilename: `[name].[fullhash].chunk.${fileVersion}.js`,
51
51
  sourceMapFilename: `[name].[fullhash].${fileVersion}.js.map`,
52
52
  clean: true
@@ -166,6 +166,10 @@ module.exports = async function (env) {
166
166
  new rspack.HtmlRspackPlugin({
167
167
  template: path.resolve(paths.PUBLIC, 'index.html'),
168
168
  favicon: path.resolve(paths.PUBLIC, 'favicon.ico')
169
+ }),
170
+ new rspack.CssExtractRspackPlugin({
171
+ filename: productionMode ? `app-tutor-ai-consumer.css` : '[name].[contenthash].css',
172
+ chunkFilename: productionMode ? '[id].[contenthash].css' : '[id].[contenthash].css'
169
173
  })
170
174
  ].concat(await getEnvironmentPlugins(!productionMode)),
171
175
  watchOptions: {
@@ -0,0 +1,3 @@
1
+ vi.mock('@/src/lib/components/icons', () => ({
2
+ Icon: vi.fn(({ name }) => <div data-test='lazy-icon'>{name}</div>)
3
+ }))
@@ -0,0 +1,10 @@
1
+ beforeEach(() => {
2
+ const mockIntersectionObserver = vi.fn()
3
+ mockIntersectionObserver.mockReturnValue({
4
+ observe: () => null,
5
+ unobserve: () => null,
6
+ disconnect: () => null
7
+ })
8
+
9
+ window.IntersectionObserver = mockIntersectionObserver
10
+ })
@@ -1,12 +1,3 @@
1
- vi.mock('@hotmart/sparkie', () => {
2
- const Sparkie = vi.fn()
1
+ import SparkieMock from '@/src/modules/sparkie/__tests__/sparkie.mock'
3
2
 
4
- Sparkie.prototype.destroy = vi.fn()
5
- Sparkie.prototype.init = vi.fn()
6
- Sparkie.prototype.off = vi.fn()
7
- Sparkie.prototype.on = vi.fn()
8
- Sparkie.prototype.listener = { trackTyping: vi.fn() }
9
- Sparkie.prototype.setAPIToken = vi.fn()
10
-
11
- return { default: Sparkie }
12
- })
3
+ vi.mock('@hotmart/sparkie', () => ({ default: SparkieMock }))
@@ -0,0 +1,14 @@
1
+ import { useInitSparkie } from '@/src/modules/widget/hooks/use-init-sparkie'
2
+
3
+ vi.mock('@/src/modules/widget/hooks/use-init-sparkie/use-init-sparkie', () => ({
4
+ useInitSparkie: vi.fn()
5
+ }))
6
+
7
+ beforeEach(() => {
8
+ vi.mocked(useInitSparkie).mockReturnValue({
9
+ data: true,
10
+ isError: false,
11
+ isLoading: false,
12
+ refetch: vi.fn()
13
+ } as unknown as ReturnType<typeof useInitSparkie>)
14
+ })
@@ -12,7 +12,10 @@ export default defineConfig({
12
12
  './config/vitest/setupTests.ts',
13
13
  './config/vitest/__mocks__/i18n.tsx',
14
14
  './config/vitest/__mocks__/sparkie.tsx',
15
- './config/vitest/polyfills/global.js',
15
+ './config/vitest/__mocks__/icons.tsx',
16
+ './config/vitest/__mocks__/intersection-observer.ts',
17
+ './config/vitest/__mocks__/use-init-sparkie.tsx',
18
+ './config/vitest/polyfills/global.js'
16
19
  ],
17
20
  coverage: {
18
21
  include: ['src/**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
@@ -28,7 +31,7 @@ export default defineConfig({
28
31
  'src/**/*.builder.ts*',
29
32
  'src/app-injector.tsx',
30
33
  'src/bootstrap.tsx',
31
- 'src/index.ts',
34
+ 'src/index.ts'
32
35
  ],
33
36
  reporter: ['text', 'html'],
34
37
  provider: 'istanbul',
@@ -36,13 +39,15 @@ export default defineConfig({
36
39
  branches: 3,
37
40
  lines: 3,
38
41
  functions: 3,
39
- statements: 3,
40
- },
42
+ statements: 3
43
+ }
41
44
  },
45
+ testTimeout: 10000,
46
+ hookTimeout: 10000,
42
47
  env: {
43
48
  ...config({
44
- path: './environments/.env.test',
45
- }).parsed,
46
- },
47
- },
49
+ path: './environments/.env.test'
50
+ }).parsed
51
+ }
52
+ }
48
53
  })
@@ -39,3 +39,5 @@ AUTH_CLIENT_SECRET=
39
39
 
40
40
  # BUNDLE
41
41
  BUNDLE_PATH=
42
+
43
+ VITE_REACT_QUERY_EXPERIMENTAL_PREFETCH_IN_RENDER=true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "app-tutor-ai-consumer",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "dev": "rspack serve --env=development --config config/rspack/rspack.config.js",
@@ -8,9 +8,9 @@
8
8
  "generate-icon-types": "ts-node scripts/generate-icon-types.js",
9
9
  "postgenerate-icon-types": "npm run format",
10
10
  "prebuild": "npm run generate-icon-types",
11
- "build": "rspack build --mode=production --env=production --config config/rspack/rspack.config.js",
11
+ "build": "NODE_ENV=production rspack build --mode=production --env=production --config config/rspack/rspack.config.js",
12
12
  "prebuild:staging": "npm run generate-icon-types",
13
- "build:staging": "rspack build --mode=production --env=staging --config config/rspack/rspack.config.js",
13
+ "build:staging": "NODE_ENV=staging rspack build --mode=production --env=staging --config config/rspack/rspack.config.js",
14
14
  "prebuild:start": "npm run build",
15
15
  "build:start": "NODE_ENV=production rspack preview --config config/rspack/rspack.config.js --port 4200",
16
16
  "test": "vitest --config config/vitest/vitest.config.mts",
package/public/index.html CHANGED
@@ -6,13 +6,12 @@
6
6
  <link rel="preconnect" href="https://fonts.googleapis.com" />
7
7
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
8
8
  <link
9
- href="https://fonts.googleapis.com/css?family=Nunito:400,700"
10
- rel="stylesheet"
11
- />
9
+ href="https://fonts.googleapis.com/css?family=Nunito:400,700&display=swap"
10
+ rel="stylesheet" />
12
11
  <title>App Tutor AI Consumer</title>
13
12
  </head>
14
13
 
15
- <body>
14
+ <body class="bg-ai-dark">
16
15
  <div id="root"></div>
17
16
  </body>
18
17
  </html>
@@ -75,8 +75,8 @@
75
75
  --hc-color-neutral-1000: #000000;
76
76
  --ai-color-primary: #a095ec;
77
77
  --ai-color-secondary: #6ba1f0;
78
- --ai-color-dark: #111925;
79
- --ai-color-chat-response: #26202f;
78
+ --ai-color-dark: #1a1c1f;
79
+ --ai-color-chat-response: #1e1926;
80
80
 
81
81
  /* Size */
82
82
  --hc-size-spacing-2: 0.5rem;
@@ -21,7 +21,8 @@ export const queryClient = new QueryClient({
21
21
  (statusCode < HttpCodes.BAD_REQUEST || statusCode >= HttpCodes.INTERNAL_SERVER_ERROR) &&
22
22
  failureCount <= maxRetries
23
23
  )
24
- }
24
+ },
25
+ retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000)
25
26
  }
26
27
  }
27
28
  })
@@ -11,13 +11,14 @@ import MockRequest from './mockRequest'
11
11
 
12
12
  const customRender = (
13
13
  ui: React.ReactElement,
14
- { shallow, withQueryProvider = true, ...options }: IExtendedRenderOptions = {}
14
+ { shallow, withQueryProvider = true, withProvider, ...options }: IExtendedRenderOptions = {}
15
15
  ) => ({
16
16
  user: userEvent.setup(),
17
17
  ...render(
18
18
  setupComponents(ui, {
19
19
  shallow,
20
- withQueryProvider
20
+ withQueryProvider,
21
+ withProvider
21
22
  }),
22
23
  options
23
24
  )
@@ -7,7 +7,10 @@ export const testQueryClient = new QueryClient({
7
7
  defaultOptions: {
8
8
  queries: {
9
9
  retry: false,
10
- refetchOnWindowFocus: false
10
+ gcTime: 0,
11
+ staleTime: 0,
12
+ refetchOnWindowFocus: false,
13
+ experimental_prefetchInRender: true
11
14
  },
12
15
  mutations: {
13
16
  retry: false
package/src/index.tsx CHANGED
@@ -1,17 +1,39 @@
1
+ import './config/styles/global.css'
2
+ import './config/styles/index.css'
3
+
1
4
  import { StrictMode } from 'react'
2
5
  import { createRoot } from 'react-dom/client'
3
6
 
4
7
  import { initDayjs } from './config/dayjs'
5
8
  import { initLanguage } from './config/i18n'
6
9
  import { initAxios } from './config/request/api'
10
+ import { productionMode } from './lib/utils'
7
11
  import { Main } from './main'
8
12
  import { TutorWidgetEvents, TutorWidgetEventTypes } from './modules/widget'
9
13
  import type { StartTutorWidgetProps } from './types'
10
14
 
15
+ const loadMainStyles = () => {
16
+ const isProduction = productionMode
17
+ const bundlePath = !isProduction
18
+ ? `${process.env.BUNDLE_PATH}/`
19
+ : `${process.env.BUNDLE_PATH}/${process.env.APP_NAME}/_current/`
20
+
21
+ const cssPath = `${bundlePath}app-tutor-ai-consumer.css`
22
+
23
+ if (!document.querySelector(`link[href="${cssPath}"]`)) {
24
+ const linkElement = document.createElement('link')
25
+ linkElement.rel = 'stylesheet'
26
+ linkElement.href = cssPath
27
+ document.head.appendChild(linkElement)
28
+ }
29
+ }
30
+
11
31
  window.startTutorWidget = async ({
12
32
  elementId = 'tutor-chat-app-widget',
13
33
  settings
14
34
  }: StartTutorWidgetProps) => {
35
+ loadMainStyles()
36
+
15
37
  const rootElement = document.getElementById(elementId) as HTMLElement
16
38
  const root = createRoot(rootElement)
17
39
 
@@ -0,0 +1,5 @@
1
+ <svg viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path
3
+ d="M13.9748 9.83038L8.47139 15.0179C8.37759 15.1116 8.25251 15.1429 8.1587 15.1429C8.03362 15.1429 7.90855 15.1116 7.81474 15.0179L2.31136 9.83038C2.09248 9.64288 2.09248 9.33038 2.28009 9.11163C2.46771 8.89288 2.7804 8.89288 2.96802 9.08038L7.65839 13.4554L7.65839 1.67413C7.65839 1.39288 7.87728 1.14288 8.12743 1.14288C8.37759 1.14288 8.65901 1.39288 8.65901 1.67413L8.65901 13.4554L13.3181 9.08038C13.5057 8.89288 13.8184 8.89288 14.006 9.11163C14.1937 9.33038 14.1937 9.64288 13.9748 9.83038Z"
4
+ fill="currentColor" />
5
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
2
+ stroke="currentColor">
3
+ <path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
4
+ </svg>
@@ -1,2 +1,2 @@
1
1
  // Auto-generated file - DO NOT EDIT
2
- export type ValidIconNames = 'send'
2
+ export type ValidIconNames = 'arrow-down' | 'chevron-down' | 'send'
@@ -28,9 +28,7 @@ const mdComponents: Partial<Components> = {
28
28
  return <MdCodeBlock {...props} />
29
29
  },
30
30
  pre({ children }) {
31
- return (
32
- <span className='my-2 inline-block w-full overflow-hidden rounded-lg border'>{children}</span>
33
- )
31
+ return <span className='my-2 inline-block w-full overflow-hidden rounded-lg'>{children}</span>
34
32
  },
35
33
  a({ href, children, ...props }) {
36
34
  const url = URLutils.getURLwithProtocol(href)
@@ -40,7 +38,7 @@ const mdComponents: Partial<Components> = {
40
38
  href={url}
41
39
  target={url?.startsWith('http') ? '_blank' : '_self'}
42
40
  rel={url?.startsWith('http') ? 'noopener noreferrer' : undefined}
43
- className='text-blue-600 underline hover:text-blue-800'
41
+ className='inline-block break-all text-blue-600 underline hover:text-blue-800'
44
42
  {...props}>
45
43
  {children}
46
44
  </a>
@@ -49,7 +47,7 @@ const mdComponents: Partial<Components> = {
49
47
  table({ children, ...props }) {
50
48
  return (
51
49
  <div className='overflow-x-auto'>
52
- <table className='min-w-full border-collapse border border-neutral-300' {...props}>
50
+ <table className='min-w-full border-collapse border border-neutral-800' {...props}>
53
51
  {children}
54
52
  </table>
55
53
  </div>
@@ -57,14 +55,14 @@ const mdComponents: Partial<Components> = {
57
55
  },
58
56
  th({ children, ...props }) {
59
57
  return (
60
- <th className='border border-neutral-300 px-4 py-2 text-left font-semibold' {...props}>
58
+ <th className='border border-neutral-800 px-4 py-2 text-left font-semibold' {...props}>
61
59
  {children}
62
60
  </th>
63
61
  )
64
62
  },
65
63
  td({ children, ...props }) {
66
64
  return (
67
- <td className='border border-neutral-300 px-4 py-2' {...props}>
65
+ <td className='border border-neutral-800 px-4 py-2' {...props}>
68
66
  {children}
69
67
  </td>
70
68
  )
@@ -72,14 +70,14 @@ const mdComponents: Partial<Components> = {
72
70
  blockquote({ children, ...props }) {
73
71
  return (
74
72
  <blockquote
75
- className='my-2 border-l-4 border-blue-500 pl-4 italic text-neutral-100'
73
+ className='my-2 border-l-4 border-primary-500 pl-4 italic text-neutral-100'
76
74
  {...props}>
77
75
  {children}
78
76
  </blockquote>
79
77
  )
80
78
  },
81
79
  p({ children }) {
82
- return <span className='my-2 inline-block'>{children}</span>
80
+ return <span className='my-3 inline-block'>{children}</span>
83
81
  }
84
82
  }
85
83
 
@@ -1,2 +1,5 @@
1
1
  export * from './use-default-id'
2
+ export * from './use-intersection-observer-reverse-scroll'
3
+ export * from './use-ref-client-height'
2
4
  export * from './use-ref-event-listener'
5
+ export * from './use-throttle'
@@ -0,0 +1,2 @@
1
+ export * from './use-intersection-observer-reverse-scroll'
2
+ export { default as useIntersectionObserverReverseScroll } from './use-intersection-observer-reverse-scroll'