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}