Statusphere running on a slice 🍕
1import { HydratedStatus } from "../types.ts";
2
3interface HomePageProps {
4 currentUser: {
5 isAuthenticated: boolean;
6 handle?: string;
7 };
8 statuses: HydratedStatus[];
9 userTimezone?: string;
10}
11
12const statusOptions = [
13 "👍",
14 "👎",
15 "💙",
16 "❤️",
17 "😍",
18 "🤩",
19 "😎",
20 "🤔",
21 "😴",
22 "🎉",
23 "🔥",
24 "💯",
25 "✨",
26 "⭐",
27 "🌟",
28 "🚀",
29 "💪",
30 "🙌",
31 "👏",
32 "🤝",
33 "🤗",
34 "😊",
35 "😄",
36 "😆",
37 "😂",
38 "🥳",
39 "🤯",
40 "😱",
41 "😭",
42 "💔",
43 "🙏",
44 "🤞",
45 "👀",
46 "🧠",
47 "💡",
48];
49
50export function HomePage({ currentUser, statuses, userTimezone }: HomePageProps) {
51 return (
52 <div>
53 <div class="card">
54 <h2>How are you feeling?</h2>
55 <div class="status-options">
56 {statusOptions.map((emoji) => (
57 <button
58 type="button"
59 key={emoji}
60 class="status-option"
61 title={`Set status to ${emoji}`}
62 hx-post="/status"
63 hx-vals={`{"status": "${emoji}"}`}
64 hx-target="#status-timeline"
65 hx-swap="outerHTML"
66 hx-indicator="#loading"
67 >
68 {emoji}
69 </button>
70 ))}
71 </div>
72 <div id="loading" class="htmx-indicator">
73 Setting status...
74 </div>
75 </div>
76
77 <div class="card">
78 <h3>Recent Statuses</h3>
79 <StatusTimeline statuses={statuses} userTimezone={userTimezone} />
80 </div>
81 </div>
82 );
83}
84
85interface StatusTimelineProps {
86 statuses: HydratedStatus[];
87 userTimezone?: string;
88}
89
90export function StatusTimeline({ statuses, userTimezone }: StatusTimelineProps) {
91 return (
92 <div id="status-timeline">
93 {statuses.length === 0 ? (
94 <div class="status-timeline">
95 <p class="status-meta">No statuses yet. Be the first to share!</p>
96 </div>
97 ) : (
98 <div class="status-timeline">
99 {statuses.map((status) => {
100 const authorHandle = status.author?.handle ||
101 status.did?.split(":").pop() ||
102 "unknown";
103 const createdAtDate = new Date(status.value.createdAt);
104 const formatOptions: Intl.DateTimeFormatOptions = {
105 year: 'numeric',
106 month: 'short',
107 day: 'numeric',
108 hour: 'numeric',
109 minute: '2-digit',
110 hour12: true
111 };
112 // Use user's timezone if available, otherwise let browser decide
113 if (userTimezone) {
114 formatOptions.timeZone = userTimezone;
115 }
116 const createdAt = new Intl.DateTimeFormat('en-US', formatOptions).format(createdAtDate);
117
118 return (
119 <div key={status.uri} class="status-item">
120 <div class="status-emoji">{status.value.status}</div>
121 <div>
122 <div class="status-meta">
123 @{authorHandle} • {createdAt}
124 </div>
125 </div>
126 </div>
127 );
128 })}
129 </div>
130 )}
131 </div>
132 );
133}