feat: even more feature implementations
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useAppStore, PostData } from '../../store';
|
||||
import { useAppStore, PostData, UnsavedDraft } from '../../store';
|
||||
import { showToast } from '../Toast';
|
||||
import './Sidebar.css';
|
||||
|
||||
@@ -222,7 +222,7 @@ const SearchBox: React.FC<SearchBoxProps> = ({ onSearch }) => {
|
||||
};
|
||||
|
||||
const PostsList: React.FC = () => {
|
||||
const { posts, selectedPostId, setSelectedPost } = useAppStore();
|
||||
const { posts, selectedPostId, setSelectedPost, unsavedDrafts } = useAppStore();
|
||||
|
||||
// Filter state
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
@@ -321,20 +321,11 @@ const PostsList: React.FC = () => {
|
||||
applyFilters();
|
||||
}, [selectedTags, selectedCategories]);
|
||||
|
||||
const handleCreatePost = async () => {
|
||||
try {
|
||||
const newPost = await window.electronAPI?.posts.create({
|
||||
title: 'Untitled Post',
|
||||
content: '# New Post\n\nStart writing your content here...',
|
||||
});
|
||||
if (newPost) {
|
||||
setSelectedPost((newPost as PostData).id);
|
||||
showToast.success('Post created');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to create post:', error);
|
||||
showToast.error('Failed to create post');
|
||||
}
|
||||
const handleCreatePost = () => {
|
||||
// Create an unsaved draft instead of immediately saving to database
|
||||
const { createUnsavedDraft, setSelectedPost: selectPost } = useAppStore.getState();
|
||||
const draftId = createUnsavedDraft();
|
||||
selectPost(draftId);
|
||||
};
|
||||
|
||||
// Determine which posts to display
|
||||
@@ -414,6 +405,34 @@ const PostsList: React.FC = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Unsaved Drafts Section - always show at top if there are any */}
|
||||
{unsavedDrafts.length > 0 && (
|
||||
<div className="sidebar-section">
|
||||
<div className="sidebar-section-title">
|
||||
<span className="section-icon status-unsaved">●</span>
|
||||
Unsaved ({unsavedDrafts.length})
|
||||
</div>
|
||||
<div className="sidebar-list">
|
||||
{unsavedDrafts.map((draft: UnsavedDraft) => (
|
||||
<div
|
||||
key={draft.id}
|
||||
className={`sidebar-item post-type-new unsaved ${selectedPostId === draft.id ? 'selected' : ''}`}
|
||||
onClick={() => setSelectedPost(draft.id)}
|
||||
>
|
||||
<span className="post-type-icon" title="New post">✨</span>
|
||||
<div className="sidebar-item-content">
|
||||
<div className="sidebar-item-title">
|
||||
{draft.title || 'New Post'}
|
||||
<span className="unsaved-indicator">●</span>
|
||||
</div>
|
||||
<div className="sidebar-item-meta">Not yet saved</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{groupedPosts.draft.length > 0 && (
|
||||
<div className="sidebar-section">
|
||||
<div className="sidebar-section-title">
|
||||
|
||||
Reference in New Issue
Block a user