import { Show, Suspense, For } from "solid-js"; import { useParams, A } from "@solidjs/router"; import { Title } from "@solidjs/meta"; import { createAsync } from "@solidjs/router"; import { cache } from "@solidjs/router"; import { ConnectionFactory } from "~/server/utils"; import { HttpStatusCode } from "@solidjs/start"; import SessionDependantLike from "~/components/blog/SessionDependantLike"; import CommentIcon from "~/components/icons/CommentIcon"; // Server function to fetch post by title const getPostByTitle = cache(async (title: string, privilegeLevel: string) => { "use server"; const conn = ConnectionFactory(); let query = "SELECT * FROM Post WHERE title = ?"; if (privilegeLevel !== "admin") { query += ` AND published = TRUE`; } const postResults = await conn.execute({ sql: query, args: [decodeURIComponent(title)], }); const post = postResults.rows[0] as any; if (!post) { // Check if post exists but is unpublished const existQuery = "SELECT id FROM Post WHERE title = ?"; const existRes = await conn.execute({ sql: existQuery, args: [decodeURIComponent(title)], }); if (existRes.rows[0]) { return { post: null, exists: true, comments: [], likes: [], tags: [], userCommentMap: new Map() }; } return { post: null, exists: false, comments: [], likes: [], tags: [], userCommentMap: new Map() }; } // Fetch comments const commentQuery = "SELECT * FROM Comment WHERE post_id = ?"; const comments = (await conn.execute({ sql: commentQuery, args: [post.id] })).rows; // Fetch likes const likeQuery = "SELECT * FROM PostLike WHERE post_id = ?"; const likes = (await conn.execute({ sql: likeQuery, args: [post.id] })).rows; // Fetch tags const tagQuery = "SELECT * FROM Tag WHERE post_id = ?"; const tags = (await conn.execute({ sql: tagQuery, args: [post.id] })).rows; // Build commenter map const commenterToCommentIDMap = new Map(); comments.forEach((comment: any) => { const prev = commenterToCommentIDMap.get(comment.commenter_id) || []; commenterToCommentIDMap.set(comment.commenter_id, [...prev, comment.id]); }); const commenterQuery = "SELECT email, display_name, image FROM User WHERE id = ?"; const commentIDToCommenterMap = new Map(); for (const [key, value] of commenterToCommentIDMap.entries()) { const res = await conn.execute({ sql: commenterQuery, args: [key] }); const user = res.rows[0]; if (user) { commentIDToCommenterMap.set(user, value); } } // Get reaction map const reactionMap = new Map(); for (const comment of comments) { const reactionQuery = "SELECT * FROM CommentReaction WHERE comment_id = ?"; const res = await conn.execute({ sql: reactionQuery, args: [(comment as any).id], }); reactionMap.set((comment as any).id, res.rows); } return { post, exists: true, comments, likes, tags, topLevelComments: comments.filter((c: any) => c.parent_comment_id == null), userCommentMap: commentIDToCommenterMap, reactionMap, }; }, "post-by-title"); export default function PostPage() { const params = useParams(); // TODO: Get actual privilege level and user ID from session/auth const privilegeLevel = "anonymous"; const userID = null; const data = createAsync(() => getPostByTitle(params.title, privilegeLevel)); const hasCodeBlock = (str: string): boolean => { return str.includes(""); }; return ( <>
Loading post...
} >
Post not found
} > {(postData) => (
Post not found
} >
That post is in the works! Come back soon!
} > {(post) => { const p = post().post; return ( <> {p.title.replaceAll("_", " ")} | Michael Freno
post-cover
{p.title.replaceAll("_", " ")}
{p.subtitle}
Written {new Date(p.date).toDateString()}
By Michael Freno
{(tag) => (
{tag.value}
)}
{/* Post body */}
{/* Comments section */}
Comments

Comments coming soon!

We're working on implementing a comment system for this blog.

); }} )} ); }