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}