=== Tiger Booking ===
Contributors: tigerelements
Tags: booking, appointments, scheduling, calendar, reservations
Requires at least: 6.2
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 2.0.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Take appointments online. Publish your services, let customers pick a time with the right person, and confirm it by email.

== Description ==

Tiger Booking turns your WordPress site into a working appointment book.

Add the services you offer, set who provides them and when they work, then put a booking form on any page. Customers choose a service, a person and a time; the slot is held, the confirmation email goes out, and the appointment lands in your dashboard. Nothing is booked twice, because availability is checked at the moment of saving, not just when the calendar was drawn.

It is self-hosted. Your services, staff, customers and appointments live in your own WordPress database. There are no per-booking fees, no seat limits and no external account to sign up for.

Everything described on this page is included and fully working. There is no licence key, no trial period, no usage cap and no locked screen anywhere in this plugin.

= What you can do =

* **Services** — what can be booked, with duration, price, buffer time and a category
* **Staff** — unlimited team members, each with their own calendar, services and holidays
* **Weekly rosters** — working hours, shifts and breaks, so bookings only land while someone is on shift
* **Public booking flow** — a service-then-person-then-time form that works on a page, a post or a widget area
* **Recurring appointments** — weekly or monthly series booked in one go
* **Manual bookings** — add, move, reschedule and cancel appointments from the admin
* **Walk-in queue** — serve people who arrive without an appointment
* **Customer records** — a profile per customer with their history, spend and notes
* **Intake and consent forms** — ask your own questions at booking time, and keep the answer next to the wording the customer actually agreed to
* **Reviews** — collect customer reviews and moderate them before they appear
* **Analytics** — bookings, revenue, staff workload, busiest hours, new versus returning customers
* **Staff and customer portals** — self-service logins with per-role, per-screen permissions
* **Email confirmations** — automatic notices to you and to the customer, with a readable activity log
* **Activity log** — who changed what, and when

= It speaks your trade =

During setup you choose what kind of business you run — Salon, Barbershop, Clinic, Therapy Practice, Personal Training, Tutoring, or plain Appointments. The admin then uses your vocabulary: a salon sees Treatments and Stylists, a clinic sees Consultations and Practitioners. Screens you have no use for are hidden rather than left to clutter the menu.

= Where the booking form goes =

Use the `[tiger_booking]` shortcode on any page, the Booking block in the block editor, or the Tiger Booking widgets if you use Elementor. Elementor is optional and is never required.

Your services also get real pages of their own, each with its price, duration and a working booking form, so a visitor can book straight from a search result. Your theme or page builder still wins if you would rather design those pages yourself.

= What is not in this plugin =

These are separate products, not locked features. This plugin contains none of their code, and nothing here is disabled, limited or waiting for a key:

* Online payments — Stripe, PayPal, Square and Razorpay checkout
* Google Calendar sync, and the Zoom / CRM / webhook integrations hub
* SMS confirmations and reminders
* Discount codes, and the waitlist for times that are already full
* Document uploads at booking time — asking a customer to attach an ID or a form
* Other booking verticals — hotel and property, restaurant, fitness classes, hourly rentals

Learn more at https://tigerelementswp.com/tiger-booking/

== Installation ==

1. In your WordPress admin go to **Plugins → Add New**, search for **Tiger Booking**, and click **Install Now**. To install manually instead, upload the `tiger-booking` folder to `/wp-content/plugins/`.
2. Click **Activate**.
3. Open **Tiger Booking** in the admin menu. The setup asks what kind of business you run and creates a booking page and a thank-you page for you.
4. Add at least one service, then at least one staff member, and give that person some working hours under **Availability**. A service with nobody able to provide it cannot be booked.
5. Visit the booking page it created, or drop `[tiger_booking]` on a page of your own, and place a test booking.

Confirmation emails use whatever WordPress already uses to send mail. If your site does not reliably send email, install an SMTP plugin first — **Tiger Booking → Settings → General** has a status panel that tells you whether mail, the database and scheduled tasks are healthy.

== Frequently Asked Questions ==

= Does it need Elementor, or any other page builder? =

No. Tiger Booking works on its own through the `[tiger_booking]` shortcode and a block for the block editor. If Elementor happens to be active, matching Elementor widgets are registered automatically — but nothing requires it.

= Where is my booking data stored? =

