FrizApp
A barber and salon booking marketplace for Romania: a Laravel API, two admin panels and three Flutter apps for customers, salon owners and barbers.
The problem#
Booking a haircut in Romania still mostly happens over the phone. Salons juggle paper calendars, missed calls and no-shows, and customers can't see when their barber is free.
What I built#
FrizApp is a multi-vendor marketplace with one backend and three apps:
- Customer app: find salons nearby on a map, choose services, a barber and a time slot, pay by card, reschedule, join a waitlist, chat with the salon and leave a review.
- Salon app: a sign-up wizard, a booking calendar, accept or reject requests, staff and working hours, services, and earnings and payout history.
- Barber app: each barber's own schedule, with a no-show button.
- Web admin: a platform panel and a salon panel built with Filament, with a staff timeline calendar, coupons, gallery, timesheets, and walk-in and phone bookings.
The customer app#
Customers discover salons nearby, browse services by category and see each salon's staff.

Booking takes three taps: a date, a barber and a time slot, then pay now or after the service.

The whole journey, from the home screen to checkout:

The salon app#
FrizApp Salon is the partner side: salon owners sign in and run their whole salon from one app.

Booking requests arrive with their status, including waiting-list requests, and owners can message customers directly.

Owners manage their service catalogue and prices, and switch on vacation mode or pay after service.

Weekly opening hours, with bulk timing, feed the slot calculation and the public salon page.

Everything in one place: bookings, chat, services, hours and profile.

Technical highlights#
- One source of truth for availability. Free slots depend on opening hours, each barber's working hours, holidays, lead time and how long the chosen barber takes for a service. All of it goes through a single working-window service, and the server re-checks every booking instead of trusting the app.
- Payments handled on the server. The backend recalculates the price, creates the Stripe payment and confirms it by webhook. A slot is reserved only after the charge succeeds, and a scheduled sweep catches abandoned checkouts.
- Reminders on two channels. Configurable appointment reminders by SMS and push notification, sent by a scheduled job that tracks the status of each reminder.
- A waitlist that fills itself. When a booking is cancelled, the freed slot is offered to customers on the waitlist.
- A modular backend. Separate Laravel modules for users, salons, bookings, the mobile API and SMS, each with its own routes, services and documentation.
Stack#
Laravel 12, Sanctum, Filament, Flutter with BLoC, Firebase (Auth, Cloud Messaging, Firestore chat, Crashlytics), Stripe, Google Maps.
Status#
Live in Romania at frizapp.ro, in Romanian and English, on iOS and Android.