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:
parent
2a905d50e0
commit
7b262f398c
@ -453,6 +453,18 @@
|
|||||||
border-color: #cbd5e1;
|
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) {
|
.thumbnail-action.delete:hover:not(:disabled) {
|
||||||
background: #fef2f2;
|
background: #fef2f2;
|
||||||
border-color: #fecaca;
|
border-color: #fecaca;
|
||||||
@ -522,6 +534,18 @@
|
|||||||
cursor: not-allowed;
|
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 {
|
.slide-content-editor {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -307,6 +307,18 @@ export const PresentationEditor: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="thumbnail-actions">
|
<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
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="thumbnail-action"
|
className="thumbnail-action"
|
||||||
@ -343,6 +355,14 @@ export const PresentationEditor: React.FC = () => {
|
|||||||
<div className="slide-header">
|
<div className="slide-header">
|
||||||
<h3>Slide {currentSlideIndex + 1} - {currentSlide.layoutId}</h3>
|
<h3>Slide {currentSlideIndex + 1} - {currentSlide.layoutId}</h3>
|
||||||
<div className="slide-controls">
|
<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
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="control-button"
|
className="control-button"
|
||||||
|
@ -359,11 +359,44 @@
|
|||||||
|
|
||||||
.content-actions {
|
.content-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
padding-top: 1rem;
|
padding-top: 1rem;
|
||||||
border-top: 1px solid #e5e7eb;
|
border-top: 1px solid #e5e7eb;
|
||||||
margin-top: 1rem;
|
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 {
|
.content-actions .action-button {
|
||||||
@ -664,6 +697,26 @@
|
|||||||
padding: 1rem;
|
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 {
|
.preview-container {
|
||||||
min-height: 200px;
|
min-height: 200px;
|
||||||
}
|
}
|
||||||
|
@ -20,13 +20,13 @@ export const SlideEditor: React.FC = () => {
|
|||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const [saving, setSaving] = useState(false);
|
const [saving, setSaving] = useState(false);
|
||||||
|
|
||||||
|
const isEditingExisting = slideId !== 'new';
|
||||||
|
|
||||||
// Editor state
|
// Editor state
|
||||||
const [selectedLayout, setSelectedLayout] = useState<SlideLayout | null>(null);
|
const [selectedLayout, setSelectedLayout] = useState<SlideLayout | null>(null);
|
||||||
const [slideContent, setSlideContent] = useState<Record<string, string>>({});
|
const [slideContent, setSlideContent] = useState<Record<string, string>>({});
|
||||||
const [slideNotes, setSlideNotes] = useState('');
|
const [slideNotes, setSlideNotes] = useState('');
|
||||||
const [currentStep, setCurrentStep] = useState<'layout' | 'content'>('layout');
|
const [currentStep, setCurrentStep] = useState<'layout' | 'content'>(isEditingExisting ? 'content' : 'layout');
|
||||||
|
|
||||||
const isEditingExisting = slideId !== 'new';
|
|
||||||
const existingSlide = isEditingExisting && presentation
|
const existingSlide = isEditingExisting && presentation
|
||||||
? presentation.slides.find(s => s.id === slideId)
|
? presentation.slides.find(s => s.id === slideId)
|
||||||
: null;
|
: null;
|
||||||
@ -69,7 +69,7 @@ export const SlideEditor: React.FC = () => {
|
|||||||
setSelectedLayout(layout);
|
setSelectedLayout(layout);
|
||||||
setSlideContent(slide.content);
|
setSlideContent(slide.content);
|
||||||
setSlideNotes(slide.notes || '');
|
setSlideNotes(slide.notes || '');
|
||||||
setCurrentStep('content');
|
// No need to set currentStep here since it's already 'content' for existing slides
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setError(`Slide not found: ${slideId}`);
|
setError(`Slide not found: ${slideId}`);
|
||||||
@ -122,6 +122,7 @@ export const SlideEditor: React.FC = () => {
|
|||||||
});
|
});
|
||||||
setSlideContent(initialContent);
|
setSlideContent(initialContent);
|
||||||
|
|
||||||
|
// Automatically move to content editing after layout selection
|
||||||
setCurrentStep('content');
|
setCurrentStep('content');
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -241,15 +242,6 @@ export const SlideEditor: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="editor-actions">
|
<div className="editor-actions">
|
||||||
{currentStep === 'content' && (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="action-button secondary"
|
|
||||||
onClick={() => setCurrentStep('layout')}
|
|
||||||
>
|
|
||||||
Change Layout
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="action-button primary"
|
className="action-button primary"
|
||||||
@ -362,13 +354,17 @@ export const SlideEditor: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="content-actions">
|
<div className="content-actions">
|
||||||
|
<div className="action-links">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="action-button secondary"
|
className="cancel-link"
|
||||||
onClick={() => setCurrentStep('layout')}
|
onClick={cancelEditing}
|
||||||
|
disabled={saving}
|
||||||
>
|
>
|
||||||
Change Layout
|
Cancel editing
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="action-buttons">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="action-button primary"
|
className="action-button primary"
|
||||||
@ -380,6 +376,7 @@ export const SlideEditor: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="content-preview">
|
<div className="content-preview">
|
||||||
<h3>Live Preview</h3>
|
<h3>Live Preview</h3>
|
||||||
|
Loading…
Reference in New Issue
Block a user