Add new pages and improve blog content display functionality

Implement new routes for articles, categories, and individual articles. Update the UI to display articles with improved content rendering, including safe HTML and media embeds. Refactor storage to use a database and add image upload capabilities.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 413891e8-d784-4bea-b9f5-91a5a68316b4
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: b96b221e-0ed6-418f-80df-e4670bf5ba4b
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/f209e72a-0939-48fa-84fc-57854de71967/413891e8-d784-4bea-b9f5-91a5a68316b4/cftwqyT
Replit-Helium-Checkpoint-Created: true
This commit is contained in:
sebastjanartic
2026-02-28 16:38:38 +00:00
parent bf2021ba3d
commit 4a7639b15d
30 changed files with 1231 additions and 69 deletions
+51 -25
View File
@@ -1,38 +1,64 @@
import { type User, type InsertUser } from "@shared/schema";
import { randomUUID } from "crypto";
// modify the interface with any CRUD methods
// you might need
import { type Article, type InsertArticle, articles } from "@shared/schema";
import { db } from "./db";
import { eq, desc, sql } from "drizzle-orm";
export interface IStorage {
getUser(id: string): Promise<User | undefined>;
getUserByUsername(username: string): Promise<User | undefined>;
createUser(user: InsertUser): Promise<User>;
getArticles(): Promise<Article[]>;
getArticleBySlug(slug: string): Promise<Article | undefined>;
getArticleById(id: number): Promise<Article | undefined>;
getFeaturedArticles(): Promise<Article[]>;
getPopularArticles(limit: number): Promise<Article[]>;
getArticlesByCategory(category: string): Promise<Article[]>;
createArticle(article: InsertArticle): Promise<Article>;
updateArticle(id: number, article: Partial<InsertArticle>): Promise<Article | undefined>;
incrementViews(id: number): Promise<void>;
deleteArticle(id: number): Promise<void>;
}
export class MemStorage implements IStorage {
private users: Map<string, User>;
constructor() {
this.users = new Map();
export class DatabaseStorage implements IStorage {
async getArticles(): Promise<Article[]> {
return db.select().from(articles).orderBy(desc(articles.publishedAt));
}
async getUser(id: string): Promise<User | undefined> {
return this.users.get(id);
async getArticleBySlug(slug: string): Promise<Article | undefined> {
const [article] = await db.select().from(articles).where(eq(articles.slug, slug));
return article;
}
async getUserByUsername(username: string): Promise<User | undefined> {
return Array.from(this.users.values()).find(
(user) => user.username === username,
);
async getArticleById(id: number): Promise<Article | undefined> {
const [article] = await db.select().from(articles).where(eq(articles.id, id));
return article;
}
async createUser(insertUser: InsertUser): Promise<User> {
const id = randomUUID();
const user: User = { ...insertUser, id };
this.users.set(id, user);
return user;
async getFeaturedArticles(): Promise<Article[]> {
return db.select().from(articles).where(eq(articles.featured, true)).orderBy(desc(articles.publishedAt)).limit(3);
}
async getPopularArticles(limit: number): Promise<Article[]> {
return db.select().from(articles).orderBy(desc(articles.views)).limit(limit);
}
async getArticlesByCategory(category: string): Promise<Article[]> {
return db.select().from(articles).where(eq(articles.category, category)).orderBy(desc(articles.publishedAt));
}
async createArticle(article: InsertArticle): Promise<Article> {
const [created] = await db.insert(articles).values(article).returning();
return created;
}
async updateArticle(id: number, article: Partial<InsertArticle>): Promise<Article | undefined> {
const [updated] = await db.update(articles).set(article).where(eq(articles.id, id)).returning();
return updated;
}
async incrementViews(id: number): Promise<void> {
await db.update(articles).set({ views: sql`${articles.views} + 1` }).where(eq(articles.id, id));
}
async deleteArticle(id: number): Promise<void> {
await db.delete(articles).where(eq(articles.id, id));
}
}
export const storage = new MemStorage();
export const storage = new DatabaseStorage();