bibot 1.0.5 → 1.0.7
Sign up to get free protection for your applications and to get access to all the features.
- package/.babelrc +7 -0
- package/.vscode/settings.json +5 -0
- package/dist/bibot.js +175 -0
- package/dist/bibot.js.map +1 -0
- package/dist/component/bibot.d.ts +5 -0
- package/dist/component/bibot.js +170 -0
- package/dist/component/bibot.js.map +1 -0
- package/dist/config/appStateEnums.js +10 -5
- package/dist/config/endpointEnums.js +27 -22
- package/dist/config/index.js +38 -5
- package/dist/config/statusCode.js +49 -44
- package/dist/context/AppContext.js +73 -56
- package/dist/context/index.js +16 -3
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +38 -4
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/mobileView.js +33 -18
- package/dist/hooks/useBiBotChatBot.d.ts +29 -0
- package/dist/hooks/useBiBotChatBot.js +206 -0
- package/dist/hooks/useBiBotChatBot.js.map +1 -0
- package/dist/hooks/usePluginFactory.js +60 -77
- package/dist/index.css +36 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +9 -6
- package/dist/index.js.map +1 -1
- package/dist/reducers/appReducer.js +24 -22
- package/dist/reducers/index.js +16 -3
- package/dist/services/index.js +16 -3
- package/dist/services/plugin-api.js +179 -182
- package/dist/styles/RegisterPageStyle.css +63 -0
- package/dist/styles/adminPortal.css +26 -0
- package/dist/styles/appConfig.css +90 -0
- package/dist/styles/buttonStyle.css +27 -0
- package/dist/styles/chatStyle.css +140 -0
- package/dist/styles/index.css +82 -0
- package/dist/styles/predefinedStyle.css +35 -0
- package/dist/styles/themeStyle.css +42 -0
- package/dist/styles/training.css +86 -0
- package/dist/types/coreInterfaces.d.ts +1 -10
- package/dist/types/coreInterfaces.js +5 -2
- package/dist/types/index.js +16 -3
- package/dist/utils/index.js +27 -3
- package/dist/utils/sessionManager.js +16 -12
- package/dist/utils/trimWhitespace.js +15 -11
- package/package.json +51 -54
- package/src/component/bibot.tsx +103 -0
- package/src/config/appStateEnums.ts +3 -0
- package/src/config/endpointEnums.ts +28 -0
- package/src/config/index.ts +5 -0
- package/src/config/statusCode.ts +49 -0
- package/src/context/AppContext.tsx +66 -0
- package/src/context/index.ts +3 -0
- package/src/hooks/index.ts +5 -0
- package/src/hooks/mobileView.tsx +17 -0
- package/src/hooks/useBiBotChatBot.tsx +107 -0
- package/src/hooks/usePluginFactory.tsx +38 -0
- package/src/index.css +36 -0
- package/src/index.tsx +3 -0
- package/src/reducers/appReducer.ts +16 -0
- package/src/reducers/index.ts +4 -0
- package/src/services/index.ts +2 -0
- package/src/services/plugin-api.tsx +120 -0
- package/src/styles/RegisterPageStyle.css +63 -0
- package/src/styles/adminPortal.css +26 -0
- package/src/styles/appConfig.css +90 -0
- package/src/styles/buttonStyle.css +27 -0
- package/src/styles/chatStyle.css +140 -0
- package/src/styles/index.css +82 -0
- package/src/styles/predefinedStyle.css +35 -0
- package/src/styles/themeStyle.css +42 -0
- package/src/styles/training.css +86 -0
- package/src/types/coreInterfaces.ts +69 -0
- package/src/types/index.ts +4 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/sessionManager.tsx +15 -0
- package/src/utils/trimWhitespace.ts +11 -0
- package/tsconfig.json +25 -0
- package/webpack.config.js +19 -0
- package/dist/components/bibot.js +0 -171
- package/dist/components/bibot.js.map +0 -1
- /package/dist/{components/bibot.d.ts → bibot.d.ts} +0 -0
@@ -0,0 +1,103 @@
|
|
1
|
+
import { Avatar, Indicator } from '@mantine/core'
|
2
|
+
import { Close, SendRounded } from '@mui/icons-material'
|
3
|
+
import ChatIcon from '@mui/icons-material/Chat'
|
4
|
+
import { Button } from 'antd'
|
5
|
+
import { useBiBotChatBot } from '../hooks'
|
6
|
+
import { AppProvider } from '../context/AppContext'
|
7
|
+
interface bubbleProps {
|
8
|
+
clientId: string
|
9
|
+
}
|
10
|
+
|
11
|
+
interface PredefinedQuestionsProps {
|
12
|
+
onSelect: (question: string) => void
|
13
|
+
questions: string[]
|
14
|
+
}
|
15
|
+
|
16
|
+
const PredefinedQuestions = ({ questions, onSelect }: PredefinedQuestionsProps) => {
|
17
|
+
return (
|
18
|
+
<div className="predefined-questions">
|
19
|
+
{questions.map((question, index) => (
|
20
|
+
<div key={index} className="predefined-question" onClick={() => onSelect(question)}>
|
21
|
+
{question}
|
22
|
+
</div>
|
23
|
+
))}
|
24
|
+
</div>
|
25
|
+
);
|
26
|
+
};
|
27
|
+
|
28
|
+
const BiBot = ({ clientId }: bubbleProps) => {
|
29
|
+
const {
|
30
|
+
chatIsOpen,
|
31
|
+
messages,
|
32
|
+
isLoading,
|
33
|
+
messageEndRef,
|
34
|
+
userInput,
|
35
|
+
handleUserInput,
|
36
|
+
handleKeyPress,
|
37
|
+
sendInputInquiry,
|
38
|
+
toggleChat,
|
39
|
+
chatBubbleConfig,
|
40
|
+
showPredefinedQuestions,
|
41
|
+
predefinedQuestions,
|
42
|
+
handlePredefinedQuestionSelect,
|
43
|
+
} = useBiBotChatBot({clientId})
|
44
|
+
|
45
|
+
return (
|
46
|
+
<AppProvider>
|
47
|
+
<div className={`chat-bubble ${chatIsOpen ? 'open' : ''}`}>
|
48
|
+
{chatIsOpen && (
|
49
|
+
<div className="chat-window" style={{ backgroundColor: chatBubbleConfig?.bgColor }}>
|
50
|
+
<div className="chat-header" style={{ backgroundColor: chatBubbleConfig?.color ?? '#dedede' }}>
|
51
|
+
<div style={{ alignItems: 'center', display: 'flex', color: '#fff', fontWeight: 'bold' }}>
|
52
|
+
<Indicator inline size={12} offset={7} position="bottom-end" color={ 'green' }>
|
53
|
+
<Avatar color="white" src={chatBubbleConfig?.logo_url} alt="profile" />
|
54
|
+
</Indicator>
|
55
|
+
</div>
|
56
|
+
<div style={{ display: 'flex', flexDirection: 'column', textAlign: 'left', paddingLeft: '10px', justifyContent: 'flex-start', color: '#fff' }}>
|
57
|
+
<span style={{ fontWeight: 'bold' }}>{chatBubbleConfig?.title}</span>
|
58
|
+
{}
|
59
|
+
{isLoading ? <span style={{ fontSize: '12px', lineHeight: '0.5' }}>Typing...</span> : <span style={{ fontSize: '12px', lineHeight: '0.5' }}>{'Online'}</span>}
|
60
|
+
</div>
|
61
|
+
</div>
|
62
|
+
<div className="message-list">
|
63
|
+
{messages.map((message: { sender: 'user' | 'bot', text: string }, index: number) => (
|
64
|
+
message.sender === 'user'
|
65
|
+
? <div key={index} className={`message ${message.sender}`}>
|
66
|
+
{message.text}
|
67
|
+
</div>
|
68
|
+
: <div key={index} style={{ display: 'flex' }}>
|
69
|
+
<Avatar color="white" src={chatBubbleConfig?.logo_url} size={25} alt="profile" />
|
70
|
+
<div className={`message ${message.sender}`}>
|
71
|
+
{message.text}
|
72
|
+
</div>
|
73
|
+
</div>
|
74
|
+
))}
|
75
|
+
{showPredefinedQuestions && predefinedQuestions && predefinedQuestions.length > 0 && (
|
76
|
+
<PredefinedQuestions questions={predefinedQuestions} onSelect={handlePredefinedQuestionSelect} />
|
77
|
+
)}
|
78
|
+
{isLoading && <div style={{marginLeft: '20px'}} className='message'> <div className="loader"></div> </div> }
|
79
|
+
<div ref={messageEndRef} />
|
80
|
+
</div>
|
81
|
+
<div className="input-area">
|
82
|
+
<input
|
83
|
+
autoFocus={true}
|
84
|
+
type="text"
|
85
|
+
value={userInput}
|
86
|
+
onChange={handleUserInput}
|
87
|
+
onKeyPress={handleKeyPress}
|
88
|
+
placeholder="Ask a question"
|
89
|
+
/>
|
90
|
+
<Button disabled={isLoading ?? true} style={{ backgroundColor: 'transparent', color: isLoading ? '#dedede' : chatBubbleConfig?.color }} size='middle' icon={<SendRounded />} onClick={sendInputInquiry}/>
|
91
|
+
</div>
|
92
|
+
</div>
|
93
|
+
)}
|
94
|
+
<Button type='link' onClick={toggleChat} className="chat-toggle" style={{ backgroundColor: chatBubbleConfig?.color ?? '#dedede' }}>
|
95
|
+
{chatIsOpen ? <Close style={{ width: 30, height: 30, color: '#fff' }} /> : <ChatIcon style={{ width: 30, height: 30, color: '#fff' }}/>}
|
96
|
+
</Button>
|
97
|
+
</div>
|
98
|
+
</AppProvider>
|
99
|
+
|
100
|
+
)
|
101
|
+
}
|
102
|
+
|
103
|
+
export default BiBot
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
export const APP_DATA = {
|
3
|
+
APP_NAME: 'Bibot'
|
4
|
+
}
|
5
|
+
|
6
|
+
const baseUrls = {
|
7
|
+
inference: 'https://inference.dev.bibot.thespuka.com/v0',
|
8
|
+
}
|
9
|
+
|
10
|
+
export const endpoints = {
|
11
|
+
get inference () {
|
12
|
+
return baseUrls.inference
|
13
|
+
},
|
14
|
+
} as const
|
15
|
+
|
16
|
+
export enum domain {
|
17
|
+
app = '/app',
|
18
|
+
bibot = '/bibot',
|
19
|
+
inference = '/inference',
|
20
|
+
}
|
21
|
+
|
22
|
+
export enum resources {
|
23
|
+
chatBubble = '/chat-bubble-config',
|
24
|
+
predefinedQ = '/predefined-q',
|
25
|
+
localQ = '/local-q',
|
26
|
+
timedOutLocalQ = '/t-local-q',
|
27
|
+
q = '/q'
|
28
|
+
}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
export enum statusCode {
|
2
|
+
ok = 200
|
3
|
+
, created = 201
|
4
|
+
, accepted = 202
|
5
|
+
|
6
|
+
// 3xx codes
|
7
|
+
, unmodified = 304
|
8
|
+
|
9
|
+
// 4xx Client Error
|
10
|
+
, sucMsg = 'success'
|
11
|
+
, badReq = 400
|
12
|
+
, unauthorized = 401
|
13
|
+
, paymentReq = 402
|
14
|
+
, forbidden = 403
|
15
|
+
, notFound = 404
|
16
|
+
, methodNotAllowed = 405
|
17
|
+
, notAcceptable = 406
|
18
|
+
, pxyAuthReq = 407
|
19
|
+
, reqTimeOut = 408
|
20
|
+
, conflict = 409
|
21
|
+
, gone = 410
|
22
|
+
, lengthReq = 411
|
23
|
+
, preConFailed = 412
|
24
|
+
, payloadTooLarge = 413
|
25
|
+
, urlTooLong = 414
|
26
|
+
, unsupportedMediaType = 415
|
27
|
+
, rangeNotSatisfiable = 416
|
28
|
+
, expectationFailed = 417
|
29
|
+
|
30
|
+
, misdirectedReq = 421
|
31
|
+
, unprocessableEntity = 422
|
32
|
+
, locked = 423
|
33
|
+
, failedDependency = 424
|
34
|
+
, tooLarge = 425
|
35
|
+
, upgradeRequired = 426
|
36
|
+
, preconReq = 428
|
37
|
+
, tooManyReq = 429
|
38
|
+
, reqHeaderTooLarge = 431
|
39
|
+
, unavailableForLegalReasons = 451
|
40
|
+
|
41
|
+
// 5xx Server Error
|
42
|
+
, internalServerError = 500
|
43
|
+
, notImplemented = 501
|
44
|
+
, badGateway = 502
|
45
|
+
, svcUnavalable = 503
|
46
|
+
, gtwayTimeout = 504
|
47
|
+
, httpVNotSupported = 505
|
48
|
+
, networkAuthReq = 511
|
49
|
+
}
|
@@ -0,0 +1,66 @@
|
|
1
|
+
import { appStateEnums } from '../config/appStateEnums'
|
2
|
+
import React, { type ReactNode, createContext, useReducer, useEffect } from 'react'
|
3
|
+
import { appReducer } from '../reducers/appReducer'
|
4
|
+
import type { AppContextProps, AppStates } from '../types/coreInterfaces'
|
5
|
+
import { getSessionId } from '../utils/sessionManager'
|
6
|
+
|
7
|
+
interface AppProps {
|
8
|
+
children: ReactNode
|
9
|
+
}
|
10
|
+
|
11
|
+
const dummyDispatch = () => {} // A no-op function.
|
12
|
+
|
13
|
+
const defaultContextValue: AppContextProps = {
|
14
|
+
state: {
|
15
|
+
chatIsOpen: false,
|
16
|
+
sessionId: getSessionId()
|
17
|
+
},
|
18
|
+
dispatch: dummyDispatch
|
19
|
+
}
|
20
|
+
|
21
|
+
const AppContext = createContext<AppContextProps>(defaultContextValue)
|
22
|
+
|
23
|
+
const AppProvider: React.FC<AppProps> = ({ children }) => {
|
24
|
+
const APP_STATE_KEY = 'app_states'
|
25
|
+
const initialState: AppStates = {
|
26
|
+
chatIsOpen: false,
|
27
|
+
sessionId: getSessionId()
|
28
|
+
}
|
29
|
+
|
30
|
+
const [state, dispatch] = useReducer(appReducer, initialState)
|
31
|
+
|
32
|
+
useEffect(() => {
|
33
|
+
// Pool the initial states from local storage
|
34
|
+
const storedStates = localStorage.getItem(APP_STATE_KEY)
|
35
|
+
|
36
|
+
if (storedStates) {
|
37
|
+
try {
|
38
|
+
const parsedStates = JSON.parse(storedStates)
|
39
|
+
|
40
|
+
// Merge stored states with initial states
|
41
|
+
const updatedStates = {
|
42
|
+
...initialState,
|
43
|
+
...parsedStates
|
44
|
+
}
|
45
|
+
console.log(initialState, parsedStates, updatedStates)
|
46
|
+
// Dispatch action to update the states
|
47
|
+
dispatch({ type: appStateEnums.BIBOT, ...updatedStates })
|
48
|
+
} catch (error) {
|
49
|
+
console.error('Failed to parse app states from local storage:', error)
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}, [])
|
53
|
+
|
54
|
+
useEffect(() => {
|
55
|
+
console.log('Changes in state: ', state)
|
56
|
+
localStorage.setItem(APP_STATE_KEY, JSON.stringify(state))
|
57
|
+
}, [state])
|
58
|
+
|
59
|
+
return (
|
60
|
+
<AppContext.Provider value={{ state, dispatch }}>
|
61
|
+
{children}
|
62
|
+
</AppContext.Provider>
|
63
|
+
)
|
64
|
+
}
|
65
|
+
|
66
|
+
export { AppContext, AppProvider }
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import React, { useState, useEffect } from 'react'
|
2
|
+
export default function MobileView () {
|
3
|
+
const [isMobile, setIsMobile] = useState<boolean>(false)
|
4
|
+
useEffect(() => {
|
5
|
+
const isMobileDevice = () => {
|
6
|
+
const screenWidth = window.innerWidth
|
7
|
+
const mobileThreshold = 768
|
8
|
+
setIsMobile(screenWidth < mobileThreshold)
|
9
|
+
}
|
10
|
+
isMobileDevice()
|
11
|
+
window.addEventListener('resize', isMobileDevice)
|
12
|
+
return () => { // clean up event listner on when component unmount
|
13
|
+
window.removeEventListener('resize', isMobileDevice)
|
14
|
+
}
|
15
|
+
}, [])
|
16
|
+
return isMobile
|
17
|
+
}
|
@@ -0,0 +1,107 @@
|
|
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 }
|
@@ -0,0 +1,38 @@
|
|
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
ADDED
@@ -0,0 +1,36 @@
|
|
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
ADDED
@@ -0,0 +1,16 @@
|
|
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
|
+
}
|
@@ -0,0 +1,120 @@
|
|
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
|
+
}
|
@@ -0,0 +1,63 @@
|
|
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
|
+
}
|