bibot 1.0.3 → 1.0.5

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 (95) hide show
  1. package/dist/components/bibot.js +171 -0
  2. package/dist/components/bibot.js.map +1 -0
  3. package/dist/config/appStateEnums.js +5 -10
  4. package/dist/config/endpointEnums.js +22 -27
  5. package/dist/config/index.js +5 -38
  6. package/dist/config/statusCode.js +44 -49
  7. package/dist/context/AppContext.js +56 -73
  8. package/dist/context/index.js +3 -16
  9. package/dist/hooks/index.d.ts +0 -1
  10. package/dist/hooks/index.js +4 -38
  11. package/dist/hooks/index.js.map +1 -1
  12. package/dist/hooks/mobileView.js +18 -33
  13. package/dist/hooks/usePluginFactory.js +77 -60
  14. package/dist/index.d.ts +2 -1
  15. package/dist/index.js +6 -9
  16. package/dist/index.js.map +1 -1
  17. package/dist/reducers/appReducer.js +22 -24
  18. package/dist/reducers/index.js +3 -16
  19. package/dist/services/index.js +3 -16
  20. package/dist/services/plugin-api.js +182 -179
  21. package/dist/types/coreInterfaces.d.ts +10 -1
  22. package/dist/types/coreInterfaces.js +2 -5
  23. package/dist/types/index.js +3 -16
  24. package/dist/utils/index.js +3 -27
  25. package/dist/utils/sessionManager.js +12 -16
  26. package/dist/utils/trimWhitespace.js +11 -15
  27. package/package.json +54 -50
  28. package/.babelrc +0 -7
  29. package/.vscode/settings.json +0 -5
  30. package/dist/bibot.js +0 -173
  31. package/dist/bibot.js.map +0 -1
  32. package/dist/hooks/useBiBotChatBot.d.ts +0 -29
  33. package/dist/hooks/useBiBotChatBot.js +0 -206
  34. package/dist/hooks/useBiBotChatBot.js.map +0 -1
  35. package/dist/index.css +0 -36
  36. package/dist/styles/RegisterPageStyle.css +0 -63
  37. package/dist/styles/adminPortal.css +0 -26
  38. package/dist/styles/appConfig.css +0 -90
  39. package/dist/styles/buttonStyle.css +0 -27
  40. package/dist/styles/chatStyle.css +0 -140
  41. package/dist/styles/index.css +0 -82
  42. package/dist/styles/predefinedStyle.css +0 -35
  43. package/dist/styles/themeStyle.css +0 -42
  44. package/dist/styles/training.css +0 -86
  45. package/example/README.md +0 -46
  46. package/example/package-lock.json +0 -18173
  47. package/example/package.json +0 -47
  48. package/example/public/favicon.ico +0 -0
  49. package/example/public/index.html +0 -43
  50. package/example/public/logo192.png +0 -0
  51. package/example/public/logo512.png +0 -0
  52. package/example/public/manifest.json +0 -25
  53. package/example/public/robots.txt +0 -3
  54. package/example/src/App.css +0 -38
  55. package/example/src/App.test.tsx +0 -9
  56. package/example/src/App.tsx +0 -28
  57. package/example/src/index.css +0 -13
  58. package/example/src/index.tsx +0 -13
  59. package/example/src/logo.svg +0 -1
  60. package/example/src/react-app-env.d.ts +0 -1
  61. package/example/tsconfig.json +0 -26
  62. package/src/bibot.tsx +0 -111
  63. package/src/config/appStateEnums.ts +0 -3
  64. package/src/config/endpointEnums.ts +0 -28
  65. package/src/config/index.ts +0 -5
  66. package/src/config/statusCode.ts +0 -49
  67. package/src/context/AppContext.tsx +0 -66
  68. package/src/context/index.ts +0 -3
  69. package/src/hooks/index.ts +0 -5
  70. package/src/hooks/mobileView.tsx +0 -17
  71. package/src/hooks/useBiBotChatBot.tsx +0 -107
  72. package/src/hooks/usePluginFactory.tsx +0 -38
  73. package/src/index.css +0 -36
  74. package/src/index.tsx +0 -3
  75. package/src/reducers/appReducer.ts +0 -16
  76. package/src/reducers/index.ts +0 -4
  77. package/src/services/index.ts +0 -2
  78. package/src/services/plugin-api.tsx +0 -120
  79. package/src/styles/RegisterPageStyle.css +0 -63
  80. package/src/styles/adminPortal.css +0 -26
  81. package/src/styles/appConfig.css +0 -90
  82. package/src/styles/buttonStyle.css +0 -27
  83. package/src/styles/chatStyle.css +0 -140
  84. package/src/styles/index.css +0 -82
  85. package/src/styles/predefinedStyle.css +0 -35
  86. package/src/styles/themeStyle.css +0 -42
  87. package/src/styles/training.css +0 -86
  88. package/src/types/coreInterfaces.ts +0 -69
  89. package/src/types/index.ts +0 -4
  90. package/src/utils/index.ts +0 -2
  91. package/src/utils/sessionManager.tsx +0 -15
  92. package/src/utils/trimWhitespace.ts +0 -11
  93. package/tsconfig.json +0 -25
  94. package/webpack.config.js +0 -19
  95. /package/dist/{bibot.d.ts → components/bibot.d.ts} +0 -0
