aboutsummaryrefslogtreecommitdiffstats
path: root/app/components
diff options
context:
space:
mode:
authorbndw <ben@bdw.to>2023-04-26 17:49:25 -0700
committerbndw <ben@bdw.to>2023-04-26 17:49:25 -0700
commit8686078ae801fdc15df5a40ee158a43373d37c1c (patch)
treef8807fa764e917c6c4cdd30dcff31aa4bb060da8 /app/components
Initial commit
Diffstat (limited to 'app/components')
-rw-r--r--app/components/bitcoin-price.module.css2
-rw-r--r--app/components/bitcoin-price.tsx26
-rw-r--r--app/components/calculator.module.css15
-rw-r--r--app/components/calculator.tsx113
4 files changed, 156 insertions, 0 deletions
diff --git a/app/components/bitcoin-price.module.css b/app/components/bitcoin-price.module.css
new file mode 100644
index 0000000..fd52c7e
--- /dev/null
+++ b/app/components/bitcoin-price.module.css
@@ -0,0 +1,2 @@
1.price {
2}
diff --git a/app/components/bitcoin-price.tsx b/app/components/bitcoin-price.tsx
new file mode 100644
index 0000000..af837d9
--- /dev/null
+++ b/app/components/bitcoin-price.tsx
@@ -0,0 +1,26 @@
1"use client";
2
3import { useEffect, useState } from "react";
4import { BitcoinPrice as btcPrice } from "../utils/bitcoin-price";
5
6export const BitcoinPrice = () => {
7 const [isLoading, setLoading] = useState(false);
8 const bitcoinPrice = btcPrice();
9
10 const formatCurrency = (val: string) => {
11 const n = parseFloat(val);
12 const formatter = new Intl.NumberFormat("en-US", {
13 style: "currency",
14 currency: "USD",
15 maximumFractionDigits: 0,
16 });
17
18 return formatter.format(n);
19 };
20
21 useEffect(() => setLoading(!bitcoinPrice), [bitcoinPrice]);
22
23 if (isLoading || !bitcoinPrice) return <p>Loading...</p>;
24
25 return <div>Bitcoin price: {formatCurrency(bitcoinPrice)}</div>;
26};
diff --git a/app/components/calculator.module.css b/app/components/calculator.module.css
new file mode 100644
index 0000000..265760d
--- /dev/null
+++ b/app/components/calculator.module.css
@@ -0,0 +1,15 @@
1.form {
2}
3
4.input {
5 border-bottom: solid 1px #eee;
6 box-sizing: border-box;
7 font-size: 3em;
8 margin: 8px 0;
9 padding: 12px 20px;
10 width: 100%;
11}
12
13.input:focus {
14 outline: none;
15}
diff --git a/app/components/calculator.tsx b/app/components/calculator.tsx
new file mode 100644
index 0000000..006a755
--- /dev/null
+++ b/app/components/calculator.tsx
@@ -0,0 +1,113 @@
1"use client";
2
3import { useEffect, useState } from "react";
4import styles from "./calculator.module.css";
5import { BitcoinPrice } from "../utils/bitcoin-price";
6
7export const Calculator = () => {
8 const [sats, setSats] = useState("");
9 const [btc, setBtc] = useState("");
10 const [usd, setUsd] = useState("");
11
12 const formatCurrency = (val: string) => {
13 const formatter = new Intl.NumberFormat("en-US", {
14 style: "currency",
15 currency: "USD",
16 maximumFractionDigits: 2,
17 });
18 return formatter.format(parseNumber(val));
19 };
20
21 const formatDecimal = (val: any) => {
22 return val.toLocaleString("fullwide", {
23 useGrouping: true,
24 maximumSignificantDigits: 6,
25 });
26 };
27
28 const parseNumber = (val: string) => {
29 return parseFloat(val.replace(/[^0-9|.]/g, ""));
30 };
31
32 const btcPrice = parseNumber(BitcoinPrice());
33
34 const handleUpdate = (type: string, v: string) => {
35 const val = parseNumber(v);
36
37 let newbtc: number;
38 switch (type) {
39 case "sats":
40 setSats(v);
41
42 if (isNaN(val) || v.endsWith(".")) {
43 return;
44 }
45 setSats(formatDecimal(val));
46
47 newbtc = val / 100000000;
48 setBtc(formatDecimal(newbtc));
49 setUsd(formatCurrency(formatDecimal(newbtc * btcPrice)));
50 break;
51 case "btc":
52 setBtc(v);
53
54 if (isNaN(val) || v.endsWith(".")) {
55 return;
56 }
57 setBtc(formatDecimal(val));
58
59 setSats(formatDecimal(val * 100000000));
60 setUsd(formatCurrency(formatDecimal(val * btcPrice)));
61 break;
62 case "usd":
63 setUsd(formatCurrency(v));
64 if (isNaN(val)) {
65 return;
66 }
67
68 newbtc = val / btcPrice;
69 setBtc(formatDecimal(newbtc));
70 setSats(formatDecimal(newbtc * 100000000));
71 break;
72 }
73 };
74
75 useEffect(() => {
76 // Initialize the calculator with some numbers
77 handleUpdate("sats", "1000");
78 }, [btcPrice]);
79
80 return (
81 <form className="flex flex-col">
82 <label htmlFor="sats">Sats</label>
83 <input
84 className={styles.input}
85 onChange={(e) => handleUpdate("sats", e.target.value)}
86 value={sats}
87 type="text"
88 id="sats"
89 name="sats"
90 />
91
92 <label htmlFor="btc">BTC</label>
93 <input
94 className={styles.input}
95 onChange={(e) => handleUpdate("btc", e.target.value)}
96 value={btc}
97 type="text"
98 id="btc"
99 name="btc"
100 />
101
102 <label htmlFor="usd">USD</label>
103 <input
104 className={styles.input}
105 onChange={(e) => handleUpdate("usd", e.target.value)}
106 value={usd}
107 type="text"
108 id="usd"
109 name="usd"
110 />
111 </form>
112 );
113};