diff --git a/src/components/invitation/Invitation.tsx b/src/components/invitation/Invitation.tsx index 212d752..7a782aa 100644 --- a/src/components/invitation/Invitation.tsx +++ b/src/components/invitation/Invitation.tsx @@ -1,6 +1,6 @@ import { createForm } from '@felte/solid'; -import { Component, createEffect, Match, Show, Switch } from 'solid-js'; -import { TextField, Button } from '@kobalte/core'; +import { Component, createSignal, Match, Switch } from 'solid-js'; +import { TextField, Button, Dialog } from '@kobalte/core'; import './style.css'; import { createServerAction$ } from 'solid-start/server'; @@ -18,6 +18,10 @@ interface Props { const Invitation: Component = (props) => { const navigate = useNavigate(); + const [openDialog, setOpenDialog] = createSignal(false); + + const [status, setStatus] = createSignal(); + const [saving, save] = createServerAction$(async (args: any) => { const { props, values } = args; console.log({ @@ -46,12 +50,19 @@ const Invitation: Component = (props) => { caller: 'Invitation / dbCheck', args, }); - let baseDbInfo; + let baseDbInfoAuth; try { const baseDb = new PouchDb(cloneDeep(args)); - baseDbInfo = await baseDb.info(); + baseDbInfoAuth = await baseDb.info(); } catch (error) { - baseDbInfo = error; + baseDbInfoAuth = { error }; + } + let baseDbInfoAnon; + try { + const baseDb = new PouchDb(args.name); + baseDbInfoAnon = await baseDb.info(); + } catch (error) { + baseDbInfoAnon = { error }; } const name = `${args.name}/userdb-${toHex(args.auth.username)}`; let userDbInfo; @@ -59,9 +70,16 @@ const Invitation: Component = (props) => { const userDb = new PouchDb({ ...args, name }); userDbInfo = await userDb.info(); } catch (error) { - userDbInfo = error; + userDbInfo = { error }; } - return { baseDbInfo, userDbInfo, args, name }; + let userDbInfoAnon; + try { + const userDb = new PouchDb(name); + userDbInfoAnon = await userDb.info(); + } catch (error) { + userDbInfoAnon = { error }; + } + return { baseDbInfoAuth, baseDbInfoAnon, userDbInfo, userDbInfoAnon }; }); const submitHandler = async (values: any, context: any) => { @@ -106,6 +124,19 @@ const Invitation: Component = (props) => { data: data(), result, }); + if (result.baseDbInfoAnon.error) { + setStatus('baseError'); + } else if (!result.userDbInfo.error) { + setStatus('OK'); + } else if ( + result.userDbInfoAnon.error.reason === + 'You are not authorized to access this db.' + ) { + setStatus('passwordError'); + } else { + setStatus('notFound'); + } + setOpenDialog(true); }; console.log({ @@ -114,65 +145,100 @@ const Invitation: Component = (props) => { }); return ( -
- - Mail address - - - Please provide a valid URL - - - - Database - - - Please provide a valid URL - - - - User name - - - - Password - - - Please provide a valid password - - - - - Save - Delete - - - Create - - - DB check - Cancel -
+ <> +
+ + Mail address + + + Please provide a valid URL + + + + Database + + + Please provide a valid URL + + + + User name + + + + Password + + + Please provide a valid password + + + + + Save + Delete + + + Create + + + DB check + Cancel +
+ + + +
+ +
+ + Database check + + + X + +
+ + + + The database address seems to be wrong !! + {' '} + + The user is already existing. + + + The user must be created. + + + The user seems to exist but the password is wrong. + + + +
+
+
+
+ ); }; diff --git a/src/components/invitation/style.css b/src/components/invitation/style.css index 921a8cc..bdd1dc4 100644 --- a/src/components/invitation/style.css +++ b/src/components/invitation/style.css @@ -18,3 +18,120 @@ label { form { text-align: left; } + + +/* Dialog */ + +.dialog__trigger { + appearance: none; + display: inline-flex; + justify-content: center; + align-items: center; + height: 40px; + width: auto; + outline: none; + border-radius: 6px; + padding: 0 16px; + background-color: hsl(200 98% 39%); + color: white; + font-size: 16px; + line-height: 0; + transition: 250ms background-color; +} +.dialog__trigger:hover { + background-color: hsl(201 96% 32%); +} +.dialog__trigger:focus-visible { + outline: 2px solid hsl(200 98% 39%); + outline-offset: 2px; +} +.dialog__trigger:active { + background-color: hsl(201 90% 27%); +} +.dialog__overlay { + position: fixed; + inset: 0; + z-index: 50; + background-color: rgb(0 0 0 / 0.2); + animation: overlayHide 250ms ease 100ms forwards; +} +.dialog__overlay[data-expanded] { + animation: overlayShow 250ms ease; +} +.dialog__positioner { + position: fixed; + inset: 0; + z-index: 50; + display: flex; + align-items: center; + justify-content: center; +} +.dialog__content { + z-index: 50; + max-width: min(calc(100vw - 16px), 500px); + border: 1px solid hsl(240 5% 84%); + border-radius: 6px; + padding: 16px; + background-color: white; + box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); + animation: contentHide 300ms ease-in forwards; +} +.dialog__content[data-expanded] { + animation: contentShow 300ms ease-out; +} +.dialog__header { + display: flex; + align-items: baseline; + justify-content: space-between; + margin-bottom: 12px; +} +.dialog__close-button { + height: 16px; + width: 16px; + color: hsl(240 5% 34%); +} +.dialog__title { + font-size: 20px; + font-weight: 500; + color: hsl(240 6% 10%); +} +.dialog__description { + font-size: 16px; + color: hsl(240 5% 26%); +} +@keyframes overlayShow { + from { + opacity: 0; + } + to { + opacity: 1; + } +} +@keyframes overlayHide { + from { + opacity: 1; + } + to { + opacity: 0; + } +} +@keyframes contentShow { + from { + opacity: 0; + transform: scale(0.96); + } + to { + opacity: 1; + transform: scale(1); + } +} +@keyframes contentHide { + from { + opacity: 1; + transform: scale(1); + } + to { + opacity: 0; + transform: scale(0.96); + } +}