Skip to content

Commit 6bdaeaf

Browse files
committed
chore: refactor
1 parent 5047c10 commit 6bdaeaf

File tree

1 file changed

+118
-90
lines changed

1 file changed

+118
-90
lines changed

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

Lines changed: 118 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,118 @@ import { cn } from '@/features/common/utils'
55
import { isDefined } from '@/utils/is-defined'
66
import { useMemo } from 'react'
77

8-
type TransactionArrow = {
8+
type Arrow = {
99
from: number
1010
to: number
1111
direction: 'leftToRight' | 'rightToLeft' | 'toSelf'
1212
}
1313

14+
function VerticalBars({ verticalBars }: { verticalBars: (number | undefined)[] }) {
15+
// The side vertical bars when there are nested items
16+
return (verticalBars ?? [])
17+
.filter(isDefined)
18+
.map((b, i) => (
19+
<div
20+
key={i}
21+
className={cn('h-full border-primary absolute')}
22+
style={{ marginLeft: b * graphConfig.indentationWidth, borderLeftWidth: `${graphConfig.lineWidth}px` }}
23+
></div>
24+
))
25+
}
26+
27+
function ConnectionToParent() {
28+
// The connection between this transaction and the parent
29+
return (
30+
<div
31+
className={cn(`border-primary rounded-bl-lg`, `h-1/2`, `absolute top-0 left-0`)}
32+
style={{
33+
borderLeftWidth: `${graphConfig.lineWidth}px`,
34+
borderBottomWidth: `${graphConfig.lineWidth}px`,
35+
width: `${graphConfig.indentationWidth + 8}px`,
36+
}}
37+
></div>
38+
)
39+
}
40+
41+
function TransactionName({ hasParent, name }: { hasParent: boolean; name: string }) {
42+
return (
43+
<div
44+
className={cn('inline')}
45+
style={{
46+
marginLeft: hasParent ? `${graphConfig.indentationWidth + 8}px` : `16px`,
47+
}}
48+
>
49+
{name}
50+
</div>
51+
)
52+
}
53+
54+
function ConnectionToSibbling() {
55+
// The connection between this transaction and the next sibbling
56+
return (
57+
<div
58+
className={cn('border-primary', 'absolute left-0')}
59+
style={{
60+
width: `${graphConfig.indentationWidth + 8}px`,
61+
borderLeftWidth: `${graphConfig.lineWidth}px`,
62+
height: `calc(50% + ${graphConfig.lineWidth}px)`,
63+
top: `calc(50% - ${graphConfig.lineWidth}px)`,
64+
}}
65+
></div>
66+
)
67+
}
68+
69+
function ConnectionToChildren({ indentLevel }: { indentLevel: number | undefined }) {
70+
// The connection between this transaction and the children
71+
return (
72+
<div
73+
className={cn('w-2', 'border-primary rounded-tl-lg', 'absolute left-0')}
74+
style={{
75+
marginLeft: indentLevel != null ? `${graphConfig.indentationWidth}px` : undefined,
76+
borderLeftWidth: `${graphConfig.lineWidth}px`,
77+
borderTopWidth: `${graphConfig.lineWidth}px`,
78+
height: `calc(50% + ${graphConfig.lineWidth}px)`,
79+
top: `calc(50% - ${graphConfig.lineWidth}px)`,
80+
}}
81+
></div>
82+
)
83+
}
84+
85+
function DisplayArrow({ arrow: transactionArrow }: { arrow: Arrow }) {
86+
return (
87+
<div
88+
className={cn('flex items-center justify-center')}
89+
style={{
90+
// 2 and 3 are the number to offset the name column
91+
gridColumnStart: transactionArrow.from + 2,
92+
gridColumnEnd: transactionArrow.to + 3,
93+
}}
94+
>
95+
<SvgCircle width={graphConfig.circleDimension} height={graphConfig.circleDimension}></SvgCircle>
96+
<div
97+
style={{
98+
width: `calc(${(100 - 100 / (transactionArrow.to - transactionArrow.from + 1)).toFixed(2)}% - ${graphConfig.circleDimension}px)`,
99+
height: `${graphConfig.circleDimension}px`,
100+
}}
101+
className="relative text-primary"
102+
>
103+
{transactionArrow.direction === 'rightToLeft' && <SvgPointerLeft className={cn('absolute top-0 left-0')} />}
104+
<div className={cn('border-primary h-1/2')} style={{ borderBottomWidth: graphConfig.lineWidth }}></div>
105+
{transactionArrow.direction === 'leftToRight' && <SvgPointerRight className={cn('absolute top-0 right-0')} />}
106+
</div>
107+
<SvgCircle width={graphConfig.circleDimension} height={graphConfig.circleDimension}></SvgCircle>
108+
</div>
109+
)
110+
}
111+
112+
function DisplaySelfTransaction() {
113+
return (
114+
<div className={cn('flex items-center justify-center')}>
115+
<SvgCircle width={graphConfig.circleDimension} height={graphConfig.circleDimension}></SvgCircle>
116+
</div>
117+
)
118+
}
119+
14120
type TransactionRowProps = {
15121
transaction: Transaction
16122
hasParent?: boolean
@@ -29,104 +135,26 @@ function TransactionRow({
29135
indentLevel,
30136
verticalBars,
31137
}: TransactionRowProps) {
32-
const transactionArrow = useMemo(() => calcTransactionArrow(transaction, accounts), [accounts, transaction])
138+
const arrow = useMemo(() => calcArrow(transaction, accounts), [accounts, transaction])
33139

34140
return (
35141
<>
36142
<div className={cn('p-0 relative pr-8')}>
37-
{
38-
// The side vertical bars when there are nested items
39-
(verticalBars ?? []).filter(isDefined).map((b, i) => (
40-
<div
41-
key={i}
42-
className={cn('h-full border-primary absolute')}
43-
style={{ marginLeft: b * graphConfig.indentationWidth, borderLeftWidth: `${graphConfig.lineWidth}px` }}
44-
></div>
45-
))
46-
}
143+
<VerticalBars verticalBars={verticalBars} />
47144
<div
48145
className={cn(`relative h-full p-0 flex items-center`, 'px-0')}
49146
style={{ marginLeft: (indentLevel ?? 0) * graphConfig.indentationWidth }}
50147
>
51-
{
52-
// The connection between this transaction and the parent
53-
hasParent && (
54-
<div
55-
className={cn(`border-primary rounded-bl-lg`, `h-1/2`, `absolute top-0 left-0`)}
56-
style={{
57-
borderLeftWidth: `${graphConfig.lineWidth}px`,
58-
borderBottomWidth: `${graphConfig.lineWidth}px`,
59-
width: `${graphConfig.indentationWidth + 8}px`,
60-
}}
61-
></div>
62-
)
63-
}
64-
<div
65-
className={cn('inline')}
66-
style={{
67-
marginLeft: hasParent ? `${graphConfig.indentationWidth + 8}px` : `16px`,
68-
}}
69-
>
70-
{transaction.name}
71-
</div>
72-
{
73-
// The connection between this transaction and the next sibbling
74-
hasParent && hasNextSibbling && (
75-
<div
76-
className={cn('border-primary', 'absolute left-0')}
77-
style={{
78-
width: `${graphConfig.indentationWidth + 8}px`,
79-
borderLeftWidth: `${graphConfig.lineWidth}px`,
80-
height: `calc(50% + ${graphConfig.lineWidth}px)`,
81-
top: `calc(50% - ${graphConfig.lineWidth}px)`,
82-
}}
83-
></div>
84-
)
85-
}
86-
{
87-
// The connection between this transaction and the children
88-
hasChildren && (
89-
<div
90-
className={cn('w-2', 'border-primary rounded-tl-lg', 'absolute left-0')}
91-
style={{
92-
marginLeft: indentLevel != null ? `${graphConfig.indentationWidth}px` : undefined,
93-
borderLeftWidth: `${graphConfig.lineWidth}px`,
94-
borderTopWidth: `${graphConfig.lineWidth}px`,
95-
height: `calc(50% + ${graphConfig.lineWidth}px)`,
96-
top: `calc(50% - ${graphConfig.lineWidth}px)`,
97-
}}
98-
></div>
99-
)
100-
}
148+
{hasParent && <ConnectionToParent />}
149+
<TransactionName hasParent={hasParent} name={transaction.name} />
150+
{hasParent && hasNextSibbling && <ConnectionToSibbling />}
151+
{hasChildren && <ConnectionToChildren indentLevel={indentLevel} />}
101152
</div>
102153
</div>
103154
{accounts.map((_, index) => {
104-
if (index < transactionArrow.from || index > transactionArrow.to) return <div key={index}></div>
105-
if (index === transactionArrow.from)
106-
return (
107-
<div
108-
className={cn('flex items-center justify-center')}
109-
style={{
110-
// 2 and 3 are the number to offset the name column
111-
gridColumnStart: transactionArrow.from + 2,
112-
gridColumnEnd: transactionArrow.to + 3,
113-
}}
114-
>
115-
<SvgCircle width={graphConfig.circleDimension} height={graphConfig.circleDimension}></SvgCircle>
116-
<div
117-
style={{
118-
width: `calc(${(100 - 100 / (transactionArrow.to - transactionArrow.from + 1)).toFixed(2)}% - ${graphConfig.circleDimension}px)`,
119-
height: `${graphConfig.circleDimension}px`,
120-
}}
121-
className="relative text-primary"
122-
>
123-
{transactionArrow.direction === 'rightToLeft' && <SvgPointerLeft className={cn('absolute top-0 left-0')} />}
124-
<div className={cn('border-primary h-1/2')} style={{ borderBottomWidth: graphConfig.lineWidth }}></div>
125-
{transactionArrow.direction === 'leftToRight' && <SvgPointerRight className={cn('absolute top-0 right-0')} />}
126-
</div>
127-
<SvgCircle width={graphConfig.circleDimension} height={graphConfig.circleDimension}></SvgCircle>
128-
</div>
129-
)
155+
if (index < arrow.from || index > arrow.to) return <div key={index}></div>
156+
if (index === arrow.from && index === arrow.to) return <DisplaySelfTransaction />
157+
if (index === arrow.from) return <DisplayArrow arrow={arrow} />
130158
else return null
131159
})}
132160

@@ -214,7 +242,7 @@ export function GroupPage() {
214242

215243
return (
216244
<div
217-
className={cn('relative grid overflow-x-scroll max-w-full')}
245+
className={cn('relative grid')}
218246
style={{
219247
gridTemplateColumns: `minmax(${graphConfig.colWidth}px, 1fr) repeat(${accounts.length}, ${graphConfig.colWidth}px)`,
220248
gridTemplateRows: `repeat(${transactionCount + 1}, ${graphConfig.rowHeight}px)`,
@@ -305,7 +333,7 @@ function extractSendersAndReceivers(group: Group) {
305333
}
306334
}
307335

308-
function calcTransactionArrow(transaction: Transaction, accounts: string[]): TransactionArrow {
336+
function calcArrow(transaction: Transaction, accounts: string[]): Arrow {
309337
const fromAccount = accounts.findIndex((a) => transaction.sender === a)
310338
const toAccount = accounts.findIndex((a) => transaction.receiver === a)
311339
const direction = fromAccount < toAccount ? 'leftToRight' : fromAccount > toAccount ? 'rightToLeft' : 'toSelf'

0 commit comments

Comments
 (0)