Skip to content

Commit 31be43b

Browse files
committed
pool+batches: add lease duration toggle to the batch section
1 parent 01f4b5e commit 31be43b

File tree

7 files changed

+141
-22
lines changed

7 files changed

+141
-22
lines changed

app/src/__tests__/components/pool/BatchSection.spec.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ describe('BatchSection', () => {
1919
await store.orderStore.fetchOrders();
2020
await store.batchStore.fetchBatches();
2121
await store.batchStore.fetchNextBatchTimestamp();
22+
await store.batchStore.fetchNodeTier();
2223
});
2324

2425
const render = () => {
@@ -33,4 +34,12 @@ describe('BatchSection', () => {
3334
fireEvent.click(getByText('bar-chart.svg'));
3435
expect(await findByText('volume')).toBeInTheDocument();
3536
});
37+
38+
it('should toggle between markets', async () => {
39+
const { getByText, findByText } = render();
40+
expect(store.batchStore.selectedLeaseDuration).toBe(2016);
41+
expect(await findByText('4032')).toBeInTheDocument();
42+
fireEvent.click(getByText('4032'));
43+
expect(store.batchStore.selectedLeaseDuration).toBe(4032);
44+
});
3645
});
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import React, { useCallback } from 'react';
2+
import { Badge } from 'components/base';
3+
import { styled } from 'components/theme';
4+
5+
const Styled = {
6+
Wrapper: styled.div<{ flex?: boolean }>`
7+
display: inline-block;
8+
`,
9+
Badge: styled(Badge)<{ selected?: boolean }>`
10+
font-family: ${props => props.theme.fonts.open.regular};
11+
font-size: ${props => props.theme.sizes.xs};
12+
color: ${props =>
13+
props.selected ? props.theme.colors.offWhite : props.theme.colors.gray};
14+
border: 1px solid
15+
${props => (props.selected ? props.theme.colors.offWhite : props.theme.colors.gray)};
16+
17+
padding: 5px 10px;
18+
letter-spacing: normal;
19+
cursor: pointer;
20+
21+
&:hover {
22+
opacity: 1;
23+
background-color: ${props => props.theme.colors.overlay};
24+
color: ${props => props.theme.colors.offWhite};
25+
border-color: ${props => props.theme.colors.offWhite};
26+
}
27+
`,
28+
};
29+
30+
export interface BadgeListOption {
31+
label: string;
32+
value: string;
33+
}
34+
35+
interface Props {
36+
options: BadgeListOption[];
37+
value?: string;
38+
onChange: (value: string) => void;
39+
}
40+
41+
const BadgeList: React.FC<Props> = ({ options, value, onChange }) => {
42+
const handleClick = useCallback((v: string) => () => onChange(v), [onChange]);
43+
44+
const { Wrapper, Badge } = Styled;
45+
return (
46+
<Wrapper>
47+
{options.map(o => (
48+
<Badge key={o.value} selected={o.value === value} onClick={handleClick(o.value)}>
49+
{o.label}
50+
</Badge>
51+
))}
52+
</Wrapper>
53+
);
54+
};
55+
56+
export default BadgeList;

app/src/components/pool/BatchSection.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { useStore } from 'store';
44
import { Section } from 'components/base';
55
import { styled } from 'components/theme';
66
import BatchChart from './batches/BatchChart';
7+
import BatchControls from './batches/BatchControls';
78
import BatchList from './batches/BatchList';
89
import BatchStats from './batches/BatchStats';
910

