Skip to content

Repository files navigation

VendorMap

vendormap_icon

Let vendors book tables at public markets and conventions online, while hosts design the floor plan (boundary, doors, power, tables and prices) and manage events and vendor approvals from an admin panel.

Background

This project was written to support the Parents Advisory Committee at JKE. Every year a Christmas Market organized by the PAC takes place at the School, with all the bookings managed manually. My wife, who serves on the PAC, and I, discussed creating a website where vendors at the market can book to streamline this process. Searching on GitHub, I couldn't find any other projects that offered this, most "table booking" apps are for restaurant reservations, not markets, conventions and so on. This project was started to meet that need.

Since this is hosted on my Ubuntu Linux Webserver, I chose to use PHP as the language behind this project. Instead of unstructured PHP, this project uses the Laravel framework. The Framework offers a number of benefits, namely an MVC (Model-View-Controller) code structure which avoid the trap of scattered disorganized PHP files with a mixture of logic and UI. Laravel also has a lot of third party support with additional libraries that integrate with the framework for easily supporting the features expected

This project is still in development, with work ongoing to refine and improve it.

Live demo

https://vendormap.jameshansen.org

The demo is a sandbox: every visitor gets their own isolated copy of the data, so feel free to change anything: it resets and never affects anyone else (see Demo mode).

Role How to sign in
Vendor vendor@demo.test / demo1234
Admin Go to /admin. Credentials are admin / demo1234.

