Skip to content

Commit dd50145

Browse files
committed
chore: wip - group transaction table
1 parent 9761756 commit dd50145

File tree

2 files changed

+136
-54
lines changed

2 files changed

+136
-54
lines changed

src/features/transactions/pages/group-page.tsx

Lines changed: 135 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -7,89 +7,171 @@ type TransactionTrProps = {
77
hasParent?: boolean
88
hasNextSibbling?: boolean
99
hasChildren?: boolean
10+
accounts: string[]
11+
indentLevel?: number
12+
verticalBars?: number[]
1013
}
11-
function TransactionTr({ transaction, hasParent = false, hasNextSibbling = false, hasChildren = false }: TransactionTrProps) {
14+
function TransactionTr({
15+
transaction,
16+
accounts,
17+
hasParent = false,
18+
hasNextSibbling = false,
19+
hasChildren = false,
20+
indentLevel = 0,
21+
verticalBars,
22+
}: TransactionTrProps) {
1223
return (
13-
<tr>
14-
<td className="p-0">
15-
<div className={cn(`relative h-10 p-0 flex items-center`, 'px-0')}>
16-
{hasParent && (
17-
<div className={cn('w-8', `border-primary border-l-2 border-b-2 rounded-bl-lg`, `h-[50%]`, `absolute top-0 left-0`)}></div>
18-
)}
19-
<div className={cn('inline ml-8')}>{transaction.name}</div>
20-
{hasParent && hasNextSibbling && (
21-
<div className={cn('w-8', 'border-primary border-l-2', 'h-[22px]', 'absolute top-[18px] left-0')}></div>
22-
)}
23-
{hasChildren && !hasParent && (
24-
<div
25-
className={cn(
26-
'w-8',
27-
`border-primary border-l-2 border-t-2 rounded-tl-lg`,
28-
`h-[calc(50%+2px)]`,
29-
`absolute top-[calc(50%-2px)] left-0`
30-
)}
31-
></div>
32-
)}
33-
{hasChildren && hasParent && (
34-
<div
35-
className={cn('w-2 ml-4', 'border-primary border-l-2 border-t-2 rounded-tl-lg', 'h-[22px]', 'absolute top-[18px] left-0')}
36-
></div>
37-
)}
38-
</div>
39-
{hasChildren && (
40-
<div className={cn('relative', hasParent ? 'pl-4' : '')}>
41-
{hasNextSibbling && <div className={cn(`border-primary border-l-2`, `h-full`, 'absolute top-0 left-0')}></div>}
42-
<table>
43-
{transaction.transactions?.map((childTransaction, index, arr) => (
44-
<TransactionTr
45-
transaction={childTransaction}
46-
hasChildren={childTransaction.transactions && childTransaction.transactions.length > 0}
47-
hasParent={true}
48-
hasNextSibbling={index < arr.length - 1}
49-
/>
50-
))}
51-
</table>
24+
<>
25+
<tr>
26+
<td className={cn('p-0 relative')}>
27+
{verticalBars &&
28+
verticalBars.length &&
29+
verticalBars
30+
.filter((b) => b > 0)
31+
.map((b, i) => <div key={i} className={cn('h-10 border-primary border-l-2 absolute')} style={{ marginLeft: b * 16 }}></div>)}
32+
<div className={cn(`relative h-10 p-0 flex items-center`, 'px-0')} style={{ marginLeft: indentLevel * 16 }}>
33+
{hasParent && (
34+
<div className={cn('w-8', `border-primary border-l-2 border-b-2 rounded-bl-lg`, `h-[50%]`, `absolute top-0 left-0`)}></div>
35+
)}
36+
<div className={cn('inline ml-8')}>{transaction.name}</div>
37+
{hasParent && hasNextSibbling && (
38+
<div className={cn('w-8', 'border-primary border-l-2', 'h-[22px]', 'absolute top-[18px] left-0')}></div>
39+
)}
40+
{hasChildren && (
41+
<div
42+
className={cn('w-2 ml-4', 'border-primary border-l-2 border-t-2 rounded-tl-lg', 'h-[22px]', 'absolute top-[18px] left-0')}
43+
></div>
44+
)}
5245
</div>
53-
)}
54-
</td>
55-
<td></td>
56-
</tr>
46+
</td>
47+
{accounts.map((account, index) => (
48+
<td key={index} className={cn('p-0 relative')}>
49+
<div className={cn('h-10 border-l-2 border-muted border-dashed absolute left-[50%]')}></div>
50+
</td>
51+
))}
52+
</tr>
53+
54+
{hasChildren &&
55+
transaction.transactions?.map((childTransaction, index, arr) => (
56+
<TransactionTr
57+
transaction={childTransaction}
58+
hasChildren={childTransaction.transactions && childTransaction.transactions.length > 0}
59+
hasParent={true}
60+
hasNextSibbling={index < arr.length - 1}
61+
accounts={accounts}
62+
indentLevel={indentLevel + 1}
63+
verticalBars={[...(verticalBars ?? []), hasNextSibbling ? indentLevel : 0]}
64+
/>
65+
))}
66+
</>
5767
)
5868
}
5969

6070
export function GroupPage() {
61-
const group: Transaction = {
62-
name: '',
71+
const group: Group = {
6372
transactions: [
64-
{ name: '7VSN...' },
73+
{ name: '7VSN...', sender: 'Account 1', receiver: 'Account 2' },
6574
{
6675
name: 'NDQX...',
76+
sender: 'Account 1',
77+
receiver: 'Account 2',
6778
transactions: [
68-
{ name: 'Inner 1' },
69-
{ name: 'Inner 2', transactions: [{ name: 'Inner 3' }, { name: 'Inner 5' }] },
70-
{ name: 'Inner 9' },
71-
{ name: 'Inner 4', transactions: [{ name: 'Inner 6' }, { name: 'Inner 7' }] },
72-
{ name: 'Inner 8' },
79+
{ name: 'Inner 1', sender: 'Account 1', receiver: 'Account 3' },
80+
{
81+
name: 'Inner 2',
82+
sender: 'Account 2',
83+
receiver: 'Account 5',
84+
transactions: [
85+
{ name: 'Inner 3', sender: 'Account 5', receiver: 'Account 1' },
86+
{
87+
name: 'Inner 11',
88+
sender: 'Account 3',
89+
receiver: 'Account 1',
90+
transactions: [
91+
{ name: 'Inner 10', sender: 'Account 2', receiver: 'Account 6' },
92+
{ name: 'Inner 10', sender: 'Account 2', receiver: 'Account 6' },
93+
],
94+
},
95+
{
96+
name: 'Inner 5',
97+
sender: 'Account 3',
98+
receiver: 'Account 1',
99+
transactions: [{ name: 'Inner 10', sender: 'Account 2', receiver: 'Account 6' }],
100+
},
101+
],
102+
},
103+
{ name: 'Inner 9', sender: 'Account 2', receiver: 'Account 6' },
104+
{
105+
name: 'Inner 4',
106+
sender: 'Account 1',
107+
receiver: 'Account 1',
108+
transactions: [
109+
{ name: 'Inner 6', sender: 'Account 3', receiver: 'Account 2' },
110+
{
111+
name: 'Inner 7',
112+
sender: 'Account 4',
113+
receiver: 'Account 2',
114+
},
115+
],
116+
},
117+
{ name: 'Inner 8', sender: 'Account 5', receiver: 'Account 3' },
73118
],
74119
},
75120
],
76121
}
122+
const accounts = extractSendersAndReceivers(group)
77123

78124
return (
79-
<table>
125+
<table className={cn('w-full')}>
126+
<tr>
127+
<th></th>
128+
{accounts.map((account, index) => (
129+
<th key={index}>{account}</th>
130+
))}
131+
</tr>
80132
{group.transactions?.map((transaction, index, arr) => (
81133
<TransactionTr
82134
transaction={transaction}
83135
hasChildren={transaction.transactions && transaction.transactions.length > 0}
84136
hasParent={false}
85137
hasNextSibbling={index < arr.length - 1}
138+
accounts={accounts}
86139
/>
87140
))}
88141
</table>
89142
)
90143
}
91144

145+
export type Group = {
146+
transactions?: Transaction[]
147+
}
148+
92149
export type Transaction = {
93150
name: string
94151
transactions?: Transaction[]
152+
sender: string
153+
receiver: string
154+
}
155+
156+
function extractSendersAndReceivers(group: Group): string[] {
157+
let sendersAndReceivers: string[] = []
158+
159+
function extract(transactionArr: Transaction[] | undefined) {
160+
if (transactionArr) {
161+
transactionArr.forEach((transaction) => {
162+
sendersAndReceivers.push(transaction.sender)
163+
sendersAndReceivers.push(transaction.receiver)
164+
if (transaction.transactions) {
165+
extract(transaction.transactions)
166+
}
167+
})
168+
}
169+
}
170+
171+
extract(group.transactions)
172+
173+
// Remove duplicates
174+
sendersAndReceivers = Array.from(new Set(sendersAndReceivers))
175+
176+
return sendersAndReceivers
95177
}

src/index.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
--secondary: 15 23 42;
2323
--secondary-foreground: 241 245 249;
2424

25-
--muted: 241 245 249;
25+
--muted: 217 217 217;
2626
--muted-foreground: 100 116 139;
2727

2828
--accent: 64 64 64;

0 commit comments

Comments
 (0)