Skip to content

Commit 502faf1

Browse files
ok, mtn la partie discord logs, la on l'avais dans CodeSpace, on peut pt
1 parent 8692b62 commit 502faf1

5 files changed

Lines changed: 299 additions & 41 deletions

File tree

src/app/(app)/projects/[id]/actions.ts

Lines changed: 94 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,15 @@ import {
3434
getUserGithubOAuthToken as dbGetUserGithubOAuthToken,
3535
deleteUserGithubOAuthToken as dbDeleteUserGithubOAuthToken,
3636
getTaskByUuid as dbGetTaskByUuid,
37+
updateProjectDiscordSettings as dbUpdateProjectDiscordSettings,
3738
} from '@/lib/db';
3839
import { z } from 'zod';
3940
import { auth } from '@/lib/authEdge';
4041
import { Octokit } from 'octokit';
4142
import { Buffer } from 'buffer';
4243
import { generateProjectScaffold, type GenerateProjectScaffoldInput, type GenerateProjectScaffoldOutput } from '@/ai/flows/generate-project-scaffold';
4344
import { editFileContentWithAI, type EditFileContentAIInput, type EditFileContentAIOutput } from '@/ai/flows/edit-file-content-ai';
45+
import { sendDiscordNotification } from '@/lib/discord';
4446

4547

