feat: add modals to Cancel and Publish buttons in Editor
This commit is contained in:
BIN
public/derek.jpg
Normal file
BIN
public/derek.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 544 KiB |
@@ -230,4 +230,53 @@ form {
|
||||
width: 350px !important;
|
||||
margin: 0 auto !important;
|
||||
contain: layout;
|
||||
}
|
||||
|
||||
/* Enhanced visual styling with shadows */
|
||||
/* PostCard component shadows */
|
||||
.k-card {
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
transition: box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.k-card:hover {
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* Campfire theme shadow for cards */
|
||||
.k-card {
|
||||
box-shadow: 0 2px 8px rgba(237, 189, 125, 0.1);
|
||||
}
|
||||
|
||||
.k-card:hover {
|
||||
box-shadow: 0 4px 16px rgba(237, 189, 125, 0.3);
|
||||
}
|
||||
|
||||
/* PanelBar component shadow */
|
||||
.k-panelbar {
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* Campfire theme shadow for PanelBar */
|
||||
.k-panelbar {
|
||||
box-shadow: 2px 0 12px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* Button component shadows */
|
||||
.k-button {
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
transition: box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.k-button:hover {
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* Campfire theme shadow for buttons */
|
||||
.k-button {
|
||||
box-shadow: 0 2px 8px rgba(237, 189, 125, 0.1);
|
||||
}
|
||||
|
||||
.k-button:hover {
|
||||
box-shadow: 0 4px 16px rgba(237, 189, 125, 0.3);
|
||||
}
|
@@ -52,9 +52,35 @@ const CampfireAppBar = ({ isLoggedIn, onLogin, onDrawerToggle }) => {
|
||||
<AppBarSpacer style={{ width: 20 }} />
|
||||
|
||||
{isLoggedIn ? (
|
||||
<Button look="flat" onClick={handleLogout}>
|
||||
Logout
|
||||
</Button>
|
||||
<>
|
||||
<Button look="flat" onClick={handleLogout}>
|
||||
Logout
|
||||
</Button>
|
||||
<Avatar
|
||||
rounded="full"
|
||||
type="image"
|
||||
style={{
|
||||
marginLeft: "8px",
|
||||
width: "48px !important",
|
||||
height: "48px !important",
|
||||
minWidth: "48px",
|
||||
maxWidth: "48px",
|
||||
minHeight: "48px",
|
||||
maxHeight: "48px"
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src="/derek.jpg"
|
||||
alt="Derek Seitz"
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
border: "2px solid #edbd7d",
|
||||
borderRadius: "50%"
|
||||
}}
|
||||
/>
|
||||
</Avatar>
|
||||
</>
|
||||
) : (
|
||||
<Link to="/login">
|
||||
<Button look="flat">Login</Button>
|
||||
|
50
src/components/Editor/UI/CancelModal.jsx
Normal file
50
src/components/Editor/UI/CancelModal.jsx
Normal file
@@ -0,0 +1,50 @@
|
||||
// CancelModal.jsx
|
||||
// Confirmation modal for canceling post editing
|
||||
import React from 'react';
|
||||
import { Dialog, DialogActionsBar } from '@progress/kendo-react-dialogs';
|
||||
import { Button } from '@progress/kendo-react-buttons';
|
||||
|
||||
const CancelModal = ({ isVisible, onClose, onConfirm, hasUnsavedChanges }) => {
|
||||
if (!isVisible) return null;
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
title="Cancel Editing"
|
||||
onClose={onClose}
|
||||
minWidth={400}
|
||||
width={500}
|
||||
style={{ borderRadius: '8px' }}
|
||||
>
|
||||
<div style={{ padding: '20px' }}>
|
||||
{hasUnsavedChanges ? (
|
||||
<>
|
||||
<p style={{ margin: '0 0 16px 0', fontSize: '16px' }}>
|
||||
You have unsaved changes.
|
||||
</p>
|
||||
<p style={{ margin: '0', fontSize: '14px', color: '#666' }}>
|
||||
Are you sure you want to cancel? All unsaved changes will be lost.
|
||||
</p>
|
||||
</>
|
||||
) : (
|
||||
<p style={{ margin: '0', fontSize: '16px' }}>
|
||||
Are you sure you want to cancel editing?
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<DialogActionsBar>
|
||||
<Button onClick={onClose}>
|
||||
Continue Editing
|
||||
</Button>
|
||||
<Button
|
||||
onClick={onConfirm}
|
||||
themeColor="primary"
|
||||
look="outline"
|
||||
>
|
||||
{hasUnsavedChanges ? 'Discard Changes' : 'Cancel'}
|
||||
</Button>
|
||||
</DialogActionsBar>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default CancelModal;
|
51
src/components/Editor/UI/PublishModal.jsx
Normal file
51
src/components/Editor/UI/PublishModal.jsx
Normal file
@@ -0,0 +1,51 @@
|
||||
// PublishModal.jsx
|
||||
// Confirmation modal for publishing posts
|
||||
import React from 'react';
|
||||
import { Dialog, DialogActionsBar } from '@progress/kendo-react-dialogs';
|
||||
import { Button } from '@progress/kendo-react-buttons';
|
||||
|
||||
const PublishModal = ({ isVisible, onClose, onConfirm, postTitle }) => {
|
||||
if (!isVisible) return null;
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
title="Publish Post"
|
||||
onClose={onClose}
|
||||
minWidth={400}
|
||||
width={500}
|
||||
style={{ borderRadius: '8px' }}
|
||||
>
|
||||
<div style={{ padding: '20px' }}>
|
||||
<p style={{ margin: '0 0 16px 0', fontSize: '16px' }}>
|
||||
Are you sure you want to publish this post?
|
||||
</p>
|
||||
{postTitle && (
|
||||
<p style={{
|
||||
margin: '0 0 16px 0',
|
||||
fontSize: '14px',
|
||||
fontStyle: 'italic',
|
||||
color: '#666'
|
||||
}}>
|
||||
"{postTitle}"
|
||||
</p>
|
||||
)}
|
||||
<p style={{ margin: '0', fontSize: '14px', color: '#666' }}>
|
||||
This will make the post visible to your readers.
|
||||
</p>
|
||||
</div>
|
||||
<DialogActionsBar>
|
||||
<Button onClick={onClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
onClick={onConfirm}
|
||||
themeColor="primary"
|
||||
>
|
||||
Publish Post
|
||||
</Button>
|
||||
</DialogActionsBar>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default PublishModal;
|
@@ -1,15 +1,18 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useParams, useNavigate } from 'react-router-dom';
|
||||
import { Button } from '@progress/kendo-react-buttons';
|
||||
import { marked } from 'marked';
|
||||
import MetadataEditor from '../components/Editor/MetadataEditor';
|
||||
import WysiwygEditor from '../components/Editor/WysiwygEditor';
|
||||
import MarkdownEditor from '../components/Editor/MarkdownEditor';
|
||||
import EditorModeToggle from '../components/Editor/custom/EditorModeToggle';
|
||||
import PublishModal from '../components/Editor/UI/PublishModal';
|
||||
import CancelModal from '../components/Editor/UI/CancelModal';
|
||||
import { getPostBySlug } from '../data/postsCache';
|
||||
|
||||
const EditorPage = React.forwardRef((props, ref) => {
|
||||
const { slug } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const [postData, setPostData] = useState(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
@@ -22,6 +25,11 @@ const EditorPage = React.forwardRef((props, ref) => {
|
||||
{}
|
||||
]);
|
||||
|
||||
// Modal state management
|
||||
const [showPublishModal, setShowPublishModal] = useState(false);
|
||||
const [showCancelModal, setShowCancelModal] = useState(false);
|
||||
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const loadPostData = async () => {
|
||||
setIsLoading(true);
|
||||
@@ -60,18 +68,31 @@ const EditorPage = React.forwardRef((props, ref) => {
|
||||
}
|
||||
|
||||
const handlePublish = () => {
|
||||
console.log('Publish clicked', { postData });
|
||||
setShowPublishModal(true);
|
||||
};
|
||||
|
||||
const handlePublishConfirm = () => {
|
||||
console.log('Publish confirmed', { postData });
|
||||
setShowPublishModal(false);
|
||||
// Demo functionality - would save and publish the post
|
||||
navigate('/dashboard');
|
||||
};
|
||||
|
||||
const handleSaveDraft = () => {
|
||||
console.log('Save Draft clicked', { postData });
|
||||
setHasUnsavedChanges(false);
|
||||
// Demo functionality - would save as draft
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
console.log('Cancel clicked');
|
||||
// Demo functionality - would navigate back to dashboard
|
||||
setShowCancelModal(true);
|
||||
};
|
||||
|
||||
const handleCancelConfirm = () => {
|
||||
console.log('Cancel confirmed');
|
||||
setShowCancelModal(false);
|
||||
setHasUnsavedChanges(false);
|
||||
navigate('/dashboard');
|
||||
};
|
||||
|
||||
// Editor mode toggle handler
|
||||
@@ -95,6 +116,13 @@ const EditorPage = React.forwardRef((props, ref) => {
|
||||
// Markdown change handler
|
||||
const handleMarkdownChange = (event) => {
|
||||
setMarkdownContent(event.target.value);
|
||||
setHasUnsavedChanges(true);
|
||||
};
|
||||
|
||||
// Content change handler for WYSIWYG editor
|
||||
const handleContentChange = (newContent) => {
|
||||
setContent(newContent);
|
||||
setHasUnsavedChanges(true);
|
||||
};
|
||||
|
||||
// Splitter change handler
|
||||
@@ -119,7 +147,7 @@ const EditorPage = React.forwardRef((props, ref) => {
|
||||
{editMode === 'html' ? (
|
||||
<WysiwygEditor
|
||||
content={content}
|
||||
onContentChange={setContent}
|
||||
onContentChange={handleContentChange}
|
||||
/>
|
||||
) : (
|
||||
<MarkdownEditor
|
||||
@@ -148,6 +176,21 @@ const EditorPage = React.forwardRef((props, ref) => {
|
||||
Publish
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* Confirmation Modals */}
|
||||
<PublishModal
|
||||
isVisible={showPublishModal}
|
||||
onClose={() => setShowPublishModal(false)}
|
||||
onConfirm={handlePublishConfirm}
|
||||
postTitle={postData?.title}
|
||||
/>
|
||||
|
||||
<CancelModal
|
||||
isVisible={showCancelModal}
|
||||
onClose={() => setShowCancelModal(false)}
|
||||
onConfirm={handleCancelConfirm}
|
||||
hasUnsavedChanges={hasUnsavedChanges}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
Reference in New Issue
Block a user