diff --git a/frontend/src/App.js b/frontend/src/App.js index df43c2d..7b5634d 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -1,7 +1,7 @@ -import React, { useState } from 'react'; +import React from 'react'; import { MantineProvider, - createTheme, + ColorSchemeScript, AppShell, Container, } from '@mantine/core'; @@ -15,44 +15,42 @@ import '@mantine/core/styles.css'; import '@mantine/notifications/styles.css'; import './App.scss'; -const mantineTheme = createTheme({ - /** You can add your Mantine theme overrides here */ -}); - function AppContent() { - const { settings, loading } = useSettings(); - const [opened, setOpened] = useState(false); + const { loading } = useSettings(); if (loading) { return
Loading...
; } return ( - - - - - -
- - - - - - - - - + + +
+ + + + + + + ); } function App() { return ( - - - - - + <> + + + + + + + + + + + + ); } diff --git a/frontend/src/components/MainContent.js b/frontend/src/components/MainContent.js index f47e73f..a461e3e 100644 --- a/frontend/src/components/MainContent.js +++ b/frontend/src/components/MainContent.js @@ -121,12 +121,14 @@ const MainContent = () => { {renderBreadcrumbs()} - }> - Source - - }> - Preview - + } + /> + } + /> diff --git a/frontend/src/components/Settings.js b/frontend/src/components/Settings.js index 866c5cf..b0e10ce 100644 --- a/frontend/src/components/Settings.js +++ b/frontend/src/components/Settings.js @@ -1,6 +1,5 @@ import React, { useReducer, useEffect, useCallback, useRef } from 'react'; -import { Modal, Badge, Button, Group } from '@mantine/core'; -import { useDisclosure } from '@mantine/hooks'; +import { Modal, Badge, Button, Group, Title } from '@mantine/core'; import { notifications } from '@mantine/notifications'; import { useSettings } from '../contexts/SettingsContext'; import AppearanceSettings from './settings/AppearanceSettings'; @@ -51,11 +50,10 @@ function settingsReducer(state, action) { } const Settings = () => { - const { settings, updateSettings, updateTheme } = useSettings(); + const { settings, updateSettings, colorScheme } = useSettings(); const { settingsModalVisible, setSettingsModalVisible } = useModalContext(); const [state, dispatch] = useReducer(settingsReducer, initialState); const isInitialMount = useRef(true); - const updateThemeTimeoutRef = useRef(null); useEffect(() => { if (isInitialMount.current) { @@ -64,22 +62,17 @@ const Settings = () => { } }, [settings]); + useEffect(() => { + dispatch({ + type: 'UPDATE_LOCAL_SETTINGS', + payload: { theme: colorScheme }, + }); + }, [colorScheme]); + const handleInputChange = useCallback((key, value) => { dispatch({ type: 'UPDATE_LOCAL_SETTINGS', payload: { [key]: value } }); }, []); - const handleThemeChange = useCallback(() => { - const newTheme = state.localSettings.theme === 'dark' ? 'light' : 'dark'; - dispatch({ type: 'UPDATE_LOCAL_SETTINGS', payload: { theme: newTheme } }); - - if (updateThemeTimeoutRef.current) { - clearTimeout(updateThemeTimeoutRef.current); - } - updateThemeTimeoutRef.current = setTimeout(() => { - updateTheme(newTheme); - }, 0); - }, [state.localSettings.theme, updateTheme]); - const handleSubmit = async () => { try { await updateSettings(state.localSettings); @@ -100,30 +93,16 @@ const Settings = () => { const handleClose = useCallback(() => { if (state.hasUnsavedChanges) { - updateTheme(state.initialSettings.theme); dispatch({ type: 'RESET' }); } setSettingsModalVisible(false); - }, [ - state.hasUnsavedChanges, - state.initialSettings.theme, - updateTheme, - setSettingsModalVisible, - ]); - - useEffect(() => { - return () => { - if (updateThemeTimeoutRef.current) { - clearTimeout(updateThemeTimeoutRef.current); - } - }; - }, []); + }, [state.hasUnsavedChanges, setSettingsModalVisible]); return ( Settings} centered size="lg" > @@ -134,7 +113,7 @@ const Settings = () => { )} handleInputChange('theme', newTheme)} /> { + const { colorScheme, toggleColorScheme } = useSettings(); + + const handleThemeChange = () => { + toggleColorScheme(); + onThemeChange(colorScheme === 'dark' ? 'light' : 'dark'); + }; -const AppearanceSettings = ({ themeSettings, onThemeChange }) => { return ( - - + + Appearance - </Text> - <Switch - label="Dark Mode" - checked={themeSettings === 'dark'} - onChange={onThemeChange} - /> - </Stack> + + + Dark Mode + + + ); }; diff --git a/frontend/src/components/settings/EditorSettings.js b/frontend/src/components/settings/EditorSettings.js index 4f6a4ed..08b1db0 100644 --- a/frontend/src/components/settings/EditorSettings.js +++ b/frontend/src/components/settings/EditorSettings.js @@ -1,21 +1,23 @@ import React from 'react'; -import { Text, Switch, Stack, Tooltip } from '@mantine/core'; +import { Text, Switch, Tooltip, Group, Box, Title } from '@mantine/core'; const EditorSettings = ({ autoSave, onAutoSaveChange }) => { return ( - - + + Editor - </Text> + - onAutoSaveChange(event.currentTarget.checked)} - disabled - /> + + Auto Save + onAutoSaveChange(event.currentTarget.checked)} + disabled + /> + - + ); }; diff --git a/frontend/src/components/settings/GitSettings.js b/frontend/src/components/settings/GitSettings.js index d2bb504..53f01d2 100644 --- a/frontend/src/components/settings/GitSettings.js +++ b/frontend/src/components/settings/GitSettings.js @@ -1,5 +1,14 @@ import React from 'react'; -import { Text, Switch, TextInput, Stack, PasswordInput } from '@mantine/core'; +import { + Text, + Switch, + TextInput, + Stack, + PasswordInput, + Group, + Box, + Title, +} from '@mantine/core'; const GitSettings = ({ gitEnabled, @@ -11,55 +20,79 @@ const GitSettings = ({ onInputChange, }) => { return ( - - - Git Integration - - - onInputChange('gitEnabled', event.currentTarget.checked) - } - /> - onInputChange('gitUrl', event.currentTarget.value)} - disabled={!gitEnabled} - /> - - onInputChange('gitUser', event.currentTarget.value) - } - disabled={!gitEnabled} - /> - - onInputChange('gitToken', event.currentTarget.value) - } - disabled={!gitEnabled} - /> - - onInputChange('gitAutoCommit', event.currentTarget.checked) - } - disabled={!gitEnabled} - /> - - onInputChange('gitCommitMsgTemplate', event.currentTarget.value) - } - disabled={!gitEnabled} - /> + + Git Integration + + Enable Git + + onInputChange('gitEnabled', event.currentTarget.checked) + } + /> + + + + Git URL + + + onInputChange('gitUrl', event.currentTarget.value) + } + disabled={!gitEnabled} + placeholder="Enter Git URL" + /> + + + + Git Username + + + onInputChange('gitUser', event.currentTarget.value) + } + disabled={!gitEnabled} + placeholder="Enter Git username" + /> + + + + Git Token + + + onInputChange('gitToken', event.currentTarget.value) + } + disabled={!gitEnabled} + placeholder="Enter Git token" + /> + + + Auto Commit + + onInputChange('gitAutoCommit', event.currentTarget.checked) + } + disabled={!gitEnabled} + /> + + + + Commit Message Template + + + onInputChange('gitCommitMsgTemplate', event.currentTarget.value) + } + disabled={!gitEnabled} + placeholder="Enter commit message template" + /> + ); }; diff --git a/frontend/src/contexts/SettingsContext.js b/frontend/src/contexts/SettingsContext.js index 3267649..5dd3455 100644 --- a/frontend/src/contexts/SettingsContext.js +++ b/frontend/src/contexts/SettingsContext.js @@ -1,10 +1,5 @@ -import React, { - createContext, - useState, - useContext, - useEffect, - useMemo, -} from 'react'; +import React, { createContext, useContext, useEffect, useMemo } from 'react'; +import { useMantineColorScheme } from '@mantine/core'; import { fetchUserSettings, saveUserSettings } from '../services/api'; import { DEFAULT_SETTINGS } from '../utils/constants'; @@ -13,14 +8,16 @@ const SettingsContext = createContext(); export const useSettings = () => useContext(SettingsContext); export const SettingsProvider = ({ children }) => { - const [settings, setSettings] = useState(DEFAULT_SETTINGS); - const [loading, setLoading] = useState(true); + const { colorScheme, setColorScheme } = useMantineColorScheme(); + const [settings, setSettings] = React.useState(DEFAULT_SETTINGS); + const [loading, setLoading] = React.useState(true); useEffect(() => { const loadSettings = async () => { try { const userSettings = await fetchUserSettings(1); setSettings(userSettings.settings); + setColorScheme(userSettings.settings.theme); } catch (error) { console.error('Failed to load user settings:', error); } finally { @@ -29,7 +26,7 @@ export const SettingsProvider = ({ children }) => { }; loadSettings(); - }, []); + }, [setColorScheme]); const updateSettings = async (newSettings) => { try { @@ -38,27 +35,31 @@ export const SettingsProvider = ({ children }) => { settings: newSettings, }); setSettings(newSettings); + // Ensure the color scheme is updated when settings are saved + if (newSettings.theme) { + setColorScheme(newSettings.theme); + } } catch (error) { console.error('Failed to save settings:', error); throw error; } }; - const updateTheme = (newTheme) => { - setSettings((prevSettings) => ({ - ...prevSettings, - theme: newTheme, - })); + const toggleColorScheme = () => { + const newTheme = colorScheme === 'dark' ? 'light' : 'dark'; + setColorScheme(newTheme); + updateSettings({ ...settings, theme: newTheme }); }; const contextValue = useMemo( () => ({ settings, updateSettings, - updateTheme, + toggleColorScheme, loading, + colorScheme, }), - [settings, loading] + [settings, loading, colorScheme] ); return (