feat(ui) - funnels listing

This commit is contained in:
Shekar Siri 2022-04-22 14:47:38 +02:00
parent a287a9ca47
commit 4907c1b26c
9 changed files with 69 additions and 11 deletions

View file

@ -1,13 +1,22 @@
import { IFunnel } from 'App/mstore/types/funnel';
import React from 'react';
import { Icon } from 'UI';
interface Props {
funnel: IFunnel
}
function FunnelItem(props: Props) {
const { funnel } = props;
return (
<div>
<div className="grid grid-cols-12 p-3 border-t select-none items-center">
<div className="col-span-4 flex items-center">
<div className="bg-tealx-lightest w-8 h-8 rounded-full flex items-center justify-center" style={{ backgroundColor: 'rgba()'}}>
<Icon name={funnel.isPublic ? 'user-friends' : 'person-fill'} color="tealx" />
</div>
<span className="ml-2 link">{funnel.name}</span>
</div>
<div className="col-span-3">{funnel.name}</div>
<div className="col-span-3">{funnel.name}</div>
</div>
);
}

View file

@ -1,10 +1,14 @@
import { PageTitle, Button, Pagination, Icon, Loader } from 'UI';
import { useStore } from 'App/mstore';
import { useObserver } from 'mobx-react-lite';
import React, { useEffect } from 'react';
import { sliceListPerPage } from 'App/utils';
import FunnelItem from '../FunnelItem/FunnelItem';
function FunnelList(props) {
const { funnelStore } = useStore()
const list = useObserver(() => funnelStore.list)
const loading = useObserver(() => funnelStore.isLoading)
useEffect(() => {
if (list.length === 0) {
@ -13,14 +17,38 @@ function FunnelList(props) {
}, [])
return (
<div>
<div>here</div>
{list.map(funnel => (
<div key={funnel.funnelId}>
<h1>{funnel.name}</h1>
<Loader loading={loading}>
<div className="flex items-center">
<PageTitle title='Funnels' className="mr-3" />
<Button primary size="small" onClick={() => {}}>New Funnel</Button>
</div>
<div className="color-gray-medium mt-2 mb-4">Funnels make it easy to uncover the most significant issues that impacted conversions.</div>
<div className="mt-3 border rounded bg-white">
<div className="grid grid-cols-12 p-3 font-medium">
<div className="col-span-4 flex items-center">
<Icon name="funnel-fill"/> <span className="ml-2">Title</span>
</div>
<div className="col-span-3">Owner</div>
<div className="col-span-3">Last Modified</div>
</div>
))}
</div>
{sliceListPerPage(list, funnelStore.page - 1, funnelStore.pageSize).map((funnel: any) => (
<FunnelItem funnel={funnel} />
))}
</div>
<div className="w-full flex items-center justify-center py-8">
<Pagination
page={funnelStore.page}
totalPages={Math.ceil(list.length / funnelStore.pageSize)}
onPageChange={(page) => funnelStore.updateKey('page', page)}
limit={funnelStore.pageSize}
debounceRequest={100}
/>
</div>
</Loader>
);
}

View file

@ -4,7 +4,7 @@ import FunnelList from '../FunnelList';
function FunnelPage(props) {
return (
<div className="page-margin container-90">
<div className="page-margin container-70">
<Switch>
<Route path="/">
<FunnelList />

View file

@ -1,7 +1,12 @@
import React from 'react';
import cn from 'classnames';
function PageTitle({ title, className = '' }) {
interface Props {
title: string;
className?: string;
}
function PageTitle(props: Props) {
const { title, className = '' } = props;
return (
<h1 className={cn("text-2xl", className)}>
{title}

View file

@ -9,9 +9,13 @@ export default class FunnelStore {
list: IFunnel[] = []
instance: IFunnel | null = null
period: Period = Period({ rangeName: LAST_7_DAYS })
page: number = 1
pageSize: number = 10
constructor() {
makeAutoObservable(this, {
updateKey: action,
fetchFunnels: action,
fetchFunnel: action,
saveFunnel: action,
@ -19,6 +23,10 @@ export default class FunnelStore {
})
}
updateKey(key: string, value: any) {
this[key] = value
}
fetchFunnels(): Promise<any> {
this.isLoading = true
return new Promise((resolve, reject) => {

View file

@ -8,6 +8,7 @@ export interface IFunnel {
conversionRate: number
totalConversations: number
lostConversations: number
isPublic: boolean
fromJSON: (json: any) => void
toJSON: () => any
}
@ -20,6 +21,7 @@ export default class Funnel implements IFunnel {
conversionRate: number = 0
totalConversations: number = 0
lostConversations: number = 0
isPublic: boolean = false
constructor() {
}

View file

@ -255,6 +255,7 @@ p {
.link {
color: $blue !important;
cursor: pointer;
&:hover {
text-decoration: underline !important;
}

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-funnel-fill" viewBox="0 0 16 16">
<path d="M1.5 1.5A.5.5 0 0 1 2 1h12a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.128.334L10 8.692V13.5a.5.5 0 0 1-.342.474l-3 1A.5.5 0 0 1 6 14.5V8.692L1.628 3.834A.5.5 0 0 1 1.5 3.5v-2z"/>
</svg>

After

Width:  |  Height:  |  Size: 313 B

View file

@ -16,6 +16,8 @@ module.exports = {
"tealx-light": "#E2F0EE",
"tealx-light-border": "#C6DCDA",
"tealx-lightest": 'rgba(62, 170, 175, 0.1)',
orange: "#E28940",
yellow: "#FFFBE5",
yellow2: "#F5A623",