Still refactoring...
This commit is contained in:
parent
a0bed34b43
commit
f4ba7afb69
|
@ -1,13 +1,13 @@
|
|||
import { createForm } from '@felte/solid';
|
||||
import reporter from '@felte/reporter-tippy';
|
||||
import { Button, Dialog, TextField } from '@kobalte/core';
|
||||
import { Component, createSignal } from 'solid-js';
|
||||
import { Component, createSignal, JSXElement, Show } from 'solid-js';
|
||||
import 'tippy.js/dist/tippy.css';
|
||||
|
||||
interface CredentialsType {
|
||||
username: string;
|
||||
password: string;
|
||||
hostname?: string;
|
||||
database: string;
|
||||
}
|
||||
|
||||
const [adminCredentials, setAdminCredentials] = createSignal<CredentialsType>();
|
||||
|
@ -155,3 +155,13 @@ const Credentials: Component<Props> = (props) => {
|
|||
};
|
||||
|
||||
export default Credentials;
|
||||
|
||||
export const CheckCredentials: Component<{ children: JSXElement }> = (
|
||||
props
|
||||
) => {
|
||||
return (
|
||||
<Show when={!!adminCredentials()} fallback={<Credentials />}>
|
||||
{props.children}
|
||||
</Show>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1 +1 @@
|
|||
export { default, adminCredentials } from './Credentials';
|
||||
export { default, adminCredentials, CheckCredentials } from './Credentials';
|
||||
|
|
|
@ -1,88 +1,30 @@
|
|||
import { createForm } from '@felte/solid';
|
||||
import { Component, createSignal, Match, Switch } from 'solid-js';
|
||||
import { TextField, Button, Dialog } from '@kobalte/core';
|
||||
|
||||
import './style.css';
|
||||
import { createServerAction$ } from 'solid-start/server';
|
||||
import PouchDb from 'pouchdb';
|
||||
import { Component, createEffect, Match, Switch } from 'solid-js';
|
||||
import { TextField, Button } from '@kobalte/core';
|
||||
import reporter from '@felte/reporter-tippy';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { put } from '~/lib/db';
|
||||
import './style.css';
|
||||
import { useNavigate } from 'solid-start';
|
||||
import { toHex } from '~/lib/to-hex';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { adminCredentials } from '../credentials';
|
||||
import { put } from '~/lib/put';
|
||||
import { del } from '~/lib/del';
|
||||
import { isFunction } from 'lodash';
|
||||
|
||||
interface Props {
|
||||
values?: any;
|
||||
values?: () => any;
|
||||
}
|
||||
|
||||
const User: Component<Props> = (props) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [openDialog, setOpenDialog] = createSignal(false);
|
||||
const [openUsernamePasswordDialog, setOpenUserNamePasswordDialog] =
|
||||
createSignal(false);
|
||||
const getValues = () => {
|
||||
if (!isFunction(props?.values)) {
|
||||
return null;
|
||||
}
|
||||
return props.values();
|
||||
};
|
||||
|
||||
const [status, setStatus] = createSignal<string>();
|
||||
|
||||
const [saving, save] = createServerAction$(async (args: any) => {
|
||||
const { props, values } = args;
|
||||
console.log({
|
||||
caller: 'User / save',
|
||||
props,
|
||||
values,
|
||||
args,
|
||||
id: props.values?._id,
|
||||
});
|
||||
const db = new PouchDb('.db');
|
||||
const id = props.values?._id ?? `user/${uuid()}`;
|
||||
await put({
|
||||
db,
|
||||
doc: {
|
||||
_id: id,
|
||||
date: new Date().toISOString(),
|
||||
type: 'user',
|
||||
...values,
|
||||
},
|
||||
});
|
||||
return id;
|
||||
});
|
||||
|
||||
const [dbChecking, dbCheck] = createServerAction$(async (args: any) => {
|
||||
console.log({
|
||||
caller: 'User / dbCheck',
|
||||
args,
|
||||
});
|
||||
let baseDbInfoAuth;
|
||||
try {
|
||||
const baseDb = new PouchDb(cloneDeep(args));
|
||||
baseDbInfoAuth = await baseDb.info();
|
||||
} catch (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;
|
||||
try {
|
||||
const userDb = new PouchDb({ ...args, name });
|
||||
userDbInfo = await userDb.info();
|
||||
} catch (error) {
|
||||
userDbInfo = { error };
|
||||
}
|
||||
let userDbInfoAnon;
|
||||
try {
|
||||
const userDb = new PouchDb(name);
|
||||
userDbInfoAnon = await userDb.info();
|
||||
} catch (error) {
|
||||
userDbInfoAnon = { error };
|
||||
}
|
||||
return { baseDbInfoAuth, baseDbInfoAnon, userDbInfo, userDbInfoAnon };
|
||||
});
|
||||
const isNew = () => !getValues();
|
||||
|
||||
const submitHandler = async (values: any, context: any) => {
|
||||
console.log({
|
||||
|
@ -91,9 +33,10 @@ const User: Component<Props> = (props) => {
|
|||
values,
|
||||
context,
|
||||
});
|
||||
const id = await save({ values, props });
|
||||
if (!props.values) {
|
||||
navigate(`/user/${encodeURIComponent(id)}`);
|
||||
const id = getValues()?._id ?? `user:${uuid()}`;
|
||||
await put(id, values, isNew());
|
||||
if (isNew()) {
|
||||
navigate(`/user/${id}`);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -104,42 +47,79 @@ const User: Component<Props> = (props) => {
|
|||
const deleteHandler = async () => {
|
||||
console.log({
|
||||
caller: 'User / deleteHandler',
|
||||
id: getValues()?._id,
|
||||
props,
|
||||
});
|
||||
await save({ props, values: { _deleted: true } });
|
||||
await del(getValues()?._id);
|
||||
navigate(`/user/`);
|
||||
};
|
||||
|
||||
const { form, data } = createForm({
|
||||
const validationHandler = async (values: any) => {
|
||||
let errors: any = {};
|
||||
const credentials = adminCredentials();
|
||||
if (!credentials) {
|
||||
return errors;
|
||||
}
|
||||
const { database, username, password } = credentials;
|
||||
try {
|
||||
const response = await fetch(database, { mode: 'cors' });
|
||||
const dbStatus = await response.json();
|
||||
if (!dbStatus.couchdb) {
|
||||
errors.database = 'The URL is not a couchdb instance';
|
||||
}
|
||||
} catch (error) {
|
||||
errors.database = "Can't access the database";
|
||||
}
|
||||
if (!!errors.database) {
|
||||
return errors;
|
||||
}
|
||||
|
||||
if (isNew()) {
|
||||
const authString = `${username}:${password}`;
|
||||
const headers = new Headers();
|
||||
headers.set('Authorization', 'Basic ' + btoa(authString));
|
||||
const response = await fetch(
|
||||
`${database}/_users/org.couchdb.user:${values.username}`,
|
||||
{
|
||||
method: 'HEAD',
|
||||
mode: 'cors',
|
||||
headers,
|
||||
}
|
||||
);
|
||||
if (response.status === 200) {
|
||||
errors.username = 'The user is already existing';
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
};
|
||||
|
||||
const { form, data, setData, setInitialValues, reset } = createForm({
|
||||
onSubmit: submitHandler,
|
||||
initialValues: props?.values,
|
||||
extend: reporter(),
|
||||
validate: validationHandler,
|
||||
initialValues: getValues(),
|
||||
});
|
||||
|
||||
const dbCheckHandler = async () => {
|
||||
const result = await dbCheck({
|
||||
name: data('database'),
|
||||
auth: { username: data('username'), password: data('password') },
|
||||
});
|
||||
console.log({
|
||||
caller: 'User / dbCheckHandler',
|
||||
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');
|
||||
createEffect(() => {
|
||||
console.log({ caller: 'user / createEffect', values: getValues() });
|
||||
if (isNew()) {
|
||||
const credentials = adminCredentials();
|
||||
if (!credentials) {
|
||||
return;
|
||||
}
|
||||
const { database } = credentials;
|
||||
setData('database', database);
|
||||
} else {
|
||||
setStatus('notFound');
|
||||
setInitialValues(getValues());
|
||||
reset();
|
||||
console.log({
|
||||
caller: 'user / createEffect',
|
||||
values: getValues(),
|
||||
data: data(),
|
||||
});
|
||||
}
|
||||
setOpenDialog(true);
|
||||
};
|
||||
});
|
||||
|
||||
const createUserHandler = async () => {
|
||||
console.log({
|
||||
|
@ -147,117 +127,70 @@ const User: Component<Props> = (props) => {
|
|||
props,
|
||||
data: data(),
|
||||
});
|
||||
setOpenUserNamePasswordDialog(true);
|
||||
// setOpenUserNamePasswordDialog(true);
|
||||
};
|
||||
|
||||
console.log({
|
||||
caller: 'User ',
|
||||
props,
|
||||
values: getValues(),
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<form use:form>
|
||||
<TextField.Root>
|
||||
<TextField.Label>Mail address</TextField.Label>
|
||||
<TextField.Input
|
||||
type='mail'
|
||||
name='mail'
|
||||
required={true}
|
||||
placeholder='Email address'
|
||||
/>
|
||||
<TextField.ErrorMessage>
|
||||
Please provide a valid URL
|
||||
</TextField.ErrorMessage>
|
||||
</TextField.Root>
|
||||
<TextField.Root>
|
||||
<TextField.Label>Database</TextField.Label>
|
||||
<TextField.Input
|
||||
type='url'
|
||||
name='database'
|
||||
required={true}
|
||||
placeholder='Database URL'
|
||||
/>
|
||||
<TextField.ErrorMessage>
|
||||
Please provide a valid URL
|
||||
</TextField.ErrorMessage>
|
||||
</TextField.Root>
|
||||
<TextField.Root>
|
||||
<TextField.Label>User name</TextField.Label>
|
||||
<TextField.Input
|
||||
type='text'
|
||||
name='username'
|
||||
required={true}
|
||||
placeholder='user name'
|
||||
/>
|
||||
</TextField.Root>
|
||||
<TextField.Root>
|
||||
<TextField.Label>Password</TextField.Label>
|
||||
<TextField.Input
|
||||
type='text'
|
||||
name='password'
|
||||
required={true}
|
||||
placeholder='Password'
|
||||
autocomplete='off'
|
||||
/>
|
||||
<TextField.ErrorMessage>
|
||||
Please provide a valid password
|
||||
</TextField.ErrorMessage>
|
||||
</TextField.Root>
|
||||
<Switch>
|
||||
<Match when={!!props.values}>
|
||||
<Button.Root type='submit'>Save</Button.Root>
|
||||
<Button.Root onclick={deleteHandler}>Delete</Button.Root>
|
||||
</Match>
|
||||
<Match when={!props.values}>
|
||||
<Button.Root type='submit'>Create</Button.Root>
|
||||
</Match>
|
||||
</Switch>
|
||||
<Button.Root onclick={dbCheckHandler}>DB check</Button.Root>
|
||||
<Button.Root onclick={cancelHandler}>Cancel</Button.Root>
|
||||
</form>
|
||||
<Dialog.Root isOpen={openDialog()} onOpenChange={setOpenDialog}>
|
||||
<Dialog.Portal>
|
||||
<Dialog.Overlay class='dialog__overlay' />
|
||||
<div class='dialog__positioner'>
|
||||
<Dialog.Content class='dialog__content'>
|
||||
<div class='dialog__header'>
|
||||
<Dialog.Title class='dialog__title'>
|
||||
Database check
|
||||
</Dialog.Title>
|
||||
<Dialog.CloseButton class='dialog__close-button'>
|
||||
X
|
||||
</Dialog.CloseButton>
|
||||
</div>
|
||||
<Dialog.Description class='dialog__description'>
|
||||
<Switch>
|
||||
<Match when={status() === 'baseError'}>
|
||||
The database address seems to be wrong !!
|
||||
</Match>
|
||||
<Match when={status() === 'OK'}>
|
||||
The user is already existing.
|
||||
</Match>
|
||||
<Match when={status() === 'notFound'}>
|
||||
<div>The user must be created.</div>
|
||||
<Button.Root onclick={createUserHandler}>
|
||||
Create user
|
||||
</Button.Root>
|
||||
</Match>
|
||||
<Match when={status() === 'passwordError'}>
|
||||
<div>
|
||||
The user seems to exist but the password is wrong.
|
||||
</div>
|
||||
<Button.Root onclick={createUserHandler}>
|
||||
Update password
|
||||
</Button.Root>
|
||||
</Match>
|
||||
</Switch>
|
||||
</Dialog.Description>
|
||||
</Dialog.Content>
|
||||
</div>
|
||||
</Dialog.Portal>
|
||||
</Dialog.Root>
|
||||
</>
|
||||
<form use:form>
|
||||
<TextField.Root>
|
||||
<TextField.Label>Mail address</TextField.Label>
|
||||
<TextField.Input
|
||||
type='mail'
|
||||
name='mail'
|
||||
required={true}
|
||||
placeholder='Email address'
|
||||
/>
|
||||
<TextField.ErrorMessage>
|
||||
Please provide a valid URL
|
||||
</TextField.ErrorMessage>
|
||||
</TextField.Root>
|
||||
<TextField.Root>
|
||||
<TextField.Label>Database</TextField.Label>
|
||||
<TextField.Input
|
||||
type='url'
|
||||
name='database'
|
||||
required={true}
|
||||
placeholder='Database URL'
|
||||
readOnly={true}
|
||||
/>
|
||||
</TextField.Root>
|
||||
<TextField.Root>
|
||||
<TextField.Label>User name</TextField.Label>
|
||||
<TextField.Input
|
||||
type='text'
|
||||
name='username'
|
||||
required={true}
|
||||
placeholder='user name'
|
||||
readOnly={!isNew()}
|
||||
/>
|
||||
</TextField.Root>
|
||||
<TextField.Root>
|
||||
<TextField.Label>Password</TextField.Label>
|
||||
<TextField.Input
|
||||
type='text'
|
||||
name='password'
|
||||
required={true}
|
||||
placeholder='Password'
|
||||
autocomplete='off'
|
||||
/>
|
||||
</TextField.Root>
|
||||
<Switch>
|
||||
<Match when={!isNew()}>
|
||||
<Button.Root type='submit'>Save</Button.Root>
|
||||
<Button.Root onclick={deleteHandler}>Delete</Button.Root>
|
||||
</Match>
|
||||
<Match when={isNew()}>
|
||||
<Button.Root type='submit'>Create</Button.Root>
|
||||
</Match>
|
||||
</Switch>
|
||||
<Button.Root onclick={cancelHandler}>Cancel</Button.Root>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,34 +1,20 @@
|
|||
import { Button } from '@kobalte/core';
|
||||
import { A } from '@solidjs/router';
|
||||
import PouchDb from 'pouchdb';
|
||||
import { Component, createEffect, For } from 'solid-js';
|
||||
import { createServerAction$ } from 'solid-start/server';
|
||||
import { useNavigate } from 'solid-start';
|
||||
|
||||
interface Props {}
|
||||
interface Props {
|
||||
users: any;
|
||||
}
|
||||
|
||||
const Users: Component<Props> = (props) => {
|
||||
const { users } = props;
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [users, getUsers] = createServerAction$(
|
||||
async (values: any) => {
|
||||
const db = new PouchDb('.db');
|
||||
const results = await db.allDocs({
|
||||
include_docs: true,
|
||||
startkey: 'user/',
|
||||
endkey: 'user/\ufff0',
|
||||
});
|
||||
console.log({ caller: 'Users / serverAction', results });
|
||||
return results.rows;
|
||||
}
|
||||
);
|
||||
|
||||
getUsers();
|
||||
|
||||
createEffect(() => {
|
||||
console.log({
|
||||
caller: 'Users',
|
||||
users: users.result,
|
||||
users: users(),
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -40,7 +26,7 @@ const Users: Component<Props> = (props) => {
|
|||
<>
|
||||
<Button.Root onclick={newHandler}>New</Button.Root>
|
||||
<ul>
|
||||
<For each={users.result}>
|
||||
<For each={users()}>
|
||||
{(user: any) => {
|
||||
console.log({
|
||||
caller: 'Users / loop',
|
||||
|
@ -48,9 +34,7 @@ const Users: Component<Props> = (props) => {
|
|||
});
|
||||
return (
|
||||
<li>
|
||||
<A href={encodeURIComponent(user.id)}>
|
||||
{user.doc.mail}
|
||||
</A>
|
||||
<A href={user.id}>{user.doc.mail}</A>
|
||||
</li>
|
||||
);
|
||||
}}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
import { adminCredentials } from '~/components/credentials';
|
||||
import { headersWithAuth } from './headers-with-auth';
|
||||
|
||||
export const adminDbExists = async () => {
|
||||
const credentials = adminCredentials();
|
||||
if (!credentials) {
|
||||
return null;
|
||||
}
|
||||
const { database } = credentials;
|
||||
|
||||
const headers = headersWithAuth();
|
||||
if (!headers) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const response = await fetch(`${database}/_dyomedea_users`, {
|
||||
method: 'HEAD',
|
||||
mode: 'cors',
|
||||
headers,
|
||||
});
|
||||
|
||||
if (response.status !== 200) {
|
||||
console.error({ caller: 'dbExists', response });
|
||||
}
|
||||
|
||||
return response.status === 200;
|
||||
};
|
|
@ -0,0 +1,29 @@
|
|||
import { adminCredentials } from '~/components/credentials';
|
||||
import { headersWithAuth } from './headers-with-auth';
|
||||
|
||||
export const createAdminDb = async () => {
|
||||
const credentials = adminCredentials();
|
||||
if (!credentials) {
|
||||
return null;
|
||||
}
|
||||
const { database } = credentials;
|
||||
|
||||
const headers = headersWithAuth();
|
||||
if (!headers) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const response = await fetch(`${database}/dyomedea_users`, {
|
||||
method: 'PUT',
|
||||
mode: 'cors',
|
||||
headers,
|
||||
});
|
||||
|
||||
console.log({ caller: 'dbExists', response });
|
||||
|
||||
if (![200, 201].includes(response.status)) {
|
||||
console.error({ caller: 'dbExists', response });
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
|
@ -1,11 +0,0 @@
|
|||
export const put = async (params: { db: any; doc: any }) => {
|
||||
const { db, doc } = params;
|
||||
try {
|
||||
const previous = await db.get(doc._id);
|
||||
doc._rev = previous._rev;
|
||||
} catch (error) {
|
||||
console.error({ caller: 'put', doc, error });
|
||||
}
|
||||
console.log({ caller: 'put', doc });
|
||||
db.put(doc);
|
||||
};
|
|
@ -0,0 +1,6 @@
|
|||
import { put } from './put';
|
||||
|
||||
export const del = async (id: string) => {
|
||||
const content = { _deleted: true };
|
||||
return await put(id, content, false);
|
||||
};
|
|
@ -0,0 +1,10 @@
|
|||
import { adminCredentials } from '~/components/credentials';
|
||||
|
||||
export const getUrl = (id: string) => {
|
||||
const credentials = adminCredentials();
|
||||
if (!credentials) {
|
||||
return '';
|
||||
}
|
||||
const { database } = credentials;
|
||||
return `${database}/dyomedea_users/${id}`;
|
||||
};
|
|
@ -0,0 +1,23 @@
|
|||
import { adminCredentials } from '~/components/credentials';
|
||||
import { headersWithAuth } from './headers-with-auth';
|
||||
|
||||
export const get = async (id: string) => {
|
||||
const credentials = adminCredentials();
|
||||
if (!credentials) {
|
||||
return null;
|
||||
}
|
||||
const { database } = credentials;
|
||||
|
||||
const headers = headersWithAuth();
|
||||
if (!headers) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const response = await fetch(`${database}/dyomedea_users/${id}`, {
|
||||
method: 'GET',
|
||||
mode: 'cors',
|
||||
headers,
|
||||
});
|
||||
|
||||
return await response.json();
|
||||
};
|
|
@ -0,0 +1,13 @@
|
|||
import { adminCredentials } from '~/components/credentials';
|
||||
|
||||
export const headersWithAuth = () => {
|
||||
const credentials = adminCredentials();
|
||||
if (!credentials) {
|
||||
return null;
|
||||
}
|
||||
const { username, password } = credentials;
|
||||
const authString = `${username}:${password}`;
|
||||
const headers = new Headers();
|
||||
headers.set('Authorization', 'Basic ' + btoa(authString));
|
||||
return headers;
|
||||
};
|
|
@ -0,0 +1,32 @@
|
|||
import { adminCredentials } from '~/components/credentials';
|
||||
import { get } from './get';
|
||||
import { getUrl } from './get-url';
|
||||
import { headersWithAuth } from './headers-with-auth';
|
||||
|
||||
export const put = async (id: string, content: any, isNew: boolean = false) => {
|
||||
const credentials = adminCredentials();
|
||||
if (!credentials) {
|
||||
return null;
|
||||
}
|
||||
const { database } = credentials;
|
||||
|
||||
if (!isNew) {
|
||||
const previous = await get(id);
|
||||
content._rev = previous._rev;
|
||||
}
|
||||
|
||||
const headers = headersWithAuth();
|
||||
if (!headers) {
|
||||
return null;
|
||||
}
|
||||
headers.set('Content-type', 'application/json; charset=UTF-8');
|
||||
|
||||
const response = await fetch(getUrl(id), {
|
||||
method: 'PUT',
|
||||
mode: 'cors',
|
||||
headers,
|
||||
body: JSON.stringify(content),
|
||||
});
|
||||
|
||||
return await response.json();
|
||||
};
|
|
@ -1,36 +1,30 @@
|
|||
import { useParams } from 'solid-start';
|
||||
import { createServerAction$ } from 'solid-start/server';
|
||||
import PouchDb from 'pouchdb';
|
||||
import User from '~/components/user';
|
||||
import { createEffect, Show } from 'solid-js';
|
||||
import { createEffect, createSignal } from 'solid-js';
|
||||
import { adminCredentials, CheckCredentials } from '~/components/credentials';
|
||||
import { get } from '~/lib/get';
|
||||
|
||||
export default () => {
|
||||
const params = useParams();
|
||||
const [user, getUser] = createServerAction$(
|
||||
async (id: string) => {
|
||||
const db = new PouchDb('.db');
|
||||
const result = await db.get(id);
|
||||
console.log({ caller: 'Users / serverAction', result });
|
||||
return result;
|
||||
const { id } = useParams();
|
||||
const [user, setUser] = createSignal();
|
||||
|
||||
createEffect(async () => {
|
||||
if (!user()) {
|
||||
setUser(await get(id));
|
||||
console.log({
|
||||
caller: '/routes/user/[id].ts / createEffect',
|
||||
user: user(),
|
||||
adminCredentials: adminCredentials(),
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
getUser(decodeURIComponent(params.id));
|
||||
|
||||
createEffect(() => {
|
||||
console.log({
|
||||
caller: 'Users/[id]',
|
||||
params,
|
||||
user: user.result,
|
||||
});
|
||||
});
|
||||
|
||||
return (
|
||||
<main>
|
||||
<h1>User</h1>
|
||||
<Show when={!user.pending} fallback={<>Loading...</>}>
|
||||
<User values={user.result} />
|
||||
</Show>
|
||||
<CheckCredentials>
|
||||
<User values={user} />
|
||||
</CheckCredentials>
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,21 +1,64 @@
|
|||
import { createEffect, Show } from 'solid-js';
|
||||
import Credentials, { adminCredentials } from '~/components/credentials';
|
||||
import { createEffect } from 'solid-js';
|
||||
import { createRouteData, refetchRouteData, useRouteData } from 'solid-start';
|
||||
import { adminCredentials, CheckCredentials } from '~/components/credentials';
|
||||
import Users from '~/components/users';
|
||||
import { adminDbExists } from '~/lib/admin-db-exists';
|
||||
import { createAdminDb } from '~/lib/create-admin-db';
|
||||
import { headersWithAuth } from '~/lib/headers-with-auth';
|
||||
|
||||
export function routeData() {
|
||||
return createRouteData(async () => {
|
||||
if (!(await adminDbExists())) {
|
||||
await createAdminDb();
|
||||
}
|
||||
|
||||
const credentials = adminCredentials();
|
||||
if (!credentials) {
|
||||
return null;
|
||||
}
|
||||
const { database } = credentials;
|
||||
const headers = headersWithAuth();
|
||||
if (!headers) {
|
||||
return null;
|
||||
}
|
||||
headers.set('Content-type', 'application/json; charset=UTF-8');
|
||||
const response = await fetch(`${database}/dyomedea_users/_all_docs`, {
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
headers,
|
||||
body: JSON.stringify({
|
||||
include_docs: true,
|
||||
startkey: 'user:',
|
||||
endkey: 'user:\ufff0',
|
||||
}),
|
||||
});
|
||||
|
||||
const results = await response.json();
|
||||
console.log({ caller: 'user route / routeData', results });
|
||||
return results.rows;
|
||||
});
|
||||
}
|
||||
|
||||
createEffect(() => {
|
||||
console.log({
|
||||
caller: 'user/index / createEffect',
|
||||
adminCredentials: adminCredentials(),
|
||||
});
|
||||
const credentials = adminCredentials();
|
||||
if (!!credentials) {
|
||||
console.log({
|
||||
caller: 'routes/user/index.tsx / createEffect',
|
||||
adminCredentials: credentials,
|
||||
});
|
||||
refetchRouteData();
|
||||
}
|
||||
});
|
||||
|
||||
export default () => {
|
||||
const users = useRouteData<typeof routeData>();
|
||||
// const users = routeData();
|
||||
return (
|
||||
<main>
|
||||
<h1>Users</h1>
|
||||
<Show when={!!adminCredentials()} fallback={<Credentials />}>
|
||||
<Users />
|
||||
</Show>
|
||||
<CheckCredentials>
|
||||
<Users users={users} />
|
||||
</CheckCredentials>
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import User from "~/components/user";
|
||||
import { CheckCredentials } from '~/components/credentials';
|
||||
import User from '~/components/user';
|
||||
|
||||
export default () => {
|
||||
return (
|
||||
<main>
|
||||
<h1>New user</h1>
|
||||
<User />
|
||||
<CheckCredentials>
|
||||
<User />
|
||||
</CheckCredentials>
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue