Add search functionality to find articles and media outlets

Implements a search feature by adding a search modal, API endpoint, and storage logic for querying articles and media outlets.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 069d4324-6c40-4355-955e-c714a50de1ea
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3df548ff-50ae-432f-9be4-25d34eccc983/069d4324-6c40-4355-955e-c714a50de1ea/gVirbWH
This commit is contained in:
kimjaehyeon0101
2025-09-29 20:12:12 +00:00
parent 463f042f64
commit a80520b85f
6 changed files with 308 additions and 3 deletions

View File

@ -354,6 +354,23 @@ export async function registerRoutes(app: Express): Promise<Server> {
}
});
// Search routes
app.get('/api/search', async (req, res) => {
try {
const { q } = req.query;
if (!q || typeof q !== 'string' || q.trim().length === 0) {
return res.json({ outlets: [], articles: [] });
}
const results = await storage.search(q.trim());
res.json(results);
} catch (error) {
console.error("Error performing search:", error);
res.status(500).json({ message: "Failed to perform search" });
}
});
const httpServer = createServer(app);
return httpServer;
}

View File

@ -82,6 +82,12 @@ export interface IStorage {
liveAuctions: number;
totalRevenue: number;
}>;
// Search operations
search(query: string): Promise<{
outlets: MediaOutlet[];
articles: Article[];
}>;
}
export class DatabaseStorage implements IStorage {
@ -381,6 +387,44 @@ export class DatabaseStorage implements IStorage {
totalRevenue: revenueSum.sum
};
}
// Search operations
async search(query: string): Promise<{
outlets: MediaOutlet[];
articles: Article[];
}> {
const searchTerm = query.toLowerCase();
// Search media outlets
const foundOutlets = await db
.select()
.from(mediaOutlets)
.where(eq(mediaOutlets.isActive, true))
.limit(50);
const filteredOutlets = foundOutlets.filter(outlet =>
outlet.name.toLowerCase().includes(searchTerm) ||
(outlet.description && outlet.description.toLowerCase().includes(searchTerm))
).slice(0, 10);
// Search articles
const foundArticles = await db
.select()
.from(articles)
.orderBy(desc(articles.publishedAt))
.limit(100);
const filteredArticles = foundArticles.filter(article =>
article.title.toLowerCase().includes(searchTerm) ||
(article.content && article.content.toLowerCase().includes(searchTerm)) ||
(article.excerpt && article.excerpt.toLowerCase().includes(searchTerm))
).slice(0, 20);
return {
outlets: filteredOutlets,
articles: filteredArticles
};
}
}
export const storage = new DatabaseStorage();