My personal site hosted @ https://indexx.dev
1import { useEffect, useState } from "react";
2const actorDid = import.meta.env.PUBLIC_ACTOR_DID;
3
4if (!actorDid) {
5 console.error(
6 "PUBLIC_ACTOR_DID is not defined. Please check your .env file.",
7 );
8}
9
10export default function Status() {
11 const [data, setData] = useState(null);
12 const [error, setError] = useState(null);
13
14 useEffect(() => {
15 const fetchStatus = async () => {
16 if (!actorDid) {
17 setError("Configuration error: Actor DID is missing.");
18 return;
19 }
20 try {
21 const res = await fetch(
22 `https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=${actorDid}&limit=1&filter=posts_no_replies`,
23 );
24 if (!res.ok) throw new Error(`HTTP ${res.status}`);
25
26 const json = await res.json();
27 const latestPost = json.feed[0].post;
28
29 const status = {
30 text: latestPost.record.text,
31 createdAt: latestPost.record.createdAt,
32 link: `https://bsky.app/profile/${actorDid}/post/${
33 latestPost.uri.split("/")[4]
34 }`,
35 };
36 setData(status);
37 } catch (err) {
38 console.error("Fetch failed:", err);
39 setError(err.message);
40 }
41 };
42
43 fetchStatus();
44 }, [actorDid]);
45
46 if (error) return <span>Error: {error}</span>;
47 if (!data) return <span>Loading status...</span>;
48
49 const date = new Date(data.createdAt);
50 const now = new Date();
51 const diff = now.getTime() - date.getTime();
52
53 const minutes = Math.floor(diff / 60000);
54 const hours = Math.floor(minutes / 60);
55 const days = Math.floor(hours / 24);
56
57 let timeAgo = "just now";
58 if (days > 0) timeAgo = `${days} days ago`;
59 else if (hours > 0) timeAgo = `${hours} hours ago`;
60 else if (minutes > 0) timeAgo = `${minutes} minutes ago`;
61
62 const oldStatusClasses = days > 3
63 ? "opacity-75 text-decoration-line-through"
64 : "";
65
66 return (
67 <a
68 href={data.link}
69 target="_blank"
70 className={`badge bg-white ${oldStatusClasses}`}
71 >
72 Index is.. "{data.text}", {timeAgo}
73 </a>
74 );
75}