diff --git a/CHANGELOG.md b/CHANGELOG.md index dacbfe1..3509576 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project follows [Semantic Versioning](https://semver.org/). ## [Unreleased] +### Added + +- Events now have an optional Location field (address), defaulting to the organisation's configured address when creating a new event. Wherever an address is shown — event admin form, public event page, event card listings, the Contact page, and Site Settings → Organisation — there's now a "Directions"/"View on map" link, and the event detail and Contact pages also show an embedded Google Maps view (no API key required). + ## [1.8.0] - 2026-08-21 ### Added diff --git a/backend/prisma/migrations/20260821090459_add_event_location/migration.sql b/backend/prisma/migrations/20260821090459_add_event_location/migration.sql new file mode 100644 index 0000000..8d4a4ed --- /dev/null +++ b/backend/prisma/migrations/20260821090459_add_event_location/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Event" ADD COLUMN "location" TEXT; diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index 95248bd..9c79b88 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -105,6 +105,7 @@ model Event { contactName String? contactPhone String? contactEmail String? + location String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt createdById String? diff --git a/backend/src/controllers/eventController.js b/backend/src/controllers/eventController.js index af32a59..e0ba75a 100644 --- a/backend/src/controllers/eventController.js +++ b/backend/src/controllers/eventController.js @@ -41,7 +41,7 @@ function toAbsoluteUrl(req, url) { // @access Private/Admin const createEvent = async (req, res) => { try { - const { title, description, startDate, endDate, registrationDeadline, goLiveAt, price, picture, redirectUrl, isHidden, requiresAuth, requiresRegistration, contactName, contactPhone, contactEmail } = req.body; + const { title, description, startDate, endDate, registrationDeadline, goLiveAt, price, picture, redirectUrl, isHidden, requiresAuth, requiresRegistration, contactName, contactPhone, contactEmail, location } = req.body; const data = { id: uuidv4(), @@ -62,6 +62,7 @@ const createEvent = async (req, res) => { contactName: contactName || null, contactPhone: contactPhone || null, contactEmail: contactEmail || null, + location: location || null, }; try { @@ -459,7 +460,7 @@ const updateEvent = async (req, res) => { // totals — same rule already enforced for payments/costs. Admin can reopen first. await assertEventOpen(req.params.id, res); - const { title, description, startDate, endDate, registrationDeadline, goLiveAt, price, picture, isActive, redirectUrl, isHidden, requiresAuth, requiresRegistration, contactName, contactPhone, contactEmail } = req.body; + const { title, description, startDate, endDate, registrationDeadline, goLiveAt, price, picture, isActive, redirectUrl, isHidden, requiresAuth, requiresRegistration, contactName, contactPhone, contactEmail, location } = req.body; const data = { title: title || event.title, @@ -477,6 +478,7 @@ const updateEvent = async (req, res) => { contactName: contactName !== undefined ? (contactName || null) : event.contactName, contactPhone: contactPhone !== undefined ? (contactPhone || null) : event.contactPhone, contactEmail: contactEmail !== undefined ? (contactEmail || null) : event.contactEmail, + location: location !== undefined ? (location || null) : event.location, updatedAt: new Date(), redirectUrl: redirectUrl !== undefined ? redirectUrl : event.redirectUrl, }; diff --git a/frontend/src/app/contact/page.tsx b/frontend/src/app/contact/page.tsx index 575f17c..db5c7c1 100644 --- a/frontend/src/app/contact/page.tsx +++ b/frontend/src/app/contact/page.tsx @@ -5,6 +5,7 @@ import { Navbar } from "@/components/layout/Navbar"; import { Footer } from "@/components/layout/Footer"; import { useSiteSettings } from "@/contexts/SiteSettingsContext"; import { appName } from "@/lib/siteConfig"; +import { LocationMap } from "@/components/events/LocationMap"; export default function ContactPage() { const { settings, loading } = useSiteSettings(); @@ -68,6 +69,12 @@ export default function ContactPage() { )} + + {address && ( +
+ +
+ )}