Skip to content

Commit 2f203be

Browse files
[dev] [Marfuen] mariano/create-task (#1495)
* feat: implement task creation functionality with validation and UI integration - Added a new action for creating tasks with input validation using Zod. - Implemented a CreateTaskSheet component for the task creation UI, integrating form handling and submission. - Updated TaskList and TaskFilterHeader components to include the new task creation functionality and controls retrieval. - Enhanced the TasksPage to fetch controls for task assignment. These changes improve task management capabilities within the application. * refactor: optimize task sheet component by replacing useMemo with useCallback - Changed the filter function in CreateTaskSheet from useMemo to useCallback to improve performance and prevent unnecessary re-renders. - Simplified the computation of selected options by removing the memoization, as it is now computed inline based on field.value. These changes enhance the efficiency of the CreateTaskSheet component in the task creation process. --------- Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
1 parent 5b406a2 commit 2f203be

File tree

5 files changed

+494
-36
lines changed

5 files changed

+494
-36
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
'use server';
2+
3+
import { authActionClient } from '@/actions/safe-action';
4+
import { db, Departments, TaskFrequency } from '@db';
5+
import { revalidatePath } from 'next/cache';
6+
import { headers } from 'next/headers';
7+
import { z } from 'zod';
8+
9+
const createTaskSchema = z.object({
10+
title: z.string().min(1, {
11+
message: 'Title is required',
12+
}),
13+
description: z.string().min(1, {
14+
message: 'Description is required',
15+
}),
16+
assigneeId: z.string().nullable().optional(),
17+
frequency: z.nativeEnum(TaskFrequency).nullable().optional(),
18+
department: z.nativeEnum(Departments).nullable().optional(),
19+
controlIds: z.array(z.string()).optional(),
20+
});
21+
22+
export const createTaskAction = authActionClient
23+
.inputSchema(createTaskSchema)
24+
.metadata({
25+
name: 'create-task',
26+
track: {
27+
event: 'create-task',
28+
channel: 'server',
29+
},
30+
})
31+
.action(async ({ parsedInput, ctx }) => {
32+
const { title, description, assigneeId, frequency, department, controlIds } = parsedInput;
33+
const {
34+
session: { activeOrganizationId },
35+
user,
36+
} = ctx;
37+
38+
if (!user.id || !activeOrganizationId) {
39+
throw new Error('Invalid user input');
40+
}
41+
42+
try {
43+
const task = await db.task.create({
44+
data: {
45+
title,
46+
description,
47+
assigneeId: assigneeId || null,
48+
organizationId: activeOrganizationId,
49+
status: 'todo',
50+
order: 0,
51+
frequency: frequency || null,
52+
department: department || null,
53+
...(controlIds &&
54+
controlIds.length > 0 && {
55+
controls: {
56+
connect: controlIds.map((id) => ({ id })),
57+
},
58+
}),
59+
},
60+
});
61+
62+
// Revalidate the path based on the header
63+
const headersList = await headers();
64+
let path = headersList.get('x-pathname') || headersList.get('referer') || '';
65+
path = path.replace(/\/[a-z]{2}\//, '/');
66+
revalidatePath(path);
67+
68+
return {
69+
success: true,
70+
task,
71+
};
72+
} catch (error) {
73+
console.error('Failed to create task:', error);
74+
return {
75+
success: false,
76+
error: 'Failed to create task',
77+
};
78+
}
79+
});

0 commit comments

Comments
 (0)