Skip to content

Commit 6abebbb

Browse files
authored
Merge pull request #12 from 42dotmk/events-backend-suport
Automated event creation for submitted event requests
2 parents 818e43f + 6e252d7 commit 6abebbb

7 files changed

Lines changed: 156 additions & 8 deletions

File tree

‎cms/src/api/event-request/content-types/event-request/schema.json‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,16 @@
5656
},
5757
"physicalPresence": {
5858
"type": "boolean"
59+
},
60+
"status": {
61+
"type": "enumeration",
62+
"enum": ["pending", "approved"],
63+
"default": "pending"
64+
},
65+
"event": {
66+
"type": "relation",
67+
"relation": "oneToOne",
68+
"target": "api::event.event"
5969
}
6070
}
6171
}

‎cms/src/api/event-request/controllers/event-request.ts‎

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,65 @@
44

55
import { factories } from '@strapi/strapi'
66

7-
export default factories.createCoreController('api::event-request.event-request');
7+
export default factories.createCoreController('api::event-request.event-request', ({ strapi }) => ({
8+
async approve(ctx) {
9+
const user = ctx.state?.user;
10+
if (!user) {
11+
return ctx.unauthorized();
12+
}
13+
14+
const { id } = ctx.params;
15+
16+
const request = (await strapi.documents('api::event-request.event-request').findOne({
17+
documentId: id,
18+
populate: { event: true } as never,
19+
})) as {
20+
documentId: string;
21+
status?: string;
22+
initiatorEmail?: string;
23+
eventName?: string;
24+
event?: { documentId: string } | null;
25+
} | null;
26+
27+
if (!request) {
28+
return ctx.notFound('Event request not found');
29+
}
30+
31+
if (!request.event) {
32+
return ctx.badRequest('No linked draft event found');
33+
}
34+
35+
if (request.status === 'approved') {
36+
return ctx.badRequest('Event request already approved');
37+
}
38+
39+
try {
40+
await strapi.documents('api::event.event').publish({
41+
documentId: request.event.documentId,
42+
});
43+
44+
await strapi.documents('api::event-request.event-request').update({
45+
documentId: id,
46+
data: { status: 'approved' } as Record<string, unknown>,
47+
});
48+
49+
await strapi.plugins['email'].services.email.send({
50+
to: request.initiatorEmail,
51+
from: 'hello@42.mk',
52+
replyTo: 'hello@42.mk',
53+
subject: 'Your event has been approved! - 42.mk',
54+
html: `
55+
<p>Great news! Your event request "<strong>${request.eventName}</strong>" has been approved and is now published.</p>
56+
<p>You can view it on our platform.</p>
57+
<p>Best regards,<br/>42.mk Team</p>
58+
`,
59+
});
60+
61+
ctx.body = { message: 'Event request approved' };
62+
} catch (error) {
63+
strapi.log.error('Error approving event request:', error);
64+
ctx.status = 500;
65+
ctx.body = { error: { message: 'Failed to approve event request' } };
66+
}
67+
},
68+
}));

‎cms/src/api/event-request/controllers/form.ts‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const formToJsonMap = {
1717
};
1818

1919
export default {
20-
async submit(ctx: any, next) {
20+
async submit(ctx, next) {
2121
const body = ctx.request.body;
2222

2323
try {
@@ -42,7 +42,7 @@ export default {
4242
acc[mappedKey] = value;
4343
}
4444
return acc;
45-
}, {} as any);
45+
}, {} as Record<string, unknown>);
4646

4747
eventRequest.physicalPresence = eventRequest.physicalPresence === "yes";
4848
eventRequest.eventStart += ":00";
@@ -52,6 +52,24 @@ export default {
5252
data: eventRequest,
5353
});
5454

55+
const startDateTime = `${eventRequest.eventDate}T${eventRequest.eventStart}`;
56+
57+
const draftEvent = await strapi.documents("api::event.event").create({
58+
data: {
59+
title: eventRequest.eventName,
60+
description: `${eventRequest.eventPurpose}\n\n${eventRequest.eventTheme}`,
61+
start: startDateTime,
62+
summary: eventRequest.eventAgenda,
63+
tags: eventRequest.eventTheme ? [{ tagName: eventRequest.eventTheme }] : [],
64+
},
65+
status: "draft",
66+
});
67+
68+
await strapi.documents("api::event-request.event-request").update({
69+
documentId: res.documentId,
70+
data: { event: draftEvent.documentId } as Record<string, unknown>,
71+
});
72+
5573
const requestCopy = `<p><strong>Organizing entity</strong>: ${eventRequest.organizingEntity}</p>
5674
<p><strong>Initiator name</strong>: ${eventRequest.initiatorName}</p>
5775
<p><strong>Initiator email</strong>: ${eventRequest.initiatorEmail}</p>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export default {
2+
routes: [
3+
{
4+
method: 'POST',
5+
path: '/event-requests/:id/approve',
6+
handler: 'event-request.approve',
7+
config: {
8+
policies: [],
9+
middlewares: [],
10+
},
11+
},
12+
],
13+
};
Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
/**
2-
* event-request router
3-
*/
4-
51
import { factories } from '@strapi/strapi';
62

7-
export default factories.createCoreRouter('api::event-request.event-request');
3+
export default factories.createCoreRouter('api::event-request.event-request');

‎cms/src/index.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
const admin = require('firebase-admin');
33
import fs from 'fs/promises';
44
import { eventNotificationMiddleware } from './middlewares/event-notifications';
5+
import { eventRequestApprovalMiddleware } from './middlewares/event-request-approval';
56

67
const FIREBASE_FCM_CREDENTIALS_PATH = './base42-mobile-app-fcm-firebase-adminsdk.json';
78

@@ -42,6 +43,7 @@ export default {
4243
});
4344

4445
strapi.documents.use(eventNotificationMiddleware());
46+
strapi.documents.use(eventRequestApprovalMiddleware());
4547
},
4648

4749
/**
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
export const eventRequestApprovalMiddleware = () => {
2+
return async (context, next) => {
3+
if (context.uid !== 'api::event.event') {
4+
return await next();
5+
}
6+
7+
const result = await next();
8+
9+
if (context.action === 'publish' && result?.documentId) {
10+
try {
11+
const request = await strapi.db.query('api::event-request.event-request').findOne({
12+
where: {
13+
event: { documentId: result.documentId },
14+
},
15+
});
16+
17+
if (request && request.status !== 'approved') {
18+
await strapi.documents('api::event-request.event-request').update({
19+
documentId: request.documentId,
20+
data: { status: 'approved' } as Record<string, unknown>,
21+
});
22+
23+
const reqDetails = await strapi.db.query('api::event-request.event-request').findOne({
24+
where: { documentId: request.documentId },
25+
});
26+
27+
if (reqDetails?.initiatorEmail) {
28+
await strapi.plugins['email'].services.email.send({
29+
to: reqDetails.initiatorEmail,
30+
from: 'hello@42.mk',
31+
replyTo: 'hello@42.mk',
32+
subject: 'Your event has been approved! - 42.mk',
33+
html: `
34+
<p>Great news! Your event request "<strong>${reqDetails.eventName}</strong>" has been approved and is now published.</p>
35+
<p>You can view it on our platform.</p>
36+
<p>Best regards,<br/>42.mk Team</p>
37+
`,
38+
});
39+
}
40+
}
41+
} catch (error) {
42+
strapi.log.error('[Event Request Approval] Error syncing status after publish:', error);
43+
}
44+
}
45+
46+
return result;
47+
};
48+
};

0 commit comments

Comments
 (0)