Start a project
Agency operations app

Travel Agency Back Office

A back office for travel agencies that run their own group trips. Staff plan each departure, sign travellers up, seat them on the bus, take payments and see who still owes, and every screen states what an action will do before it is taken.

Records save as staff type, sending only the fields that changed; a value the server rejects is marked on its field while the rest is saved. Hints under fields and confirmations before consequential actions say what happens automatically, what does not, and whether it can be undone. Staff do all day-to-day work; admins also manage users, settings and the activity log, and deactivating a user signs them out everywhere. The app runs in Croatian and English, in light and dark themes.

Try the demo ↗
ForAgencies running their own group trips
StaffPlan trips, sign up and seat travellers, take payments
AdminsManage users and settings, read the activity log
StatusIn development with its first agency
Trips

Season overview

Trips are grouped by month with their dates, fill and price, under a four-month timeline of the season. A strip at the top flags drafts that depart within 60 days and drafts still missing what they need to open.

  • A trip opens for sign-ups only once its dates, seats and price are set
  • Departures within a week are marked on the list and the timeline
  • A paid column splits each trip's money into paid, overdue and due later, so late bookings stand out from money that simply isn't due yet
  • Status changes are confirmed, list their consequences and can be undone
Bookings

Bookings and the waiting list

A booking has one payer and one or more travellers. Each traveller's price is copied from the trip at the moment of booking, with surcharges and discounts as separate lines. A booking that does not fit goes on the waiting list automatically, and nobody can be on the same trip twice.

  • Travellers are added from one search field, which stays ready for the next
  • A family can be added to one booking and pay together
  • Seats are counted from active bookings only, so every screen shows the same fill
Buses

Buses and seating

A trip has one or more buses, and their seats set its capacity. Seats are assigned on a map of the bus: choose a traveller, then a free seat, or a taken one to swap the two, and the next member of the same booking is chosen automatically. Saved buses bring their carrier, seat layout and usual driver and guide onto a trip, and each bus gets its own printable passenger list.

  • Seat layouts are drawn in an editor, double-deckers included, starting from four templates
  • Automatic seating goes in booking order and keeps each booking on one bus where it fits
  • Adding a saved bus warns when it is already on a trip with overlapping dates
  • Every seat change can be undone
Payments

Payments, refunds and transfers

Payments belong to the booking, which pays as a whole. Each records its date, method, reference and who handed over the money, and the booking panel shows the total, what is paid and what remains. Money can also go back as a refund, which needs a reason, or move to another booking as a linked pair of entries. A cancelled booking shows what the agency still holds.

  • Transfer, cash or card, with the card type recorded
  • Refunds and transfers can never exceed what has been paid
  • Deleting either side of a transfer deletes both
  • A spreadsheet export (CSV) of payments for the accountant, filtered by kind
Overdue

Overdue balances

Bookings still owing after their trip's final payment date are collected on one page, longest overdue first, with the payer's phone number. The final payment date is set per trip, or defaults to 30 days before departure.

  • The overdue count sits in the sidebar, visible from every screen
  • Completed trips leave the list 60 days after return
Travellers

Traveller records

A traveller's record keeps their details and every trip they have booked, with what they paid and what they owe. Search ignores diacritics, so "saric" finds "Šarić", and a new entry warns when the person may already exist.

  • Personal ID numbers are validated, stored encrypted and matched exactly
  • Age is worked out from the birth date on the date of the trip
  • Travellers who no longer book are archived, with their history kept
Activity log

Who changed what

Every change to trips, travellers, bookings, payments, users and settings is recorded field by field, with the old value, the new one and who made it. Edits by the same person to the same record within ten minutes fold into one entry, so autosave doesn't write a line per pause. Admins read the log on its own page and in a history tab on each trip and traveller.

  • Personal ID numbers and passwords are recorded as changed, never as values
  • Payment exports are logged with their filters and row count
  • History outlives the records it describes, including deleted bookings
How it's built
Backend & API
Laravel, PHP, Sanctum, MySQL
Frontend
Vue, TypeScript, Vue Router, Pinia, TanStack Query, TanStack Table
Interface
shadcn-vue, Reka UI, Tailwind, vue-i18n
Quality
PHPUnit, Vitest, ESLint, Prettier