Auth v2: Register/Login/Profile, Households, per-user Favorites/Notes/Shopping, Frontend Auth Pages
This commit is contained in:
@@ -63,7 +63,7 @@ function mapTimeFields(row: any) {
|
||||
|
||||
export function listRecipes(opts: {
|
||||
page?: number; limit?: number; category_id?: string; category_slug?: string;
|
||||
favorite?: boolean; difficulty?: string; maxTime?: number;
|
||||
favorite?: boolean; difficulty?: string; maxTime?: number; userId?: string;
|
||||
}) {
|
||||
const db = getDb();
|
||||
const page = opts.page || 1;
|
||||
@@ -74,15 +74,30 @@ export function listRecipes(opts: {
|
||||
|
||||
if (opts.category_id) { conditions.push('r.category_id = ?'); params.push(opts.category_id); }
|
||||
if (opts.category_slug) { conditions.push('c.slug = ?'); params.push(opts.category_slug); }
|
||||
if (opts.favorite !== undefined) { conditions.push('r.is_favorite = ?'); params.push(opts.favorite ? 1 : 0); }
|
||||
if (opts.favorite !== undefined && opts.userId) {
|
||||
conditions.push('uf.user_id IS ' + (opts.favorite ? 'NOT NULL' : 'NULL'));
|
||||
}
|
||||
if (opts.difficulty) { conditions.push('r.difficulty = ?'); params.push(opts.difficulty); }
|
||||
if (opts.maxTime) { conditions.push('r.total_time <= ?'); params.push(opts.maxTime); }
|
||||
|
||||
let joins = 'LEFT JOIN categories c ON r.category_id = c.id';
|
||||
if (opts.userId) {
|
||||
joins += ' LEFT JOIN user_favorites uf ON r.id = uf.recipe_id AND uf.user_id = ?';
|
||||
params.unshift(opts.userId);
|
||||
}
|
||||
|
||||
const where = conditions.length ? 'WHERE ' + conditions.join(' AND ') : '';
|
||||
const countRow = db.prepare(`SELECT COUNT(*) as total FROM recipes r LEFT JOIN categories c ON r.category_id = c.id ${where}`).get(...params) as any;
|
||||
|
||||
// Adjust parameter positions based on whether userId is included
|
||||
const countParams = opts.userId ? [opts.userId, ...params.slice(1)] : params;
|
||||
const dataParams = opts.userId ? [opts.userId, ...params.slice(1), limit, offset] : [...params, limit, offset];
|
||||
|
||||
const countRow = db.prepare(`SELECT COUNT(*) as total FROM recipes r ${joins} ${where}`).get(...countParams) as any;
|
||||
const rows = db.prepare(
|
||||
`SELECT r.*, c.name as category_name, c.slug as category_slug FROM recipes r LEFT JOIN categories c ON r.category_id = c.id ${where} ORDER BY r.created_at DESC LIMIT ? OFFSET ?`
|
||||
).all(...params, limit, offset);
|
||||
`SELECT r.*, c.name as category_name, c.slug as category_slug,
|
||||
${opts.userId ? '(uf.user_id IS NOT NULL) as is_favorite' : 'r.is_favorite'}
|
||||
FROM recipes r ${joins} ${where} ORDER BY r.created_at DESC LIMIT ? OFFSET ?`
|
||||
).all(...dataParams);
|
||||
|
||||
const data = rows.map(mapTimeFields);
|
||||
return { data, total: countRow.total, page, limit, totalPages: Math.ceil(countRow.total / limit) };
|
||||
@@ -205,13 +220,34 @@ export function deleteRecipe(id: string): boolean {
|
||||
return result.changes > 0;
|
||||
}
|
||||
|
||||
export function toggleFavorite(id: string) {
|
||||
export function toggleFavorite(id: string, userId?: string) {
|
||||
const db = getDb();
|
||||
const recipe = db.prepare('SELECT is_favorite FROM recipes WHERE id = ?').get(id) as any;
|
||||
const recipe = db.prepare('SELECT id FROM recipes WHERE id = ?').get(id) as any;
|
||||
if (!recipe) return null;
|
||||
const newVal = recipe.is_favorite ? 0 : 1;
|
||||
db.prepare('UPDATE recipes SET is_favorite = ? WHERE id = ?').run(newVal, id);
|
||||
return { id, is_favorite: newVal };
|
||||
|
||||
// If no user authentication, fallback to old is_favorite column
|
||||
if (!userId) {
|
||||
const recipeWithFavorite = db.prepare('SELECT is_favorite FROM recipes WHERE id = ?').get(id) as any;
|
||||
const newVal = recipeWithFavorite.is_favorite ? 0 : 1;
|
||||
db.prepare('UPDATE recipes SET is_favorite = ? WHERE id = ?').run(newVal, id);
|
||||
return { id, is_favorite: newVal };
|
||||
}
|
||||
|
||||
// Check if recipe is already favorited by user
|
||||
const existing = db.prepare(
|
||||
'SELECT id FROM user_favorites WHERE user_id = ? AND recipe_id = ?'
|
||||
).get(userId, id) as any;
|
||||
|
||||
if (existing) {
|
||||
// Remove from favorites
|
||||
db.prepare('DELETE FROM user_favorites WHERE user_id = ? AND recipe_id = ?').run(userId, id);
|
||||
return { id, is_favorite: false };
|
||||
} else {
|
||||
// Add to favorites
|
||||
const favoriteId = ulid();
|
||||
db.prepare('INSERT INTO user_favorites (id, user_id, recipe_id) VALUES (?, ?, ?)').run(favoriteId, userId, id);
|
||||
return { id, is_favorite: true };
|
||||
}
|
||||
}
|
||||
|
||||
export function getRandomRecipe() {
|
||||
|
||||
Reference in New Issue
Block a user