4648
export async function fetchProjectAction(uuid: string | undefined): Promise<Project | null> {
@@ -134,12 +136,12 @@ export async function inviteUserToProjectAction(
134136
formData: FormData
135137
): Promise<InviteUserFormState> {
136138
const session = await auth();
137-
if (!session?.user?.uuid) {
138-
console.error("[inviteUserToProjectAction] Authentication required. No session user UUID.");
139+
if (!session?.user?.uuid || !session.user.name) {
140+
console.error("[inviteUserToProjectAction] Authentication required. No session user UUID or name.");
139141
return { error: "Authentication required." };
140142
}
141143
const inviterUserUuid = session.user.uuid;
142-
console.log("[inviteUserToProjectAction] Authenticated user for permission check:", inviterUserUuid);
144+
const inviterName = session.user.name;
143145

144146
const validatedFields = InviteUserSchema.safeParse({
145147
projectUuid: formData.get('projectUuid'),
@@ -160,7 +162,6 @@ export async function inviteUserToProjectAction(
160162
if (!project) return { error: "Project not found." };
161163

162164
const inviterRole = await dbGetProjectMemberRole(projectUuid, inviterUserUuid);
163-
console.log(`[inviteUserToProjectAction] Inviter role check for project ${projectUuid} (user ${inviterUserUuid}): ${inviterRole}`);
164165
if (!inviterRole || !['owner', 'co-owner'].includes(inviterRole)) {
165166
return { error: `You do not have permission to invite users to this project. Your role: ${inviterRole || 'not a member'}. UUID: ${inviterUserUuid}` };
166167
}
@@ -200,7 +201,7 @@ export async function inviteUserToProjectAction(
200201
invitedUserGithubLogin = invitedUserOAuthDetails.login;
201202
console.log(`[inviteUserToProjectAction] Fetched GitHub login for invited user: ${invitedUserGithubLogin}`);
202203
} else {
203-
console.log(`[inviteUserToProjectAction] Invited user ${userToInvite.email} has not connected their GitHub account via OAuth or login not found.`);
204+
console.log(`[inviteUserToProjectAction] Invited user ${userToInvite.email} has not connected their GitHub account or login not found.`);
204205
}
205206

206207

@@ -238,6 +239,18 @@ export async function inviteUserToProjectAction(
238239
}
239240
}
240241

242+
if (project.discordWebhookUrl && project.discordNotificationsEnabled) {
243+
await sendDiscordNotification(project.discordWebhookUrl, {
244+
embeds: [{
245+
title: "👥 New Member Invited",
246+
description: `**${userToInvite.name}** was invited to the project as a **${role}** by **${inviterName}**.`,
247+
color: 3447003, // Blue
248+
timestamp: new Date().toISOString(),
249+
footer: { text: `Project: ${project.name}` }
250+
}]
251+
});
252+
}
253+
241254
return { message: `${userToInvite.name} has been successfully ${existingMembership ? 'updated to role' : 'invited as'} ${role}.${githubMessage}`, invitedMember: newOrUpdatedMember };
242255
} catch (error: any) {
243256
console.error("Error inviting user:", error);
@@ -314,11 +327,11 @@ export interface CreateTaskFormState {
314327

315328
export async function createTaskAction(prevState: CreateTaskFormState, formData: FormData): Promise<CreateTaskFormState> {
316329
const session = await auth();
317-
if (!session?.user?.uuid) {
318-
console.error("[createTaskAction] Authentication required. No session user UUID.");
330+
if (!session?.user?.uuid || !session.user.name) {
331+
console.error("[createTaskAction] Authentication required. No session user UUID or name.");
319332
return { error: "Authentication required." };
320333
}
321-
console.log("[createTaskAction] Authenticated user:", session.user.uuid);
334+
const creatorName = session.user.name;
322335

323336
const validatedFields = CreateTaskSchema.safeParse({
324337
projectUuid: formData.get('projectUuid'),
@@ -343,8 +356,10 @@ export async function createTaskAction(prevState: CreateTaskFormState, formData:
343356
}
344357

345358
try {
359+
const project = await dbGetProjectByUuid(projectUuid);
360+
if (!project) return { error: "Project not found." };
361+
346362
const userRole = await dbGetProjectMemberRole(projectUuid, session.user.uuid);
347-
console.log(`[createTaskAction] User role for project ${projectUuid} (user ${session.user.uuid}): ${userRole}`);
348363
if (!userRole || !['owner', 'co-owner', 'editor'].includes(userRole)) {
349364
return { error: `You do not have permission to create tasks in this project. Your role: ${userRole || 'not a member'}. UUID: ${session.user.uuid}` };
350365
}
@@ -359,6 +374,23 @@ export async function createTaskAction(prevState: CreateTaskFormState, formData:
359374
tagsString: tagsString || undefined,
360375
};
361376
const createdTask = await dbCreateTask(taskData);
377+
378+
if (project.discordWebhookUrl && project.discordNotificationsEnabled) {
379+
await sendDiscordNotification(project.discordWebhookUrl, {
380+
embeds: [{
381+
title: `✅ New Task Created: ${createdTask.title}`,
382+
description: `A new task has been added by **${creatorName}**.`,
383+
color: 5763719, // Green
384+
fields: [
385+
{ name: "Status", value: createdTask.status, inline: true },
386+
{ name: "Assigned To", value: createdTask.assigneeName || "Everyone", inline: true },
387+
],
388+
timestamp: new Date().toISOString(),
389+
footer: { text: `Project: ${project.name}` }
390+
}]
391+
});
392+
}
393+
362394
return { message: "Task created successfully!", createdTask };
363395
} catch (error: any) {
364396
console.error("Error creating task:", error);
@@ -1793,3 +1825,56 @@ export async function editFileWithAIAction(
17931825
return { error: `AI file editing failed: ${error.message || "An unexpected error occurred."}` };
17941826
}
17951827
}
1828+
1829+
1830+
export interface UpdateProjectDiscordSettingsFormState {
1831+
message?: string;
1832+
error?: string;
1833+
project?: Project;
1834+
}
1835+
1836+
const updateDiscordSettingsSchema = z.object({
1837+
projectUuid: z.string().uuid(),
1838+
discordWebhookUrl: z.string().url("Please enter a valid Discord webhook URL.").or(z.literal('')),
1839+
discordNotificationsEnabled: z.enum(['true', 'false']).transform(v => v === 'true'),
1840+
});
1841+
1842+
export async function updateProjectDiscordSettingsAction(
1843+
prevState: UpdateProjectDiscordSettingsFormState,
1844+
formData: FormData
1845+
): Promise<UpdateProjectDiscordSettingsFormState> {
1846+
const session = await auth();
1847+
if (!session?.user?.uuid) {
1848+
return { error: "Authentication required." };
1849+
}
1850+
1851+
const validatedFields = updateDiscordSettingsSchema.safeParse({
1852+
projectUuid: formData.get('projectUuid'),
1853+
discordWebhookUrl: formData.get('discordWebhookUrl'),
1854+
discordNotificationsEnabled: formData.get('discordNotificationsEnabled'),
1855+
});
1856+
1857+
if (!validatedFields.success) {
1858+
return { error: "Invalid input: " + validatedFields.error.flatten().fieldErrors.discordWebhookUrl?.join(', ') };
1859+
}
1860+
1861+
const { projectUuid, discordWebhookUrl, discordNotificationsEnabled } = validatedFields.data;
1862+
1863+
try {
1864+
const userRole = await dbGetProjectMemberRole(projectUuid, session.user.uuid);
1865+
if (!userRole || !['owner', 'co-owner'].includes(userRole)) {
1866+
return { error: "You do not have permission to change Discord settings for this project." };
1867+
}
1868+
1869+
const updatedProject = await dbUpdateProjectDiscordSettings(projectUuid, discordWebhookUrl, discordNotificationsEnabled);
1870+
1871+
if (!updatedProject) {
1872+
return { error: "Failed to update project settings in the database." };
1873+
}
1874+
1875+
return { message: "Discord settings updated successfully.", project: updatedProject };
1876+
1877+
} catch (error: any) {
1878+
return { error: error.message || "An unexpected error occurred." };
1879+
}
1880+
}

0 commit comments

Comments
 (0)