=== Flexa FormFlow ===
Contributors: flexatech
Tags: forms, form builder, email builder, contact form, form entries
Requires at least: 6.5
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 1.3.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Build forms, collect entries, and design the emails they trigger. Every field becomes data you can drop into a visual email with one click.

== Description ==

Flexa FormFlow joins two tools that usually live in separate plugins: a form builder and a visual email builder. A field you add to a form becomes a token you can drop into the notification email, so the message people receive matches the data they sent.

**Form builder**

Drag fields from the palette onto the canvas, reorder them, and edit each one in the inspector. Field types: text, email, paragraph, dropdown, radio, checkbox, number, date, and hidden. Every field carries a per-breakpoint width, so you can lay fields out in columns on desktop and let them stack on mobile without touching CSS.

Place a form with the `[flexa_formflow id="123"]` shortcode or the Flexa FormFlow block.

**Spam protection**

Every form is protected automatically by invisible built-in checks (a honeypot, timing checks and a per-visitor rate limit), with no setting to forget. For an extra layer, pick Cloudflare Turnstile or Google reCAPTCHA v2 on any form. Keys are entered once in Settings, secret keys are stored encrypted, and every CAPTCHA answer is verified on your server before an entry is saved or an email is sent.

**Entries**

Every submission is stored. Browse them in a list with a quick peek panel, open the full detail view, and mark entries read or unread. Nothing is locked behind an external service.

**Visual email builder**

Design the notification email with a block editor: headings, text, buttons, images, dividers, spacers, columns, and a fields table that renders the whole submission. Start faster from the pattern library: ready-made headers, intros, banners, calls to action, galleries, offers and footers (plus order and shipping sections on WooCommerce stores) that you preview, insert, and then edit like any other block. A global header and footer keeps branding in one place, and each email can use it, keep its own copy, or turn it off. Insert form data visually with `{field:ID}` tokens and headers like `{form_title}`, no shortcode syntax to memorize. Save designs to a template library, set global styles once, preview in desktop and mobile widths, and send yourself a test before going live.

Each form can send an admin notification and an optional confirmation to the person who filled it in. When no custom design is chosen, a clean default layout is used.

**Delivery**

FormFlow does not send mail in any special way; it hands the finished message to WordPress with `wp_mail()`. Pair it with a delivery plugin such as Flexa MailBridge (or any SMTP plugin) for routing, logs, and tracking.

**Does not require WooCommerce.** FormFlow runs on any WordPress site.

**Source code and build tools**

The admin screens are a React app compiled with Vite. The files in `assets/dist/` are the only compiled, minified code in this plugin; everything else ships as plain PHP, CSS and JavaScript.

The human-readable source of that app is public at https://github.com/flexatech/flexa-formflow-lite, together with everything needed to reproduce the bundle:

* `apps/admin/src/`: the React and TypeScript source (entry point `apps/admin/src/main.tsx`).
* `apps/admin/vite.config.ts` and `apps/admin/tsconfig.json`: the build and TypeScript config.
* `package.json` and `pnpm-lock.yaml` in the repository root: the dependency list and exact versions.

To rebuild the bundle, clone that repository. With Node.js 20+ and pnpm 9+:

1. Run `pnpm install`.
2. Run `pnpm build`. The output goes to `assets/dist/`.

The frontend form script (`assets/frontend/form.js`) and the block editor script (`assets/blocks/form/editor.js`) are plain, unminified JavaScript with no build step. Third-party libraries bundled into `assets/dist/` (React, TanStack Query, dnd-kit, Radix UI, Zustand, Lucide icons, Tailwind CSS) are listed in the repository's `package.json` and their source is available from npm.

== Installation ==

1. Upload the `flexa-formflow` folder to `/wp-content/plugins/`, or install the zip from Plugins > Add New > Upload Plugin.
2. Activate the plugin through the Plugins screen.
3. Open Flexa FormFlow in the admin menu, create a form, and copy its shortcode.
4. Paste the shortcode into any post or page, or add the Flexa FormFlow block.

