@@ -14,8 +14,10 @@ import { RollerTransaction } from '@urbit/roller-api';
1414
1515import './TransactionHistory.scss';
1616import { TransactionRow } from './TransactionRow';
17−import { Box } from '@tlon/indigo-react';
18−import { ShipRow } from './ShipRow';
17+import { Box, Row } from '@tlon/indigo-react';
18+import { PatpRow } from './PatpRow';
19+import Dropdown from 'components/L2/Dropdowns/Dropdown';
20+import Sigil from 'components/Sigil';
1921
2022interface GroupedTransactions {
2123 [ship: string]: RollerTransaction[];
@@ -26,7 +28,21 @@ const TransactionHistory = () => {
2628 const { api } = useRoller();
2729 const { wallet }: any = useWallet();
2830 const address = need.addressFromWallet(wallet);
31+ const [loading, setLoading] = useState(true);
2932 const [transactions, setTransactions] = useState<RollerTransaction[]>([]);
33+ const [dropdownOpen, setDropdownOpen] = useState<boolean>(false);
34+ const [selectedPatp, setSelectedPatp] = useState<string | null>(null);
35+
36+ const fetchTransactions = useCallback(async () => {
37+ const txns = await api.getHistory(address);
38+ setTransactions(txns);
39+ setLoading(false);
40+ }, [address, api]);
41+
42+ const selectPatp = useCallback(patp => {
43+ setSelectedPatp(patp);
44+ setDropdownOpen(false);
45+ }, []);
3046
3147 const txnsByPatp = useMemo(() => {
3248 return transactions.reduce((memo, tx) => {
@@ -39,14 +55,17 @@ const TransactionHistory = () => {
3955 }, {} as GroupedTransactions);
4056 }, [transactions]);
4157
42− const txKeys = useMemo(() => {
58+ const txPatps = useMemo(() => {
4359 return Object.keys(txnsByPatp).sort();
4460 }, [txnsByPatp]);
4561
46− const fetchTransactions = useCallback(async () => {
47− const txns = await api.getHistory(address);
48− setTransactions(txns);
49− }, [address, api]);
62+ const filteredPatps = useMemo(() => {
63+ if (!selectedPatp) {
64+ return txPatps;
65+ }
66+
67+ return txPatps.filter(p => p === selectedPatp);
68+ }, [selectedPatp, txPatps]);
5069
5170 useEffect(() => {
5271 fetchTransactions();
@@ -60,27 +79,64 @@ const TransactionHistory = () => {
6079 className="transaction-history"
6180 header={<L2BackHeader />}>
6281 <Window>
63− <HeaderPane>
64− <h5>Transactions</h5>
65− </HeaderPane>
66− <BodyPane>
67− <Box className="transaction-container">
68− {txKeys.map(patp => {
69− return (
70− <>
71− <ShipRow patp={patp} />
72− {txnsByPatp[patp]
73− .sort((a, b) => {
74− return a.time - b.time;
75− })
76− .map(tx => (
77− <TransactionRow key={tx.time} {...tx} />
78− ))}
79− </>
80− );
81− })}
82− </Box>
83− </BodyPane>
82+ {loading ? (
83+ <Box className={'loading'}>Loading...</Box>
84+ ) : (
85+ <>
86+ <HeaderPane>
87+ <Box className="transaction-header">
88+ <h5>Transactions</h5>
89+ <Dropdown
90+ className="transaction-dropdown"
91+ open={dropdownOpen}
92+ value={selectedPatp}
93+ toggleOpen={() => setDropdownOpen(!dropdownOpen)}>
94+ <Box className="divider" />
95+ <Box className="points">
96+ {txPatps.map(patp => {
97+ return (
98+ <Row
99+ className="entry"
100+ onClick={() => selectPatp(patp)}
101+ key={patp}>
102+ <Box>{patp}</Box>
103+ <Row>
104+ <Box className="sigil">
105+ <Sigil
106+ icon
107+ patp={patp}
108+ size={1}
109+ colors={['#000', '#FFF']}
110+ />
111+ </Box>
112+ </Row>
113+ </Row>
114+ );
115+ })}
116+ </Box>
117+ </Dropdown>
118+ </Box>
119+ </HeaderPane>
120+ <BodyPane>
121+ <Box className="transaction-container">
122+ {filteredPatps.map(patp => {
123+ return (
124+ <Box key={patp}>
125+ <PatpRow patp={patp} />
126+ {txnsByPatp[patp]
127+ .sort((a, b) => {
128+ return a.time - b.time;
129+ })
130+ .map(tx => (
131+ <TransactionRow key={tx.time} {...tx} />
132+ ))}
133+ </Box>
134+ );
135+ })}
136+ </Box>
137+ </BodyPane>
138+ </>
139+ )}
84140 </Window>
85141 </View>
86142 );