Rename root folders

This commit is contained in:
2024-11-12 21:25:02 +01:00
parent f4c21edca0
commit fb1c9a499f
101 changed files with 11 additions and 11 deletions

View File

@@ -0,0 +1,24 @@
import React from 'react';
import { Text, Switch, Group, Box, Title } from '@mantine/core';
import { useWorkspace } from '../../../contexts/WorkspaceContext';
const AppearanceSettings = ({ themeSettings, onThemeChange }) => {
const { colorScheme, updateColorScheme } = useWorkspace();
const handleThemeChange = () => {
const newTheme = colorScheme === 'dark' ? 'light' : 'dark';
updateColorScheme(newTheme);
onThemeChange(newTheme);
};
return (
<Box mb="md">
<Group justify="space-between" align="center">
<Text size="sm">Dark Mode</Text>
<Switch checked={colorScheme === 'dark'} onChange={handleThemeChange} />
</Group>
</Box>
);
};
export default AppearanceSettings;

View File

@@ -0,0 +1,46 @@
import React, { useState } from 'react';
import { Box, Button, Title } from '@mantine/core';
import DeleteWorkspaceModal from '../../modals/workspace/DeleteWorkspaceModal';
import { useWorkspace } from '../../../contexts/WorkspaceContext';
import { useModalContext } from '../../../contexts/ModalContext';
const DangerZoneSettings = () => {
const { currentWorkspace, workspaces, deleteCurrentWorkspace } =
useWorkspace();
const { setSettingsModalVisible } = useModalContext();
const [deleteModalOpened, setDeleteModalOpened] = useState(false);
const handleDelete = async () => {
await deleteCurrentWorkspace();
setDeleteModalOpened(false);
setSettingsModalVisible(false);
};
return (
<Box mb="md">
<Button
color="red"
variant="light"
onClick={() => setDeleteModalOpened(true)}
fullWidth
disabled={workspaces.length <= 1}
title={
workspaces.length <= 1
? 'Cannot delete the last workspace'
: 'Delete this workspace'
}
>
Delete Workspace
</Button>
<DeleteWorkspaceModal
opened={deleteModalOpened}
onClose={() => setDeleteModalOpened(false)}
onConfirm={handleDelete}
workspaceName={currentWorkspace?.name}
/>
</Box>
);
};
export default DangerZoneSettings;

View File

@@ -0,0 +1,36 @@
import React from 'react';
import { Text, Switch, Tooltip, Group, Box } from '@mantine/core';
const EditorSettings = ({
autoSave,
showHiddenFiles,
onAutoSaveChange,
onShowHiddenFilesChange,
}) => {
return (
<Box mb="md">
<Tooltip label="Auto Save feature is coming soon!" position="left">
<Group justify="space-between" align="center" mb="sm">
<Text size="sm">Auto Save</Text>
<Switch
checked={autoSave}
onChange={(event) => onAutoSaveChange(event.currentTarget.checked)}
disabled
/>
</Group>
</Tooltip>
<Group justify="space-between" align="center">
<Text size="sm">Show Hidden Files</Text>
<Switch
checked={showHiddenFiles}
onChange={(event) =>
onShowHiddenFilesChange(event.currentTarget.checked)
}
/>
</Group>
</Box>
);
};
export default EditorSettings;

View File

@@ -0,0 +1,26 @@
import React from 'react';
import { Title, Box, TextInput, Text, Grid } from '@mantine/core';
const GeneralSettings = ({ name, onInputChange }) => {
return (
<Box mb="md">
<Grid gutter="md" align="center">
<Grid.Col span={6}>
<Text size="sm">Workspace Name</Text>
</Grid.Col>
<Grid.Col span={6}>
<TextInput
value={name || ''}
onChange={(event) =>
onInputChange('name', event.currentTarget.value)
}
placeholder="Enter workspace name"
required
/>
</Grid.Col>
</Grid>
</Box>
);
};
export default GeneralSettings;

View File

