@@ -14,8 +14,10 @@ import { RollerTransaction } from '@urbit/roller-api';
15import './TransactionHistory.scss';
15import './TransactionHistory.scss';
16import { TransactionRow } from './TransactionRow';
16import { TransactionRow } from './TransactionRow';
17−import { Box } from '@tlon/indigo-react';
17+import { Box, Row } from '@tlon/indigo-react';
18−import { ShipRow } from './ShipRow';
18+import { PatpRow } from './PatpRow';
19+import Dropdown from 'components/L2/Dropdowns/Dropdown';
20+import Sigil from 'components/Sigil';
20interface GroupedTransactions {
22interface GroupedTransactions {
21 [ship: string]: RollerTransaction[];
23 [ship: string]: RollerTransaction[];
@@ -26,7 +28,21 @@ const TransactionHistory = () => {
26 const { api } = useRoller();
28 const { api } = useRoller();
27 const { wallet }: any = useWallet();
29 const { wallet }: any = useWallet();
28 const address = need.addressFromWallet(wallet);
30 const address = need.addressFromWallet(wallet);
31+ const [loading, setLoading] = useState(true);
29 const [transactions, setTransactions] = useState<RollerTransaction[]>([]);
32 const [transactions, setTransactions] = useState<RollerTransaction[]>([]);
33+ const [dropdownOpen, setDropdownOpen] = useState<boolean>(false);
34+ const [selectedPatp, setSelectedPatp] = useState<string | null>(null);
36+ const fetchTransactions = useCallback(async () => {
37+ const txns = await api.getHistory(address);
38+ setTransactions(txns);
42+ const selectPatp = useCallback(patp => {
43+ setSelectedPatp(patp);
44+ setDropdownOpen(false);
31 const txnsByPatp = useMemo(() => {
47 const txnsByPatp = useMemo(() => {
32 return transactions.reduce((memo, tx) => {
48 return transactions.reduce((memo, tx) => {
@@ -39,14 +55,17 @@ const TransactionHistory = () => {
39 }, {} as GroupedTransactions);
55 }, {} as GroupedTransactions);
40 }, [transactions]);
56 }, [transactions]);
42− const txKeys = useMemo(() => {
58+ const txPatps = useMemo(() => {
43 return Object.keys(txnsByPatp).sort();
59 return Object.keys(txnsByPatp).sort();
44 }, [txnsByPatp]);
60 }, [txnsByPatp]);
46− const fetchTransactions = useCallback(async () => {
62+ const filteredPatps = useMemo(() => {
47− const txns = await api.getHistory(address);
63+ if (!selectedPatp) {
48− setTransactions(txns);
64+ return txPatps;
49− }, [address, api]);
65+ }
67+ return txPatps.filter(p => p === selectedPatp);
68+ }, [selectedPatp, txPatps]);
51 useEffect(() => {
70 useEffect(() => {
52 fetchTransactions();
71 fetchTransactions();
@@ -60,27 +79,64 @@ const TransactionHistory = () => {
60 className="transaction-history"
79 className="transaction-history"
61 header={<L2BackHeader />}>
80 header={<L2BackHeader />}>
63− <HeaderPane>
82+ {loading ? (
83+ <Box className={'loading'}>Loading...</Box>
87+ <Box className="transaction-header">
64− <h5>Transactions</h5>
88+ <h5>Transactions</h5>
90+ className="transaction-dropdown"
93+ toggleOpen={() => setDropdownOpen(!dropdownOpen)}>
94+ <Box className="divider" />
95+ <Box className="points">
96+ {txPatps.map(patp => {
100+ onClick={() => selectPatp(patp)}
104+ <Box className="sigil">
109+ colors={['#000', '#FFF']}
65− </HeaderPane>
119+ </HeaderPane>
66− <BodyPane>
120+ <BodyPane>
67− <Box className="transaction-container">
121+ <Box className="transaction-container">
68− {txKeys.map(patp => {
122+ {filteredPatps.map(patp => {
69− return (
123+ return (
70− <>
124+ <Box key={patp}>
71− <ShipRow patp={patp} />
125+ <PatpRow patp={patp} />
72− {txnsByPatp[patp]
126+ {txnsByPatp[patp]
73− .sort((a, b) => {
127+ .sort((a, b) => {
74− return a.time - b.time;
128+ return a.time - b.time;
76− .map(tx => (
130+ .map(tx => (
77− <TransactionRow key={tx.time} {...tx} />
131+ <TransactionRow key={tx.time} {...tx} />
84 </Window>
140 </Window>