@@ -1,107 +0,0 @@
1
- import { message } from 'antd'
2
- import { appStateEnums } from '../config/appStateEnums'
3
- import React, { useEffect, useRef, useState, useContext, useCallback } from 'react'
4
- import { AppContext } from '../context/AppContext'
5
-
6
- import { v4 as uuidv4 } from 'uuid'
7
- import { askBiBot, getRemoteClientChatBubbleConfig, getRemoteClientChatPredefinedQuestions } from '../services/plugin-api'
8
- interface UseBiBotChatBotProps {
9
- clientId: string
10
- }
11
-
12
- interface ChatBubbleConfigProps {
13
- bgColor?: string,
14
- color?: string,
15
- title?: string,
16
- logo_url?: string
17
- }
18
- const useBiBotChatBot = ({ clientId }: UseBiBotChatBotProps) => {
19
- const [predefinedQuestions, setPredefinedQuestions] = useState<string[]>([]) // State to store predefined questions
20
- const [showPredefinedQuestions, setShowPredefinedQuestions] = useState(true); // State to toggle predefined questions
21
- const { state, dispatch } = useContext(AppContext)
22
- const { chatIsOpen } = state
23
- const [messages, setMessages] = useState<Array<{ sender: 'user' | 'bot', text: string }>>([])
24
- const [userInput, setUserInput] = useState('')
25
- const [isLoading, setIsLoading] = useState(false)
26
- const messageEndRef = useRef<HTMLDivElement>(null)
27
- const [chatBubbleConfig, setChatBubbleConfig] = useState<ChatBubbleConfigProps>()
28
-
29
- // Function to handle selecting a predefined question
30
- const handlePredefinedQuestionSelect = (question: any) => {
31
- setUserInput(question);
32
- sendInputInquiry();
33
- setShowPredefinedQuestions(false); // Hide predefined questions after selection
34
- }
35
-
36
- const getChatBubbleConfig = useCallback(async()=>{
37
- const remotePredefinedQuestions = await getRemoteClientChatPredefinedQuestions({client_id: clientId})
38
- if (remotePredefinedQuestions){
39
- setPredefinedQuestions(remotePredefinedQuestions)
40
- }
41
- const remoteChatBubbleConfig = await getRemoteClientChatBubbleConfig({client_id: clientId})
42
- if (remoteChatBubbleConfig){
43
- setChatBubbleConfig(remoteChatBubbleConfig)
44
- }
45
- },[clientId])
46
-
47
- useEffect(()=>{
48
- void getChatBubbleConfig()
49
- }, [getChatBubbleConfig])
50
-
51
- useEffect(() => {
52
- if (messageEndRef?.current) { messageEndRef.current.scrollIntoView({ behavior: 'smooth' }) }
53
- }, [messages])
54
-
55
- const toggleChat = () => {
56
- dispatch({ type: appStateEnums.BIBOT, chatIsOpen: !chatIsOpen })
57
- }
58
-
59
- const handleUserInput = (e: React.ChangeEvent<HTMLInputElement>) => {
60
- setUserInput(e.target.value)
61
- }
62
-
63
- async function sendInputInquiry () {
64
- setIsLoading(true)
65
- setUserInput('')
66
- try {
67
- if (userInput.trim()) {
68
- // dispatch({ type: appStateEnums.BIBOT, chatIsOpen: true })
69
- setMessages(messages => [...messages, { sender: 'user', text: userInput }])
70
- const response = await askBiBot({
71
- client_id: clientId,
72
- q: userInput.trim(),
73
- session_id: state.sessionId,
74
- chat_id: uuidv4()
75
- })
76
- setMessages(messages => [...messages, { sender: 'bot', text: response }])
77
- }
78
- } catch (error: any) {
79
- void message.error(error?.message ?? 'Failed to get response from server')
80
- } finally {
81
- setIsLoading(false)
82
- }
83
- }
84
-
85
- const handleKeyPress = async (e: React.KeyboardEvent<HTMLInputElement>) => {
86
- if (e.key === 'Enter' && !isLoading) {
87
- await sendInputInquiry()
88
- }
89
- }
90
- return {
91
- chatIsOpen,
92
- messages,
93
- isLoading,
94
- messageEndRef,
95
- userInput,
96
- handleUserInput,
97
- handleKeyPress,
98
- toggleChat,
99
- sendInputInquiry,
100
- chatBubbleConfig,
101
- showPredefinedQuestions,
102
- predefinedQuestions,
103
- handlePredefinedQuestionSelect,
104
- }
105
- }
106
-
107
- export { useBiBotChatBot }
@@ -1,38 +0,0 @@
1
- import axios from 'axios';
2
- import { endpoints } from '../config/endpointEnums';
3
- import React from 'react';
4
- const inferenceBaseURL = endpoints.inference;
5
-
6
- export const createPluginAxiosInstance = (params = {}, headers = {}) => {
7
- const instance = axios.create({
8
- baseURL: inferenceBaseURL,
9
- timeout: 60000, // 1 minute
10
- headers: {
11
- 'Content-Type': 'application/json',
12
- ...headers
13
- },
14
- ...params
15
- });
16
-
17
-
18
- instance.interceptors.response.use(
19
- (response) => {
20
- return response
21
- },
22
- async (error) => {
23
- let errMsg = 'An unknown error occurred'
24
- if (error.response) {
25
- errMsg = error.response.data.message
26
- } else if (error.request) {
27
- errMsg = 'No response received from the server.'
28
- } else {
29
- errMsg = `Error setting up the request: ${error.message}`
30
- }
31
- return await Promise.reject(new Error(errMsg))
32
- }
33
- )
34
-
35
- return instance
36
- }
37
-
38
-
package/src/index.css DELETED
@@ -1,36 +0,0 @@
1
- body {
2
- margin: 0;
3
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4
- 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5
- sans-serif;
6
- -webkit-font-smoothing: antialiased;
7
- -moz-osx-font-smoothing: grayscale;
8
- }
9
-
10
-
11
- *{
12
- margin: 0;
13
- padding: 0;
14
- box-sizing: border-box;
15
- }
16
- code {
17
- font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
18
- monospace;
19
- }
20
-
21
- .upload-component {
22
- .drop-area {
23
- border: 2px dashed #ccc;
24
- border-radius: 5px;
25
- padding: 20px;
26
- text-align: center;
27
- cursor: pointer;
28
- &:hover, &:focus {
29
- border-color: #007bff;
30
- }
31
- }
32
-
33
- .uploading { background-color: #fff3cd; }
34
- .completed { background-color: #d4edda; }
35
- .error { background-color: #f8d7da; }
36
- }
package/src/index.tsx DELETED
@@ -1,3 +0,0 @@
1
- import React from 'react';
2
- import BiBot from './bibot';
3
- export default BiBot;
@@ -1,16 +0,0 @@
1
- import { appStateEnums } from '../config/appStateEnums'
2
- import type { AppStates, AppAction } from 'types'
3
- import React from 'react';
4
-
5
- export const appReducer = (state: AppStates, action: AppAction): AppStates => {
6
- console.log('This is the appReducer state', state, action)
7
- switch (action.type) {
8
- case appStateEnums.BIBOT:
9
- return {
10
- ...state,
11
- chatIsOpen: action.chatIsOpen
12
- }
13
- default:
14
- return state
15
- }
16
- }
@@ -1,4 +0,0 @@
1
- // created from 'create-ts-index'
2
-
3
- export * from './appReducer'
4
-
@@ -1,2 +0,0 @@
1
- // export * from './bibot'
2
- export * from './plugin-api'
@@ -1,120 +0,0 @@
1
- import { domain, resources } from '../config/endpointEnums'
2
- import React from 'react';
3
- // import { createPluginAxiosInstance } from '../hooks/usePluginFactory'
4
-
5
- // const pluginAxiosInstance=createPluginAxiosInstance()
6
-
7
- interface Q_DATA_TYPE {
8
- client_id: string
9
- q: string
10
- endSession?: boolean
11
- session_id: string
12
- chat_id: string
13
- tries?: number
14
- }
15
-
16
- interface RemoteChatBubbleConfigProps {
17
- bgColor: string,
18
- chatColor: string,
19
- title: string,
20
- userImage: string
21
- }
22
-
23
- async function askTimedOutBiBot(data: Q_DATA_TYPE): Promise<string> {
24
- try {
25
- return 'Hello'
26
- // const path=`${domain.bibot}${resources.timedOutLocalQ}`
27
- // const response=await pluginAxiosInstance.post<any>(path, data)
28
- // console.log(response)
29
- // return response.data.message
30
- } catch (error: any) {
31
- console.log(error.message)
32
- return error.message
33
- }
34
- }
35
-
36
- async function askBiBot(data: Q_DATA_TYPE): Promise<string> {
37
- try {
38
- // const path=`${domain.inference}${resources.q}`
39
- // const response=await pluginAxiosInstance.post<any>(path, data)
40
- // console.log(response)
41
- // return response.data.message
42
- return 'Hello'
43
- } catch (error1: any) {
44
- console.log(error1.message)
45
- if (error1.code==='ECONNABORTED'||error1.message.includes('Endpoint request timed out')) {
46
- try {
47
- return await askTimedOutBiBot({
48
- ...data,
49
- tries: 2
50
- })
51
- } catch (error2: any) {
52
- if (error2.code==='ECONNABORTED'||error2.message.includes('Endpoint request timed out')) {
53
- try {
54
- return await askTimedOutBiBot({
55
- ...data,
56
- tries: 3
57
- })
58
- } catch (error3: any) {
59
- return error3.message
60
- }
61
- } else {
62
- return error2.message
63
- }
64
- }
65
- } else {
66
- return error1.message
67
- }
68
- }
69
- }
70
- // TODO: Emmanuel fix the default returned values, especially the userImage to a default robot image
71
- async function getRemoteClientChatBubbleConfig(params: { client_id: string }): Promise<RemoteChatBubbleConfigProps> {
72
- try {
73
- return {
74
- bgColor: 'white',
75
- chatColor: 'blue',
76
- title: 'ChatBot',
77
- userImage: 'string'
78
- }
79
- // const path=`${domain.inference}${resources.chatBubble}`
80
- // const response=await pluginAxiosInstance.get<any>(path, { params })
81
- // return response.data
82
- } catch (error: any) {
83
- return {
84
- bgColor: 'white',
85
- chatColor: 'blue',
86
- title: 'ChatBot',
87
- userImage: 'string'
88
- }
89
- }
90
- }
91
-
92
- async function getRemoteClientChatPredefinedQuestions(params: { client_id: string }): Promise<string[]> {
93
- try {
94
- return ['Hello']
95
- // const path=`${domain.inference}${resources.predefinedQ}`
96
- // const response=await pluginAxiosInstance.get<any>(path, { params })
97
- // return response.data.predefined_messages
98
- } catch (error: any) {
99
- return ['These are placeholders', 'They will be removed in production', 'This will be empty if there are no predefined questions', 'So hide if there are no predefined questions']
100
- }
101
- }
102
-
103
- async function GetPredefinedQuestion (){
104
- const clientId = '6c74b4bb-0395-4751-a55f-7d065d67c56b'
105
- try {
106
- return [{question: "q", answer: "a"}]
107
- // const path = `${domain.inference}${resources.predefinedQ}?client_id=${clientId}`
108
- // const response = await pluginAxiosInstance.get(path)
109
- // return response.data
110
- } catch (error) {
111
- console.error('Error fetching subscription:', error)
112
- }
113
- }
114
-
115
- export {
116
- askBiBot,
117
- getRemoteClientChatBubbleConfig,
118
- getRemoteClientChatPredefinedQuestions,
119
- GetPredefinedQuestion
120
- }
@@ -1,63 +0,0 @@
1
-
2
- .amplify-button--primary {
3
- background-color: #0fa781;
4
- }
5
-
6
- .preAuditLogo-on-registerPage{
7
- max-height: 50px;
8
- margin-bottom: 20px;
9
- }
10
- .amplify-tabs-item[data-state=active] {
11
- color: #fff;
12
- border-color: #0fa781;
13
- }
14
- .amplify-tabs-item[data-state=active]:hover {
15
- color: #fff;
16
- }
17
-
18
- .amplify-tabs-item:hover {
19
- color: #00152a;
20
- }
21
-
22
- [data-amplify-authenticator] [data-amplify-router] {
23
- background-color: #ffffff;
24
- border-color: #b9eee1;
25
- }
26
- .amplify-tabs-item[data-spacing=equal]{
27
-
28
- }
29
- .amplify-button--link {
30
- color: #00152a;
31
- }
32
- .amplify-button--link:hover {
33
- color: #00152a;
34
- background-color: #fff;
35
- }
36
-
37
- .amplify-input, .amplify-input:focus {
38
- border-color: #bed7f0;
39
- border: 1px solid;
40
- }
41
- .fieldContainer{
42
- display: flex;
43
- justify-content: space-between;
44
- flex-direction: row;
45
- }
46
- select, .amplify-field-group__outer-end .amplify-field-group__control, .amplify-field-group__outer-start .amplify-select__wrapper:not(:first-child) .amplify-select:not(:first-child), .amplify-field-group__outer-start--quiet .amplify-field-group__control, .amplify-field-group__outer-start .amplify-field-group__control:not(:first-child), .amplify-field-group :not(:first-child) .amplify-input {
47
- border-color: #c9ebe2;
48
- }
49
- .amplify-input{
50
- border-color: #c9ebe2;
51
- }
52
-
53
- .amplify-checkbox__icon {
54
- background-color: #c9ebe2;
55
- border-color: #c9ebe2;
56
- }
57
- .input-select-field{
58
- border-color: #0fa781;
59
- }
60
- .amplify-select{
61
- border-color: #c9ebe2 !important;
62
-
63
- }
@@ -1,26 +0,0 @@
1
- .useremail{
2
- width: 70px;
3
- white-space: nowrap;
4
- overflow: hidden;
5
- text-overflow: ellipsis;
6
- margin-top: 0;
7
- }
8
-
9
- /* Media query for screens smaller than 600px */
10
- @media screen and (max-width: 600px) {
11
- .hideOnMobile{
12
- display: none !important;
13
- }
14
- }
15
-
16
- /* Media query for screens between 600px and 900px */
17
- /* @media screen and (min-width: 600px) and (max-width: 900px) {
18
- .hideProfile{
19
- display: none;
20
- }
21
- } */
22
-
23
- /* Media query for screens larger than 1200px */
24
- @media screen and (min-width: 1200px) {
25
-
26
- }
@@ -1,90 +0,0 @@
1
- .mainContent{
2
- display: flex;
3
- width: 100%;
4
- justify-content: space-around;
5
- flex-wrap: wrap;
6
- }
7
- .firstSection{
8
- text-align: start;
9
- }
10
- .secondSection{
11
- display: flex;
12
- align-items: center;
13
- justify-content: center;
14
- }
15
- .previewSection{
16
- height: 100%;
17
- }
18
- input[type="file"] {
19
- display: none;
20
- }
21
- .inputfileButton{
22
- display: inline-block;
23
- align-items: center;
24
- /* background-color: #73767a; */
25
- border: none;
26
- border-radius: 5px;
27
- cursor: pointer;
28
- }
29
-
30
-
31
- /* Media query for screens smaller than 600px */
32
- @media screen and (max-width: 600px) {
33
- .mainContent{
34
- display: flex;
35
- width: 100%;
36
- flex-direction: column;
37
- justify-content: space-around;
38
- align-items: center;
39
- }
40
- .button{
41
- width: 100% !important;
42
- }
43
- .previewSection{
44
- width: 100%;
45
- margin-top: 30px;
46
- }
47
- .firstSection{
48
- width: 100%;
49
- text-align: start;
50
- margin-bottom: 50px;
51
- }
52
- .secondSection{
53
- width: 100%;
54
- display: flex;
55
- align-items: center;
56
- justify-content: center;
57
- text-align: start;
58
- }
59
- }
60
-
61
- /* Media query for screens between 600px and 900px */
62
- @media screen and (min-width: 600px) and (max-width: 900px) {
63
- .mainContent{
64
- display: flex;
65
- width: 100%;
66
- flex-direction: column;
67
- justify-content: space-around;
68
- align-items: center;
69
- }
70
- .previewSection{
71
- width: 100%;
72
- }
73
- .firstSection{
74
- width: 100%;
75
- text-align: start;
76
- margin-bottom: 50px;
77
- }
78
- .secondSection{
79
- width: 100%;
80
- display: flex;
81
- align-items: center;
82
- justify-content: center;
83
- text-align: start;
84
- }
85
- }
86
-
87
- /* Media query for screens larger than 1200px */
88
- @media screen and (min-width: 1200px) {
89
-
90
- }
@@ -1,27 +0,0 @@
1
- .button,
2
- .ant-btn.button {
3
- font-family: Arial, sans-serif;
4
- font-size: 14px;
5
- display: flex;
6
- justify-content: center;
7
- align-items: center;
8
- border-radius: 10px;
9
- border: 2px solid #d67632;
10
- outline: none;
11
- cursor: pointer;
12
- transition: background-color 0.3s, color 0.3s;
13
- background-color: #5f2d78;
14
- color: white;
15
- }
16
-
17
- .ant-popover-buttons {
18
- display: flex;
19
- justify-content: flex-end;
20
- background-color: #5f2d78;
21
- color: white
22
- }
23
-
24
- .ant-popover-button {
25
- margin: 8px;
26
- }
27
-
@@ -1,140 +0,0 @@
1
- .chat-bubble {
2
- position: fixed;
3
- bottom: 20px;
4
- right: 20px;
5
- z-index: 9999;
6
- }
7
-
8
- .chat-toggle {
9
- color: #fff;
10
- border-radius: 50%;
11
- height: 60px;
12
- width: 60px;
13
- display: flex;
14
- align-items: center;
15
- justify-content: center;
16
- }
17
-
18
- .chat-window {
19
- position: absolute;
20
- bottom: 50px;
21
- right: 25px;
22
- width: 350px;
23
- height: 500px;
24
- background-color: white;
25
- border: 1px solid #ddd;
26
- border-radius: 10px;
27
- /* padding: 10px; */
28
- box-shadow: 0 2px 10px rgba(0,0,0,0.2);
29
- display: flex;
30
- flex-direction: column;
31
- justify-content: space-between;
32
- }
33
-
34
- /* Existing styles... */
35
- .chat-header{
36
- height: 50px;
37
- border-top-left-radius: 8px;
38
- border-top-right-radius: 8px;
39
- display: flex;
40
- align-items: center;
41
- justify-content: flex-start;
42
- padding-inline: 15px;
43
- padding-block: 30px;
44
- }
45
- .message-list {
46
- height: calc(100% - 100px);
47
- overflow-y: auto;
48
- padding: 10px;
49
- display: flex;
50
- flex-grow: 1;
51
- flex-direction: column;
52
- }
53
-
54
- .message {
55
- margin-bottom: 10px;
56
- padding: 5px 10px;
57
- border-radius: 8px;
58
- max-width: 70%;
59
- }
60
-
61
- .message.user {
62
- background-color: #b8b8b8c6;
63
- align-self: flex-end;
64
- }
65
-
66
- .message.bot {
67
- background-color: #f0f0f0;
68
- align-self: flex-start;
69
- }
70
- textarea:focus, input:focus{
71
- outline: none;
72
- }
73
-
74
- /* Chat loader*/
75
- .loader {
76
- width: 12px;
77
- aspect-ratio: 1;
78
- border-radius: 50%;
79
- animation: l5 1s infinite linear alternate;
80
- }
81
- @keyframes l5 {
82
- 0% {box-shadow: 20px 0 #000, -20px 0 #0002;background: #000 }
83
- 33% {box-shadow: 20px 0 #000, -20px 0 #0002;background: #0002}
84
- 66% {box-shadow: 20px 0 #0002,-20px 0 #000; background: #0002}
85
- 100%{box-shadow: 20px 0 #0002,-20px 0 #000; background: #000 }
86
- }
87
-
88
-
89
- .input-area {
90
- display: flex;
91
- align-items: center;
92
- border-top: 1px solid #ddd;
93
- padding: 10px;
94
- border-bottom-left-radius: 8px;
95
- border-bottom-right-radius: 8px;
96
- }
97
-
98
- .input-area input {
99
- flex-grow: 1;
100
- border: none;
101
- background-color: transparent;
102
- /* border: 1px solid #ccc; */
103
- /* border-radius: 15px; */
104
- padding: 5px 10px;
105
- margin-right: 10px;
106
- }
107
-
108
- .input-area button {
109
- background-color: #007bff;
110
- color: white;
111
- border: none;
112
- border-radius: 15px;
113
- padding: 5px 10px;
114
- cursor: pointer;
115
- }
116
-
117
- /* Existing styles... */
118
-
119
- .loading-bubbles {
120
- display: flex;
121
- justify-content: center;
122
- align-items: center;
123
- }
124
-
125
- .bubble {
126
- width: 8px;
127
- height: 8px;
128
- border-radius: 50%;
129
- margin: 0 3px;
130
- animation: bounce 0.6s infinite alternate;
131
- }
132
-
133
- @keyframes bounce {
134
- from {
135
- transform: translateY(0);
136
- }
137
- to {
138
- transform: translateY(-15px);
139
- }
140
- }