diff --git a/src/App.tsx b/src/App.tsx index baeb464..f1a70d9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -90,6 +90,8 @@ export const routeResolver = new RouteResolver({ }, new: 'new', }, + settings: { + }, }); const AppBarWitHistory = withRouter( diff --git a/src/Settings/index.tsx b/src/Settings/index.tsx new file mode 100644 index 0000000..363bdcf --- /dev/null +++ b/src/Settings/index.tsx @@ -0,0 +1,77 @@ +import * as React from 'react'; +import { connect } from 'react-redux'; +import { History } from 'history'; + +import Select from '@material-ui/core/Select'; +import MenuItem from '@material-ui/core/MenuItem'; +import FormControl from '@material-ui/core/FormControl'; +import InputLabel from '@material-ui/core/InputLabel'; + +import { store, StoreState, SettingsType } from '../store'; +import { setSettings } from '../store/actions'; + +import Container from '../widgets/Container'; +import AppBarOverride from '../widgets/AppBarOverride'; + +interface PropsType { + history: History; +}; + +interface PropsTypeInner extends PropsType { + settings: SettingsType; +}; + +class Settings extends React.PureComponent { + constructor(props: any) { + super(props); + this.onCancel = this.onCancel.bind(this); + this.handleChange = this.handleChange.bind(this); + } + + private handleChange(event: React.ChangeEvent) { + const name = event.target.name; + const value = event.target.value; + + const { settings } = this.props; + store.dispatch(setSettings({ ...settings, [name]: value})); + } + + render() { + const { settings } = this.props; + return ( + <> + + +

Localization

+ + + Time & Date Style + + + +
+ + ); + } + + onCancel() { + this.props.history.goBack(); + } +} + +const mapStateToProps = (state: StoreState, props: PropsType) => { + return { + settings: state.settings, + }; +}; + +export default connect( + mapStateToProps +)(Settings); diff --git a/src/SideMenu/index.tsx b/src/SideMenu/index.tsx index 7acfaa5..24c0280 100644 --- a/src/SideMenu/index.tsx +++ b/src/SideMenu/index.tsx @@ -5,6 +5,7 @@ import { List, ListItem, ListSubheader, ListDivider } from '../widgets/List'; import { Theme, withTheme } from '@material-ui/core/styles'; import ActionCode from '@material-ui/icons/Code'; import ActionHome from '@material-ui/icons/Home'; +import ActionSettings from '@material-ui/icons/Settings'; import ActionJournals from '@material-ui/icons/LibraryBooks'; import ActionBugReport from '@material-ui/icons/BugReport'; import ActionQuestionAnswer from '@material-ui/icons/QuestionAnswer'; @@ -59,6 +60,14 @@ class SideMenu extends React.PureComponent { this.props.history.push(routeResolver.getRoute('journals')); }} /> + } + onClick={() => { + this.props.onCloseDrawerRequest(); + this.props.history.push(routeResolver.getRoute('settings')); + }} + /> } onClick={this.logout} /> ); diff --git a/src/SyncGate.tsx b/src/SyncGate.tsx index 32db328..bea2b6c 100644 --- a/src/SyncGate.tsx +++ b/src/SyncGate.tsx @@ -13,6 +13,7 @@ import LoadingIndicator from './widgets/LoadingIndicator'; import PrettyError from './widgets/PrettyError'; import Journals from './Journals'; +import Settings from './Settings'; import Pim from './Pim'; import * as EteSync from './api/EteSync'; @@ -218,6 +219,15 @@ class SyncGate extends React.PureComponent { /> )} /> + ( + + )} + /> ); } diff --git a/src/store/actions.ts b/src/store/actions.ts index aa7e112..10b1a2b 100644 --- a/src/store/actions.ts +++ b/src/store/actions.ts @@ -3,7 +3,7 @@ import { createAction, createActions } from 'redux-actions'; import * as EteSync from '../api/EteSync'; import { UserInfo } from '../api/EteSync'; -import { CredentialsData, EntriesType, JournalsData } from './'; +import { CredentialsData, EntriesType, JournalsData, SettingsType } from './'; export const { fetchCredentials, logout } = createActions({ FETCH_CREDENTIALS: (username: string, password: string, server: string) => { @@ -170,3 +170,11 @@ export function fetchAll(etesync: CredentialsData, currentEntries: EntriesType) }); }; } + +// FIXME: Move the rest to their own file +export const setSettings = createAction( + 'SET_SETTINGS', + (settings: SettingsType) => { + return {...settings}; + }, +); diff --git a/src/store/index.ts b/src/store/index.ts index 51442c2..97f83f7 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -6,7 +6,7 @@ import { createLogger } from 'redux-logger'; import promiseMiddleware from './promise-middleware'; import reducers from './reducers'; -import { CredentialsTypeRemote, JournalsType, EntriesType, UserInfoType } from './reducers'; +import { CredentialsTypeRemote, JournalsType, EntriesType, UserInfoType, SettingsType } from './reducers'; // Workaround babel limitation export * from './reducers'; @@ -14,6 +14,7 @@ export * from './reducers'; export interface StoreState { fetchCount: number; credentials: CredentialsTypeRemote; + settings: SettingsType; encryptionKey: {key: string}; cache: { journals: JournalsType; diff --git a/src/store/reducers.ts b/src/store/reducers.ts index 6865ec7..c5f0b75 100644 --- a/src/store/reducers.ts +++ b/src/store/reducers.ts @@ -272,6 +272,25 @@ const fetchCount = handleAction( 0, ); +// FIXME Move all the below (potentially the fetchCount ones too) to their own file +export interface SettingsType { + locale: string; +}; + +const settingsReducer = handleActions( + { + [actions.setSettings.toString()]: (state: {key: string | null}, action: any) => ( + {...action.payload} + ), + }, + { locale: 'en-gb' } +); + +const settingsPersistConfig = { + key: 'settings', + storage: localforage, +}; + const credentialsPersistConfig = { key: 'credentials', storage: localforage, @@ -395,6 +414,7 @@ const cachePersistConfig = { const reducers = combineReducers({ fetchCount, + settings: persistReducer(settingsPersistConfig, settingsReducer), credentials: persistReducer(credentialsPersistConfig, credentials), encryptionKey: persistReducer(encryptionKeyPersistConfig, encryptionKeyReducer), cache: persistReducer(cachePersistConfig, combineReducers({