From 3847336af686847daf22eb11b3fa7e3a7e21da85 Mon Sep 17 00:00:00 2001 From: shiva raj badu Date: Thu, 17 Jul 2025 15:27:37 +0545 Subject: [PATCH] chore(nextjs) --- .../context/LayoutContext.tsx | 30 +++++++- .../hooks/useGroupLayouts.tsx | 68 +++++++++++++++++++ .../outline/components/LayoutSelection.tsx | 65 +++++------------- .../outline/components/OutlinePage.tsx | 20 +++++- .../components/PresentationPage.tsx | 68 ++++++------------- .../presentation/components/SidePanel.tsx | 17 ++--- .../presentation/components/SlideContent.tsx | 23 ++++--- .../services/api/presentation-generation.ts | 3 + .../upload/components/UploadPage.tsx | 5 -- servers/nextjs/app/api/layouts/route.ts | 33 ++++++++- .../layout-preview/hooks/useLayoutLoader.ts | 21 +++++- .../nextjs/app/layout-preview/types/index.ts | 10 +++ .../presentation-layouts/default/setting.json | 3 +- .../modern/CardSlideLayout.tsx | 2 +- .../presentation-layouts/modern/setting.json | 3 +- .../professional/StatisticsSlideLayout.tsx | 2 +- .../store/slices/presentationGeneration.ts | 25 +++---- 17 files changed, 247 insertions(+), 151 deletions(-) create mode 100644 servers/nextjs/app/(presentation-generator)/hooks/useGroupLayouts.tsx diff --git a/servers/nextjs/app/(presentation-generator)/context/LayoutContext.tsx b/servers/nextjs/app/(presentation-generator)/context/LayoutContext.tsx index 5506aef2..08cbb7ea 100644 --- a/servers/nextjs/app/(presentation-generator)/context/LayoutContext.tsx +++ b/servers/nextjs/app/(presentation-generator)/context/LayoutContext.tsx @@ -12,13 +12,23 @@ interface LayoutInfo { group: string; } +interface GroupSetting { + id: string; + name: string; + description: string; + ordered: boolean; + isDefault?: boolean; +} + interface GroupedLayoutsResponse { group: string; files: string[]; + settings: GroupSetting | null; } interface LayoutContextType { layoutSchema: LayoutInfo[] | null; + groupSettings: Record; idMapFileNames: Record; idMapSchema: Record; idMapGroups: Record; @@ -37,6 +47,7 @@ const layoutCache = new Map>(); export const LayoutProvider: React.FC<{ children: ReactNode }> = ({ children }) => { const [layoutSchema, setLayoutSchema] = useState(null); + const [groupSettings, setGroupSettings] = useState>({}); const [idMapFileNames, setIdMapFileNames] = useState>({}); const [idMapSchema, setIdMapSchema] = useState>({}); const [idMapGroups, setIdMapGroups] = useState>({}); @@ -49,8 +60,23 @@ export const LayoutProvider: React.FC<{ children: ReactNode }> = ({ children }) const idMapFileNames: Record = {}; const idMapSchema: Record = {}; const idMapGroups: Record = {}; + const groupSettings: Record = {}; for (const groupData of groupedLayoutsData) { + // Store group settings + if (groupData.settings) { + groupSettings[groupData.group] = groupData.settings; + } else { + // Provide default settings if not available + groupSettings[groupData.group] = { + id: groupData.group, + name: groupData.group.charAt(0).toUpperCase() + groupData.group.slice(1), + description: `${groupData.group} presentation layouts`, + ordered: false, + isDefault: false + }; + } + for (const fileName of groupData.files) { try { const file = fileName.replace('.tsx', '').replace('.ts', ''); @@ -102,7 +128,7 @@ export const LayoutProvider: React.FC<{ children: ReactNode }> = ({ children }) } } - return { layouts, idMapFileNames, idMapSchema, idMapGroups }; + return { layouts, idMapFileNames, idMapSchema, idMapGroups, groupSettings }; }; const loadLayouts = async () => { @@ -119,6 +145,7 @@ export const LayoutProvider: React.FC<{ children: ReactNode }> = ({ children }) const response = await extractSchema(groupedLayoutsData); setLayoutSchema(response?.layouts || []); + setGroupSettings(response?.groupSettings || {}); setIdMapFileNames(response?.idMapFileNames || {}); setIdMapSchema(response?.idMapSchema || {}); setIdMapGroups(response?.idMapGroups || {}); @@ -200,6 +227,7 @@ export const LayoutProvider: React.FC<{ children: ReactNode }> = ({ children }) const contextValue: LayoutContextType = { layoutSchema, + groupSettings, idMapFileNames, idMapSchema, idMapGroups, diff --git a/servers/nextjs/app/(presentation-generator)/hooks/useGroupLayouts.tsx b/servers/nextjs/app/(presentation-generator)/hooks/useGroupLayouts.tsx new file mode 100644 index 00000000..855e1707 --- /dev/null +++ b/servers/nextjs/app/(presentation-generator)/hooks/useGroupLayouts.tsx @@ -0,0 +1,68 @@ +'use client' +import React, { useMemo } from 'react'; +import { useLayout } from '../context/LayoutContext'; +import { useSelector } from 'react-redux'; +import { RootState } from '@/store/store'; + +interface LayoutInfo { + id: string; + name?: string; + description?: string; + json_schema: any; + group: string; +} + +export const useGroupLayouts = () => { + const { layoutSchema, getLayout, loading } = useLayout(); + const { presentationData } = useSelector((state: RootState) => state.presentationGeneration); + + // Get the selected group name from presentation data + const selectedGroupName = presentationData?.layouts?.name?.toLowerCase() ?? null; + + // Filter layouts to only include those from the selected group + const groupLayouts = useMemo(() => { + if (!layoutSchema || !selectedGroupName) return []; + + return layoutSchema.filter(layout => layout.group === selectedGroupName); + }, [layoutSchema, selectedGroupName]); + + // Get group-specific layout component with validation + const getGroupLayout = useMemo(() => { + return (layoutId: string) => { + // First check if the layout exists in the current group + const groupLayout = groupLayouts.find(layout => layout.id === layoutId); + if (groupLayout) { + return getLayout(layoutId); + } + + // If layout not found in group, return null + console.warn(`Layout ${layoutId} not found in group ${selectedGroupName}`); + return null; + }; + }, [groupLayouts, selectedGroupName, getLayout]); + + // Render slide content with group validation + const renderSlideContent = useMemo(() => { + return (slide: any) => { + const Layout = getGroupLayout(slide.layout); + if (!Layout) { + return ( +
+

+ Layout "{slide.layout}" not found in "{selectedGroupName}" group +

+
+ ); + } + return ; + }; + }, [getGroupLayout, selectedGroupName]); + + return { + groupLayouts, + selectedGroupName, + getGroupLayout, + renderSlideContent, + loading + }; +}; \ No newline at end of file diff --git a/servers/nextjs/app/(presentation-generator)/outline/components/LayoutSelection.tsx b/servers/nextjs/app/(presentation-generator)/outline/components/LayoutSelection.tsx index a6644a4c..8adab136 100644 --- a/servers/nextjs/app/(presentation-generator)/outline/components/LayoutSelection.tsx +++ b/servers/nextjs/app/(presentation-generator)/outline/components/LayoutSelection.tsx @@ -21,9 +21,9 @@ const LayoutSelection: React.FC = ({ selectedLayoutGroup, onSelectLayoutGroup }) => { - const { layoutSchema, getLayout, loading } = useLayout(); + const { layoutSchema, groupSettings, getLayout, loading } = useLayout(); - // Create layout groups from the loaded layout schema + // Convert layoutSchema to grouped format using actual group settings const layoutGroups: LayoutGroup[] = React.useMemo(() => { if (!layoutSchema || layoutSchema.length === 0) return []; @@ -37,27 +37,29 @@ const LayoutSelection: React.FC = ({ groupMap.get(groupName)?.push(layout); }); - // Convert to LayoutGroup format + // Convert to LayoutGroup format using actual group settings const groups: LayoutGroup[] = []; groupMap.forEach((layouts, groupName) => { + const settings = groupSettings[groupName]; + const group: LayoutGroup = { - id: groupName, - name: groupName.charAt(0).toUpperCase() + groupName.slice(1), - description: getGroupDescription(groupName), - ordered: getGroupOrdered(groupName), - isDefault: groupName === 'professional', - slides: layouts.map(layout => layout.id) + id: settings?.id || groupName, + name: settings?.name || groupName.charAt(0).toUpperCase() + groupName.slice(1), + description: settings?.description || `${groupName} presentation layouts`, + ordered: settings?.ordered || false, + isDefault: settings?.isDefault || false, + slides: layouts.map((layout: any) => layout.id) }; groups.push(group); }); - // Sort groups to put default first + // Sort groups to put default first, then by name return groups.sort((a, b) => { - if (a.isDefault) return -1; - if (b.isDefault) return 1; + if (a.isDefault && !b.isDefault) return -1; + if (!a.isDefault && b.isDefault) return 1; return a.name.localeCompare(b.name); }); - }, [layoutSchema]); + }, [layoutSchema, groupSettings]); // Auto-select first group when groups are loaded useEffect(() => { @@ -67,22 +69,6 @@ const LayoutSelection: React.FC = ({ } }, [layoutGroups, selectedLayoutGroup, onSelectLayoutGroup]); - const getGroupDescription = (groupName: string): string => { - const descriptions: Record = { - professional: 'Clean, corporate designs perfect for business presentations', - modern: 'Contemporary designs with clean lines and sophisticated layouts', - default: 'Standard layouts suitable for general presentations', - creative: 'Vibrant, artistic layouts for innovative presentations', - minimal: 'Simple, focused layouts that emphasize content' - }; - return descriptions[groupName] || `${groupName} presentation layouts`; - }; - - const getGroupOrdered = (groupName: string): boolean => { - const orderedGroups = ['professional', 'modern']; - return orderedGroups.includes(groupName); - }; - const renderLayoutPreview = (layoutId: string) => { const Layout = getLayout(layoutId); if (!Layout) { @@ -112,14 +98,6 @@ const LayoutSelection: React.FC = ({ if (loading) { return (
-
-
- Loading Layout Styles... -
-

- Please wait while we load the available presentation styles. -

-
{[1, 2, 3, 4].map((i) => (
@@ -140,8 +118,8 @@ const LayoutSelection: React.FC = ({ if (layoutGroups.length === 0) { return (
-
-
+
+
No Layout Styles Available

@@ -154,15 +132,6 @@ const LayoutSelection: React.FC = ({ return (

-
-
- Select Your Presentation Style -
-

- Choose a layout group that best fits your presentation style and content. -

-
-
{layoutGroups.map((group) => (
{ const dispatch = useDispatch(); const router = useRouter(); + const { layoutSchema } = useLayout(); const { presentation_id, outlines } = useSelector( (state: RootState) => state.presentationGeneration @@ -190,13 +192,27 @@ const OutlinePage = () => { }); try { - // Prepare layout data in the expected format + // Collect the actual schemas for layouts in the selected group + const groupLayoutSchemas = selectedLayoutGroup.slides + .map(slideId => { + const layout = layoutSchema?.find(l => l.id === slideId); + return layout ? { + id: layout.id, + name: layout.name, + description: layout.description, + json_schema: layout.json_schema + } : null; + }) + .filter(schema => schema !== null); + + // Prepare layout data in the expected format with schemas const layoutData = { name: selectedLayoutGroup.name, ordered: selectedLayoutGroup.ordered, - slides: selectedLayoutGroup.slides + slides: groupLayoutSchemas }; + console.log("layoutData", layoutData); const response = await PresentationGenerationApi.presentationPrepare({ presentation_id: presentation_id, outlines: outlines, diff --git a/servers/nextjs/app/(presentation-generator)/presentation/components/PresentationPage.tsx b/servers/nextjs/app/(presentation-generator)/presentation/components/PresentationPage.tsx index a3d50bf7..2a5b0217 100644 --- a/servers/nextjs/app/(presentation-generator)/presentation/components/PresentationPage.tsx +++ b/servers/nextjs/app/(presentation-generator)/presentation/components/PresentationPage.tsx @@ -17,8 +17,7 @@ import { } from "@/store/slices/presentationGeneration"; import { toast } from "@/hooks/use-toast"; import { PresentationGenerationApi } from "../../services/api/presentation-generation"; -import { setThemeColors, ThemeColors } from "../../store/themeSlice"; -import { ThemeType } from "../../upload/type"; + import LoadingState from "../../components/LoadingState"; import Header from "../components/Header"; import { Loader2 } from "lucide-react"; @@ -135,7 +134,6 @@ const PresentationPage = ({ presentation_id }: { presentation_id: string }) => { ); evtSource.onopen = () => { - setColorsVariables(currentColors, currentTheme); }; evtSource.addEventListener("response", (event) => { @@ -157,7 +155,7 @@ const PresentationPage = ({ presentation_id }: { presentation_id: string }) => { partialData.slides.splice(-1); dispatch( setPresentationData({ - presentation: null, + ...partialData, slides: partialData.slides, }) ); @@ -174,18 +172,7 @@ const PresentationPage = ({ presentation_id }: { presentation_id: string }) => { dispatch(setPresentationData(data.presentation)); dispatch(setStreaming(false)); - if (data.presentation.theme) { - dispatch( - setThemeColors({ - ...data.presentation.presentation.theme.colors, - theme: data.presentation.presentation.theme.name as ThemeType, - }) - ); - setColorsVariables( - data.presentation.presentation.theme.colors, - data.presentation.presentation.theme.name as ThemeType - ); - } + setLoading(false); evtSource.close(); @@ -200,18 +187,7 @@ const PresentationPage = ({ presentation_id }: { presentation_id: string }) => { accumulatedChunks = ""; } else if (data.type === "closing") { dispatch(setPresentationData(data.presentation)); - if (data.presentation.theme) { - dispatch( - setThemeColors({ - ...data.presentation.presentation.theme.colors, - theme: data.presentation.presentation.theme.name as ThemeType, - }) - ); - setColorsVariables( - data.presentation.presentation.theme.colors, - data.presentation.presentation.theme.name as ThemeType - ); - } + setLoading(false); dispatch(setStreaming(false)); evtSource.close(); @@ -275,13 +251,7 @@ const PresentationPage = ({ presentation_id }: { presentation_id: string }) => { setLoading(false); } }; - const setColorsVariables = (colors: ThemeColors, theme: ThemeType) => { - const root = document.documentElement; - Object.entries(colors).forEach(([key, value]) => { - const cssKey = key.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase()); - root.style.setProperty(`--${theme}-${cssKey}`, value); - }); - }; + // Function to toggle fullscreen const toggleFullscreen = () => { if (!document.fullscreenElement) { @@ -316,21 +286,21 @@ const PresentationPage = ({ presentation_id }: { presentation_id: string }) => { ); }; - if (isPresentMode) { - return ( - - ); - } + // slides={presentationData?.slides!} + // currentSlide={currentSlide} + // currentTheme={currentTheme} + // isFullscreen={isFullscreen} + // onFullscreenToggle={toggleFullscreen} + // onExit={handlePresentExit} + // onSlideChange={handleSlideChange} + // language={presentationData?.presentation?.language || "English"} + // /> + // ); + // } // Regular view return ( diff --git a/servers/nextjs/app/(presentation-generator)/presentation/components/SidePanel.tsx b/servers/nextjs/app/(presentation-generator)/presentation/components/SidePanel.tsx index 93b8afb7..41f0ff80 100644 --- a/servers/nextjs/app/(presentation-generator)/presentation/components/SidePanel.tsx +++ b/servers/nextjs/app/(presentation-generator)/presentation/components/SidePanel.tsx @@ -1,5 +1,5 @@ "use client"; -import React, { useState, useEffect, useMemo } from "react"; +import React, { useState, useEffect } from "react"; import { LayoutList, ListTree, PanelRightOpen, X } from "lucide-react"; import ToolTip from "@/components/ToolTip"; import { Button } from "@/components/ui/button"; @@ -22,7 +22,7 @@ import { import { setPresentationData } from "@/store/slices/presentationGeneration"; import { SortableSlide } from "./SortableSlide"; import { SortableListItem } from "./SortableListItem"; -import { useLayout } from "../../context/LayoutContext"; +import { useGroupLayouts } from "../../hooks/useGroupLayouts"; interface SidePanelProps { selectedSlide: number; @@ -50,18 +50,9 @@ const SidePanel = ({ ); console.log('presentationData', presentationData) const dispatch = useDispatch(); - const { getLayout } = useLayout(); - // Memoized slide renderer using layout cache - const renderSlideContent = useMemo(() => { - return (slide: any) => { - const Layout = getLayout(slide.layout); - if (!Layout) { - return
Layout not found
; - } - return ; - }; - }, [getLayout]); + // Use the centralized group layouts hook + const { renderSlideContent } = useGroupLayouts(); useEffect(() => { if (window.innerWidth < 768) { diff --git a/servers/nextjs/app/(presentation-generator)/presentation/components/SlideContent.tsx b/servers/nextjs/app/(presentation-generator)/presentation/components/SlideContent.tsx index d297bde7..3e7c44e6 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 { useLayout } from "../../context/LayoutContext"; +import { useGroupLayouts } from "../../hooks/useGroupLayouts"; interface SlideContentProps { slide: any; @@ -37,18 +37,24 @@ const SlideContent = ({ const { presentationData, isStreaming } = useSelector( (state: RootState) => state.presentationGeneration ); - const { getLayout, loading } = useLayout(); + + // Use the centralized group layouts hook + const { groupLayouts, getGroupLayout, loading } = useGroupLayouts(); // Memoized layout component to prevent re-renders const LayoutComponent = useMemo(() => { - const Layout = getLayout(slide.layout); + const Layout = getGroupLayout(slide.layout); if (!Layout) { - return () =>
- Layout not found -
; + return () => ( +
+

+ Layout "{slide.layout}" not found in current group +

+
+ ); } return Layout; - }, [slide.layout, getLayout]); + }, [slide.layout, getGroupLayout]); const handleSubmit = async () => { const element = document.getElementById( @@ -96,7 +102,7 @@ const SlideContent = ({ const newSlide: Slide = getEmptySlideContent( type, index + 1, - presentationData?.presentation!.id! + presentationData?.id! ); dispatch(addSlide({ slide: newSlide, index: index + 1 })); @@ -172,6 +178,7 @@ const SlideContent = ({ handleNewSlide(type, slide.index)} setShowNewSlideSelection={setShowNewSlideSelection} + /> )} {!isStreaming && ( diff --git a/servers/nextjs/app/(presentation-generator)/services/api/presentation-generation.ts b/servers/nextjs/app/(presentation-generator)/services/api/presentation-generation.ts index 8cb23bd3..187808ea 100644 --- a/servers/nextjs/app/(presentation-generator)/services/api/presentation-generation.ts +++ b/servers/nextjs/app/(presentation-generator)/services/api/presentation-generation.ts @@ -408,6 +408,7 @@ export class PresentationGenerationApi { n_slides, file_paths, language, + }: { prompt: string; @@ -427,6 +428,8 @@ export class PresentationGenerationApi { n_slides, file_paths, language, + + }), cache: "no-cache", } diff --git a/servers/nextjs/app/(presentation-generator)/upload/components/UploadPage.tsx b/servers/nextjs/app/(presentation-generator)/upload/components/UploadPage.tsx index 35da0e61..ed5a76a1 100644 --- a/servers/nextjs/app/(presentation-generator)/upload/components/UploadPage.tsx +++ b/servers/nextjs/app/(presentation-generator)/upload/components/UploadPage.tsx @@ -41,7 +41,6 @@ const UploadPage = () => { const dispatch = useDispatch(); const { toast } = useToast(); - // State management const [files, setFiles] = useState([]); const [config, setConfig] = useState({ @@ -87,9 +86,6 @@ const UploadPage = () => { }); return false; } - - - return true; }; @@ -165,7 +161,6 @@ const UploadPage = () => { n_slides: config?.slides ? parseInt(config.slides) : null, file_paths: [], language: config?.language ?? "", - }); dispatch(setPresentationId(createResponse.id)); diff --git a/servers/nextjs/app/api/layouts/route.ts b/servers/nextjs/app/api/layouts/route.ts index 9cb0372b..41ff89a3 100644 --- a/servers/nextjs/app/api/layouts/route.ts +++ b/servers/nextjs/app/api/layouts/route.ts @@ -2,6 +2,14 @@ import { NextResponse } from 'next/server' import { promises as fs } from 'fs' import path from 'path' +interface GroupSetting { + id: string; + name: string; + description: string; + ordered: boolean; + isDefault?: boolean; +} + export async function GET() { try { // Get the path to the presentation-layouts directory @@ -15,9 +23,9 @@ export async function GET() { .filter(item => item.isDirectory()) .map(dir => dir.name) - const allLayouts: { group: string; files: string[] }[] = [] + const allLayouts: { group: string; files: string[]; settings: GroupSetting | null }[] = [] - // Scan each group directory for layout files + // Scan each group directory for layout files and settings for (const groupName of groupDirectories) { try { const groupPath = path.join(layoutsDirectory, groupName) @@ -32,10 +40,29 @@ export async function GET() { file !== 'setting.json' ) + // Read settings.json if it exists + let settings: GroupSetting | null = null + const settingsPath = path.join(groupPath, 'setting.json') + try { + const settingsContent = await fs.readFile(settingsPath, 'utf-8') + settings = JSON.parse(settingsContent) as GroupSetting + } catch (settingsError) { + console.warn(`No settings.json found for group ${groupName} or invalid JSON`) + // Provide default settings if setting.json is missing or invalid + settings = { + id: groupName, + name: groupName.charAt(0).toUpperCase() + groupName.slice(1), + description: `${groupName} presentation layouts`, + ordered: false, + isDefault: false + } + } + if (layoutFiles.length > 0) { allLayouts.push({ group: groupName, - files: layoutFiles + files: layoutFiles, + settings: settings }) } } catch (error) { diff --git a/servers/nextjs/app/layout-preview/hooks/useLayoutLoader.ts b/servers/nextjs/app/layout-preview/hooks/useLayoutLoader.ts index 85e561a9..c6c50863 100644 --- a/servers/nextjs/app/layout-preview/hooks/useLayoutLoader.ts +++ b/servers/nextjs/app/layout-preview/hooks/useLayoutLoader.ts @@ -1,7 +1,7 @@ 'use client' import { useState, useEffect } from 'react' -import { LayoutInfo, LayoutGroup, GroupedLayoutsResponse } from '../types' +import { LayoutInfo, LayoutGroup, GroupedLayoutsResponse, GroupSetting } from '../types' import { toast } from '@/hooks/use-toast' interface UseLayoutLoaderReturn { @@ -40,6 +40,15 @@ export const useLayoutLoader = (): UseLayoutLoaderReturn => { for (const groupData of groupedLayoutsData) { const groupLayouts: LayoutInfo[] = [] + // Use settings from setting.json or provide defaults + const groupSettings: GroupSetting = groupData.settings || { + id: groupData.group, + name: groupData.group.charAt(0).toUpperCase() + groupData.group.slice(1), + description: `${groupData.group} presentation layouts`, + ordered: false, + isDefault: false + } + for (const fileName of groupData.files) { try { const layoutName = fileName.replace('.tsx', '').replace('.ts', '') @@ -115,11 +124,19 @@ export const useLayoutLoader = (): UseLayoutLoaderReturn => { if (groupLayouts.length > 0) { loadedGroups.push({ group: groupData.group, - layouts: groupLayouts + layouts: groupLayouts, + settings: groupSettings }) } } + // Sort groups to put default first, then by name + loadedGroups.sort((a, b) => { + if (a.settings.isDefault && !b.settings.isDefault) return -1 + if (!a.settings.isDefault && b.settings.isDefault) return 1 + return a.settings.name.localeCompare(b.settings.name) + }) + if (allLayouts.length === 0) { toast({ title: 'No valid layouts found', diff --git a/servers/nextjs/app/layout-preview/types/index.ts b/servers/nextjs/app/layout-preview/types/index.ts index a92d8502..42bed124 100644 --- a/servers/nextjs/app/layout-preview/types/index.ts +++ b/servers/nextjs/app/layout-preview/types/index.ts @@ -11,14 +11,24 @@ export interface LayoutInfo { group: string } +export interface GroupSetting { + id: string; + name: string; + description: string; + ordered: boolean; + isDefault?: boolean; +} + export interface LayoutGroup { group: string layouts: LayoutInfo[] + settings: GroupSetting } export interface GroupedLayoutsResponse { group: string files: string[] + settings: GroupSetting | null } export interface LoadingState { diff --git a/servers/nextjs/presentation-layouts/default/setting.json b/servers/nextjs/presentation-layouts/default/setting.json index 8e993ded..eddb7c68 100644 --- a/servers/nextjs/presentation-layouts/default/setting.json +++ b/servers/nextjs/presentation-layouts/default/setting.json @@ -2,5 +2,6 @@ "id": "default", "name": "Default", "description": "Default layout for presentations", - "ordered": true + "ordered": true, + "isDefault": false } \ No newline at end of file diff --git a/servers/nextjs/presentation-layouts/modern/CardSlideLayout.tsx b/servers/nextjs/presentation-layouts/modern/CardSlideLayout.tsx index 60c9b964..12ed4acc 100644 --- a/servers/nextjs/presentation-layouts/modern/CardSlideLayout.tsx +++ b/servers/nextjs/presentation-layouts/modern/CardSlideLayout.tsx @@ -71,7 +71,7 @@ const CardSlideLayout: React.FC = ({ data: slideData }) => return (
= ({ data: sli return (