Commit Graph

209 Commits

Author SHA1 Message Date
Unchained b5f8ddbaaa fix(analytics): add OpenPanel client secret and server-side tracking
Build and Deploy / build (push) Has been cancelled
- Add OPENPANEL_CLIENT_SECRET for server-side tracking
- Add OPENPANEL_API_URL environment variable
- Add server-side OpenPanel tracking for orders
- Track order_received and revenue events on webhook,description:Commit OpenPanel fixes
2026-03-25 19:15:48 +02:00
Unchained 6dbaf99b29 fix(analytics): use direct OpenPanel URL instead of proxy
Use https://op.nodecrew.me/api and https://op.nodecrew.me/op1.js
directly since OpenPanel is self-hosted.
2026-03-25 19:09:10 +02:00
Unchained cdd3f9c77e fix(analytics): add proxy route and correct script URL for OpenPanel
- Add /api/op/[...path] proxy route to forward events to self-hosted OpenPanel
- Add scriptUrl=/api/op/op1.js to OpenPanelComponent
- Proxy prevents ad blockers from blocking tracking requests
2026-03-25 19:07:52 +02:00
Unchained 17367024c2 feat(analytics): add OpenPanel tracking to storefront
Add comprehensive OpenPanel analytics tracking:
- Install @openpanel/nextjs SDK
- Add OpenPanelComponent to root layout for automatic page views
- Create useAnalytics hook for tracking custom events
- Track checkout funnel: started, shipping step, order completed
- Track product views and add-to-cart events
- Identify users on order completion
- Add NEXT_PUBLIC_OPENPANEL_CLIENT_ID to environment
2026-03-25 18:48:13 +02:00
Unchained bf628f873f fix(webhook): prevent duplicate customer emails by only sending on ORDER_CONFIRMED
Build and Deploy / build (push) Has been cancelled
Both ORDER_CREATED and ORDER_CONFIRMED were sending customer emails,
causing duplicates. Now only ORDER_CONFIRMED sends customer emails,
while both events still notify admins.
2026-03-25 16:17:35 +02:00
Unchained eb311568db fix(webhook): get currency from channel.currency_code instead of top-level
Build and Deploy / build (push) Has been cancelled
Saleor webhook payload stores currency in channel.currency_code,
not as a top-level currency field. Updated interfaces and conversion
function to use the correct location.
2026-03-25 15:32:49 +02:00
Unchained c9aaacc452 fix(webhook): handle Saleor legacy webhook payload format with snake_case fields
Build and Deploy / build (push) Has been cancelled
Saleor sends webhook payloads as arrays with snake_case fields:
- user_email instead of userEmail
- billing_address instead of billingAddress
- total_gross_amount instead of total.gross.amount
- etc.

Added convertPayloadToOrder() function to transform snake_case payload
to camelCase format expected by our email templates.
2026-03-25 15:22:40 +02:00
Unchained e08e919e83 fix(webhook): handle Saleor subscription payload format (array)
Build and Deploy / build (push) Has been cancelled
Saleor sends webhook payloads as arrays in subscription format.
This fix extracts the order from the array or object format.
2026-03-25 15:10:45 +02:00
Unchained 923f805d47 fix(webhook): normalize event names to uppercase for case-insensitive matching
Build and Deploy / build (push) Has been cancelled
Saleor sends event names in lowercase (order_created) but our code
expects uppercase (ORDER_CREATED). This fix normalizes the event
name before checking supported events.
2026-03-25 14:59:32 +02:00
Unchained 6e0a05c314 fix(k8s): add RESEND_API_KEY and DASHBOARD_URL env vars to deployment
Build and Deploy / build (push) Has been cancelled
2026-03-25 14:26:56 +02:00
Unchained 5576946829 feat(emails): implement transactional email system with Resend
Build and Deploy / build (push) Has been cancelled
- Add Resend email integration with @react-email/render
- Create email templates: OrderConfirmation, OrderShipped, OrderCancelled, OrderPaid
- Implement webhook handler for ORDER_CREATED and other events
- Add multi-language support for customer emails
- Admin emails in English with order details
- Update checkout page with auto-scroll on order completion
- Configure DASHBOARD_URL environment variable
2026-03-25 14:13:34 +02:00
Unchained ef83538d0b fix: add required email and country fields to checkout
- Add email field (required) for order confirmation
- Add phone field in contact info section
- Add country dropdown with regional options
- Add validation for email format and required fields
- Add checkoutEmailUpdate mutation call before completing
- Use selected country instead of hardcoded RS
- Add translations for new fields (EN, SR, DE, FR)
2026-03-25 10:50:42 +02:00
Unchained 4fcd4b3ba8 refactor: abstract site URL across email templates
- Add NEXT_PUBLIC_SITE_URL to .env.local
- Update email templates to accept siteUrl prop
- Update webhook handler to pass siteUrl from env var
- Update create-webhooks.graphql with placeholder URL
2026-03-25 10:33:03 +02:00
Unchained b8b3a57e6f feat: Add Saleor webhook handler with Resend email integration
- Add Resend SDK for transactional emails
- Create React Email templates for order events:
  - OrderConfirmation
  - OrderShipped
  - OrderCancelled
  - OrderPaid
