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) {
47 return (
48 <span
49 className="badge bg-dark"
50 style={{ color: "#595959 !important" }}
51 >
52 Error: {error}
53 </span>
54 );
55 }
56 if (!data) {
57 return (
58 <span
59 className="badge bg-dark"
60 style={{ color: "#595959 !important" }}
61 >
62 Loading status...
63 </span>
64 );
65 }
66
67 const date = new Date(data.createdAt);
68 const now = new Date();
69 const diff = now.getTime() - date.getTime();
70
71 const minutes = Math.floor(diff / 60000);
72 const hours = Math.floor(minutes / 60);
73 const days = Math.floor(hours / 24);
74
75 let timeAgo = "just now";
76 if (days > 0) timeAgo = `${days} days ago`;
77 else if (hours > 0) timeAgo = `${hours} hours ago`;
78 else if (minutes > 0) timeAgo = `${minutes} minutes ago`;
79
80 const oldStatusClasses = days > 3
81 ? "opacity-75 text-decoration-line-through"
82 : "";
83
84 return (
85 <a
86 href={data.link}
87 target="_blank"
88 className={`badge bg-white ${oldStatusClasses}`}
89 >
90 Index is.. "{data.text}", {timeAgo}
91 </a>
92 );
93}