=== Appointly === Contributors: tscholene Tags: booking, appointment, calendar, scheduling, reservation Requires at least: 6.2 Tested up to: 6.9 Requires PHP: 7.4 Stable tag: 2.0.7 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html Offer-first booking for WordPress: customers request, you review, you send a personal offer, they confirm. Built for the craft of booking. == Description == **For businesses that treat every reservation as a conversation, not a checkout.** Appointly is an appointment booking system for WordPress that puts you back in the loop. Instead of automatic scheduling, customers submit booking requests — you review each one, send a personalized offer (with or without pricing), and the customer accepts or declines. Every reservation is deliberate, every price is yours to set, every customer gets a personal touch. Perfect for photographers, consultants, event planners, freelancers, hair & beauty salons, tattoo artists, yoga and fitness studios, tutors — any service business where every reservation deserves a human in the loop. **Why Appointly?** Most booking plugins force automatic scheduling. Appointly is different: 1. Customer picks a date (or timeslot) and submits an inquiry 2. You review the request in the admin dashboard 3. You send a personalized offer with a price and personal note 4. Customer accepts or declines via a link in the email 5. Booking confirmed — everyone gets notified This offer workflow gives you the flexibility to adjust pricing, check availability manually, and add a personal touch before confirming any reservation. **Features:** * **Booking Calendar** — Beautiful, responsive appointment calendar with real-time availability, day-mode single-day booking * **Unlimited Services** — Create as many services as you need, with title, description, image, and base price * **Personal Offer Workflow** — Review every inquiry and send customised offers with automatic email delivery and one-click Accept / Decline links * **SMTP Email Delivery** — Reliable email delivery with presets for Gmail, Outlook, Yahoo, iCloud, IONOS, Strato, World4You, Host Europe, ALL-INKL, Hetzner, and more * **Default Email Templates** — Five polished HTML email templates (inquiry, admin notification, offer, confirmation, cancellation) with light and dark modes, fully translatable * **Dark Mode** — Calendar automatically adapts to the visitor's colour scheme * **Accessibility** — WCAG AA compliant with keyboard navigation * **Gutenberg Block & Shortcodes** — Add the calendar via block editor or shortcode * **Setup Wizard** — Guided onboarding in four steps * **GDPR Ready** — Consent checkbox on the booking form, personal data exporter and eraser integration, encrypted SMTP credentials * **Multilingual** — Full i18n support. German translation included (de_DE, de_DE_formal, de_AT, de_CH, de_CH_informal) **Appointly Pro — coming soon:** Appointly Pro is a separate companion plugin that extends Appointly with 12 professional booking features. It is sold on https://appointly.tscholene.com for €2.99 per month and is NOT distributed through the WordPress.org Plugin Directory. The free plugin remains fully functional without Pro — Pro is an opt-in upgrade, not a lock on existing features. *Pro v1 features (launching in 2.1):* * **Timeslot Scheduling** — Time-based appointment slots per service. Customers pick a specific time, not just a date. Essential for yoga studios, therapists, consultants, and hair salons. * **Custom Service Fields** — Build your own booking form with text, textarea, select, radio, checkbox, date, number, and file upload fields. Ask exactly what you need ("number of guests", "venue address", "special requests"). * **Service Addons & Upsells** — Offer extras like "extra hour", "priority scheduling", "photo album", or "follow-up session" with configurable pricing and quantity. * **Blocked Dates** — Block individual dates globally or per service, plus recurring patterns ("block every Sunday", "block December 20 – January 3"). * **Multi-day Bookings** — Date range bookings for multi-day events, workshops, retreats, and courses. * **iCal Feed** — Subscribe to your bookings in Google Calendar, Apple Calendar, or Outlook for seamless two-way sync. * **Recurring Bookings** — Automatic re-booking for weekly, bi-weekly, and monthly sessions. Ideal for yoga teachers, therapists, and consultants running regular appointments. * **Group Bookings** — Multiple seats per time slot for classes, workshops, and small-group events. * **Customer Self-Service Portal** — Customers reschedule or cancel their bookings via a secure email link, no admin contact required. * **Automatic Booking Reminders** — Polite, on-brand reminder emails sent 24 hours before each appointment. * **Cancellation Policies** — Rule-based fees and cutoff times ("cancellations under 24h incur a 50% fee") enforced automatically. * **Custom Email Template Editor** — Live preview editor with version history for all six email templates. *Coming in 2.2–2.5:* * Staff scheduling with per-staff calendars and load balancing * Deposit collection via Stripe (your own Stripe keys, no middleman) * WooCommerce integration with product-based bookings * Advanced analytics with revenue reports and conversion funnels * Zapier and webhook integrations for workflow automation * Custom branding with logo and colours for your calendar and emails * CSV and Excel export for accounting * Priority email support Learn more and join the waitlist at https://appointly.tscholene.com **Shortcodes & Block:** * Gutenberg Block: Search "Booking Calendar" in the block editor * `[appointly_calendar]` — Display the booking calendar * `[appointly_calendar service="2"]` — Calendar for a specific service * `[appointly_form service="2"]` — Standalone booking form == Installation == 1. Upload the `appointly` folder to `/wp-content/plugins/` 2. Activate the plugin through the 'Plugins' menu in WordPress 3. Complete the setup wizard (Admin → Booking) 4. Add `[appointly_calendar]` to any page or post, or use the "Booking Calendar" Gutenberg block 5. Optionally configure SMTP under **Booking → Settings → Email Delivery** == Frequently Asked Questions == = Does this plugin require any external dependencies? = No PHP dependencies. The free plugin is fully self-contained and works offline. The admin SPA is bundled with @wordpress/scripts and ships with its own translation files. Google Fonts (Instrument Serif, Plus Jakarta Sans, DM Mono) are loaded on admin pages only for the Appointly brand typography — this is documented in the "External services" section below. No fonts or third-party assets are loaded on customer-facing booking pages. = Can I use multiple calendars on one page? = Yes. Each `[appointly_calendar]` shortcode creates an independent instance. = How does the booking flow work? = 1. Customer selects a date (and optionally a timeslot) and fills out the booking form 2. Customer and admin receive confirmation emails 3. Admin reviews the request in Booking → Bookings and clicks "Send Offer" with a price and personal note 4. Customer receives an offer email with Accept / Decline buttons 5. On acceptance, both parties receive the final confirmation email = Does it support multiple languages? = Yes. All strings are translatable via the standard WordPress .po/.mo system. German translations are included for de_DE, de_DE_formal, de_AT, de_CH, and de_CH_informal. The admin React bundle also ships per-bundle .json translation files so all admin UI strings render in the selected language. You can override the customer-facing email language independently of the site language under **Booking → Settings → General → Email Language**. = Can I customize the email templates? = The free plugin ships six default HTML email templates that are fully translatable through the standard WordPress translation system. If you need to rewrite the copy beyond translation, you can either override the templates in a child theme via the standard WordPress template loader, or wait for the live preview template editor coming with Appointly Pro. = Does it support payments? = The free plugin does not collect online payments directly. The booking flow supports manual / offline payment arrangements: when you send an offer, you state the price, the customer accepts, and you handle payment out-of-band (invoice, bank transfer, cash on arrival, etc.). Online payment collection via Stripe — using your own Stripe keys — will be available through Appointly Pro in a later release. = How is Appointly different from other booking plugins? = Unlike most booking and appointment plugins that push automatic scheduling, Appointly is built around a personal offer workflow. You receive booking requests, review them personally, and send customised offers. This gives service providers full control over their calendar, pricing, and customer communication — perfect for businesses where every reservation deserves a personal touch. = How do I get Appointly Pro? = Appointly Pro is a separate companion plugin, not yet publicly available. Visit https://appointly.tscholene.com to join the waitlist — we will email you when Pro launches. When you subscribe, you will receive a download link and a license key via email. You install Appointly Pro as a second plugin (Plugins → Add New → Upload Plugin) alongside this free plugin, paste your license key, and the Pro features activate. The installation takes about two minutes. Appointly Pro is NOT distributed through the WordPress.org Plugin Directory. It is sold directly on appointly.tscholene.com via Lemon Squeezy, which handles EU VAT, subscriptions, failed payments, the customer portal, and refunds. Appointly Pro coexists with this free plugin in one admin menu — no duplicate menu entries, no configuration conflicts, and Pro can be removed independently without affecting any of your booking data. == External services == Appointly loads Google Fonts on the WordPress admin pages so the admin UI can render with the Appointly brand typography (Instrument Serif for hero headings, Plus Jakarta Sans for body text, DM Mono for data labels). This is the only external service that the free plugin connects to. * **Service:** Google Fonts (https://fonts.google.com) * **Purpose:** Loading three web font families so the admin SPA renders with the Appointly brand typography * **Data sent:** Your browser's IP address and User-Agent are sent to `fonts.googleapis.com` and `fonts.gstatic.com` when an admin user opens any Appointly admin page. No booking, customer, or plugin-specific data is transmitted. * **When:** Only when an authenticated WordPress administrator opens an Appointly admin page. Fonts are never loaded on customer-facing booking pages, iCal feed requests, or REST API calls. * **Terms of use:** https://developers.google.com/fonts/faq#what_does_using_the_google_fonts_api_mean_for_the_privacy_of_my_users * **Privacy policy:** https://policies.google.com/privacy If you prefer to block Google Fonts entirely (for example in a privacy-hardened admin environment), the admin UI degrades gracefully to a system font stack (system-ui / BlinkMacSystemFont / Segoe UI / ui-serif / Menlo) and remains fully functional. No other external services are contacted by the free plugin. Appointly does not call any payment providers (Stripe, PayPal), analytics services, license servers, or telemetry endpoints. Appointly Pro — the separate companion plugin sold on https://appointly.tscholene.com — will, when installed, connect to appointly.tscholene.com for license validation (once per day) and plugin update checks. That connection is a feature of the Pro plugin and does not affect this free plugin. Appointly Pro ships with its own readme, privacy disclosures, and external-services documentation. The free plugin on this page does not make any requests to appointly.tscholene.com at runtime. == Screenshots == 1. Admin dashboard with pending, offered, and confirmed booking counts plus recent requests 2. Booking calendar on the front end — customers pick a date and submit an inquiry 3. Bookings list with status filters, search, and one-click offer-workflow actions 4. Booking detail view — customer info, timeline, and Send Offer / Accept / Decline actions 5. Service editor with reorderable services, day or timeslot mode, and active-status toggle 6. Settings page with booking defaults, SMTP email delivery, privacy, and uninstall behavior == Build Instructions == The admin dashboard and the Gutenberg block are built with `@wordpress/scripts` (webpack). The uncompiled source is included in this distribution: * Admin React source: `admin/src/` (entry point: `admin/src/index.js`) * Block source: `blocks/src/` (entry point: `blocks/src/index.js`) To rebuild from source: `cd admin && npm install && npm run build` `cd blocks && npm install && npm run build` Output goes to `admin/build/` and `blocks/build/` respectively. The public frontend calendar (`public/js/appointly-calendar.js`) and stylesheet (`public/css/appointly-calendar.css`) are **not compiled** — they are vanilla JavaScript and CSS, human-readable as-is. == Changelog == = 2.0.7 = * Changed: Consolidated all internal prefixes to `appointly` / `APPOINTLY_` / `Appointly\` per WordPress.org plugin review guidance. Database tables, options, hooks, constants, namespaces, REST namespace, script handles, JS globals, and CSS classes/custom properties were all unified under a single plugin-specific prefix. * Fixed: SMTP connection test no longer loads core PHPMailer files directly; uses `wp_mail()` with `wp_mail_failed` hook for error capture. * Fixed: Booking Response page contrast (light-on-light text on some themes). * Fixed: `manage_bookings` capability is now ensured on every `admin_init` as a safety net for file-overwrite upgrades that skip the activation hook. * Fixed: Cancelling a booking whose service has been deleted no longer produces a stuck "cannot cancel" error — the cancellation proceeds and skips the email step with a clear explanation. * Internal: DB tables renamed from `wpbk_*` to `appointly_*`. CSS custom properties renamed from `--wpbk-*` to `--appointly-*`. REST namespace changed from `wp-booking/v1` to `appointly/v1`. = 2.0.6 = * Added: New filter hook `wpbk_booking_initial_status` so Appointly Pro can implement direct-booking workflows (per-service auto-confirm). * Added: Status-driven email routing for newly created bookings — confirmed bookings send `booking_confirmed` + `admin_new_booking`, inquiry bookings keep the existing pair. * Added: New default email template `admin_new_booking` for admin notifications on direct bookings. * Internal: DB version bumped to reflect new extension points. = 2.0.5 = * Added: Direct accept — mark a pending booking as confirmed without sending an offer (offline workflow). * Added: Status change dialog with an "Inform customer via email" checkbox and optional admin note for every confirm/decline/cancel action. * Added: Offered bookings can be manually cancelled by the admin (withdraw the offer). * Added: Decline email template for manual admin declines (pending → declined, offered → declined). * Added: Status-sensitive action buttons in both BookingDetail and the Bookings list, each with a tooltip explaining what the action does. * Changed: The cancel booking flow now lets the admin opt out of the cancellation email. * Changed: Offers sent without a price now show "Price on request" in the customer email instead of hiding the price box. * Changed: Delete action only available on rows where no customer email has been sent yet (pending) or on finalized records (declined/cancelled). * Fixed: Several pre-existing German translation errors surfaced during regeneration (`Accept` was "Angebot annehmen", `Cancel Offer` was "Angebot annehmen", `Price on request` was "Offene Anfragen", `Decline Booking` was "Buchung stornieren"). = 2.0.4 = * WordPress.org plugin directory compliance release. * Fixed: Review prompt now uses wp_register_script + wp_localize_script instead of echoing inline