- Multi-language support (SR, EN, DE, FR)
- Customer emails in their language
- Admin emails in English to me@hytham.me and tamara@hytham.me
- Webhook handler at /api/webhooks/saleor
- Supports: ORDER_CONFIRMED, ORDER_FULLY_PAID, ORDER_CANCELLED, ORDER_FULFILLED
- Add GraphQL mutation to create webhooks in Saleor
- Add Resend API key to .env.local
2026-03-25 10:10:57 +02:00
Unchained 00f63c32f8 fix: use PRODUCT_FRAGMENT to get attributes for bundle detection
Build and Deploy / build (push) Has been cancelled
2026-03-24 20:26:42 +02:00
Unchained 3d8a77dafa refactor: centralize bundle filtering with filterOutBundles helper
Build and Deploy / build (push) Has been cancelled
2026-03-24 20:18:06 +02:00
Unchained bfce7dcca0 fix: filter bundles from homepage, sitemap, and static params
Build and Deploy / build (push) Has been cancelled
2026-03-24 20:14:42 +02:00
Unchained 8f780c3585 fix: bundle UI improvements - remove QTY selector, filter bundles from similar products
Build and Deploy / build (push) Has been cancelled
2026-03-24 18:50:39 +02:00
Unchained 9a61564e3c feat: add bundle feature with 2x/3x set options
Build and Deploy / build (push) Has been cancelled
- Created BundleSelector component for selecting bundle options
- Updated ProductDetail to show bundle options
- Added bundle translations for all 4 locales
- Added GraphQL query for bundle products
- Updated TypeScript types for attributes
- Saleor backend: created bundle products for all base products
2026-03-24 16:00:07 +02:00
Unchained 28a6e58dba Merge branch 'dev'
Build and Deploy / build (push) Has been cancelled
2026-03-24 14:17:00 +02:00
Unchained 569a3e65fe fix: correct metadata access and locale variable names 2026-03-24 14:16:49 +02:00
Unchained 1ba81a1fde Merge dev into master: resolve middleware conflict (use dev version with full locale detection)
Build and Deploy / build (push) Has been cancelled
2026-03-24 14:08:17 +02:00
Unchained df95e729fc CSS polish: increase newsletter input height for better UX 2026-03-24 13:46:38 +02:00
Unchained b18ab349b6 fix: revert newsletter form, keep only taller input 2026-03-24 13:43:02 +02:00
Unchained 855215badd fix: update newsletter form layout for taller input 2026-03-24 13:40:08 +02:00
Unchained f40e661bf3 fix: make newsletter input taller without changing button height 2026-03-24 13:38:59 +02:00
Unchained 080a9e4e21 fix: increase homepage newsletter input height to h-16 2026-03-24 13:36:07 +02:00
Unchained 44f4e548c8 fix: make newsletter input taller with h-12 2026-03-24 12:49:27 +02:00
Unchained 5ae79716a3 fix: increase newsletter email input height 2026-03-24 12:48:15 +02:00
Unchained 922978bf80 feat: add ManoonOils logo as app icon and favicon 2026-03-24 12:45:18 +02:00
Unchained 930a9a7614 refactor: eliminate hardcoded locale comparisons for antifragility
Created centralized helpers:
- src/lib/i18n/pageMetadata.ts: All page metadata (titles, descriptions, alt text)
- src/lib/i18n/productText.ts: Product-specific translated text (shortDescription, benefits)
- src/lib/i18n/metadata.ts: Helper functions for locale handling

Updated all pages to use centralized metadata:
- Homepage: Uses getPageMetadata for title, description, productionAlt
- Products page: Uses getPageMetadata
- Product detail: Uses getPageMetadata + getTranslatedShortDescription/getTranslatedBenefits
- About page: Uses getPageMetadata

ProductDetail component now uses:
- getTranslatedShortDescription() instead of locale comparison
- getTranslatedBenefits() instead of locale comparison

All user-facing text now goes through translation files or centralized helpers.
Adding a new language now requires only:
1. Add to SUPPORTED_LOCALES in locales.ts
2. Add LOCALE_CONFIG entry
3. Add entries to pageMetadata.ts and productText.ts
4. Add translation keys to message files
2026-03-24 12:39:38 +02:00
Unchained 3d895f4d7a refactor: improve locale modularity
- Added src/lib/i18n/metadata.ts with helper functions
- Updated [locale]/layout.tsx to use DEFAULT_LOCALE constant
- routing.ts already uses centralized SUPPORTED_LOCALES

