diff --git a/src/components/account/Account.module.css b/src/components/account/Account.module.css new file mode 100644 index 0000000..c0ab6e6 --- /dev/null +++ b/src/components/account/Account.module.css @@ -0,0 +1,7 @@ +.control { + opacity: 1; + position: fixed !important; + top: 0px; + margin-left: calc(100% - 35px) !important; + z-index: 1; +} diff --git a/src/components/account/Account.tsx b/src/components/account/Account.tsx new file mode 100644 index 0000000..296087b --- /dev/null +++ b/src/components/account/Account.tsx @@ -0,0 +1,163 @@ +import { Component, createSignal, For } from 'solid-js'; + +import PersonIcon from '@suid/icons-material/Person'; + +import style from './Account.module.css'; +import { + Box, + IconButton, + InputLabel, + NativeSelect, + TextField, +} from '@suid/material'; +import { useI18n } from '@solid-primitives/i18n'; +import Dialog from '../dialog'; +import dispatch from '../../workers/dispatcher-main'; +import allGpxes from '../all-gpxes'; +import gpx from '../gpx'; +import { cloneDeep } from 'lodash'; + +const Account: Component<{}> = (props) => { + const [t] = useI18n(); + const [open, setOpen] = createSignal(false); + const [settings, setSettings] = createSignal(); + const [accounts, setAccounts] = createSignal(); + const [account, setAccount] = createSignal({}); + + const handleClickOpen = async () => { + setOpen(true); + const newSettings: any = await dispatch({ + action: 'getSettings', + }); + setSettings(newSettings || {}); + const newAccounts: any = await dispatch({ + action: 'getAccounts', + }); + setAccounts([ + { id: '--new--', name: t('newAccount') }, + ...newAccounts.rows, + ]); + + console.log({ + caller: 'Account / handleClickOpen', + settings: settings(), + accounts: accounts(), + }); + }; + + const handleClose = (event: any, reason?: string) => { + console.log({ + caller: 'Account / handleClose', + event, + reason, + }); + if (reason === undefined) { + setOpen(false); + } + }; + + const changeAccountHandler = (event: any) => { + const selectedAccountName = event.target.value; + const targetAccount = + accounts().filter((acc: any) => acc.name === selectedAccountName)[0] || + {}; + setAccount(cloneDeep(targetAccount)); + console.log({ + caller: 'Account / changeAccountHandler', + event, + selectedAccountName, + account: account(), + }); + }; + + const changeHandlerFactory = (path: string) => (event: any) => { + const value = event.target.value; + const newAccount = cloneDeep(account()); + newAccount[path] = value; + setAccount(newAccount); + console.log({ + caller: 'Account / changeHandlerFactory / ' + path, + event, + value, + account: account(), + }); + }; + + return ( + <> +
+ + + +
+ + + + {t('accountChooser')} + + + + {(account: any) => ( + + )} + + + + + + + + + + + + + + + + ); +}; + +export default Account; diff --git a/src/components/account/index.ts b/src/components/account/index.ts new file mode 100644 index 0000000..ce6b24c --- /dev/null +++ b/src/components/account/index.ts @@ -0,0 +1 @@ +export { default } from './Account'; diff --git a/src/components/dialog/Dialog.tsx b/src/components/dialog/Dialog.tsx index dcc9c59..a8e8b07 100644 --- a/src/components/dialog/Dialog.tsx +++ b/src/components/dialog/Dialog.tsx @@ -27,28 +27,14 @@ const Dialog: Component<{ backgroundColor: 'rgba(14, 116, 144, 0.7)', color: 'white', clear: 'both', - paddingRight: '20px', + margin: '0', + paddingLeft: '0', }} > - - - {props.title} - - - - - - - + + + + {props.title} {props.children} diff --git a/src/components/map/Map.tsx b/src/components/map/Map.tsx index 76e5f29..4aa4d85 100644 --- a/src/components/map/Map.tsx +++ b/src/components/map/Map.tsx @@ -40,6 +40,7 @@ import dispatch from '../../workers/dispatcher-main'; import { debounce } from 'lodash'; import { AndroidFullScreen } from '@awesome-cordova-plugins/android-full-screen'; +import Account from '../account'; const [getState, setState] = createSignal({ lon: 0, @@ -271,6 +272,7 @@ const Map: Component = () => { + diff --git a/src/db/account.ts b/src/db/account.ts new file mode 100644 index 0000000..b1bb32d --- /dev/null +++ b/src/db/account.ts @@ -0,0 +1,11 @@ +import { getFamily, put } from './lib'; +import getUri from '../lib/ids'; + +export const getAccounts = async () => { + return await getFamily('account', {}, true); +}; + +export const putAccount = async (name: string, account: any) => { + const uri = getUri('account', name); + return await put(uri, 'account', (_: any) => account, {}, true); +}; diff --git a/src/db/lib.ts b/src/db/lib.ts index abafe73..d9f1bbd 100644 --- a/src/db/lib.ts +++ b/src/db/lib.ts @@ -36,8 +36,9 @@ export const put = async ( } }; -export const getFamily = async (key: string, options: any = {}) => { - return await db.allDocs({ +export const getFamily = async (key: string, options: any = {}, local: boolean = false) => { + const targetDb = local ? localDb : db; + return await targetDb.allDocs({ startkey: key, endkey: key + '\ufff0', ...options, diff --git a/src/db/settings.ts b/src/db/settings.ts new file mode 100644 index 0000000..8ff1b6f --- /dev/null +++ b/src/db/settings.ts @@ -0,0 +1,14 @@ +import { get, put } from './lib'; + +export const getSettings = async () => { + try { + return await get('settings', true); + } catch (err) { + console.error({ caller: 'getSettings', err }); + return undefined; + } +}; + +export const putSettings = async (settings: any) => { + return await put('settings', 'settings', (_: any) => settings, {}, true); +}; diff --git a/src/i18n/en.ts b/src/i18n/en.ts index 7f4cd53..8f067c8 100644 --- a/src/i18n/en.ts +++ b/src/i18n/en.ts @@ -52,6 +52,15 @@ const dict = { gpxPauseRecording: 'Suspend recording', ResumeRecording: 'Resume recording', StopRecording: 'Stop recording', + + account: 'User account', + newAccount: '-- new account --', + accountChooser: 'Choose an account', + accountName: 'Account name', + localDb: 'Local database name', + remoteDbServer: 'Remote database server URL', + remoteDbUser: 'Remote database user', + remoteDbPassword: 'Remote database password', }; export default dict; diff --git a/src/i18n/fr.ts b/src/i18n/fr.ts index 8b21c1b..0764d3e 100644 --- a/src/i18n/fr.ts +++ b/src/i18n/fr.ts @@ -57,6 +57,15 @@ const dict = { gpxPauseRecording: "Mettre l'enregistrement en pause", gpxResumeRecording: "Reprendre l'enregistrement", gpxStopRecording: "Arrêter l'enregistrement", + + account: 'Compte utilisateur', + newAccount: '-- nouveau compte --', + accountChooser: 'Choisissez un compte', + accountName: 'Nom du compte', + localDb: 'Nom de la base de données locale', + remoteDbServer: 'Adresse du serveur de base de données distant', + remoteDbUser: 'Utilisateur de la base de données distante', + remoteDbPassword: 'Mot de passe de la base de données distante', }; export default dict; diff --git a/src/lib/ids.ts b/src/lib/ids.ts index 2723703..c32ce27 100644 --- a/src/lib/ids.ts +++ b/src/lib/ids.ts @@ -26,6 +26,8 @@ const coding = { const routes = { dbdef: route('dbdef', coding), + state: route('state', coding), + account: route('account/:account', coding), settings: route('settings', coding), gpx: route('gpx/:gpx', coding), wpt: route('gpx/:gpx/1wpt/:wpt', coding), diff --git a/src/workers/dispatcher-worker.ts b/src/workers/dispatcher-worker.ts index db2aa91..5baac38 100644 --- a/src/workers/dispatcher-worker.ts +++ b/src/workers/dispatcher-worker.ts @@ -1,5 +1,6 @@ /// import { initDb } from '../db'; +import { getAccounts, putAccount } from '../db/account'; import { cancelWatch, getAndWatch } from '../db/change-handler'; import { putNewGpx, @@ -11,6 +12,7 @@ import { getAllGpxes, getAllGpxesWithSummary, } from '../db/gpx'; +import { getSettings, putSettings } from '../db/settings'; import { getState, setState } from '../db/state'; import { getTrk, putNewTrk } from '../db/trk'; import { getTrkseg, appendTrkpt } from '../db/trkseg'; @@ -43,6 +45,12 @@ onmessage = async function (e) { getAndWatch, cancelWatch, + + getSettings, + putSettings, + + getAccounts, + putAccount, }; console.log({ caller: 'dispatcher-worker / onmessage', e });