@@ -0,0 +1,113 @@
import React from 'react';
import {
Text,
Switch,
TextInput,
Stack,
PasswordInput,
Group,
Grid,
} from '@mantine/core';
const GitSettings = ({
gitEnabled,
gitUrl,
gitUser,
gitToken,
gitAutoCommit,
gitCommitMsgTemplate,
onInputChange,
}) => {
return (
<Stack spacing="md">
<Grid gutter="md" align="center">
<Grid.Col span={6}>
<Text size="sm">Enable Git</Text>
</Grid.Col>
<Grid.Col span={6}>
<Group justify="flex-end">
<Switch
checked={gitEnabled}
onChange={(event) =>
onInputChange('gitEnabled', event.currentTarget.checked)
}
/>
</Group>
</Grid.Col>
<Grid.Col span={6}>
<Text size="sm">Git URL</Text>
</Grid.Col>
<Grid.Col span={6}>
<TextInput
value={gitUrl}
onChange={(event) =>
onInputChange('gitUrl', event.currentTarget.value)
}
disabled={!gitEnabled}
placeholder="Enter Git URL"
/>
</Grid.Col>
<Grid.Col span={6}>
<Text size="sm">Git Username</Text>
</Grid.Col>
<Grid.Col span={6}>
<TextInput
value={gitUser}
onChange={(event) =>
onInputChange('gitUser', event.currentTarget.value)
}
disabled={!gitEnabled}
placeholder="Enter Git username"
/>
</Grid.Col>
<Grid.Col span={6}>
<Text size="sm">Git Token</Text>
</Grid.Col>
<Grid.Col span={6}>
<PasswordInput
value={gitToken}
onChange={(event) =>
onInputChange('gitToken', event.currentTarget.value)
}
disabled={!gitEnabled}
placeholder="Enter Git token"
/>
</Grid.Col>
<Grid.Col span={6}>
<Text size="sm">Auto Commit</Text>
</Grid.Col>
<Grid.Col span={6}>
<Group justify="flex-end">
<Switch
checked={gitAutoCommit}
onChange={(event) =>
onInputChange('gitAutoCommit', event.currentTarget.checked)
}
disabled={!gitEnabled}
/>
</Group>
</Grid.Col>
<Grid.Col span={6}>
<Text size="sm">Commit Message Template</Text>
</Grid.Col>
<Grid.Col span={6}>
<TextInput
value={gitCommitMsgTemplate}
onChange={(event) =>
onInputChange('gitCommitMsgTemplate', event.currentTarget.value)
}
disabled={!gitEnabled}
placeholder="Enter commit message template"
/>
</Grid.Col>
</Grid>
</Stack>
);
};
export default GitSettings;

View File

