import React, { createContext, useContext, useState, useEffect, useRef, } from "react"; import { BrowserRouter as Router, Routes, Route, Link, useNavigate, } from "react-router-dom"; import { useForm } from "react-hook-form"; import { BlogViewer } from "./utils/BlogViewer"; import { RequireAdmin } from "./utils/RouteGuard"; import { AdminPage } from "./utils/AdminPage"; import Unauthorized from "./utils/UnauthorizedPage"; import { FaGithub, FaGitAlt, FaLinkedin, FaTwitter, FaSun, FaMoon, } from "react-icons/fa"; import type { Blog } from "./utils/types"; import { countWords } from "./utils/countWords"; // Base API URL from env const API_URL = import.meta.env.VITE_API_URL || "http://localhost:8000"; // Auth Context interface AuthContextProps { isAuthenticated: boolean; login: (token: string, user_id: number) => void; logout: () => void; } const AuthContext = createContext({ isAuthenticated: false, login: () => {}, logout: () => {}, }); export const useAuth = () => useContext(AuthContext); const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children, }) => { const [isAuthenticated, setIsAuthenticated] = useState(false); const navigate = useNavigate(); useEffect(() => { const token = localStorage.getItem("token"); setIsAuthenticated(!!token); }, []); const login = (token: string, user_id: number) => { localStorage.setItem("token", token); localStorage.setItem("user_id", user_id.toString()); setIsAuthenticated(true); }; const logout = () => { localStorage.removeItem("token"); setIsAuthenticated(false); navigate("/signin"); }; return ( {children} ); }; function BlogPage() { const { isAuthenticated } = useAuth(); const navigate = useNavigate(); const [blogs, setBlogs] = useState([]); useEffect(() => { fetch(`${API_URL}/blogs`) .then((res) => res.json()) .then((data: Blog[]) => setBlogs(data)) .catch((err) => console.error(err)); }, []); return (
{blogs.map((blog) => (

{blog.title}

By {blog.author_id}

))}
); } // Page for creating a blog post function CreateBlog() { const [fileName, setFileName] = useState(""); const [title, setTitle] = useState(""); const username = localStorage.getItem("user_id") || ""; const [author, setAuthor] = useState(username); const [description, setDescription] = useState(""); const [content, setContent] = useState(""); const navigate = useNavigate(); const handleFile = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; const reader = new FileReader(); reader.onload = () => { const text = reader.result as string; setContent(text); setFileName(file.name); const baseName = file.name.replace(/\.[^.]+$/, ""); setTitle(baseName); setAuthor(username); }; reader.readAsText(file); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); // Stubbed API call try { const body = { title: title, author_id: localStorage.getItem("user_id"), description: description, body: content, created_at: new Date(Date.now()).toISOString(), updated_at: new Date(Date.now()).toISOString(), published_at: new Date(Date.now()).toISOString(), word_count: countWords(content), version: 1, read_time: 0, language: "US", }; const res = await fetch(`${API_URL}/blogs`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }); alert(res); navigate("/blog"); } catch (err: any) { alert(err.message); } }; return (

Create Post

{fileName && (
setTitle(e.target.value)} className="w-full border border-gray-300 dark:border-gray-600 rounded px-3 py-2" />
setAuthor(e.target.value)} className="w-full border border-gray-300 dark:border-gray-600 rounded px-3 py-2" />
setDescription(e.target.value)} className="w-full border border-gray-300 dark:border-gray-600 rounded px-3 py-2" />