feat: Notifications page, Sidebar layout fixes, and Achievements enhancements
continuous-integration/drone/push Build is failing

- implemented /notifications page with overdue/upcoming alerts
- Fixed sidebar scrolling in collapsed mode
- Moved notification button to sidebar footer
- Enhanced Achievements page with streak stats and tooltips
- Improved XP history to show task titles
- Added missing translations (en/de)
- Removed top bar header
- Fixed Docker environment routing
This commit is contained in:
2025-12-17 10:06:36 +01:00
parent 7b79015ac2
commit 9819d8db0b
47 changed files with 2309 additions and 1241 deletions
+10 -3
View File
@@ -19,9 +19,15 @@ export const users = pgTable("users", {
isSearchable: boolean("is_searchable").notNull().default(false), // Privacy setting
apiKey: text("api_key"), // For MCP Server access
aiEnabled: boolean("ai_enabled").notNull().default(true), // Feature flag per user
routineConfig: json("routine_config").$type<{ morningTime: string, eveningTime: string, enabled: boolean }>().default({ morningTime: "09:00", eveningTime: "17:00", enabled: true }),
routineConfig: json("routine_config").$type<{ morningTime: string, eveningTime: string, enabled: boolean }>().default({ morningTime: "09:00", eveningTime: "17:00", enabled: false }),
lastMorningRoutine: timestamp("last_morning_routine"),
lastEveningRoutine: timestamp("last_evening_routine"),
// 2FA Fields
is2faEnabled: boolean("is_2fa_enabled").notNull().default(false),
otpCode: text("otp_code"), // The temporary 6-digit code
otpExpiresAt: timestamp("otp_expires_at"),
language: text("language").notNull().default("en"), // 'en' | 'de'
});
export const systemSettings = pgTable("system_settings", {
@@ -98,6 +104,7 @@ export const insertUserSchema = createInsertSchema(users).pick({
showOnLeaderboard: true,
isSearchable: true,
aiEnabled: true,
language: true,
});
export const registerSchema = insertUserSchema;
@@ -120,8 +127,8 @@ export const insertLabelSchema = createInsertSchema(labels).omit({
});
export const insertTaskSchema = createInsertSchema(tasks, {
dueDate: z.coerce.date().nullable(),
startDate: z.coerce.date().nullable(),
dueDate: z.coerce.date().nullable().optional(),
startDate: z.coerce.date().nullable().optional(),
}).omit({
id: true,
userId: true, // We will set this server-side