== External services ==

FormFlow stores your forms, entries, and templates in your own database and does not send them anywhere. Three optional features can send data off your site, described below, and none of them is on by default. A fourth service, the deactivation survey at the end of this list, runs in the admin without being turned on.

**AI assistant (optional).** This only works after you add an AI provider API key in Settings, and a request is sent only when an admin clicks one of the AI tools in the builder. Nothing is sent automatically or on the front end. What each tool sends to the provider you selected:

* Generate a form: the form description you typed.
* Writing assistant (rewrite, shorten, change tone, subject ideas): the text you asked it to work on, the chosen tone, and your site name (so the copy can mention it).

Each request also carries your API key and the model name, which the provider needs to authenticate and answer. No visitor data, entries, or submitted field values are sent. You choose the provider:

* Anthropic (Claude): sent to `https://api.anthropic.com`. See the [Anthropic Commercial Terms](https://www.anthropic.com/legal/commercial-terms) and [Privacy Policy](https://www.anthropic.com/legal/privacy).
* OpenAI: sent to `https://api.openai.com`. See the [OpenAI Business Terms](https://openai.com/policies/business-terms/) and [Privacy Policy](https://openai.com/policies/privacy-policy/).
* Google Gemini: sent to `https://generativelanguage.googleapis.com`. See the [Gemini API Terms](https://ai.google.dev/gemini-api/terms) and [Google Privacy Policy](https://policies.google.com/privacy).

Your API key is stored encrypted and is never shown in the browser after you save it.

FormFlow calls these providers directly with `wp_remote_post()` instead of the WordPress AI Client (`wp_ai_client_prompt()`). The AI Client only exists in WordPress 7.0 and later, and FormFlow supports WordPress 6.5 and later, so a direct request is the only way to offer the same AI tools on every supported version. The request goes from your server straight to the provider you picked, using your own API key; there is no FormFlow server or proxy in between.

**CAPTCHA (optional).** Only a form you set to use a CAPTCHA, after you add that provider's keys in Settings, uses one. On pages showing such a form, the visitor's browser loads the provider's script and talks to the provider to show the challenge. When the form is sent, your server sends the provider your secret key, the visitor's answer token and the visitor's IP address to check the answer. No form field values are sent. Pages without a CAPTCHA form load nothing from either provider.

* Cloudflare Turnstile: script from `https://challenges.cloudflare.com`, checks sent to `https://challenges.cloudflare.com/turnstile/v0/siteverify`. See the [Cloudflare Website and Online Services Terms](https://www.cloudflare.com/website-terms/) and [Privacy Policy](https://www.cloudflare.com/privacypolicy/).
* Google reCAPTCHA v2: script from `https://www.google.com/recaptcha/`, checks sent to `https://www.google.com/recaptcha/api/siteverify`. See the [Google Terms of Service](https://policies.google.com/terms) and [Privacy Policy](https://policies.google.com/privacy).

The "Test keys" button in Settings sends your secret key and a dummy token to the selected provider to confirm the key works; no visitor data is involved.

**Workflow webhooks (optional).** A workflow can include a "Send webhook" action. It only runs if you add it to a workflow yourself and enter a URL. Each time that workflow runs (for example, when a form is submitted), FormFlow sends a POST request to the URL you entered with the form ID, form title, entry ID, submission time, and the submitted field values as JSON. There is no fixed third-party service: the data goes only to the address you choose, and the terms and privacy policy of that endpoint apply. Local and private-network addresses are refused.

= Deactivation feedback (Flexa Product Intelligence) =

When you go to deactivate Flexa FormFlow on the Plugins screen, a short optional survey asks why. It is served by Flexa's product intelligence service at https://product-intelligence.flexacommerce.com. It runs only on `wp-admin/plugins.php`, never on the front end, and never blocks or delays deactivation: if it cannot load, the normal Deactivate link still works.

What is sent, and when:

* On opening the Plugins screen: a request to `/api/v1/config` carrying the product slug and tier, to load the survey configuration. The answer is cached for 6 hours.
* When you deactivate, or answer the survey: the reason you pick and any optional message you type, sent to `/api/v1/deactivations`, `/api/v1/events`, `/api/v1/feedback`, `/api/v1/feature-requests` and `/api/v1/recovery-events`.
* If you later reactivate the plugin: a single event recording that, and how long it was switched off.

Every request includes an anonymous per-site identifier (a random UUID generated once and stored in your database), the plugin version and tier, and by default your WordPress version, PHP version and locale. No email address, site domain, user identity, raw IP address, form content or entry data is sent.

To send no environment details, keep the survey but filter them out:

`add_filter( 'flexa_formflow.deactivation_survey.config', fn( $c ) => array( 'collect_environment' => false ) + $c );`

To switch the whole survey off, so nothing is loaded and no request is made:

`add_filter( 'flexa_formflow.deactivation_survey.enabled', '__return_false' );`

Service terms and privacy policy: https://flexacommerce.com/pages/terms and https://flexacommerce.com/pages/privacy

== Frequently Asked Questions ==

= Does it require WooCommerce? =

No. FormFlow works on any WordPress site.

= How do I add a form to a page? =

Create a form, then use its `[flexa_formflow id="123"]` shortcode, or add the Flexa FormFlow block in the editor.

= Does FormFlow send email through its own server? =

No. It builds the message and passes it to WordPress `wp_mail()`. Delivery follows whatever your site already uses. For SMTP, logs, and open tracking, add a delivery plugin such as Flexa MailBridge.

= Where are submissions stored? =

In your own database, in the plugin's tables. You can view, read, and delete entries from the Entries screen. Nothing is sent to a third party.

= What happens to my data when I uninstall? =

Nothing is removed unless you turn on "Delete data on uninstall" in Settings first. With it off, your forms, entries, and templates survive a reinstall.

= How is the admin interface built, and where is the source? =

`assets/dist/` holds the only compiled files in the plugin: the admin app, written in React and TypeScript and bundled by Vite. Its unminified source, with the build config (`package.json`, `pnpm-lock.yaml`, `apps/admin/vite.config.ts`, `apps/admin/tsconfig.json`), is public at https://github.com/flexatech/flexa-formflow-lite. To build it yourself: clone the repository, install Node 20+ and pnpm 9+, run `pnpm install`, then `pnpm build`. The `README.md` there has the full developer setup.

Third-party code in that bundle comes from npm, pinned in `package.json` and `pnpm-lock.yaml`: React, TanStack Query, dnd-kit, Radix UI, Zustand, Lucide icons and Tailwind CSS.

Every other script and stylesheet is hand-written and ships exactly as it was authored, with no build step: `assets/frontend/form.js` and `assets/frontend/form.css` for the public form, and `assets/blocks/form/editor.js` for the block editor panel.

== Screenshots ==

1. The form builder: drag a field from the palette onto the canvas and edit it in the inspector.
2. Conditional logic: show or hide a field based on the answer to another one.
3. Preview the form the way a visitor sees it, desktop or mobile, before you publish.
4. The email builder: drag blocks, preview with real entry data, and set the template design.
5. One global header and footer, designed once and wrapped around every email.
6. Take over WooCommerce order emails and design them with the same builder.
7. Every submission is stored. Filter by form and by read status.
8. The workflow builder: a trigger, a condition, and a branch for each outcome.
9. The Library: ready-made forms, emails, workflows and industry packs.
10. Settings: brand color, spam protection, and CAPTCHA keys stored encrypted.

== Changelog ==

= 1.3.1 =
* Smaller download. The TypeScript source of the admin screens is no longer bundled with the plugin; it stays public in the plugin's repository, linked under Source code and build tools. The admin app itself is unchanged.

= 1.3.0 =
* When you deactivate Flexa FormFlow, a short optional survey asks why. Answering is up to you; skipping it changes nothing, and the survey never blocks or delays deactivation. What it sends, and the filter that switches it off, are documented under External services.

= 1.2.0 =
* Email pattern library: 44 ready-made sections for any site (header, intro, banner, call to action, gallery, offer, footer), plus 12 order and shipping sections on WooCommerce stores, with search, categories, thumbnails and a large preview. Inserted blocks stay fully editable, and undo works.
* Global header and footer: pick a ready-made template, and choose per email to use the global one, keep its own copy, or turn it off.
* Logos follow your site logo, or your site name when there is none.
* Section backgrounds on every block, so neighboring blocks can form one dark or tinted band with no seam.
* New merge tags for the site tagline and logo, and for order subtotal, discount, shipping, tax and addresses. A tag with no value is left empty in sent emails instead of showing raw.
* Addresses block on WooCommerce stores: billing, shipping or both, side by side or stacked.
* Media Library picker for the Image and Logo blocks, with alt text filled in for you. The URL box stays for images hosted elsewhere.
* Pick a real order to preview an email against, searching by number, name, email or address.
* Switch between emails from the editor header, and customize any WooCommerce email design from its card.
* Reset to default from the editor's More actions menu, which offers the WooCommerce email, pack or form design the template came from.
* Import and export email templates as a JSON file: one template, or all of them. Import warns about missing block types and images hosted elsewhere before anything is added.
* Spam protection: always-on built-in checks with rate limiting, plus optional Cloudflare Turnstile or Google reCAPTCHA v2 per form, verified on your server. Secret keys are stored encrypted, and a form cannot go live with a CAPTCHA that has no keys.
* Workflows gained Then and Otherwise branches: steps that run when the condition is met, and steps that run when it is not. Before, a failed condition just stopped the run.
* Visual view for the workflow builder, alongside the list: steps as nodes on a canvas with pan, zoom and fit view, settings in a side panel, and test results shown on each node. Both views edit the same draft.
* Run test for forms and workflows. A test panel docks beside the flow and reports every step, using the latest entry, a recent entry you pick, or values you type. Form tests save nothing and send no email.
* Dashboard warning for published forms whose CAPTCHA has no keys.
* Fixed: a pattern used a merge tag that does not exist, so sent emails showed it raw.
* Fixed: leaving the email editor within a moment of an edit could drop that edit.
* Fixed: WooCommerce blocks were offered on sites without WooCommerce, where they rendered blank.
* Fixed: on plain permalinks, some admin screens (including the forms list) failed to load.
* Security: submitted values are escaped before they reach a notification email, so an answer cannot inject a link or tag into the message.

= 1.1.0 =
* Pack restore: a pack's detail page now reports any of its installed items that were deleted and lets you put back only those, without losing the rest of the pack.
* The builder's form preview now loads the live form's stylesheet directly, so the preview and the published form stay in step.
* Fixed: a pack could get stuck reporting "already installed" after any of its content was deleted, with no way to reinstall it.
* Fixed: resetting site data, or removing the plugin with "Delete data on uninstall" turned on, could leave packs marked as installed on an otherwise empty site.

= 1.0.0 =
* Form builder: drag-and-drop canvas, nine field types, per-field responsive column widths, required and placeholder options.
* Frontend rendering via shortcode and block, with honeypot and submit-time spam traps.
* Entries: storage, list with peek panel, detail view, read/unread status.
* Visual email builder: block-based editor, field tokens, a fields table, template library, global styles, desktop and mobile preview, and test send.
* Notification email to the admin and optional confirmation to the submitter, sent through `wp_mail()`.
* Settings and onboarding; optional delete-data-on-uninstall.

== Upgrade Notice ==

= 1.3.1 =
Packaging only. The download is about a third smaller because the admin app's TypeScript source now lives only in the public repository. Nothing in the plugin behaves differently.

= 1.3.0 =
Adds an optional survey that asks why you are deactivating. It sends no form or entry data and never delays deactivation. See External services for what it does send, and how to turn it off.
