feat(account): Implement account and organization management features
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
import { IdpState } from './idp.state.js';
|
||||
|
||||
export type TStateTypes = 'IAccountState';
|
||||
export interface IAccountState {
|
||||
user: plugins.idpInterfaces.data.IUser;
|
||||
/**
|
||||
* the available orgs
|
||||
*/
|
||||
organizations: Array<plugins.idpInterfaces.data.IOrganization>;
|
||||
roles: Array<plugins.idpInterfaces.data.IRole>
|
||||
|
||||
selectedOrg: plugins.idpInterfaces.data.IOrganization;
|
||||
selectedOrgBillingPlan: plugins.tsclass.typeFest.PartialDeep<plugins.idpInterfaces.data.IBillingPlan>;
|
||||
|
||||
/**
|
||||
* used for keeping the state when creating a new org
|
||||
*/
|
||||
newOrg: {
|
||||
chosenName: string;
|
||||
chosenSlug: string;
|
||||
validated: boolean;
|
||||
validationOk: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
const smartStateInstance = new plugins.deesDomtools.plugins.smartstate.Smartstate<TStateTypes>();
|
||||
export const accountState = await smartStateInstance.getStatePart<IAccountState>('IAccountState', {
|
||||
user: null,
|
||||
organizations: [],
|
||||
roles: [],
|
||||
selectedOrg: null,
|
||||
selectedOrgBillingPlan: null,
|
||||
newOrg: {
|
||||
chosenName: null,
|
||||
chosenSlug: null,
|
||||
validated: null,
|
||||
validationOk: null,
|
||||
},
|
||||
});
|
||||
|
||||
export const getOrganizationsAction = accountState.createAction<void>(
|
||||
async (statePartArg, payloadArg) => {
|
||||
const idpState = await IdpState.getSingletonInstance();
|
||||
const currentState = statePartArg.getState();
|
||||
const response = await idpState.idpClient.getRolesAndOrganizations();
|
||||
currentState.organizations = response.organizations;
|
||||
currentState.roles = response.roles;
|
||||
return currentState;
|
||||
}
|
||||
);
|
||||
|
||||
export const setNewOrgName = accountState.createAction<string>(async (statePartArg, payloadArg) => {
|
||||
const idpState = await IdpState.getSingletonInstance();
|
||||
const currentState = statePartArg.getState();
|
||||
currentState.newOrg.chosenName = payloadArg;
|
||||
currentState.newOrg.chosenSlug = payloadArg
|
||||
.replace(/[^a-zA-Z0-9]/g, '-')
|
||||
.replace(/\s/g, '-')
|
||||
.toLowerCase();
|
||||
const result = await idpState.idpClient.createOrganization(
|
||||
currentState.newOrg.chosenName,
|
||||
currentState.newOrg.chosenSlug,
|
||||
'checkAvailability'
|
||||
);
|
||||
console.log(result);
|
||||
currentState.newOrg.validated = true;
|
||||
currentState.newOrg.validationOk = result.nameAvailable;
|
||||
if (payloadArg === '') {
|
||||
currentState.newOrg.validated = false;
|
||||
currentState.newOrg.validationOk = false;
|
||||
}
|
||||
return currentState;
|
||||
});
|
||||
|
||||
export const manifestNewOrgName = accountState.createAction(async (statePartArg, payloadArg) => {
|
||||
const idpState = await IdpState.getSingletonInstance();
|
||||
const currentState: IAccountState = statePartArg.getState();
|
||||
const result = await idpState.idpClient.createOrganization(
|
||||
currentState.newOrg.chosenName,
|
||||
currentState.newOrg.chosenSlug,
|
||||
'manifest'
|
||||
);
|
||||
currentState.organizations.push(result.resultingOrganization);
|
||||
currentState.selectedOrg = result.resultingOrganization;
|
||||
return currentState;
|
||||
});
|
||||
|
||||
export const setSelectedOrg = accountState.createAction<plugins.idpInterfaces.data.IOrganization>(async (statePartArg, payloadArg) => {
|
||||
const currentState = statePartArg.getState();
|
||||
currentState.selectedOrg = payloadArg;
|
||||
return currentState;
|
||||
})
|
||||
|
||||
export const updatePaddleCheckoutId = accountState.createAction<string>(async (statePartArg, checkoutIdArg) => {
|
||||
const idpState = await IdpState.getSingletonInstance();
|
||||
const currentState: IAccountState = statePartArg.getState();
|
||||
const response = await idpState.idpClient.updatePaddleCheckoutId(currentState.selectedOrg.id, checkoutIdArg);
|
||||
currentState.selectedOrgBillingPlan = response.billingPlan;
|
||||
return currentState;
|
||||
});
|
||||
@@ -0,0 +1,70 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
import { domtools } from '@design.estate/dees-element'
|
||||
|
||||
export class IdpState {
|
||||
// STATIC
|
||||
private static idpStateDeferred = plugins.smartpromise.defer<IdpState>();
|
||||
public static async getSingletonInstance() {
|
||||
if (!this.idpStateDeferred.claimed) {
|
||||
this.idpStateDeferred.claim();
|
||||
const newIdpState = new IdpState();
|
||||
await newIdpState.init();
|
||||
this.idpStateDeferred.resolve(newIdpState);
|
||||
}
|
||||
return this.idpStateDeferred.promise;
|
||||
}
|
||||
|
||||
// INSTANCE
|
||||
public receptionUrl = window.location.origin;
|
||||
public idpClient = new plugins.idpClient.IdpClient(this.receptionUrl);
|
||||
public domtools: domtools.DomTools;
|
||||
public mainStatePart: plugins.deesDomtools.plugins.smartstate.StatePart<'main', {
|
||||
view: 'welcome' | 'login' | 'register' | 'finishregistration' | 'account';
|
||||
}>
|
||||
|
||||
public async init() {
|
||||
this.idpClient.enableTypedSocket();
|
||||
const domtoolsInstance = await domtools.DomTools.setupDomTools();
|
||||
this.domtools = domtoolsInstance;
|
||||
const state = new plugins.deesDomtools.plugins.smartstate.Smartstate<'main'>();
|
||||
this.mainStatePart = await state.getStatePart('main', {
|
||||
view: 'welcome',
|
||||
}, 'soft');
|
||||
this.domtools.router.on('/', async () => {
|
||||
await this.mainStatePart.setState({
|
||||
...this.mainStatePart.getState(),
|
||||
view: 'welcome',
|
||||
})
|
||||
});
|
||||
|
||||
this.domtools.router.on('/login', async () => {
|
||||
await this.mainStatePart.setState({
|
||||
...this.mainStatePart.getState(),
|
||||
view: 'login',
|
||||
})
|
||||
});
|
||||
|
||||
this.domtools.router.on('/register', async () => {
|
||||
await this.mainStatePart.setState({
|
||||
...this.mainStatePart.getState(),
|
||||
view: 'register',
|
||||
})
|
||||
});
|
||||
|
||||
this.domtools.router.on('/finishregistration', async () => {
|
||||
await this.mainStatePart.setState({
|
||||
...this.mainStatePart.getState(),
|
||||
view: 'finishregistration',
|
||||
})
|
||||
});
|
||||
|
||||
this.domtools.router.on('/account{/*path}', async () => {
|
||||
await this.mainStatePart.setState({
|
||||
...this.mainStatePart.getState(),
|
||||
view: 'account',
|
||||
})
|
||||
});
|
||||
|
||||
this.domtools.router._handleRouteState();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user