238 lines
7.0 KiB
TypeScript
238 lines
7.0 KiB
TypeScript
import * as plugins from '../../../plugins.js';
|
|
import {
|
|
customElement,
|
|
DeesElement,
|
|
property,
|
|
html,
|
|
cssManager,
|
|
unsafeCSS,
|
|
css,
|
|
render,
|
|
directives,
|
|
} from '@design.estate/dees-element';
|
|
|
|
import sharedStyles, { accountDesignTokens, cardStyles, typographyStyles } from '../sharedstyles.js';
|
|
|
|
declare global {
|
|
interface HTMLElementTagNameMap {
|
|
'lele-accountview-baseview': BaseView;
|
|
}
|
|
}
|
|
|
|
import * as state from '../../../states/accountstate.js';
|
|
|
|
@customElement('lele-accountview-baseview')
|
|
export class BaseView extends DeesElement {
|
|
@property({
|
|
type: Array,
|
|
})
|
|
accessor subscriptions: any[] = [
|
|
{
|
|
organization: 'org1',
|
|
'subscription type': 'workspace.global SaaS',
|
|
price: '4€',
|
|
userFactor: 4,
|
|
total: '16.00€',
|
|
},
|
|
{
|
|
organization: 'org1',
|
|
'subscription type': 'workspace.global IaaS Base Access',
|
|
price: '0€',
|
|
userFactor: 4,
|
|
total: '0€',
|
|
},
|
|
{
|
|
organization: 'org1',
|
|
'subscription type': 'workspace.global SLA Senior',
|
|
price: '2000€',
|
|
userFactor: 'none',
|
|
total: '2000.00€',
|
|
},
|
|
];
|
|
|
|
public static styles = [
|
|
cssManager.defaultStyles,
|
|
accountDesignTokens,
|
|
cardStyles,
|
|
typographyStyles,
|
|
css`
|
|
:host {
|
|
display: block;
|
|
padding: 48px;
|
|
}
|
|
|
|
.viewHost {
|
|
max-width: 600px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.card {
|
|
background: var(--card);
|
|
border: 1px solid var(--border);
|
|
border-radius: 12px;
|
|
padding: 32px;
|
|
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4);
|
|
}
|
|
|
|
.slug {
|
|
color: var(--foreground);
|
|
font-weight: 600;
|
|
font-family: 'Geist Mono', monospace;
|
|
}
|
|
|
|
.hint {
|
|
display: block;
|
|
font-size: 13px;
|
|
color: var(--muted-foreground);
|
|
margin: 16px 0;
|
|
padding: 12px 16px;
|
|
background: var(--muted);
|
|
border-radius: 8px;
|
|
}
|
|
|
|
dees-form {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 16px;
|
|
margin-top: 24px;
|
|
}
|
|
|
|
.orgGrid {
|
|
display: grid;
|
|
grid-gap: 16px;
|
|
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
|
margin-top: 24px;
|
|
}
|
|
|
|
.org {
|
|
padding: 20px;
|
|
background: var(--card);
|
|
border: 1px solid var(--border);
|
|
border-radius: 12px;
|
|
color: var(--foreground);
|
|
transition: all 0.15s ease;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.org:hover {
|
|
background: var(--muted);
|
|
border-color: var(--muted-foreground);
|
|
}
|
|
|
|
.org dees-icon {
|
|
opacity: 0.7;
|
|
}
|
|
`,
|
|
];
|
|
|
|
public render() {
|
|
return html`
|
|
<div class="viewHost">
|
|
|
|
</div> `;
|
|
}
|
|
|
|
public async firstUpdated(_changedProperties: Map<string | number | symbol, unknown>) {
|
|
await this.domtoolsPromise;
|
|
super.firstUpdated(_changedProperties);
|
|
const viewHost: HTMLDivElement = this.shadowRoot.querySelector('.viewHost');
|
|
await state.accountState.dispatchAction(state.getOrganizationsAction, null);
|
|
console.log('got orgs');
|
|
if (state.accountState.getState().organizations.length === 0) {
|
|
render(
|
|
html`
|
|
<div class="card">
|
|
<h1>Setup Your Account</h1>
|
|
<p>
|
|
There are no organizations for your account. Please create one now. Alternatively you
|
|
can ask an admin of an existing organization to invite you.
|
|
</p>
|
|
<dees-form>
|
|
<dees-input-text .label=${'Organization Name'} .key=${'orgName'}></dees-input-text>
|
|
</dees-form>
|
|
<p>
|
|
The organization slug will be:<br />
|
|
<span class="slug"
|
|
>${directives.subscribe(
|
|
state.accountState.select((stateArg) => stateArg.newOrg.chosenSlug)
|
|
)}</span
|
|
>
|
|
</p>
|
|
<span class="hint"></span>
|
|
<dees-button .disabled=${true}>Create the Organization</dees-button>
|
|
</div>
|
|
`,
|
|
viewHost
|
|
);
|
|
const subscriptions: plugins.deesDomtools.plugins.smartrx.rxjs.Subscription[] = [];
|
|
const form = this.shadowRoot.querySelector('dees-form');
|
|
const orgInput = this.shadowRoot.querySelector('dees-input-text');
|
|
const hint = this.shadowRoot.querySelector('.hint');
|
|
const button = this.shadowRoot.querySelector('dees-button');
|
|
const newOrgSubscription = state.accountState
|
|
.select((stateArg) => stateArg.newOrg)
|
|
.subscribe((data) => {
|
|
if (data.chosenSlug) {
|
|
hint.innerHTML = 'Waiting: Validating...';
|
|
} else {
|
|
hint.innerHTML = 'Hint: Enter a valid organization name.';
|
|
}
|
|
if (data.validated && data.validationOk) {
|
|
hint.innerHTML =
|
|
'Success: Name is available. Please click the button to create the organization.';
|
|
button.disabled = false;
|
|
} else if (!data.validated || !data.validationOk) {
|
|
hint.innerHTML = `Info: Name not available. Please choose another one.`;
|
|
button.disabled = true;
|
|
}
|
|
});
|
|
subscriptions.push(newOrgSubscription);
|
|
|
|
const formSubscription = form.changeSubject.subscribe(async (dataArg: any) => {
|
|
await state.accountState.dispatchAction(state.setNewOrgName, dataArg.orgName);
|
|
});
|
|
subscriptions.push(formSubscription);
|
|
button.addEventListener('clicked', async () => {
|
|
orgInput.disabled = true;
|
|
button.text = 'creating org...';
|
|
button.status = 'pending';
|
|
hint.innerHTML = 'Waiting for creation of the organization...';
|
|
await state.accountState.dispatchAction(state.manifestNewOrgName, null);
|
|
hint.innerHTML = `The Organization with name ${
|
|
state.accountState.getState().organizations[0].data.name
|
|
} has been created!`;
|
|
button.text = 'created!';
|
|
button.status = 'success';
|
|
const parentElement = (this.getRootNode() as any).host;
|
|
parentElement.subrouter.pushUrl(
|
|
`/org/${state.accountState.getState().organizations[0].data.slug}/billing`
|
|
);
|
|
});
|
|
} else {
|
|
render(
|
|
html`
|
|
<h1>Select An Organization</h1>
|
|
<p>Choose an organization to manage its settings and billing.</p>
|
|
<div class="orgGrid">
|
|
${state.accountState.getState().organizations.map((orgArg) => {
|
|
return html`
|
|
<div
|
|
class="org"
|
|
@click=${() => {
|
|
state.accountState.dispatchAction(state.setSelectedOrg, orgArg);
|
|
const parentElement = (this.getRootNode() as any).host;
|
|
parentElement.subrouter.pushUrl(`/org/${orgArg.data.slug}/billing`);
|
|
}}
|
|
>
|
|
<dees-icon .icon=${'lucide:building2'} style="display: inline-block; transform: translateY(3px); padding-right: 8px;"></dees-icon> ${orgArg.data.name}
|
|
</div>
|
|
`;
|
|
})}
|
|
</div>
|
|
`,
|
|
viewHost
|
|
);
|
|
}
|
|
}
|
|
}
|