on dffcebf help sign in
bridge/src/components/Passport.js
96 lines 2.9 kB history raw
1import React from 'react';
2import cn from 'classnames';
3import { Just, Nothing } from 'folktale/maybe';
4import * as ob from 'urbit-ob';
5import { Grid, Flex, Text } from 'indigo-react';
6import { times } from 'lodash';
8import usePointBirthday from 'lib/usePointBirthday';
10import {
11 LOADING_CHARACTER,
12 INTERSTITIAL_CHARACTER,
13 matchBlinkyDate,
14} from './Blinky';
15import MaybeSigil from './MaybeSigil';
17const TICKET_CHAR_LENGTH = 30;
18const TICKET = times(TICKET_CHAR_LENGTH, i =>
19 i % 2 === 0 ? LOADING_CHARACTER : INTERSTITIAL_CHARACTER
20).join('');
21const PENDING_TICKET = TICKET;
22const VALID_TICKET = `${TICKET} ◆`;
24const VISIBLE_ADDRESS_CHAR_COUNT = 20;
25const EMPTY_ADDRESS = times(VISIBLE_ADDRESS_CHAR_COUNT, () => '<').join('');
26const ADDRESS_BUFFER_CHARS = times(40, () => '<').join('');
28/**
29 * point is Maybe<number>
30 * ticket is null | boolean
31 * address is null | Maybe<string>
32 */
33export default function Passport({
34 point,
35 className,
36 ticket = null,
37 address = Nothing(),
38 mini = false,
39}) {
40 const birthday = usePointBirthday(point.getOrElse(null));
41 const visualBirthday = matchBlinkyDate(birthday);
43 const name = point.matchWith({
44 Nothing: () => Nothing(),
45 Just: p => Just(ob.patp(p.value)),
46 });
47 const visualName = name.matchWith({
48 Nothing: () => '...',
49 Just: p => p.value,
50 });
52 const showTicket = ticket !== null;
53 const isValidTiket = !!ticket;
54 const visibleTicket = isValidTiket ? VALID_TICKET : PENDING_TICKET;
55 const visibleAddress = `${address.matchWith({
56 Nothing: () => EMPTY_ADDRESS,
57 Just: p => p.value.slice(0, VISIBLE_ADDRESS_CHAR_COUNT),
58 })}${ADDRESS_BUFFER_CHARS}`;
60 return (
61 <Grid gap={4} className={cn('bg-black r8 p7', className)}>
62 <Grid.Item cols={[1, 4]} className="bg-green">
63 <MaybeSigil patp={name} size={64} margin={0} />
64 </Grid.Item>
65 <Grid.Item as={Flex} cols={[4, 13]} col justify="between">
66 <Flex.Item className="mono white f5">{visualName}</Flex.Item>
67 <Flex.Item as={Flex} col>
68 <Flex.Item as={Text} className="mono f6 f5-ns gray4 uppercase">
69 Birth Time
70 </Flex.Item>
71 <Flex.Item as={Text} className="mono f6 f5-ns gray4 ">
72 {visualBirthday}
73 </Flex.Item>
74 </Flex.Item>
75 </Grid.Item>
76 {!mini && showTicket && (
77 <Grid.Item full className="mv3" as={Flex} col>
78 <Flex.Item as={Text} className="mono f6 f5-ns gray4 uppercase">
79 Master Ticket
80 </Flex.Item>
81 <Flex.Item
82 as={Text}
83 className={cn('mono f6 f5-ns wrap', {
84 gray4: !isValidTiket,
85 green3: isValidTiket,
86 })}>
87 {visibleTicket}
88 </Flex.Item>
89 <Flex.Item as={Text} className="mono f6 f5-ns gray4 wrap">
90 {visibleAddress}
91 </Flex.Item>
92 </Grid.Item>
93 )}
94 </Grid>
95 );