From d39b1aec5c2d36456b0e30b796acbff0eefcdb09 Mon Sep 17 00:00:00 2001 From: shiva raj badu Date: Sat, 2 Aug 2025 21:24:43 +0545 Subject: [PATCH] fix(Nextjs): Custom Layout compile issue --- servers/fastapi/chroma/chroma.sqlite3 | Bin 4329472 -> 4329472 bytes .../components/TiptapTextReplacer.tsx | 25 ++++++++ .../context/LayoutContext.tsx | 14 +++-- .../(presentation-generator)/outline/page.tsx | 2 +- .../hooks/usePresentationStreaming.ts | 27 +++++++-- .../custom-layout/components/FontManager.tsx | 6 +- servers/nextjs/app/custom-layout/page.tsx | 55 +++++++----------- 7 files changed, 80 insertions(+), 49 deletions(-) diff --git a/servers/fastapi/chroma/chroma.sqlite3 b/servers/fastapi/chroma/chroma.sqlite3 index 284b2129b702c0b807c19fa23fcdf144077ab8e4..5f337926f6fb73ea274d91e3b2941259bc5ba34a 100644 GIT binary patch delta 306 zcmWm9M-ssR06b~xaK3vPHI!3!V! z2tY;%2AB1$Nuf+}jLqk$$`XrqHJdgx<-Ax0Quf+=R0 PV}T|9_tjfh*W1qzL2z+W delta 300 zcmWm9M-ssR06zqP0Yzvip^OTusG*JqnrNYo4!Y=}j{$}lVT=i;m|>0umiXUS JZ$n>iKR?}SaWMb@ diff --git a/servers/nextjs/app/(presentation-generator)/components/TiptapTextReplacer.tsx b/servers/nextjs/app/(presentation-generator)/components/TiptapTextReplacer.tsx index 3f23474a..5cc70ce3 100644 --- a/servers/nextjs/app/(presentation-generator)/components/TiptapTextReplacer.tsx +++ b/servers/nextjs/app/(presentation-generator)/components/TiptapTextReplacer.tsx @@ -96,6 +96,31 @@ const TiptapTextReplacer: React.FC = ({ wordBreak: computedStyles.wordBreak, overflow: computedStyles.overflow, textAlignLast: computedStyles.textAlignLast, + position: computedStyles.position, + top: computedStyles.top, + left: computedStyles.left, + right: computedStyles.right, + bottom: computedStyles.bottom, + display: computedStyles.display, + flexDirection: computedStyles.flexDirection, + flexWrap: computedStyles.flexWrap, + flexGrow: computedStyles.flexGrow, + flexShrink: computedStyles.flexShrink, + flexBasis: computedStyles.flexBasis, + alignItems: computedStyles.alignItems, + justifyContent: computedStyles.justifyContent, + gap: computedStyles.gap, + gridTemplateColumns: computedStyles.gridTemplateColumns, + gridTemplateRows: computedStyles.gridTemplateRows, + gridTemplateAreas: computedStyles.gridTemplateAreas, + gridTemplate: computedStyles.gridTemplate, + gridAutoFlow: computedStyles.gridAutoFlow, + gridAutoColumns: computedStyles.gridAutoColumns, + gridAutoRows: computedStyles.gridAutoRows, + gridColumn: computedStyles.gridColumn, + gridRow: computedStyles.gridRow, + gridArea: computedStyles.gridArea, + grid: computedStyles.grid, }; // Try to find matching data path const dataPath = findDataPath(slideData, trimmedText); diff --git a/servers/nextjs/app/(presentation-generator)/context/LayoutContext.tsx b/servers/nextjs/app/(presentation-generator)/context/LayoutContext.tsx index 16bd6724..9c9a88bb 100644 --- a/servers/nextjs/app/(presentation-generator)/context/LayoutContext.tsx +++ b/servers/nextjs/app/(presentation-generator)/context/LayoutContext.tsx @@ -81,8 +81,11 @@ const createCacheKey = (groupName: string, fileName: string): string => const compileCustomLayout = (layoutCode: string, React: any, z: any) => { const cleanCode = layoutCode .replace(/import\s+React\s+from\s+'react';?/g, "") - .replace(/import\s*{\s*z\s*}\s*from\s+'zod';?/g, ""); - + .replace(/import\s*{\s*z\s*}\s*from\s+'zod';?/g, "") + .replace(/import\s+.*\s+from\s+['"]zod['"];?/g, "") + // remove every zod import (any style) + .replace(/import\s+.*\s+from\s+['"]zod['"];?/g, "") + .replace(/const\s+[^=]*=\s*require\(['"]zod['"]\);?/g, ""); const compiled = Babel.transform(cleanCode, { presets: [ ["react", { runtime: "classic" }], @@ -93,8 +96,9 @@ const compileCustomLayout = (layoutCode: string, React: any, z: any) => { const factory = new Function( "React", - "z", + "_z", ` + const z = _z; ${compiled} /* everything declared in the string is in scope here */ @@ -108,7 +112,7 @@ const compileCustomLayout = (layoutCode: string, React: any, z: any) => { }; ` ); - + // globalThis.z = z; return factory(React, z); }; @@ -120,6 +124,7 @@ export const LayoutProvider: React.FC<{ const [error, setError] = useState(null); const [isPreloading, setIsPreloading] = useState(false); const dispatch = useDispatch(); + console.log("🔍 layoutData", layoutData); const buildData = async (groupedLayoutsData: GroupedLayoutsResponse[]) => { const layouts: LayoutInfo[] = []; @@ -343,6 +348,7 @@ export const LayoutProvider: React.FC<{ const customGroup = customGroupData.presentations; console.log("🔍 customGroup", customGroup); for (const group of customGroup) { + console.log("🔍 group", group); const groupName = `custom-${group.presentation_id}`; fullDataByGroup.set(groupName, []); if (!layoutsByGroup.has(groupName)) { diff --git a/servers/nextjs/app/(presentation-generator)/outline/page.tsx b/servers/nextjs/app/(presentation-generator)/outline/page.tsx index d47a1e80..5cbaf2a8 100644 --- a/servers/nextjs/app/(presentation-generator)/outline/page.tsx +++ b/servers/nextjs/app/(presentation-generator)/outline/page.tsx @@ -1,7 +1,7 @@ import React from 'react' -import Header from '@/app/dashboard/components/Header' import { Metadata } from 'next' import OutlinePage from './components/OutlinePage' +import Header from '@/components/Header' export const metadata: Metadata = { title: "Outline Presentation", description: "Customize and organize your presentation outline. Drag and drop slides, add charts, and generate your presentation with ease.", diff --git a/servers/nextjs/app/(presentation-generator)/presentation/hooks/usePresentationStreaming.ts b/servers/nextjs/app/(presentation-generator)/presentation/hooks/usePresentationStreaming.ts index 78ccea88..1b099f09 100644 --- a/servers/nextjs/app/(presentation-generator)/presentation/hooks/usePresentationStreaming.ts +++ b/servers/nextjs/app/(presentation-generator)/presentation/hooks/usePresentationStreaming.ts @@ -1,8 +1,13 @@ import { useEffect, useRef } from "react"; import { useDispatch, useSelector } from "react-redux"; -import { clearPresentationData, setPresentationData, setStreaming } from "@/store/slices/presentationGeneration"; +import { + clearPresentationData, + setPresentationData, + setStreaming, +} from "@/store/slices/presentationGeneration"; import { jsonrepair } from "jsonrepair"; import { RootState } from "@/store/store"; +import { toast } from "sonner"; export const usePresentationStreaming = ( presentationId: string, @@ -11,7 +16,9 @@ export const usePresentationStreaming = ( setError: (error: boolean) => void, fetchUserSlides: () => void ) => { - const { presentationData } = useSelector((state: RootState) => state.presentationGeneration); + const { presentationData } = useSelector( + (state: RootState) => state.presentationGeneration + ); const dispatch = useDispatch(); const previousSlidesLength = useRef(0); @@ -64,7 +71,7 @@ export const usePresentationStreaming = ( dispatch(setStreaming(false)); setLoading(false); eventSource.close(); - + // Remove stream parameter from URL const newUrl = new URL(window.location.href); newUrl.searchParams.delete("stream"); @@ -81,12 +88,20 @@ export const usePresentationStreaming = ( setLoading(false); dispatch(setStreaming(false)); eventSource.close(); - + // Remove stream parameter from URL const newUrl = new URL(window.location.href); newUrl.searchParams.delete("stream"); window.history.replaceState({}, "", newUrl.toString()); break; + case "error": + eventSource.close(); + toast.error("Error in outline streaming", { + description: + data.detail || + "Failed to connect to the server. Please try again.", + }); + break; } }); @@ -102,7 +117,7 @@ export const usePresentationStreaming = ( if (stream) { initializeStream(); } else { - if(!presentationData || presentationData.slides.length === 0){ + if (!presentationData || presentationData.slides.length === 0) { fetchUserSlides(); } } @@ -113,4 +128,4 @@ export const usePresentationStreaming = ( } }; }, [presentationId, stream, dispatch, setLoading, setError, fetchUserSlides]); -}; \ No newline at end of file +}; diff --git a/servers/nextjs/app/custom-layout/components/FontManager.tsx b/servers/nextjs/app/custom-layout/components/FontManager.tsx index 119942bc..f9b590e4 100644 --- a/servers/nextjs/app/custom-layout/components/FontManager.tsx +++ b/servers/nextjs/app/custom-layout/components/FontManager.tsx @@ -88,11 +88,11 @@ const FontManager: React.FC = ({ } return ( - + - Global Font Management + Font Management

Manage fonts across all slides. Upload fonts once and they'll be @@ -158,7 +158,7 @@ const FontManager: React.FC = ({ variant="outline" disabled={uploadingFonts.has(fontName)} onClick={() => fileInputRefs.current[fontName]?.click()} - className="text-xs bg-blue-600 text-white hover:bg-blue-700 border-blue-600" + className="text-xs bg-blue-600 text-white hover:text-white hover:bg-blue-700 border-blue-600" > {uploadingFonts.has(fontName) ? ( <> diff --git a/servers/nextjs/app/custom-layout/page.tsx b/servers/nextjs/app/custom-layout/page.tsx index cbf845f5..8e50ef49 100644 --- a/servers/nextjs/app/custom-layout/page.tsx +++ b/servers/nextjs/app/custom-layout/page.tsx @@ -18,6 +18,7 @@ import { v4 as uuidv4 } from "uuid"; import EachSlide from "./components/EachSlide"; import FontManager from "./components/FontManager"; import Header from "@/components/Header"; +import { useLayout } from "../(presentation-generator)/context/LayoutContext"; // Types interface SlideData { @@ -50,6 +51,7 @@ interface FontData { } const CustomLayoutPage = () => { + const { refetch } = useLayout(); // State management const [selectedFile, setSelectedFile] = useState(null); const [isProcessingPptx, setIsProcessingPptx] = useState(false); @@ -311,6 +313,7 @@ const CustomLayoutPage = () => { ); toast.success(`Layout saved successfully`); + refetch(); setIsLayoutSaved(true); } catch (error) { console.error("Error saving layout:", error); @@ -559,8 +562,6 @@ const CustomLayoutPage = () => { const completedSlides = slides.filter( (slide) => slide.processed || slide.error ).length; - const progressPercentage = - slides.length > 0 ? Math.round((completedSlides / slides.length) * 100) : 0; return (

@@ -577,17 +578,6 @@ const CustomLayoutPage = () => {

- {/* Global Font Management */} - {fontsData && ( - - )} - {/* Upload Section */} @@ -599,6 +589,14 @@ const CustomLayoutPage = () => { Select a PowerPoint file (.pptx) to process. Maximum file size: 50MB + {slides.length > 0 && ( +
+ {slides.some((s) => s.processing) && ( + + )} + {completedSlides}/{slides.length} slides completed +
+ )}
{!selectedFile ? ( @@ -663,28 +661,15 @@ const CustomLayoutPage = () => {
- {/* Progress Section */} - {slides.length > 0 && ( - - - - Processing Progress - - {completedSlides}/{slides.length} slides completed - - - - Converting slides to HTML layouts... - - - - -
- Progress: {progressPercentage}% - {slides.length} total slides -
-
-
+ {/* Global Font Management */} + {fontsData && ( + )} {/* Slides Section */}