feat(Nextjs): Font uploading before processing slides addded

This commit is contained in:
shiva raj badu 2025-08-06 20:50:52 +05:45
parent 4d0a88d5e0
commit 6da278ae4f
No known key found for this signature in database
8 changed files with 53 additions and 19 deletions

View file

@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useState, useEffect } from "react";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
@ -21,6 +21,10 @@ export const HtmlEditor: React.FC<HtmlEditorProps> = ({
const [htmlContent, setHtmlContent] = useState(slide.html || "");
const [isPreviewMode, setIsPreviewMode] = useState(false);
useEffect(() => {
setHtmlContent(slide.html || "");
}, [slide.html]);
if (!isHtmlEditMode) return null;
const handleSave = () => {
@ -83,8 +87,8 @@ export const HtmlEditor: React.FC<HtmlEditorProps> = ({
Edit HTML Content:
</label>
<Textarea
value={htmlContent}
onChange={(e) => setHtmlContent(e.target.value)}
defaultValue={htmlContent}
onBlur={(e) => setHtmlContent(e.target.value)}
className="font-mono text-sm h-96 resize-none"
placeholder="Enter HTML content here..."
/>

View file

@ -73,7 +73,7 @@ const EachSlide: React.FC<EachSlideProps> = ({
// Handle save with drawing data
const handleSaveWithDrawing = () => {
handleSave(slideDisplayRef, didYourDraw);
handleSave(slideDisplayRef!, didYourDraw);
};
// Handle delete slide
@ -132,7 +132,6 @@ const EachSlide: React.FC<EachSlideProps> = ({
onEraserModeChange={handleEraserModeChange}
onClearCanvas={handleClearCanvas}
/>
{/* Slide Content Display */}
<SlideContentDisplay
slide={slide}
@ -152,6 +151,7 @@ const EachSlide: React.FC<EachSlideProps> = ({
onMouseUp={handleMouseUp}
onTouchStart={handleTouchStart}
onTouchMove={handleTouchMove}
retrySlide={handleRetrySlide}
onTouchEnd={handleTouchEnd}
/>
</CardContent>

View file

@ -1,6 +1,5 @@
import React from "react";
import { Button } from "@/components/ui/button";
import { Loader2 } from "lucide-react";
import SlideContent from "../SlideContent";
import { SlideContentDisplayProps } from "../../types";
@ -12,9 +11,9 @@ export const SlideContentDisplay: React.FC<SlideContentDisplayProps> = ({
slideDisplayRef,
canvasRef,
canvasDimensions,
eraserMode,
strokeWidth,
strokeColor,
eraserMode,
isDrawing,
didYourDraw,
onMouseDown,
@ -23,6 +22,7 @@ export const SlideContentDisplay: React.FC<SlideContentDisplayProps> = ({
onTouchStart,
onTouchMove,
onTouchEnd,
retrySlide,
}) => {
// Don't show slide content when in HTML edit mode
if (isHtmlEditMode) {
@ -103,6 +103,7 @@ export const SlideContentDisplay: React.FC<SlideContentDisplayProps> = ({
slide.error
)}
</div>
<button onClick={() => retrySlide(slide.slide_number)}>Retry</button>
</div>
);
}

View file

@ -30,6 +30,7 @@ interface FontManagerProps {
uploadFont: (fontName: string, file: File) => Promise<string | null>;
removeFont: (fontUrl: string) => void;
getAllUnsupportedFonts: () => string[];
processSlideToHtml: () => void;
}
const FontManager: React.FC<FontManagerProps> = ({
@ -38,6 +39,7 @@ const FontManager: React.FC<FontManagerProps> = ({
uploadFont,
removeFont,
getAllUnsupportedFonts,
processSlideToHtml,
}) => {
const [uploadingFonts, setUploadingFonts] = useState<Set<string>>(new Set());
const fileInputRefs = useRef<{ [key: string]: HTMLInputElement | null }>({});
@ -214,6 +216,17 @@ const FontManager: React.FC<FontManagerProps> = ({
</div>
</div>
)}
<div className="flex justify-center mt-4">
<Button
size="sm"
variant="outline"
onClick={processSlideToHtml}
className="text-xs px-8 py-2 font-semibold bg-blue-600 text-white hover:text-white hover:bg-blue-700 border-blue-600"
>
Extract layouts
</Button>
</div>
</CardContent>
</Card>
);

View file

@ -12,7 +12,7 @@ export const useSlideEdit = (
const [isUpdating, setIsUpdating] = useState(false);
const [prompt, setPrompt] = useState("");
const [slideHtml, setSlideHtml] = useState("");
const slideContentRef = useRef<HTMLDivElement>(null);
const slideContentRef = useRef<HTMLDivElement | null>(null);
// Load Tailwind CSS dynamically for slide content
useEffect(() => {
@ -90,7 +90,7 @@ export const useSlideEdit = (
};
const handleSave = async (
slideDisplayRef: React.RefObject<HTMLDivElement>,
slideDisplayRef: React.RefObject<HTMLDivElement |null>,
didYourDraw: boolean
) => {
if (
@ -173,6 +173,20 @@ export const useSlideEdit = (
processing: false,
error: undefined,
};
// download screenshot
const screenshot = slideOnly.toDataURL("image/png");
const link = document.createElement("a");
link.href = screenshot;
link.download = `slide-${slide.slide_number}-current.png`;
link.click();
// second screenshot
if (sketchImageBlob && slideWithCanvas) {
const screenshot2 = slideWithCanvas.toDataURL("image/png");
const link2 = document.createElement("a");
link2.href = screenshot2;
link2.download = `slide-${slide.slide_number}-sketch.png`;
link2.click();
}
if (onSlideUpdate) {
onSlideUpdate(updatedSlideData);

View file

@ -161,11 +161,7 @@ export const useSlideProcessing = (
`Successfully extracted ${pptxData.slides.length} slides! Converting to HTML...`
);
// Start processing first slide
setTimeout(() => {
console.log("Starting to process first slide");
processSlideToHtml(initialSlides[0], 0);
}, 500);
} catch (error) {
console.error("Error processing file:", error);
const errorMessage =

View file

@ -25,7 +25,7 @@ const CustomLayoutPage = () => {
const { selectedFile, handleFileSelect, removeFile } = useFileUpload();
const { slides, setSlides, completedSlides } = useCustomLayout();
const { fontsData, UploadedFonts, uploadFont, removeFont, getAllUnsupportedFonts, setFontsData } = useFontManagement();
const { isProcessingPptx, processFile, retrySlide } = useSlideProcessing(
const { isProcessingPptx, processFile, retrySlide,processSlideToHtml } = useSlideProcessing(
selectedFile,
slides,
setSlides,
@ -38,6 +38,10 @@ const CustomLayoutPage = () => {
refetch
);
const handleProcessSlideToHtml = (slide: any) => {
processSlideToHtml(slide,0)
}
// Handle slide updates
const handleSlideUpdate = (index: number, updatedSlideData: any) => {
setSlides((prevSlides) =>
@ -97,6 +101,7 @@ const CustomLayoutPage = () => {
uploadFont={uploadFont}
removeFont={removeFont}
getAllUnsupportedFonts={getAllUnsupportedFonts}
processSlideToHtml={()=>handleProcessSlideToHtml(slides[0])}
/>
)}

View file

@ -83,9 +83,9 @@ export interface SlideContentDisplayProps {
slide: ProcessedSlide;
isEditMode: boolean;
isHtmlEditMode: boolean;
slideContentRef: React.RefObject<HTMLDivElement>;
slideDisplayRef: React.RefObject<HTMLDivElement>;
canvasRef: React.RefObject<HTMLCanvasElement>;
slideContentRef: React.RefObject<HTMLDivElement | null>;
slideDisplayRef: React.RefObject<HTMLDivElement | null>;
canvasRef: React.RefObject<HTMLCanvasElement | null>;
canvasDimensions: { width: number; height: number };
strokeWidth: number;
strokeColor: string;
@ -98,6 +98,7 @@ export interface SlideContentDisplayProps {
onTouchStart: (e: React.TouchEvent<HTMLCanvasElement>) => void;
onTouchMove: (e: React.TouchEvent<HTMLCanvasElement>) => void;
onTouchEnd: (e: React.TouchEvent<HTMLCanvasElement>) => void;
retrySlide: (slideNumber: number) => void;
}
export interface HtmlEditorProps {