A resource booking calendar application with email-code login.
- Frontend: Vanilla JS, Axios
- Backend: Node.js / Express
- Database: MongoDB (Mongoose)
- Email: AWS SES
-
Install server dependencies:
cd server && npm install
-
Configure
server/.env:JWT_SECRET=your-secret MONGODB_URI=mongodb://localhost:27017/booking-calendar PORT=3000 EMAIL_REGION=eu-north-1 EMAIL_ACCESS_KEY=your-aws-access-key EMAIL_SECRET_KEY=your-aws-secret-key -
Start the server:
node handler.js
-
Open
client/index.htmlin a browser.
Resources are stored in the MongoDB resources collection. Each resource has:
| Field | Type | Description |
|---|---|---|
resourceId |
String | Unique identifier, e.g. room-1 |
name |
String | Display name |
description |
String | Optional description |
isActive |
Boolean | Whether it appears in the UI |
slot_length |
Number | Booking slot duration in minutes (default: 60) |
earliest |
String | Earliest bookable time, e.g. 09:00 |
latest |
String | Latest bookable time, e.g. 17:00 |
Requires a valid JWT token (log in first to obtain one).
curl -X POST http://localhost:3000/api/resources \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"resourceId": "room-3",
"name": "Konferensrum 3",
"description": "Litet rum, max 4 personer",
"isActive": true,
"slot_length": 30,
"earliest": "08:00",
"latest": "18:00"
}'Edit the initialResources array in server/init-db.js, then run:
cd server && node init-db.jsWarning: This deletes all existing resources before inserting the new ones.
Insert a document into the resources collection:
db.resources.insertOne({
resourceId: "room-3",
name: "Konferensrum 3",
description: "Litet rum, max 4 personer",
isActive: true,
slot_length: 30,
earliest: "08:00",
latest: "17:00"
})- Enter your email address and click Skicka kod till e-post.
- A 6-digit code is sent to your email (valid for 10 minutes).
- Enter the code and click Logga in.
- Click a resource card to select it.
- Click a day in the calendar — the day view opens with the resource pre-selected.
- Click Boka next to an available time slot.