Я использовал редактор Puck для веб -строителя и имеет некоторые компоненты, я создал компонент чатбота и файл контекста, Chatbot вернет HTML -код, и я установлю это значение в значении контекста, но я Wnatthat Code в свой редактор, как только я получу это значение, например, AI Code находится в редакторе Builder < /p>
pleientditor."use client";
import type { Data } from "@measured/puck";
import { DropZone, Puck } from "@measured/puck";
import config from "../../../puck.config";
import { useEffect, useState } from "react";
import ChatBox from "../../../components/ChatBox/ChatBox";
import { useAppContext } from "../../../contexts/HtmlContext";
export function Client({ path, data }: { path: string; data: Partial }) {
const [isOpen, setIsOpen] = useState(false);
const { html } = useAppContext();
function ToggleChatBox() {
setIsOpen((prev) => !prev);
}
const [puckData, setPuckData] = useState
>({});
useEffect(() => {
if (html) {
const newData =
typeof html === "string" ? JSON.parse(html) : html;
setPuckData(newData);
}
}, [html]);
return (
{isOpen && (
)}
{isOpen ? (
) : (
)}
{
await fetch("/puck/api", {
method: "post",
body: JSON.stringify({ data, path }),
});
}}
/>
);
}
< /code>
chatbot.tsx
import React, { useRef } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { useState } from "react";
import "./style.css";
import axios from "axios";
import { useAppContext } from "../../contexts/HtmlContext";
export default function ChatBox() {
const [chatHistory, setChatHistory] = useState<
{ role: "user" | "ai"; text: string }[]
>([]);
const userMsg = useRef(null);
const { setHtml } = useAppContext();
const [isReplied, setIsReplied] = useState(false);
async function SubmitUserMsg() {
if (!userMsg.current) {
return;
}
const msg = userMsg.current.value;
if (msg.trim().length [
...prev,
{ role: "user", text: msg },
{ role: "ai", text: "Thinking..." },
]);
setIsReplied(false);
userMsg.current.value = "";
userMsg.current.focus();
try {
const res = await axios.post(`${process.env.NEXT_PUBLIC_URL}/api/chat`, {
messages: msg,
});
if (res.data.isResponse) {
if(res.data.isHtml){
const blockData = {
content: [
{
type: "RawHTMLBlock",
props: {
html: res.data.AIreply,
},
},
],
};
setHtml(blockData);
}
setChatHistory((prev) => {
const updated = [...prev];
updated[updated.length - 1] = { role: "ai", text: res.data.AIreply };
return updated;
});
setIsReplied(true);
}
} catch (e) {
setChatHistory((prev) => {
const updated = [...prev];
updated[updated.length - 1] = {
role: "ai",
text: "Error in AI response",
};
return updated;
});
}
}
function copyToClipboard(text: string) {
navigator.clipboard
.writeText(text)
.then(() => {
})
.catch((err) => {
console.error("Failed to copy: ", err);
});
}
return (
AI Assistant
{chatHistory.map((item, ind) => {
if (item.role === "user") {
return (
{item.text}
);
} else {
return (
{item.text}
copyToClipboard(item.text)}
>
);
}
})}
onKeyDown={(e) => {
if (e.key === "Enter") {
e.preventDefault();
SubmitUserMsg();
}
}}
ref={userMsg}
type="text"
placeholder="Type your message..."
className="form-control rounded-pill ps-3 pe-5 border-0 bg-light"
/>
);
}
< /code>
puck.config.ts
import type { Config } from "@measured/puck";
import { DropZone } from "@measured/puck";
import Image from "next/image";
import React, { useState, useEffect } from "react";
import HTMLrender from "./components/HTMLrender";
type Props = {
RawHTMLBlock: {
html: string;
};
};
export const config: Config
= {
components: {
RawHTMLBlock: {
render: HTMLrender,
fields: {
html: {
type: "textarea",
label: "HTML",
},
},
},
}
}
< /code>
htmlrenderer.tsx
export default function HTMLrender({ html}: { html: string }) {
console.log("HTMLrender component received html:", html);
return (
)
}```
in console log
{
"content": [
{
"type": "RawHTMLBlock",
"props": {
"html": "Click Me"
}
}
]
}
Подробнее здесь: https://stackoverflow.com/questions/796 ... w-one-from