feat(ee): one-click demo account

This commit is contained in:
Ahmed Bouhuolia
2024-08-19 12:08:58 +02:00
parent 25297bc191
commit a008aea3f3
7 changed files with 192 additions and 2 deletions

View File

@@ -0,0 +1,41 @@
import { Router, Request, Response, NextFunction } from 'express';
import { Service, Inject } from 'typedi';
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
import BaseController from '@/api/controllers/BaseController';
import { OneClickDemoApplication } from '@/services/OneClickDemo/OneClickDemoApplication';
@Service()
export class OneClickDemoController extends BaseController {
@Inject()
private oneClickDemoApp: OneClickDemoApplication;
/**
* Router constructor method.
*/
router() {
const router = Router();
router.post('/one_click', asyncMiddleware(this.oneClickDemo.bind(this)));
return router;
}
/**
* One-click demo application.
* @param {Request} req -
* @param {Response} res -
* @param {NextFunction} next -
*/
private async oneClickDemo(req: Request, res: Response, next: NextFunction) {
try {
const data = await this.oneClickDemoApp.createOneClick();
return res.status(200).send({
data,
message: 'The one-click demo has been created successfully.',
});
} catch (error) {
next(error);
}
}
}

View File

@@ -7,7 +7,6 @@ export interface IRegisterDTO {
lastName: string;
email: string;
password: string;
organizationName: string;
}
export interface ILoginDTO {

View File

@@ -0,0 +1,57 @@
import { Inject, Service } from 'typedi';
import { faker } from '@faker-js/faker';
import AuthenticationApplication from '../Authentication/AuthApplication';
import OrganizationService from '../Organization/OrganizationService';
import { IAuthSignInPOJO } from '@/interfaces';
@Service()
export class CreateOneClickDemo {
@Inject()
private authApp: AuthenticationApplication;
@Inject()
private organizationService: OrganizationService;
/**
* Creates one-click demo account.
* @returns {Promise<ICreateOneClickDemoPOJO>}
*/
async createOneClickDemo(): Promise<ICreateOneClickDemoPOJO> {
const firstName = faker.person.firstName();
const lastName = faker.person.lastName();
const email = faker.internet.email();
const password = '123123123';
await this.authApp.signUp({ firstName, lastName, email, password });
//
const signedIn = await this.authApp.signIn(email, password);
const tenantId = signedIn.tenant.id;
const buildJob = await this.organizationService.buildRunJob(
tenantId,
{
name: 'BIGCAPITAL, INC',
base_currency: 'USD',
location: 'US',
language: 'en',
fiscal_year: 'march',
timezone: 'US/Central',
},
signedIn.user
);
return { email, signedIn, buildJob };
}
/**
* Sign-in automicatlly using the demo id one creating an account finish.
* @param {string} oneClickDemoId -
*/
async autoSignIn(oneClickDemoId: string) {}
}
interface ICreateOneClickDemoPOJO {
email: string;
signedIn: IAuthSignInPOJO;
buildJob: any;
}

View File

@@ -0,0 +1,14 @@
import { Inject, Service } from "typedi";
import { CreateOneClickDemo } from "./CreateOneClickDemo";
@Service()
export class OneClickDemoApplication {
@Inject()
private createOneClickDemoService: CreateOneClickDemo;
public createOneClick() {
return this.createOneClickDemoService.createOneClickDemo();
}
}

View File

@@ -27,7 +27,9 @@ const EmailConfirmation = LazyLoader({
const RegisterVerify = LazyLoader({
loader: () => import('@/containers/Authentication/RegisterVerify'),
});
const OneClickDemoPage = LazyLoader({
loader: () => import('@/containers/OneClickDemo/OneClickDemoPage'),
});
/**
* App inner.
*/
@@ -37,6 +39,9 @@ function AppInsider({ history }) {
<DashboardThemeProvider>
<Router history={history}>
<Switch>
<Route path={'/one_click_demo'}>
<OneClickDemoPage />
</Route>
<Route path={'/auth/register/verify'}>
<EnsureAuthenticated>
<EnsureUserEmailNotVerified>

View File

@@ -0,0 +1,39 @@
// @ts-nocheck
import { useEffect, useState } from 'react';
import { Box } from '@/components';
import { useCreateOneClickDemo } from '@/hooks/query/oneclick-demo';
import { Button } from '@blueprintjs/core';
import { useJob } from '@/hooks/query';
export default function OneClickDemoPage() {
const { mutateAsync: createOneClickDemo } = useCreateOneClickDemo();
const [buildJobId, setBuildJobId] = useState<string>('');
const {
data: { running, queued, failed, completed },
isFetching: isJobFetching,
} = useJob(buildJobId, {
refetchInterval: 2000,
enabled: !!buildJobId,
});
useEffect(() => {
if (completed) {
}
}, [completed]);
const handleCreateAccountBtnClick = () => {
createOneClickDemo({})
.then((res) => {
setBuildJobId(res?.data?.data?.build_job?.job_id)
})
.catch(() => {});
};
return (
<Box>
{running && (<h1>Building...</h1>)}
<Button onClick={handleCreateAccountBtnClick}>One-Click Create</Button>
</Box>
);
}

View File

@@ -0,0 +1,35 @@
// @ts-nocheck
import {
useMutation,
UseMutationOptions,
UseMutationResult,
useQueryClient,
} from 'react-query';
import useApiRequest from '../useRequest';
interface CreateOneClickDemoValues {}
interface CreateOneClickDemoRes {}
/**
*
* @param {UseMutationOptions<CreateOneClickDemoRes, Error, CreateOneClickDemoValues>} props
* @returns {UseMutationResult<CreateOneClickDemoRes, Error, CreateOneClickDemoValues>}
*/
export function useCreateOneClickDemo(
props?: UseMutationOptions<
CreateOneClickDemoRes,
Error,
CreateOneClickDemoValues
>,
): UseMutationResult<CreateOneClickDemoRes, Error, CreateOneClickDemoValues> {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation<CreateOneClickDemoRes, Error, CreateOneClickDemoValues>(
() => apiRequest.post(`/demo/one_click`),
{
onSuccess: (res, id) => {},
...props,
},
);
}