Disclaimer: This is a non-commercial project created as part of our web development course. All photos and media content are the property of their respective owners and are used solely for educational and demonstrational purposes.
Note: The back end is hosted on Render's free tier - please allow ~10 seconds for the initial load while the server spins up from the cold start.
The Greenroom is a web platform connecting artists and small venues in Germany for performances, jam sessions, and gigs. It provides a space where musicians, comedians, poets, and other performers can showcase their work and easily find performance opportunities, while venues can discover new talent and manage their bookings efficiently.
See live demo here.
This web application was developed from March to April 2025 as a final project for our Web Development course.
The team consisted of 4 full stack developers:
- User registration & login
- Role selection (artist or venue) upon signup
- Verification email upon signup (required)
- Guest access (limited browsing: no favouriting, booking access or messaging)
- Edit account settings (first name, last name, email)
- Change password
- Delete account and all associated data
- Edit public profile information (public name, description, genres & types, media, address & opening/performing times, revenue split, and availability)
- Set own available dates on calendar and see booked dates
- Create bio and upload media and photos about work/space
- Browse venues and artists and view individual profiles
- Set own available dates in dashboard
- Check availability and book an artist or venue via calendar on individual profile pages (both artists and venues can do this)
- Request a booking (both artists and venues can do this)
- Receive a booking (both artists and venues can do this)
- Received and requested bookings are stored under My Bookings in the user dashboard
- Booking dates can be edited by the user who initated it until booking is accepted from the receiver
- Once booking is accepted by the other party, the booking moves from My Bookings to My Confirmed Gigs
- When a booking is accepted, an email is sent to the other party
- When a booking is declined by the other party, an email is sent to the other party and removed from user dashboard (kept in DB)
- When a booking is cancelled by the other party, an email is sent to the other party and removed from user dashboard (kept in DB)
- Search & filter system in both Find Artists and Find Venues pages with text search and dropdown filters
- User dashboard (bookings, confirmed gigs, profile and user data management)
- Contact user via email form (only once booking has been accepted) or social links
- Responsive design (accessible across devices)
- Reviews & ratings
- Preview profile before publishing
- Germany-only address filter
- Auto-filling addresses & search bar
- Real-time notification system (Socket.IO)
Users can be artists, venues or guests.
- As an artist, I want to register and receive a verification email. I am redirected to login page and after logging in, I am redirected to my dashboard.
- As an artist, I want to be able to change my password. After clicking "Change Password", I am redirected to the login page so I can login with my new password.
- As an artist, I want to be able to change my email. After this, I am informed about a verification link sent to my email and I am logged out. I must then verify new email through the link and login again with updated email.
- As an artist, I want to be able to delete my account. After typing DELETE, I am redirected to the login page and my account and all associated data are permanently deleted.
- As an artist, I want to create a profile so that I can showcase my work and attract venues.
- As an artist, I want to upload links and photos to my profile so that venues can see examples of my performances.
- As an artist, I want to be able to set my availability in my calendar in the user dashboard.
- As an artist, I want to browse all venues and see their available gig dates and revenue split so that I can decide whether to make a booking.
- As an artist, I want to browse other artists and see their next three confirmed gigs with dates, names and clickable profile pictures of the venues.
- As an artist, I want to receive bookings from venues via my booking calendar on my profile page.
- As an artist, I want to book venues via the venue's booking calendar on their profile page.
- As an artist, I want to see my received and sent bookings in my user dashboard with the booking details (name, profile picture, link to profile, date, revenue split).
- As an artist, I want to be able to edit the booking date I requested before the booking is accepted by the other party.
- As an artist, I want to be able to accept or decline received bookings, and an email will be sent to the other party in both cases.
- As an artist, I want to see my accepted bookings stored under "My Confirmed Gigs" in the user dashboard.
- As an artist, I want to be able to cancel accepted bookings, and an email will be sent to the other party.
- As an artist, I want to contact the venue via an email form. This is only possible for confirmed gigs. Users can always access each other's social media.
- As an artist, I want to favourite artists and venues, but I cannot favourite my own profile.
- As a venue, I want to register and receive a verification email. I am redirected to login page and after logging in, I am redirected to my dashboard.
- As a venue, I want to be able to change my password. After clicking "Change Password", I am redirected to the login page so I can login with my new password.
- As a venue, I want to be able to change my email. After this, I am informed about a verification link sent to my email and I am logged out. I must then verify new email through the link and login again with updated email.
- As a venue, I want to be able to delete my account. After typing DELETE, I am redirected to the login page and my account and all associated data are permanently deleted.
- As a venue, I want to create a profile so that artists can learn about my venue and available gig dates.
- As a venue, I want to add the address of my venue to my profile, as well as opening and performing times.
- As a venue, I want to define the revenue split on my profile.
- As a venue, I want to upload links and photos of my venue so that artists can see the performance space.
- As a venue, I want to be able to set my availability in my calendar in the user dashboard.
- As a venue, I want to browse all artists and see their available gig dates and music so that I can decide whether to make a booking.
- As a venue, I want to browse other venues and see their next three confirmed gigs with dates, names and clickable profile pictures of the artists.
- As a venue, I want to receive bookings from artists via my booking calendar on my profile page.
- As a venue, I want to book artists via the artist's booking calendar on their profile page.
- As a venue, I want to see my received and sent bookings in my user dashboard with the booking details (name, profile picture, link to profile, date, revenue split).
- As a venue, I want to be able to edit the booking date I requested before the booking is accepted by the other party.
- As a venue, I want to be able to accept or decline received bookings, and an email will be sent to the other party in both cases.
- As a venue, I want to see my accepted bookings stored under "My Confirmed Gigs" in the user dashboard.
- As a venue, I want to be able to cancel accepted bookings, and an email will be sent to the other party.
- As a venue, I want to contact the artist via an email form. This is only possible for confirmed gigs. Users can always access each other's social media.
- As a venue, I want to favourite artists and venues, but I cannot favourite my own profile.
- As a guest, I want to see a homepage explaining how The Greenroom works so that I understand the platform's purpose before signing up. Registered users can also see this.
- As a guest, I want to access the registration and login pages so that I can create an account when I'm ready.
- As a guest, I want to browse all venues so that I can explore potential performance spaces before signing up.
- As a guest, I want to browse all artists so that I can see the types of performers available on the platform.
- As a guest, I want to see individual venue and artist profiles so that I can get a sense of the platform. I cannot make bookings, favourite artists/venues, or email artists/venues, but I can see their social media links.
- Register Page: Sign up for an account
- Login Page: Securely log in
- Forgot Password Page: Send a reset link to email
- Reset Password Page: Set new password
- Homepage: Explain how platform works and have a glimpse of what users can do
- All Artists Page (Find Artists): Display all artist cards
- All Venues Page (Find Venues): Display all venue cards
- Individual Artist Page: Artist profile page with gallery and details, media, social links, and booking calendar
- Individual Venue Page: Venue profile page with gallery and details, media, social links, and booking calendar
- Favourites Page: Display all favourited artists and venues
- My Greenroom: Profile type, first name, last name, email, password. Ability to edit all data, change password and delete account.
- My Account: Profile type, first name, last name, email, password. Ability to edit all data, change password and delete account.
- My Public Profile: Artistic name/venue name, description, profile picture, performance type, genre, images, social links, media links, and calendar availability. Address, revenue split, opening times and performing times for venues only. Ability to edit all data.
- My Bookings: Received bookings (to accept or decline) & sent bookings (with option to edit booking date, only enabled until booking is accepted). If accepted, booking moves to My Confirmed Gigs and an email is sent to the other party. If declined, booking is removed from dashboard but remains in DB (soft delete) and an email is sent to the other party.
- My Confirmed Gigs - Gig cards with option to message other party via email form or to cancel. If cancelled, booking is removed from dashboard but remains in DB (soft delete) and an email is sent to the other party.
- About Us Page: Briefly explain the platform and its purpose
- Privacy Policy Page: Explain how we handle user data and privacy
- Contact Us Page: Contact form to send a message to the platform admins via Formspree
- Terms of Service Page: Reference to our Privacy Policy
- Not Found Page: A 404 page for invalid URLs
const UserSchema = new Schema(
{
// Registration
firstName: { type: String, required: true },
lastName: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
role: { type: String, enum: ["artist", "venue"], required: true }, // Defines account type
isConfirmed: { type: Boolean, default: false }, // Email verification
// Profile
name: { type: String }, // artisticName for artists & venue name for venues
description: { type: String }, // Bio for artists & description for venues
type: [{ type: String }], // Performance type for artists & venue type for venues
//additionalInfo for venue or artist only:
additionalInfo: {
// Venue only:
address: {
streetName: { type: String },
number: { type: String },
zipCode: { type: String },
city: { type: String },
},
revenueSplit: { type: String },
openingTimes: [{ type: String }],
performingTimes: [{ type: String }],
// Artist only:
genre: [{ type: String }],
},
// Media
profilePicture: {
type: String,
default:
"https://res.cloudinary.com/dtlnz58z5/image/upload/v1742665279/icon-7797704_1280_lifkba.webp",
}, // Default Cloudinary image
media: [{ url: { type: String }, platform: { type: String } }], // YouTube for artists & venues. Spotify and SoundCloud for artists only
images: [{ type: String }], // Cloudinary URLs to store images
socialLinks: [{ type: String }], // Social media and portfolio links
// Mark own availability
availability: [{ type: Date }], // Dates the user has marked as available in their availability calendar
// Bookings
bookingsReceived: [
{ type: mongoose.Schema.Types.ObjectId, ref: "Booking" },
],
bookingsSent: [{ type: mongoose.Schema.Types.ObjectId, ref: "Booking" }],
// Favourites
favourites: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }],
// Temporary email fields
tempEmail: String,
emailVerificationToken: String,
emailVerificationExpires: Date,
},
{ timestamps: true }
);
const BookingSchema = new Schema(
{
// Venue or artist who makes the request booking
initiatedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},
// Venue or artist who receives the request booking
receivedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},
performanceDate: { type: Date, required: true },
status: {
type: String,
enum: ["pending", "accepted", "declined", "cancelled"],
default: "pending",
},
statusUpdatedAt: { type: Date, default: Date.now },
isCancelledOrDeclined: { type: Boolean, default: false }, // Soft deleted from DB (not deleted from DB but does not appear in the FE)
},
{ timestamps: true }
);
Method | Endpoint | Description | Logged in User? |
---|---|---|---|
POST | /register |
Register a new user as an artist or venue | ❌ No |
GET | /verify-email |
User verifies email and is sent to log in page | ❌ No |
POST | /login |
Authenticate user & return JWT token | ❌ No |
POST | /login/google |
Authenticate user & return JWT token (registration & login) | ❌ No |
GET | /logout |
Log out user | ✅ Yes |
GET | /user-data |
Fetch logged-in user data | ✅ Yes |
PATCH | /update-account |
Update user auth data | ✅ Yes |
PATCH | /change-password |
User clicks change password, is sent an email and redirected to change password modal | ✅ Yes |
DELETE | /delete-account |
Delete user account and all related data | ✅ Yes |
POST | /forgot-password |
User clicks forgot password, is sent an | ❌ No |
POST | /reset-password |
User clicks reset password, is sent an | ✅ Yes |
Method | Endpoint | Description | Logged in User? |
---|---|---|---|
GET | /venues |
Display all venues on venues page | ❌ No |
GET | /artists |
Display all artists on artists page | ❌ No |
GET | /:id |
Get specific artist/venue profile | ❌ No |
PATCH | /:id/update-profile |
Update an existing artist/venue profile (includes everything profile related) | ✅ Yes |
DELETE | /:id/delete-media/:mediaId |
Delete individual media link | ✅ Yes |
DELETE | /:id/delete-image/:imageId |
Delete individual image | ✅ Yes |
POST | /favourites |
Add artist/venue to favourites | ✅ Yes |
DELETE | /favourites/:id |
Remove artist/venue from favourites | ✅ Yes |
GET | /favourites |
Display all favourited artists/venues | ✅ Yes |
GET | /:id/bookings |
Get all received & sent bookings of a user | ✅ Yes |
GET | /:id/bookings/received |
Get only received bookings of a user | ✅ Yes |
GET | /:id/bookings/sent |
Get only sent bookings of a user | ✅ Yes |
GET | /search?q=searchTerm |
Search artists/venues by name, performance/venue type, artist genre, location | ✅ Yes |
Method | Endpoint | Description | Logged in User? |
---|---|---|---|
POST | / |
Artist requests a venue or venue requests an artist | ✅ Yes |
GET | /:id |
Get a specific booking | ✅ Yes |
PATCH | /:id/edit |
Modify booking date (only enabled until booking accepted) | ✅ Yes |
PATCH | /:id/accept |
Accept booking request and notify other party (automatic email) | ✅ Yes |
PATCH | /:id/decline |
Decline request and notify other party (automatic email) | ✅ Yes |
PATCH | /:id/cancel |
Cancel accepted booking and notify other party (automatic email) | ✅ Yes |
GET | /accepted |
Get all accepted bookings (under My Gigs) | ✅ Yes |
Method | Endpoint | Description | Logged in User? |
---|---|---|---|
POST | / |
Send message via email form once booking is accepted | ✅ Yes |
Page | Description |
---|---|
checkToken.js |
Validates user identity and ensures that only authenticated users can access protected routes |
errorHandler.js |
Global error handler & 404 route not found |
checkUploads.js |
Checks link origin for media and social links and converts media to embed |
📌 User registers (with email verification)
- User clicks "Register".
- Selects role: Artist or Venue.
- Fills out the form (email, password, first name, last name).
- Clicks "Create Account".
- Account is created in "isConfirmed: false" state.
- Verification email is sent with a unique link.
- User is NOT automatically logged in.
- Sees message on register page: "Please check your email to verify your account before logging in."
📌 User verifies email after registration
- User opens the email.
- Clicks the verification link.
- Redirected to verification page (most likley won't be seen by the user as they are redirected to login page almost immediately).
- Once verification is complete, automatically redirected to login page with an added message on top: "Your email has been successfully verified. Please log in to continue."
- User manually enters credentials & logs in.
- Account is now marked as "isConfirmed: true" in the database.
📌 User tries to log in without verifying email
- User goes to the login page.
- Enters email & password.
- Clicks "Login".
- Sees error message on login form: "Please verify your email before logging in."
- Can request resend verification email.
📌 User is logged in and changes password in dashboard
- User logs in and navigates to My Greenroom > My Account (tab) > Password (tab).
- Types in current password and new password twice, and clicks "Change Password".
- Backend generates a one-time secure link with a token.
- User sees a success message: "Password changed successfully. You will be redirected to login..."
- User is logged out. Previous session is invalidated (logs out from all devices).
- User logs in manually again.
📌 User is logged out and forgets password
- User clicks "Forgot Password?" on the login page.
- Is redirected to Forgot Password page and enters their email address.
- Clicks "Send Reset Link".
- Receives an email with a unique link.
- Clicks the link and is redirected to the Reset Password page.
- Enters a new password and clicks "Reset Password".
- User is redirected to login page and can now log in with new password.
📌 User logs in after verifying account
- User clicks "Log In".
- Enters email & password.
- Clicks "Login".
- Redirected to the dashboard.
📌 User deletes account
- User navigates to My Greenroom > My Account (tab) > Delete Account (tab).
- Types "DELETE" in the confirmation field.
- Clicks "Confirm Deletion".
- Account is deleted & user is logged out.
📌 User creates or updates profile
- Navigates to My Greenroom > My Public Profile.
- Fills out profile fields and/or add:
- Name (artist name/venue name)
- Description
- Profile picture
- Genre & types
- For venues: Revenue split, opening times, performance times, address
- Media links (YouTube, Spotify, etc.)
- Images
- Social media links
- Availability calendar
- Clicks "Save Changes".
- Confirm modal appears & user clicks "Confirm".
- Success message appears.
- Profile is updated.
NOTE: Profile is only published once all required fields have been filled in. An orange info box appears at the top of the page saying "Profile Not Published" and listing which required fields have not been filled in yet. Once filled in, green info box appears saying "Profile Published" with a button to view own profile.
📌 User sets availability (calendar)
- Navigates to My Greenroom > My Public Profile.
- Selects available dates on calendar.
- Clicks "Save Changes".
- Confirm modal appears & user clicks "Confirm".
- Success message appears.
- Profile is updated.
📌 Artist/venue initiates booking
- User navigates to an artist or venue profile.
- Selects an available date from the calendar.
- Clicks "Request Booking".
- Confirmation modal appears.
- Clicks "Request Booking".
- Success toast appears.
- Pending booking is created and added to My Greenroom > My Bookings > Sent Bookings.
- The other party receives an email.
📌 Artist/venue who initiated booking edits a pending booking
- User navigates to My Greenroom > My Bookings > Sent Bookings.
- Clicks "Edit Date".
- Modal appears and user selects another available date from the calendar.
- Clicks "Confirm".
- Success toast appears.
- Pending booking is updated and awaits confirmation from the other party.
- The other party receives an email and the booking is updated in their dashboard.
📌 Other party confirms booking
- User navigates to My Greenroom > My Bookings > Received Bookings.
- Sees pending booking request.
- Clicks "Accept".
- Success toast appears.
- Booking status updates to "accepted".
- An email confirmation is sent to the other party.
- The booked date is removed from availability.
- Booking moves from "My Bookings" to "My Confirmed Gigs".
- Messaging (email form - nodemailer) is now enabled.
📌 Other party declines booking
- User navigates to My Greenroom > My Bookings > Received Bookings.
- Sees pending booking request.
- Clicks "Decline".
- Confirmation modal appears.
- Clicks "Decline Booking".
- Success toast appears.
- The booking disappears from the dashboard (soft delete).
- An email is sent to the other party.
- The requested date remains available.
📌 User cancels an accepted booking
- User navigates to My Greenroom > My Confirmed Gigs.
- Clicks "Cancel Gig".
- Confirmation modal appears.
- Clicks "Cancel Gig".
- Success toast appears.
- The booking disappears from the dashboard (soft delete).
- An email is sent to the other party.
- The date becomes available again in the calendar.
📌 Artist visits another artist's profile
- Navigates to an artist's profile.
- Cannot see their calendar.
- Instead sees their next three confirmed gigs with dates, names and clickable profile pictures of the venues.
📌 Venue visits another venue's profile
- Navigates to a venue's profile.
- Cannot see their calendar.
- Instead sees their next three confirmed gigs with dates, names and clickable profile pictures of the artists.
📌 User searches for artists or venues
- Navigates to "Find Artists" or "Find Venues" page.
- Can browse all artists and venues cards.
- Can use the search bar to refine search.
- Clicks "Search Venues" or "Search Artists".
- Sees filtered results or a no results message.
- Clicks on a profile to view more details.
📌 Guest browsing
- Navigates to homepage.
- Reads how The Greenroom works.
- Clicks on "Find Artists" or "Find Venues".
- Can view profiles, including:
- Name
- Description
- Photos
- Social media links
- Media links (YouTube, SoundCloud, etc.)
- Revenue split, opening hours, performance times (for venues)
- Availability calendar (but cannot book)
- Cannot book artist/venue or contact them via email form.
- When tries to book, a toast appears asking guest user to log in to make a booking.
- When tries to favourite, a toast appears asking guest user to log in to add a favourite.
📌 Registered user favourites an artist/venue
- Navigates to homepage in Featured section, or to Find Artists/Venues page, or individual artist/venue page.
- Clicks heart icon.
- Success toast appears.
- The favourite is saved.
- Navigates to My Favourites page.
- Sees list of saved artists and venues grouped by type.
📌 Registered user removes a favourite
- Navigates to My Favourites page.
- Clicks the "X" button on an artist/venue card.
- Success toast appears.
- Artist/venue is removed from favourites.
📌 User tries to book a date that was taken
- User navigates to an artist or venue profile.
- Tries to select a date that was booked by someone else, button is faded and unclickable.
- Selects a new date & reattempts booking.
📌 User contacts another user
- Once a booking is accepted, user navigates to My Confirmed Gigs and can contact other party via an email form.
- User clicks "Message".
- A modal pops up with subject and message inputs.
- Writes a message in a form with pre-filled sender and receiver emails.
- Clicks "Send Message".
- The other party receives an email and can reply directly.
Action | Unregistered User (Guest) | Registered User (Artist/Venue) |
---|---|---|
Browse homepage (see how it works) | ✅ Yes | ✅ Yes |
Register | ✅ Yes | ❌ No (already registered) |
Login | ❌ No | ✅ Yes |
Browse venues & artists | ✅ Yes | ✅ Yes |
View artist profiles | ✅ Yes | ✅ Yes |
View venue profiles | ✅ Yes | ✅ Yes |
See social media links | ✅ Yes | ✅ Yes |
View available gig dates & revenue split | ✅ Yes | ✅ Yes |
Create a profile (after registering) | ❌ No | ✅ Yes |
Edit profile (bio, media, availability, images) | ❌ No | ✅ Yes |
Set & update availability calendar | ❌ No | ✅ Yes |
Upload media (links, photos, profile picture) | ❌ No | ✅ Yes |
Send a booking request | ❌ No | ✅ Yes |
Modify a booking request before acceptance | ❌ No | ✅ Yes |
Accept or decline a booking | ❌ No | ✅ Yes |
Cancel a confirmed booking | ❌ No | ✅ Yes |
View received & sent bookings in dashboard | ❌ No | ✅ Yes |
See accepted bookings ("My Confirmed Gigs") | ❌ No | ✅ Yes |
Contact a venue/artist via email form | ❌ No | ✅ Yes |
Favourite artists & venues | ❌ No | ✅ Yes |
Delete account | ❌ No | ✅ Yes |
We have 2 reducers, matching the 2 collections in the database:
- Users (
usersReducer.js
) - Bookings (
bookingsReducer.js
)
These are managed in Context.jsx
to provide a global state.
-
Use
feature/...
if you're adding or enhancing functionality or content. -
Use
fix/...
if you're correcting a mistake. -
Use
refactor/...
if you're improving structure or code without adding new functionality. -
Please add your name before branch name.
evie/feature/artists-page
omar/fix/dashboard-user-data
swagatika/refactor/home-page
- Clone the repository:
git clone git@github.com:diecatiamonteiro/final-project-mern.git
- Install dependencies and run the development on
server/
(BE):
npm install
npm start
- Install dependencies and run the development on
client/
(FE):
npm install
npm run dev
- Open http://localhost:5173 in your browser (FE).
See live demo here.
Thanks for checking out our project! ❤️ We hope you enjoy The Greenroom as much as we do.