Uname: Linux business55.web-hosting.com 4.18.0-553.lve.el8.x86_64 #1 SMP Mon May 27 15:27:34 UTC 2024 x86_64
Software: LiteSpeed
PHP version: 8.1.31 [ PHP INFO ] PHP os: Linux
Server Ip: 162.213.251.212
Your Ip: 18.191.210.103
User: allssztx (535) | Group: allssztx (533)
Safe Mode: OFF
Disable Function:
NONE

name : AIChat.jsx
import { useLayoutEffect, useState } from '@wordpress/element';
import { __, isRTL } from '@wordpress/i18n';
import {
	chevronLeft,
	chevronRight,
	Icon,
	postComments,
} from '@wordpress/icons';
import { useAIConsentStore } from '@shared/state/ai-consent';
import { AnimatePresence, motion } from 'framer-motion';
import { Answer } from '@help-center/components/ai-chat/Answer';
import { History } from '@help-center/components/ai-chat/History';
import { Nav } from '@help-center/components/ai-chat/Nav';
import { Question } from '@help-center/components/ai-chat/Question';
import { Support } from '@help-center/components/ai-chat/Support';
import { getAnswer } from '@help-center/lib/api';
import { useAIChatStore } from '@help-center/state/ai-chat';

export const AIChatDashboard = ({ onOpen }) => {
	return (
		<section className="">
			<button
				data-test="help-center-dashboard-ai-chat-button"
				type="button"
				onClick={onOpen}
				className="m-0 flex w-full cursor-pointer justify-between gap-2 rounded-md border border-gray-200 bg-transparent p-2.5 text-left hover:bg-gray-100 rtl:text-right">
				<Icon
					icon={postComments}
					className="rounded-full border-0 bg-design-main fill-design-text p-2"
					size={48}
				/>
				<div className="grow pl-1">
					<h1 className="m-0 p-0 text-lg font-medium">
						{__('Ask AI', 'extendify-local')}
					</h1>
					<p className="m-0 p-0 text-xs text-gray-800">
						{__('Got questions? Ask our AI chatbot', 'extendify-local')}
					</p>
				</div>
				<div className="flex h-12 grow-0 items-center justify-end">
					<Icon
						icon={isRTL() ? chevronLeft : chevronRight}
						size={24}
						className="fill-current text-gray-700"
					/>
				</div>
			</button>
		</section>
	);
};

export const AIChat = () => {
	const [question, setQuestion] = useState(undefined);
	const [answer, setAnswer] = useState(undefined);
	const [answerId, setAnswerId] = useState(undefined);
	const [error, setError] = useState(false);

	const [showHistory, setShowHistory] = useState(false);
	const { experienceLevel, currentQuestion, setCurrentQuestion } =
		useAIChatStore();

	const shouldShowAIConsent = useAIConsentStore((state) =>
		state.shouldShowAIConsent('help-center'),
	);

	const reset = () => {
		setQuestion(undefined);
		setAnswer(undefined);
		setAnswerId(undefined);
		setError(false);
		setShowHistory(false);
		setCurrentQuestion(undefined);
	};

	const handleSubmit = async (formSubmitEvent) => {
		formSubmitEvent.preventDefault();
		const q = formSubmitEvent.target?.[0]?.value ?? '';
		if (!q) return;
		setAnswer('...');
		setQuestion(q);
		const response = await getAnswer({ question: q, experienceLevel });
		if (!response.ok) {
			setError(true);
			return;
		}
		try {
			const reader = response.body.getReader();
			const decoder = new TextDecoder();
			while (true) {
				const { value, done } = await reader.read();
				if (done) break;
				const chunk = decoder.decode(value);
				setAnswer((v) => {
					if (v === '...') return chunk;
					// For bw compatability we remove the json appended to the end
					return (v + chunk).replace(/\{"id":"[a-zA-Z0-9]+"\}/g, '');
				});
			}
			setAnswerId(response.headers.get('x-extendify-chat-id') || undefined);
		} catch (e) {
			console.error(e);
		}
	};

	useLayoutEffect(() => {
		setQuestion(currentQuestion?.question);
		setAnswer(currentQuestion?.htmlAnswer);
		setShowHistory(false);
	}, [currentQuestion]);

	if (shouldShowAIConsent) {
		return <ConsentOverlay />;
	}

	if (question) {
		return (
			<Answer
				question={question}
				answer={answer}
				answerId={answerId}
				reset={reset}
				error={error}
			/>
		);
	}

	return (
		<>
			<section className="flex h-full flex-col">
				<Nav setShowHistory={setShowHistory} showHistory={showHistory} />
				<div className="flex flex-grow items-center bg-design-main p-6 text-design-text">
					<Question onSubmit={handleSubmit} />
				</div>
				<Support height={'h-11'} />
			</section>
			<AnimatePresence>
				{showHistory && (
					<motion.section
						// slide up from bottom 100%
						initial={{ x: 50 }}
						animate={{ x: 0 }}
						exit={{ x: 0 }}
						transition={{ duration: 0.2 }}
						style={{ '--ext-design-text': '#000000' }}
						className="absolute bottom-0 left-0 right-0 top-0 z-20 ml-4 mt-4 flex h-full flex-col overflow-hidden rounded-tl-lg bg-white shadow-2xl">
						<History setShowHistory={setShowHistory} />
					</motion.section>
				)}
			</AnimatePresence>
		</>
	);
};

const ConsentOverlay = () => {
	const { consentTermsHTML, setUserGaveConsent } = useAIConsentStore();

	return (
		<div
			data-test="help-center-ai-chat-consent-prompt"
			className="absolute inset-0 flex items-center justify-center bg-black/75 p-6">
			<div className="rounded bg-white p-4">
				<h2 className="mb-2 mt-0 text-lg">
					{__('Terms of Use', 'extendify-local')}
				</h2>
				<p
					className="m-0"
					dangerouslySetInnerHTML={{
						__html: consentTermsHTML,
					}}
				/>
				<button
					data-test="help-center-ai-chat-consent-accept-button"
					className="mt-4 w-full cursor-pointer rounded border-0 bg-design-main px-4 py-2 text-center text-white"
					type="button"
					onClick={() => setUserGaveConsent(true)}>
					{__('Accept', 'extendify-local')}
				</button>
			</div>
		</div>
	);
};

export const routes = [
	{
		slug: 'ai-chat',
		title: __('AI Chatbot', 'extendify-local'),
		component: AIChat,
	},
];
© 2025 GrazzMean-Shell