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:
+51
-25
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user