feat(nextjs): Slide edit using prompt added
This commit is contained in:
parent
f10eb5d7a6
commit
dece7399d4
8 changed files with 22 additions and 29 deletions
|
|
@ -42,11 +42,11 @@ const EditableLayoutWrapper: React.FC<EditableLayoutWrapperProps> = ({
|
|||
const matches: { path: string; type: 'image' | 'icon'; data: any }[] = [];
|
||||
|
||||
// Check current level for __image_url__ or __icon_url__
|
||||
if (data.__image_url__ && isMatchingUrl(data.__image_url__, targetUrl)) {
|
||||
if (data.__image_url__ && targetUrl.includes(data.__image_url__)) {
|
||||
matches.push({ path, type: 'image', data });
|
||||
}
|
||||
|
||||
if (data.__icon_url__ && isMatchingUrl(data.__icon_url__, targetUrl)) {
|
||||
if (data.__icon_url__ && targetUrl.includes(data.__icon_url__)) {
|
||||
matches.push({ path, type: 'icon', data });
|
||||
}
|
||||
|
||||
|
|
@ -109,14 +109,16 @@ const EditableLayoutWrapper: React.FC<EditableLayoutWrapperProps> = ({
|
|||
* Checks if two URLs match using various comparison strategies
|
||||
*/
|
||||
const isMatchingUrl = (url1: string, url2: string): boolean => {
|
||||
console.log('url1', url1);
|
||||
console.log('url2', url2);
|
||||
if (!url1 || !url2) return false;
|
||||
|
||||
// Direct match
|
||||
if (url1 === url2) return true;
|
||||
|
||||
// Remove protocol and domain differences
|
||||
const cleanUrl1 = url1.replace(/^https?:\/\/[^\/]+/, '').replace(/^\/+/, '');
|
||||
const cleanUrl2 = url2.replace(/^https?:\/\/[^\/]+/, '').replace(/^\/+/, '');
|
||||
const cleanUrl1 = url1 && url1.replace(/^https?:\/\/[^\/]+/, '').replace(/^\/+/, '');
|
||||
const cleanUrl2 = url2 && url2.replace(/^https?:\/\/[^\/]+/, '').replace(/^\/+/, '');
|
||||
|
||||
if (cleanUrl1 === cleanUrl2) return true;
|
||||
|
||||
|
|
@ -304,7 +306,7 @@ const EditableLayoutWrapper: React.FC<EditableLayoutWrapperProps> = ({
|
|||
imageUrl: newImageUrl,
|
||||
prompt: prompt || activeEditor.data?.__image_prompt__ || ''
|
||||
}));
|
||||
|
||||
setActiveEditor(null);
|
||||
}
|
||||
};
|
||||
/**
|
||||
|
|
@ -323,6 +325,8 @@ const EditableLayoutWrapper: React.FC<EditableLayoutWrapperProps> = ({
|
|||
query: query || activeEditor.data?.__icon_query__ || ''
|
||||
}));
|
||||
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -341,7 +345,6 @@ const EditableLayoutWrapper: React.FC<EditableLayoutWrapperProps> = ({
|
|||
onClose={handleEditorClose}
|
||||
onImageChange={handleImageChange}
|
||||
>
|
||||
|
||||
</ImageEditor>
|
||||
)}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,6 @@ import ReactDOM from 'react-dom/client';
|
|||
import TiptapText from './TiptapText';
|
||||
|
||||
interface TiptapTextReplacerProps {
|
||||
layout: React.ComponentType<{
|
||||
data: any;
|
||||
}>;
|
||||
children: ReactNode;
|
||||
slideData?: any;
|
||||
slideIndex?: number;
|
||||
|
|
@ -18,11 +15,11 @@ interface TiptapTextReplacerProps {
|
|||
const TiptapTextReplacer: React.FC<TiptapTextReplacerProps> = ({
|
||||
children,
|
||||
slideData,
|
||||
layout,
|
||||
slideIndex,
|
||||
onContentChange = () => { },
|
||||
isEditMode = true
|
||||
}) => {
|
||||
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [processedElements, setProcessedElements] = useState(new Set<HTMLElement>());
|
||||
useEffect(() => {
|
||||
|
|
@ -107,7 +104,6 @@ const TiptapTextReplacer: React.FC<TiptapTextReplacerProps> = ({
|
|||
const root = ReactDOM.createRoot(tiptapContainer);
|
||||
root.render(
|
||||
<TiptapText
|
||||
key={trimmedText}
|
||||
content={trimmedText}
|
||||
onContentChange={(content: string) => {
|
||||
if (dataPath && onContentChange) {
|
||||
|
|
@ -261,7 +257,7 @@ const TiptapTextReplacer: React.FC<TiptapTextReplacerProps> = ({
|
|||
}, [slideData, isEditMode, slideIndex]);
|
||||
|
||||
return (
|
||||
<div ref={containerRef} className="tiptap-text-replacer">
|
||||
<div ref={containerRef} key={slideData} className="tiptap-text-replacer">
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -55,13 +55,11 @@ export const useGroupLayouts = () => {
|
|||
isEditMode={isEditMode}
|
||||
>
|
||||
<TiptapTextReplacer
|
||||
key={slide.id}
|
||||
|
||||
slideData={slide.content}
|
||||
slideIndex={slide.index}
|
||||
isEditMode={isEditMode}
|
||||
layout={Layout}
|
||||
onContentChange={(content: string, dataPath: string, slideIndex?: number) => {
|
||||
|
||||
// Dispatch Redux action to update slide content
|
||||
if (dataPath && slideIndex !== undefined) {
|
||||
dispatch(updateSlideContent({
|
||||
|
|
@ -72,12 +70,12 @@ export const useGroupLayouts = () => {
|
|||
}
|
||||
}}
|
||||
>
|
||||
<Layout data={slide.content} />
|
||||
<Layout key={`layout-${slide.index}-${JSON.stringify(slide.content)}`} data={slide.content} />
|
||||
</TiptapTextReplacer>
|
||||
</EditableLayoutWrapper>
|
||||
);
|
||||
}
|
||||
return <Layout data={slide.content} />;
|
||||
return <Layout key={`layout-${slide.index}-${JSON.stringify(slide.content)}`} data={slide.content} />;
|
||||
};
|
||||
}, [getGroupLayout, dispatch]);
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ const GroupLayouts: React.FC<GroupLayoutsProps> = ({ group, onSelectLayoutGroup,
|
|||
)}
|
||||
|
||||
<div className="mb-3">
|
||||
<h6 className="text-base font-medium text-gray-900 mb-1">
|
||||
<h6 className="text-base capitalize font-medium text-gray-900 mb-1">
|
||||
{group.name}
|
||||
</h6>
|
||||
<p className="text-sm text-gray-600">
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ const PresentationPage = ({ presentation_id }: { presentation_id: string }) => {
|
|||
setContentLoading(false);
|
||||
}
|
||||
};
|
||||
console.log("presentationData", presentationData);
|
||||
// Regular view
|
||||
return (
|
||||
<div className="flex overflow-hidden flex-col">
|
||||
|
|
|
|||
|
|
@ -52,13 +52,11 @@ const SlideContent = ({
|
|||
|
||||
try {
|
||||
const response = await PresentationGenerationApi.editSlide(
|
||||
presentationId,
|
||||
slide.index,
|
||||
slide.id,
|
||||
value
|
||||
);
|
||||
|
||||
if (response) {
|
||||
console.log("response", response);
|
||||
dispatch(updateSlide({ index: slide.index, slide: response }));
|
||||
toast.success("Slide updated successfully");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,20 +65,18 @@ export class PresentationGenerationApi {
|
|||
|
||||
|
||||
static async editSlide(
|
||||
presentation_id: string,
|
||||
index: number,
|
||||
slide_id: string,
|
||||
|
||||
prompt: string
|
||||
) {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`/api/v1/ppt/edit`,
|
||||
`/api/v1/ppt/slide/edit`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: getHeader(),
|
||||
body: JSON.stringify({
|
||||
presentation_id,
|
||||
|
||||
index,
|
||||
id: slide_id,
|
||||
prompt,
|
||||
}),
|
||||
cache: "no-cache",
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export async function POST(req: NextRequest) {
|
|||
return NextResponse.json({ error: "Missing Presentation ID" }, { status: 400 });
|
||||
}
|
||||
const browser = await puppeteer.launch({
|
||||
headless: true,
|
||||
headless: false,
|
||||
args: [
|
||||
'--no-sandbox',
|
||||
'--disable-setuid-sandbox',
|
||||
|
|
@ -31,6 +31,7 @@ export async function POST(req: NextRequest) {
|
|||
width: "1280px",
|
||||
height: "720px",
|
||||
margin: { top: 0, right: 0, bottom: 0, left: 0 }
|
||||
|
||||
});
|
||||
browser.close();
|
||||
const sanitizedTitle = sanitizeFilename(title);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue