Skip to content

Commit

Permalink
[Feature] #46 added functionality to retrieve post(s)
Browse files Browse the repository at this point in the history
  • Loading branch information
YongenChen committed Nov 8, 2024
1 parent bb7a537 commit f90cc74
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 75 deletions.
19 changes: 16 additions & 3 deletions app/api/posts/[id]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,22 @@ export async function GET(
const id = params.id;
const { rows } = await pool.query(
`
SELECT post_id, title, subtitle, author_id, author_name, content_url, topics, header_img, engagement_count, created_at, updated_at
FROM posts
WHERE post_id = $1;
SELECT
p.id AS post_id,
p.title,
p.subtitle,
p.user_id,
u.name AS author_name,
p.content_url,
array_agg(pt.topic_name) AS topics,
p.like_count,
p.comment_count,
p.published_at AS created_at
FROM posts p
LEFT JOIN users u ON p.user_id = u.id
LEFT JOIN posts_topics pt ON p.id = pt.post_id
WHERE p.id = $1
GROUP BY p.id, u.name;
`,
[id]
);
Expand Down
159 changes: 87 additions & 72 deletions app/api/posts/route.ts
Original file line number Diff line number Diff line change
@@ -1,79 +1,94 @@
import { getSessionUserId } from '@/lib/auth-user';
import pool from '@/lib/db';
import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
export async function GET(request: Request) {
try {
const userId = await getSessionUserId();
const userId = await getSessionUserId();

if (userId === undefined) {
return new Response(JSON.stringify({ error: 'Unauthorized' }), { status: 401 });
}

if (userId === null) {
return new Response(JSON.stringify({ error: 'User not found' }), { status: 404 });
}

const url = new URL(request.url);
const query = url.searchParams.get('query') || '';
const id = url.searchParams.get('id'); // Get the id query parameter
const limit = Number(url.searchParams.get('limit') || 10);
const page = Number(url.searchParams.get('page') || 1);
const type = url.searchParams.get('type') || '';
const topics = url.searchParams.getAll('topics[]');
const author_ids = url.searchParams.getAll('author_ids[]');
const offset = (page - 1) * limit;

let queryText = `
SELECT
p.id AS post_id,
p.title,
p.subtitle,
p.user_id,
u.name AS author_name,
p.content_url,
array_agg(pt.topic_name) AS topics,
p.like_count,
p.comment_count,
p.published_at AS created_at
FROM posts p
LEFT JOIN users u ON p.user_id = u.id
LEFT JOIN posts_topics pt ON p.id = pt.post_id
`;

const queryParams: any[] = [];
const whereClauses = [];

if (id) {
queryParams.push(id);
whereClauses.push(`p.id = $${queryParams.length}`);
}

if (userId === undefined) {
return res.status(401).json({ error: 'Unauthorized' });
}

if (userId === null) {
return res.status(404).json({ error: 'User not found' });
}

const { query, limit = 10, page = 1, type, topics = [], author_ids = [] } = req.query;
const offset = (Number(page) - 1) * Number(limit);

let queryText = `
SELECT
p.post_id,
p.title,
p.subtitle,
p.author_id,
u.name AS author_name,
p.content_url,
array_agg(pt.topic_name) AS topics,
p.header_img,
p.engagement_count,
p.created_at,
p.updated_at
FROM posts p
LEFT JOIN users u ON p.author_id = u.id
LEFT JOIN posts_topics pt ON p.post_id = pt.post_id
`;

const queryParams: any[] = [];
let whereClauses = [];

if (query) {
queryParams.push(`%${query}%`);
whereClauses.push(`(p.title ILIKE $${queryParams.length} OR p.subtitle ILIKE $${queryParams.length} OR p.content_url ILIKE $${queryParams.length})`);
}

if (type === 'my_feed') {
queryParams.push(userId);
whereClauses.push(`p.author_id IN (SELECT following_id FROM follows WHERE follower_id = $${queryParams.length})`);
} else if (type === 'author_posts' && author_ids.length > 0) {
queryParams.push(author_ids);
whereClauses.push(`p.author_id = ANY($${queryParams.length})`);
} else if (type === 'author_drafts') {
whereClauses.push(`p.author_id = $${queryParams.length + 1} AND p.is_published = FALSE`);
queryParams.push(userId);
} else if (type === 'trending') {
queryText += ' ORDER BY p.engagement_count DESC';
} else {
queryText += ' ORDER BY p.created_at DESC';
}

if (topics.length > 0) {
queryParams.push(topics);
whereClauses.push(`p.post_id IN (SELECT post_id FROM posts_topics WHERE topic_name = ANY($${queryParams.length}))`);
}

if (whereClauses.length > 0) {
queryText += ' WHERE ' + whereClauses.join(' AND ');
}

queryParams.push(limit, offset);
queryText += ` GROUP BY p.post_id, u.name LIMIT $${queryParams.length - 1} OFFSET $${queryParams.length};`;

const { rows } = await pool.query(queryText, queryParams);

return res.status(200).json({ posts: rows.length > 0 ? rows : null });
if (query) {
queryParams.push(`%${query}%`);
whereClauses.push(`(p.title ILIKE $${queryParams.length} OR p.subtitle ILIKE $${queryParams.length} OR p.content_url ILIKE $${queryParams.length})`);
}

if (type === 'my_feed') {
queryParams.push(userId);
whereClauses.push(`p.user_id IN (SELECT following_id FROM follows WHERE follower_id = $${queryParams.length})`);
} else if (type === 'author_posts' && author_ids.length > 0) {
queryParams.push(author_ids);
whereClauses.push(`p.user_id = ANY($${queryParams.length})`);
} else if (type === 'author_drafts') {
whereClauses.push(`p.user_id = $${queryParams.length + 1} AND p.is_published = FALSE`);
queryParams.push(userId);
}

if (topics.length > 0) {
queryParams.push(topics);
whereClauses.push(`p.id IN (SELECT post_id FROM posts_topics WHERE topic_name = ANY($${queryParams.length}))`);
}

if (whereClauses.length > 0) {
queryText += ' WHERE ' + whereClauses.join(' AND ');
}

queryText += ` GROUP BY p.id, u.name`;

if (type === 'trending') {
queryText += ' ORDER BY p.like_count DESC, p.comment_count DESC';
} else {
queryText += ' ORDER BY p.published_at DESC';
}

queryParams.push(limit, offset);
queryText += ` LIMIT $${queryParams.length - 1} OFFSET $${queryParams.length};`;

const { rows } = await pool.query(queryText, queryParams);

return new Response(JSON.stringify({ posts: rows.length > 0 ? rows : null }), { status: 200 });
} catch (error) {
return res.status(500).json({ error: error instanceof Error ? error.message : 'An unexpected error occurred' });
return new Response(JSON.stringify({ error: error instanceof Error ? error.message : 'An unexpected error occurred' }), { status: 500 });
}
}
}

0 comments on commit f90cc74

Please sign in to comment.