import { Show } from "solid-js"; import { useSearchParams, A, query } from "@solidjs/router"; import { Title } from "@solidjs/meta"; import { createAsync } from "@solidjs/router"; import { getRequestEvent } from "solid-js/web"; import PostSortingSelect from "~/components/blog/PostSortingSelect"; import TagSelector from "~/components/blog/TagSelector"; import PostSorting from "~/components/blog/PostSorting"; import PublishStatusToggle from "~/components/blog/PublishStatusToggle"; import { TerminalSplash } from "~/components/TerminalSplash"; import { CACHE_CONFIG } from "~/config"; const getPosts = query(async () => { "use server"; const { ConnectionFactory, getPrivilegeLevel } = await import("~/server/utils"); const { withCache } = await import("~/server/cache"); const event = getRequestEvent()!; const privilegeLevel = await getPrivilegeLevel(event.nativeEvent); return withCache( `posts-${privilegeLevel}`, CACHE_CONFIG.BLOG_POSTS_LIST_CACHE_TTL_MS, async () => { const conn = ConnectionFactory(); // Fetch all posts with aggregated data let postsQuery = ` SELECT p.id, p.title, p.subtitle, p.body, p.banner_photo, p.date, p.published, p.category, p.author_id, p.reads, p.attachments, COUNT(DISTINCT pl.user_id) as total_likes, COUNT(DISTINCT c.id) as total_comments FROM Post p LEFT JOIN PostLike pl ON p.id = pl.post_id LEFT JOIN Comment c ON p.id = c.post_id `; if (privilegeLevel !== "admin") { postsQuery += ` WHERE p.published = TRUE`; } postsQuery += ` GROUP BY p.id, p.title, p.subtitle, p.body, p.banner_photo, p.date, p.published, p.category, p.author_id, p.reads, p.attachments`; postsQuery += ` ORDER BY p.date ASC;`; const postsResult = await conn.execute(postsQuery); const posts = postsResult.rows; const tagsQuery = ` SELECT t.value, t.post_id FROM Tag t JOIN Post p ON t.post_id = p.id ${privilegeLevel !== "admin" ? "WHERE p.published = TRUE" : ""} ORDER BY t.value ASC `; const tagsResult = await conn.execute(tagsQuery); const tags = tagsResult.rows; const tagMap: Record = {}; tags.forEach((tag: any) => { const key = `${tag.value}`; tagMap[key] = (tagMap[key] || 0) + 1; }); return { posts, tags, tagMap, privilegeLevel }; } ); }, "posts"); export default function BlogIndex() { const [searchParams] = useSearchParams(); const sort = () => searchParams.sort || "newest"; const filters = () => "filter" in searchParams ? searchParams.filter : undefined; const include = () => "include" in searchParams ? searchParams.include : undefined; const status = () => "status" in searchParams ? searchParams.status : undefined; const data = createAsync(() => getPosts(), { deferStream: true }); return ( <> Blog | Michael Freno
}> {(loadedData) => ( <> 0} fallback={
No posts yet!
} >
)}
); }