ricochetjs/public/js/main.js
2024-03-12 14:06:53 +01:00

184 lines
4.9 KiB
JavaScript

import {
html,
render,
} from 'https://unpkg.com/htm@latest/preact/index.mjs?module';
import {
useState,
useEffect,
} from 'https://unpkg.com/preact@latest/hooks/dist/hooks.module.js?module';
function SiteForm({ create = false }) {
const [newSite, setNewSite] = useState({});
const [error, setError] = useState(null);
const [siteKey, setSiteKey] = useState(null);
const [siteUpdated, setSiteUpdated] = useState(false);
const onChange = (att) => (e) => {
setNewSite((prev) => ({ ...prev, [att]: e.target.value }));
};
const onClick = async (e) => {
e.preventDefault();
setSiteUpdated(false);
setError(null);
const result = await fetch(
create ? '/_register/' : `/_register/${newSite.siteId}`,
{
method: create ? 'POST' : 'PATCH',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(newSite),
}
);
if (result.status === 400) {
const { message } = await result.json();
setError(message);
return;
}
if (result.status === 403) {
const { message } = await result.json();
setError(message);
return;
}
if (result.status === 404) {
const { message } = await result.json();
setError(message);
return;
}
if (result.status >= 300) {
setError('Unknown error, try again later...');
return;
}
setNewSite({});
if (create) {
const { key } = await result.json();
setSiteKey(key);
} else {
setSiteUpdated(true);
}
};
return html`<div class="card">
<header>
<h2>${create ? 'Create new site' : 'Update site'}</h2>
</header>
<div class="content">
<form>
<div class="field">
<label>
Site Id:
<input value=${newSite.siteId || ''} onChange=${onChange('siteId')}
/></label>
<p class="help-text">Only letters and '_' are accepted.</p>
</div>
<div class="field">
<label>
Name:
<input value=${newSite.name || ''} onChange=${onChange('name')}
/></label>
<p class="help-text">This name will appears in sent email.</p>
</div>
<div class="field">
<label>
Email from:
<input
value=${newSite.emailFrom || ''}
onChange=${onChange('emailFrom')}
/>
</label>
<p class="help-text">
All sent email for this site will have this origin.
</p>
</div>
${create &&
html`<div class="field">
<label>
Owner:
<input value=${newSite.owner || ''} onChange=${onChange('owner')} />
</label>
<p class="help-text">
This is the site owner email. Confirmation links are sent to this
address.
</p>
</div>`}
</form>
${error && html`<p class="text-error">${error}</p>`}
${siteKey &&
html`<p class="text-success">
Success! Please, save the site encryption key:
<input value=${siteKey} onChange=${(e) => e.preventDefault()} />
this is the last opportunity to read it.
</p>
<p class="text-success">
Now you must confirm the site creation before using it, you will
receive an email at the 'owner' address with a confirmation link.
</p>`}
${siteUpdated &&
html` <p class="text-success">
Success! Now you must confirm the site update by visiting the
confirmation link we have just sent to the owner email.
</p>`}
</div>
<footer>
<button
class="button primary"
onClick=${onClick}
disabled=${!newSite.siteId}
>
${create ? 'Create site' : 'Update site'}
</button>
</footer>
</div>`;
}
function App() {
const [settings, setSettings] = useState({});
useEffect(() => {
let mounted = true;
const updateRegistration = async () => {
const result = await (await fetch('/site/settings')).json();
console.log(result);
if (mounted) setSettings(result);
};
updateRegistration();
return () => (mounted = false);
}, []);
return html`<div class="container">
<div class="row">
<div class="col-4" />
<div class="col"><h1>Ricochet.js admin</h1></div>
</div>
${settings.registrationEnabled &&
html`<div class="row">
<div class="col-2" />
<div class="col-4">
<${SiteForm} create />
</div>
<div class="col-4">
<${SiteForm} />
</div>
</div>`}
${settings.registrationEnabled === false &&
html`<div class="row">
<div class="col-4" />
<div class="col">
<h2 class="text-error">Site registration is disabled</h2>
</div>
</div>`}
</div>`;
}
render(html`<${App} />`, document.body);