diff --git a/servers/nextjs/app/(presentation-generator)/upload/components/ConfigurationSelects.tsx b/servers/nextjs/app/(presentation-generator)/upload/components/ConfigurationSelects.tsx index 741ebf99..e2be22c2 100644 --- a/servers/nextjs/app/(presentation-generator)/upload/components/ConfigurationSelects.tsx +++ b/servers/nextjs/app/(presentation-generator)/upload/components/ConfigurationSelects.tsx @@ -23,6 +23,7 @@ import { PopoverTrigger, } from "@/components/ui/popover"; import { cn } from "@/lib/utils"; +import { Input } from "@/components/ui/input"; // Types interface ConfigurationSelectsProps { @@ -41,28 +42,89 @@ const SLIDE_OPTIONS: SlideOption[] = ["5", "8", "9", "10", "11", "12", "13", "14 const SlideCountSelect: React.FC<{ value: string | null; onValueChange: (value: string) => void; -}> = ({ value, onValueChange }) => ( - + + + + + {/* Sticky custom input at the top */} +
e.stopPropagation()} + onPointerDown={(e) => e.stopPropagation()} + onClick={(e) => e.stopPropagation()} > - {option} slides - - ))} - - -); +
+ e.stopPropagation()} + onPointerDown={(e) => e.stopPropagation()} + onClick={(e) => e.stopPropagation()} + onChange={(e) => { + const next = sanitizeToPositiveInteger(e.target.value); + setCustomInput(next); + }} + onKeyDown={(e) => { + if (e.key === "Enter") { + e.preventDefault(); + applyCustomValue(); + } + }} + onBlur={applyCustomValue} + placeholder="X" + className="h-8 w-16 px-2 text-sm" + /> + slides +
+
+ + {/* Hidden item to allow SelectValue to render custom selection */} + {value && !SLIDE_OPTIONS.includes(value as SlideOption) && ( + + {value} slides + + )} + + {SLIDE_OPTIONS.map((option) => ( + + {option} slides + + ))} +
+ + ); +}; /** * Renders a language selection component with search functionality diff --git a/servers/nextjs/app/api/export-as-pdf/route.ts b/servers/nextjs/app/api/export-as-pdf/route.ts index 59ea3dda..836f633d 100644 --- a/servers/nextjs/app/api/export-as-pdf/route.ts +++ b/servers/nextjs/app/api/export-as-pdf/route.ts @@ -20,8 +20,10 @@ export async function POST(req: NextRequest) { }); const page = await browser.newPage(); await page.setViewport({ width: 1280, height: 720 }); + page.setDefaultNavigationTimeout(300000); + page.setDefaultTimeout(300000); - await page.goto(`http://localhost/pdf-maker?id=${id}`, { waitUntil: 'networkidle0', timeout: 180000 }); + await page.goto(`http://localhost/pdf-maker?id=${id}`, { waitUntil: 'networkidle0', timeout: 300000 }); await page.waitForFunction('() => document.readyState === "complete"') @@ -47,7 +49,7 @@ export async function POST(req: NextRequest) { return (loadedElements / totalElements) >= 0.99; } `, - { timeout: 10000 } + { timeout: 300000 } ); await new Promise(resolve => setTimeout(resolve, 1000)); diff --git a/servers/nextjs/app/api/layout/route.ts b/servers/nextjs/app/api/layout/route.ts index 06287d8e..863fab44 100644 --- a/servers/nextjs/app/api/layout/route.ts +++ b/servers/nextjs/app/api/layout/route.ts @@ -22,12 +22,14 @@ export async function GET(request: Request) { }); const page = await browser.newPage(); await page.setViewport({ width: 1280, height: 720 }); + page.setDefaultNavigationTimeout(300000); + page.setDefaultTimeout(300000); await page.goto(schemaPageUrl, { waitUntil: "networkidle0", - timeout: 80000, + timeout: 300000, }); - await page.waitForSelector("[data-layouts]", { timeout: 30000 }); + await page.waitForSelector("[data-layouts]", { timeout: 300000 }); // Extract both data-layouts and data-group-settings attributes const { dataLayouts, dataGroupSettings } = await page.$eval( diff --git a/servers/nextjs/app/api/presentation_to_pptx_model/route.ts b/servers/nextjs/app/api/presentation_to_pptx_model/route.ts index 3a312a18..0cebd027 100644 --- a/servers/nextjs/app/api/presentation_to_pptx_model/route.ts +++ b/servers/nextjs/app/api/presentation_to_pptx_model/route.ts @@ -75,9 +75,11 @@ async function getBrowserAndPage(id: string): Promise<[Browser, Page]> { const page = await browser.newPage(); await page.setViewport({ width: 1280, height: 720, deviceScaleFactor: 1 }); + page.setDefaultNavigationTimeout(300000); + page.setDefaultTimeout(300000); await page.goto(`http://localhost/pdf-maker?id=${id}`, { waitUntil: "networkidle0", - timeout: 180000, + timeout: 300000, }); return [browser, page]; } diff --git a/servers/nextjs/app/api/template/route.ts b/servers/nextjs/app/api/template/route.ts index 2b862d33..dec565b8 100644 --- a/servers/nextjs/app/api/template/route.ts +++ b/servers/nextjs/app/api/template/route.ts @@ -16,9 +16,11 @@ export async function GET(request: Request) { browser = await puppeteer.launch({ headless: true, args: ["--no-sandbox", "--disable-web-security"] }); const page = await browser.newPage(); await page.setViewport({ width: 1280, height: 720 }); - await page.goto(schemaPageUrl, { waitUntil: "networkidle0", timeout: 80000 }); + page.setDefaultNavigationTimeout(300000); + page.setDefaultTimeout(300000); + await page.goto(schemaPageUrl, { waitUntil: "networkidle0", timeout: 300000 }); - await page.waitForSelector("[data-layouts]", { timeout: 30000 }); + await page.waitForSelector("[data-layouts]", { timeout: 300000 }); const { dataLayouts, dataGroupSettings } = await page.$eval( "[data-layouts]",