Skip to content
This repository has been archived by the owner on Sep 2, 2024. It is now read-only.

feat: add expiry notices to connection cards #460

Merged
merged 4 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 0 additions & 107 deletions frontend/src/components/AppCard.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
CheckCircle2,
CircleX,
Edit,
EditIcon,
ExternalLinkIcon,
Link2Icon,
ZapIcon,
Expand All @@ -10,6 +10,8 @@ import { Link } from "react-router-dom";
import ExternalLink from "src/components/ExternalLink";
import Loading from "src/components/Loading";
import UserAvatar from "src/components/UserAvatar";
import { AppCardConnectionInfo } from "src/components/connections/AppCardConnectionInfo";
import { AppCardNotice } from "src/components/connections/AppCardNotice";
import { Button } from "src/components/ui/button";
import {
Card,
Expand All @@ -19,7 +21,6 @@ import {
CardTitle,
} from "src/components/ui/card";
import { LoadingButton } from "src/components/ui/loading-button";
import { Progress } from "src/components/ui/progress";
import { Separator } from "src/components/ui/separator";
import { useAlbyMe } from "src/hooks/useAlbyMe";
import { LinkStatus, useLinkAccount } from "src/hooks/useLinkAccount";
Expand All @@ -33,21 +34,24 @@ function AlbyConnectionCard({ connection }: { connection?: App }) {
return (
<Card>
<CardHeader>
<CardTitle>Alby Account</CardTitle>
<CardTitle className="relative">
Alby Account
{connection && <AppCardNotice app={connection} />}
</CardTitle>
<CardDescription>
Link Your Alby Account to use your lightning address with Alby Hub and
use apps that you connected to your Alby Account.
</CardDescription>
</CardHeader>
<Separator />
<CardContent>
<div className="grid grid-cols-1 xl:grid-cols-2 mt-5 gap-3 items-center">
<CardContent className="group">
<div className="grid grid-cols-1 xl:grid-cols-2 mt-5 gap-3 items-center relative">
<div className="flex flex-col gap-4">
<div className="flex flex-row gap-4 ">
<UserAvatar className="h-14 w-14" />
<div className="flex flex-col">
<div className="text-xl font-semibold">{albyMe?.name}</div>
<div className="flex flex-row items-center gap-1 text-sm">
<div className="flex flex-row items-center gap-1 text-sm text-muted-foreground">
<ZapIcon className="w-4 h-4" />
{albyMe?.lightning_address}
</div>
Expand Down Expand Up @@ -89,63 +93,13 @@ function AlbyConnectionCard({ connection }: { connection?: App }) {
</div>
</div>
<div>
{connection && (
<>
{connection.maxAmount > 0 && (
<>
<div className="flex flex-row justify-between">
<div className="mb-2">
<p className="text-xs text-secondary-foreground font-medium">
You've spent
</p>
<p className="text-xl font-medium">
{new Intl.NumberFormat().format(
connection.budgetUsage
)}{" "}
sats
</p>
</div>
<div className="text-right">
{" "}
<p className="text-xs text-secondary-foreground font-medium">
Left in budget
</p>
<p className="text-xl font-medium text-muted-foreground">
{new Intl.NumberFormat().format(
connection.maxAmount - connection.budgetUsage
)}{" "}
sats
</p>
</div>
</div>
<Progress
className="h-4"
value={
(connection.budgetUsage * 100) / connection.maxAmount
}
/>
<div className="flex flex-row justify-between text-xs items-center mt-2">
{connection.maxAmount > 0 ? (
<>
{new Intl.NumberFormat().format(connection.maxAmount)}{" "}
sats / {connection.budgetRenewal}
</>
) : (
"Not set"
)}
<div>
<Link to={`/apps/${connection.nostrPubkey}`}>
<Button variant="ghost" size="sm">
<Edit className="w-4 h-4 mr-2" />
Edit
</Button>
</Link>
</div>
</div>
</>
)}
</>
)}
<Link
to={`/apps/${connection?.nostrPubkey}`}
className="absolute top-0 right-0"
>
<EditIcon className="w-4 h-4 hidden group-hover:inline text-muted-foreground hover:text-card-foreground" />
</Link>
{connection && <AppCardConnectionInfo connection={connection} />}
</div>
</div>
</CardContent>
Expand Down
45 changes: 45 additions & 0 deletions frontend/src/components/connections/AppCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import { Link } from "react-router-dom";
import AppAvatar from "src/components/AppAvatar";
import { AppCardConnectionInfo } from "src/components/connections/AppCardConnectionInfo";
import { AppCardNotice } from "src/components/connections/AppCardNotice";
import {
Card,
CardContent,
CardHeader,
CardTitle,
} from "src/components/ui/card";
import { App } from "src/types";

dayjs.extend(relativeTime);

type Props = {
app: App;
csrf?: string;
};

export default function AppCard({ app }: Props) {
return (
<>
<Link className="h-full" to={`/apps/${app.nostrPubkey}`}>
<Card className="h-full flex flex-col group">
<CardHeader>
<CardTitle className="relative">
<AppCardNotice app={app} />
<div className="flex flex-row items-center">
<AppAvatar className="w-10 h-10" appName={app.name} />
<div className="flex-1 font-semibold text-xl whitespace-nowrap text-ellipsis overflow-hidden ml-4">
{app.name}
</div>
</div>
</CardTitle>
</CardHeader>
<CardContent className="flex-1 flex flex-col">
<AppCardConnectionInfo connection={app} />
</CardContent>
</Card>
</Link>
</>
);
}
59 changes: 59 additions & 0 deletions frontend/src/components/connections/AppCardConnectionInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import dayjs from "dayjs";
import { Progress } from "src/components/ui/progress";
import { formatAmount } from "src/lib/utils";
import { App } from "src/types";

type AppCardConnectionInfoProps = {
connection: App;
};

export function AppCardConnectionInfo({
connection,
}: AppCardConnectionInfoProps) {
return (
<>
{connection.maxAmount > 0 && (
<>
<div className="flex flex-row justify-between">
<div className="mb-2">
<p className="text-xs text-secondary-foreground font-medium">
Left in budget
</p>
<p className="text-xl font-medium">
{new Intl.NumberFormat().format(
connection.maxAmount - connection.budgetUsage
)}{" "}
sats
</p>
</div>
</div>
<Progress
className="h-4"
value={(connection.budgetUsage * 100) / connection.maxAmount}
/>
<div className="flex flex-row justify-between text-xs items-center text-muted-foreground mt-2">
<div>
{connection.maxAmount && (
<>{formatAmount(connection.maxAmount * 1000)} sats</>
)}
</div>
<div>
{connection.maxAmount > 0 &&
connection.budgetRenewal !== "never" && (
<>Renews {connection.budgetRenewal}</>
)}
</div>
</div>
{connection.lastEventAt && (
<div className="flex flex-row justify-between text-xs items-center text-muted-foreground">
<div className="flex flex-row justify-between">
<div>Last used:&nbsp;</div>
<div>{dayjs(connection.lastEventAt).fromNow()}</div>
</div>
</div>
)}
</>
)}
</>
);
}
Loading
Loading