In your own WordPress database, in the plugin's own tables. It is not sent anywhere, and there are no per-booking fees.

= Can customers pay when they book? =

Not with this plugin — it contains no payment gateway code at all. Bookings are confirmed by you or by email, and you take payment however you already do: on arrival, by invoice, or with a separate payments plugin. Online checkout is part of a separate product.

= Is anything here limited, trial-based or waiting for a licence key? =

No. There is no licence check, no trial, no cap on services, staff or bookings, and no screen anywhere that asks you to upgrade. Every feature listed on this page is complete in this plugin.

= Can two people book the same slot? =

No. Availability is re-checked inside the write, per staff member and per resource, at the moment the booking is saved — not only when the calendar was drawn. If someone takes the slot while another person is filling in the form, the second person is told the time has gone and asked to choose another.

= Can staff manage their own calendar without a WordPress admin account? =

Yes. The staff portal is a separate self-service login with its own per-role permissions, screen by screen and action by action. It gives no access to WordPress admin.

= Does it send anything to a third party? =

No. Your bookings never leave your server, and the plugin contacts no third party under any setting. Its typefaces are bundled inside the plugin rather than fetched from a font host. See **External services** below.

= How do I remove everything when I uninstall? =

Tick **Delete all data on uninstall** under **Tiger Booking → Tools** before you delete the plugin. Without that box ticked, deleting the plugin leaves your bookings in place so you can reinstall safely.

= Is it translation ready? =

Yes. The plugin's text domain is `tiger-booking` and it loads translations from wordpress.org language packs automatically.

== External services ==

This plugin uses no external services.

Tiger Booking is entirely self-hosted. Your services, staff, customers and bookings are stored in your own WordPress database and never leave your server. The plugin makes no outbound request to any third party, under any setting.

The booking widget uses typefaces bundled inside the plugin, so no font is fetched from a remote host. No third party is contacted. The plugin sends no analytics, no telemetry and no usage data anywhere, and it does not phone home. The sample content installed by the demo seeder ships with its own artwork inside the plugin, so no image is fetched from a remote host either.

== Screenshots ==

1. Choosing a time — the visitor picks a service and a member of staff, then a day and a free slot.
2. Bookings — every appointment in one list, with status filters and a calendar view.
3. Services — what can be booked, with price, duration and buffer time.
4. Staff — unlimited team members, each with their own calendar and portal login.
5. Availability — weekly working hours, shifts, breaks and days off, per person.
6. Analytics — bookings, revenue and staff workload across everything you offer.
7. The staff portal sign-in — your team log in here, not through WordPress admin, and each role sees only the screens you allow.
8. Confirming — the visitor checks what they are booking and leaves their details.

== Source code ==

The admin screens and the public booking form are a React application, so what
runs in your browser is compiled. Nothing here is obfuscated, and you do not
have to ask anyone for the source: **the readable source ships inside this
plugin**, in `src/`, next to the compiled output in `tiger-dist/`.

To rebuild it, from the plugin directory:

`npm install`
`npm run build`

That regenerates `tiger-dist/` from `src/`. The JavaScript it produces is
identical, file for file, to what ships. The stylesheet can differ by a small
number of unused utility classes, because Tailwind generates CSS by scanning
the files present on disk — it is the same stylesheet, not a different one.

