A modern, feature-rich resource booking system similar to Calendly. Perfect for shared spaces, coworking areas, residential buildings, and businesses that need to manage bookable resources like washing machines, meeting rooms, parking spots, and more.
Deployed to: https://bookathing.vercel.app/
- Multi-Resource Management - Book washing machines, meeting rooms, saunas, parking spots, and more
- Real-Time Status Tracking - See if resources are currently in use (on/off state)
- YAML Configuration - Easy-to-customize settings without code changes
- Modern UI - Fresh, responsive design with Tailwind CSS and smooth animations
- Embeddable Widget - Integrate booking into any website with an iframe
- Admin Dashboard - Manage bookings, approve requests, and view statistics
- Conflict Detection - Prevents double bookings automatically
- Timezone Support - Works across different timezones
- Flexible Scheduling - Configurable working hours per resource and day
- React 18 with Hooks
- Tailwind CSS for styling
- Framer Motion for animations
- React Router 6 for navigation
- Heroicons for icons
- date-fns for date handling
- Node.js + Express
- YAML configuration
- Firebase Firestore (optional)
- In-memory storage fallback
- RESTful API
- Node.js 16+
- npm or yarn
-
Clone the repository
git clone https://github.com/yourusername/bookathing.git cd bookathing -
Install server dependencies
cd server npm install -
Install client dependencies
cd ../client npm install -
Configure the application
Edit
server/config.yamlto customize:- Resources (washing machines, rooms, etc.)
- Working hours
- Slot durations
- Business information
-
Start the server
cd ../server npm start # Server runs on http://localhost:5000
-
Start the client (in a new terminal)
cd client npm start # Client runs on http://localhost:3000
-
Open your browser Navigate to
http://localhost:3000
The entire system is configured via server/config.yaml. Here's what you can customize:
app:
name: "BookAThing"
description: "Modern resource booking system"
primaryColor: "#6366f1"business:
name: "Shared Living Community"
timezone: "Europe/Oslo"
currency: "NOK"workingHours:
monday:
enabled: true
start: "06:00"
end: "23:00"
# ... other daysresources:
- id: "washing-machine-1"
name: "Washing Machine #1"
type: "appliance"
description: "Front-loading washer, 8kg capacity"
icon: "washing-machine"
color: "#3b82f6"
location: "Basement - Room 101"
slotDuration: 120 # minutes
maxBookingsPerDay: 3
showStatus: true # Show on/off indicator
tags: ["laundry", "appliance"]embed:
enabled: true
allowedDomains: ["*"]
defaultTheme: "light"GET /api/config- Get app configurationGET /api/health- Health check
GET /api/resources- List all resourcesGET /api/resources/:id- Get single resourceGET /api/resources/:id/status- Get resource status (on/off)PUT /api/resources/:id/status- Update resource status (for IoT)GET /api/resources/:id/slots?date=YYYY-MM-DD&timezone=UTC- Get available slots
POST /api/bookings- Create a bookingGET /api/bookings- List bookings (with filters)GET /api/bookings/:id- Get single bookingDELETE /api/bookings/:id- Cancel bookingPUT /api/bookings/:id/status- Update booking status
GET /api/stats- Get dashboard statistics
Embed the booking widget on any website:
<iframe
src="https://your-domain.com/embed"
width="100%"
height="800"
frameborder="0">
</iframe><iframe
src="https://your-domain.com/embed/washing-machine-1"
width="100%"
height="700"
frameborder="0">
</iframe>bookathing/
├── client/ # React frontend
│ ├── public/ # Static assets
│ ├── src/
│ │ ├── components/ # Reusable UI components
│ │ │ ├── Layout.js # Main layout wrapper
│ │ │ ├── Calendar.js # Date picker
│ │ │ ├── TimeSlotPicker.js
│ │ │ └── ResourceCard.js
│ │ ├── pages/ # Route pages
│ │ │ ├── HomePage.js # Resource listing
│ │ │ ├── BookingPage.js
│ │ │ ├── ConfirmationPage.js
│ │ │ ├── AdminPage.js # Dashboard
│ │ │ └── EmbedPage.js # Embeddable widget
│ │ ├── hooks/ # Custom React hooks
│ │ ├── utils/ # API client
│ │ ├── App.js
│ │ └── index.css # Tailwind CSS
│ ├── tailwind.config.js
│ └── package.json
│
├── server/ # Express backend
│ ├── config.yaml # Main configuration
│ ├── configLoader.js # YAML parser
│ ├── server.js # API endpoints
│ ├── db.js # Firebase connection
│ └── package.json
│
└── README.md
-
Build the client:
cd client npm run build -
Copy build to server:
cp -r build ../server/
-
Deploy server (Heroku, Railway, etc.)
Server:
PORT- Server port (default: 5000)- Firebase credentials (optional)
Client:
REACT_APP_API_URL- Backend API URL
For real-time status tracking (e.g., detecting if a washing machine is running):
# Update resource status
curl -X PUT http://localhost:5000/api/resources/washing-machine-1/status \
-H "Content-Type: application/json" \
-d '{"status": "in_use"}'Status options: available, in_use, maintenance, offline
- Edit
server/config.yaml - Add icon mapping in
client/src/components/ResourceCard.js - Restart the server (config auto-reloads)
Modify client/tailwind.config.js to change:
- Primary colors
- Animations
- Spacing
The system is ready for auth integration:
- Add middleware to server
- Implement login in client
- Set
admin.requireAuth: truein config
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Open a Pull Request
ISC License
For issues and feature requests, please open a GitHub issue.
Built with React, Express, and Tailwind CSS