diff --git a/packages/server/src/api/controllers/OneClickDemo/OneClickDemoController.ts b/packages/server/src/api/controllers/OneClickDemo/OneClickDemoController.ts new file mode 100644 index 000000000..b2812fbec --- /dev/null +++ b/packages/server/src/api/controllers/OneClickDemo/OneClickDemoController.ts @@ -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); + } + } +} diff --git a/packages/server/src/interfaces/Authentication.ts b/packages/server/src/interfaces/Authentication.ts index af29d0b5f..2743ee513 100644 --- a/packages/server/src/interfaces/Authentication.ts +++ b/packages/server/src/interfaces/Authentication.ts @@ -7,7 +7,6 @@ export interface IRegisterDTO { lastName: string; email: string; password: string; - organizationName: string; } export interface ILoginDTO { diff --git a/packages/server/src/services/OneClickDemo/CreateOneClickDemo.ts b/packages/server/src/services/OneClickDemo/CreateOneClickDemo.ts new file mode 100644 index 000000000..a29ed2560 --- /dev/null +++ b/packages/server/src/services/OneClickDemo/CreateOneClickDemo.ts @@ -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} + */ + async createOneClickDemo(): Promise { + 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; +} diff --git a/packages/server/src/services/OneClickDemo/OneClickDemoApplication.ts b/packages/server/src/services/OneClickDemo/OneClickDemoApplication.ts new file mode 100644 index 000000000..9465827f3 --- /dev/null +++ b/packages/server/src/services/OneClickDemo/OneClickDemoApplication.ts @@ -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(); + } +} \ No newline at end of file diff --git a/packages/webapp/src/components/App.tsx b/packages/webapp/src/components/App.tsx index 4f43a8613..ba148ba5b 100644 --- a/packages/webapp/src/components/App.tsx +++ b/packages/webapp/src/components/App.tsx @@ -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 }) { + + + diff --git a/packages/webapp/src/containers/OneClickDemo/OneClickDemoPage.tsx b/packages/webapp/src/containers/OneClickDemo/OneClickDemoPage.tsx new file mode 100644 index 000000000..620452f7d --- /dev/null +++ b/packages/webapp/src/containers/OneClickDemo/OneClickDemoPage.tsx @@ -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(''); + + 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 ( + + {running && (

Building...

)} + +
+ ); +} diff --git a/packages/webapp/src/hooks/query/oneclick-demo.ts b/packages/webapp/src/hooks/query/oneclick-demo.ts new file mode 100644 index 000000000..537729214 --- /dev/null +++ b/packages/webapp/src/hooks/query/oneclick-demo.ts @@ -0,0 +1,35 @@ +// @ts-nocheck +import { + useMutation, + UseMutationOptions, + UseMutationResult, + useQueryClient, +} from 'react-query'; +import useApiRequest from '../useRequest'; + +interface CreateOneClickDemoValues {} +interface CreateOneClickDemoRes {} + +/** + * + * @param {UseMutationOptions} props + * @returns {UseMutationResult} + */ +export function useCreateOneClickDemo( + props?: UseMutationOptions< + CreateOneClickDemoRes, + Error, + CreateOneClickDemoValues + >, +): UseMutationResult { + const queryClient = useQueryClient(); + const apiRequest = useApiRequest(); + + return useMutation( + () => apiRequest.post(`/demo/one_click`), + { + onSuccess: (res, id) => {}, + ...props, + }, + ); +}