update: add template generation from pdf as well

This commit is contained in:
Suraj Jha 2025-08-19 23:35:00 +05:45
parent 3bf5280a25
commit 77d97b6954
No known key found for this signature in database
GPG key ID: 5AC6C16355CE2C14
5 changed files with 55 additions and 31 deletions

View file

@ -36,10 +36,10 @@ export const FileUploadSection: React.FC<FileUploadSectionProps> = ({
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Upload className="w-5 h-5" />
Upload PPTX File
Upload PDF or PPTX File
</CardTitle>
<CardDescription>
Select a PowerPoint file (.pptx) to process. Maximum file size: 50MB
Select a PDF or PowerPoint file (.pdf or .pptx) to process. Maximum file size: 50MB
</CardDescription>
{slides.length > 0 && (
<div className="flex items-center justify-end gap-2">
@ -56,12 +56,12 @@ export const FileUploadSection: React.FC<FileUploadSectionProps> = ({
<Upload className="w-12 h-12 text-gray-400 mx-auto mb-4" />
<Label htmlFor="file-upload" className="cursor-pointer">
<span className="text-lg font-medium text-gray-700">
Click to upload a PPTX file
Click to upload a PDF or PPTX file
</span>
<input
id="file-upload"
type="file"
accept=".pptx"
accept=".pdf,.pptx"
onChange={handleFileSelect}
className="opacity-0 w-full h-full cursor-pointer absolute top-0 left-0 z-10"
/>
@ -106,7 +106,7 @@ export const FileUploadSection: React.FC<FileUploadSectionProps> = ({
{isProcessingPptx
? "Extracting Slides..."
: !selectedFile
? "Select a PPTX file"
? "Select a PDF or PPTX file"
: "Process File"}
</Button>
{isProcessingPptx && <Timer duration={90} />}

View file

@ -10,8 +10,11 @@ export const useFileUpload = () => {
if (!file) return;
// Validate file type
if (!file.name.toLowerCase().endsWith(".pptx")) {
toast.error("Please select a valid PPTX file");
const lowerName = file.name.toLowerCase();
const isPptx = lowerName.endsWith(".pptx");
const isPdf = lowerName.endsWith(".pdf");
if (!isPptx && !isPdf) {
toast.error("Please select a valid PDF or PPTX file");
return;
}

View file

@ -115,10 +115,10 @@ export const useSlideProcessing = (
[]
);
// Process PPTX file to extract slides
// Process PDF or PPTX file to extract slides
const processFile = useCallback(async () => {
if (!selectedFile) {
toast.error("Please select a PPTX file first");
toast.error("Please select a PDF or PPTX file first");
return;
}
@ -126,30 +126,51 @@ export const useSlideProcessing = (
setIsProcessingPptx(true);
const formData = new FormData();
formData.append("pptx_file", selectedFile);
const fileName = selectedFile.name.toLowerCase();
const isPdf = fileName.endsWith(".pdf");
const isPptx = fileName.endsWith(".pptx");
const pptxResponse = await fetch("/api/v1/ppt/pptx-slides/process", {
method: "POST",
body: formData,
});
const pptxData = await ApiResponseHandler.handleResponse(
pptxResponse,
"Failed to process PPTX file"
);
if (!pptxData.success || !pptxData.slides?.length) {
throw new Error("No slides found in the PPTX file");
let slidesResponseData: any = null;
if (isPdf) {
formData.append("pdf_file", selectedFile);
const pdfResponse = await fetch("/api/v1/ppt/pdf-slides/process", {
method: "POST",
body: formData,
});
slidesResponseData = await ApiResponseHandler.handleResponse(
pdfResponse,
"Failed to process PDF file"
);
} else if (isPptx) {
formData.append("pptx_file", selectedFile);
const pptxResponse = await fetch("/api/v1/ppt/pptx-slides/process", {
method: "POST",
body: formData,
});
slidesResponseData = await ApiResponseHandler.handleResponse(
pptxResponse,
"Failed to process PPTX file"
);
} else {
throw new Error("Unsupported file type. Please upload a PDF or PPTX file.");
}
// Extract fonts data from the response
if (pptxData.fonts) {
setFontsData(pptxData.fonts);
if (!slidesResponseData.success || !slidesResponseData.slides?.length) {
throw new Error("No slides found in the uploaded file");
}
// Initialize slides with skeleton state
const initialSlides: ProcessedSlide[] = pptxData.slides.map(
// Extract fonts data only for PPTX where available
if (slidesResponseData.fonts) {
setFontsData(slidesResponseData.fonts);
}
// Initialize slides with skeleton state; for PDF, xml/fonts won't exist
const initialSlides: ProcessedSlide[] = slidesResponseData.slides.map(
(slide: any) => ({
...slide,
slide_number: slide.slide_number,
screenshot_url: slide.screenshot_url,
xml_content: slide.xml_content ?? "",
normalized_fonts: slide.normalized_fonts ?? [],
processing: false,
processed: false,
})
@ -157,7 +178,7 @@ export const useSlideProcessing = (
setSlides(initialSlides);
const hasUnsupported = Array.isArray(pptxData.fonts?.not_supported_fonts) && pptxData.fonts.not_supported_fonts.length > 0;
const hasUnsupported = Array.isArray(slidesResponseData.fonts?.not_supported_fonts) && slidesResponseData.fonts.not_supported_fonts.length > 0;
toast.success(
`Template Processing Finished`,

View file

@ -103,8 +103,8 @@ const CustomTemplatePage = () => {
Custom Template Processor
</h1>
<p className="text-lg text-gray-600 max-w-2xl mx-auto">
Upload your PPTX file to extract slides and convert them to
template which then can be used to generate AI presentations.
Upload your PDF or PPTX file to extract slides and convert them to
a template which you can use to generate AI presentations.
</p>
<div className="max-w-2xl mx-auto mt-2">
<div className="inline-block rounded border border-orange-200 bg-orange-50 px-3 py-2 text-sm text-orange-700">

View file

@ -3,7 +3,7 @@ import type React from "react";
export interface SlideData {
slide_number: number;
screenshot_url: string;
xml_content: string;
xml_content?: string;
normalized_fonts?: string[];
}