mirror of
https://github.com/lordmathis/lemma.git
synced 2025-11-05 23:44:22 +00:00
Initial git settings on frontend
This commit is contained in:
@@ -20,7 +20,7 @@ func SetupRoutes(r chi.Router, db *db.DB, fs *filesystem.FileSystem) {
|
||||
r.Delete("/*", DeleteFile(fs))
|
||||
})
|
||||
r.Route("/git", func(r chi.Router) {
|
||||
r.Post("commit", StageCommitAndPush(fs))
|
||||
r.Post("/commit", StageCommitAndPush(fs))
|
||||
r.Post("/pull", PullChanges(fs))
|
||||
})
|
||||
})
|
||||
|
||||
@@ -9,12 +9,12 @@ import (
|
||||
type UserSettings struct {
|
||||
Theme string `json:"theme" validate:"oneof=light dark"`
|
||||
AutoSave bool `json:"autoSave"`
|
||||
GitEnabled bool `json:"git_enabled"`
|
||||
GitURL string `json:"git_url" validate:"required_with=GitEnabled"`
|
||||
GitUser string `json:"git_user" validate:"required_with=GitEnabled"`
|
||||
GitToken string `json:"git_token" validate:"required_with=GitEnabled"`
|
||||
GitAutoCommit bool `json:"git_auto_commit"`
|
||||
GitCommitMsgTemplate string `json:"git_commit_msg_template"`
|
||||
GitEnabled bool `json:"gitEnabled"`
|
||||
GitURL string `json:"gitUrl" validate:"required_with=GitEnabled"`
|
||||
GitUser string `json:"gitUser" validate:"required_with=GitEnabled"`
|
||||
GitToken string `json:"gitToken" validate:"required_with=GitEnabled"`
|
||||
GitAutoCommit bool `json:"gitAutoCommit"`
|
||||
GitCommitMsgTemplate string `json:"gitCommitMsgTemplate"`
|
||||
}
|
||||
|
||||
type Settings struct {
|
||||
|
||||
@@ -1,26 +1,72 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Modal, Text, Toggle, Tooltip, Spacer, useTheme, useToasts } from '@geist-ui/core';
|
||||
import { saveUserSettings } from '../services/api';
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import { Modal, Text, Toggle, Input, Spacer, useTheme, Button, Dot, useToasts } from '@geist-ui/core';
|
||||
import { saveUserSettings, fetchUserSettings } from '../services/api';
|
||||
|
||||
const Settings = ({ visible, onClose, currentTheme, onThemeChange }) => {
|
||||
const theme = useTheme();
|
||||
const [autoSave, setAutoSave] = useState(false);
|
||||
const userId = 1;
|
||||
const { setToast } = useToasts();
|
||||
const [settings, setSettings] = useState({
|
||||
autoSave: false,
|
||||
gitEnabled: false,
|
||||
gitUrl: '',
|
||||
gitUser: '',
|
||||
gitToken: '',
|
||||
gitAutoCommit: false,
|
||||
gitCommitMsgTemplate: '',
|
||||
});
|
||||
const [themeSettings, setThemeSettings] = useState(currentTheme);
|
||||
const [originalSettings, setOriginalSettings] = useState({});
|
||||
const [originalTheme, setOriginalTheme] = useState(currentTheme);
|
||||
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
|
||||
const [isInitialized, setIsInitialized] = useState(false);
|
||||
|
||||
const loadSettings = useCallback(async () => {
|
||||
try {
|
||||
const userSettings = await fetchUserSettings(1); // Assuming user ID 1 for now
|
||||
const { theme, ...otherSettings } = userSettings.settings;
|
||||
setSettings(otherSettings);
|
||||
setThemeSettings(theme);
|
||||
setOriginalSettings(otherSettings);
|
||||
setOriginalTheme(theme);
|
||||
setHasUnsavedChanges(false);
|
||||
setIsInitialized(true);
|
||||
} catch (error) {
|
||||
console.error('Failed to load user settings:', error);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isInitialized) {
|
||||
loadSettings();
|
||||
}
|
||||
}, [isInitialized, loadSettings]);
|
||||
|
||||
useEffect(() => {
|
||||
const settingsChanged = JSON.stringify(settings) !== JSON.stringify(originalSettings);
|
||||
const themeChanged = themeSettings !== originalTheme;
|
||||
setHasUnsavedChanges(settingsChanged || themeChanged);
|
||||
}, [settings, themeSettings, originalSettings, originalTheme]);
|
||||
|
||||
const handleInputChange = (key, value) => {
|
||||
setSettings(prev => ({ ...prev, [key]: value }));
|
||||
};
|
||||
|
||||
const handleThemeChange = () => {
|
||||
const newTheme = themeSettings === 'dark' ? 'light' : 'dark';
|
||||
setThemeSettings(newTheme);
|
||||
onThemeChange(newTheme);
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
const savedSettings = await saveUserSettings({
|
||||
userId: userId,
|
||||
settings: {
|
||||
theme: currentTheme,
|
||||
autoSave: autoSave
|
||||
}
|
||||
await saveUserSettings({
|
||||
userId: 1, // Assuming user ID 1 for now
|
||||
settings: { ...settings, theme: themeSettings },
|
||||
});
|
||||
setOriginalSettings(settings);
|
||||
setOriginalTheme(themeSettings);
|
||||
setHasUnsavedChanges(false);
|
||||
setToast({ text: 'Settings saved successfully', type: 'success' });
|
||||
// Update local state with saved settings
|
||||
setAutoSave(savedSettings.settings.autoSave);
|
||||
onThemeChange(savedSettings.settings.theme);
|
||||
onClose();
|
||||
} catch (error) {
|
||||
console.error('Failed to save settings:', error);
|
||||
@@ -28,22 +74,21 @@ const Settings = ({ visible, onClose, currentTheme, onThemeChange }) => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleThemeChange = () => {
|
||||
onThemeChange(currentTheme === 'light' ? 'dark' : 'light');
|
||||
};
|
||||
|
||||
const disabledMessage = "This feature is not yet implemented";
|
||||
|
||||
return (
|
||||
<Modal visible={visible} onClose={onClose}>
|
||||
<Modal.Title>Settings</Modal.Title>
|
||||
<Modal.Title>
|
||||
Settings
|
||||
{hasUnsavedChanges && (
|
||||
<Dot type="warning" style={{ marginLeft: '8px' }} />
|
||||
)}
|
||||
</Modal.Title>
|
||||
<Modal.Content>
|
||||
<div className="setting-group">
|
||||
<Text h4>Appearance</Text>
|
||||
<div className="setting-item">
|
||||
<Text>Dark Mode</Text>
|
||||
<Toggle
|
||||
checked={currentTheme === 'dark'}
|
||||
checked={themeSettings === 'dark'}
|
||||
onChange={handleThemeChange}
|
||||
/>
|
||||
</div>
|
||||
@@ -51,12 +96,66 @@ const Settings = ({ visible, onClose, currentTheme, onThemeChange }) => {
|
||||
<Spacer h={1} />
|
||||
<div className="setting-group">
|
||||
<Text h4>Editor</Text>
|
||||
<Tooltip text={disabledMessage} type="dark" placement="left">
|
||||
<div className="setting-item disabled">
|
||||
<div className="setting-item">
|
||||
<Text>Auto Save</Text>
|
||||
<Toggle disabled/>
|
||||
<Toggle
|
||||
checked={settings.autoSave}
|
||||
onChange={(e) => handleInputChange('autoSave', e.target.checked)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Spacer h={1} />
|
||||
<div className="setting-group">
|
||||
<Text h4>Git Integration</Text>
|
||||
<div className="setting-item">
|
||||
<Text>Enable Git</Text>
|
||||
<Toggle
|
||||
checked={settings.gitEnabled}
|
||||
onChange={(e) => handleInputChange('gitEnabled', e.target.checked)}
|
||||
/>
|
||||
</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>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</Modal.Content>
|
||||
<Modal.Action passive onClick={onClose}>Cancel</Modal.Action>
|
||||
|
||||
@@ -70,8 +70,7 @@ export const saveUserSettings = async (settings) => {
|
||||
throw new Error(errorData?.message || `HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const savedSettings = await response.json();
|
||||
return savedSettings;
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error('Error saving user settings:', error);
|
||||
throw error;
|
||||
|
||||
Reference in New Issue
Block a user