diff options
| author | Raphael <mail@raphaelkabo.com> | 2025-05-28 18:58:46 +0100 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-28 18:58:46 +0100 | 
| commit | 3d84891118f8a81af3ddb978af9b3f8b02fd5d65 (patch) | |
| tree | 0a8d344e331a0551b73435bbbb3919107737f69f /src/routes | |
| parent | 6f0b7a44b995b6b66baf42a9369182fc05a90b34 (diff) | |
| parent | 4664b6968fdcaca54268d60f400da02364213f05 (diff) | |
Merge branch 'main' into main
Diffstat (limited to 'src/routes')
| -rw-r--r-- | src/routes/event.ts | 25 | ||||
| -rw-r--r-- | src/routes/frontend.ts | 101 | ||||
| -rw-r--r-- | src/routes/magicLink.ts | 9 | 
3 files changed, 79 insertions, 56 deletions
diff --git a/src/routes/event.ts b/src/routes/event.ts index ee45d96..84a7c6b 100644 --- a/src/routes/event.ts +++ b/src/routes/event.ts @@ -27,7 +27,8 @@ import ical from "ical";  import { markdownToSanitizedHTML } from "../util/markdown.js";  import { checkMagicLink, getConfigMiddleware } from "../lib/middleware.js";  import { getConfig } from "../lib/config.js"; - +import i18next from "i18next"; +moment.locale(i18next.language);   const config = getConfig();  const storage = multer.memoryStorage(); @@ -397,33 +398,33 @@ router.put(                      : undefined,              };              let diffText = -                "<p>This event was just updated with new information.</p><ul>"; +                "<p>" + i18next.t("routes.event.difftext") + "</p><ul>";              let displayDate;              if (event.name !== updatedEvent.name) { -                diffText += `<li>the event name changed to ${updatedEvent.name}</li>`; +                diffText += `<li>` + i18next.t("routes.event.namechanged", { eventname: updatedEvent.name} ) + `</li>`;              }              if (event.location !== updatedEvent.location) { -                diffText += `<li>the location changed to ${updatedEvent.location}</li>`; +                diffText += `<li>` + i18next.t("routes.event.locationchanged", { location: updatedEvent.location} ) + `</li>`;              }              if (                  event.start.toISOString() !== updatedEvent.start.toISOString()              ) {                  displayDate = moment                      .tz(updatedEvent.start, updatedEvent.timezone) -                    .format("dddd D MMMM YYYY h:mm a"); -                diffText += `<li>the start time changed to ${displayDate}</li>`; +                    .format(i18next.t("common.datetimeformat")); +                diffText += `<li>` + i18next.t("routes.event.starttimechanged", { starttime: displayDate }) + `</li>`;              }              if (event.end.toISOString() !== updatedEvent.end.toISOString()) {                  displayDate = moment                      .tz(updatedEvent.end, updatedEvent.timezone) -                    .format("dddd D MMMM YYYY h:mm a"); -                diffText += `<li>the end time changed to ${displayDate}</li>`; +                    .format(i18next.t("common.datetimeformat")); +                diffText += `<li>` + i18next.t("routes.event.endtimechanged", { endtime: displayDate }) + `</li>`;              }              if (event.timezone !== updatedEvent.timezone) { -                diffText += `<li>the time zone changed to ${updatedEvent.timezone}</li>`; +                diffText += `<li>` + i18next.t("routes.event.timezonechanged", { timezone: updatedEvent.timezone }) + `</li>`;              }              if (event.description !== updatedEvent.description) { -                diffText += `<li>the event description changed</li>`; +                diffText += `<li>` + i18next.t("routes.event.descriptionchanged") + `</li>`;              }              diffText += `</ul>`;              const updatedEventObject = await Event.findOneAndUpdate( @@ -487,7 +488,7 @@ router.put(                  req.emailService.sendEmailFromTemplate({                      to: config.general.email,                      bcc: attendeeEmails, -                    subject: `${event.name} was just edited`, +                    subject: i18next.t("routes.event.editedsubject", { eventname: event.name}),                      templateName: "editEvent",                      templateData: {                          diffText, @@ -672,7 +673,7 @@ router.delete(              if (attendeeEmail) {                  await req.emailService.sendEmailFromTemplate({                      to: attendeeEmail, -                    subject: "You have been removed from an event", +                    subject: i18next.t("routes.removeeventattendeesubject"),                      templateName: "unattendEvent",                      templateData: {                          eventID: req.params.eventID, diff --git a/src/routes/frontend.ts b/src/routes/frontend.ts index 1b95763..fca14c6 100644 --- a/src/routes/frontend.ts +++ b/src/routes/frontend.ts @@ -7,7 +7,7 @@ import {      instanceDescription,      instanceRules,  } from "../lib/config.js"; -import { addToLog, exportICal } from "../helpers.js"; +import { addToLog, exportIcal } from "../helpers.js";  import Event from "../models/Event.js";  import EventGroup, { IEventGroup } from "../models/EventGroup.js";  import { @@ -18,6 +18,7 @@ import MagicLink from "../models/MagicLink.js";  import { getConfigMiddleware } from "../lib/middleware.js";  import { getMessage } from "../util/messages.js";  import { EventListEvent, bucketEventsByMonth } from "../lib/event.js"; +import i18next from "i18next";  const router = Router(); @@ -48,7 +49,7 @@ router.get("/new", (_: Request, res: Response) => {          return res.render("createEventMagicLink", frontendConfig(res));      }      return res.render("newevent", { -        title: "New event", +        title: i18next.t("frontend.newevent"),          ...frontendConfig(res),      });  }); @@ -69,12 +70,12 @@ router.get("/new/:magicLinkToken", async (req: Request, res: Response) => {              ...frontendConfig(res),              message: {                  type: "danger", -                text: "This magic link is invalid or has expired. Please request a new one here.", +                text: i18next.t("routes.magiclink-invalid"),              },          });      }      res.render("newevent", { -        title: "New event", +        title: i18next.t("frontend.newevent"),          ...frontendConfig(res),          magicLinkToken: req.params.magicLinkToken,          creatorEmail: magicLink.email, @@ -99,9 +100,9 @@ router.get("/events", async (_: Request, res: Response) => {              name: event.name,              location: event.location,              displayDate: isSameDay -                ? startMoment.format("D MMM YYYY") -                : `${startMoment.format("D MMM YYYY")} - ${endMoment.format( -                      "D MMM YYYY", +                ? startMoment.format("LL") +                : `${startMoment.format("LL")} - ${endMoment.format( +                      "LL",                    )}`,              eventHasConcluded: endMoment.isBefore(moment.tz(event.timezone)),              eventGroup: event.eventGroup as any as IEventGroup, @@ -131,7 +132,7 @@ router.get("/events", async (_: Request, res: Response) => {      });      res.render("publicEventList", { -        title: "Public events", +        title: i18next.t("frontend.publicevents"),          upcomingEvents: upcomingEventsInMonthBuckets,          pastEvents: pastEventsInMonthBuckets,          eventGroups: updatedEventGroups, @@ -153,31 +154,53 @@ router.get("/:eventID", async (req: Request, res: Response) => {          }          const parsedLocation = event.location.replace(/\s+/g, "+");          let displayDate; +        const dateformat = i18next.t("frontend.dateformat"); +        const timeformat = i18next.t('frontend.timeformat');          if (moment.tz(event.end, event.timezone).isSame(event.start, "day")) {              // Happening during one day -            displayDate = -                moment -                    .tz(event.start, event.timezone) -                    .format( -                        'dddd D MMMM YYYY [<span class="text-muted">from</span>] h:mm a', -                    ) + -                moment -                    .tz(event.end, event.timezone) -                    .format( -                        ' [<span class="text-muted">to</span>] h:mm a [<span class="text-muted">](z)[</span>]', -                    ); +            displayDate = i18next.t("frontend.displaydate-sameday", +                {  +                    startdate:  +                        moment +                            .tz(event.start, event.timezone) +                            .format(dateformat), +                    starttime: +                        moment +                            .tz(event.start, event.timezone) +                            .format(timeformat), +                    endtime: +                        moment +                            .tz(event.end, event.timezone) +                            .format(timeformat), +                    timezone: +                        moment +                            .tz(event.end, event.timezone) +                            .format('(z)',) +                });          } else { -            displayDate = -                moment -                    .tz(event.start, event.timezone) -                    .format( -                        'dddd D MMMM YYYY [<span class="text-muted">at</span>] h:mm a', -                    ) + -                moment -                    .tz(event.end, event.timezone) -                    .format( -                        ' [<span class="text-muted">–</span>] dddd D MMMM YYYY [<span class="text-muted">at</span>] h:mm a [<span class="text-muted">](z)[</span>]', -                    ); +            displayDate = i18next.t("frontend.displaydate-days", +                { +                    startdate: +                        moment +                            .tz(event.start, event.timezone) +                            .format(dateformat), +                    starttime: +                        moment +                            .tz(event.start, event.timezone) +                            .format(timeformat), +                    enddate: +                        moment +                            .tz(event.end, event.timezone) +                            .format(dateformat), +                    endtime: +                        moment +                            .tz(event.end, event.timezone) +                            .format(timeformat), +                    timezone: +                        moment +                            .tz(event.end, event.timezone) +                            .format('(z)',) +                });          }          let eventStartISO = moment.tz(event.start, "Etc/UTC").toISOString();          let eventEndISO = moment.tz(event.end, "Etc/UTC").toISOString(); @@ -256,7 +279,7 @@ router.get("/:eventID", async (req: Request, res: Response) => {                      el.id = el._id;                  }                  if (el.number && el.number > 1) { -                    el.name = `${el.name} (${el.number} people)`; +                    el.name = `${el.name} ${i18next.t("frontend.elnumber", { count: el.number })}`;                  }                  return {                      ...el, @@ -428,8 +451,8 @@ router.get("/group/:eventGroupID", async (req: Request, res: Response) => {              .sort("start");          const updatedEvents: EventListEvent[] = events.map((event) => { -            const startMoment = moment.tz(event.start, event.timezone); -            const endMoment = moment.tz(event.end, event.timezone); +            const startMoment = moment.tz(event.start, event.timezone).locale(i18next.language); +            const endMoment = moment.tz(event.end, event.timezone).locale(i18next.language);              const isSameDay = startMoment.isSame(endMoment, "day");              return { @@ -437,10 +460,8 @@ router.get("/group/:eventGroupID", async (req: Request, res: Response) => {                  name: event.name,                  location: event.location,                  displayDate: isSameDay -                    ? startMoment.format("D MMM YYYY") -                    : `${startMoment.format("D MMM YYYY")} - ${endMoment.format( -                          "D MMM YYYY", -                      )}`, +                    ? startMoment.format("LL") +                    : `${startMoment.format("LL")} - ${endMoment.format("LL")}`,                  eventHasConcluded: endMoment.isBefore(                      moment.tz(event.timezone),                  ), @@ -545,7 +566,7 @@ router.get(                  const events = await Event.find({                      eventGroup: eventGroup._id,                  }).sort("start"); -                const string = exportICal(events, eventGroup.name); +                const string = exportIcal(events, eventGroup.name);                  res.set("Content-Type", "text/calendar").send(string);              }          } catch (err) { @@ -567,7 +588,7 @@ router.get("/export/event/:eventID", async (req: Request, res: Response) => {          }).populate("eventGroup");          if (event) { -            const string = exportICal([event], event.name); +            const string = exportIcal([event], event.name);              res.set("Content-Type", "text/calendar").send(string);          }      } catch (err) { @@ -593,7 +614,7 @@ router.get(                  const events = await Event.find({                      eventGroup: eventGroup._id,                  }).sort("start"); -                const string = exportICal(events, eventGroup.name); +                const string = exportIcal(events, eventGroup.name);                  res.set("Content-Type", "text/calendar").send(string);              }          } catch (err) { diff --git a/src/routes/magicLink.ts b/src/routes/magicLink.ts index e0a6310..1e0f87b 100644 --- a/src/routes/magicLink.ts +++ b/src/routes/magicLink.ts @@ -3,6 +3,7 @@ import { frontendConfig } from "../lib/config.js";  import { generateMagicLinkToken } from "../util/generator.js";  import MagicLink from "../models/MagicLink.js";  import { getConfigMiddleware } from "../lib/middleware.js"; +import i18next from "i18next";  const router = Router(); @@ -15,7 +16,7 @@ router.post("/magic-link/event/create", async (req: Request, res: Response) => {              ...frontendConfig(res),              message: {                  type: "danger", -                text: "Please provide an email address.", +                text: i18next.t("routes.magiclink.provideemail"),              },          });          return; @@ -30,7 +31,7 @@ router.post("/magic-link/event/create", async (req: Request, res: Response) => {              ...frontendConfig(res),              message: {                  type: "success", -                text: "Thanks! If this email address can create events, you should receive an email with a magic link.", +                text: i18next.t("routes.magiclink.thanks"),              },          });          return; @@ -49,7 +50,7 @@ router.post("/magic-link/event/create", async (req: Request, res: Response) => {      req.emailService.sendEmailFromTemplate({          to: email, -        subject: "Magic link to create an event", +        subject: i18next.t("routes.magiclink.mailsubject"),          templateName: "createEventMagicLink",          templateData: {              token @@ -59,7 +60,7 @@ router.post("/magic-link/event/create", async (req: Request, res: Response) => {          ...frontendConfig(res),          message: {              type: "success", -            text: "Thanks! If this email address can create events, you should receive an email with a magic link.", +            text: i18next.t("routes.magiclink.thanks"),          },      });  });  | 
