diff --git a/src/apps/explorer/components/SummaryCardsWidget/SummaryCards.tsx b/src/apps/explorer/components/SummaryCardsWidget/SummaryCards.tsx
new file mode 100644
index 000000000..447aed6ce
--- /dev/null
+++ b/src/apps/explorer/components/SummaryCardsWidget/SummaryCards.tsx
@@ -0,0 +1,97 @@
+import React from 'react'
+import styled from 'styled-components'
+import { media } from 'theme/styles/media'
+
+import { Card, CardContent } from 'components/common/Card'
+import { TotalSummaryResponse } from '.'
+
+const Wrapper = styled.div`
+ display: grid;
+ grid-template-columns: 0.7fr 2.35fr;
+ grid-template-areas: 'one two';
+
+ > div:first-child {
+ justify-content: flex-end;
+ }
+`
+
+const WrapperDoubleContent = styled.div<{ column?: boolean }>`
+ display: flex;
+ flex-direction: ${({ column }): string => (column ? 'column' : 'row')};
+ justify-content: flex-start;
+ flex: 1;
+ gap: 3.5rem;
+
+ > div {
+ text-align: center;
+ }
+
+ ${media.mediumDown} {
+ flex-direction: column;
+ }
+`
+const CardRow = styled.div`
+ grid-area: one;
+ display: flex;
+ flex-wrap: wrap;
+ align-items: stretch;
+`
+const WrapperTwo = styled.div`
+ grid-area: two;
+ display: flex;
+ flex: 1;
+`
+
+export function SummaryCards({ summaryData }: { summaryData: TotalSummaryResponse }): JSX.Element {
+ const { batchInfo, dailyTransactions, totalTokens, dailyFees, monthSurplus, isLoading } = summaryData
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/apps/explorer/components/SummaryCardsWidget/index.tsx b/src/apps/explorer/components/SummaryCardsWidget/index.tsx
new file mode 100644
index 000000000..bb206f436
--- /dev/null
+++ b/src/apps/explorer/components/SummaryCardsWidget/index.tsx
@@ -0,0 +1,43 @@
+import React, { useEffect, useState } from 'react'
+import { SummaryCards } from './SummaryCards'
+
+import summaryData from './summaryGraphResp.json'
+
+const DELAY_SECONDS = 3 // Emulating API request
+
+interface TotalSummary {
+ batchInfo: { lastBatchDate: string; batchId: string }
+ dailyTransactions: { now: number; before: string }
+ totalTokens: number
+ dailyFees: { now: string; before: string }
+ monthSurplus: { now: string; before: string }
+}
+
+export type TotalSummaryResponse = TotalSummary & {
+ isLoading: boolean
+}
+
+function useGetTotalSummary(): TotalSummaryResponse {
+ const [summary, setSummary] = useState({
+ batchInfo: { lastBatchDate: '', batchId: '' },
+ dailyTransactions: { now: 0, before: '' },
+ totalTokens: 0,
+ dailyFees: { now: '', before: '' },
+ monthSurplus: { now: '', before: '' },
+ isLoading: true,
+ })
+
+ useEffect(() => {
+ const timer = setTimeout(() => setSummary({ ...summaryData, isLoading: false }), DELAY_SECONDS * 1000)
+
+ return (): void => clearTimeout(timer)
+ }, [])
+
+ return summary
+}
+
+export function SummaryCardsWidget(): JSX.Element {
+ const summary = useGetTotalSummary()
+
+ return
+}
diff --git a/src/apps/explorer/components/SummaryCardsWidget/summaryGraphResp.json b/src/apps/explorer/components/SummaryCardsWidget/summaryGraphResp.json
new file mode 100644
index 000000000..5c720a0f4
--- /dev/null
+++ b/src/apps/explorer/components/SummaryCardsWidget/summaryGraphResp.json
@@ -0,0 +1,8 @@
+{
+
+ "batchInfo": { "lastBatchDate": "3m 42s Ago", "batchId": "fd3f932" },
+ "dailyTransactions": {"now": 194, "before": "+1.2%"},
+ "totalTokens": 193,
+ "dailyFees": {"now": "$33.3K", "before": "-3.23%"},
+ "monthSurplus": {"now": "$53.9K", "before": "14.49%"}
+}
\ No newline at end of file
diff --git a/src/apps/explorer/components/common/ShimmerBar/index.tsx b/src/apps/explorer/components/common/ShimmerBar/index.tsx
new file mode 100644
index 000000000..134f72c7b
--- /dev/null
+++ b/src/apps/explorer/components/common/ShimmerBar/index.tsx
@@ -0,0 +1,31 @@
+import styled, { keyframes } from 'styled-components'
+
+const ShimmerKeyframe = keyframes`
+ 0% {
+ background-position: 0px top;
+ }
+ 90% {
+ background-position: 300px top;
+ }
+ 100% {
+ background-position: 300px top;
+ }
+`
+
+const ShimmerBar = styled.div`
+ width: 100%;
+ height: 12px;
+ border-radius: 2px;
+ margin-bottom: 20px;
+ color: white;
+ background: ${({ theme }): string =>
+ `${theme.greyOpacity} -webkit-gradient(linear, 100% 0, 0 0, from(${theme.greyOpacity}), color-stop(0.5, ${theme.borderPrimary}), to(${theme.gradient1}))`};
+ background-position: -5rem top;
+ background-repeat: no-repeat;
+ -webkit-animation-name: ${ShimmerKeyframe};
+ -webkit-animation-duration: 1.3s;
+ -webkit-animation-iteration-count: infinite;
+ -webkit-background-size: 5rem 100%;
+`
+
+export default ShimmerBar
diff --git a/src/apps/explorer/pages/Home/index.tsx b/src/apps/explorer/pages/Home/index.tsx
index 497c8715c..b08bd2d11 100644
--- a/src/apps/explorer/pages/Home/index.tsx
+++ b/src/apps/explorer/pages/Home/index.tsx
@@ -3,11 +3,12 @@ import { Search } from 'apps/explorer/components/common/Search'
import { Wrapper as WrapperMod } from 'apps/explorer/pages/styled'
import styled from 'styled-components'
import { media } from 'theme/styles/media'
+import { SummaryCardsWidget } from 'apps/explorer/components/SummaryCardsWidget'
const Wrapper = styled(WrapperMod)`
max-width: 140rem;
flex-flow: column wrap;
- justify-content: center;
+ justify-content: flex-start;
display: flex;
> h1 {
@@ -23,9 +24,19 @@ const Wrapper = styled(WrapperMod)`
}
`
+const SummaryWrapper = styled.section`
+ display: grid;
+ /* grid-template-columns: 35fr 65fr; // There will be 2 sections */
+ grid-gap: 1 rem;
+ padding-bottom: 5rem;
+`
+
export const Home: React.FC = () => {
return (
+
+
+
Search on CoW Protocol Explorer
diff --git a/src/components/common/Card/Card.tsx b/src/components/common/Card/Card.tsx
new file mode 100644
index 000000000..e591a7ffa
--- /dev/null
+++ b/src/components/common/Card/Card.tsx
@@ -0,0 +1,54 @@
+import React from 'react'
+import styled from 'styled-components'
+
+import { COLOURS } from 'styles'
+import { Theme } from 'theme'
+
+const { white, fadedGreyishWhite, blackLight } = COLOURS
+
+const DefaultCard = styled.div`
+ height: inherit;
+ min-width: 200px;
+ min-height: 100px;
+ background-color: #f5f5f5;
+ border-radius: 6px;
+ box-shadow: 0 10px 15px -3px rgb(0 0 0 / 7%), 0 4px 6px -2px rgb(0 0 0 / 5%);
+ margin: 10px;
+`
+
+const CardComponent = styled(DefaultCard)`
+ display: flex;
+ flex-direction: column;
+ border-top-right-radius: 6px;
+ border-top-left-radius: 6px;
+ background: ${({ theme }): string => (theme.mode == Theme.DARK ? fadedGreyishWhite : white)};
+ color: ${({ theme }): string => (theme.mode == Theme.DARK ? white : blackLight)};
+`
+
+// CARD CONTENT STYLES
+const CardContent = styled.div`
+ flex: 1;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-size: 15px;
+ padding: 16px;
+ line-height: normal;
+`
+
+export interface CardBaseProps {
+ children?: React.ReactElement | string
+}
+
+/**
+ * Card component.
+ *
+ * An extensible content container.
+ */
+export const Card: React.FC = ({ children, ...rest }) => {
+ return (
+
+ {children}
+
+ )
+}
diff --git a/src/components/common/Card/CardContent.tsx b/src/components/common/Card/CardContent.tsx
index 32197b088..c4c9a5154 100644
--- a/src/components/common/Card/CardContent.tsx
+++ b/src/components/common/Card/CardContent.tsx
@@ -1,6 +1,8 @@
import React from 'react'
import styled from 'styled-components'
+import ShimmerBar from 'apps/explorer/components/common/ShimmerBar'
+
export type statusType = 'success' | 'danger'
export interface CardContentProps {
@@ -8,10 +10,10 @@ export interface CardContentProps {
direction?: string
icon1?: React.ReactElement
label1: string
- value1: string
+ value1: string | number
valueSize?: number
labelWidth?: number
- caption1?: string
+ caption1?: string | number
captionColor?: string
hint1?: string
hintColor?: string
@@ -20,6 +22,7 @@ export interface CardContentProps {
value2?: string
caption2?: string
hint2?: string
+ loading?: boolean
}
const CardBody = styled.div<{
@@ -98,6 +101,7 @@ export const CardContent: React.FC = ({
value2,
caption2,
hint2,
+ loading,
}): JSX.Element => {
return (
= ({
{label1}
-
{value1}
- {caption1 && (
+ {loading ? : {value1}
}
+ {!loading && caption1 && (
{caption1}
{hint1}
@@ -123,7 +127,7 @@ export const CardContent: React.FC = ({
)}
- {label2 && (
+ {!loading && label2 && (
{icon2 && {icon2} }
diff --git a/src/components/common/Card/index.tsx b/src/components/common/Card/index.tsx
index 9c5a9dfd7..68ae5954a 100644
--- a/src/components/common/Card/index.tsx
+++ b/src/components/common/Card/index.tsx
@@ -1,63 +1,2 @@
-import React from 'react'
-import styled from 'styled-components'
-import Grid from '@material-ui/core/Grid'
-
-import { COLOURS } from 'styles'
-import { Theme } from 'theme'
-
-const { white, fadedGreyishWhite, blackLight } = COLOURS
-
-const DefaultCard = styled.div`
- height: inherit;
- min-width: 200px;
- min-height: 100px;
- background-color: #f5f5f5;
- border-radius: 6px;
- box-shadow: 0 10px 15px -3px rgb(0 0 0 / 7%), 0 4px 6px -2px rgb(0 0 0 / 5%);
- margin: 10px;
-`
-
-const CardComponent = styled(DefaultCard)`
- display: flex;
- flex-direction: column;
- border-top-right-radius: 6px;
- border-top-left-radius: 6px;
- background: ${({ theme }): string => (theme.mode == Theme.DARK ? fadedGreyishWhite : white)};
- color: ${({ theme }): string => (theme.mode == Theme.DARK ? white : blackLight)};
-`
-
-// CARD CONTENT STYLES
-const CardContent = styled.div`
- flex: 1;
- display: flex;
- justify-content: center;
- align-items: center;
- font-size: 15px;
- padding: 16px;
- line-height: normal;
-`
-
-type CardBreakdown = boolean | 1 | 'auto' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | undefined
-
-export interface CardBaseProps {
- children?: React.ReactElement | string
- xs?: CardBreakdown
- sm?: CardBreakdown
- md?: CardBreakdown
- lg?: CardBreakdown
-}
-
-/**
- * Card component.
- *
- * An extensible content container.
- */
-export const Card: React.FC = ({ children, xs = 12, sm = 6, md = 4, lg = 3, ...rest }) => {
- return (
-
-
- {children}
-
-
- )
-}
+export * from './Card'
+export * from './CardContent'
diff --git a/src/components/common/CardRow/CardRow.stories.tsx b/src/components/common/CardRow/CardRow.stories.tsx
index 7df39f5ce..1db014ada 100644
--- a/src/components/common/CardRow/CardRow.stories.tsx
+++ b/src/components/common/CardRow/CardRow.stories.tsx
@@ -4,9 +4,8 @@ import { Story, Meta } from '@storybook/react/types-6-0'
import { GlobalStyles, ThemeToggler } from 'storybook/decorators'
-import { Card } from '../Card/index'
+import { Card, CardContent } from 'components/common/Card'
import { CardRow, CardRowProps } from '.'
-import { CardContent } from '../Card/CardContent'
import QuestionIcon from '../../../assets/img/question1.svg'
@@ -46,7 +45,7 @@ const Template: Story = (args) => (
Dummy Card
-
+
= ({ children }) => {
- return {children}
+ return {children}
}