feat: set checkout languageCode based on user locale
Some checks failed
Build and Deploy / build (push) Has been cancelled

- Add languageCode to checkout store state
- Add setLanguageCode action to store
- Pass languageCode when creating checkout
- Header component sets language code from useLocale hook
- Enables multi-language order confirmation emails
This commit is contained in:
Unchained
2026-03-28 12:31:34 +02:00
parent ee574cb736
commit 5ec0e6c92c
2 changed files with 24 additions and 11 deletions

View File

@@ -5,7 +5,7 @@ import Link from "next/link";
import Image from "next/image"; import Image from "next/image";
import { usePathname } from "next/navigation"; import { usePathname } from "next/navigation";
import { AnimatePresence, motion } from "framer-motion"; import { AnimatePresence, motion } from "framer-motion";
import { useTranslations } from "next-intl"; import { useTranslations, useLocale } from "next-intl";
import { useSaleorCheckoutStore } from "@/stores/saleorCheckoutStore"; import { useSaleorCheckoutStore } from "@/stores/saleorCheckoutStore";
import { User, ShoppingBag, Menu, X, Globe } from "lucide-react"; import { User, ShoppingBag, Menu, X, Globe } from "lucide-react";
import CartDrawer from "@/components/cart/CartDrawer"; import CartDrawer from "@/components/cart/CartDrawer";
@@ -16,14 +16,15 @@ interface HeaderProps {
locale?: string; locale?: string;
} }
export default function Header({ locale = "sr" }: HeaderProps) { export default function Header({ locale: propLocale = "sr" }: HeaderProps) {
const t = useTranslations("Header"); const t = useTranslations("Header");
const pathname = usePathname(); const pathname = usePathname();
const dropdownRef = useRef<HTMLDivElement>(null); const dropdownRef = useRef<HTMLDivElement>(null);
const [mobileMenuOpen, setMobileMenuOpen] = useState(false); const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const [scrolled, setScrolled] = useState(false); const [scrolled, setScrolled] = useState(false);
const [langDropdownOpen, setLangDropdownOpen] = useState(false); const [langDropdownOpen, setLangDropdownOpen] = useState(false);
const { getLineCount, toggleCart, initCheckout } = useSaleorCheckoutStore(); const { getLineCount, toggleCart, initCheckout, setLanguageCode } = useSaleorCheckoutStore();
const locale = useLocale();
const itemCount = getLineCount(); const itemCount = getLineCount();
const currentLocale = isValidLocale(locale) ? LOCALE_CONFIG[locale] : LOCALE_CONFIG.sr; const currentLocale = isValidLocale(locale) ? LOCALE_CONFIG[locale] : LOCALE_CONFIG.sr;
@@ -58,6 +59,13 @@ export default function Header({ locale = "sr" }: HeaderProps) {
initCheckout(); initCheckout();
}, [initCheckout]); }, [initCheckout]);
// Set language code for checkout based on current locale
useEffect(() => {
if (locale) {
setLanguageCode(locale);
}
}, [locale, setLanguageCode]);
useEffect(() => { useEffect(() => {
const handleScroll = () => { const handleScroll = () => {
setScrolled(window.scrollY > 50); setScrolled(window.scrollY > 50);

View File

@@ -58,6 +58,7 @@ interface GetCheckoutResponse {
interface SaleorCheckoutStore { interface SaleorCheckoutStore {
checkout: Checkout | null; checkout: Checkout | null;
checkoutToken: string | null; checkoutToken: string | null;
languageCode: string | null;
isOpen: boolean; isOpen: boolean;
isLoading: boolean; isLoading: boolean;
error: string | null; error: string | null;
@@ -68,6 +69,7 @@ interface SaleorCheckoutStore {
updateLine: (lineId: string, quantity: number) => Promise<void>; updateLine: (lineId: string, quantity: number) => Promise<void>;
removeLine: (lineId: string) => Promise<void>; removeLine: (lineId: string) => Promise<void>;
setEmail: (email: string) => Promise<void>; setEmail: (email: string) => Promise<void>;
setLanguageCode: (languageCode: string) => void;
refreshCheckout: () => Promise<void>; refreshCheckout: () => Promise<void>;
toggleCart: () => void; toggleCart: () => void;
openCart: () => void; openCart: () => void;
@@ -85,12 +87,13 @@ export const useSaleorCheckoutStore = create<SaleorCheckoutStore>()(
(set, get) => ({ (set, get) => ({
checkout: null, checkout: null,
checkoutToken: null, checkoutToken: null,
languageCode: null,
isOpen: false, isOpen: false,
isLoading: false, isLoading: false,
error: null, error: null,
initCheckout: async () => { initCheckout: async () => {
const { checkoutToken } = get(); const { checkoutToken, languageCode } = get();
if (checkoutToken) { if (checkoutToken) {
// Try to fetch existing checkout // Try to fetch existing checkout
@@ -109,7 +112,7 @@ export const useSaleorCheckoutStore = create<SaleorCheckoutStore>()(
} }
} }
// Create new checkout // Create new checkout with language code
try { try {
const { data } = await saleorClient.mutate<CheckoutCreateResponse>({ const { data } = await saleorClient.mutate<CheckoutCreateResponse>({
mutation: CHECKOUT_CREATE, mutation: CHECKOUT_CREATE,
@@ -117,6 +120,7 @@ export const useSaleorCheckoutStore = create<SaleorCheckoutStore>()(
input: { input: {
channel: CHANNEL, channel: CHANNEL,
lines: [], lines: [],
languageCode: languageCode ? languageCode.toUpperCase() : undefined,
}, },
}, },
}); });
@@ -294,6 +298,7 @@ export const useSaleorCheckoutStore = create<SaleorCheckoutStore>()(
openCart: () => set({ isOpen: true }), openCart: () => set({ isOpen: true }),
closeCart: () => set({ isOpen: false }), closeCart: () => set({ isOpen: false }),
clearError: () => set({ error: null }), clearError: () => set({ error: null }),
setLanguageCode: (languageCode: string) => set({ languageCode }),
getLineCount: () => { getLineCount: () => {
const { checkout } = get(); const { checkout } = get();