feat: ability to add and view blogs for a user

This commit is contained in:
2025-06-24 18:54:48 -04:00
parent 07c0977aa7
commit 7da38ddd8c
26 changed files with 1553 additions and 142 deletions
View File
+36 -8
View File
@@ -1,15 +1,43 @@
import { useEffect, useState } from "react";
import Markdown from "react-markdown";
import { useParams } from "react-router-dom";
import { API_URL } from "./constants";
import type { Blog } from "./types";
import Markdown from "react-markdown";
import remarkGfm from "remark-gfm";
import remarkRehype from "remark-rehype";
import rehypeRaw from "rehype-raw";
import "../styles/markdown.css";
export function BlogViewer() {
const [content, setContent] = useState("");
const { slug } = useParams();
const { slug } = useParams<{ slug: string }>();
const [blog, setBlog] = useState<Blog | null>(null);
useEffect(() => {
fetch(`localhost:8000/get-blogs/${slug}`)
.then((res) => res.text())
.then(setContent);
}, []);
return <Markdown>{content}</Markdown>;
if (!slug) return;
fetch(`${API_URL}/blogs/${slug}`)
.then((res) => res.json())
.then((data: Blog) => setBlog(data))
.catch((err) => console.error(err));
}, [slug]);
if (!blog) {
return <p>Loading...</p>;
}
return (
<div className="max-w-2xl mx-auto py-10 space-y-6">
<h1 className="text-3xl font-bold">{blog.title.toUpperCase()}</h1>
<p className="text-sm text-gray-500">By User {blog.author_id}</p>
<p className="italic text-gray-600 dark:text-gray-400">
{blog.description}
</p>
<div className="markdown-body mx-auto p-4">
<Markdown
remarkPlugins={[remarkGfm, remarkRehype]}
rehypePlugins={[rehypeRaw]}
children={blog.body}
></Markdown>
</div>
</div>
);
}
+1
View File
@@ -0,0 +1 @@
export const API_URL = import.meta.env.VITE_API_URL || "http://localhost:8000";
+9
View File
@@ -0,0 +1,9 @@
export function countWords(text: string): number {
// Trim leading/trailing whitespace, then split on one-or-more whitespace characters
const words = text.trim().split(/\s+/);
// If the string was empty or only whitespace, split() returns [''], so handle that
if (words.length === 1 && words[0] === "") {
return 0;
}
return words.length;
}
+7
View File
@@ -0,0 +1,7 @@
export interface Blog {
id: number;
title: string;
author_id: number;
description: string;
body: string;
}