feat(app): wire dashboard administration flows
This commit is contained in:
@@ -14,8 +14,6 @@ import {
|
||||
|
||||
import '@uptime.link/webwidget';
|
||||
|
||||
import '@design.estate/dees-catalog';
|
||||
import { DeesForm, DeesFormSubmit, DeesInputText } from '@design.estate/dees-catalog';
|
||||
import { IdpState } from '../states/idp.state.js';
|
||||
|
||||
declare global {
|
||||
@@ -146,7 +144,7 @@ export class IdpLoginPrompt extends DeesElement {
|
||||
return false;
|
||||
}
|
||||
|
||||
const loginForm = this.shadowRoot.querySelector('#loginForm') as DeesForm | null;
|
||||
const loginForm = this.shadowRoot.querySelector('#loginForm') as plugins.idpCatalog.IdpForm | null;
|
||||
loginForm?.setStatus('pending', 'preparing application authorization...');
|
||||
this.oidcConsentError = '';
|
||||
|
||||
@@ -177,7 +175,7 @@ export class IdpLoginPrompt extends DeesElement {
|
||||
}
|
||||
|
||||
const idpState = await IdpState.getSingletonInstance();
|
||||
const loginForm = this.shadowRoot.querySelector('#loginForm') as DeesForm | null;
|
||||
const loginForm = this.shadowRoot.querySelector('#loginForm') as plugins.idpCatalog.IdpForm | null;
|
||||
loginForm?.setStatus('pending', 'authorizing application...');
|
||||
this.oidcConsentError = '';
|
||||
|
||||
@@ -233,7 +231,7 @@ export class IdpLoginPrompt extends DeesElement {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
dees-form {
|
||||
idp-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
@@ -318,25 +316,6 @@ export class IdpLoginPrompt extends DeesElement {
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.consent-button {
|
||||
border: none;
|
||||
border-radius: 999px;
|
||||
padding: 12px 18px;
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.consent-button-secondary {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.consent-button-primary {
|
||||
background: linear-gradient(135deg, #9b7bff, #5fd1ff);
|
||||
color: #0a0a0a;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.consent-error {
|
||||
color: #ff9a9a;
|
||||
font-size: 14px;
|
||||
@@ -370,16 +349,16 @@ export class IdpLoginPrompt extends DeesElement {
|
||||
</div>
|
||||
${this.oidcConsentError ? html`<div class="consent-error">${this.oidcConsentError}</div>` : null}
|
||||
<div class="consent-actions">
|
||||
<button
|
||||
class="consent-button consent-button-secondary"
|
||||
<idp-button
|
||||
variant="outline"
|
||||
@click=${() => {
|
||||
this.redirectOidcError('access_denied');
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
class="consent-button consent-button-primary"
|
||||
</idp-button>
|
||||
<idp-button
|
||||
variant="accent"
|
||||
@click=${async () => {
|
||||
const idpState = await IdpState.getSingletonInstance();
|
||||
const jwt = await idpState.idpClient.getJwt();
|
||||
@@ -391,7 +370,7 @@ export class IdpLoginPrompt extends DeesElement {
|
||||
}}
|
||||
>
|
||||
Allow and continue
|
||||
</button>
|
||||
</idp-button>
|
||||
</div>
|
||||
</div>
|
||||
</idp-centercontainer>
|
||||
@@ -404,29 +383,31 @@ export class IdpLoginPrompt extends DeesElement {
|
||||
<h2>Sign in to your account</h2>
|
||||
<p>Enter your credentials to continue</p>
|
||||
</div>
|
||||
<dees-form
|
||||
<idp-form
|
||||
id="loginForm"
|
||||
@formData=${(eventArg) => {
|
||||
@idp-submit=${(eventArg: CustomEvent<plugins.idpCatalog.IIdpFormSubmitEventDetail>) => {
|
||||
this.login({
|
||||
emailAddress: eventArg.detail.data.emailAddress,
|
||||
passwordArg: eventArg.detail.data.password,
|
||||
emailAddress: String(eventArg.detail.data.emailAddress || ''),
|
||||
passwordArg: String(eventArg.detail.data.password || ''),
|
||||
});
|
||||
}}
|
||||
>
|
||||
<dees-input-text
|
||||
<idp-input
|
||||
id="loginEmailInput"
|
||||
.required=${true}
|
||||
key="emailAddress"
|
||||
required
|
||||
name="emailAddress"
|
||||
label="Email or Username"
|
||||
></dees-input-text>
|
||||
<dees-input-text
|
||||
.id=${'loginPasswordInput'}
|
||||
.key=${'password'}
|
||||
.label=${'Password'}
|
||||
.isPasswordBool=${true}
|
||||
></dees-input-text>
|
||||
<dees-form-submit id="loginSubmitButton"></dees-form-submit>
|
||||
</dees-form>
|
||||
autocomplete="username"
|
||||
></idp-input>
|
||||
<idp-input
|
||||
id="loginPasswordInput"
|
||||
name="password"
|
||||
label="Password"
|
||||
type="password"
|
||||
autocomplete="current-password"
|
||||
></idp-input>
|
||||
<idp-form-submit id="loginSubmitButton"></idp-form-submit>
|
||||
</idp-form>
|
||||
<div class="form-footer">
|
||||
Don't have an account?
|
||||
<a @click=${async () => {
|
||||
@@ -441,9 +422,9 @@ export class IdpLoginPrompt extends DeesElement {
|
||||
public async firstUpdated() {
|
||||
await this.domtoolsPromise;
|
||||
const idpState = await IdpState.getSingletonInstance();
|
||||
const loginForm = this.shadowRoot.querySelector('#loginForm') as DeesForm;
|
||||
const loginPasswordInput = loginForm.querySelector('#loginPasswordInput') as DeesInputText;
|
||||
const loginSubmitButton = loginForm.querySelector('#loginSubmitButton') as DeesFormSubmit;
|
||||
const loginForm = this.shadowRoot.querySelector('#loginForm') as plugins.idpCatalog.IdpForm;
|
||||
const loginPasswordInput = loginForm.querySelector('#loginPasswordInput') as plugins.idpCatalog.IdpInput;
|
||||
const loginSubmitButton = loginForm.querySelector('#loginSubmitButton') as plugins.idpCatalog.IdpFormSubmit;
|
||||
const oidcContext = this.getOidcAuthorizationContext();
|
||||
const setButtonText = async () => {
|
||||
if (loginPasswordInput.value) {
|
||||
@@ -452,7 +433,7 @@ export class IdpLoginPrompt extends DeesElement {
|
||||
loginSubmitButton.text = 'Send magic link (or enter password)';
|
||||
}
|
||||
};
|
||||
loginForm.changeSubject.subscribe(() => {
|
||||
loginForm.addEventListener('idp-input-change', () => {
|
||||
void setButtonText();
|
||||
});
|
||||
await setButtonText();
|
||||
@@ -470,17 +451,19 @@ export class IdpLoginPrompt extends DeesElement {
|
||||
await this.handleOidcAfterLogin(jwt);
|
||||
}
|
||||
}
|
||||
} else if (await idpState.idpClient.determineLoginStatus(false)) {
|
||||
idpState.domtools.router.pushUrl('/dash/overview');
|
||||
}
|
||||
}
|
||||
|
||||
private login = async (valueArg: { emailAddress: string; passwordArg: string }) => {
|
||||
const loginSubmitButton = this.shadowRoot.querySelector(
|
||||
'#loginSubmitButton'
|
||||
) as plugins.deesCatalog.DeesFormSubmit;
|
||||
) as plugins.idpCatalog.IdpFormSubmit;
|
||||
loginSubmitButton.disabled = true;
|
||||
|
||||
const idpState = await IdpState.getSingletonInstance();
|
||||
const loginForm = this.shadowRoot.querySelector('#loginForm') as DeesForm;
|
||||
const loginForm = this.shadowRoot.querySelector('#loginForm') as plugins.idpCatalog.IdpForm;
|
||||
const loginRequestWithUsernameAndPassword =
|
||||
idpState.idpClient.typedsocket.createTypedRequest<plugins.idpInterfaces.request.IReq_LoginWithEmailOrUsernameAndPassword>(
|
||||
'loginWithEmailOrUsernameAndPassword'
|
||||
@@ -512,7 +495,7 @@ export class IdpLoginPrompt extends DeesElement {
|
||||
loginForm.setStatus('success', 'obtained jwt.');
|
||||
const oidcHandled = await this.handleOidcAfterLogin(jwt);
|
||||
if (!oidcHandled) {
|
||||
idpState.domtools.router.pushUrl('/account');
|
||||
idpState.domtools.router.pushUrl('/dash/overview');
|
||||
}
|
||||
} else {
|
||||
loginForm.setStatus('error', 'something went wrong');
|
||||
@@ -522,8 +505,12 @@ export class IdpLoginPrompt extends DeesElement {
|
||||
loginForm.setStatus('pending', 'sending magic link...');
|
||||
const response = await loginRequestWithEmail.fire({
|
||||
email: valueArg.emailAddress,
|
||||
}).catch((err) => {
|
||||
const message = err?.errorText || err?.message || 'Could not send the magic link. Please try again.';
|
||||
loginForm.setStatus('error', message);
|
||||
return null;
|
||||
});
|
||||
if (response.status === 'ok') {
|
||||
if (response?.status === 'ok') {
|
||||
loginForm.setStatus('success', 'Please check your email!');
|
||||
}
|
||||
}
|
||||
@@ -547,7 +534,7 @@ export class IdpLoginPrompt extends DeesElement {
|
||||
}
|
||||
|
||||
public async focus() {
|
||||
(this.shadowRoot.querySelector('#loginEmailInput') as plugins.deesCatalog.DeesInputText).focus();
|
||||
(this.shadowRoot.querySelector('#loginEmailInput') as plugins.idpCatalog.IdpInput).focus();
|
||||
}
|
||||
|
||||
public async show() {
|
||||
|
||||
Reference in New Issue
Block a user