-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: add home widgets - app of the day - block height - latest used apps - node status - onchain fees - what's new in alby hub * fix: seeded random function * fix: link to app on latest apps widget * chore: remove connected peers from node status widget * chore: minor adjustments to home page widgets * chore: move technical home page widgets into a nerds card
- Loading branch information
Showing
7 changed files
with
390 additions
and
80 deletions.
There are no files selected for viewing
56 changes: 56 additions & 0 deletions
56
frontend/src/components/home/widgets/AppOfTheDayWidget.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { ExternalLinkIcon } from "lucide-react"; | ||
import { Link } from "react-router-dom"; | ||
import { suggestedApps } from "src/components/SuggestedAppData"; | ||
import { Button } from "src/components/ui/button"; | ||
import { | ||
Card, | ||
CardContent, | ||
CardDescription, | ||
CardFooter, | ||
CardHeader, | ||
CardTitle, | ||
} from "src/components/ui/card"; | ||
|
||
export function AppOfTheDayWidget() { | ||
function seededRandom(seed: number) { | ||
const x = Math.sin(seed++) * 10000; | ||
return x - Math.floor(x); | ||
} | ||
|
||
const daysSinceEpoch = Math.floor(Date.now() / (1000 * 60 * 60 * 24)); | ||
const todayIndex = Math.floor( | ||
seededRandom(daysSinceEpoch) * suggestedApps.length | ||
); | ||
const app = suggestedApps[todayIndex]; | ||
|
||
return ( | ||
<Card> | ||
<CardHeader> | ||
<CardTitle>App of the Day</CardTitle> | ||
</CardHeader> | ||
<CardContent> | ||
<div className="flex gap-3 items-center"> | ||
<img | ||
src={app.logo} | ||
alt="logo" | ||
className="inline rounded-lg w-12 h-12" | ||
/> | ||
<div className="flex-grow"> | ||
<CardTitle>{app.title}</CardTitle> | ||
<CardDescription>{app.description}</CardDescription> | ||
</div> | ||
</div> | ||
</CardContent> | ||
<CardFooter className="flex flex-row justify-end"> | ||
<Link | ||
to={app.internal ? `/internal-apps/${app.id}` : `/appstore/${app.id}`} | ||
> | ||
<Button variant="outline"> | ||
<ExternalLinkIcon className="w-4 h-4 mr-2" /> | ||
Open | ||
</Button> | ||
</Link> | ||
</CardFooter> | ||
</Card> | ||
); | ||
} |
25 changes: 25 additions & 0 deletions
25
frontend/src/components/home/widgets/BlockHeightWidget.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { | ||
Card, | ||
CardContent, | ||
CardHeader, | ||
CardTitle, | ||
} from "src/components/ui/card"; | ||
import { useMempoolApi } from "src/hooks/useMempoolApi"; | ||
|
||
export function BlockHeightWidget() { | ||
const { data: blocks } = useMempoolApi<{ height: number }[]>("/v1/blocks"); | ||
|
||
if (!blocks?.length) { | ||
return null; | ||
} | ||
return ( | ||
<Card> | ||
<CardHeader> | ||
<CardTitle>Block Height</CardTitle> | ||
</CardHeader> | ||
<CardContent className="mt-6"> | ||
<p className="text-4xl font-semibold">{blocks[0].height}</p> | ||
</CardContent> | ||
</Card> | ||
); | ||
} |
55 changes: 55 additions & 0 deletions
55
frontend/src/components/home/widgets/LatestUsedAppsWidget.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import dayjs from "dayjs"; | ||
import { ChevronRight } from "lucide-react"; | ||
import { Link } from "react-router-dom"; | ||
import AppAvatar from "src/components/AppAvatar"; | ||
import { | ||
Card, | ||
CardContent, | ||
CardHeader, | ||
CardTitle, | ||
} from "src/components/ui/card"; | ||
import { useApps } from "src/hooks/useApps"; | ||
|
||
export function LatestUsedAppsWidget() { | ||
const { data: apps } = useApps(); | ||
if (!apps?.length) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<Card> | ||
<CardHeader> | ||
<CardTitle>Latest Used Apps</CardTitle> | ||
</CardHeader> | ||
<CardContent className="grid grid-cols-1 gap-4"> | ||
{apps | ||
.sort( | ||
(a, b) => | ||
new Date(b.lastEventAt ?? 0).getTime() - | ||
new Date(a.lastEventAt ?? 0).getTime() | ||
) | ||
.slice(0, 3) | ||
.map((app) => ( | ||
<Link key={app.id} to={`/apps/${app.appPubkey}`}> | ||
<div className="flex items-center justify-between w-full"> | ||
<div className="flex items-center justify-center gap-4"> | ||
<AppAvatar app={app} className="w-14 h-14 rounded-lg" /> | ||
<p className="text-xl font-semibold"> | ||
{app.name === "getalby.com" ? "Alby Account" : app.name} | ||
</p> | ||
</div> | ||
<div className="flex items-center justify-center gap-4"> | ||
<p className="text-sm text-muted-foreground"> | ||
{app.lastEventAt | ||
? dayjs(app.lastEventAt).fromNow() | ||
: "never"} | ||
</p> | ||
<ChevronRight className="text-muted-foreground w-8 h-8" /> | ||
</div> | ||
</div> | ||
</Link> | ||
))} | ||
</CardContent> | ||
</Card> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { Link } from "react-router-dom"; | ||
import { | ||
Card, | ||
CardContent, | ||
CardHeader, | ||
CardTitle, | ||
} from "src/components/ui/card"; | ||
import { useChannels } from "src/hooks/useChannels"; | ||
import { usePeers } from "src/hooks/usePeers"; | ||
|
||
export function NodeStatusWidget() { | ||
const { data: channels } = useChannels(); | ||
const { data: peers } = usePeers(); | ||
|
||
if (!channels || !peers) { | ||
return null; | ||
} | ||
return ( | ||
<Link to="/channels"> | ||
<Card> | ||
<CardHeader> | ||
<CardTitle>Node</CardTitle> | ||
</CardHeader> | ||
<CardContent> | ||
<p className="text-muted-foreground text-xs">Channels Online</p> | ||
<p className="text-xl font-semibold"> | ||
{channels.filter((c) => c.active).length || 0} /{" "} | ||
{channels.filter((c) => c.active).length || 0} | ||
</p> | ||
<p className="text-muted-foreground text-xs mt-6">Connected Peers</p> | ||
<p className="text-xl font-semibold"> | ||
{peers.filter((p) => p.isConnected).length || 0} /{" "} | ||
{peers.filter((p) => p.isConnected).length || 0} | ||
</p> | ||
</CardContent> | ||
</Card> | ||
</Link> | ||
); | ||
} |
55 changes: 55 additions & 0 deletions
55
frontend/src/components/home/widgets/OnchainFeesWidget.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { | ||
Card, | ||
CardContent, | ||
CardHeader, | ||
CardTitle, | ||
} from "src/components/ui/card"; | ||
import { useMempoolApi } from "src/hooks/useMempoolApi"; | ||
|
||
export function OnchainFeesWidget() { | ||
const { data: recommendedFees } = useMempoolApi<{ | ||
fastestFee: number; | ||
halfHourFee: number; | ||
economyFee: number; | ||
minimumFee: number; | ||
}>("/v1/fees/recommended"); | ||
|
||
if (!recommendedFees) { | ||
return null; | ||
} | ||
|
||
const entries = [ | ||
{ | ||
title: "No priority", | ||
value: recommendedFees.minimumFee, | ||
}, | ||
{ | ||
title: "Low priority", | ||
value: recommendedFees.economyFee, | ||
}, | ||
{ | ||
title: "Medium priority", | ||
value: recommendedFees.halfHourFee, | ||
}, | ||
{ | ||
title: "High priority", | ||
value: recommendedFees.fastestFee, | ||
}, | ||
]; | ||
|
||
return ( | ||
<Card> | ||
<CardHeader> | ||
<CardTitle>On-Chain Fees</CardTitle> | ||
</CardHeader> | ||
<CardContent className="grid grid-cols-2 gap-6"> | ||
{entries.map((entry) => ( | ||
<div key={entry.title}> | ||
<p className="text-muted-foreground text-xs">{entry.title}</p> | ||
<p className="text-xl font-semibold">{entry.value} sat/vB</p> | ||
</div> | ||
))} | ||
</CardContent> | ||
</Card> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { compare } from "compare-versions"; | ||
import { | ||
Card, | ||
CardContent, | ||
CardHeader, | ||
CardTitle, | ||
} from "src/components/ui/card"; | ||
import { useAlbyInfo } from "src/hooks/useAlbyInfo"; | ||
import { useInfo } from "src/hooks/useInfo"; | ||
|
||
export function WhatsNewWidget() { | ||
const { data: info } = useInfo(); | ||
const { data: albyInfo } = useAlbyInfo(); | ||
|
||
if (!info || !albyInfo || !albyInfo.hub.latestReleaseNotes) { | ||
return null; | ||
} | ||
|
||
const upToDate = | ||
info.version && | ||
info.version.startsWith("v") && | ||
compare(info.version.substring(1), albyInfo.hub.latestVersion, ">="); | ||
|
||
return ( | ||
<Card> | ||
<CardHeader> | ||
<CardTitle>What's New in {upToDate && "your "}Alby Hub?</CardTitle> | ||
</CardHeader> | ||
<CardContent> | ||
<p className="text-xl font-semibold">v{albyInfo.hub.latestVersion}</p> | ||
<p className="text-muted-foreground mt-1"> | ||
{albyInfo.hub.latestReleaseNotes} | ||
</p> | ||
{!upToDate && ( | ||
<p className="font-semibold mt-2 text-sm"> | ||
Make sure to update! you're currently running {info.version} | ||
</p> | ||
)} | ||
</CardContent> | ||
</Card> | ||
); | ||
} |
Oops, something went wrong.