Skip to content

Commit

Permalink
feat: redesign first channel payment UI (#819)
Browse files Browse the repository at this point in the history
  • Loading branch information
rolznz authored Nov 27, 2024
1 parent c3ddb5d commit 199f65f
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 8 deletions.
22 changes: 18 additions & 4 deletions frontend/src/components/Loading.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
import { Loader2 } from "lucide-react";
import { Loader, Loader2 } from "lucide-react";
import { cn } from "src/lib/utils";

function Loading({ className }: { className?: string }) {
function Loading({
className,
variant = "loader2",
}: {
className?: string;
variant?: "loader2" | "loader";
}) {
const Component = variant === "loader2" ? Loader2 : Loader;

return (
<>
<Loader2 className={cn("h-6 w-6 animate-spin", className)}>
<Component
className={cn(
"h-6 w-6",
variant === "loader2" ? "animate-spin" : "animate-spin-slow",
className
)}
>
<span className="sr-only">Loading...</span>
</Loader2>
</Component>
</>
);
}
Expand Down
72 changes: 72 additions & 0 deletions frontend/src/components/PayLightningInvoice.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Invoice, fiat } from "@getalby/lightning-tools";
import { CopyIcon, LightbulbIcon } from "lucide-react";
import React from "react";
import QRCode from "react-qr-code";
import { LightningIcon } from "src/components/icons/Lightning";
import Loading from "src/components/Loading";
import { Button, ExternalLinkButton } from "src/components/ui/button";
import { useToast } from "src/components/ui/use-toast";
import { copyToClipboard } from "src/lib/clipboard";

type PayLightningInvoiceProps = {
invoice: string;
};

export function PayLightningInvoice({ invoice }: PayLightningInvoiceProps) {
const amount = new Invoice({
pr: invoice,
}).satoshi;
const [fiatAmount, setFiatAmount] = React.useState(0);
React.useEffect(() => {
fiat
.getFiatValue({ satoshi: amount, currency: "USD" })
.then((fiatAmount) => setFiatAmount(fiatAmount));
}, [amount]);
const { toast } = useToast();
const copy = () => {
copyToClipboard(invoice, toast);
};

return (
<div className="w-96 flex flex-col gap-6 p-6 items-center justify-center">
<div className="flex items-center justify-center gap-2 text-muted-foreground">
<Loading variant="loader" />
<p>Waiting for lightning payment...</p>
</div>
<div className="w-full relative flex items-center justify-center">
<QRCode value={invoice} className="w-full" />
<div className="bg-primary-foreground absolute">
<LightningIcon className="w-12 h-12" />
</div>
</div>
<div>
<p className="text-lg font-semibold">
{new Intl.NumberFormat().format(amount)} sats
</p>
<p className="flex flex-col items-center justify-center">
{new Intl.NumberFormat("en-US", {
currency: "USD",
style: "currency",
}).format(fiatAmount)}
</p>
</div>
<div className="flex gap-4 w-full">
<Button
onClick={copy}
variant="outline"
className="flex-1 flex gap-2 items-center justify-center"
>
<CopyIcon className="w-4 h-4 mr-2" />
Copy Invoice
</Button>
<ExternalLinkButton
to="https://guides.getalby.com/user-guide/alby-account-and-browser-extension/alby-hub/wallet/open-your-first-channel"
variant="secondary"
className="flex-1 flex gap-2 items-center justify-center"
>
<LightbulbIcon className="w-4 h-4" /> How to pay
</ExternalLinkButton>
</div>
</div>
);
}
43 changes: 43 additions & 0 deletions frontend/src/components/icons/Lightning.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { SVGAttributes } from "react";

export function LightningIcon(props: SVGAttributes<SVGElement>) {
return (
<svg
width="64"
height="64"
viewBox="0 0 64 64"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<g clip-path="url(#clip0_5703_10021)">
<mask
id="mask0_5703_10021"
style={{ maskType: "luminance" }}
maskUnits="userSpaceOnUse"
x="0"
y="0"
width="64"
height="64"
>
<path d="M64 0H0V64H64V0Z" fill="white" />
</mask>
<g mask="url(#mask0_5703_10021)">
<path
d="M31.9961 64C49.6692 64 63.9961 49.6731 63.9961 32C63.9961 14.3269 49.6692 0 31.9961 0C14.323 0 -0.00390625 14.3269 -0.00390625 32C-0.00390625 49.6731 14.323 64 31.9961 64Z"
fill="#FFDF6F"
/>
<path
d="M33.3099 12.4881C32.5628 12.3958 31.9053 12.6446 31.3666 13.0015C30.8466 13.346 30.3632 13.8383 29.8999 14.3907C28.9936 15.4713 27.9225 17.0832 26.5847 19.0983L19.0419 30.4596C18.1163 31.8537 17.3375 33.0266 16.8825 33.9955C16.4166 34.9876 16.1007 36.1567 16.7178 37.3017C17.335 38.4468 18.4871 38.8294 19.5742 38.9896C20.6357 39.1461 22.0465 39.146 23.7235 39.146H24.9235C25.8369 39.146 26.4043 39.1481 26.8221 39.197C27.2053 39.2418 27.2901 39.3106 27.3097 39.3265C27.3533 39.3618 27.3937 39.4022 27.4291 39.4457C27.445 39.4652 27.5135 39.549 27.5584 39.9311C27.6074 40.3476 27.6096 40.9132 27.6096 41.8239V41.9194C27.6095 44.3546 27.6095 46.3017 27.7679 47.7093C27.8484 48.4249 27.979 49.1014 28.2219 49.6748C28.4735 50.2688 28.884 50.8381 29.5581 51.1722C29.9135 51.3484 30.2962 51.4633 30.6901 51.5119C31.4372 51.6042 32.0947 51.3554 32.6334 50.9985C33.1534 50.654 33.6368 50.1617 34.1001 49.6093C35.0114 48.5227 36.0894 46.899 37.4375 44.8683L44.9581 33.5404C45.8837 32.1463 46.6625 30.9734 47.1175 30.0045C47.5834 29.0124 47.8993 27.8433 47.2822 26.6983C46.665 25.5532 45.5129 25.1706 44.4258 25.0104C43.3643 24.8539 41.9535 24.854 40.2765 24.854L39.0765 24.854C38.1631 24.854 37.5957 24.8519 37.1779 24.803C36.7947 24.7582 36.7099 24.6894 36.6903 24.6735C36.6467 24.6382 36.6063 24.5978 36.5709 24.5543C36.555 24.5348 36.4865 24.4509 36.4416 24.0689C36.3926 23.6524 36.3904 23.0868 36.3904 22.1761V22.0806C36.3905 19.6454 36.3905 17.6982 36.2321 16.2907C36.1516 15.5751 36.021 14.8986 35.7781 14.3252C35.5265 13.7312 35.116 13.1619 34.4419 12.8278C34.0865 12.6516 33.7038 12.5367 33.3099 12.4881Z"
fill="white"
/>
</g>
</g>
<defs>
<clipPath id="clip0_5703_10021">
<rect width="64" height="64" fill="white" />
</clipPath>
</defs>
</svg>
);
}
4 changes: 2 additions & 2 deletions frontend/src/screens/channels/first/FirstChannel.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Payment } from "@getalby/bitcoin-connect-react";
import { ChevronDown } from "lucide-react";
import React from "react";
import { Link, useNavigate } from "react-router-dom";
Expand All @@ -19,6 +18,7 @@ import { AutoChannelRequest, AutoChannelResponse } from "src/types";
import { request } from "src/utils/request";

