aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx
blob: 02bc1b0146902585640e2dcac2d2a2249df58be3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import { constants as sharedConstants, Styles } from '@0xproject/react-shared';
import * as _ from 'lodash';
import { GridTile as PlainGridTile } from 'material-ui/GridList';
import * as React from 'react';
import { analytics } from 'ts/utils/analytics';

import { TopTokens } from 'ts/components/relayer_index/relayer_top_tokens';
import { Container } from 'ts/components/ui/container';
import { Image } from 'ts/components/ui/image';
import { Island } from 'ts/components/ui/island';
import { colors } from 'ts/style/colors';
import { media } from 'ts/style/media';
import { styled } from 'ts/style/theme';
import { WebsiteBackendRelayerInfo } from 'ts/types';
import { utils } from 'ts/utils/utils';

export interface RelayerGridTileProps {
    relayerInfo: WebsiteBackendRelayerInfo;
    networkId: number;
}

const styles: Styles = {
    root: {
        boxSizing: 'border-box',
        // All material UI components have position: relative
        // which creates a new stacking context and makes z-index stuff impossible. So reset.
        position: 'static',
    },
    innerDiv: {
        height: '100%',
        boxSizing: 'border-box',
    },
    header: {
        height: '50%',
        width: '100%',
    },
    body: {
        height: '50%',
        width: '100%',
        boxSizing: 'border-box',
        padding: 12,
    },
    weeklyTradeVolumeLabel: {
        fontSize: 14,
        color: colors.mediumBlue,
    },
    subLabel: {
        fontSize: 12,
        color: colors.lightGrey,
    },
    relayerNameLabel: {
        fontSize: 16,
        fontWeight: 'bold',
        color: colors.black,
    },
};

const FALLBACK_IMG_SRC = '/images/relayer_fallback.png';
const FALLBACK_PRIMARY_COLOR = colors.grey300;
const NO_CONTENT_MESSAGE = '--';
const RELAYER_ICON_HEIGHT = '110px';

export const RelayerGridTile: React.StatelessComponent<RelayerGridTileProps> = (props: RelayerGridTileProps) => {
    const link = props.relayerInfo.appUrl || props.relayerInfo.url;
    const topTokens = props.relayerInfo.topTokens;
    const weeklyTxnVolume = props.relayerInfo.weeklyTxnVolume;
    const networkName = sharedConstants.NETWORK_NAME_BY_ID[props.networkId];
    const eventLabel = `${props.relayerInfo.name}-${networkName}`;
    const onClick = () => {
        analytics.logEvent('Portal', 'Relayer Click', eventLabel);
        utils.openUrl(link);
    };
    const headerImageUrl = props.relayerInfo.logoImgUrl;
    const headerBackgroundColor =
        !_.isUndefined(headerImageUrl) && !_.isUndefined(props.relayerInfo.primaryColor)
            ? props.relayerInfo.primaryColor
            : FALLBACK_PRIMARY_COLOR;
    return (
        <Island style={styles.root} Component={GridTile}>
            <div style={styles.innerDiv} onClick={onClick}>
                <div className="flex items-center" style={{ ...styles.header, backgroundColor: headerBackgroundColor }}>
                    <Image
                        className="mx-auto"
                        src={props.relayerInfo.logoImgUrl}
                        fallbackSrc={FALLBACK_IMG_SRC}
                        height={RELAYER_ICON_HEIGHT}
                    />
                </div>
                <div style={styles.body}>
                    <div className="pb1" style={styles.relayerNameLabel}>
                        {props.relayerInfo.name}
                    </div>
                    <Section titleText="Weekly Trade Volume">
                        {!_.isUndefined(weeklyTxnVolume) && (
                            <div style={styles.weeklyTradeVolumeLabel}>{props.relayerInfo.weeklyTxnVolume}</div>
                        )}
                    </Section>
                    <Container marginTop="10px">
                        <Section titleText="Top Tokens">
                            {!_.isEmpty(topTokens) && <TopTokens tokens={topTokens} networkId={props.networkId} />}
                        </Section>
                    </Container>
                </div>
            </div>
        </Island>
    );
};

const GridTile = styled(PlainGridTile)`
    cursor: pointer;
    transition: transform 0.2s ease;
    &:hover {
        transform: translate(0px, -3px);
    }
    ${media.small`
        transform: none;
    `};
`;

interface SectionProps {
    titleText: string;
    children?: React.ReactNode;
}
const Section = (props: SectionProps) => {
    return (
        <div>
            <div style={styles.subLabel}>{props.titleText}</div>
            <Container marginTop="6px">{props.children || <NoContent />}</Container>
        </div>
    );
};

const NoContent = () => <div style={styles.subLabel}>{NO_CONTENT_MESSAGE}</div>;