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);
}