diff --git a/server/routes.ts b/server/routes.ts index ebb37c9..4f50912 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -38,7 +38,7 @@ export async function registerRoutes(app: Express): Promise { console.log(`Found ${newNewsletters.length} new newsletters, sending notifications...`); // Send push notifications - const subscriptions = await storage.getSubscriptions(); + const subscriptions = await storage.getActiveSubscriptions(); console.log(`Sending notifications to ${subscriptions.length} subscribers`); const notificationPayload = JSON.stringify({ @@ -47,6 +47,20 @@ export async function registerRoutes(app: Express): Promise { icon: '/icon.png' }); + + app.post("/api/subscriptions/:id/settings", async (req, res) => { + try { + const subscriptionId = parseInt(req.params.id); + await storage.saveNotificationSettings(subscriptionId, { + newsletter_notifications: req.body.newsletter_notifications + }); + res.json({ message: "Notification settings updated successfully" }); + } catch (error) { + console.error('Error updating notification settings:', error); + res.status(500).json({ message: "Failed to update notification settings" }); + } + }); + const results = await Promise.allSettled( subscriptions.map(subscription => webpush.sendNotification({ diff --git a/server/storage.ts b/server/storage.ts index c065f4f..a0f6373 100644 --- a/server/storage.ts +++ b/server/storage.ts @@ -47,6 +47,32 @@ export class DatabaseStorage implements IStorage { async getSubscriptions(): Promise { return await db.select().from(subscriptions); } + + async getActiveSubscriptions(): Promise { + const result = await db + .select({ + subscription: subscriptions, + settings: notificationSettings + }) + .from(subscriptions) + .leftJoin(notificationSettings, eq(subscriptions.id, notificationSettings.subscription_id)) + .where(eq(notificationSettings.newsletter_notifications, true)); + + return result.map(r => r.subscription); + } + + async saveNotificationSettings(subscriptionId: number, settings: Partial): Promise { + await db + .insert(notificationSettings) + .values({ + subscription_id: subscriptionId, + ...settings + }) + .onConflictDoUpdate({ + target: [notificationSettings.subscription_id], + set: settings + }); + } } export const storage = new DatabaseStorage(); \ No newline at end of file diff --git a/shared/schema.ts b/shared/schema.ts index c023fac..797cabd 100644 --- a/shared/schema.ts +++ b/shared/schema.ts @@ -41,4 +41,16 @@ export const insertSubscriptionSchema = createInsertSchema(subscriptions).pick({ }); export type InsertSubscription = z.infer; -export type Subscription = typeof subscriptions.$inferSelect; \ No newline at end of file +export type Subscription = typeof subscriptions.$inferSelect; + +export const notificationSettings = pgTable("notification_settings", { + id: serial("id").primaryKey(), + subscription_id: serial("subscription_id").references(() => subscriptions.id), + newsletter_notifications: boolean("newsletter_notifications").default(true), + created_at: timestamp("created_at").defaultNow(), + updated_at: timestamp("updated_at").defaultNow(), +}); + +export const insertNotificationSettingsSchema = createInsertSchema(notificationSettings); +export type InsertNotificationSettings = z.infer; +export type NotificationSettings = typeof notificationSettings.$inferSelect; \ No newline at end of file