Implement slide deletion and duplication functionality

- Add complete slide deletion with smart confirmation messages
- Implement slide duplication that copies layout, content, and notes
- Handle edge cases for navigation after deletion/duplication
- Add proper slide order management and renumbering
- Include comprehensive error handling and user feedback
- Support deleting last slide, only slide, and middle slides
- Navigate intelligently after operations (to duplicated slide, adjusted position after deletion)
- Add improved confirmation dialogs with context-aware messaging
- Integrate with existing presentation storage and state management
- Replace placeholder TODO implementations with full functionality

Features completed:
 User can delete slides from presentation
 User gets confirmation before slide deletion
 Slide order adjusts automatically
 User can duplicate existing slides copying layout and content
 Smart navigation maintains user context after operations
 Robust error handling with proper user feedback

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Michael Mainguy 2025-08-20 17:32:06 -05:00
parent 79060f0945
commit 4ce9f225a6
2 changed files with 90 additions and 10 deletions

View File

@ -35,6 +35,7 @@
- [x] User can add presentation notes to slide
- [x] User can see miniature preview of slide live while editing
- [x] User can save slide (auto-saves presentation)
- [x] User can duplicate an existing slide copying it's layout and content.
### Edit Existing Slide
- [x] User can click on existing slide to edit
@ -43,6 +44,7 @@
- [x] User can exit slide editing mode without saving changes in an obvious way
- [x] User can edit presentation notes
- [x] Changes auto-save to presentation
- [ ] User can edit slide content without preview if desired by clicking inside content slot areas
### Remove Slide
- [ ] User can delete slides from presentation
@ -53,3 +55,8 @@
- [ ] User can preview individual slides
- [ ] User can view slides in presentation mode
- [ ] User can navigate between slides in preview
### Slide Order Management
- [ ] User can reorder slides via drag-and-drop
- [ ] User can see slide order visually in editor
- [ ] Slide order automatically saves when changed

View File

@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react';
import { useParams, useNavigate, Link } from 'react-router-dom';
import type { Presentation } from '../../types/presentation';
import type { Theme } from '../../types/theme';
import { getPresentationById } from '../../utils/presentationStorage';
import { getPresentationById, updatePresentation } from '../../utils/presentationStorage';
import { getTheme } from '../../themes';
import './PresentationEditor.css';
@ -88,16 +88,47 @@ export const PresentationEditor: React.FC = () => {
const duplicateSlide = async (slideIndex: number) => {
if (!presentation) return;
const slideToDuplicate = presentation.slides[slideIndex];
if (!slideToDuplicate) return;
try {
setSaving(true);
setError(null);
// TODO: Implement slide duplication
console.log('Duplicate slide functionality to be implemented');
alert('Slide duplication will be implemented next.');
// Create a duplicate slide with new ID
const duplicatedSlide = {
...slideToDuplicate,
id: `slide_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
order: slideIndex + 1 // Insert right after the original
};
// Create updated presentation with the duplicated slide
const updatedPresentation = { ...presentation };
const newSlides = [...presentation.slides];
// Insert the duplicated slide after the original
newSlides.splice(slideIndex + 1, 0, duplicatedSlide);
// Update slide order for all slides after the insertion point
newSlides.forEach((slide, index) => {
slide.order = index;
});
updatedPresentation.slides = newSlides;
// Save the updated presentation
await updatePresentation(updatedPresentation);
// Update local state
setPresentation(updatedPresentation);
// Navigate to the duplicated slide
const newSlideNumber = slideIndex + 2; // +2 because we inserted after and slide numbers are 1-based
navigate(`/presentations/${presentationId}/edit/slides/${newSlideNumber}`);
} catch (err) {
console.error('Error duplicating slide:', err);
alert('Failed to duplicate slide');
setError(err instanceof Error ? err.message : 'Failed to duplicate slide');
} finally {
setSaving(false);
}
@ -106,20 +137,62 @@ export const PresentationEditor: React.FC = () => {
const deleteSlide = async (slideIndex: number) => {
if (!presentation) return;
if (!confirm('Are you sure you want to delete this slide?')) {
const slideToDelete = presentation.slides[slideIndex];
if (!slideToDelete) return;
const slideNumber = slideIndex + 1;
const totalSlides = presentation.slides.length;
let confirmMessage = `Are you sure you want to delete slide ${slideNumber}?`;
if (totalSlides === 1) {
confirmMessage = `Are you sure you want to delete the only slide in this presentation? The presentation will be empty after deletion.`;
} else {
confirmMessage += ` This will remove the slide and renumber all subsequent slides. This action cannot be undone.`;
}
if (!confirm(confirmMessage)) {
return;
}
try {
setSaving(true);
setError(null);
// TODO: Implement slide deletion
console.log('Delete slide functionality to be implemented');
alert('Slide deletion will be implemented next.');
// Create updated presentation with the slide removed
const updatedPresentation = { ...presentation };
updatedPresentation.slides = presentation.slides.filter((_, index) => index !== slideIndex);
// Update slide order for remaining slides
updatedPresentation.slides.forEach((slide, index) => {
slide.order = index;
});
// Save the updated presentation
await updatePresentation(updatedPresentation);
// Update local state
setPresentation(updatedPresentation);
// Handle navigation after deletion
const totalSlides = updatedPresentation.slides.length;
if (totalSlides === 0) {
// No slides left, stay on editor main view
navigate(`/presentations/${presentationId}/edit`);
} else {
// Navigate to appropriate slide
let newSlideIndex = slideIndex;
if (slideIndex >= totalSlides) {
// If we deleted the last slide, go to the new last slide
newSlideIndex = totalSlides - 1;
}
// Navigate to the adjusted slide number
const slideNumber = newSlideIndex + 1;
navigate(`/presentations/${presentationId}/edit/slides/${slideNumber}`);
}
} catch (err) {
console.error('Error deleting slide:', err);
alert('Failed to delete slide');
setError(err instanceof Error ? err.message : 'Failed to delete slide');
} finally {
setSaving(false);
}