diff options
| author | Adam Soltys <[email protected]> | 2026-02-26 14:48:30 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-02-26 14:48:30 -0800 |
| commit | 2a59047dc8fc10560a7fde614238ee821cfb6b1b (patch) | |
| tree | edf33331d3715f2b615c49c62d454be2ac32a899 /src | |
| parent | d915b18b3883e53e9a10ab5de6d617361c61cf7d (diff) | |
| download | coinos-ui-2a59047dc8fc10560a7fde614238ee821cfb6b1b.tar.gz coinos-ui-2a59047dc8fc10560a7fde614238ee821cfb6b1b.zip | |
payment details redesign
Diffstat (limited to 'src')
| -rw-r--r-- | src/routes/(app)/payment/[id]/+page.svelte | 275 |
1 files changed, 138 insertions, 137 deletions
diff --git a/src/routes/(app)/payment/[id]/+page.svelte b/src/routes/(app)/payment/[id]/+page.svelte index af729233..ca3d5b6a 100644 --- a/src/routes/(app)/payment/[id]/+page.svelte +++ b/src/routes/(app)/payment/[id]/+page.svelte @@ -16,6 +16,8 @@ import locales from "$lib/locales"; import { goto } from "$app/navigation"; + let expanded: Set<string> = $state(new Set()); + let { data } = $props(); let user = $derived(data.user); let p = $derived(data.payment); @@ -72,16 +74,16 @@ </script> {#snippet field(title, amount)} - <div> - <span class="text-lg text-secondary">{$t(title)}</span> + <div class="flex justify-between items-center py-4 border-b border-base-300 min-h-20"> + <span class="text-secondary">{$t(title)}</span> <button type="button" - class="flex gap-2 items-end" + class="flex gap-1 items-center text-right text-lg" onclick={toggleFiat} aria-label="Toggle currency display" > {#if $fiat} - <div class="flex items-center">{f(toFiat(amount, rate), currency, userLocale)}</div> + <div>{f(toFiat(amount, rate), currency, userLocale)}</div> {:else} <div class="flex items-center"> <iconify-icon noobserver icon="ph:lightning-fill" class="text-yellow-300"></iconify-icon> @@ -92,155 +94,154 @@ </div> {/snippet} -<div class="container mx-auto max-w-lg px-4 space-y-8 break-all text-2xl"> - <h1 class="px-3 md:px-0 text-center text-3xl md:text-4xl font-semibold mb-10"> - {$t(amount < 0 ? "payments.sent" : "payments.received")} - </h1> +{#snippet copyable(label, value, href)} + <div class="flex justify-between items-center gap-4 py-4 border-b border-base-300 min-h-20"> + <span class="text-secondary shrink-0">{label}</span> + <div class="flex items-center gap-2 min-w-0"> + <button + class="font-mono text-sm text-right break-all hover:opacity-80" + onclick={() => { + if (expanded.has(label)) { + expanded.delete(label); + } else { + expanded.add(label); + } + expanded = new Set(expanded); + }} + aria-label={expanded.has(label) ? "Collapse" : "Expand"} + > + {#if expanded.has(label)} + {value} + {:else} + {value.slice(0, 8)}...{value.slice(-8)} + {/if} + </button> + <button + class="shrink-0 hover:opacity-80" + onclick={() => copy(value)} + aria-label="Copy {label}" + > + <iconify-icon noobserver icon="ph:copy-bold" width="20" class="text-secondary"></iconify-icon> + </button> + {#if href} + <a {href} target="_blank" rel="noreferrer" class="shrink-0 hover:opacity-80" aria-label="View in explorer"> + <iconify-icon noobserver icon="ph:arrow-square-out-bold" width="20" class="text-secondary"></iconify-icon> + </a> + {/if} + </div> + </div> +{/snippet} + +<div class="container mx-auto max-w-lg px-4 pb-12"> + <div class="flex flex-col items-center gap-2 mb-8"> + <h1 class="text-2xl font-semibold"> + {$t(amount < 0 ? "payments.sent" : "payments.received")} + </h1> + <button + type="button" + class="text-4xl font-bold tracking-tight" + onclick={toggleFiat} + aria-label="Toggle currency display" + > + {#if $fiat} + {f(toFiat(a, rate), currency, userLocale)} + {:else} + <span class="flex items-center"> + <iconify-icon noobserver icon="ph:lightning-fill" class="text-yellow-300"></iconify-icon> + {s(a, userLocale)} + </span> + {/if} + </button> + <div class="text-secondary"> + {format(new Date(created), "MMM d, yyyy", { locale })} · {format(new Date(created), "h:mmaaa", { locale })} + </div> + </div> {#if p.with} - <a href={`/${p.with.username}`}> - <span class="text-lg text-secondary my-auto mr-2">{direction}</span> - <div class="flex"> - <div class="my-auto"> - <Avatar user={p.with} size={20} disabled={true} /> - </div> - <div class="my-auto ml-1">{p.with.username}</div> + <a href={`/${p.with.username}`} class="flex items-center gap-3 py-3 border-b border-base-300"> + <span class="text-secondary">{direction}</span> + <div class="flex items-center gap-2 ml-auto"> + <Avatar user={p.with} size={20} disabled={true} /> + <span>{p.with.username}</span> </div> </a> {/if} - {@render field("payments.amount", a)} + <div class="mt-2"> + {#if tip} + {@render field("payments.amount", a)} + {@render field("invoice.tip", tip)} + {@render field("payments.total", a + (tip || 0))} + {/if} - {#if tip} - {@render field("invoice.tip", tip)} - {@render field("payments.total", a + (tip || 0))} - {/if} + {@render field("payments.networkFee", fee)} - {@render field("payments.networkFee", fee)} + {#if ourfee > 0} + {@render field("payments.platformFee", ourfee)} + {/if} - {#if ourfee > 0} - {@render field("payments.platformFee", ourfee)} - {/if} - - <div> - <span class="text-lg text-secondary">{$t("payments.exchangeRate")}</span> - <div class="flex justify-left gap-2"> - <div class="text-secondary flex"> - <div class="flex mr-1"> - <div class="my-auto mr-1">1</div> - <img src="/images/bitcoin.svg" class="w-5 my-auto" alt="Bitcoin" /> + <div class="flex justify-between items-center py-4 border-b border-base-300 min-h-20"> + <span class="text-secondary">{$t("payments.exchangeRate")}</span> + <div class="flex gap-3 text-secondary"> + <div class="flex items-center gap-1"> + <span>1</span> + <img src="/images/bitcoin.svg" class="w-4" alt="Bitcoin" /> + <span>= {f(rate, currency, userLocale, 0, 0)}</span> </div> - <div>= {f(rate, currency, userLocale, 0, 0)}</div> </div> - <div class="text-secondary flex"> - <div class="flex items-center"> - <iconify-icon noobserver icon="ph:lightning-fill" class="text-yellow-300"></iconify-icon> - {s((1 * sats) / rate)} = {f(1, currency, userLocale, 0, 0)} - </div> - </div> - </div> - </div> - - <div> - <span class="text-lg text-secondary">{$t("payments.date")}</span> - <div> - {format(new Date(created), "MMM d, yyyy", { locale })} {format(new Date(created), "h:mmaaa", { locale })} </div> - </div> - {#if type === types.ecash && amount < 0} - <a href={`/ecash/${memo}`} class="btn"> - <img src="/images/cash.png" class="w-8" alt="Cash" /> - <div>{$t("payments.ecashToken")}</div> - </a> - {:else if type === types.fund} - <a href={`/fund/${memo}`} class="btn btn-accent"> - <iconify-icon noobserver icon="ph:lightning-fill" class="text-yellow-300"></iconify-icon> - {$t( - "payments.viewFund", - )} - </a> - {:else if memo?.includes("9734")} - {@const eid = JSON.parse(memo).tags.find((t) => t[0] === "e")[1]} - <a href={`/e/${eid}`} class="btn btn-accent"> - <img src="/images/nostr.png" class="w-8" alt="Nostr" /> - <iconify-icon noobserver icon="ph:lightning-fill" class="text-yellow-300"></iconify-icon> - {$t( - "payments.zappedEvent", - )} - </a> - {:else if memo} - <div> - <span class="text-lg text-secondary">{$t("payments.memo")}</span> - <div> - {#if memo.includes("text/plain")} - {JSON.parse(memo)[0][1]} - {:else} - {memo} - {/if} + {#if type === types.ecash && amount < 0} + <div class="pt-4"> + <a href={`/ecash/${memo}`} class="btn w-full"> + <img src="/images/cash.png" class="w-6" alt="Cash" /> + {$t("payments.ecashToken")} + </a> </div> - </div> - {/if} - - {#if type === types.lightning || type === types.bolt12} - <div> - <span class="text-lg text-secondary">{$t("payments.invoice")}</span> - <div>{hash}</div> - </div> - - <div> - <span class="text-lg text-secondary">{$t("payments.preimage")}</span> - <div>{ref}</div> - </div> - {/if} - - {#if type === types.ark && hash} - <div> - <span class="text-lg text-secondary">Txid</span> - <div class="flex"> - <div>{hash}</div> - <button - class="flex font-bold hover:opacity-80 mb-auto my-auto" - onclick={() => copy(hash)} - aria-label="Copy transaction ID" - ></button> + {:else if type === types.fund} + <div class="pt-4"> + <a href={`/fund/${memo}`} class="btn btn-accent w-full"> + <iconify-icon noobserver icon="ph:lightning-fill" class="text-yellow-300"></iconify-icon> + {$t("payments.viewFund")} + </a> </div> - </div> - {/if} - - {#if type === "bitcoin" || type === "liquid"} - <div> - <span class="text-lg text-secondary">Txid</span> - <div class="flex"> - <div> - <a - href={`${expl}/tx/${txid}${vout ? "#vout=" + vout : ""}`} - target="_blank" - rel="noreferrer" - > - {txid} - </a> + {:else if memo?.includes("9734")} + {@const eid = JSON.parse(memo).tags.find((t) => t[0] === "e")[1]} + <div class="pt-4"> + <a href={`/e/${eid}`} class="btn btn-accent w-full"> + <img src="/images/nostr.png" class="w-6" alt="Nostr" /> + <iconify-icon noobserver icon="ph:lightning-fill" class="text-yellow-300"></iconify-icon> + {$t("payments.zappedEvent")} + </a> + </div> + {:else if memo} + <div class="flex justify-between items-start gap-4 py-3 border-b border-base-300"> + <span class="text-sm text-secondary shrink-0">{$t("payments.memo")}</span> + <div class="text-right break-all"> + {#if memo.includes("text/plain")} + {JSON.parse(memo)[0][1]} + {:else} + {memo} + {/if} </div> - <button - class="flex font-bold hover:opacity-80 mb-auto my-auto" - onclick={() => copy(txid)} - aria-label="Copy transaction ID" - ></button> </div> - </div> - {/if} + {/if} - {#if path} - <div> - <span class="text-lg text-secondary">Path</span> - <div class="flex"> - <div>{path}</div> - <button - class="flex font-bold hover:opacity-80 mb-auto my-auto" - onclick={() => copy(path)} - aria-label="Copy path" - ></button> - </div> - </div> - {/if} + {#if type === types.lightning || type === types.bolt12} + {@render copyable($t("payments.invoice"), hash)} + {@render copyable($t("payments.preimage"), ref)} + {/if} + + {#if type === types.ark && hash} + {@render copyable("Txid", hash)} + {/if} + + {#if type === "bitcoin" || type === "liquid"} + {@render copyable("Txid", txid, `${expl}/tx/${txid}${vout ? "#vout=" + vout : ""}`)} + {/if} + + {#if path} + {@render copyable("Path", path)} + {/if} + </div> </div> |
