feat: latest news on homepage
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
24
src/components/latest-news.tsx
Normal file
24
src/components/latest-news.tsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { EventKind, RequestBuilder } from "@snort/system";
|
||||||
|
import { NostrProfile } from "../const";
|
||||||
|
import { useRequestBuilder } from "@snort/system-react";
|
||||||
|
import { NewLink } from "./news-link";
|
||||||
|
|
||||||
|
export function LatestNews() {
|
||||||
|
const req = new RequestBuilder("latest-news");
|
||||||
|
req
|
||||||
|
.withFilter()
|
||||||
|
.kinds([EventKind.LongFormTextNote])
|
||||||
|
.authors([NostrProfile.id])
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
const posts = useRequestBuilder(req);
|
||||||
|
|
||||||
|
if (posts.length > 0) {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<div className="text-xl">Latest News</div>
|
||||||
|
<NewLink ev={posts[0]} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
26
src/components/news-link.tsx
Normal file
26
src/components/news-link.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { NostrEvent, NostrLink } from "@snort/system";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
|
export function NewLink({ ev }: { ev: NostrEvent }) {
|
||||||
|
const link = NostrLink.fromEvent(ev);
|
||||||
|
const title = ev.tags.find((a) => a[0] == "title")?.[1];
|
||||||
|
const posted = Number(
|
||||||
|
ev.tags.find((a) => a[0] == "published_at")?.[1] ?? ev.created_at,
|
||||||
|
);
|
||||||
|
const slug = title
|
||||||
|
?.toLocaleLowerCase()
|
||||||
|
.replace(/[:/]/g, "")
|
||||||
|
.trimStart()
|
||||||
|
.trimEnd()
|
||||||
|
.replace(/ /g, "-");
|
||||||
|
return (
|
||||||
|
<Link to={`/news/${slug}`} state={ev} key={link.tagKey}>
|
||||||
|
<div className="flex flex-col rounded-xl bg-neutral-900 px-3 py-4">
|
||||||
|
<div className="text-xl flex items-center justify-between">
|
||||||
|
<div>{title}</div>
|
||||||
|
<div>{new Date(posted * 1000).toDateString()}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
}
|
@ -4,6 +4,7 @@ import VpsCard from "../components/vps-card";
|
|||||||
import { ApiUrl, NostrProfile } from "../const";
|
import { ApiUrl, NostrProfile } from "../const";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { VpsCustomOrder } from "../components/vps-custom";
|
import { VpsCustomOrder } from "../components/vps-custom";
|
||||||
|
import { LatestNews } from "../components/latest-news";
|
||||||
|
|
||||||
export default function HomePage() {
|
export default function HomePage() {
|
||||||
const [offers, setOffers] = useState<VmTemplateResponse>();
|
const [offers, setOffers] = useState<VmTemplateResponse>();
|
||||||
@ -16,6 +17,7 @@ export default function HomePage() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
|
<LatestNews />
|
||||||
<div className="text-2xl">VPS Offers</div>
|
<div className="text-2xl">VPS Offers</div>
|
||||||
<div>
|
<div>
|
||||||
Virtual Private Server hosting with flexible plans, high uptime, and
|
Virtual Private Server hosting with flexible plans, high uptime, and
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { EventKind, NostrLink, RequestBuilder } from "@snort/system";
|
import { EventKind, RequestBuilder } from "@snort/system";
|
||||||
import { NostrProfile } from "../const";
|
import { NostrProfile } from "../const";
|
||||||
import { useRequestBuilder } from "@snort/system-react";
|
import { useRequestBuilder } from "@snort/system-react";
|
||||||
import { Link } from "react-router-dom";
|
import { NewLink } from "../components/news-link";
|
||||||
|
|
||||||
export function NewsPage() {
|
export function NewsPage() {
|
||||||
const req = new RequestBuilder("news");
|
const req = new RequestBuilder("news");
|
||||||
@ -26,29 +26,9 @@ export function NewsPage() {
|
|||||||
);
|
);
|
||||||
return b_posted - a_posted;
|
return b_posted - a_posted;
|
||||||
})
|
})
|
||||||
.map((a) => {
|
.map((a) => (
|
||||||
const link = NostrLink.fromEvent(a);
|
<NewLink ev={a} />
|
||||||
const title = a.tags.find((a) => a[0] == "title")?.[1];
|
))}
|
||||||
const posted = Number(
|
|
||||||
a.tags.find((a) => a[0] == "published_at")?.[1] ?? a.created_at,
|
|
||||||
);
|
|
||||||
const slug = title
|
|
||||||
?.toLocaleLowerCase()
|
|
||||||
.replace(/[:/]/g, "")
|
|
||||||
.trimStart()
|
|
||||||
.trimEnd()
|
|
||||||
.replace(/ /g, "-");
|
|
||||||
return (
|
|
||||||
<Link to={`/news/${slug}`} state={a} key={link.tagKey}>
|
|
||||||
<div className="flex flex-col rounded-xl bg-neutral-900 px-3 py-4">
|
|
||||||
<div className="text-xl flex items-center justify-between">
|
|
||||||
<div>{title}</div>
|
|
||||||
<div>{new Date(posted * 1000).toDateString()}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
{posts.length === 0 && <div>No posts yet..</div>}
|
{posts.length === 0 && <div>No posts yet..</div>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
Reference in New Issue
Block a user