avycado13-valboard.web.val.run
1
2
3
4
5
6
7
8
9
10
11
12
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import renderToString from "https://esm.sh/preact-render-to-string@6.2.1";
import { h } from "https://esm.sh/preact@10.23.2";
// Function to fetch JSON data from URL
async function fetchJSON(url: string) {
try {
console.log(`Attempting to fetch data from: ${url}`);
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
console.log(`Successfully fetched data: ${JSON.stringify(data)}`);
return data;
} catch (error) {
console.error(`Fetch error: ${error.message}`);
return null;
}
}
// Function to parse and format date
function formatDate(dateString: string) {
try {
const [datePart, timePart] = dateString.split(" ");
const [year, month, day] = datePart.split("-").map(Number);
const [hour, minute, second] = timePart.split(":").map(Number);
const date = new Date(year, month - 1, day, hour, minute, second);
if (isNaN(date.getTime())) {
throw new Error(`Invalid date: ${dateString}`);
}
const options: Intl.DateTimeFormatOptions = {
year: "numeric",
month: "long",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
hour12: true,
};
return date.toLocaleString("en-US", options);
} catch (error) {
console.error(`Error formatting date: ${error.message}`);
return `Error: ${dateString}`;
}
}
// Define the FeedItem component
const FeedItem = ({ subject, time, text }: { subject: string; time: string; text: string }) => (
h(
"div",
{ className: "feed-item" },
h("h2", null, subject || "No Subject"),
h("p", { className: "timestamp" }, formatDate(time)),
h("p", null, text || "No Content"),
h("p", { className: "debug" }, `Raw time: ${time}`),
)
);
// Main App component
function App({ data }: { data: Array<{ id: number; Subject: string; Time: string; Text: string }> }) {
if (!data || data.length === 0) {
return h("div", null, "No data available");
}
// Sort data by time in descending order
const sortedData = [...data].sort((a, b) => new Date(b.Time).getTime() - new Date(a.Time).getTime());
return h(
"div",
{ id: "feed-container" },
h("pre", { className: "debug" }, JSON.stringify(data, null, 2)),
sortedData.map((item) =>
h(FeedItem, {
key: item.id,
subject: item.Subject,
time: item.Time,
text: item.Text,
})
),
);
}
// Server-side rendering
export default async function server(request: Request): Promise<Response> {
const jsonUrl = "https://avycado13-valboardapi.web.val.run";
const data = await fetchJSON(jsonUrl);
let debugInfo = "";
if (!data) {
debugInfo = "<p>Error: Failed to fetch data. Check console for more details.</p>";
} else if (data.length === 0) {
debugInfo = "<p>Warning: Fetched data is empty</p>";
} else {
debugInfo = `<p>Fetched ${data.length} items</p>`;
}
const appHtml = renderToString(h(App, { data: data || [] }));
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
August 23, 2024