Organization Onboarding Workflow
This commit is contained in:
@@ -0,0 +1,263 @@
|
||||
import { Component, signal, inject } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { DataTable } from '../../../shared/components/data-table/data-table';
|
||||
import { DataTableColumn, DataTableRecord } from '../../../shared/components/data-table/data-table.types';
|
||||
|
||||
type OrganizationPlan = 'Enterprise' | 'Standard' | 'Trial';
|
||||
type OrganizationStatus = 'Active' | 'Trial' | 'Suspended';
|
||||
|
||||
interface DashboardStatCard {
|
||||
title: string;
|
||||
value: string;
|
||||
helper: string;
|
||||
accentClass: string;
|
||||
iconClass: string;
|
||||
iconBackgroundClass: string;
|
||||
helperClass: string;
|
||||
}
|
||||
|
||||
interface RecentOrganizationRow extends DataTableRecord {
|
||||
id: string;
|
||||
code: string;
|
||||
organizationName: string;
|
||||
country: string;
|
||||
plan: OrganizationPlan;
|
||||
status: OrganizationStatus;
|
||||
created: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'dashboard',
|
||||
standalone: true,
|
||||
imports: [DataTable],
|
||||
templateUrl: './dashboard.html',
|
||||
styleUrl: './dashboard.scss',
|
||||
})
|
||||
export class Dashboard {
|
||||
private readonly router = inject(Router);
|
||||
|
||||
readonly statCards = signal<DashboardStatCard[]>([
|
||||
{
|
||||
title: 'Total Organizations',
|
||||
value: '24',
|
||||
helper: 'All registered',
|
||||
accentClass: 'border-primary',
|
||||
iconClass: 'ti ti-building-community',
|
||||
iconBackgroundClass: 'bg-primary',
|
||||
helperClass: 'bg-primary/10 text-primary',
|
||||
},
|
||||
{
|
||||
title: 'Active',
|
||||
value: '19',
|
||||
helper: 'Currently operational',
|
||||
accentClass: 'border-primary',
|
||||
iconClass: 'ti ti-circle-check',
|
||||
iconBackgroundClass: 'bg-primary',
|
||||
helperClass: 'bg-primary/10 text-primary',
|
||||
},
|
||||
{
|
||||
title: 'Trial',
|
||||
value: '3',
|
||||
helper: 'Trial subscriptions',
|
||||
accentClass: 'border-primary',
|
||||
iconClass: 'ri-wallet-2-line',
|
||||
iconBackgroundClass: 'bg-primary',
|
||||
helperClass: 'bg-primary/10 text-primary',
|
||||
},
|
||||
{
|
||||
title: 'Suspended',
|
||||
value: '1',
|
||||
helper: 'Temporarily disabled',
|
||||
accentClass: 'border-primary',
|
||||
iconClass: 'ti ti-player-pause',
|
||||
iconBackgroundClass: 'bg-primary',
|
||||
helperClass: 'bg-primary/10 text-primary',
|
||||
},
|
||||
{
|
||||
title: 'Expired License',
|
||||
value: '1',
|
||||
helper: 'Needs renewal action',
|
||||
accentClass: 'border-primary',
|
||||
iconClass: 'ti ti-license',
|
||||
iconBackgroundClass: 'bg-primary',
|
||||
helperClass: 'bg-primary/10 text-primary',
|
||||
},
|
||||
{
|
||||
title: 'Active Users',
|
||||
value: '482',
|
||||
helper: 'Users with access',
|
||||
accentClass: 'border-primary',
|
||||
iconClass: 'ri-profile-line',
|
||||
iconBackgroundClass: 'bg-primary',
|
||||
helperClass: 'bg-primary/10 text-primary',
|
||||
},
|
||||
]);
|
||||
|
||||
readonly recentOrganizations = signal<RecentOrganizationRow[]>([
|
||||
{
|
||||
id: '1',
|
||||
code: 'ORG-0024',
|
||||
organizationName: 'Syscom Group',
|
||||
country: 'Saudi Arabia',
|
||||
plan: 'Enterprise',
|
||||
status: 'Active',
|
||||
created: '09-07-2026',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
code: 'ORG-0023',
|
||||
organizationName: 'Acme Trading',
|
||||
country: 'India',
|
||||
plan: 'Standard',
|
||||
status: 'Active',
|
||||
created: '01-07-2026',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
code: 'ORG-0022',
|
||||
organizationName: 'Falcon Retail LLC',
|
||||
country: 'UAE',
|
||||
plan: 'Trial',
|
||||
status: 'Trial',
|
||||
created: '28-06-2026',
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
code: 'ORG-0025',
|
||||
organizationName: 'Syscom Group',
|
||||
country: 'Saudi Arabia',
|
||||
plan: 'Enterprise',
|
||||
status: 'Active',
|
||||
created: '09-07-2026',
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
code: 'ORG-0026',
|
||||
organizationName: 'Acme Trading',
|
||||
country: 'India',
|
||||
plan: 'Standard',
|
||||
status: 'Active',
|
||||
created: '01-07-2026',
|
||||
},
|
||||
{
|
||||
id: '6',
|
||||
code: 'ORG-0027',
|
||||
organizationName: 'Falcon Retail LLC',
|
||||
country: 'UAE',
|
||||
plan: 'Trial',
|
||||
status: 'Trial',
|
||||
created: '28-06-2026',
|
||||
},
|
||||
{
|
||||
id: '7',
|
||||
code: 'ORG-0028',
|
||||
organizationName: 'Syscom Group',
|
||||
country: 'Saudi Arabia',
|
||||
plan: 'Enterprise',
|
||||
status: 'Active',
|
||||
created: '09-07-2026',
|
||||
},
|
||||
{
|
||||
id: '8',
|
||||
code: 'ORG-0029',
|
||||
organizationName: 'Acme Trading',
|
||||
country: 'India',
|
||||
plan: 'Standard',
|
||||
status: 'Active',
|
||||
created: '01-07-2026',
|
||||
},
|
||||
{
|
||||
id: '9',
|
||||
code: 'ORG-0030',
|
||||
organizationName: 'Falcon Retail LLC',
|
||||
country: 'UAE',
|
||||
plan: 'Trial',
|
||||
status: 'Trial',
|
||||
created: '28-06-2026',
|
||||
},
|
||||
]);
|
||||
|
||||
readonly columns = signal<DataTableColumn<RecentOrganizationRow>[]>([
|
||||
{ key: 'code', label: 'Code', header: 'Code', sortable: false, align: 'left' },
|
||||
{
|
||||
key: 'organizationName',
|
||||
label: 'Name',
|
||||
header: 'Name',
|
||||
sortable: true,
|
||||
align: 'left',
|
||||
},
|
||||
{ key: 'country', label: 'Country', header: 'Country', sortable: false },
|
||||
{
|
||||
key: 'plan',
|
||||
label: 'Plan',
|
||||
header: 'Plan',
|
||||
sortable: true,
|
||||
badge: true,
|
||||
badgeClass: value =>
|
||||
value === 'Trial'
|
||||
? 'badge bg-warning/10 text-warning'
|
||||
: 'badge bg-light text-defaulttextcolor',
|
||||
},
|
||||
{
|
||||
key: 'status',
|
||||
label: 'Status',
|
||||
header: 'Status',
|
||||
sortable: true,
|
||||
badge: true,
|
||||
badgeClass: value =>
|
||||
value === 'Active'
|
||||
? 'badge bg-success/10 text-success'
|
||||
: value === 'Trial'
|
||||
? 'badge bg-warning/10 text-warning'
|
||||
: 'badge bg-danger/10 text-danger',
|
||||
},
|
||||
{ key: 'created', label: 'Created', header: 'Created', sortable: false },
|
||||
]);
|
||||
|
||||
readonly totalRecords = signal<number>(6);
|
||||
readonly queryState = {
|
||||
pageIndex: signal<number>(0)
|
||||
};
|
||||
readonly emptyMessage = signal<string>('No Organizations');
|
||||
readonly emptyDescription = signal<string>('Start by adding your first organization');
|
||||
|
||||
readonly actions = signal<any[]>([
|
||||
{ id: 'edit', label: 'Edit', icon: 'ti ti-edit' },
|
||||
{ id: 'delete', label: 'Delete', icon: 'ti ti-trash' },
|
||||
]);
|
||||
|
||||
onAddOrganization(): void {
|
||||
void this.router.navigate(['/organizations/onboarding']);
|
||||
}
|
||||
|
||||
onSearch(searchTerm: string) {
|
||||
console.log('Search:', searchTerm);
|
||||
}
|
||||
|
||||
onPageChange(event: any) {
|
||||
console.log('Page changed:', event);
|
||||
}
|
||||
|
||||
onSortChange(event: any) {
|
||||
console.log('Sort changed:', event);
|
||||
}
|
||||
|
||||
onActionClick(event: any) {
|
||||
const { actionId, record } = event;
|
||||
|
||||
switch (actionId) {
|
||||
case 'edit':
|
||||
console.log('Edit organization:', record);
|
||||
// Implement edit logic here
|
||||
break;
|
||||
case 'delete':
|
||||
console.log('Delete organization:', record);
|
||||
// Implement delete logic here
|
||||
break;
|
||||
default:
|
||||
console.log('Unknown action:', actionId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user