Simplify slide editor by removing layout change feature and add obvious edit buttons

- Remove "Change Layout" buttons from slide editor header and content actions
- Simplify user flow: layout selection only happens once when creating new slides
- Existing slides go directly to content editing, skipping layout selection
- Add prominent edit buttons to slide thumbnails and main slide view
- Style edit buttons with blue theme to make them obvious primary actions
- Add "Cancel editing" link styled as underlined text link for clear visual distinction
- Improve responsive design for mobile with proper button spacing
- Lock in layout choice after selection to prevent confusion and content loss

Benefits:
- Cleaner, more focused editing interface
- Prevents accidental layout changes that could break content formatting
- Clear visual hierarchy with obvious edit and cancel options
- Faster editing workflow for existing slides

🤖 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:25:33 -05:00
parent 2a905d50e0
commit 7b262f398c
4 changed files with 123 additions and 29 deletions

View File

@ -453,6 +453,18 @@
border-color: #cbd5e1;
}
.thumbnail-action.edit {
background: #eff6ff;
border-color: #3b82f6;
color: #3b82f6;
}
.thumbnail-action.edit:hover:not(:disabled) {
background: #dbeafe;
border-color: #2563eb;
color: #2563eb;
}
.thumbnail-action.delete:hover:not(:disabled) {
background: #fef2f2;
border-color: #fecaca;
@ -522,6 +534,18 @@
cursor: not-allowed;
}
.control-button.edit-slide-button {
background: #3b82f6;
color: white;
border-color: #3b82f6;
font-weight: 600;
}
.control-button.edit-slide-button:hover:not(:disabled) {
background: #2563eb;
border-color: #2563eb;
}
.slide-content-editor {
flex: 1;
display: flex;

View File

@ -307,6 +307,18 @@ export const PresentationEditor: React.FC = () => {
</div>
</div>
<div className="thumbnail-actions">
<button
type="button"
className="thumbnail-action edit"
onClick={(e) => {
e.stopPropagation();
navigate(`/presentations/${presentationId}/slide/${slide.id}/edit`);
}}
title="Edit slide content"
disabled={saving}
>
</button>
<button
type="button"
className="thumbnail-action"
@ -343,6 +355,14 @@ export const PresentationEditor: React.FC = () => {
<div className="slide-header">
<h3>Slide {currentSlideIndex + 1} - {currentSlide.layoutId}</h3>
<div className="slide-controls">
<button
type="button"
className="control-button edit-slide-button"
onClick={() => navigate(`/presentations/${presentationId}/slide/${currentSlide.id}/edit`)}
disabled={saving}
>
Edit Content
</button>
<button
type="button"
className="control-button"

View File

@ -359,11 +359,44 @@
.content-actions {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
padding-top: 1rem;
border-top: 1px solid #e5e7eb;
margin-top: 1rem;
justify-content: flex-end;
}
.action-links {
display: flex;
align-items: center;
}
.action-buttons {
display: flex;
gap: 1rem;
}
.cancel-link {
background: none;
border: none;
color: #64748b;
font-size: 0.875rem;
font-weight: 400;
text-decoration: underline;
cursor: pointer;
padding: 0;
transition: color 0.2s ease;
}
.cancel-link:hover:not(:disabled) {
color: #374151;
text-decoration: underline;
}
.cancel-link:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.content-actions .action-button {
@ -664,6 +697,26 @@
padding: 1rem;
}
.content-actions {
flex-direction: column;
align-items: stretch;
gap: 0.75rem;
}
.action-links {
justify-content: center;
order: 2;
}
.action-buttons {
justify-content: stretch;
order: 1;
}
.action-buttons .action-button {
flex: 1;
}
.preview-container {
min-height: 200px;
}

View File

@ -20,13 +20,13 @@ export const SlideEditor: React.FC = () => {
const [error, setError] = useState<string | null>(null);
const [saving, setSaving] = useState(false);
const isEditingExisting = slideId !== 'new';
// Editor state
const [selectedLayout, setSelectedLayout] = useState<SlideLayout | null>(null);
const [slideContent, setSlideContent] = useState<Record<string, string>>({});
const [slideNotes, setSlideNotes] = useState('');
const [currentStep, setCurrentStep] = useState<'layout' | 'content'>('layout');
const isEditingExisting = slideId !== 'new';
const [currentStep, setCurrentStep] = useState<'layout' | 'content'>(isEditingExisting ? 'content' : 'layout');
const existingSlide = isEditingExisting && presentation
? presentation.slides.find(s => s.id === slideId)
: null;
@ -69,7 +69,7 @@ export const SlideEditor: React.FC = () => {
setSelectedLayout(layout);
setSlideContent(slide.content);
setSlideNotes(slide.notes || '');
setCurrentStep('content');
// No need to set currentStep here since it's already 'content' for existing slides
}
} else {
setError(`Slide not found: ${slideId}`);
@ -122,6 +122,7 @@ export const SlideEditor: React.FC = () => {
});
setSlideContent(initialContent);
// Automatically move to content editing after layout selection
setCurrentStep('content');
};
@ -241,15 +242,6 @@ export const SlideEditor: React.FC = () => {
</div>
<div className="editor-actions">
{currentStep === 'content' && (
<button
type="button"
className="action-button secondary"
onClick={() => setCurrentStep('layout')}
>
Change Layout
</button>
)}
<button
type="button"
className="action-button primary"
@ -362,21 +354,26 @@ export const SlideEditor: React.FC = () => {
</div>
<div className="content-actions">
<button
type="button"
className="action-button secondary"
onClick={() => setCurrentStep('layout')}
>
Change Layout
</button>
<button
type="button"
className="action-button primary"
onClick={saveSlide}
disabled={saving}
>
{saving ? 'Saving...' : (isEditingExisting ? 'Update Slide' : 'Save Slide')}
</button>
<div className="action-links">
<button
type="button"
className="cancel-link"
onClick={cancelEditing}
disabled={saving}
>
Cancel editing
</button>
</div>
<div className="action-buttons">
<button
type="button"
className="action-button primary"
onClick={saveSlide}
disabled={saving}
>
{saving ? 'Saving...' : (isEditingExisting ? 'Update Slide' : 'Save Slide')}
</button>
</div>
</div>
</div>
</div>