import {renderer} from "@b9g/crank/dom";
import {Suspense} from "@b9g/crank/async";
function formatNumber(number, type) {
number = number.padEnd(16, "0");
if (type === "American Express") {
return [number.slice(0, 4), number.slice(4, 10), number.slice(10, 15)].join(" ");
}
return [
number.slice(0, 4),
number.slice(4, 8),
number.slice(8, 12),
number.slice(12),
].join(" ");
}
function CreditCard({type, expiration, number, owner}) {
return (
<div style="
padding: 10px;
margin: 10px 0;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 1fr);
border: 1px solid currentcolor;
border-radius: 10px;
">
<pre>{formatNumber(number, type)}</pre>
<pre>Exp: {expiration}</pre>
<pre>{type}</pre>
<pre>{owner}</pre>
</div>
);
}
async function *LoadingCreditCard() {
let count = 0;
const interval = setInterval(() => {
this.refresh(() => count++);
}, 250);
this.cleanup(() => clearInterval(interval));
for ({} of this) {
yield (
<CreditCard
number={"*".repeat(count) + "?".repeat(Math.max(0, 16 - count))}
type={"Loading" + ".".repeat(count % 4)}
owner="__ __"
expiration="__/__"
/>
);
}
}
async function MockCreditCard({throttle}) {
if (throttle) {
await new Promise((r) => setTimeout(r, 2000));
}
const res = await fetch("https://fakerapi.it/api/v2/creditCards?_quantity=1");
if (res.status === 429) {
return (
<marquee>Too many requests. Please use free APIs responsibly.</marquee>
);
}
const {data: [card]} = await res.json();
return (
<CreditCard
number={card.number}
type={card.type}
owner={card.owner}
expiration={card.expiration}
/>
);
}
function RandomCreditCard({throttle}) {
return (
<Suspense fallback={<LoadingCreditCard />}>
<MockCreditCard throttle={throttle} />
</Suspense>
);
}
function *CreditCardGenerator() {
let throttle = false;
const toggleThrottle = () => {
this.refresh(() => throttle = !throttle);
};
for ({} of this) {
yield (
<div>
<div>
<button onclick={() => this.refresh()}>
Generate new card
</button>
{" "}
<button onclick={toggleThrottle}>
{throttle ? "Unthrottle" : "Throttle"} API
</button>
</div>
<RandomCreditCard throttle={throttle} />
</div>
);
}
}
renderer.render(<CreditCardGenerator />, document.body);
.png)

