update: add template generation from pdf as well
This commit is contained in:
parent
3bf5280a25
commit
77d97b6954
5 changed files with 55 additions and 31 deletions
|
|
@ -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} />}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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`,
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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[];
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue