=== Nik Wishlist & Ajax Mini Cart ===
Contributors: nikdimon
Tags: wishlist, mini cart, ajax add to cart, woocommerce, cart
Requires at least: 6.2
Tested up to: 7.0
Stable tag: 3.1.0
Requires PHP: 7.4
WC requires at least: 7.0
WC tested up to: 10.9
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Wishlist, sliding ajax mini cart and ajax add-to-cart for WooCommerce, plus sales automations. Free — no licence key, no subscription.

== Description ==

Nik Wishlist & Ajax Mini Cart adds three things every WooCommerce store needs:

* **Wishlist** — a heart button on catalog cards and product pages. Guests keep their list in a cookie (no registration needed); when a customer logs in, the guest list is merged into their account automatically.
* **Ajax mini cart** — a sliding cart panel with quantity controls and item removal, updated without page reloads. Optionally opens automatically whenever a product is added to the cart.
* **Ajax add to cart** — add products from single product pages (including variable products) without a page reload.

= Features =

* Wishlist button on catalog cards and single product pages (position configurable).
* Sliding wishlist modal + a dedicated wishlist page (created automatically, shortcode `[nik_wishlist]`).
* Shareable wishlist links for logged-in customers (secure tokens, no user ids exposed).
* Sliding ajax mini cart with quantity +/- controls, item removal and totals.
* Item counters on the fixed wishlist and cart icons.
* Icon galleries + custom icons from your media library.
* Colors, border radius and custom CSS — all configurable from the admin.
* All front-end texts editable and fully translatable.
* Works with page caching (state is loaded via ajax).
* HPOS compatible. Clean uninstall (opt-in).

= Price =

Free. There is no licence key and no subscription — every feature is available the moment the plugin is activated, including the sales automations:

* **Wishlist analytics** — most-wanted products, adds/removes, wishlist-to-cart conversion.
* **Saved carts** — every logged-in customer cart is stored with contents and totals.
* **Abandoned cart recovery e-mails** — configurable delay, subject and text, one-click unsubscribe, recovery tracking.

