diff --git a/servers/nextjs/app/(presentation-generator)/context/LayoutContext.tsx b/servers/nextjs/app/(presentation-generator)/context/LayoutContext.tsx new file mode 100644 index 00000000..d806faa7 --- /dev/null +++ b/servers/nextjs/app/(presentation-generator)/context/LayoutContext.tsx @@ -0,0 +1,209 @@ +"use client"; +import React, { createContext, useContext, useEffect, useState, ReactNode } from 'react'; +import dynamic from 'next/dynamic'; +import { toast } from "@/hooks/use-toast"; +import * as z from 'zod'; + +interface LayoutInfo { + id: string; + name?: string; + description?: string; + json_schema: any; +} + +interface LayoutContextType { + layoutSchema: LayoutInfo[] | null; + idMapFileNames: Record; + idMapSchema: Record; + loading: boolean; + error: string | null; + getLayout: (layoutId: string) => React.ComponentType<{ data: any }> | null; + isPreloading: boolean; + cacheSize: number; + refetch: () => Promise; +} + +const LayoutContext = createContext(undefined); + +// Global layout cache +const layoutCache = new Map>(); + +export const LayoutProvider: React.FC<{ children: ReactNode }> = ({ children }) => { + const [layoutSchema, setLayoutSchema] = useState(null); + const [idMapFileNames, setIdMapFileNames] = useState>({}); + const [idMapSchema, setIdMapSchema] = useState>({}); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + const [isPreloading, setIsPreloading] = useState(false); + + const extractSchema = async (layoutFiles: string[]) => { + const layouts: LayoutInfo[] = []; + const idMapFileNames: Record = {}; + const idMapSchema: Record = {}; + + for (const fileName of layoutFiles) { + try { + const file = fileName.replace('.tsx', '').replace('.ts', ''); + const module = await import(`@/components/layouts/${file}`); + + if (!module.default) { + toast({ + title: `${file} has no default export`, + description: 'Please ensure the layout file exports a default component', + }); + console.warn(`${file} has no default export`); + continue; + } + + if (!module.Schema) { + toast({ + title: `${file} has no Schema export`, + description: 'Please ensure the layout file exports a Schema', + }); + console.warn(`${file} has no Schema export`); + continue; + } + + const layoutId = module.layoutId; + if (!layoutId) { + toast({ + title: `${file} has no layoutId`, + description: 'Please ensure the layout file exports a layoutId', + }); + console.warn(`${file} has no layoutId`); + continue; + } + + const layoutName = module.layoutName; + const layoutDescription = module.layoutDescription; + const jsonSchema = z.toJSONSchema(module.Schema, { + override: (ctx) => { + delete ctx.jsonSchema.default; + }, + }); + + const layout = { + id: layoutId, + name: layoutName, + description: layoutDescription, + json_schema: jsonSchema, + }; + + idMapFileNames[layoutId] = fileName; + idMapSchema[layoutId] = module.Schema; + layouts.push(layout); + } catch (error) { + console.error(`Error extracting schema for ${fileName}:`, error); + } + } + + return { layouts, idMapFileNames, idMapSchema }; + }; + + const loadLayouts = async () => { + if (layoutSchema) return; // Already loaded + + try { + setLoading(true); + setError(null); + + const layoutResponse = await fetch('/api/layouts'); + const layoutFiles = await layoutResponse.json(); + const response = await extractSchema(layoutFiles); + + setLayoutSchema(response?.layouts || []); + setIdMapFileNames(response?.idMapFileNames || {}); + setIdMapSchema(response?.idMapSchema || {}); + + // Preload layouts after loading schema + await preloadLayouts(response?.idMapFileNames || {}); + } catch (err: unknown) { + const errorMessage = err instanceof Error ? err.message : 'Failed to load layouts'; + setError(errorMessage); + console.error('Error loading layouts:', err); + } finally { + setLoading(false); + } + }; + + const preloadLayouts = async (fileNames: Record) => { + setIsPreloading(true); + + try { + const layoutPromises = Object.values(fileNames).map(async (layoutName) => { + if (!layoutCache.has(layoutName)) { + const Layout = dynamic( + () => import(`@/components/layouts/${layoutName}`), + { + loading: () =>
, + ssr: false, + } + ) as React.ComponentType<{ data: any }>; + + layoutCache.set(layoutName, Layout); + } + }); + + await Promise.all(layoutPromises); + } catch (error) { + console.error('Error preloading layouts:', error); + } finally { + setIsPreloading(false); + } + }; + + const getLayout = (layoutId: string): React.ComponentType<{ data: any }> | null => { + const layoutName = idMapFileNames[layoutId]; + if (!layoutName) { + return null; + } + + // Return cached layout if available + if (layoutCache.has(layoutName)) { + return layoutCache.get(layoutName)!; + } + + // Create and cache layout if not available + const Layout = dynamic( + () => import(`@/components/layouts/${layoutName}`), + { + loading: () =>
, + ssr: false, + } + ) as React.ComponentType<{ data: any }>; + + layoutCache.set(layoutName, Layout); + return Layout; + }; + + // Load layouts on mount + useEffect(() => { + loadLayouts(); + }, []); + + const contextValue: LayoutContextType = { + layoutSchema, + idMapFileNames, + idMapSchema, + loading, + error, + getLayout, + isPreloading, + cacheSize: layoutCache.size, + refetch: loadLayouts, + }; + + return ( + + {children} + + ); +}; + +export const useLayout = (): LayoutContextType => { + const context = useContext(LayoutContext); + if (context === undefined) { + throw new Error('useLayout must be used within a LayoutProvider'); + } + return context; +}; \ No newline at end of file diff --git a/servers/nextjs/app/(presentation-generator)/documents-preview/components/DocumentPreviewPage.tsx b/servers/nextjs/app/(presentation-generator)/documents-preview/components/DocumentPreviewPage.tsx index 1e18f58e..14efe8ee 100644 --- a/servers/nextjs/app/(presentation-generator)/documents-preview/components/DocumentPreviewPage.tsx +++ b/servers/nextjs/app/(presentation-generator)/documents-preview/components/DocumentPreviewPage.tsx @@ -29,7 +29,7 @@ import { getIconFromFile } from "../../utils/others"; import { ChevronRight, PanelRightOpen, X } from "lucide-react"; import ToolTip from "@/components/ToolTip"; import Header from "@/app/dashboard/components/Header"; -import useLayoutSchema from "../../hooks/useLayoutSchema"; +import { useLayout } from "../../context/LayoutContext"; // Types interface LoadingState { @@ -70,7 +70,7 @@ const DocumentsPreviewPage: React.FC = () => { duration: 10, progress: false, }); - const { layoutSchema } = useLayoutSchema(); + const { layoutSchema } = useLayout(); // Memoized computed values const fileItems: FileItem[] = useMemo(() => { diff --git a/servers/nextjs/app/(presentation-generator)/hooks/useLayoutCache.tsx b/servers/nextjs/app/(presentation-generator)/hooks/useLayoutCache.tsx deleted file mode 100644 index f6fcac0b..00000000 --- a/servers/nextjs/app/(presentation-generator)/hooks/useLayoutCache.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import React, { useState, useEffect, useRef } from "react"; -import dynamic from "next/dynamic"; -import useLayoutSchema from "./useLayoutSchema"; - -// Global layout cache to persist across component unmounts -const layoutCache = new Map>(); - -const useLayoutCache = () => { - const { idMapFileNames, loading } = useLayoutSchema(); - const [isPreloading, setIsPreloading] = useState(false); - const preloadedRef = useRef(false); - - // Pre-load all layouts when schema is available - useEffect(() => { - if (!loading && idMapFileNames && Object.keys(idMapFileNames).length > 0 && !preloadedRef.current) { - preloadLayouts(); - preloadedRef.current = true; - } - }, [idMapFileNames, loading]); - - const preloadLayouts = async () => { - if (isPreloading) return; - - setIsPreloading(true); - - try { - const layoutPromises = Object.values(idMapFileNames).map(async (layoutName) => { - if (!layoutCache.has(layoutName)) { - const Layout = dynamic( - () => import(`@/components/layouts/${layoutName}`), - { - loading: () =>
, - ssr: false, - } - ) as React.ComponentType<{ data: any }>; - - layoutCache.set(layoutName, Layout); - } - }); - - await Promise.all(layoutPromises); - } catch (error) { - console.error('Error preloading layouts:', error); - } finally { - setIsPreloading(false); - } - }; - - const getLayout = (layoutId: string): React.ComponentType<{ data: any }> | null => { - const layoutName = idMapFileNames[layoutId]; - if (!layoutName) { - return null; - } - - // Return cached layout if available - if (layoutCache.has(layoutName)) { - return layoutCache.get(layoutName)!; - } - - // Create and cache layout if not available - const Layout = dynamic( - () => import(`@/components/layouts/${layoutName}`), - { - loading: () =>
, - ssr: false, - } - ) as React.ComponentType<{ data: any }>; - - layoutCache.set(layoutName, Layout); - return Layout; - }; - - const clearCache = () => { - layoutCache.clear(); - preloadedRef.current = false; - }; - - return { - getLayout, - isPreloading, - clearCache, - cacheSize: layoutCache.size, - }; -}; - -export default useLayoutCache; \ No newline at end of file diff --git a/servers/nextjs/app/(presentation-generator)/hooks/useLayoutSchema.ts b/servers/nextjs/app/(presentation-generator)/hooks/useLayoutSchema.ts deleted file mode 100644 index e019d078..00000000 --- a/servers/nextjs/app/(presentation-generator)/hooks/useLayoutSchema.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { useState, useEffect } from "react"; -import { toast } from "@/hooks/use-toast"; -import * as z from 'zod'; -interface LayoutInfo { - id: string; - name?: string; - description?: string; - json_schema: any; -} - -// interface LayoutStructure { -// name: string; -// ordered: boolean; -// slides: LayoutInfo[]; -// } - -const useLayoutSchema = () => { - const [layoutSchema, setLayoutSchema] = useState(null); - const [idMapFileNames, setIdMapFileNames] = useState>({}); - const [idMapSchema, setIdMapSchema] = useState>({}); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); - - const loadLayouts = async () => { - try { - setLoading(true); - setError(null); - const layoutResponse = await fetch('/api/layouts'); - const layoutFiles = await layoutResponse.json(); - const response = await extractSchema(layoutFiles); - - setLayoutSchema(response?.layouts || []); - setIdMapFileNames(response?.idMapFileNames || {}); - setIdMapSchema(response?.idMapSchema || {}); - } catch (err: unknown) { - const errorMessage = err instanceof Error ? err.message : 'Failed to load layouts'; - setError(errorMessage); - console.error('Error loading layouts:', err); - } finally { - setLoading(false); - } - }; - - - - // Auto-load layouts on mount - useEffect(() => { - loadLayouts(); - }, []); - - return { - layoutSchema, - setLayoutSchema, - loading, - error, - refetch: loadLayouts, - idMapFileNames, - idMapSchema - }; -}; - -export default useLayoutSchema; - - -const extractSchema = async (layoutFiles: string[]) => { - const layouts: LayoutInfo[] = []; - const idMapFileNames: Record = {}; - const idMapSchema: Record = {}; - for (const fileName of layoutFiles) { - try { - const file = fileName.replace('.tsx', '').replace('.ts', '') - const module = await import(`@/components/layouts/${file}`) - if (!module.default) { - toast({ - title: `${file} has no default export`, - description: 'Please ensure the layout file exports a default component', - }) - console.warn(`${file} has no default export`) - return - } - if (!module.Schema) { - toast({ - title: `${file} has no Schema export`, - description: 'Please ensure the layout file exports a Schema', - }) - console.warn(`${file} has no Schema export`) - return - } - const layoutId = module.layoutId - if(!layoutId) { - toast({ - title: `${file} has no layoutId`, - description: 'Please ensure the layout file exports a layoutId', - }) - console.warn(`${file} has no layoutId`) - return - } - const layoutName = module.layoutName - const layoutDescription = module.layoutDescription - const jsonSchema = z.toJSONSchema(module.Schema,{ - override :(ctx)=>{ - delete ctx.jsonSchema.default - }, - }) - const layout = { - id: layoutId, - name: layoutName, - description: layoutDescription, - json_schema: jsonSchema, - } - idMapFileNames[layoutId] = fileName - idMapSchema[layoutId] = module.Schema - layouts.push(layout) - } catch (error) { - console.error(`Error extracting schema for ${fileName}:`, error) - return null - } - } - return {layouts, idMapFileNames, idMapSchema} -}; diff --git a/servers/nextjs/app/(presentation-generator)/presentation/components/PresentationPage.tsx b/servers/nextjs/app/(presentation-generator)/presentation/components/PresentationPage.tsx index d398fdd7..a3d50bf7 100644 --- a/servers/nextjs/app/(presentation-generator)/presentation/components/PresentationPage.tsx +++ b/servers/nextjs/app/(presentation-generator)/presentation/components/PresentationPage.tsx @@ -260,18 +260,6 @@ const PresentationPage = ({ presentation_id }: { presentation_id: string }) => { try { const data = await DashboardApi.getPresentation(presentation_id); if (data) { - if (data.presentation.theme) { - dispatch( - setThemeColors({ - ...data.presentation.theme.colors, - theme: data.presentation.theme.name as ThemeType, - }) - ); - setColorsVariables( - data.presentation.theme.colors, - data.presentation.theme.name as ThemeType - ); - } dispatch(setPresentationData(data)); setLoading(false); } @@ -393,8 +381,8 @@ const PresentationPage = ({ presentation_id }: { presentation_id: string }) => { />
{!presentationData || loading || diff --git a/servers/nextjs/app/(presentation-generator)/presentation/components/SidePanel.tsx b/servers/nextjs/app/(presentation-generator)/presentation/components/SidePanel.tsx index 94b80189..93b8afb7 100644 --- a/servers/nextjs/app/(presentation-generator)/presentation/components/SidePanel.tsx +++ b/servers/nextjs/app/(presentation-generator)/presentation/components/SidePanel.tsx @@ -22,7 +22,7 @@ import { import { setPresentationData } from "@/store/slices/presentationGeneration"; import { SortableSlide } from "./SortableSlide"; import { SortableListItem } from "./SortableListItem"; -import useLayoutCache from "../../hooks/useLayoutCache"; +import { useLayout } from "../../context/LayoutContext"; interface SidePanelProps { selectedSlide: number; @@ -50,7 +50,7 @@ const SidePanel = ({ ); console.log('presentationData', presentationData) const dispatch = useDispatch(); - const { getLayout } = useLayoutCache(); + const { getLayout } = useLayout(); // Memoized slide renderer using layout cache const renderSlideContent = useMemo(() => { diff --git a/servers/nextjs/app/(presentation-generator)/presentation/components/SlideContent.tsx b/servers/nextjs/app/(presentation-generator)/presentation/components/SlideContent.tsx index e0029a9b..6063eb4b 100644 --- a/servers/nextjs/app/(presentation-generator)/presentation/components/SlideContent.tsx +++ b/servers/nextjs/app/(presentation-generator)/presentation/components/SlideContent.tsx @@ -16,7 +16,7 @@ import { useDispatch, useSelector } from "react-redux"; import { addSlide, updateSlide } from "@/store/slices/presentationGeneration"; import NewSlide from "../../components/slide_layouts/NewSlide"; import { getEmptySlideContent } from "../../utils/NewSlideContent"; -import useLayoutCache from "../../hooks/useLayoutCache"; +import { useLayout } from "../../context/LayoutContext"; interface SlideContentProps { slide: any; @@ -37,13 +37,15 @@ const SlideContent = ({ const { presentationData, isStreaming } = useSelector( (state: RootState) => state.presentationGeneration ); - const { getLayout } = useLayoutCache(); + const { getLayout, loading } = useLayout(); // Memoized layout component to prevent re-renders const LayoutComponent = useMemo(() => { const Layout = getLayout(slide.layout); if (!Layout) { - return () =>
Layout not found
; + return () =>
+ Layout not found +
; } return Layout; }, [slide.layout, getLayout]); @@ -122,7 +124,7 @@ const SlideContent = ({ ) { // Scroll to the last slide (newly generated during streaming) const lastSlideIndex = presentationData.slides.length - 1; - const slideElement = document.getElementById(`slide-${presentationData.slides[lastSlideIndex].id}`); + const slideElement = document.getElementById(`slide-${presentationData.slides[lastSlideIndex].index}`); if (slideElement) { slideElement.scrollIntoView({ behavior: "smooth", @@ -140,7 +142,7 @@ const SlideContent = ({ return ( <>
{isStreaming && ( @@ -148,7 +150,9 @@ const SlideContent = ({ )}
{/* render slides */} - {slideContent} + {loading ?
+ +
: slideContent} {!showNewSlideSelection && (
diff --git a/servers/nextjs/app/(presentation-generator)/presentation/components/SortableListItem.tsx b/servers/nextjs/app/(presentation-generator)/presentation/components/SortableListItem.tsx index 30e88ac6..1aad2a56 100644 --- a/servers/nextjs/app/(presentation-generator)/presentation/components/SortableListItem.tsx +++ b/servers/nextjs/app/(presentation-generator)/presentation/components/SortableListItem.tsx @@ -38,7 +38,7 @@ export function SortableListItem({ slide, index, selectedSlide, onSlideClick }: // If the mouse was down for less than 200ms, consider it a click if (timeDiff < 200 && !isDragging) { - onSlideClick(slide.id); + onSlideClick(slide.index); } }; @@ -50,10 +50,10 @@ export function SortableListItem({ slide, index, selectedSlide, onSlideClick }: {...listeners} onMouseDown={handleMouseDown} onMouseUp={handleMouseUp} - className={`p-3 cursor-pointer rounded-lg slide-box + className={`p-3 cursor-pointer ring-0 border-[3px] rounded-lg slide-box ${selectedSlide === index - ? 'ring-2 ring-[#5141e5] text-white' - : 'hover:slide-box/40' + ? ' border-[#5141e5] ' + : 'hover:slide-box/40 border-gray-300' }`} > Slide {index + 1} diff --git a/servers/nextjs/app/(presentation-generator)/presentation/components/SortableSlide.tsx b/servers/nextjs/app/(presentation-generator)/presentation/components/SortableSlide.tsx index de527cc6..fe4cf9e9 100644 --- a/servers/nextjs/app/(presentation-generator)/presentation/components/SortableSlide.tsx +++ b/servers/nextjs/app/(presentation-generator)/presentation/components/SortableSlide.tsx @@ -39,7 +39,7 @@ export function SortableSlide({ slide, index, selectedSlide, onSlideClick, rende // If the mouse was down for less than 200ms, consider it a click if (timeDiff < 200 && !isDragging) { - onSlideClick(slide.id); + onSlideClick(slide.index); } }; @@ -51,7 +51,7 @@ export function SortableSlide({ slide, index, selectedSlide, onSlideClick, rende {...listeners} onMouseDown={handleMouseDown} onMouseUp={handleMouseUp} - className={` cursor-pointer border-[3px] p-1 shadow-lg rounded-md transition-all duration-200 ${selectedSlide === index ? ' border-[#5141e5]' : 'border-color' + className={` cursor-pointer border-[3px] p-1 shadow-lg rounded-md transition-all duration-200 ${selectedSlide === index ? ' border-[#5141e5]' : 'border-gray-300' }`} >
diff --git a/servers/nextjs/app/(presentation-generator)/upload/components/UploadPage.tsx b/servers/nextjs/app/(presentation-generator)/upload/components/UploadPage.tsx index 93ce4b4a..0f99f20d 100644 --- a/servers/nextjs/app/(presentation-generator)/upload/components/UploadPage.tsx +++ b/servers/nextjs/app/(presentation-generator)/upload/components/UploadPage.tsx @@ -25,7 +25,7 @@ import { PresentationGenerationApi } from "../../services/api/presentation-gener import { OverlayLoader } from "@/components/ui/overlay-loader"; import Wrapper from "@/components/Wrapper"; import { setPptGenUploadState } from "@/store/slices/presentationGenUpload"; -import useLayoutSchema from "../../hooks/useLayoutSchema"; +import { useLayout } from "../../context/LayoutContext"; // Types for loading state interface LoadingState { @@ -40,7 +40,7 @@ const UploadPage = () => { const router = useRouter(); const dispatch = useDispatch(); const { toast } = useToast(); - const { layoutSchema, loading: layoutsLoading, error: layoutsError } = useLayoutSchema(); + const { layoutSchema, loading: layoutsLoading, error: layoutsError } = useLayout(); // State management const [files, setFiles] = useState([]); diff --git a/servers/nextjs/app/(presentation-generator)/upload/page.tsx b/servers/nextjs/app/(presentation-generator)/upload/page.tsx index 5260ccbf..13d3c028 100644 --- a/servers/nextjs/app/(presentation-generator)/upload/page.tsx +++ b/servers/nextjs/app/(presentation-generator)/upload/page.tsx @@ -39,18 +39,18 @@ export const metadata: Metadata = { } const page = () => { - return (
-

Create Presentation

{/*

We will generate a presentation for you

*/}
- -
) + + +
) } + export default page diff --git a/servers/nextjs/app/dashboard/api/dashboard.ts b/servers/nextjs/app/dashboard/api/dashboard.ts index cc3ab590..89d7fbde 100644 --- a/servers/nextjs/app/dashboard/api/dashboard.ts +++ b/servers/nextjs/app/dashboard/api/dashboard.ts @@ -1,6 +1,5 @@ import { getHeader, - getHeaderForFormData, } from "@/app/(presentation-generator)/services/api/header"; @@ -28,7 +27,7 @@ export class DashboardApi { static async getPresentations(): Promise { try { const response = await fetch( - `/api/v1/ppt/user_presentations`, + `/api/v1/ppt/presentation/all`, { method: "GET", } @@ -49,7 +48,7 @@ export class DashboardApi { static async getPresentation(id: string) { try { const response = await fetch( - `/api/v1/ppt/presentation?presentation_id=${id}`, + `/api/v1/ppt/presentation/?id=${id}`, { method: "GET", @@ -68,7 +67,7 @@ export class DashboardApi { static async deletePresentation(presentation_id: string) { try { const response = await fetch( - `/api/v1/ppt/delete?presentation_id=${presentation_id}`, + `/api/v1/ppt/delete?id=${presentation_id}`, { method: "DELETE", headers: getHeader(), diff --git a/servers/nextjs/app/layout.tsx b/servers/nextjs/app/layout.tsx index 783bf2b9..d8ea12de 100644 --- a/servers/nextjs/app/layout.tsx +++ b/servers/nextjs/app/layout.tsx @@ -5,6 +5,7 @@ import "./globals.css"; import { Providers } from "./providers"; import { Toaster } from "@/components/ui/toaster"; import { FooterProvider } from "./(presentation-generator)/context/footerContext"; +import { LayoutProvider } from "./(presentation-generator)/context/LayoutContext"; const fraunces = Fraunces({ subsets: ["latin"], @@ -102,10 +103,13 @@ export default function RootLayout({ className={`$ ${inter.variable} ${fraunces.variable} ${montserrat.variable} ${inria_serif.variable} ${roboto.variable} ${instrument_sans.variable} antialiased`} > - + + - {children} - + + {children} + + diff --git a/servers/nextjs/components/layouts/Type1SlideLayout.tsx b/servers/nextjs/components/layouts/Type1SlideLayout.tsx index 30c73952..6b587fbb 100644 --- a/servers/nextjs/components/layouts/Type1SlideLayout.tsx +++ b/servers/nextjs/components/layouts/Type1SlideLayout.tsx @@ -33,7 +33,7 @@ const Type1SlideLayout: React.FC = ({ data: slideData }) return (
diff --git a/servers/nextjs/components/layouts/Type2NumberedSlideLayout.tsx b/servers/nextjs/components/layouts/Type2NumberedSlideLayout.tsx index 74d6b10f..0dc07e76 100644 --- a/servers/nextjs/components/layouts/Type2NumberedSlideLayout.tsx +++ b/servers/nextjs/components/layouts/Type2NumberedSlideLayout.tsx @@ -49,7 +49,7 @@ const Type2NumberedSlideLayout: React.FC = ({ dat const renderGridContent = () => { return ( -
+
{items.map((item, index) => (
= ({ dat const renderHorizontalContent = () => { return ( -
+
{items.map((item, index) => (
= ({ dat return (
diff --git a/servers/nextjs/components/layouts/Type2SlideLayout.tsx b/servers/nextjs/components/layouts/Type2SlideLayout.tsx index 49f744ed..979117fa 100644 --- a/servers/nextjs/components/layouts/Type2SlideLayout.tsx +++ b/servers/nextjs/components/layouts/Type2SlideLayout.tsx @@ -94,7 +94,7 @@ const Type2SlideLayout: React.FC = ({ data: slideData }) return (
diff --git a/servers/nextjs/components/layouts/Type2TimelineSlideLayout.tsx b/servers/nextjs/components/layouts/Type2TimelineSlideLayout.tsx index 580627d1..2684fd06 100644 --- a/servers/nextjs/components/layouts/Type2TimelineSlideLayout.tsx +++ b/servers/nextjs/components/layouts/Type2TimelineSlideLayout.tsx @@ -86,7 +86,7 @@ const Type2TimelineSlideLayout: React.FC = ({ dat return (

diff --git a/servers/nextjs/components/layouts/Type3SlideLayout.tsx b/servers/nextjs/components/layouts/Type3SlideLayout.tsx index 21385dba..2d5db420 100644 --- a/servers/nextjs/components/layouts/Type3SlideLayout.tsx +++ b/servers/nextjs/components/layouts/Type3SlideLayout.tsx @@ -73,7 +73,7 @@ const Type3SlideLayout: React.FC = ({ data: slideData }) return (
diff --git a/servers/nextjs/components/layouts/Type4SlideLayout.tsx b/servers/nextjs/components/layouts/Type4SlideLayout.tsx index 1fbb236f..f89f9ec5 100644 --- a/servers/nextjs/components/layouts/Type4SlideLayout.tsx +++ b/servers/nextjs/components/layouts/Type4SlideLayout.tsx @@ -44,14 +44,14 @@ const Type4SlideLayout: React.FC = ({ data: slideData }) return (

{slideData?.title || 'Chart Analysis'}

-
diff --git a/servers/nextjs/components/layouts/Type5SlideLayout.tsx b/servers/nextjs/components/layouts/Type5SlideLayout.tsx index 91765142..9a3a0a74 100644 --- a/servers/nextjs/components/layouts/Type5SlideLayout.tsx +++ b/servers/nextjs/components/layouts/Type5SlideLayout.tsx @@ -51,7 +51,7 @@ const Type5SlideLayout: React.FC = ({ data: slideData }) return (
diff --git a/servers/nextjs/components/layouts/Type6SlideLayout.tsx b/servers/nextjs/components/layouts/Type6SlideLayout.tsx index c199e288..34f2656c 100644 --- a/servers/nextjs/components/layouts/Type6SlideLayout.tsx +++ b/servers/nextjs/components/layouts/Type6SlideLayout.tsx @@ -133,7 +133,7 @@ const Type6SlideLayout: React.FC = ({ data: slideData }) return (
diff --git a/servers/nextjs/components/layouts/Type7SlideLayout.tsx b/servers/nextjs/components/layouts/Type7SlideLayout.tsx index b717e433..98700163 100644 --- a/servers/nextjs/components/layouts/Type7SlideLayout.tsx +++ b/servers/nextjs/components/layouts/Type7SlideLayout.tsx @@ -157,7 +157,7 @@ const Type7SlideLayout: React.FC = ({ data: slideData }) return (

diff --git a/servers/nextjs/components/layouts/Type8SlideLayout.tsx b/servers/nextjs/components/layouts/Type8SlideLayout.tsx index a87b18d5..b2b7494a 100644 --- a/servers/nextjs/components/layouts/Type8SlideLayout.tsx +++ b/servers/nextjs/components/layouts/Type8SlideLayout.tsx @@ -141,7 +141,7 @@ const Type8SlideLayout: React.FC = ({ data: slideData }) return (
{/* Left section - Title and Description */}