Files
app/ts_web/elements/idp-registerprompt.ts
T

223 lines
5.9 KiB
TypeScript

import * as plugins from '../plugins.js';
import {
customElement,
DeesElement,
property,
html,
type TemplateResult,
css,
cssManager,
state,
domtools,
} from '@design.estate/dees-element';
// third party catalogs
import '@uptime.link/webwidget';
import { IdpState } from '../states/idp.state.js';
declare global {
interface HTMLElementTagNameMap {
'idp-registrationprompt': IdpRegistrationPrompt;
}
}
@customElement('idp-registrationprompt')
export class IdpRegistrationPrompt extends DeesElement {
public static demo = () => html`<idp-registrationprompt></idp-registrationprompt>`;
@property()
accessor productOfInterest: string;
@property()
accessor jwt: string;
@property({
reflect: true,
type: Object,
})
accessor appData: plugins.idpInterfaces.data.IApp;
public jwtObserable = new domtools.plugins.smartrx.rxjs.Subject<string>();
constructor() {
super();
domtools.elementBasic.setup();
}
public static styles = [
cssManager.defaultStyles,
css`
:host {
--foreground: hsl(0 0% 98%);
--muted-foreground: hsl(240 5% 64.9%);
font-family: 'Geist Sans', -apple-system, BlinkMacSystemFont, sans-serif;
display: block;
color: var(--foreground);
}
.form-header {
margin-bottom: 32px;
text-align: center;
}
.form-header h2 {
font-size: 24px;
font-weight: 600;
color: var(--foreground);
margin: 0 0 8px 0;
letter-spacing: -0.02em;
}
.form-header p {
font-size: 14px;
color: var(--muted-foreground);
margin: 0;
}
idp-form {
display: flex;
flex-direction: column;
gap: 16px;
}
.form-footer {
margin-top: 24px;
text-align: center;
font-size: 14px;
color: var(--muted-foreground);
}
.form-footer a {
color: var(--foreground);
text-decoration: none;
font-weight: 500;
cursor: pointer;
transition: opacity 0.15s ease;
}
.form-footer a:hover {
opacity: 0.8;
}
`,
];
public render(): TemplateResult {
return html`
<idp-centercontainer>
<div class="form-header">
<h2>Create your account</h2>
<p>Get started with your permanent identity</p>
</div>
<idp-form
id="registrationForm"
@idp-submit=${(eventArg: CustomEvent<plugins.idpCatalog.IIdpFormSubmitEventDetail>) => {
this.register({
emailAddress: String(eventArg.detail.data.emailAddress || ''),
});
}}
>
<idp-input
required
name="emailAddress"
label="Email Address"
type="email"
autocomplete="email"
></idp-input>
<idp-checkbox
name="termsAccepted"
label="I agree to the Terms and Conditions"
required
></idp-checkbox>
<idp-form-submit>Send Verification Email</idp-form-submit>
</idp-form>
<div class="form-footer">
Already have an account? <a @click=${async () => {
const idpState = await IdpState.getSingletonInstance();
idpState.domtools.router.pushUrl('/login');
}}>Sign in</a>
</div>
</idp-centercontainer>
`;
}
public async firstUpdated() {
await this.domtoolsPromise;
const idpState = await IdpState.getSingletonInstance();
const loggedIn = await idpState.idpClient.determineLoginStatus();
if (loggedIn) {
idpState.domtools.router.pushUrl('/dash/overview');
}
}
private register = async (valueArg: { emailAddress: string }) => {
const registrationForm = this.shadowRoot.querySelector('#registrationForm') as plugins.idpCatalog.IdpForm;
registrationForm.setStatus('pending', 'registering...');
const idpState = await IdpState.getSingletonInstance();
const firstSignupRequest =
idpState.idpClient.typedsocket.createTypedRequest<plugins.idpInterfaces.request.IReq_FirstRegistration>(
'firstRegistrationRequest'
);
const response = await firstSignupRequest
.fire({
email: valueArg.emailAddress,
productSlugOfInterest: this.productOfInterest,
})
.catch((err) => {
const message = err?.errorText || err?.message || 'Registration request failed. Please try again.';
registrationForm.setStatus('error', message);
return null;
});
if (response?.status === 'ok') {
registrationForm.setStatus('success', 'Please check your email!');
} else if (response) {
registrationForm.setStatus('error', 'Registration request failed. Please try again.');
}
console.log(response);
};
public async dispatchJwt(jwtArg?: string) {
if (jwtArg !== undefined) {
console.log(`dispatching jwt from loginprompt.`);
this.jwt = jwtArg;
await domtools.plugins.smartdelay.delayFor(200);
this.dispatchEvent(
new CustomEvent('leleLoginGotJwt', {
detail: {
jwt: this.jwt,
},
})
);
this.jwtObserable.next(this.jwt);
}
}
public async handleRefreshToken(refreshTokenArg: string, delayDispatchMillisArg = 0) {
const idpState = await IdpState.getSingletonInstance();
const jwt = await idpState.idpClient.refreshJwt(refreshTokenArg);
if (jwt) {
this.domtools.convenience.smartdelay.delayFor(delayDispatchMillisArg).then(() => {
this.dispatchJwt(jwt);
});
return jwt;
} else {
return null;
}
}
public async show() {
await this.updateComplete;
const centerContainer = this.shadowRoot.querySelector('idp-centercontainer');
await centerContainer.show();
}
public async hide() {
await this.updateComplete;
const centerContainer = this.shadowRoot.querySelector('idp-centercontainer');
await centerContainer.hide();
}
}