Add automatic lunch feature. Clean up some code.

This commit is contained in:
2025-10-23 15:34:09 -05:00
parent 40489be8e9
commit 7eb3a1dff0
7 changed files with 197 additions and 126 deletions

View File

@@ -156,23 +156,41 @@ export const updateAllStatuses = mutation({
});
export const createLunchStatus = mutation({
args: {},
handler: async (ctx) => {
args: { userId: v.optional(v.id('users'))},
handler: async (ctx, args) => {
const authUserId = await getAuthUserId(ctx);
if (!authUserId) throw new ConvexError('Not authenticated.');
const lunchUserId = args.userId ?? authUserId
if (!lunchUserId) throw new ConvexError('Not authenticated.');
await ctx.runMutation(api.statuses.create, {
message: 'At lunch',
userId: authUserId,
userId: lunchUserId,
});
const oneHour = 60 * 60 * 1000;
await ctx.scheduler.runAfter(oneHour, api.statuses.create, {
message: 'At desk',
userId: authUserId,
await ctx.scheduler.runAfter(oneHour, api.statuses.backFromLunchStatus, {
userId: lunchUserId,
});
return { success: true };
},
});
export const backFromLunchStatus = mutation({
args: { userId: v.optional(v.id('users')) },
handler: async (ctx, args) => {
const authUserId = await getAuthUserId(ctx);
const lunchUserId = args.userId ?? authUserId
if (!lunchUserId) throw new ConvexError('Not authenticated.');
const user = await ensureUser(ctx, lunchUserId);
if (!user.currentStatusId) throw new ConvexError('User has no current status.');
const currentStatus = await ctx.db.get(user.currentStatusId);
if (currentStatus?.message === 'At lunch') {
await ctx.runMutation(api.statuses.create, {
message: 'At desk',
userId: lunchUserId,
});
}
},
});
export const getCurrentForUser = query({
args: { userId: v.id('users') },
handler: async (ctx, { userId }) => {
@@ -331,3 +349,36 @@ export const endOfShiftUpdate = action({
} else return;
},
});
export const automaticLunch = action({
handler: async (ctx) => {
const now = new Date(
new Date().toLocaleString('en-US', {
timeZone: 'America/Chicago',
}),
);
const users = await ctx.runQuery(api.auth.getAllUsers);
await Promise.all(
users.map(async (user) => {
if (user.automaticLunch && user.lunchTime) {
const [hours, minutes] = user.lunchTime.split(':').map(Number);
const userLunchTime = new Date(now);
userLunchTime.setHours(hours, minutes, 0, 0);
const diffInMs = userLunchTime.getTime() - now.getTime();
// Only schedule if lunch is in the future today
if (diffInMs > 0) {
await ctx.scheduler.runAfter(
diffInMs,
api.statuses.createLunchStatus,
{ userId: user.id },
);
} else {
console.warn(
`Skipped ${user.name} - lunch time ${user.lunchTime} already passed.`
);
}
}
})
);
},
});