diff --git a/frontend/src/App.scss b/frontend/src/App.scss
index df3fcec..f5b1623 100644
--- a/frontend/src/App.scss
+++ b/frontend/src/App.scss
@@ -14,11 +14,6 @@ $navbar-height: 64px;
.file-tree-container {
width: 100%;
-
- & > div {
- padding: 0;
- margin: 0;
- }
}
}
diff --git a/frontend/src/components/ContentView.js b/frontend/src/components/ContentView.js
new file mode 100644
index 0000000..29aa61e
--- /dev/null
+++ b/frontend/src/components/ContentView.js
@@ -0,0 +1,51 @@
+import React from 'react';
+import Editor from './Editor';
+import MarkdownPreview from './MarkdownPreview';
+import { getFileUrl } from '../services/api';
+import { isImageFile } from '../utils/fileHelpers';
+
+const ContentView = ({
+ activeTab,
+ content,
+ selectedFile,
+ onContentChange,
+ onSave,
+ themeType,
+ onLinkClick,
+ lookupFileByName,
+}) => {
+ if (isImageFile(selectedFile)) {
+ return (
+
+
})
+
+ );
+ }
+
+ return activeTab === 'source' ? (
+
+ ) : (
+
+ );
+};
+
+export default ContentView;
diff --git a/frontend/src/components/FileActions.js b/frontend/src/components/FileActions.js
new file mode 100644
index 0000000..6a54f46
--- /dev/null
+++ b/frontend/src/components/FileActions.js
@@ -0,0 +1,78 @@
+import React from 'react';
+import { Button, Tooltip, ButtonGroup, Spacer } from '@geist-ui/core';
+import { Plus, Trash, GitPullRequest, GitCommit } from '@geist-ui/icons';
+
+const FileActions = ({
+ selectedFile,
+ gitEnabled,
+ gitAutoCommit,
+ onPull,
+ onCommitAndPush,
+ onCreateFile,
+ onDeleteFile,
+}) => {
+ return (
+
+
+ }
+ auto
+ scale={2 / 3}
+ onClick={onCreateFile}
+ px={0.6}
+ />
+
+
+
+ }
+ auto
+ scale={2 / 3}
+ onClick={onDeleteFile}
+ disabled={!selectedFile}
+ type="error"
+ px={0.6}
+ />
+
+
+
+ }
+ auto
+ scale={2 / 3}
+ onClick={onPull}
+ disabled={!gitEnabled}
+ px={0.6}
+ />
+
+
+
+ }
+ auto
+ scale={2 / 3}
+ onClick={onCommitAndPush}
+ disabled={!gitEnabled || gitAutoCommit}
+ px={0.6}
+ />
+
+
+ );
+};
+
+export default FileActions;
diff --git a/frontend/src/components/FileTree.js b/frontend/src/components/FileTree.js
index 4239e40..3eb5bcb 100644
--- a/frontend/src/components/FileTree.js
+++ b/frontend/src/components/FileTree.js
@@ -1,26 +1,11 @@
import React from 'react';
-import { Tree, Button, Tooltip, Spacer, ButtonGroup } from '@geist-ui/core';
-import {
- File,
- Folder,
- GitPullRequest,
- GitCommit,
- Plus,
- Trash,
- Image,
-} from '@geist-ui/icons';
-import { isImageFile } from '../utils/fileHelpers';
+import { Tree } from '@geist-ui/core';
+import { File, Folder, Image } from '@geist-ui/icons';
const FileTree = ({
files = [],
onFileSelect = () => {},
selectedFile = null,
- gitEnabled = false,
- gitAutoCommit = false,
- onPull = () => {},
- onCommitAndPush = () => {},
- onCreateFile = () => {},
- onDeleteFile = () => {},
}) => {
if (files.length === 0) {
return No files to display
;
@@ -39,80 +24,23 @@ const FileTree = ({
);
};
+ const isImageFile = (fileName) => {
+ const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg'];
+ return imageExtensions.some((ext) => fileName.toLowerCase().endsWith(ext));
+ };
+
const renderIcon = ({ type, name }) => {
if (type === 'directory') return ;
return isImageFile(name) ? : ;
};
return (
-
-
-
- }
- auto
- scale={2 / 3}
- onClick={onCreateFile}
- px={0.6}
- />
-
-
-
- }
- auto
- scale={2 / 3}
- onClick={onDeleteFile}
- disabled={!selectedFile}
- type="error"
- px={0.6}
- />
-
-
-
- }
- auto
- scale={2 / 3}
- onClick={onPull}
- disabled={!gitEnabled}
- px={0.6}
- />
-
-
-
- }
- auto
- scale={2 / 3}
- onClick={onCommitAndPush}
- disabled={!gitEnabled || gitAutoCommit}
- px={0.6}
- />
-
-
-
-
+
);
};
diff --git a/frontend/src/components/MainContent.js b/frontend/src/components/MainContent.js
index 01ac0d9..7142c19 100644
--- a/frontend/src/components/MainContent.js
+++ b/frontend/src/components/MainContent.js
@@ -11,16 +11,10 @@ import {
Button,
} from '@geist-ui/core';
import { Code, Eye } from '@geist-ui/icons';
-import Editor from './Editor';
import FileTree from './FileTree';
-import MarkdownPreview from './MarkdownPreview';
-import {
- commitAndPush,
- saveFileContent,
- deleteFile,
- getFileUrl,
- lookupFileByName,
-} from '../services/api';
+import FileActions from './FileActions';
+import ContentView from './ContentView';
+import { commitAndPush, saveFileContent, deleteFile } from '../services/api';
import { isImageFile } from '../utils/fileHelpers';
const MainContent = ({
@@ -33,33 +27,31 @@ const MainContent = ({
onContentChange,
onSave,
settings,
- onPullLatestChanges,
+ pullLatestChanges,
onLinkClick,
+ lookupFileByName,
}) => {
const [activeTab, setActiveTab] = useState('source');
const { type: themeType } = useTheme();
const { setToast } = useToasts();
const [newFileModalVisible, setNewFileModalVisible] = useState(false);
const [newFileName, setNewFileName] = useState('');
- const [isCurrentFileImage, setIsCurrentFileImage] = useState(false);
useEffect(() => {
- const currentFileIsImage = isImageFile(selectedFile);
- setIsCurrentFileImage(currentFileIsImage);
- if (currentFileIsImage) {
+ if (isImageFile(selectedFile)) {
setActiveTab('preview');
}
}, [selectedFile]);
const handleTabChange = (value) => {
- if (!isCurrentFileImage || value === 'preview') {
+ if (!isImageFile(selectedFile) || value === 'preview') {
setActiveTab(value);
}
};
const handlePull = async () => {
try {
- await onPullLatestChanges();
+ await pullLatestChanges();
setToast({ text: 'Successfully pulled latest changes', type: 'success' });
} catch (error) {
setToast({
@@ -78,7 +70,7 @@ const MainContent = ({
text: 'Changes committed and pushed successfully',
type: 'success',
});
- await onPullLatestChanges(); // Pull changes after successful push
+ await pullLatestChanges();
}
} catch (error) {
setToast({
@@ -97,8 +89,8 @@ const MainContent = ({
try {
await saveFileContent(newFileName, '');
setToast({ text: 'New file created successfully', type: 'success' });
- await onPullLatestChanges(); // Refresh file list
- onFileSelect(newFileName); // Select the new file
+ await pullLatestChanges();
+ onFileSelect(newFileName);
} catch (error) {
setToast({
text: 'Failed to create new file: ' + error.message,
@@ -119,8 +111,8 @@ const MainContent = ({
try {
await deleteFile(selectedFile);
setToast({ text: 'File deleted successfully', type: 'success' });
- await onPullLatestChanges(); // Refresh file list
- onFileSelect(null); // Deselect the file
+ await pullLatestChanges();
+ onFileSelect(null);
} catch (error) {
setToast({
text: 'Failed to delete file: ' + error.message,
@@ -153,9 +145,7 @@ const MainContent = ({
-
+
}
value="source"
- disabled={isCurrentFileImage}
+ disabled={isImageFile(selectedFile)}
/>
} value="preview" />
- {activeTab === 'source' && !isCurrentFileImage ? (
-
- ) : isCurrentFileImage ? (
-
-
})
-
- ) : (
-
- )}
+
diff --git a/frontend/src/components/Settings.js b/frontend/src/components/Settings.js
index 03123e2..2ab0c0b 100644
--- a/frontend/src/components/Settings.js
+++ b/frontend/src/components/Settings.js
@@ -1,16 +1,9 @@
import React, { useState, useEffect, useCallback } from 'react';
-import {
- Modal,
- Text,
- Toggle,
- Input,
- Spacer,
- useTheme,
- Button,
- Dot,
- useToasts,
-} from '@geist-ui/core';
+import { Modal, Spacer, useTheme, Dot, useToasts } from '@geist-ui/core';
import { saveUserSettings, fetchUserSettings } from '../services/api';
+import AppearanceSettings from './settings/AppearanceSettings';
+import EditorSettings from './settings/EditorSettings';
+import GitSettings from './settings/GitSettings';
const Settings = ({ visible, onClose, currentTheme, onThemeChange }) => {
const theme = useTheme();
@@ -97,86 +90,25 @@ const Settings = ({ visible, onClose, currentTheme, onThemeChange }) => {
)}
-
-
Appearance
-
- Dark Mode
-
-
-
+
-
-
Editor
-
- Auto Save
- handleInputChange('autoSave', e.target.checked)}
- />
-
-
+ handleInputChange('autoSave', value)}
+ />
-
-
Git Integration
-
- Enable Git
-
- handleInputChange('gitEnabled', e.target.checked)
- }
- />
-
-
-
+
Cancel
diff --git a/frontend/src/components/settings/AppearanceSettings.js b/frontend/src/components/settings/AppearanceSettings.js
new file mode 100644
index 0000000..185db81
--- /dev/null
+++ b/frontend/src/components/settings/AppearanceSettings.js
@@ -0,0 +1,16 @@
+import React from 'react';
+import { Text, Toggle } from '@geist-ui/core';
+
+const AppearanceSettings = ({ themeSettings, onThemeChange }) => {
+ return (
+
+
Appearance
+
+ Dark Mode
+
+
+
+ );
+};
+
+export default AppearanceSettings;
diff --git a/frontend/src/components/settings/EditorSettings.js b/frontend/src/components/settings/EditorSettings.js
new file mode 100644
index 0000000..fa679f9
--- /dev/null
+++ b/frontend/src/components/settings/EditorSettings.js
@@ -0,0 +1,26 @@
+import React from 'react';
+import { Text, Toggle, Tooltip } from '@geist-ui/core';
+
+const EditorSettings = ({ autoSave, onAutoSaveChange }) => {
+ return (
+
+
Editor
+
+ Auto Save
+
+ onAutoSaveChange(e.target.checked)}
+ disabled
+ />
+
+
+
+ );
+};
+
+export default EditorSettings;
diff --git a/frontend/src/components/settings/GitSettings.js b/frontend/src/components/settings/GitSettings.js
new file mode 100644
index 0000000..883e5c0
--- /dev/null
+++ b/frontend/src/components/settings/GitSettings.js
@@ -0,0 +1,71 @@
+import React from 'react';
+import { Text, Toggle, Input, Spacer } from '@geist-ui/core';
+
+const GitSettings = ({
+ gitEnabled,
+ gitUrl,
+ gitUser,
+ gitToken,
+ gitAutoCommit,
+ gitCommitMsgTemplate,
+ onInputChange,
+}) => {
+ return (
+
+
Git Integration
+
+ Enable Git
+ onInputChange('gitEnabled', e.target.checked)}
+ />
+
+
+
+ );
+};
+
+export default GitSettings;