mirror of
https://github.com/lordmathis/lemma.git
synced 2025-11-06 07:54:22 +00:00
Split large components
This commit is contained in:
@@ -14,11 +14,6 @@ $navbar-height: 64px;
|
|||||||
|
|
||||||
.file-tree-container {
|
.file-tree-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
& > div {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
51
frontend/src/components/ContentView.js
Normal file
51
frontend/src/components/ContentView.js
Normal file
@@ -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 (
|
||||||
|
<div className="image-preview">
|
||||||
|
<img
|
||||||
|
src={getFileUrl(selectedFile)}
|
||||||
|
alt={selectedFile}
|
||||||
|
style={{
|
||||||
|
maxWidth: '100%',
|
||||||
|
maxHeight: '100%',
|
||||||
|
objectFit: 'contain',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return activeTab === 'source' ? (
|
||||||
|
<Editor
|
||||||
|
content={content}
|
||||||
|
onChange={onContentChange}
|
||||||
|
onSave={onSave}
|
||||||
|
filePath={selectedFile}
|
||||||
|
themeType={themeType}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<MarkdownPreview
|
||||||
|
content={content}
|
||||||
|
baseUrl={window.API_BASE_URL}
|
||||||
|
onLinkClick={onLinkClick}
|
||||||
|
lookupFileByName={lookupFileByName}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ContentView;
|
||||||
78
frontend/src/components/FileActions.js
Normal file
78
frontend/src/components/FileActions.js
Normal file
@@ -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 (
|
||||||
|
<ButtonGroup className="file-actions">
|
||||||
|
<Tooltip text="Create new file" type="dark">
|
||||||
|
<Button
|
||||||
|
icon={<Plus />}
|
||||||
|
auto
|
||||||
|
scale={2 / 3}
|
||||||
|
onClick={onCreateFile}
|
||||||
|
px={0.6}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
<Spacer w={0.5} />
|
||||||
|
<Tooltip
|
||||||
|
text={selectedFile ? 'Delete current file' : 'No file selected'}
|
||||||
|
type="dark"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
icon={<Trash />}
|
||||||
|
auto
|
||||||
|
scale={2 / 3}
|
||||||
|
onClick={onDeleteFile}
|
||||||
|
disabled={!selectedFile}
|
||||||
|
type="error"
|
||||||
|
px={0.6}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
<Spacer w={0.5} />
|
||||||
|
<Tooltip
|
||||||
|
text={gitEnabled ? 'Pull changes from remote' : 'Git is not enabled'}
|
||||||
|
type="dark"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
icon={<GitPullRequest />}
|
||||||
|
auto
|
||||||
|
scale={2 / 3}
|
||||||
|
onClick={onPull}
|
||||||
|
disabled={!gitEnabled}
|
||||||
|
px={0.6}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
<Spacer w={0.5} />
|
||||||
|
<Tooltip
|
||||||
|
text={
|
||||||
|
!gitEnabled
|
||||||
|
? 'Git is not enabled'
|
||||||
|
: gitAutoCommit
|
||||||
|
? 'Auto-commit is enabled'
|
||||||
|
: 'Commit and push changes'
|
||||||
|
}
|
||||||
|
type="dark"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
icon={<GitCommit />}
|
||||||
|
auto
|
||||||
|
scale={2 / 3}
|
||||||
|
onClick={onCommitAndPush}
|
||||||
|
disabled={!gitEnabled || gitAutoCommit}
|
||||||
|
px={0.6}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
</ButtonGroup>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FileActions;
|
||||||
@@ -1,26 +1,11 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Tree, Button, Tooltip, Spacer, ButtonGroup } from '@geist-ui/core';
|
import { Tree } from '@geist-ui/core';
|
||||||
import {
|
import { File, Folder, Image } from '@geist-ui/icons';
|
||||||
File,
|
|
||||||
Folder,
|
|
||||||
GitPullRequest,
|
|
||||||
GitCommit,
|
|
||||||
Plus,
|
|
||||||
Trash,
|
|
||||||
Image,
|
|
||||||
} from '@geist-ui/icons';
|
|
||||||
import { isImageFile } from '../utils/fileHelpers';
|
|
||||||
|
|
||||||
const FileTree = ({
|
const FileTree = ({
|
||||||
files = [],
|
files = [],
|
||||||
onFileSelect = () => {},
|
onFileSelect = () => {},
|
||||||
selectedFile = null,
|
selectedFile = null,
|
||||||
gitEnabled = false,
|
|
||||||
gitAutoCommit = false,
|
|
||||||
onPull = () => {},
|
|
||||||
onCommitAndPush = () => {},
|
|
||||||
onCreateFile = () => {},
|
|
||||||
onDeleteFile = () => {},
|
|
||||||
}) => {
|
}) => {
|
||||||
if (files.length === 0) {
|
if (files.length === 0) {
|
||||||
return <div>No files to display</div>;
|
return <div>No files to display</div>;
|
||||||
@@ -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 }) => {
|
const renderIcon = ({ type, name }) => {
|
||||||
if (type === 'directory') return <Folder />;
|
if (type === 'directory') return <Folder />;
|
||||||
return isImageFile(name) ? <Image /> : <File />;
|
return isImageFile(name) ? <Image /> : <File />;
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<Tree
|
||||||
<ButtonGroup className="file-tree-buttons">
|
value={files}
|
||||||
<Tooltip text="Create new file" type="dark">
|
onClick={handleSelect}
|
||||||
<Button
|
renderIcon={renderIcon}
|
||||||
icon={<Plus />}
|
renderLabel={renderLabel}
|
||||||
auto
|
/>
|
||||||
scale={2 / 3}
|
|
||||||
onClick={onCreateFile}
|
|
||||||
px={0.6}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
<Spacer w={0.5} />
|
|
||||||
<Tooltip
|
|
||||||
text={selectedFile ? 'Delete current file' : 'No file selected'}
|
|
||||||
type="dark"
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
icon={<Trash />}
|
|
||||||
auto
|
|
||||||
scale={2 / 3}
|
|
||||||
onClick={onDeleteFile}
|
|
||||||
disabled={!selectedFile}
|
|
||||||
type="error"
|
|
||||||
px={0.6}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
<Spacer w={0.5} />
|
|
||||||
<Tooltip
|
|
||||||
text={gitEnabled ? 'Pull changes from remote' : 'Git is not enabled'}
|
|
||||||
type="dark"
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
icon={<GitPullRequest />}
|
|
||||||
auto
|
|
||||||
scale={2 / 3}
|
|
||||||
onClick={onPull}
|
|
||||||
disabled={!gitEnabled}
|
|
||||||
px={0.6}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
<Spacer w={0.5} />
|
|
||||||
<Tooltip
|
|
||||||
text={
|
|
||||||
!gitEnabled
|
|
||||||
? 'Git is not enabled'
|
|
||||||
: gitAutoCommit
|
|
||||||
? 'Auto-commit is enabled'
|
|
||||||
: 'Commit and push changes'
|
|
||||||
}
|
|
||||||
type="dark"
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
icon={<GitCommit />}
|
|
||||||
auto
|
|
||||||
scale={2 / 3}
|
|
||||||
onClick={onCommitAndPush}
|
|
||||||
disabled={!gitEnabled || gitAutoCommit}
|
|
||||||
px={0.6}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
</ButtonGroup>
|
|
||||||
<Tree
|
|
||||||
value={files}
|
|
||||||
onClick={handleSelect}
|
|
||||||
renderIcon={renderIcon}
|
|
||||||
renderLabel={renderLabel}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,16 +11,10 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
} from '@geist-ui/core';
|
} from '@geist-ui/core';
|
||||||
import { Code, Eye } from '@geist-ui/icons';
|
import { Code, Eye } from '@geist-ui/icons';
|
||||||
import Editor from './Editor';
|
|
||||||
import FileTree from './FileTree';
|
import FileTree from './FileTree';
|
||||||
import MarkdownPreview from './MarkdownPreview';
|
import FileActions from './FileActions';
|
||||||
import {
|
import ContentView from './ContentView';
|
||||||
commitAndPush,
|
import { commitAndPush, saveFileContent, deleteFile } from '../services/api';
|
||||||
saveFileContent,
|
|
||||||
deleteFile,
|
|
||||||
getFileUrl,
|
|
||||||
lookupFileByName,
|
|
||||||
} from '../services/api';
|
|
||||||
import { isImageFile } from '../utils/fileHelpers';
|
import { isImageFile } from '../utils/fileHelpers';
|
||||||
|
|
||||||
const MainContent = ({
|
const MainContent = ({
|
||||||
@@ -33,33 +27,31 @@ const MainContent = ({
|
|||||||
onContentChange,
|
onContentChange,
|
||||||
onSave,
|
onSave,
|
||||||
settings,
|
settings,
|
||||||
onPullLatestChanges,
|
pullLatestChanges,
|
||||||
onLinkClick,
|
onLinkClick,
|
||||||
|
lookupFileByName,
|
||||||
}) => {
|
}) => {
|
||||||
const [activeTab, setActiveTab] = useState('source');
|
const [activeTab, setActiveTab] = useState('source');
|
||||||
const { type: themeType } = useTheme();
|
const { type: themeType } = useTheme();
|
||||||
const { setToast } = useToasts();
|
const { setToast } = useToasts();
|
||||||
const [newFileModalVisible, setNewFileModalVisible] = useState(false);
|
const [newFileModalVisible, setNewFileModalVisible] = useState(false);
|
||||||
const [newFileName, setNewFileName] = useState('');
|
const [newFileName, setNewFileName] = useState('');
|
||||||
const [isCurrentFileImage, setIsCurrentFileImage] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const currentFileIsImage = isImageFile(selectedFile);
|
if (isImageFile(selectedFile)) {
|
||||||
setIsCurrentFileImage(currentFileIsImage);
|
|
||||||
if (currentFileIsImage) {
|
|
||||||
setActiveTab('preview');
|
setActiveTab('preview');
|
||||||
}
|
}
|
||||||
}, [selectedFile]);
|
}, [selectedFile]);
|
||||||
|
|
||||||
const handleTabChange = (value) => {
|
const handleTabChange = (value) => {
|
||||||
if (!isCurrentFileImage || value === 'preview') {
|
if (!isImageFile(selectedFile) || value === 'preview') {
|
||||||
setActiveTab(value);
|
setActiveTab(value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePull = async () => {
|
const handlePull = async () => {
|
||||||
try {
|
try {
|
||||||
await onPullLatestChanges();
|
await pullLatestChanges();
|
||||||
setToast({ text: 'Successfully pulled latest changes', type: 'success' });
|
setToast({ text: 'Successfully pulled latest changes', type: 'success' });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setToast({
|
setToast({
|
||||||
@@ -78,7 +70,7 @@ const MainContent = ({
|
|||||||
text: 'Changes committed and pushed successfully',
|
text: 'Changes committed and pushed successfully',
|
||||||
type: 'success',
|
type: 'success',
|
||||||
});
|
});
|
||||||
await onPullLatestChanges(); // Pull changes after successful push
|
await pullLatestChanges();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setToast({
|
setToast({
|
||||||
@@ -97,8 +89,8 @@ const MainContent = ({
|
|||||||
try {
|
try {
|
||||||
await saveFileContent(newFileName, '');
|
await saveFileContent(newFileName, '');
|
||||||
setToast({ text: 'New file created successfully', type: 'success' });
|
setToast({ text: 'New file created successfully', type: 'success' });
|
||||||
await onPullLatestChanges(); // Refresh file list
|
await pullLatestChanges();
|
||||||
onFileSelect(newFileName); // Select the new file
|
onFileSelect(newFileName);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setToast({
|
setToast({
|
||||||
text: 'Failed to create new file: ' + error.message,
|
text: 'Failed to create new file: ' + error.message,
|
||||||
@@ -119,8 +111,8 @@ const MainContent = ({
|
|||||||
try {
|
try {
|
||||||
await deleteFile(selectedFile);
|
await deleteFile(selectedFile);
|
||||||
setToast({ text: 'File deleted successfully', type: 'success' });
|
setToast({ text: 'File deleted successfully', type: 'success' });
|
||||||
await onPullLatestChanges(); // Refresh file list
|
await pullLatestChanges();
|
||||||
onFileSelect(null); // Deselect the file
|
onFileSelect(null);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setToast({
|
setToast({
|
||||||
text: 'Failed to delete file: ' + error.message,
|
text: 'Failed to delete file: ' + error.message,
|
||||||
@@ -153,9 +145,7 @@ const MainContent = ({
|
|||||||
<Grid.Container gap={1} height="calc(100vh - 64px)">
|
<Grid.Container gap={1} height="calc(100vh - 64px)">
|
||||||
<Grid xs={24} sm={6} md={5} lg={4} height="100%" className="sidebar">
|
<Grid xs={24} sm={6} md={5} lg={4} height="100%" className="sidebar">
|
||||||
<div className="file-tree-container">
|
<div className="file-tree-container">
|
||||||
<FileTree
|
<FileActions
|
||||||
files={files}
|
|
||||||
onFileSelect={onFileSelect}
|
|
||||||
selectedFile={selectedFile}
|
selectedFile={selectedFile}
|
||||||
gitEnabled={settings.gitEnabled}
|
gitEnabled={settings.gitEnabled}
|
||||||
gitAutoCommit={settings.gitAutoCommit}
|
gitAutoCommit={settings.gitAutoCommit}
|
||||||
@@ -164,6 +154,11 @@ const MainContent = ({
|
|||||||
onCreateFile={handleCreateFile}
|
onCreateFile={handleCreateFile}
|
||||||
onDeleteFile={handleDeleteFile}
|
onDeleteFile={handleDeleteFile}
|
||||||
/>
|
/>
|
||||||
|
<FileTree
|
||||||
|
files={files}
|
||||||
|
onFileSelect={onFileSelect}
|
||||||
|
selectedFile={selectedFile}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid
|
<Grid
|
||||||
@@ -180,40 +175,22 @@ const MainContent = ({
|
|||||||
<Tabs.Item
|
<Tabs.Item
|
||||||
label={<Code />}
|
label={<Code />}
|
||||||
value="source"
|
value="source"
|
||||||
disabled={isCurrentFileImage}
|
disabled={isImageFile(selectedFile)}
|
||||||
/>
|
/>
|
||||||
<Tabs.Item label={<Eye />} value="preview" />
|
<Tabs.Item label={<Eye />} value="preview" />
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
<div className="content-body">
|
<div className="content-body">
|
||||||
{activeTab === 'source' && !isCurrentFileImage ? (
|
<ContentView
|
||||||
<Editor
|
activeTab={activeTab}
|
||||||
content={content}
|
content={content}
|
||||||
onChange={onContentChange}
|
selectedFile={selectedFile}
|
||||||
onSave={onSave}
|
onContentChange={onContentChange}
|
||||||
filePath={selectedFile}
|
onSave={onSave}
|
||||||
themeType={themeType}
|
themeType={themeType}
|
||||||
/>
|
onLinkClick={onLinkClick}
|
||||||
) : isCurrentFileImage ? (
|
lookupFileByName={lookupFileByName}
|
||||||
<div className="image-preview">
|
/>
|
||||||
<img
|
|
||||||
src={getFileUrl(selectedFile)}
|
|
||||||
alt={selectedFile}
|
|
||||||
style={{
|
|
||||||
maxWidth: '100%',
|
|
||||||
maxHeight: '100%',
|
|
||||||
objectFit: 'contain',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<MarkdownPreview
|
|
||||||
content={content}
|
|
||||||
baseUrl={window.API_BASE_URL}
|
|
||||||
onLinkClick={onLinkClick}
|
|
||||||
lookupFileByName={lookupFileByName}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid.Container>
|
</Grid.Container>
|
||||||
|
|||||||
@@ -1,16 +1,9 @@
|
|||||||
import React, { useState, useEffect, useCallback } from 'react';
|
import React, { useState, useEffect, useCallback } from 'react';
|
||||||
import {
|
import { Modal, Spacer, useTheme, Dot, useToasts } from '@geist-ui/core';
|
||||||
Modal,
|
|
||||||
Text,
|
|
||||||
Toggle,
|
|
||||||
Input,
|
|
||||||
Spacer,
|
|
||||||
useTheme,
|
|
||||||
Button,
|
|
||||||
Dot,
|
|
||||||
useToasts,
|
|
||||||
} from '@geist-ui/core';
|
|
||||||
import { saveUserSettings, fetchUserSettings } from '../services/api';
|
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 Settings = ({ visible, onClose, currentTheme, onThemeChange }) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
@@ -97,86 +90,25 @@ const Settings = ({ visible, onClose, currentTheme, onThemeChange }) => {
|
|||||||
)}
|
)}
|
||||||
</Modal.Title>
|
</Modal.Title>
|
||||||
<Modal.Content>
|
<Modal.Content>
|
||||||
<div className="setting-group">
|
<AppearanceSettings
|
||||||
<Text h4>Appearance</Text>
|
themeSettings={themeSettings}
|
||||||
<div className="setting-item">
|
onThemeChange={handleThemeChange}
|
||||||
<Text>Dark Mode</Text>
|
/>
|
||||||
<Toggle
|
|
||||||
checked={themeSettings === 'dark'}
|
|
||||||
onChange={handleThemeChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Spacer h={1} />
|
<Spacer h={1} />
|
||||||
<div className="setting-group">
|
<EditorSettings
|
||||||
<Text h4>Editor</Text>
|
autoSave={settings.autoSave}
|
||||||
<div className="setting-item">
|
onAutoSaveChange={(value) => handleInputChange('autoSave', value)}
|
||||||
<Text>Auto Save</Text>
|
/>
|
||||||
<Toggle
|
|
||||||
checked={settings.autoSave}
|
|
||||||
onChange={(e) => handleInputChange('autoSave', e.target.checked)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Spacer h={1} />
|
<Spacer h={1} />
|
||||||
<div className="setting-group">
|
<GitSettings
|
||||||
<Text h4>Git Integration</Text>
|
gitEnabled={settings.gitEnabled}
|
||||||
<div className="setting-item">
|
gitUrl={settings.gitUrl}
|
||||||
<Text>Enable Git</Text>
|
gitUser={settings.gitUser}
|
||||||
<Toggle
|
gitToken={settings.gitToken}
|
||||||
checked={settings.gitEnabled}
|
gitAutoCommit={settings.gitAutoCommit}
|
||||||
onChange={(e) =>
|
gitCommitMsgTemplate={settings.gitCommitMsgTemplate}
|
||||||
handleInputChange('gitEnabled', e.target.checked)
|
onInputChange={handleInputChange}
|
||||||
}
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className={settings.gitEnabled ? '' : 'disabled'}>
|
|
||||||
<Input
|
|
||||||
width="100%"
|
|
||||||
label="Git URL"
|
|
||||||
value={settings.gitUrl}
|
|
||||||
onChange={(e) => handleInputChange('gitUrl', e.target.value)}
|
|
||||||
disabled={!settings.gitEnabled}
|
|
||||||
/>
|
|
||||||
<Spacer h={0.5} />
|
|
||||||
<Input
|
|
||||||
width="100%"
|
|
||||||
label="Git Username"
|
|
||||||
value={settings.gitUser}
|
|
||||||
onChange={(e) => handleInputChange('gitUser', e.target.value)}
|
|
||||||
disabled={!settings.gitEnabled}
|
|
||||||
/>
|
|
||||||
<Spacer h={0.5} />
|
|
||||||
<Input.Password
|
|
||||||
width="100%"
|
|
||||||
label="Git Token"
|
|
||||||
value={settings.gitToken}
|
|
||||||
onChange={(e) => handleInputChange('gitToken', e.target.value)}
|
|
||||||
disabled={!settings.gitEnabled}
|
|
||||||
/>
|
|
||||||
<Spacer h={0.5} />
|
|
||||||
<div className="setting-item">
|
|
||||||
<Text>Auto Commit</Text>
|
|
||||||
<Toggle
|
|
||||||
checked={settings.gitAutoCommit}
|
|
||||||
onChange={(e) =>
|
|
||||||
handleInputChange('gitAutoCommit', e.target.checked)
|
|
||||||
}
|
|
||||||
disabled={!settings.gitEnabled}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<Spacer h={0.5} />
|
|
||||||
<Input
|
|
||||||
width="100%"
|
|
||||||
label="Commit Message Template"
|
|
||||||
value={settings.gitCommitMsgTemplate}
|
|
||||||
onChange={(e) =>
|
|
||||||
handleInputChange('gitCommitMsgTemplate', e.target.value)
|
|
||||||
}
|
|
||||||
disabled={!settings.gitEnabled}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Modal.Content>
|
</Modal.Content>
|
||||||
<Modal.Action passive onClick={onClose}>
|
<Modal.Action passive onClick={onClose}>
|
||||||
Cancel
|
Cancel
|
||||||
|
|||||||
16
frontend/src/components/settings/AppearanceSettings.js
Normal file
16
frontend/src/components/settings/AppearanceSettings.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Text, Toggle } from '@geist-ui/core';
|
||||||
|
|
||||||
|
const AppearanceSettings = ({ themeSettings, onThemeChange }) => {
|
||||||
|
return (
|
||||||
|
<div className="setting-group">
|
||||||
|
<Text h4>Appearance</Text>
|
||||||
|
<div className="setting-item">
|
||||||
|
<Text>Dark Mode</Text>
|
||||||
|
<Toggle checked={themeSettings === 'dark'} onChange={onThemeChange} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AppearanceSettings;
|
||||||
26
frontend/src/components/settings/EditorSettings.js
Normal file
26
frontend/src/components/settings/EditorSettings.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Text, Toggle, Tooltip } from '@geist-ui/core';
|
||||||
|
|
||||||
|
const EditorSettings = ({ autoSave, onAutoSaveChange }) => {
|
||||||
|
return (
|
||||||
|
<div className="setting-group">
|
||||||
|
<Text h4>Editor</Text>
|
||||||
|
<div className="setting-item">
|
||||||
|
<Text>Auto Save</Text>
|
||||||
|
<Tooltip
|
||||||
|
text="Auto Save feature is coming soon!"
|
||||||
|
type="dark"
|
||||||
|
placement="left"
|
||||||
|
>
|
||||||
|
<Toggle
|
||||||
|
checked={autoSave}
|
||||||
|
onChange={(e) => onAutoSaveChange(e.target.checked)}
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default EditorSettings;
|
||||||
71
frontend/src/components/settings/GitSettings.js
Normal file
71
frontend/src/components/settings/GitSettings.js
Normal file
@@ -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 (
|
||||||
|
<div className="setting-group">
|
||||||
|
<Text h4>Git Integration</Text>
|
||||||
|
<div className="setting-item">
|
||||||
|
<Text>Enable Git</Text>
|
||||||
|
<Toggle
|
||||||
|
checked={gitEnabled}
|
||||||
|
onChange={(e) => onInputChange('gitEnabled', e.target.checked)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className={gitEnabled ? '' : 'disabled'}>
|
||||||
|
<Input
|
||||||
|
width="100%"
|
||||||
|
label="Git URL"
|
||||||
|
value={gitUrl}
|
||||||
|
onChange={(e) => onInputChange('gitUrl', e.target.value)}
|
||||||
|
disabled={!gitEnabled}
|
||||||
|
/>
|
||||||
|
<Spacer h={0.5} />
|
||||||
|
<Input
|
||||||
|
width="100%"
|
||||||
|
label="Git Username"
|
||||||
|
value={gitUser}
|
||||||
|
onChange={(e) => onInputChange('gitUser', e.target.value)}
|
||||||
|
disabled={!gitEnabled}
|
||||||
|
/>
|
||||||
|
<Spacer h={0.5} />
|
||||||
|
<Input.Password
|
||||||
|
width="100%"
|
||||||
|
label="Git Token"
|
||||||
|
value={gitToken}
|
||||||
|
onChange={(e) => onInputChange('gitToken', e.target.value)}
|
||||||
|
disabled={!gitEnabled}
|
||||||
|
/>
|
||||||
|
<Spacer h={0.5} />
|
||||||
|
<div className="setting-item">
|
||||||
|
<Text>Auto Commit</Text>
|
||||||
|
<Toggle
|
||||||
|
checked={gitAutoCommit}
|
||||||
|
onChange={(e) => onInputChange('gitAutoCommit', e.target.checked)}
|
||||||
|
disabled={!gitEnabled}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<Spacer h={0.5} />
|
||||||
|
<Input
|
||||||
|
width="100%"
|
||||||
|
label="Commit Message Template"
|
||||||
|
value={gitCommitMsgTemplate}
|
||||||
|
onChange={(e) =>
|
||||||
|
onInputChange('gitCommitMsgTemplate', e.target.value)
|
||||||
|
}
|
||||||
|
disabled={!gitEnabled}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GitSettings;
|
||||||
Reference in New Issue
Block a user