import { useLHSession } from '@components/Contexts/LHSessionContext'
import {
sendActivityAIChatMessage,
startActivityAIChatSession,
} from '@services/ai/ai'
import { AlertTriangle, BadgeInfo, NotebookTabs } from 'lucide-react'
import { motion, AnimatePresence } from 'framer-motion'
import { FlaskConical, MessageCircle, X } from 'lucide-react'
import Image from 'next/image'
import learnhouseAI_icon from 'public/learnhouse_ai_simple.png'
import learnhouseAI_logo_black from 'public/learnhouse_ai_black_logo.png'
import React, { useEffect, useRef } from 'react'
import {
AIChatBotStateTypes,
useAIChatBot,
useAIChatBotDispatch,
} from '@components/Contexts/AI/AIChatBotContext'
import useGetAIFeatures from '../../../AI/Hooks/useGetAIFeatures'
import UserAvatar from '@components/Objects/UserAvatar'
type AIActivityAskProps = {
activity: any
}
function AIActivityAsk(props: AIActivityAskProps) {
const is_ai_feature_enabled = useGetAIFeatures({ feature: 'activity_ask' })
const [isButtonAvailable, setIsButtonAvailable] = React.useState(false)
const dispatchAIChatBot = useAIChatBotDispatch() as any
useEffect(() => {
if (is_ai_feature_enabled) {
setIsButtonAvailable(true)
}
}, [is_ai_feature_enabled])
return (
<>
{isButtonAvailable && (
dispatchAIChatBot({ type: 'setIsModalOpen' })}
style={{
background:
'conic-gradient(from 32deg at 53.75% 50%, rgb(35, 40, 93) 4deg, rgba(20, 0, 52, 0.95) 59deg, rgba(164, 45, 238, 0.88) 281deg)',
}}
className="rounded-full px-5 drop-shadow-md flex items-center space-x-1.5 p-2.5 text-sm text-white hover:cursor-pointer transition delay-150 duration-300 ease-in-out hover:scale-105"
>
{' '}
{' '}
Ask AI
)}
>
)
}
export type AIMessage = {
sender: string
message: any
type: 'ai' | 'user'
}
type ActivityChatMessageBoxProps = {
activity: any
}
function ActivityChatMessageBox(props: ActivityChatMessageBoxProps) {
const session = useLHSession() as any
const access_token = session?.data?.tokens?.access_token;
const aiChatBotState = useAIChatBot() as AIChatBotStateTypes
const dispatchAIChatBot = useAIChatBotDispatch() as any
// TODO : come up with a better way to handle this
const inputClass = aiChatBotState.isWaitingForResponse
? 'ring-1 ring-inset ring-white/10 bg-gray-950/40 w-full rounded-lg outline-none px-4 py-2 text-white text-sm placeholder:text-white/30 opacity-30 '
: 'ring-1 ring-inset ring-white/10 bg-gray-950/40 w-full rounded-lg outline-none px-4 py-2 text-white text-sm placeholder:text-white/30'
useEffect(() => {
if (aiChatBotState.isModalOpen) {
document.body.style.overflow = 'hidden'
} else {
document.body.style.overflow = 'unset'
}
}, [aiChatBotState.isModalOpen])
function handleKeyDown(event: React.KeyboardEvent) {
if (event.key === 'Enter') {
// Perform the sending action here
sendMessage(event.currentTarget.value)
}
}
const handleChange = async (event: React.ChangeEvent) => {
await dispatchAIChatBot({
type: 'setChatInputValue',
payload: event.currentTarget.value,
})
}
const sendMessage = async (message: string) => {
if (aiChatBotState.aichat_uuid) {
await dispatchAIChatBot({
type: 'addMessage',
payload: { sender: 'user', message: message, type: 'user' },
})
await dispatchAIChatBot({ type: 'setIsWaitingForResponse' })
const response = await sendActivityAIChatMessage(
message,
aiChatBotState.aichat_uuid,
props.activity.activity_uuid,
access_token
)
if (response.success == false) {
await dispatchAIChatBot({ type: 'setIsNoLongerWaitingForResponse' })
await dispatchAIChatBot({ type: 'setChatInputValue', payload: '' })
await dispatchAIChatBot({
type: 'setError',
payload: {
isError: true,
status: response.status,
error_message: response.data.detail,
},
})
return
}
await dispatchAIChatBot({ type: 'setIsNoLongerWaitingForResponse' })
await dispatchAIChatBot({ type: 'setChatInputValue', payload: '' })
await dispatchAIChatBot({
type: 'addMessage',
payload: { sender: 'ai', message: response.data.message, type: 'ai' },
})
} else {
await dispatchAIChatBot({
type: 'addMessage',
payload: { sender: 'user', message: message, type: 'user' },
})
await dispatchAIChatBot({ type: 'setIsWaitingForResponse' })
const response = await startActivityAIChatSession(
message,access_token,
props.activity.activity_uuid
)
if (response.success == false) {
await dispatchAIChatBot({ type: 'setIsNoLongerWaitingForResponse' })
await dispatchAIChatBot({ type: 'setChatInputValue', payload: '' })
await dispatchAIChatBot({
type: 'setError',
payload: {
isError: true,
status: response.status,
error_message: response.data.detail,
},
})
return
}
await dispatchAIChatBot({
type: 'setAichat_uuid',
payload: response.data.aichat_uuid,
})
await dispatchAIChatBot({ type: 'setIsNoLongerWaitingForResponse' })
await dispatchAIChatBot({ type: 'setChatInputValue', payload: '' })
await dispatchAIChatBot({
type: 'addMessage',
payload: { sender: 'ai', message: response.data.message, type: 'ai' },
})
}
}
function closeModal() {
dispatchAIChatBot({ type: 'setIsModalClose' })
}
const messagesEndRef = useRef(null)
useEffect(() => {
if (messagesEndRef.current) {
messagesEndRef.current.scrollIntoView({ behavior: 'smooth' })
}
}, [aiChatBotState.messages, session])
return (
{aiChatBotState.isModalOpen && (
<>
{aiChatBotState.messages.length > 0 &&
!aiChatBotState.error.isError ? (
{aiChatBotState.messages.map(
(message: AIMessage, index: number) => {
return (
)
}
)}
) : (
)}
{aiChatBotState.error.isError && (
Something wrong happened
{aiChatBotState.error.error_message}
)}
sendMessage(aiChatBotState.chatInputValue)}
/>
>
)}
)
}
type AIMessageProps = {
message: AIMessage
animated: boolean
}
function AIMessage(props: AIMessageProps) {
const session = useLHSession() as any
const words = props.message.message.split(' ')
return (
{props.message.sender == 'ai' ? (
) : (
)}
{words.map((word: string, i: number) => (
{word + ' '}
))}
)
}
const AIMessagePlaceHolder = (props: {
activity_uuid: string
sendMessage: any
}) => {
const session = useLHSession() as any
const [feedbackModal, setFeedbackModal] = React.useState(false)
const aiChatBotState = useAIChatBot() as AIChatBotStateTypes
if (!aiChatBotState.error.isError) {
return (
Hello
{session.data.user.username},
how can we help today ?
)
}
}
const AIChatPredefinedQuestion = (props: {
sendMessage: any
label: string
}) => {
function getQuestion(label: string) {
if (label === 'about') {
return `What is this Activity about ?`
} else if (label === 'flashcards') {
return `Generate flashcards about this Activity`
} else if (label === 'examples') {
return `Explain this Activity in practical examples`
}
}
return (
props.sendMessage(getQuestion(props.label))}
className="flex space-x-1.5 items-center bg-white/5 cursor-pointer px-4 py-1.5 rounded-xl outline outline-1 outline-neutral-100/10 text-xs font-semibold text-white/40 hover:text-white/60 hover:bg-white/10 hover:outline-neutral-200/40 delay-75 ease-linear transition-all"
>
{props.label === 'about' &&
}
{props.label === 'flashcards' &&
}
{props.label === 'examples' &&
Ex
}
{getQuestion(props.label)}
)
}
export default AIActivityAsk