* Build tools: [Vite](https://vitejs.dev/) and [Tailwind CSS](https://tailwindcss.com/),
  both free software. The exact versions are pinned in the bundled
  `package.json` and `package-lock.json`.
* `src/` contains the source for everything this plugin does. Code for the paid
  add-on is not included, because none of it runs here either.
* The two bundled typefaces, Inter and Space Grotesk, are under the SIL Open
  Font License 1.1; the license text ships in `LICENSE-FONTS.txt`, and every
  other bundled dependency is listed in `LICENSE-THIRD-PARTY.txt`.
* No code is downloaded or executed from a remote server, at any point.

== Changelog ==

= 2.0.1 =
* Every JSON request body is now sanitised at a single boundary before it reaches any handler, and each storage column is sanitised again with the function that fits it.
* Admin notices are limited to this plugin's own screens, are dismissible, and are fully translatable; the inline scripts they used to print are now an enqueued file.
* CSV import accepts only the columns a module declares; unknown headers are discarded.
* Fixed a database error on sites without the hotel module that could break the booking importer's response.
* Booking actions that only read or re-send are now icons, so the detail footer no longer overflows when translated.

= 2.0.0 =
This is the release the plugin was tidied up for, so the version number moves with it.

* The whole admin was tightened. Dialogs, cards, forms and buttons were built at a scale meant for a marketing page rather than a tool you open forty times a day; every screen now uses one spacing scale, so more fits on screen without anything feeling cramped.
* Form fields have visible borders again. They were drawn as a grey fill with no outline, which on a white card read as no field at all.
* The compact booking layout shows a full month. It offered one week at a time, so a customer looking for a slot three weeks out had to page through the calendar to find it.
* Fixed: Edit in a location's or service's "..." menu opened nothing. The menu closed and the dialog never appeared.
* Fixed: on the staff list, Save Member was a fraction of the width of Cancel, and the tick in a checkbox sat off-centre.
* Staff cards now show the person's name beside their photo, never a contact icon with nothing next to it, and keep Edit and Delete visible instead of hiding them until you hover — which put them out of reach entirely on a touch screen.
* The admin menu no longer changes shape as you move through it. Reviews and Activity Log stayed put instead of folding into an "Operations" entry that hid them.
* The WordPress footer and other plugins' admin notices are no longer hidden on Tiger Booking screens. Suppressing them hid update prompts and security warnings the site owner needs to see.
* The plugin row on the Plugins screen listed "Upgrade to Pro" twice.
* The readable source for the compiled app now ships inside the plugin, in `src/`, so rebuilding it needs nothing from anywhere else.

= 1.13.9 =
* Smaller download. The bundled logo was a full-resolution image being displayed at thumbnail size; it now ships at the size it is actually drawn, which halves the plugin.
* Added a Source code section to the readme, pointing at the readable source behind the compiled app.

= 1.13.8 =
* The admin menu icon is now the bold Tiger Booking mark, with the calendar cut out of it so the menu shows through.

= 1.13.7 =
* The admin menu icon now fills its space. The artwork carried around a fifth of empty padding on every edge, which left it looking small and ringed by a faint border.

= 1.13.6 =
* Buttons now show the hand cursor everywhere. They had been showing the plain arrow across the whole plugin, which made the interface read as though nothing was clickable.
* Admin screens scroll as one page again. A second, inner scrollbar had crept in, which broke find-in-page, Page Up/Down and the browser remembering where you were.
* The admin menu icon no longer carries a faint border around it.

= 1.13.5 =
* A bolder admin menu icon, which holds its shape at the size WordPress draws it.

= 1.13.4 =
* The admin menu icon is now the white Tiger Booking mark, shown at full strength instead of the faded treatment WordPress applies to its own grey icons.

= 1.13.3 =
* Tiger Booking now has its own icon in the WordPress admin menu, and the product mark appears on the staff and hotel portal sign-in screens and in the block editor, in place of the generic placeholder icons used before.
* Zero errors and zero warnings against WordPress.org's Plugin Check. The last one was on the staff-save path, which removed departed staff with a hand-built list of ids inside the SQL. That list is now bound as parameters instead, so no id is ever written into a query string — safe by construction rather than safe because of a conversion done further up the function.

= 1.13.2 =
* Code quality: the plugin now reports zero errors and one warning against WordPress.org's Plugin Check, down from 545 warnings. Two of those were miscounted SQL placeholders flagged in code that was already safe; the rest were direct database calls on the plugin's own tables, each now carrying the reason it is written that way — including why booking availability is deliberately never served from a cache, so two visitors can't both be told a taken slot is free.
* The booking script now declares itself non-blocking explicitly, so page-speed tooling stops reporting it as render-blocking. No change to how or when it loads.

= 1.13.1 =
* Completes the translation work started in 1.13.0. Sentences that wrap a value — "No staff yet", "3 bookings · £240 · 6h booked" — were still half-English because each half had been treated as a separate phrase; they are now single phrases with the value slotted in, which is the only shape most languages can actually be translated into.
* Business types are translatable. The labels, descriptions, menu names and the whole vocabulary of every business type (Salon, Clinic, Barbershop, Therapy Practice, Personal Training, Tutoring) live in data files that no translation tool could previously read — 87 more phrases now reachable.
* Chart labels and the settings menu headings translate too.
* Fixed: a percentage in a translated sentence ("34% of the period") could come out mangled.

= 1.13.0 =
* The whole interface can now be translated. Every screen — the booking form your visitors see and the admin behind it — reads its wording from a translation file instead of having English baked into the compiled app. Around 1,800 phrases are now in the translation template; before this release the template covered the PHP half only and none of the app.
* Booking widgets now have width controls. Every shortcode takes `width="900px"`, `width="80%"` or `width="full"`, plus `align="wide"` / `align="full"` for block themes, and the block editor gains a Width setting. Leave them out and nothing changes: the widget still fills whatever container it is in.
* Fixed: the block editor's Wide/Full alignment control had never done anything on the front end.
* Fixed: the block editor panel's own labels could not be translated either — the script was never told where its translations live.

= 1.12.0 =
* Reminders now actually send. The switch existed and nothing was scheduled behind it; a reminder is sent once per booking, in the booking's own time zone, and is skipped for cancelled, past or just-made bookings.
* Customers now receive a link to manage their own booking in the confirmation email, and staff can copy that link from the booking screen.
* Multiple locations: assign staff to branches, and the booking form asks visitors which one only when you have more than one.
* Setup wizard: business identity, business type, solo or team, services, hours and your booking page — and an exit if you do not run an appointment business.
* Business types are now a setting inside Appointments rather than a separate switch, so turning Appointments off no longer leaves its screens behind.
* Fixed: practitioners with no working hours were offered to customers, giving an empty calendar. Fixed: the thank-you page said a booking was confirmed when it was still pending. Fixed: admin dialogs could open mis-positioned. Fixed: clearing demo data reported success while deleting nothing. Fixed: uninstall left four tables and all transients behind. Fixed: business-type wording silently failed on translated sites.

= 1.11.0 =
* Security: closed seven endpoints that answered anonymous callers, including staff contact details and clinical records. Public booking submissions can no longer claim a confirmed status.
* Pro is now an add-on that installs alongside the free plugin instead of replacing it.

= 1.10.0 =
* New: intake and consent forms. Ask your own questions at booking time — text, choices, dates or a consent tick — per service or for everything. A required answer or an unticked consent box stops the booking, and answers are kept with the wording the customer actually agreed to, even if you reword the question later.
* New: your services now have real pages. Each one shows its price, duration and a working booking form, so people can book straight from a search result. Your theme or page builder still wins if you design your own.
* New: a booking page and a thank-you page are set up for you, and you can point them at pages of your own under Settings → Pages.
* New: analytics worth reading — pick any date range and see staff workload, new versus returning customers, what is still owed and your busiest hour.
* New: staff can be viewed as cards or as a list, on a grid that fits your screen.
* Fix: the confirmation email template used PHP 8 syntax, which was a fatal error on the PHP 7.4 the plugin says it supports.
* Fix: uninstall left several of the plugin's own options, transients and mirrored posts behind even when "delete all data" was ticked.
* Improve: a calmer, tidier admin — lighter headings, tighter fields, and page controls moved up into the page header instead of a second row.

= 1.9.6 =
* Security: the previous fix only closed one of the two ways these lists could be reached. Discount codes and the waitlist were still readable without logging in, through the site's REST API. Both routes are now protected. Please update.

= 1.9.5 =
* Security: booking lists could be read by anyone without logging in, exposing customer names, email addresses and phone numbers. Booking data sent back after a form submission is now stripped of personal details for anyone who is not an administrator. Please update.

= 1.9.4 =
* Fix: switching on a second business type appeared to work but changed nothing, because two types share the same screens. Choosing one now simply replaces the other.

= 1.9.3 =
* Improve: your business type's wording now reaches the shared screens too — a clinic sees "Patients", a tutor sees "Students", instead of "Customers" everywhere. Page descriptions match as well.

= 1.9.2 =
* Improve: the admin menu now shows only the screens your business type uses. A tutor no longer sees a walk-in queue, and a generic appointment site no longer sees patient records. Screens you already have data in are always kept.
* Fix: a business type added by a plugin update could switch itself on and take over the menu, so a barbershop could suddenly relabel itself as another trade.

= 1.9.1 =
* Security: the waitlist could be read by anyone without logging in, exposing the name, email address and phone number of everyone waiting for a slot. Discount codes were readable the same way. Both now require an administrator login. Please update.

= 1.9.0 =
* New: choose your business type during setup — Salon, Barbershop, Clinic, Therapy Practice, Personal Training, Tutoring, or plain Appointments. Only the screens you need are shown.
* New: the admin now speaks your trade. A salon sees "Treatments" and "Stylists", a clinic sees "Consultations" and "Practitioners", instead of generic wording.
* Fix: business-type wording was included in the plugin but never actually applied anywhere — menus and page headings always read "Services" and "Employees".

= 1.8.8 =
* Fix: saving more than one setting change at once silently lost all but the last one. All changes in a save are now applied together.

= 1.8.7 =
* Fix: two people booking at the very same moment could both be given the last place. Each is now handed out once.
* Improve: clearer wording when something is fully booked.

= 1.8.6 =
* Fix: error messages never appeared on public booking pages. If a booking could not be completed — for example the time was taken while you were filling in the form — nothing was shown at all. The reason is now displayed.

= 1.8.5 =
* Fix: booking widgets placed in a narrow theme column could overlap their own text, hiding names and descriptions behind the price. Widgets now lay themselves out from the space they are actually given.

= 1.8.4 =
* Fix: when two people booked at the very same moment, both could be accepted for a resource with only one place left. Bookings are now taken one at a time per resource, so only one can win.

= 1.8.3 =
* Improve: setup now asks what your business books and sets up only that. Fewer menu items, nothing to tidy up afterwards.

= 1.8.2 =
* Fix: two people could book the same staff member for the same time. Bookings are now checked for clashes as they are saved, so only one can win a slot.
* Fix: the booking calendar kept offering times that were already booked — they are now hidden.
* Fix: if a slot is taken while you are filling in your details, the message now says so and asks you to pick another time, instead of "please try again".

= 1.8.1 =
* Fix: the booking widget could not be completed on sites installed in a subdirectory — every API request went to the wrong path.
* Fix: choosing a service then showed no staff to book with, so the booking flow could not be finished.
* Fix: sample data now creates the staff and service links and working hours it needs, so the demo is actually bookable.
* Fix: sample images are bundled with the plugin instead of loaded from an external image host.
* Fix: the email activity log now records what was sent.
* Improve: admin menu no longer collides with the Comments menu position.

= 1.8.0 =
* New: recurring appointments in the public booking flow.
* New: weekly staff rosters — bookings only land while a staff member is on shift.
* New: walk-in queue, reviews moderation and an activity log.
* Improve: unlimited staff, analytics and the staff and customer portals are all part of this plugin, with no licence check anywhere.
* Improve: faster admin boot and a tidier settings layout.

= 1.4.0 =
* New: System Status panel (Settings → General) — email delivery, database and scheduled-task health at a glance.
* New: read-only email activity log, plus a per-booking "Resend email".
* New: responsive Services screen — up to six columns, with a grid and list toggle.
* Improve: much faster admin — pages now paint with their data inline, instead of a request storm on load.
* Fix: the public booking widget no longer resets the host theme's styles, and native browser confirm and alert popups were replaced with styled dialogs.

= 1.3.3 =
* Fix: booking confirmation and reminder emails now authenticate reliably on any host. Tiger Booking sets the SMTP envelope sender so SPF passes even under WP-Cron, and defaults the From name to your site title rather than "WordPress".

= 1.0.1 =
* Fix: frontend booking widgets could boot without their API configuration, breaking authenticated actions on some hosts.
* Fix: admin and customer notification emails could be sent to the wrong address instead of the configured business email.

= 1.0.0 =
* Initial release: services, booking calendar, single-staff scheduling, manual bookings, email confirmations.

== Upgrade Notice ==

= 2.0.0 =
A large tidy-up of every admin screen, plus fixes for menus that opened nothing and fields that looked absent. Nothing you have set up changes.

= 1.10.0 =
Intake and consent forms, real service pages, and a much better analytics screen. Also fixes a fatal error on PHP 7.4 in the confirmation email, and an uninstall that left some of its own data behind.

= 1.9.6 =
Security release. Discount codes and the waitlist were still readable without logging in through a second route. Please update.

= 1.9.5 =
Security release. Booking lists could be read without logging in, exposing customer names, emails and phone numbers. Please update.

= 1.9.1 =
Security release. The waitlist and discount codes could be read by anyone without logging in. Please update.

= 1.8.2 =
Fixes double bookings: two people could book the same staff member for the same time. Recommended for every site taking live bookings.
