Skip to content

Commit ea6ae1c

Browse files
Improve filter button styling.
1 parent 981f3f1 commit ea6ae1c

4 files changed

Lines changed: 106 additions & 60 deletions

File tree

src/App.tsx

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -195,26 +195,40 @@ function FilterAreaContents(): React.JSX.Element {
195195
);
196196

197197
return (
198-
<>
199-
<section className="col-span-2">
200-
<h2>
201-
{mismatchCount} mismatched{" "}
202-
{mismatchCount == 1 ? "transaction" : "transactions"}
203-
</h2>
204-
<MismatchFiltersList />
205-
</section>
206-
207-
<section className="col-span-2">
208-
<label>
209-
Show excluded transactions
210-
<input
211-
type="checkbox"
212-
checked={showingExcludedTransactions}
213-
onChange={() => dispatch(toggleShowExcludedFromComparison())}
214-
/>
215-
</label>
216-
</section>
217-
</>
198+
<div className="mx-auto max-w-6xl space-y-4 text-center">
199+
<p className="text-lg font-bold">
200+
{mismatchCount === 0 ? (
201+
<>All transactions match between YNAB and the bank.</>
202+
) : (
203+
<>
204+
{mismatchCount}{" "}
205+
{mismatchCount === 1 ? "transaction is" : "transactions are"} out of
206+
sync between YNAB and the bank.
207+
</>
208+
)}
209+
</p>
210+
<p>
211+
{mismatchCount === 0 ? (
212+
<>
213+
If this doesn't seem right, check the "Comparing" columns and make
214+
sure that all the transactions that you expect are included in the
215+
comparison.
216+
</>
217+
) : (
218+
<>Use these filters to narrow them down.</>
219+
)}
220+
</p>
221+
<MismatchFiltersList />
222+
<label>
223+
<input
224+
className="accent-green-700"
225+
type="checkbox"
226+
checked={!showingExcludedTransactions}
227+
onChange={() => dispatch(toggleShowExcludedFromComparison())}
228+
/>{" "}
229+
Hide transactions that aren't being compared
230+
</label>
231+
</div>
218232
);
219233
}
220234

src/MismatchFiltersList.tsx

Lines changed: 21 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import type currency from "currency.js";
2-
3-
import { Amount } from "./currencyFormatting";
1+
import { FilterToggleButton } from "./components/FilterToggleButton";
42
import { selectAmountFilters, toggleFilter } from "./redux/tablesSlice";
53
import { useAppDispatch, useAppSelector } from "./redux/typedHooks";
64

@@ -11,40 +9,25 @@ export function MismatchFiltersList(): React.JSX.Element {
119
useAppSelector((state) => selectAmountFilters(state.present)) ?? [];
1210

1311
return (
14-
<ul>
15-
{filters.map((filter) => (
16-
<li key={filter.key} className="inline-block">
17-
<MismatchToggleButton
18-
amount={filter.mismatch.amount}
19-
count={Math.abs(
20-
filter.mismatch.bankCount - filter.mismatch.ynabCount,
21-
)}
22-
enabled={filter.filterEnabled}
23-
onClick={() => dispatch(toggleFilter({ key: filter.key }))}
24-
/>
25-
</li>
26-
))}
27-
</ul>
28-
);
29-
}
30-
31-
function MismatchToggleButton({
32-
amount,
33-
count,
34-
enabled,
35-
onClick,
36-
}: {
37-
amount: currency;
38-
count: number;
39-
enabled: boolean;
40-
onClick: () => void;
41-
}): React.JSX.Element {
42-
return (
43-
<button
44-
className={enabled ? "font-bold text-blue-500" : ""}
45-
onClick={onClick}
46-
>
47-
<Amount amount={amount} /> ({count})
48-
</button>
12+
<div className="rounded bg-well p-3">
13+
{filters.length === 0 ? (
14+
<i className="mx-auto">No filters to show</i>
15+
) : (
16+
<menu className="scroll flex gap-3 overflow-x-auto">
17+
{filters.map((filter) => (
18+
<li key={filter.key}>
19+
<FilterToggleButton
20+
currencyAmount={filter.mismatch.amount}
21+
mismatchCount={Math.abs(
22+
filter.mismatch.bankCount - filter.mismatch.ynabCount,
23+
)}
24+
selected={filter.filterEnabled}
25+
onClick={() => dispatch(toggleFilter({ key: filter.key }))}
26+
/>
27+
</li>
28+
))}
29+
</menu>
30+
)}
31+
</div>
4932
);
5033
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import clsx from "clsx";
2+
import type currency from "currency.js";
3+
import type React from "react";
4+
5+
import { Amount } from "../currencyFormatting";
6+
import styles from "./inputs/inputs.module.css";
7+
8+
export interface Props {
9+
currencyAmount: currency;
10+
mismatchCount: number;
11+
selected: boolean;
12+
onClick?: () => void;
13+
}
14+
15+
export function FilterToggleButton(props: Props): React.JSX.Element {
16+
const { currencyAmount, mismatchCount, selected, onClick } = props;
17+
18+
return (
19+
<button
20+
type="button"
21+
aria-pressed={selected}
22+
className={clsx(
23+
styles.input,
24+
selected && (mismatchCount === 0 ? "bg-green-200" : "bg-amber-200"),
25+
)}
26+
onClick={onClick}
27+
>
28+
<span className="flex gap-2">
29+
<span
30+
className={clsx(
31+
"inline-block min-w-[1lh] rounded-full",
32+
mismatchCount === 0
33+
? selected
34+
? "bg-green-400"
35+
: "bg-green-200"
36+
: selected
37+
? "bg-amber-400"
38+
: "bg-amber-200",
39+
)}
40+
>
41+
{mismatchCount}x
42+
</span>
43+
<span>
44+
<Amount amount={currencyAmount} />
45+
</span>
46+
</span>
47+
</button>
48+
);
49+
}

src/components/icons/ComparedIcon.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ export function ComparedIcon(props: Props): JSX.Element {
1919
const otherSideCopy = thisSide === "bank" ? "YNAB" : "bank";
2020

2121
const title = compared
22-
? `This ${thisSideCopy} transaction is included in the comparison. You expect it to also exist on the ${otherSideCopy} side.`
23-
: `This ${thisSideCopy} transaction is excluded from the comparison. You don't expect it to exist on the ${otherSideCopy} side.`;
22+
? `This ${thisSideCopy} transaction is included in the comparison, meaning you expect it to have a match on the ${otherSideCopy} side.`
23+
: `This ${thisSideCopy} transaction is excluded from the comparison, meaning you don't expect it to have a match on the ${otherSideCopy} side.`;
2424
return compared ? (
2525
<SearchCheck {...{ className, ...rest }}>
2626
<title>{title}</title>

0 commit comments

Comments
 (0)