63 Commits

Author SHA1 Message Date
myron 06260ed192 fix: move loadCustomerEmails to module scope, wire into switchCTab, add emails to tab loop; drop redundant ?: [] in customer-emails.php 2026-06-23 16:35:11 +00:00
myron 145397ab81 sync: updated admin, assets, new images, composer config, customer email API 2026-06-21 03:46:45 +00:00
myron 3d9b648f74 Rewrite returns policy to match Google Merchant Center requirements
30-day window, defective + non-defective returns, exchanges accepted,
free prepaid return label, no restocking fees, 5-day refund processing.
US only. Removes old three-tier responsibility model.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 01:02:30 +00:00
myron 67caf9ad3b Use product name as-is for merchant feed title
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 00:56:07 +00:00
myron 69f09a257c Fix doubled category suffix in merchant feed titles
Product names already include 'Whole Bean Coffee' / 'Ground Coffee' so
appending the category label was doubling the suffix. Now only appends
if the product name doesn't already contain 'coffee'.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 00:52:46 +00:00
myron a2bc87e947 Update admin nav logo to new PNG design
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 20:03:24 +00:00
myron afc8750b67 Increase nav logo height to 70px for readability
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 19:54:25 +00:00
myron cf1f090e25 Crop website logo to content — remove surrounding whitespace
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 19:48:09 +00:00
myron 712ec8c584 Update site logo to new horizontal design
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 19:46:25 +00:00
myron 1112fa2ab6 Revert site logo to original — new logo kept for GMC only
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 19:35:10 +00:00
myron 60fc302443 Add cache-busting version string to logo img tags
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 19:31:07 +00:00
myron 530bb8e4ce Replace logo-icon.png with new logo (was broken HTML file)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 19:29:31 +00:00
myron 51ca171060 Replace logo with new 1500x1500 transparent PNG design
Fresh Tom's Java Jive logo with coffee cup, Tom's Java Jive text,
Artisan Coffee Roaster, and www.tomsjavajive.com. Bump logo display
height to 65px to suit square aspect ratio.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 19:28:09 +00:00
myron b11a274986 Fix stale contact info in privacy page
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 19:01:58 +00:00
myron 73143577e3 Fix contact form 500 — use sendEmail() not cybermailSend()
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 18:50:59 +00:00
myron c1c926a416 Fix contact info — correct email, phone, and ZIP throughout
sales@tomsjavajive.com, (817) 266-2022, Weatherford TX 76088 applied to
contact page, header schema, returns page, and FAQ. Fix Quick Links
list style so links render properly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 18:49:24 +00:00
myron 15bcef262f Google Merchant Center trust signal improvements
- Add contact.php (was 404, linked from footer and returns page)
- Add shippingDetails and hasMerchantReturnPolicy to product schema
- Add priceValidUntil to product Offer schema
- Improve merchant feed descriptions (use DB description when present)
- Add handling/transit times and return_policy_label to feed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 18:46:21 +00:00
myron 5637b6d7f5 CSS modularization Phase 2: account, cart, checkout
Extract account/cart/checkout styles into dedicated CSS files; remove inline styles and orphaned style blocks from HTML. Wire $extraHead on all account pages, cart.php, and checkout.php.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 17:51:57 +00:00
myron 771e1a15b1 Modularize CSS into page-specific files
Split style.css into home.css (hero, features, newsletter, splash) and
products.css (product grid/cards). Each page loads only what it needs
via $extraHead. style.css now contains only truly shared styles.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 17:32:57 +00:00
myron f54148dbe7 Condense footer from 5 columns to 3
Merged Company + Support into a single Help column, removed Sub
Categories section. Tightened grid gap, padding, and list spacing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 17:23:32 +00:00
myron 01dc6f90fe Remove Weatherford TX location references from merchant feed 2026-06-14 23:49:11 +00:00
myron 94d19d27f1 Add Google Search Console verification meta tag 2026-06-14 23:10:07 +00:00
myron b504981b89 Add Google Merchant Center product feed and GSC meta tag placeholder
- merchant-feed.php: RSS 2.0 feed with all active products; includes
  title, description, image_link, price, availability, brand, shipping,
  google_product_category for each item; URL to submit in Merchant Center
