import * as plugins from '../../plugins.js'; import { customElement, DeesElement, property, html, cssManager, css, state, type TemplateResult, } from '@design.estate/dees-element'; import { accountDesignTokens } from './sharedstyles.js'; import * as accountStateModule from '../../states/accountstate.js'; declare global { interface HTMLElementTagNameMap { 'idp-org-select-modal': OrgSelectModal; } } @customElement('idp-org-select-modal') export class OrgSelectModal extends DeesElement { @state() accessor visible: boolean = false; @state() accessor organizations: plugins.idpInterfaces.data.IOrganization[] = []; @state() accessor targetPath: string = ''; @state() accessor title: string = 'Select Organization'; @state() accessor description: string = 'Choose an organization to continue.'; public static styles = [ cssManager.defaultStyles, accountDesignTokens, css` :host { display: none; } :host([visible]) { display: block; } .overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.8); display: flex; align-items: center; justify-content: center; z-index: 1000; animation: fadeIn 0.15s ease; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } .modal { background: #18181b; border: 1px solid #27272a; border-radius: 16px; width: 100%; max-width: 420px; max-height: 90vh; overflow-y: auto; animation: slideIn 0.2s ease; } @keyframes slideIn { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } } .modal-header { padding: 20px 24px; border-bottom: 1px solid #27272a; } .modal-title { font-size: 18px; font-weight: 600; margin: 0 0 4px 0; color: #fafafa; } .modal-description { font-size: 14px; color: #71717a; margin: 0; } .modal-body { padding: 0; } .org-list { display: flex; flex-direction: column; } .org-item { display: flex; align-items: center; gap: 12px; padding: 14px 24px; border-bottom: 1px solid #27272a; cursor: pointer; transition: background 0.15s ease; } .org-item:last-child { border-bottom: none; } .org-item:hover { background: #27272a; } .org-icon { width: 40px; height: 40px; border-radius: 10px; background: #27272a; display: flex; align-items: center; justify-content: center; flex-shrink: 0; } .org-item:hover .org-icon { background: #3f3f46; } .org-icon dees-icon { opacity: 0.7; } .org-info { flex: 1; min-width: 0; } .org-name { font-size: 14px; font-weight: 600; margin-bottom: 2px; color: #fafafa; } .org-slug { font-size: 12px; color: #71717a; } .org-arrow { opacity: 0.5; } .empty-state { text-align: center; padding: 40px 24px; color: #71717a; } .empty-state dees-icon { font-size: 40px; opacity: 0.5; margin-bottom: 12px; } .empty-state p { margin: 0 0 16px 0; font-size: 14px; } .modal-footer { display: flex; justify-content: flex-end; gap: 12px; padding: 16px 24px; border-top: 1px solid #27272a; } `, ]; public render(): TemplateResult { if (!this.visible) { return html``; } return html`
`; } private renderOrgList(): TemplateResult { return html`
${this.organizations.map((org) => html`
this.handleSelectOrg(org)}>
${org.data.name}
${org.data.slug}
`)}
`; } private renderEmptyState(): TemplateResult { return html`

You don't have any organizations yet.

Create Organization
`; } public show(options: { targetPath: string; title?: string; description?: string; }) { this.targetPath = options.targetPath; this.title = options.title || 'Select Organization'; this.description = options.description || 'Choose an organization to continue.'; // Load organizations from state const state = accountStateModule.accountState.getState(); this.organizations = state.organizations; this.visible = true; this.setAttribute('visible', ''); } public hide() { this.visible = false; this.removeAttribute('visible'); } private handleOverlayClick(e: Event) { if ((e.target as HTMLElement).classList.contains('overlay')) { this.hide(); } } private handleCancel() { this.hide(); } private handleSelectOrg(org: plugins.idpInterfaces.data.IOrganization) { accountStateModule.accountState.dispatchAction(accountStateModule.setSelectedOrg, org); // Replace :orgName placeholder with actual slug const path = this.targetPath.replace(':orgName', org.data.slug); this.dispatchEvent(new CustomEvent('org-selected', { bubbles: true, composed: true, detail: { org, path }, })); this.hide(); } private handleCreateOrg() { this.hide(); this.dispatchEvent(new CustomEvent('open-create-org-modal', { bubbles: true, composed: true, })); } }