import { MempoolAlert } from "src/components/MempoolAlert";
import { PayLightningInvoice } from "src/components/PayLightningInvoice";
import {
ALBY_HIDE_HOSTED_BALANCE_BELOW,
ALBY_MIN_HOSTED_BALANCE_FOR_FIRST_CHANNEL,
Expand Down Expand Up @@ -110,7 +110,7 @@ export function FirstChannel() {
{new Intl.NumberFormat().format(channelSize)} sats of incoming
liquidity.
</p>
<Payment invoice={invoice} paymentMethods="external" />
<PayLightningInvoice invoice={invoice} />

<Separator className="mt-8" />
<p className="mt-8 text-sm mb-2 text-muted-foreground">
Expand Down
1 change: 1 addition & 0 deletions frontend/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ module.exports = {
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
"spin-slow": "spin 3s linear infinite",
},
fontFamily: {
sans: ["Inter var", ...defaultTheme.fontFamily.sans],
Expand Down
2 changes: 1 addition & 1 deletion frontend/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ const insertDevCSPPlugin: Plugin = {
"<head>",
`<head>
<!-- DEV-ONLY CSP - when making changes here, also update the CSP header in http_service.go (without the nonce!) -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self' ${DEVELOPMENT_NONCE}; img-src 'self' https://uploads.getalby-assets.com https://getalby.com; connect-src 'self' https://api.getalby.com"/>`
<meta http-equiv="Content-Security-Policy" content="default-src 'self' ${DEVELOPMENT_NONCE}; img-src 'self' https://uploads.getalby-assets.com https://getalby.com; connect-src 'self' https://api.getalby.com https://getalby.com"/>`
);
},
},
Expand Down
2 changes: 1 addition & 1 deletion http/http_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (httpSvc *HttpService) RegisterSharedRoutes(e *echo.Echo) {
e.Use(middleware.SecureWithConfig(middleware.SecureConfig{
ContentTypeNosniff: "nosniff",
XFrameOptions: "DENY",
ContentSecurityPolicy: "default-src 'self'; img-src 'self' https://uploads.getalby-assets.com https://getalby.com; connect-src 'self' https://api.getalby.com",
ContentSecurityPolicy: "default-src 'self'; img-src 'self' https://uploads.getalby-assets.com https://getalby.com; connect-src 'self' https://api.getalby.com https://getalby.com",
ReferrerPolicy: "no-referrer",
}))
e.Use(middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{
Expand Down

0 comments on commit 199f65f

Please sign in to comment.