[Open the product page](https://products.nikdimon.com/ru/products/nik-wamc/)

== Installation ==

1. Upload the plugin to `/wp-content/plugins/` or install it through the WordPress plugins screen.
2. Activate the plugin. A wishlist page with the `[nik_wishlist]` shortcode is created automatically.
3. Configure icons, positions, colors and texts under **Nik Wishlist → Settings**.
4. For ajax add-to-cart buttons in product archives, enable *WooCommerce → Settings → Products → General → "Enable AJAX add to cart buttons on archives"*.

== Frequently Asked Questions ==

= Does it work for guests? =

Yes. Guests keep their wishlist in a cookie (lifetime configurable). When they log in, the list is merged into their account.

= How do I open the wishlist or mini cart from my own header icon? =

Add the CSS class `btn_open_whishlist` (wishlist) or `btn_open_mini_cart` (mini cart) to any element.

= Can customers share their wishlist? =

Logged-in customers get a share link in the wishlist modal. Sharing can be disabled in the settings.

= Does it slow the site down? =

No. One small CSS and one small JS file; all data is loaded via ajax, so the plugin plays nicely with page caching.

== Privacy ==

**What the plugin stores**

* *Wishlists.* Guests: product ids in the `nik_wamc_wishlist` cookie (lifetime configurable, 28 days by default). Logged-in customers: in user meta, so the list follows the account.
* *Saved carts.* For logged-in customers only: products, quantities, totals, currency and the shop language, used for the recovery e-mail and the restore link. The snapshot is deleted as soon as the cart is emptied.
* *Analytics events.* Product viewed / added to / removed from wishlist or cart / ordered. Visitors are told apart by a random id in the `nik_wamc_vid` cookie (one year) — no name, e-mail or address. Events are pruned automatically after 400 days (filter `nik_wamc_events_retention_days`).
* *E-mail bookkeeping.* Unsubscribe flag, which price-drop notices were sent, when a coupon was issued.

**Consent**

The analytics cookie is gated: with a WP Consent API compatible cookie banner installed, it is only set once the visitor accepts the *statistics* category. Without a banner it is set, and can be switched off with the `nik_wamc_allow_tracking_cookie` filter or by turning analytics off in the settings. No data is sent anywhere except your own site — the plugin makes no outbound calls.

**Customer requests**

The plugin registers a WordPress personal-data exporter and eraser, so *Tools → Export/Erase Personal Data* covers wishlists, saved carts, e-mail preferences and shop activity. Suggested wording for your privacy policy is added to *Settings → Privacy → Policy guide*.

**Removal**

Enable *Settings → General → Clean up on uninstall* and deleting the plugin removes every table, option, user meta and scheduled task it created.

== Changelog ==

= 3.1.0 =

* The plugin is now free. The whole licence layer has been removed: there is no more License tab, no licence key and no subscription check, and every feature — the wishlist, the mini cart, ajax add-to-cart, analytics, saved carts and the recovery e-mails — is available immediately on activation. The plugin no longer makes any outbound call and no longer needs the PHP openssl extension.
* Upgrading from a paid release: everything unlocks on the first load and every setting, saved cart, price-history record and statistic is kept exactly as it was.
* Removed the bundled licence client (nikd-license) from the package.

= 3.0.13 =
* The wishlist and the mini cart can now be opened from your own elements: two settings fields take CSS selectors of any button, link, menu item or page-builder block, and clicking one opens the panel. A link opens the panel instead of following its href, so the feature works on menu items too. A bare word is read as a class, so "my-cart-button" and ".my-cart-button" both work, and a selector with a mistake in it is ignored rather than breaking clicks on the page.

= 3.0.12 =
* Changed: the wishlist page grid is now rendered together with the page itself instead of being fetched afterwards. A theme hooks its product-card parts up while the page is being built, so the fetched grid was always the bare WooCommerce card — different from the catalogue. Rendered with the page, the card is exactly the catalogue card: same image ratio, badges, rating, excerpt and buttons, with the wishlist hearts already active. Removing a product now simply takes its card out of the grid; a list shared by link and the collaborative view keep working as before.
* Fixed: asset versions are now stamped with the file modification time, so browsers pick up a new script right after an update instead of serving a stale copy until the next release.

= 3.0.11 =
* Fixed: on the wishlist page every heart came back grey and removing a product took two clicks. The grid arrives after the page has painted, so its buttons had never been through the state sync — the first click read "not in the list" and added the product again.
* Fixed: the number of columns on the wishlist page was ignored. The card now comes from the catalogue, and so did the catalogue's own column rule; the plugin's setting is applied to the wishlist grid only, and steps down to two columns and then one on narrow screens.
* Changed: each floating icon has its own offsets. One shared pair put the wishlist and the mini cart exactly on top of each other whenever the same corner was chosen. Existing offsets are carried over to the wishlist icon on update.

= 3.0.10 =
* Removed: the Telegram and CRM webhook order notifications, together with their settings (bot token, chat id, webhook URL and secret, "send orders"). Order notifications belong to a plugin that does only that; keeping a second half-implementation here meant two places to configure and two chances to send the same order twice. Stored values are ignored and can be deleted.

= 3.0.9 =
* Added: the wishlist page now draws products with the shop's own product card — the same `content-product.php` the catalogue uses — so the list inherits the theme and whatever the site's card settings define: image ratio, which parts are shown, colours, badges, buttons. Until now the plugin imposed its own card and the wishlist looked like a different shop. The previous markup is still available under Wishlist → Product card.

= 3.0.8 =
* The free-shipping goal now reaches carrier plugins. Until now it only unlocked
  WooCommerce's own "Free shipping" method, so a shop delivering through Nova
  Poshta or Ukrposhta saw the bar say "Free shipping unlocked!" while the
  checkout still charged for delivery. Nik Shipping UA now follows the same
  threshold, and — this is the point — it is decided from the very cart total the
  bar is drawn from, so both switch at the same moment instead of on two totals
  that merely happen to be configured alike. One number, set here.
* Accessibility: the sliding panels are proper dialogs now — focus moves into them when they open and returns to the button that opened them, Tab is kept inside, and a closed panel is out of the tab order (it used to be reachable by keyboard while invisible). Added visible focus rings for keyboard users, right-to-left styles, and respect for the "reduce motion" system setting.
* Security: on a server without the PHP openssl extension the licence response cannot be verified, so premium features stay off instead of being unlocked on trust — with a notice explaining that the key itself is fine and openssl needs enabling.
* Security: share, collaborative, unsubscribe and cart-restore links are now signed with 80 bits instead of 48. Links already sent to customers keep working; a shop that wants them invalidated can return false from the `nik_wamc_accept_legacy_tokens` filter.

= 3.0.7 =
* Fixed: the mini cart discount goal was applied as a negative fee, which WooCommerce does not treat as a discount — tax was charged on the full amount, the order's discount total stayed at zero (so reports and refunds were wrong) and a multilingual shop could end up with two of them. The goal now applies a managed coupon and goes through the normal discount pipeline.
* Fixed: a literal "%" in the mini cart progress texts (e.g. "10% off from %s") crashed the cart endpoint and the mini cart stopped opening for every visitor. Merchant wording is now normalized before it is used.
* Fixed: adding a variable product whose variation leaves an attribute open ("Any size") failed and bounced the customer back to the product page. Add-to-cart now passes the attributes the customer actually chose, and returns the mini cart in the same request — one round trip less.
* Fixed: deactivating the plugin left its scheduled tasks behind, and a task from versions before 3.0 kept firing with no code to handle it. All scheduled events are now removed on deactivation and the stale one is cleared on update.
* Fixed: "Clean up on uninstall" left the price-history table, four user meta keys, two options and the licence state in the database.
* Fixed: the admin stayed in English until a licence key was entered — the translations now load regardless of licence state.
* Fixed: the copy button for the collaborative wishlist link showed a broken image when a custom wishlist icon was used.
* Fixed: adding to cart without ajax (archive ajax buttons off, or no JavaScript) gave the customer no feedback at all.
* Added: GDPR support — personal-data export and erase, a consent gate for the analytics cookie (WP Consent API), and suggested privacy-policy text.
* Added: cart reminder unsubscribe links now ask for confirmation, so mail scanners cannot unsubscribe customers on their own.
* Added: cart restore links from e-mails expire after 30 days; generated coupons are cleaned up once expired and unused.
* Added: translations for the progress goals, coupon and e-mail texts are now exposed to WPML and Polylang.
* Hardened: the public render endpoints cap batches at 200 products and are rate limited; front-end escaping now covers quotes.
* Tested with WooCommerce 10.9.

= 3.0.4 =
* The Saved carts screen now has three sub-tabs: the carts list, **Auto reminders** and the **Reminder e-mail designer**.
* Auto reminders: enable + delay settings moved next to the carts, with a transparent cron panel — next scheduled run, last run with the number of e-mails sent, how many carts are due right now and how many wait for the timer, plus a "Run the check now" button.
* Carts list: a per-cart **"Send reminder now" / "Send again"** button and an honest status per row (sent / queued / scheduled in N hours / unsubscribed / recovered).
* Reminder e-mail designer: logo, shop name, colors (accent, button text, background, card, text), corner radius, button label, intro text, product thumbnails and prices toggles, footer signature and custom footer links — with a live preview on a sample cart and a "send a test to my e-mail" button. The e-mail is a standalone branded HTML template (product images, totals, CTA button, unsubscribe link).

= 3.0.3 =
* Perceived speed: the mini cart panel now opens with a spinner the moment an add-to-cart button is clicked (block and classic buttons alike) instead of waiting ~1.5s for the server round trips; the cart contents fill in as soon as they arrive.
* Instant first paint: the last known wishlist state and cart count are cached per tab, so hearts and counters are correct immediately after navigation; both heart icons are pre-loaded.
* Cart reads are throttled: bursts of WooCommerce cart events now trigger a single request instead of several.

= 3.0.2 =
* Block themes: the mini cart now reacts to the Store API add/remove-to-cart events of the Product Button / Product Collection blocks — it opens on add (or just updates the counter, per the "Open on add" setting).
* The wishlist heart button is now immune to theme/plugin button skins: a hardened CSS reset strips borders, backgrounds, outlines and focus rings in all states.

= 3.0.1 =
* Block themes (e.g. Twenty Twenty-Five): the plugin now takes over the cart completely — the WooCommerce header Mini-Cart block, its drawer and classic cart widgets are disabled while the plugin mini cart is on (new "Replace default carts" switch, enabled by default).
* Wishlist buttons now anchor correctly to product cards in the Product Collection / Products blocks; a JS fallback adds position:relative to cards on any theme.

= 3.0.0 =
* The plugin is now subscription-only: without an active license key from products.nikdimon.com all storefront features stay off.
* Revoking or blocking the key on the portal disables the plugin on the client site at the next license check (cron or any admin visit).
* Removed the free tier and the "Powered by" credit link.

= 2.2.2 =
* The plugin now has its own top-level admin menu (below Settings) with Analytics, Saved carts and Price history as submenus.

= 2.2.1 =
* Plugin Check clean-up: escaping, sanitization and i18n polish; Tested up to WordPress 7.0.

= 2.2.0 =
* New crisp SVG icon set (hearts, bookmarks, stars, carts, light variants for dark headers).
* Configurable offsets for the floating icons; new "Panel text color" style option.
* Mini cart polish: no horizontal scrollbar, clean progress-bar labels.
* Pro: the discount goal now applies a real discount to cart & checkout; free-shipping goal unlocks the Free shipping method.
* Pro: coupons apply with one click from the e-mails; price-drop notifications are logged on the Price history screen.

= 2.1.0 =
* Free version shows a small "Powered by" link (can be switched off); premium features unlock with a license key.
* Pro: multiple and collaborative wishlists, cart restore links, price watch e-mails and history, upsell and free-shipping progress in the mini cart, sleeping-customer coupons, CSV exports, analytics insights and interactive trend chart.

= 2.0.0 =
* Complete rewrite for WordPress.org distribution.
* Security: all requests go through admin-ajax with nonces; full input sanitization and output escaping.
* Wishlists moved to user meta (guests: cookie). Data from 1.x is migrated automatically.
* Finished settings screens: icons, positions, columns, image ratios, colors, border radius, custom CSS, editable texts.
* Wishlist buttons are now rendered by WooCommerce hooks (no fragile DOM parsing).
* Share links now use secure tokens instead of raw user ids.
* Prices rendered with the store currency (no hardcoded currency).
* Full internationalization; English base language.
* HPOS compatibility declared; WooCommerce dependency handled gracefully.

= 1.0 =
* Initial release.

== Upgrade Notice ==

= 2.0.0 =
Major rewrite: safer, faster, configurable. Wishlist data from 1.x is migrated automatically on activation.