- header.php: placeholder GSC meta tag (replace PASTE_GSC_CODE_HERE with
  verification content value from Search Console)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 23:01:53 +00:00
myron 873a0962c6 SEO overhaul: product schema, dynamic sitemap, favicon, og-image fix
- product.php: set metaTitle, metaDescription, canonicalUrl, ogImage,
  ogType=product, productSchema (JSON-LD with price/availability/reviews),
  and breadcrumbs variables for header.php to consume
- sitemap.php: dynamic XML sitemap generated from DB — includes all 30
  active products + static pages; robots.txt now points here
- header.php: fix favicon links (favicon.ico in root + icon-192.png);
  fix productSchema output (was double-encoding via json_encode)
- robots.txt: point Sitemap directive to /sitemap.php

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 22:50:25 +00:00
myron f89362528a Fix loyalty system: load tiers from DB, award points on payment
- LoyaltyProgram now loads tiers from loyalty_tiers DB table in constructor
  with fallback to hardcoded defaults if table is empty
- awardPoints() accepts order_id param with duplicate-prevention check so
  points cannot be double-awarded for the same order
- Inserts balance_after into loyalty_transactions for accurate history
- payment-status.php: award points after Stripe checkout session or
  PaymentIntent confirmed as paid
- create-checkout-session.php: award points in demo mode payment path

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 20:58:37 +00:00
myron b6d0319be7 Fix admin order page blank redirect after status/note update
Missing ob_start() meant HTML was output before POST handler ran,
so header() redirects silently failed after saving changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 20:50:53 +00:00
myron bdba57166d Condense shop page: merge hero + filters into one compact bar
Combined the large hero section and two-row filter section into a single
compact dark header bar. Category and type pills are inline with a divider,
search/sort sit in the header row. Reduced section top padding.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 20:48:45 +00:00
myron 6e4d2734bb Fix console warnings: remove SW registration, fix meta tag, clean manifest
- Remove service worker registration from footer (SW is already self-unregistering)
- Add mobile-web-app-capable meta to fix deprecation warning
- Remove missing icon references from manifest (only 192/512 PNGs exist)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 20:38:15 +00:00
myron 714ef13897 Fix Stripe checkout: wrong column name stripe_checkout_session → stripe_session_id
DB column is stripe_session_id but code was writing to stripe_checkout_session,
causing a 500 on checkout and breaking payment status checks.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 20:35:35 +00:00
myron ecf5a7ab67 Fix cart quantity update: reload page to reflect accurate totals
Partial DOM update was missing item row totals, shipping recalc, and
grand total. Reload ensures all numbers are always correct.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 20:29:31 +00:00
myron ca2f612421 Fix add-to-cart on home page: wrong class and data attribute
Button used add-to-cart/data-id instead of add-to-cart-btn/data-product-id.
Added inline onclick to match shop and product pages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 20:26:47 +00:00
myron 7dfec466a1 Disable service worker and clear all caches
SW was caching shop pages and JS files, serving stale versions without
the inline onclick handler. Replacing with self-unregistering SW.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 20:23:36 +00:00
myron 935b838c8f Fix cart: start session in functions.php so API endpoints persist cart
All api/*.php files include functions.php but none called session_start(),
so $_SESSION writes were lost after each request. Cart appeared to work
(API returned cart_count:1) but nothing was ever saved.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 20:18:23 +00:00
myron 6e86031576 Fix add-to-cart: bust main.js SW cache, add inline onclick to shop buttons
Service worker was caching main.js (cache-first strategy) so event listeners
may not have been running. Added filemtime version param to main.js like CSS.
Also added inline onclick to shop page buttons so they work regardless of
whether event delegation is functional.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 20:11:35 +00:00
myron e389254a7c Auto-bust Cloudflare CSS cache using filemtime version param
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 20:04:09 +00:00
myron 5c0927af39 Fix ambiguous column error on shop page JOIN query
Prefixed is_active, category, product_type_id, name, description, and ORDER BY columns with table alias p to resolve ambiguity with the product_types JOIN.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 19:56:47 +00:00
myron e6ca96b75c Make footer Shop links dynamic from products categories
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 19:50:51 +00:00
myron 29656bd4d7 Add product count column to product types admin page
Shows how many active products are linked to each type, linked to the filtered products list.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 19:50:29 +00:00
myron 890c98d4cd Fix product images, add-to-cart, and add Sub Categories filter
- Add display:block to .product-card-image so padding-top aspect ratio works on anchor tags
- Add Cache-Control: no-transform header to disable Cloudflare Rocket Loader (was deferring main.js and breaking add-to-cart click handlers)
- Add Sub Categories filter row on shop page using product_types table
- Show category · sub-category on product cards
- Add Sub Categories section to footer
- Preserve subcat param across category/sort filter links

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 19:47:08 +00:00
myron 548713971d Fix pagination styling, add-to-cart class/data-attr mismatch, shop.php pagination 2026-06-14 16:24:39 +00:00
myron da60888b72 Fix CSV import — convert tags/images to valid JSON before insert (mysql json_valid constraint) 2026-06-14 16:05:42 +00:00
myron 0a6c4508d5 Rebuild product image upload section — fix broken HTML, wrong textarea name, JS quote errors 2026-06-14 15:57:33 +00:00
myron 1609dea8fb Fix product image upload — remove header.php (outputs HTML), auth check directly 2026-06-14 15:48:19 +00:00
myron 5058da704a Fix product image upload — ob_end_clean() before JSON response, fix uploads dir permissions 2026-06-14 15:44:25 +00:00
myron 602bc77cdd Fix CyberMail from field — use separate from/from_name fields (API rejects Name <email> format) 2026-06-14 15:40:35 +00:00
myron 66cbd3f0d3 Remove prefilled placeholder email from admin login 2026-06-14 15:18:27 +00:00
myron 8957cb2c28 Remove equipment link from footer
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 12:53:53 +00:00
myron 2a1ca85062 Add FAQ, shipping, returns, track order, and privacy policy pages
- faq.php: accordion FAQ with Orders, Coffee & Products, Coffee Freshness & Storage, and Account sections
- shipping.php: rates table (3-5 days after processing), processing time, delivery flow
- returns.php: three-tier policy (your/our/shared responsibility) adapted from DripShipper
- track-order.php: order lookup by order number + email, progress steps, tracking link
- privacy.php: full privacy policy adapted for Toms Java Jive
- footer.php: added Privacy Policy link to Support section

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 12:52:25 +00:00
myron 62dd05780a Add payment_status guard to payment_intent.succeeded handler
Mirrors the checkout.session.completed case which checks
payment_status === paid before acting. Now checks data.status
=== succeeded on the PaymentIntent object, consistent with how
Stripe structures the event and defensive against any future
edge case where the event fires in a non-final state.
2026-06-03 06:13:22 +00:00
myron 7eddf9e85d Fix remaining code review findings: email transport errors, metadata payload, from-name, pagination
- Email::send(): add curl_error() check so transport failures (timeout,
  DNS, TLS) return a diagnosable error string instead of Unknown error
- Email::send(): strip metadata key from options before array_merge so
  non-API fields are never sent to CyberMail endpoint
- Email::send() + sendEmail(): include from-name in From field using
  RFC 5322 "Name <email>" format so fromName DB setting takes effect
- email-log.php: replace unbounded page-link loop with a windowed
  paginator (first/last 2 pages + ±2 around current) with ellipsis
  gaps — prevents hundreds of anchors rendering at scale
2026-06-03 06:01:44 +00:00