@@ -0,0 +1,231 @@
import React, { useReducer, useEffect, useCallback, useRef } from 'react';
import {
Modal,
Badge,
Button,
Group,
Title,
Stack,
Accordion,
} from '@mantine/core';
import { notifications } from '@mantine/notifications';
import { useWorkspace } from '../../../contexts/WorkspaceContext';
import AppearanceSettings from './AppearanceSettings';
import EditorSettings from './EditorSettings';
import GitSettings from './GitSettings';
import GeneralSettings from './GeneralSettings';
import { useModalContext } from '../../../contexts/ModalContext';
import DangerZoneSettings from './DangerZoneSettings';
import AccordionControl from '../AccordionControl';
const initialState = {
localSettings: {},
initialSettings: {},
hasUnsavedChanges: false,
};
function settingsReducer(state, action) {
switch (action.type) {
case 'INIT_SETTINGS':
return {
...state,
localSettings: action.payload,
initialSettings: action.payload,
hasUnsavedChanges: false,
};
case 'UPDATE_LOCAL_SETTINGS':
const newLocalSettings = { ...state.localSettings, ...action.payload };
const hasChanges =
JSON.stringify(newLocalSettings) !==
JSON.stringify(state.initialSettings);
return {
...state,
localSettings: newLocalSettings,
hasUnsavedChanges: hasChanges,
};
case 'MARK_SAVED':
return {
...state,
initialSettings: state.localSettings,
hasUnsavedChanges: false,
};
default:
return state;
}
}
const WorkspaceSettings = () => {
const { currentWorkspace, updateSettings } = useWorkspace();
const { settingsModalVisible, setSettingsModalVisible } = useModalContext();
const [state, dispatch] = useReducer(settingsReducer, initialState);
const isInitialMount = useRef(true);
useEffect(() => {
if (isInitialMount.current) {
isInitialMount.current = false;
const settings = {
name: currentWorkspace.name,
theme: currentWorkspace.theme,
autoSave: currentWorkspace.autoSave,
showHiddenFiles: currentWorkspace.showHiddenFiles,
gitEnabled: currentWorkspace.gitEnabled,
gitUrl: currentWorkspace.gitUrl,
gitUser: currentWorkspace.gitUser,
gitToken: currentWorkspace.gitToken,
gitAutoCommit: currentWorkspace.gitAutoCommit,
gitCommitMsgTemplate: currentWorkspace.gitCommitMsgTemplate,
};
dispatch({ type: 'INIT_SETTINGS', payload: settings });
}
}, [currentWorkspace]);
const handleInputChange = useCallback((key, value) => {
dispatch({ type: 'UPDATE_LOCAL_SETTINGS', payload: { [key]: value } });
}, []);
const handleSubmit = async () => {
try {
if (!state.localSettings.name?.trim()) {
notifications.show({
message: 'Workspace name cannot be empty',
color: 'red',
});
return;
}
await updateSettings(state.localSettings);
dispatch({ type: 'MARK_SAVED' });
notifications.show({
message: 'Settings saved successfully',
color: 'green',
});
setSettingsModalVisible(false);
} catch (error) {
console.error('Failed to save settings:', error);
notifications.show({
message: 'Failed to save settings: ' + error.message,
color: 'red',
});
}
};
const handleClose = useCallback(() => {
setSettingsModalVisible(false);
}, [setSettingsModalVisible]);
return (
<Modal
opened={settingsModalVisible}
onClose={handleClose}
title={<Title order={2}>Workspace Settings</Title>}
centered
size="lg"
>
<Stack spacing="xl">
{state.hasUnsavedChanges && (
<Badge color="yellow" variant="light">
Unsaved Changes
</Badge>
)}
<Accordion
defaultValue={['general', 'appearance', 'editor', 'git', 'danger']}
multiple
styles={(theme) => ({
control: {
paddingTop: theme.spacing.md,
paddingBottom: theme.spacing.md,
},
item: {
borderBottom: `1px solid ${
theme.colorScheme === 'dark'
? theme.colors.dark[4]
: theme.colors.gray[3]
}`,
'&[data-active]': {
backgroundColor:
theme.colorScheme === 'dark'
? theme.colors.dark[7]
: theme.colors.gray[0],
},
},
chevron: {
'&[data-rotate]': {
transform: 'rotate(180deg)',
},
},
})}
>
<Accordion.Item value="general">
<AccordionControl>General</AccordionControl>
<Accordion.Panel>
<GeneralSettings
name={state.localSettings.name}
onInputChange={handleInputChange}
/>
</Accordion.Panel>
</Accordion.Item>
<Accordion.Item value="appearance">
<AccordionControl>Appearance</AccordionControl>
<Accordion.Panel>
<AppearanceSettings
themeSettings={state.localSettings.theme}
onThemeChange={(newTheme) =>
handleInputChange('theme', newTheme)
}
/>
</Accordion.Panel>
</Accordion.Item>
<Accordion.Item value="editor">
<AccordionControl>Editor</AccordionControl>
<Accordion.Panel>
<EditorSettings
autoSave={state.localSettings.autoSave}
onAutoSaveChange={(value) =>
handleInputChange('autoSave', value)
}
showHiddenFiles={state.localSettings.showHiddenFiles}
onShowHiddenFilesChange={(value) =>
handleInputChange('showHiddenFiles', value)
}
/>
</Accordion.Panel>
</Accordion.Item>
<Accordion.Item value="git">
<AccordionControl>Git Integration</AccordionControl>
<Accordion.Panel>
<GitSettings
gitEnabled={state.localSettings.gitEnabled}
gitUrl={state.localSettings.gitUrl}
gitUser={state.localSettings.gitUser}
gitToken={state.localSettings.gitToken}
gitAutoCommit={state.localSettings.gitAutoCommit}
gitCommitMsgTemplate={state.localSettings.gitCommitMsgTemplate}
onInputChange={handleInputChange}
/>
</Accordion.Panel>
</Accordion.Item>
<Accordion.Item value="danger">
<AccordionControl>Danger Zone</AccordionControl>
<Accordion.Panel>
<DangerZoneSettings />
</Accordion.Panel>
</Accordion.Item>
</Accordion>
<Group justify="flex-end">
<Button variant="default" onClick={handleClose}>
Cancel
</Button>
<Button onClick={handleSubmit}>Save Changes</Button>
</Group>
</Stack>
</Modal>
);
};
export default WorkspaceSettings;