feat(ui) - funnels - wip

This commit is contained in:
Shekar Siri 2022-04-20 18:05:10 +02:00
parent bf509a374d
commit 45e39c8749
6 changed files with 230 additions and 1 deletions

View file

@ -0,0 +1,90 @@
import { makeAutoObservable, runInAction, observable, action, reaction } from "mobx"
import { funnelService } from "App/services"
import Funnel, { IFunnel } from "./types/funnel";
import Period, { LAST_7_DAYS } from 'Types/app/period';
export default class FunnelStore {
isLoading: boolean = false
isSaving: boolean = false
list: IFunnel[] = []
instance: IFunnel | null = null
period: Period = Period({ rangeName: LAST_7_DAYS })
constructor() {
makeAutoObservable(this, {
fetchFunnels: action,
fetchFunnel: action,
saveFunnel: action,
deleteFunnel: action
})
}
fetchFunnels(): Promise<any> {
this.isLoading = true
return new Promise((resolve, reject) => {
funnelService.all()
.then(response => {
this.list = response
resolve(response)
}).catch(error => {
reject(error)
}).finally(() => {
this.isLoading = false
}
)
})
}
fetchFunnel(funnelId: string): Promise<any> {
this.isLoading = true
return new Promise((resolve, reject) => {
funnelService.one(funnelId)
.then(response => {
const _funnel = new Funnel().fromJSON(response)
this.instance = _funnel
resolve(_funnel)
}).catch(error => {
reject(error)
}).finally(() => {
this.isLoading = false
}
)
})
}
saveFunnel(funnel: IFunnel): Promise<any> {
this.isSaving = true
const wasCreating = !funnel.funnelId
return new Promise((resolve, reject) => {
funnelService.save(funnel)
.then(response => {
const _funnel = new Funnel().fromJSON(response)
if (wasCreating) {
this.list.push(_funnel)
}
resolve(_funnel)
}).catch(error => {
reject(error)
}).finally(() => {
this.isSaving = false
}
)
})
}
deleteFunnel(funnelId: string): Promise<any> {
this.isSaving = true
return new Promise((resolve, reject) => {
funnelService.delete(funnelId)
.then(response => {
this.list = this.list.filter(funnel => funnel.funnelId !== funnelId)
resolve(funnelId)
}).catch(error => {
reject(error)
}).finally(() => {
this.isSaving = false
}
)
})
}
}

View file

@ -0,0 +1,45 @@
import Filter, { IFilter } from "./filter"
export interface IFunnel {
funnelId: string
name: string
filter: IFilter
sessionsCount: number
conversionRate: number
totalConversations: number
lostConversations: number
fromJSON: (json: any) => void
toJSON: () => any
}
export default class Funnel implements IFunnel {
funnelId: string = ''
name: string = ''
filter: IFilter = new Filter()
sessionsCount: number = 0
conversionRate: number = 0
totalConversations: number = 0
lostConversations: number = 0
constructor() {
}
fromJSON(json: any) {
this.funnelId = json.funnelId
this.name = json.name
this.filter = new Filter().fromJson(json.filter)
this.sessionsCount = json.sessionsCount
this.conversionRate = json.conversionRate
return this
}
toJSON(): any {
return {
funnelId: this.funnelId,
name: this.name,
filter: this.filter.toJson(),
sessionsCount: this.sessionsCount,
conversionRate: this.conversionRate,
}
}
}

View file

@ -0,0 +1,18 @@
export default class FunnelStage {
dropDueToIssues: number = 0;
dropPct: number = 0;
operator: string = "";
sessionsCount: number = 0;
usersCount: number = 0;
value: string[] = [];
fromJSON(json: any) {
this.dropDueToIssues = json.dropDueToIssues;
this.dropPct = json.dropPct;
this.operator = json.operator;
this.sessionsCount = json.sessionsCount;
this.usersCount = json.usersCount;
this.value = json.value;
return this;
}
}

View file

@ -0,0 +1,12 @@
import FunnelStage from "./funnelStage";
export default class FunnelInsights {
stages: FunnelStage[] = [];
totalDropDueToIssues: number = 0;
fromJSON(json: any) {
this.stages = json.stages.map(stage => new FunnelStage().fromJSON(stage));
this.totalDropDueToIssues = json.totalDropDueToIssues;
return this;
}
}

View file

@ -0,0 +1,62 @@
import { IFunnel } from "App/mstore/types/funnel"
import APIClient from 'App/api_client';
export interface IFunnelService {
initClient(client?: APIClient)
all(): Promise<any[]>
one(funnelId: string): Promise<any>
save(funnel: IFunnel): Promise<any>
delete(funnelId: string): Promise<any>
fetchInsights(funnelId: string, payload: any): Promise<any>
fetchIssues(funnelId: string, payload: any): Promise<any>
fetchIssue(funnelId: string, issueId: string): Promise<any>
}
export default class FunnelService implements IFunnelService {
private client: APIClient;
constructor(client?: APIClient) {
this.client = client ? client : new APIClient();
}
initClient(client?: APIClient) {
this.client = client || new APIClient();
}
all(): Promise<any[]> {
return this.client.get('/funnels')
.then(response => response.json())
.then(response => response.data || []);
}
one(funnelId: string): Promise<any> {
return this.client.get(`/funnels/${funnelId}`)
.then(response => response.json())
}
save(funnel: IFunnel): Promise<any> {
return this.client.post('/funnels', funnel)
.then(response => response.json())
}
delete(funnelId: string): Promise<any> {
return this.client.delete(`/funnels/${funnelId}`)
.then(response => response.json())
}
fetchInsights(funnelId: string, payload: any): Promise<any> {
return this.client.post(`/funnels/${funnelId}/insights`, payload)
.then(response => response.json())
}
fetchIssues(funnelId: string, payload: any): Promise<any> {
return this.client.post(`/funnels/${funnelId}/issues`, payload)
.then(response => response.json())
}
fetchIssue(funnelId: string, issueId: string): Promise<any> {
return this.client.get(`/funnels/${funnelId}/issues/${issueId}`)
.then(response => response.json())
}
}

View file

@ -1,5 +1,7 @@
import DashboardService, { IDashboardService } from "./DashboardService";
import MetricService, { IMetricService } from "./MetricService";
import FunnelService, { IFunnelService } from "./FunnelService";
export const dashboardService: IDashboardService = new DashboardService();
export const metricService: IMetricService = new MetricService();
export const metricService: IMetricService = new MetricService();
export const funnelService: IFunnelService = new FunnelService();