Features

  • Floor-plan designer (admin): draw the venue boundary, drop doors, power outlets and tables, set table size/price/shape/status, mark "has power", save reusable presets, and duplicate venues. Built on Konva.
  • Per-venue layouts: each event+venue keeps its own independent table layout.
  • Vendor booking: vendors view the live floor plan and click an available table to book. Shows price, size and a power indicator. Respects a configurable tables-per-vendor limit and an auto-approve vs. hold-for-admin booking rule.
  • Vendor accounts: email/password or Google sign-in (Laravel Socialite). Sign-up collects business details + socials and is hardened against bots (honeypot, timing, optional reCAPTCHA). New accounts are pending until an admin approves them.
  • Admin panel (/admin): dashboard, full event CRUD, the designer, and a vendor approval queue. Approving/rejecting emails the vendor.
  • Email notifications: admin alert on new sign-ups, approval/rejection notices to vendors (best-effort; logged if SMTP isn't configured).
  • Single config.php: site name, admin login, SMTP, Google keys, reCAPTCHA, booking rules and demo mode, all in one commented file.

Tech stack

PHP 8.4 · Laravel 13 · Blade · Vite · Konva · MySQL 8+ / MariaDB 10.5+.

MySQL/MariaDB is required: the floor-plan geometry columns use spatial types, so SQLite won't work.

Requires PHP 8.4 (composer.json requires ^8.4). The Symfony 8.1 components pinned in composer.lock need PHP 8.4.1+, so composer install fails on 8.3 or earlier.

Setup

From the shell on your webserver:

cd <your-folder>
git clone https://github.com/jameshansen/VendorMap ./

To copy the latest version to the current folder. Then:

composer install
cp .env.example .env
# Create a MySQL database, then set DB_HOST, DB_PORT, DB_DATABASE, etc. in .env
php artisan key:generate
php artisan migrate
npm install
npm run build

# Site settings (admin login, SMTP, Google, booking rules, demo mode)
cp config.php.example config.php   # then edit config.php

# Optional sample data
php artisan db:seed --class=DemoSeeder

While developing, run npm run dev instead of npm run build. Serve the app with php artisan serve (or Laravel Herd, which serves it automatically).

Configuration (config.php)

config.php (git-ignored, copied from config.php.example) holds all operational settings and is bridged into Laravel at boot. You don't need to touch .env for these:

  • app_name - shown in the public header and as "<name> Admin".
  • admin - admin panel username/password.
  • smtp - outgoing mail. Leave host blank to log emails instead of sending.
  • google_oauth - Google sign-in keys. Blank client_id hides the Google button.
  • recaptcha - optional anti-bot keys for sign-up.
  • booking - tables_per_vendor and auto_approve_booking.
  • demo - see below.

Demo mode

For a public sandbox where visitors can change anything without risking a shared database. When demo.enabled is true, the app hands each visitor one of a fixed pool of pre-seeded MySQL databases (a "slot"), tracked by a cookie. When all slots are busy, the least-recently-used one is recycled (reset to the demo baseline) for the new visitor. Nothing is created or dropped at runtime, and the main database is never touched.

# One-time: create + seed the pool (needs CREATE privilege for this command only)
php artisan demo:setup

The demo:setup command creates databases named <db_prefix>1 .. <db_prefix>N, so the configured MySQL user needs permission to create them. A single grant covers it (note the escaped underscores so the wildcard matches the slot names):

GRANT ALL PRIVILEGES ON `vendormap\_demo\_%`.* TO 'vendormap'@'localhost';

Then set in config.php:

'demo' => [
    'enabled'   => true,
    'pool_size' => 25,                // max concurrent isolated visitors
    'db_prefix' => 'vendormap_demo_', // slot DBs: vendormap_demo_1 .. _25
],

In demo mode, sessions/cache/queue are kept on the filesystem so they don't depend on the swapped-per-visitor database.

Deployment

VendorMap is a standard Laravel app: follow the official guide for Nginx, PHP and optimisation: https://laravel.com/docs/13.x/deployment

Project-specific notes:

  • Use MySQL 8+ / MariaDB 10.5+ (spatial columns; SQLite won't work).

  • Build assets with npm run build (Node only needed at build time).

  • First deploy: set APP_ENV=production, APP_DEBUG=false, APP_URL, then php artisan key:generate and php artisan migrate --force.

  • Copy and edit config.php. For the public demo, run php artisan demo:setup and set demo.enabled = true.

  • PHP on older Ubuntu: 22.04 (Jammy) ships PHP 8.1. Add ppa:ondrej/php, then install php8.4 and the php8.4-* extensions to meet the 8.4 requirement.

  • Run composer and artisan as the web user, not as root. Root-owned files in storage/ and bootstrap/cache/ are the usual cause of a 500 right after deploy, because the web server can't write to them. Use sudo -u www-data php8.4 artisan ..., and if you've already run things as root, reset ownership:

    sudo chown -R www-data:www-data .
    sudo chmod -R 775 storage bootstrap/cache

Apache instead of Nginx

The app runs fine under Apache. To serve it with PHP-FPM (which also lets you keep other vhosts on a different PHP version), enable the proxy module and hand .php to the FPM socket inside the vhost:

sudo a2enmod proxy_fcgi
<VirtualHost *:80>
    ServerName vendormap.example.org
    DocumentRoot /var/www/vendormap/public

    <Directory /var/www/vendormap/public>
        AllowOverride All
        Require all granted
    </Directory>

    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php/php8.4-fpm.sock|fcgi://localhost"
    </FilesMatch>
</VirtualHost>

Then add HTTPS with sudo certbot --apache -d vendormap.example.org.

Other Issues

image

If a message asking to access apps on your local computer shows up after you deploy, remove the public/hot folder - this causes Vite to attempt a local connection:

rm -f public/hot

Build dependencies on the server, don't copy them from another machine. Copying vendor/ or node_modules from a local copy causes two failures: a stale autoloader that tries to require a missing dev package such as PHPUnit (fatal error on any artisan command), and Vite failing with vite: Permission denied from lost executable bits or a wrong-platform esbuild binary. Rebuild both on the server:

rm -rf vendor node_modules
composer install --no-dev --optimize-autoloader
npm install && npm run build

About

Allow vendors at a public market event or convention to book a table online, while allowing hosts to manage the events and design spaces for events, including the layout and table prices and properties

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages