diff --git a/public/derek.jpg b/public/derek.jpg new file mode 100644 index 0000000..acb490c Binary files /dev/null and b/public/derek.jpg differ diff --git a/src/assets/css/index.css b/src/assets/css/index.css index 12d89ac..c885f9a 100644 --- a/src/assets/css/index.css +++ b/src/assets/css/index.css @@ -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); } \ No newline at end of file diff --git a/src/components/AppBar.jsx b/src/components/AppBar.jsx index 06aa6b5..86096c6 100644 --- a/src/components/AppBar.jsx +++ b/src/components/AppBar.jsx @@ -52,9 +52,35 @@ const CampfireAppBar = ({ isLoggedIn, onLogin, onDrawerToggle }) => { {isLoggedIn ? ( - - Logout - + <> + + Logout + + + + + > ) : ( Login diff --git a/src/components/Editor/UI/CancelModal.jsx b/src/components/Editor/UI/CancelModal.jsx new file mode 100644 index 0000000..f61d273 --- /dev/null +++ b/src/components/Editor/UI/CancelModal.jsx @@ -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 ( + + + {hasUnsavedChanges ? ( + <> + + You have unsaved changes. + + + Are you sure you want to cancel? All unsaved changes will be lost. + + > + ) : ( + + Are you sure you want to cancel editing? + + )} + + + + Continue Editing + + + {hasUnsavedChanges ? 'Discard Changes' : 'Cancel'} + + + + ); +}; + +export default CancelModal; diff --git a/src/components/Editor/UI/PublishModal.jsx b/src/components/Editor/UI/PublishModal.jsx new file mode 100644 index 0000000..eaea66d --- /dev/null +++ b/src/components/Editor/UI/PublishModal.jsx @@ -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 ( + + + + Are you sure you want to publish this post? + + {postTitle && ( + + "{postTitle}" + + )} + + This will make the post visible to your readers. + + + + + Cancel + + + Publish Post + + + + ); +}; + +export default PublishModal; diff --git a/src/pages/EditorPage.jsx b/src/pages/EditorPage.jsx index 3142d45..91f145a 100644 --- a/src/pages/EditorPage.jsx +++ b/src/pages/EditorPage.jsx @@ -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' ? ( ) : ( { Publish + + {/* Confirmation Modals */} + setShowPublishModal(false)} + onConfirm={handlePublishConfirm} + postTitle={postData?.title} + /> + + setShowCancelModal(false)} + onConfirm={handleCancelConfirm} + hasUnsavedChanges={hasUnsavedChanges} + /> ); });
+ You have unsaved changes. +
+ Are you sure you want to cancel? All unsaved changes will be lost. +
+ Are you sure you want to cancel editing? +
+ Are you sure you want to publish this post? +
+ "{postTitle}" +
+ This will make the post visible to your readers. +