diff --git a/frontend/app/components/Funnels/FunnelItem/FunnelItem.tsx b/frontend/app/components/Funnels/FunnelItem/FunnelItem.tsx index 1125eecbd..2c0793745 100644 --- a/frontend/app/components/Funnels/FunnelItem/FunnelItem.tsx +++ b/frontend/app/components/Funnels/FunnelItem/FunnelItem.tsx @@ -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 ( -
- +
+
+
+ +
+ {funnel.name} +
+
{funnel.name}
+
{funnel.name}
); } diff --git a/frontend/app/components/Funnels/FunnelList/FunnelList.tsx b/frontend/app/components/Funnels/FunnelList/FunnelList.tsx index d14efe93f..b73b643c2 100644 --- a/frontend/app/components/Funnels/FunnelList/FunnelList.tsx +++ b/frontend/app/components/Funnels/FunnelList/FunnelList.tsx @@ -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 ( -
-
here
- {list.map(funnel => ( -
-

{funnel.name}

+ +
+ + +
+ +
Funnels make it easy to uncover the most significant issues that impacted conversions.
+ +
+
+
+ Title +
+
Owner
+
Last Modified
- ))} -
+ + {sliceListPerPage(list, funnelStore.page - 1, funnelStore.pageSize).map((funnel: any) => ( + + ))} +
+ +
+ funnelStore.updateKey('page', page)} + limit={funnelStore.pageSize} + debounceRequest={100} + /> +
+ ); } diff --git a/frontend/app/components/Funnels/FunnelPage/FunnelPage.tsx b/frontend/app/components/Funnels/FunnelPage/FunnelPage.tsx index c26c4be08..f4b3da812 100644 --- a/frontend/app/components/Funnels/FunnelPage/FunnelPage.tsx +++ b/frontend/app/components/Funnels/FunnelPage/FunnelPage.tsx @@ -4,7 +4,7 @@ import FunnelList from '../FunnelList'; function FunnelPage(props) { return ( -
+
diff --git a/frontend/app/components/ui/PageTitle/PageTitle.tsx b/frontend/app/components/ui/PageTitle/PageTitle.tsx index 6ee102c0d..1d94bdf3c 100644 --- a/frontend/app/components/ui/PageTitle/PageTitle.tsx +++ b/frontend/app/components/ui/PageTitle/PageTitle.tsx @@ -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 (

{title} diff --git a/frontend/app/mstore/funnelStore.ts b/frontend/app/mstore/funnelStore.ts index cd43065b3..721adeb6b 100644 --- a/frontend/app/mstore/funnelStore.ts +++ b/frontend/app/mstore/funnelStore.ts @@ -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 { this.isLoading = true return new Promise((resolve, reject) => { diff --git a/frontend/app/mstore/types/funnel.ts b/frontend/app/mstore/types/funnel.ts index 058587a66..95c95e5c4 100644 --- a/frontend/app/mstore/types/funnel.ts +++ b/frontend/app/mstore/types/funnel.ts @@ -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() { } diff --git a/frontend/app/styles/general.css b/frontend/app/styles/general.css index 7e99468ad..ecd424721 100644 --- a/frontend/app/styles/general.css +++ b/frontend/app/styles/general.css @@ -255,6 +255,7 @@ p { .link { color: $blue !important; + cursor: pointer; &:hover { text-decoration: underline !important; } diff --git a/frontend/app/svg/icons/funnel-fill.svg b/frontend/app/svg/icons/funnel-fill.svg new file mode 100644 index 000000000..5f16f16ae --- /dev/null +++ b/frontend/app/svg/icons/funnel-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/frontend/app/theme/colors.js b/frontend/app/theme/colors.js index 07aca3a8b..963c71eec 100644 --- a/frontend/app/theme/colors.js +++ b/frontend/app/theme/colors.js @@ -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",