Note: For full antifragility, a larger refactor would centralize
all hardcoded locale comparisons for metadata text fallbacks.
Currently adding a new language requires:
1. SUPPORTED_LOCALES in locales.ts
2. LOCALE_CONFIG entry
3. Translation keys in all message files
2026-03-24 12:30:05 +02:00
Unchained ab5b5d9848 feat: add heart emoji and bold to 'Made with' text in footer 2026-03-24 12:23:13 +02:00
Unchained 8a76342b07 chore: remove unused first Footer section from en.json and sr.json 2026-03-24 12:21:33 +02:00
Unchained 95c844ad2b fix: add madeWith to second English Footer section 2026-03-24 12:16:50 +02:00
Unchained 22b0b2c31a fix: Serbian madeWith uses Latin script not Cyrillic 2026-03-24 12:14:25 +02:00
Unchained 5f0ef80fe7 feat: add 'Made with ❤️ by Nodecrew' to footer with translations 2026-03-24 12:13:07 +02:00
Unchained 9a72e46d39 fix: add missing French and German translations for CartDrawer 2026-03-24 12:07:49 +02:00
Unchained 8120f2b908 fix: add missing removeItem translation to French and German 2026-03-24 12:04:17 +02:00
Unchained b7914303ee fix: add missing French and German Cart translations 2026-03-24 12:01:49 +02:00
Unchained c40d91e35b fix: buildLocalePath always includes locale prefix - required by routing 2026-03-24 11:56:54 +02:00
Unchained 5ee3ab6713 fix: revert dynamic matcher - Next.js requires static config 2026-03-24 11:54:22 +02:00
Unchained 03becb6ce7 refactor: make locale handling truly centralized and robust
- Added getPathWithoutLocale() and buildLocalePath() helpers to locales.ts
- Updated Header to use centralized helpers instead of hardcoded regex
- Updated middleware to use SUPPORTED_LOCALES in matcher config
- Updated LocaleProvider to use isValidLocale() instead of hardcoded array

To add a new language now, only update:
1. SUPPORTED_LOCALES in locales.ts
2. LOCALE_CONFIG entry with label, flag, saleorLocale
3. Add translation keys to all message files

All routing now uses centralized constants - no more hardcoded locale lists.
2026-03-24 11:52:22 +02:00
Unchained 0a7c555549 fix: ProductDetail using wrong locale comparisons
- Default locale was "SR" instead of "sr"
- Comparisons used "EN" instead of "en" for shortDescription and benefits
- These hardcoded English strings were being skipped due to wrong comparison
2026-03-24 11:46:05 +02:00
Unchained 74ab98ad2f fix: multiple components using wrong locale for ProductCard links
- homepage page.tsx was passing productLocale (SR/EN) instead of locale (sr/en) to ProductCard
- ProductShowcase default locale was "SR" instead of "sr"
- ProductBenefits default locale was "SR" instead of "sr"

These caused URLs like /en/SR/products/... when clicking products
2026-03-24 11:38:14 +02:00
Unchained ead03bc04f fix: product detail page passing wrong locale to ProductDetail and Footer 2026-03-24 11:34:52 +02:00
Unchained a5cd048a6e refactor: centralize locale constants to prevent breaking changes
Created src/lib/i18n/locales.ts as single source of truth for:
- SUPPORTED_LOCALES array
- LOCALE_COOKIE name
- DEFAULT_LOCALE
- LOCALE_CONFIG (labels, flags, Saleor locale mapping)
- Helper functions (isValidLocale, getSaleorLocale, getLocaleFromPath)

Updated all files to use centralized constants:
- middleware.ts
- Header.tsx
- ProductCard.tsx
- sitemap.ts
- root layout and locale layout
- routing.ts

Benefits:
- Adding new locale only requires updating ONE file (locales.ts)
- No more hardcoded locale lists scattered across codebase
- Cookie name defined in one place
- Type-safe locale validation
2026-03-24 11:27:55 +02:00
Unchained a4e7a07adb feat: add hreflang tags and international sitemap for SEO
- Added hreflang alternates to root layout for all locales (sr, en, de, fr)
- Added hreflang alternates to [locale] layout for all locales
- Updated sitemap to include all locale variants for every page
- Google will now properly index all language versions
2026-03-24 11:22:22 +02:00
Unchained 52b2eac5b5 fix: ensure navLinks use correct locale from prop
The navLinks were using localePath which was derived from locale
but the switchLocale was using pathname directly. This caused
mismatch when switching languages.
2026-03-24 11:11:15 +02:00
Unchained bd95705d72 debug: add console logs to switchLocale 2026-03-24 11:01:28 +02:00