@@ -23,6 +24,7 @@ const BatchSection: React.FC = () => {
2324
return (
2425
<Section>
2526
<BatchStats />
27+
<BatchControls />
2628
{batchesView.viewMode === 'chart' ? <BatchChart /> : <BatchList />}
2729
</Section>
2830
);
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import React, { useCallback } from 'react';
2+
import { observer } from 'mobx-react-lite';
3+
import { usePrefixedTranslation } from 'hooks';
4+
import { useStore } from 'store';
5+
import { BarChart, HeaderFour, List } from 'components/base';
6+
import BadgeList from 'components/common/BadgeList';
7+
import { styled } from 'components/theme';
8+
9+
const Styled = {
10+
Wrapper: styled.div`
11+
display: flex;
12+
justify-content: space-between;
13+
`,
14+
Title: styled(HeaderFour)`
15+
display: inline-block;
16+
`,
17+
ViewMode: styled.div`
18+
opacity: 0.6;
19+
20+
&:hover {
21+
opacity: 1;
22+
}
23+
`,
24+
};
25+
26+
const BatchControls: React.FC = () => {
27+
const { l } = usePrefixedTranslation('cmps.pool.batches.BatchControls');
28+
const { batchesView } = useStore();
29+
30+
const handleViewChart = useCallback(() => batchesView.setViewMode('chart'), []);
31+
const handleViewList = useCallback(() => batchesView.setViewMode('list'), []);
32+
33+
const { Wrapper, Title, ViewMode } = Styled;
34+
return (
35+
<Wrapper>
36+
<div>
37+
<Title>{l('markets')}</Title>
38+
<BadgeList
39+
options={batchesView.marketOptions}
40+
value={batchesView.selectedMarket}
41+
onChange={batchesView.changeMarket}
42+
/>
43+
</div>
44+
<ViewMode>
45+
<BarChart size="large" onClick={handleViewChart} />
46+
<List size="large" onClick={handleViewList} />
47+
</ViewMode>
48+
</Wrapper>
49+
);
50+
};
51+
52+
export default observer(BatchControls);

app/src/components/pool/batches/BatchStats.tsx

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import React, { useCallback } from 'react';
1+
import React from 'react';
22
import { observer } from 'mobx-react-lite';
33
import { usePrefixedTranslation } from 'hooks';
44
import { useStore } from 'store';
5-
import { BarChart, List } from 'components/base';
65
import LoaderLines from 'components/common/LoaderLines';
76
import Stat from 'components/common/Stat';
87
import Unit from 'components/common/Unit';
@@ -42,17 +41,6 @@ const Styled = {
4241
`,
4342
Stat: StyledStat.withComponent(Stat),
4443
BatchCountdown: StyledStat.withComponent(BatchCountdown),
45-
ViewMode: styled.div`
46-
position: absolute;
47-
bottom: -40px;
48-
right: 0;
49-
z-index: 1;
50-
opacity: 0.6;
51-
52-
&:hover {
53-
opacity: 1;
54-
}
55-
`,
5644
LoaderLines: styled(LoaderLines)`
5745
.line {
5846
margin: 10px 1px;
@@ -65,12 +53,9 @@ const BatchStats: React.FC = () => {
6553
const { l } = usePrefixedTranslation('cmps.pool.batches.BatchStats');
6654
const { batchesView } = useStore();
6755

68-
const handleViewChart = useCallback(() => batchesView.setViewMode('chart'), []);
69-
const handleViewList = useCallback(() => batchesView.setViewMode('list'), []);
70-
7156
const tipProps = { tipPlacement: 'bottom', tipCapitalize: false };
7257

73-
const { Wrapper, Stat, BatchCountdown, ViewMode, LoaderLines } = Styled;
58+
const { Wrapper, Stat, BatchCountdown, LoaderLines } = Styled;
7459
return (
7560
<Wrapper>
7661
<div>
@@ -111,10 +96,6 @@ const BatchStats: React.FC = () => {
11196
value={<Unit sats={batchesView.paidSats} suffix={false} />}
11297
/>
11398
</div>
114-
<ViewMode>
115-
<BarChart size="large" onClick={handleViewChart} />
116-
<List size="large" onClick={handleViewList} />
117-
</ViewMode>
11899
</Wrapper>
119100
);
120101
};

app/src/i18n/locales/en-US.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@
169169
"cmps.pool.batches.BatchStats.tier": "Node Tier",
170170
"cmps.pool.batches.BatchStats.earned": "Earned",
171171
"cmps.pool.batches.BatchStats.paid": "Paid",
172+
"cmps.pool.batches.BatchControls.markets": "Markets",
172173
"cmps.pool.orders.OrdersList.emptyMsg": "You do not have any {{filter}} orders.",
173174
"cmps.pool.orders.OrdersList.emptyAllMsg": "Submit an order using the form on the left.",
174175
"cmps.pool.orders.OrdersList.type": "Type",

app/src/store/views/batchesView.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { makeAutoObservable } from 'mobx';
1+
import { keys, makeAutoObservable } from 'mobx';
22
import { NodeTier } from 'types/generated/auctioneer_pb';
33
import { toPercent } from 'util/bigmath';
44
import { Store } from 'store';
@@ -75,11 +75,29 @@ export default class BatchesView {
7575
return this._store.orderStore.paidSats;
7676
}
7777

78+
/** the currently selected market */
79+
get selectedMarket() {
80+
return `${this._store.batchStore.selectedLeaseDuration}`;
81+
}
82+
83+
/** the list of markets to display as badges */
84+
get marketOptions() {
85+
return keys(this._store.batchStore.leaseDurations).map(duration => ({
86+
label: `${duration}`,
87+
value: `${duration}`,
88+
}));
89+
}
90+
7891
//
7992
// Actions
8093
//
8194

8295
setViewMode(mode: BatchesView['viewMode']) {
8396
this.viewMode = mode;
8497
}
98+
99+
changeMarket(value: string) {
100+
const duration = parseInt(value);
101+
this._store.batchStore.setActiveMarket(duration);
102+
}
85103
}

0 commit comments

Comments
 (0)