diff --git a/VISION.md b/VISION.md index 4a81e6c..d41cf50 100644 --- a/VISION.md +++ b/VISION.md @@ -261,7 +261,9 @@ to easy template creation. For the styling I want the system to be based on css templates, so that the look can be easily swapped to the wish of the user. There should be a selection of light and dark themes bundled with the application, so that starting is simple. New css templates must be easily integrateable into the application, -maybe even with easy importing from a central repository site or something like that. +maybe even with easy importing from a central repository site or something like that. I think Pico CSS is a +good choice, since it sticks to semantic HTML and auto-adapts to light/dark mode settings of users. +I want to work minimalist, but still allow some style influence into the site based on user prefs. Check the site https://hugo.rfc1437.de/ for its structure, this is the structure of blog I want to be capable of building with this tooling. So we need templates for overview pages and ways to manage menues diff --git a/src/renderer/components/SettingsView/SettingsView.css b/src/renderer/components/SettingsView/SettingsView.css index 9bc43c7..0af0204 100644 --- a/src/renderer/components/SettingsView/SettingsView.css +++ b/src/renderer/components/SettingsView/SettingsView.css @@ -185,7 +185,8 @@ } .setting-control input[type="text"], -.setting-control input[type="password"] { +.setting-control input[type="password"], +.setting-control textarea { width: 100%; max-width: 400px; padding: 6px 10px; @@ -195,13 +196,21 @@ color: var(--vscode-input-foreground); border-radius: 4px; outline: none; + font-family: inherit; } -.setting-control input:focus { +.setting-control textarea { + resize: vertical; + min-height: 60px; +} + +.setting-control input:focus, +.setting-control textarea:focus { border-color: var(--vscode-focusBorder); } -.setting-control input::placeholder { +.setting-control input::placeholder, +.setting-control textarea::placeholder { color: var(--vscode-input-placeholderForeground); } diff --git a/src/renderer/components/SettingsView/SettingsView.tsx b/src/renderer/components/SettingsView/SettingsView.tsx index 047a7a5..342f85a 100644 --- a/src/renderer/components/SettingsView/SettingsView.tsx +++ b/src/renderer/components/SettingsView/SettingsView.tsx @@ -4,7 +4,7 @@ import { showToast } from '../Toast'; import './SettingsView.css'; // Export category IDs for sidebar navigation -export type SettingsCategory = 'editor' | 'content' | 'sync' | 'publishing' | 'data'; +export type SettingsCategory = 'project' | 'editor' | 'content' | 'sync' | 'publishing' | 'data'; // Scroll to a settings section by category ID export const scrollToSettingsSection = (category: SettingsCategory) => { @@ -102,14 +102,18 @@ const SettingSection: React.FC<{ }; export const SettingsView: React.FC = () => { - const { preferredEditorMode, setPreferredEditorMode, syncConfigured } = useAppStore(); + const { preferredEditorMode, setPreferredEditorMode, syncConfigured, activeProject, setActiveProject } = useAppStore(); const [searchQuery, setSearchQuery] = useState(''); const [credentials, setCredentials] = useState(defaultCredentials); const [showSecrets, setShowSecrets] = useState(false); const [dropboxConfigured, setDropboxConfigured] = useState(false); const [dropboxLastSync, setDropboxLastSync] = useState(null); const contentRef = useRef(null); - + + // Project settings + const [projectName, setProjectName] = useState(''); + const [projectDescription, setProjectDescription] = useState(''); + // Post categories management const [postCategories, setPostCategories] = useState(DEFAULT_POST_CATEGORIES); const [newCategoryInput, setNewCategoryInput] = useState(''); @@ -128,6 +132,14 @@ export const SettingsView: React.FC = () => { ); }, [searchQuery]); + // Sync project fields from active project + useEffect(() => { + if (activeProject) { + setProjectName(activeProject.name); + setProjectDescription(activeProject.description || ''); + } + }, [activeProject]); + // Load saved credentials and categories useEffect(() => { const loadSettings = async () => { @@ -284,13 +296,76 @@ export const SettingsView: React.FC = () => { } }; + // Save project settings + const handleSaveProject = async () => { + if (!activeProject) return; + try { + const updated = await window.electronAPI?.projects.update(activeProject.id, { + name: projectName.trim() || activeProject.name, + description: projectDescription.trim(), + }); + if (updated) { + setActiveProject(updated as any); + useAppStore.getState().updateProject(activeProject.id, updated as any); + } + showToast.success('Project settings saved'); + } catch (error) { + console.error('Failed to save project settings:', error); + showToast.error('Failed to save project settings'); + } + }; + // Keywords for each section for search filtering + const projectKeywords = ['project', 'name', 'description', 'blog', 'site']; const editorKeywords = ['editor', 'mode', 'wysiwyg', 'markdown', 'preview', 'visual']; const contentKeywords = ['content', 'categories', 'post', 'article', 'picture', 'aside', 'page']; const syncKeywords = ['sync', 'turso', 'libsql', 'cloud', 'database', 'dropbox', 'file', 'backup', 'token', 'remote']; const publishingKeywords = ['publishing', 'ftp', 'ssh', 'deploy', 'server', 'host', 'upload']; const dataKeywords = ['data', 'database', 'rebuild', 'maintenance', 'posts', 'media', 'links', 'folder', 'filesystem']; + const renderProjectSettings = () => ( +