Skip to content
Snippets Groups Projects
Commit 54940dc0 authored by Alexander Schoch's avatar Alexander Schoch
Browse files

Merge branch 'dev' into 'main'

Update to newest version after release of new website

See merge request vseth/0500-kom/0522-thealt/website!2
parents 253c2dde a2df2863
No related branches found
No related tags found
No related merge requests found
......@@ -153,7 +153,7 @@ export default function EventCard({
</div>
<div>
{!event.isStammtisch && (
<Group style={{ verticalAlign: "middle", marginTop: "20px" }}>
<Group style={{ verticalAlign: "middle", marginTop: "20px" }} grow>
{event.signUp ? (
<Button
href={event.signUp}
......
import { useState } from "react";
import { useTranslation } from "next-i18next";
import { Button, Modal, Table } from "@mantine/core";
import { Button, Group, Modal, Table } from "@mantine/core";
import { gql, useMutation } from "@apollo/client";
const sendReminderMutation = gql`
mutation sendReminder($id: Int) {
sendReminder(id: $id)
}
`;
export default function SignUpsModal({ open, close, event }) {
const { t } = useTranslation("common");
const [sendReminder] = useMutation(sendReminderMutation);
const [loading, setLoading] = useState(false);
const copyMailAddresses = () => {
const addresses = event.signUps.map((signUp) => signUp.email).join(", ");
navigator.clipboard.writeText(addresses);
};
const sendRem = async () => {
setLoading(true);
await sendReminder({
variables: {
id: event.id,
},
});
setLoading(false);
};
if (!event) return <></>;
return (
......@@ -34,9 +56,12 @@ export default function SignUpsModal({ open, close, event }) {
</tbody>
</Table>
<Button onClick={copyMailAddresses} mt="md">
{t("copyMailAddresses")}
</Button>
<Group grow mt="md">
<Button onClick={copyMailAddresses}>{t("copyMailAddresses")}</Button>
<Button onClick={sendRem} loading={loading}>
{t("sendReminder")}
</Button>
</Group>
</Modal>
);
}
......@@ -11,6 +11,8 @@ import {
import { Icon, ICONS } from "vseth-canine-ui";
import { getAccentColor } from "../utilities/colors";
const useStyles = createStyles((theme) => ({
link: {
...theme.fn.focusStyles(),
......@@ -119,7 +121,7 @@ export default function TOC() {
}}
>
<Group mb="md">
<Icon icon={ICONS.LIST} />
<Icon icon={ICONS.LIST} color={getAccentColor(theme)} />
<Text>Table of contents</Text>
</Group>
{entries}
......
......@@ -3,7 +3,10 @@ import { getServerSession } from "next-auth/next";
import { authOptions } from "../pages/api/auth/[...nextauth]";
import hasAccess from "../utilities/hasAccess";
import { isInFuture } from '../utilities/dates';
import { isInFuture, formatDateFromDB, formatTimeFromDB } from '../utilities/dates';
import { sendMail } from '../utilities/mail';
import config from '../thealternative.config';
export const resolvers = {
Query: {
......@@ -21,8 +24,9 @@ export const resolvers = {
lastName: hasAccess(session, true),
email: hasAccess(session, true)
}
},
}
}
},
orderBy: [{date: 'asc'}, {startTime: 'asc'}]
});
const futureEvents = events.filter((event) => isInFuture(event));
return futureEvents;
......@@ -59,6 +63,8 @@ export const resolvers = {
addSignUp: async(_, { id }, { session }) => {
if(!hasAccess(session, false)) return false;
const event = await prisma.event.findUnique({ where: { id }});
const signUp = await prisma.signUp.create({
data: {
eventId: id,
......@@ -69,6 +75,18 @@ export const resolvers = {
}
});
sendMail(
session.info.payload.email,
config.address,
config.signUpText
.replace('NAME', session.info.payload.given_name)
.replace('EVENT', event.title)
.replace('DATE', formatDateFromDB(event.date, 'en'))
.replace('TIME', formatTimeFromDB(event.startTime, event.endTime))
.replace('PLACE', event.place),
config.signUpSubject
);
return signUp ? true : false;
},
removeSignUp: async(_, { id }, { session }) => {
......@@ -89,7 +107,36 @@ export const resolvers = {
}
});
return true;
},
sendReminder: async(_, { id }, { session }) => {
if(!hasAccess(session, true)) return false;
const event = await prisma.event.findUnique({
where: { id },
include: {
signUps: true,
}
});
const promises = event.signUps.map(async (signUp) => {
await sendMail(
signUp.email,
config.address,
config.reminderText
.replace('NAME', signUp.firstName)
.replace('EVENT', event.title)
.replace('DATE', formatDateFromDB(event.date, 'en'))
.replace('TIME', formatTimeFromDB(event.startTime, event.endTime))
.replace('PLACE', event.place),
config.reminderSubject
);
});
Promise.allSettled(promises).then(([result]) => {
return true;
});
return true;
}
},
}
};
......@@ -36,6 +36,7 @@ export const typeDefs = `
editEvent(id: Int, title: String, speaker: String, description: String, date: DateTime, time: [DateTime], place: String, signUp: String, isStammtisch: Boolean): Boolean
addSignUp(id: Int): Boolean
removeSignUp(id: Int): Boolean
sendReminder(id: Int): Boolean
}
`;
......@@ -40,5 +40,6 @@
"viewParticipants": "Teilnehmendenliste",
"participants": "Teilnehmendenliste",
"copyMailAddresses": "Mailadressen Kopieren",
"loadTemplate": "Template Laden"
"loadTemplate": "Template Laden",
"sendReminder": "Reminder Versenden"
}
\ No newline at end of file
......@@ -40,5 +40,6 @@
"viewParticipants": "View Participants",
"participants": "Participants",
"copyMailAddresses": "Copy Mail Addresses",
"loadTemplate": "Load Template"
"loadTemplate": "Load Template",
"sendReminder": "Send Reminder"
}
\ No newline at end of file
......@@ -4,6 +4,7 @@ p {
h1 {
font-size: 4rem !important;
overflow-x: auto;
}
h2 {
......@@ -142,12 +143,13 @@ p {
}
.bash-guide pre {
background-color: #eeeeee;
padding: 0.5rem;
background-color: rgba(125,125,125,0.1);
overflow-x: auto;
}
.bash-guide p>code {
color: #888888;
color: #f28a20;
}
.vseth-footer-dark {
......
This diff is collapsed.
......@@ -15,10 +15,11 @@ export function formatDateFromDB(date, locale) {
export function formatTimeFromDB(startTime, endTime) {
const s = dayjs(startTime);
const e = dayjs(endTime);
return s.format("HH:mm") + " " + e.format("HH:mm");
return s.format("HH:mm") + " " + e.format("HH:mm");
}
export function isInFuture(event) {
// TODO: implement logic
return true;
const now = new Date();
now.setDate(now.getDate() - 1);
return event.date > now.toISOString();
}
......@@ -3,8 +3,7 @@ export default function hasAccess(session, admin) {
const prod_role = "thealt_prod_website_website";
// this is just for development purposes
return true;
return session ? true : false;
// return session ? true : false;
if (process.env.NODE_ENV && process.env.NODE_ENV === "development")
return session ? true : false;
......
import nodemailer from "nodemailer";
export async function sendMail(receiver, replyTo, html, subject) {
const transporter = nodemailer.createTransport({
host: process.env.MAILER_HOST,
port: 587,
secure: false, // true for 465, false for other ports
auth: {
user: process.env.MAILER_USERNAME,
pass: process.env.MAILER_PASSWORD,
},
});
await transporter.sendMail({
from: process.env.MAILER_NAME,
to: receiver,
replyTo: replyTo,
subject: subject,
html: html,
});
return;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment