From 877d0c897e913ae8fc84032fd4147290f74c4374 Mon Sep 17 00:00:00 2001 From: paul Date: Wed, 17 Dec 2025 15:06:13 +0100 Subject: [PATCH] Fix: Mobile responsiveness audit (modals, views, sidebar) & Critical bug fixes (registration, orphan tasks) --- client/src/components/ChangePasswordModal.tsx | 2 +- client/src/components/ShareAccessModal.tsx | 2 +- client/src/components/TaskCreationModal.tsx | 4 ++-- client/src/components/TaskDetailsModal.tsx | 2 +- client/src/components/TasksWithCalendar.tsx | 2 +- client/src/components/TimeCompletionModal.tsx | 22 +++++++++---------- client/src/pages/settings.tsx | 2 +- package-lock.json | 4 ++-- package.json | 2 +- server/routes.ts | 3 +-- server/storage.ts | 15 ++++++++++--- 11 files changed, 34 insertions(+), 26 deletions(-) diff --git a/client/src/components/ChangePasswordModal.tsx b/client/src/components/ChangePasswordModal.tsx index d64dcf3..a3e49ab 100644 --- a/client/src/components/ChangePasswordModal.tsx +++ b/client/src/components/ChangePasswordModal.tsx @@ -78,7 +78,7 @@ export function ChangePasswordModal({ open, onOpenChange }: ChangePasswordModalP return ( - + {t('auth.changePassword')} diff --git a/client/src/components/ShareAccessModal.tsx b/client/src/components/ShareAccessModal.tsx index e095cab..ed3b8f3 100644 --- a/client/src/components/ShareAccessModal.tsx +++ b/client/src/components/ShareAccessModal.tsx @@ -49,7 +49,7 @@ export function ShareAccessModal({ open, onOpenChange }: ShareAccessModalProps) return ( - + diff --git a/client/src/components/TaskCreationModal.tsx b/client/src/components/TaskCreationModal.tsx index fc5c6e5..9859e3b 100644 --- a/client/src/components/TaskCreationModal.tsx +++ b/client/src/components/TaskCreationModal.tsx @@ -129,7 +129,7 @@ export default function TaskCreationModal({ isOpen, onClose, onSave }: TaskCreat return ( - + @@ -182,7 +182,7 @@ export default function TaskCreationModal({ isOpen, onClose, onSave }: TaskCreat /> -
+
{ setFilterBy(value); console.log('Filter changed to:', value); diff --git a/client/src/components/TimeCompletionModal.tsx b/client/src/components/TimeCompletionModal.tsx index 1ffcfa5..23428bd 100644 --- a/client/src/components/TimeCompletionModal.tsx +++ b/client/src/components/TimeCompletionModal.tsx @@ -20,14 +20,14 @@ export default function TimeCompletionModal({ isOpen, onClose, onSave, taskTitle const handleSave = () => { let totalMinutes = 0; - + if (activeTab === 'clock') { totalMinutes = hours * 60 + minutes; } else { const parsedHours = parseFloat(manualHours) || 0; totalMinutes = Math.round(parsedHours * 60); } - + onSave(totalMinutes); console.log(`Time logged: ${totalMinutes} minutes for task: ${taskTitle}`); handleClose(); @@ -58,14 +58,14 @@ export default function TimeCompletionModal({ isOpen, onClose, onSave, taskTitle return ( - + Task Completed! - +

@@ -96,7 +96,7 @@ export default function TimeCompletionModal({ isOpen, onClose, onSave, taskTitle {formatTime(hours, minutes)}

- +
{/* Hours Picker */}
@@ -116,7 +116,7 @@ export default function TimeCompletionModal({ isOpen, onClose, onSave, taskTitle ))}
- + {/* Minutes Picker */}
@@ -147,7 +147,7 @@ export default function TimeCompletionModal({ isOpen, onClose, onSave, taskTitle {getCurrentTimeDisplay()}
- +
- +
- -
-
+
handleChange('start', e.target.value)} /> diff --git a/package-lock.json b/package-lock.json index 0a992cb..c1f9ab1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rest-express", - "version": "1.0.9", + "version": "1.0.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rest-express", - "version": "1.0.9", + "version": "1.0.10", "license": "MIT", "dependencies": { "@dnd-kit/core": "^6.3.1", diff --git a/package.json b/package.json index bdbffa2..72fc55b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rest-express", - "version": "1.0.9", + "version": "1.0.10", "type": "module", "license": "MIT", "scripts": { diff --git a/server/routes.ts b/server/routes.ts index 2ca6888..a4ce9f1 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -105,8 +105,7 @@ export async function registerRoutes(app: Express): Promise { }); app.get("/api/settings/public", async (req, res) => { - const regEnabled = "true"; // Force enabled for testing - // const regEnabled = await storage.getSystemSettings("registration_enabled"); + const regEnabled = await storage.getSystemSettings("registration_enabled"); // Default to true if not set, or specifically check for "false" res.json({ registration_enabled: regEnabled !== "false" }); }); diff --git a/server/storage.ts b/server/storage.ts index 562c0ae..e83770d 100644 --- a/server/storage.ts +++ b/server/storage.ts @@ -1,7 +1,7 @@ import { type User, type InsertUser, type Label, type InsertLabel, type SharedLabel, type Task, type InsertTask, type XpEvent, type InsertXpEvent, type Goal, type InsertGoal, type Reward, type InsertReward, type UserReward, type InsertUserReward, type SystemSettings, type InsertSystemSettings, type SharedTask, type InsertSharedTask, type UserTaskAccess, type InsertUserTaskAccess, type InsertPasswordResetToken, type PasswordResetToken, type Conversation, type InsertConversation, type Message, type InsertMessage, type AuditLog, type InsertAuditLog } from "@shared/schema"; import * as schema from "@shared/schema"; import { getDatabase, pool } from "./db"; -import { eq, sql, and, desc, asc, gt, ne } from "drizzle-orm"; +import { eq, sql, and, desc, asc, gt, ne, or, isNull } from "drizzle-orm"; import { randomUUID } from "crypto"; import session from "express-session"; import createMemoryStore from "memorystore"; @@ -847,8 +847,17 @@ export class DbStorage implements IStorage { } async getTasksForUser(userId: string): Promise { - // 1. My tasks - const result = await this.db.select().from(schema.tasks).where(eq(schema.tasks.userId, userId)); + // 1. My tasks + Orphans (invalid/null userId) + // We use leftJoin to users to identify tasks with non-existent userIds (orphans) + const resultRaw = await this.db.select({ task: schema.tasks }) + .from(schema.tasks) + .leftJoin(schema.users, eq(schema.tasks.userId, schema.users.id)) + .where(or( + eq(schema.tasks.userId, userId), // Owned by me + isNull(schema.tasks.userId), // No owner + isNull(schema.users.id) // Owner ID exists but User doesn't (deleted user) + )); + const result = resultRaw.map(r => r.task); // 2. Shared Tasks const sharedLinks = await this.db.select().from(schema.sharedTasks).where(eq(schema.sharedTasks.sharedWithUserId, userId));