@raxonltd/raxon-core 1.0.5 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/core/feature/analytic-event/analytic.event.api.d.ts +13 -0
  2. package/dist/core/feature/analytic-event/analytic.event.api.d.ts.map +1 -0
  3. package/dist/core/feature/analytic-event/analytic.event.api.js +10 -0
  4. package/dist/core/feature/analytic-event/analytic.event.context.d.ts +8 -5
  5. package/dist/core/feature/analytic-event/analytic.event.context.d.ts.map +1 -1
  6. package/dist/core/feature/analytic-event/analytic.event.context.js +58 -84
  7. package/dist/core/feature/analytic-event/analytic.event.util.d.ts +8 -0
  8. package/dist/core/feature/analytic-event/analytic.event.util.d.ts.map +1 -0
  9. package/dist/core/feature/analytic-event/analytic.event.util.js +39 -0
  10. package/dist/core/feature/analytic-event/use.analytic.auto.d.ts +13 -0
  11. package/dist/core/feature/analytic-event/use.analytic.auto.d.ts.map +1 -0
  12. package/dist/core/feature/analytic-event/use.analytic.auto.js +81 -0
  13. package/dist/core/feature/brand/hook/use.brand.d.ts +10 -0
  14. package/dist/core/feature/brand/hook/use.brand.d.ts.map +1 -0
  15. package/dist/core/feature/brand/hook/use.brand.js +21 -0
  16. package/dist/core/raxon.context.d.ts +3 -1
  17. package/dist/core/raxon.context.d.ts.map +1 -1
  18. package/dist/core/raxon.context.js +11 -12
  19. package/dist/core/util/nexine.axios.js +22 -0
  20. package/dist/core/view/view.checkout.d.ts +5 -1
  21. package/dist/core/view/view.checkout.d.ts.map +1 -1
  22. package/dist/core/view/view.checkout.js +265 -10
  23. package/dist/hook.d.ts +1 -0
  24. package/dist/hook.d.ts.map +1 -1
  25. package/dist/hook.js +1 -0
  26. package/dist/index.d.ts +2 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +1 -0
  29. package/dist/tsconfig.tsbuildinfo +1 -1
  30. package/package.json +1 -1
@@ -1,9 +1,10 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import Link from 'next/link';
4
- import { useRouter } from 'next/navigation';
5
- import { HelpCircle } from 'lucide-react';
6
- import { useState, useRef, useEffect, useMemo } from 'react';
4
+ import { useRouter, useSearchParams } from 'next/navigation';
5
+ import { CheckCircle2, HelpCircle, Loader2, Package, XCircle } from 'lucide-react';
6
+ import { useState, useRef, useEffect, useMemo, useCallback, Suspense, createContext, useContext } from 'react';
7
+ import { useQueryClient } from '@tanstack/react-query';
7
8
  import { useForm } from 'react-hook-form';
8
9
  import { Input } from 'rizzui/input';
9
10
  import { Button } from 'rizzui/button';
@@ -17,8 +18,10 @@ import { AddressSearchInput } from '../feature/address/form/address-search-input
17
18
  import { formatAddressSummary, parsedAddressToFormFields } from '../feature/address/util/parse-google-place';
18
19
  import { formatBasketItemVariantLine } from '../util/basket.item.display';
19
20
  import { GeneralImage } from '../component/general.image';
20
- import { AddressType, PaymentProvider, PaymentTerms } from '../interface/prisma.interface';
21
- import { storeGarantiPaymentHtml } from '../util/garanti-payment';
21
+ import { AddressType, PaymentProvider, PaymentTerms, Status } from '../interface/prisma.interface';
22
+ import { consumeGarantiPaymentHtml, storeGarantiPaymentHtml, submitGarantiPaymentHtml } from '../util/garanti-payment';
23
+ import { useOrder } from '../feature/order/hook/use.order';
24
+ import { nexineAxios } from '../util/nexine.axios';
22
25
  import { resolveClientIp } from '../util/client-ip';
23
26
  import { CartPromoCodeSection } from '../feature/cart/component/cart.promo.code.section';
24
27
  const addressFormDefaultValues = {
@@ -42,6 +45,23 @@ const addressFormDefaultValues = {
42
45
  savedBillingAddressId: '',
43
46
  addressSearch: '',
44
47
  };
48
+ const CheckoutViewContext = createContext({
49
+ webReturnUrl: '/sepet/odeme',
50
+ });
51
+ function useCheckoutViewConfig() {
52
+ return useContext(CheckoutViewContext);
53
+ }
54
+ function resolveAbsoluteReturnUrl(webReturnUrl) {
55
+ if (/^https?:\/\//i.test(webReturnUrl))
56
+ return webReturnUrl;
57
+ if (typeof window === 'undefined')
58
+ return webReturnUrl;
59
+ return `${window.location.origin}${webReturnUrl.startsWith('/') ? webReturnUrl : `/${webReturnUrl}`}`;
60
+ }
61
+ function withCheckoutQuery(webReturnUrl, query) {
62
+ const separator = webReturnUrl.includes('?') ? '&' : '?';
63
+ return `${webReturnUrl}${separator}${query}`;
64
+ }
45
65
  function formatAddressLine(addr) {
46
66
  const name = addr.companyName || `${addr.firstName ?? ''} ${addr.lastName ?? ''}`.trim();
47
67
  const street = addr.streetName ?? addr.fullAddress ?? '';
@@ -117,7 +137,7 @@ function ViewStep1({ onContinue }) {
117
137
  const handleEmailBlur = () => {
118
138
  void saveEmail(emailInput);
119
139
  };
120
- return (_jsxs(_Fragment, { children: [_jsx(ModalAuth, { ref: modalAuthRef }), _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-base font-semibold text-gray-900", children: "\u0130leti\u015Fim" }), _jsx("p", { className: "mt-1 text-sm text-gray-500", children: "Sipari\u015F onay\u0131 ve kargo bilgileri bu adrese g\u00F6nderilir." })] }), !isGuest && isAuthenticated ? (_jsx("p", { className: "text-sm text-gray-600", children: _jsx("button", { type: "button", className: "font-medium text-[#CF0A2C] hover:underline", onClick: () => modalAuthRef.current?.open('login'), children: "Hesab\u0131n\u0131zla giri\u015F yapt\u0131n\u0131z" }) })) : (_jsxs("p", { className: "text-sm text-gray-600", children: ["Hesab\u0131n\u0131z var m\u0131?", ' ', _jsx("button", { type: "button", className: "font-medium text-[#CF0A2C] hover:underline", onClick: () => modalAuthRef.current?.open('login'), children: "Giri\u015F yap" }), ' veya ', _jsx("button", { type: "button", className: "font-medium text-[#CF0A2C] hover:underline", onClick: () => modalAuthRef.current?.open('register'), children: "kay\u0131t ol" })] })), _jsx(Input, { type: "email", label: "E-posta", placeholder: "ornek@email.com", value: emailInput, onChange: e => {
140
+ return (_jsxs(_Fragment, { children: [_jsx(ModalAuth, { ref: modalAuthRef }), _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-base font-semibold text-gray-900", children: "\u0130leti\u015Fim" }), _jsx("p", { className: "mt-1 text-sm text-gray-500", children: "Sipari\u015F onay\u0131 ve kargo bilgileri bu adrese g\u00F6nderilir." })] }), !isGuest && isAuthenticated ? (_jsx("p", { className: "text-sm text-gray-600", children: _jsx("button", { type: "button", className: "font-medium text-[#CF0A2C] hover:underline", onClick: () => modalAuthRef.current?.open('login'), children: "Hesab\u0131n\u0131zla giri\u015F yapt\u0131n\u0131z" }) })) : (_jsxs("p", { className: "text-sm text-gray-600", children: ["Hesab\u0131n\u0131z var m\u0131?", _jsx("button", { type: "button", className: "font-medium text-[#CF0A2C] hover:underline", onClick: () => modalAuthRef.current?.open('login'), children: "Giri\u015F yap" }), ' veya ', _jsx("button", { type: "button", className: "font-medium text-[#CF0A2C] hover:underline", onClick: () => modalAuthRef.current?.open('register'), children: "kay\u0131t ol" })] })), _jsx(Input, { type: "email", label: "E-posta", placeholder: "ornek@email.com", value: emailInput, onChange: e => {
121
141
  userEditedEmailRef.current = true;
122
142
  setEmailInput(e.target.value);
123
143
  }, onBlur: handleEmailBlur, size: "lg", className: "rounded-xl", required: true }), isSaving ? _jsx("p", { className: "text-xs text-gray-500", children: "Kaydediliyor\u2026" }) : null, emailError ? _jsx("p", { className: "text-sm text-red-600", children: emailError }) : null, _jsx(Button, { type: "button", size: "lg", className: "w-full rounded-xl bg-[#CF0A2C] font-semibold text-white hover:bg-[#a80824]", disabled: !emailInput.trim() || isSaving, onClick: async () => {
@@ -410,6 +430,7 @@ function ViewStep2({ onComplete, onBack }) {
410
430
  }
411
431
  function ViewStepCheckout({ onBack }) {
412
432
  const router = useRouter();
433
+ const { webReturnUrl } = useCheckoutViewConfig();
413
434
  const { cart, cartLoading, paymentMethod, deliveryMethod, bankAccount } = useRaxon();
414
435
  const [payStartError, setPayStartError] = useState(null);
415
436
  const [bankTransferError, setBankTransferError] = useState(null);
@@ -598,7 +619,7 @@ function ViewStepCheckout({ onBack }) {
598
619
  return;
599
620
  setPayStartError(null);
600
621
  try {
601
- const payReturnUrl = `${window.location.origin}/sepet/odeme/sonuc`;
622
+ const payReturnUrl = resolveAbsoluteReturnUrl(webReturnUrl);
602
623
  const paymentResponse = await payMutation({ platform: 'web', webReturnUrl: payReturnUrl });
603
624
  const ok = paymentResponse && typeof paymentResponse === 'object' && 'status' in paymentResponse && paymentResponse.status === true;
604
625
  const info = paymentResponse && typeof paymentResponse === 'object' && 'info' in paymentResponse && paymentResponse.info && typeof paymentResponse.info === 'object'
@@ -618,12 +639,12 @@ function ViewStepCheckout({ onBack }) {
618
639
  const garantiTransactionId = info && typeof info.transactionId === 'string' ? info.transactionId : null;
619
640
  if (ok && provider === PaymentProvider.GARANTI && garantiHtml && garantiTransactionId) {
620
641
  storeGarantiPaymentHtml(garantiTransactionId, garantiHtml);
621
- router.push(`/sepet/odeme/pay?provider=garanti&transactionId=${encodeURIComponent(garantiTransactionId)}`);
642
+ router.push(withCheckoutQuery(webReturnUrl, `type=pay&provider=garanti&transactionId=${encodeURIComponent(garantiTransactionId)}`));
622
643
  return;
623
644
  }
624
645
  const token = info && typeof info.token === 'string' ? info.token : null;
625
646
  if (ok && token) {
626
- router.push(`/sepet/odeme/pay?token=${encodeURIComponent(token)}`);
647
+ router.push(withCheckoutQuery(webReturnUrl, `type=pay&token=${encodeURIComponent(token)}`));
627
648
  }
628
649
  else {
629
650
  setPayStartError('Ödeme ekranı açılamadı. Lütfen tekrar deneyin.');
@@ -642,7 +663,234 @@ const CHECKOUT_STEP_LABELS = {
642
663
  address: 'Adres',
643
664
  checkout: 'Önizleme ve ödeme',
644
665
  };
645
- export default function PaymentPage() {
666
+ const PAYTR_IFRAME_ID = 'paytriframe';
667
+ const TERMINAL_FAILURE_STATUSES = new Set([
668
+ Status.REJECTED,
669
+ Status.ERROR,
670
+ Status.CANCELLED,
671
+ Status.TIMEOUT,
672
+ ]);
673
+ function normalizeReturnMessage(raw) {
674
+ if (raw == null || raw === '')
675
+ return null;
676
+ try {
677
+ const d = decodeURIComponent(raw.replace(/\+/g, ' '));
678
+ return d.replace(/^['"]|['"]$/g, '').trim() || null;
679
+ }
680
+ catch {
681
+ return raw.replace(/^['"]|['"]$/g, '').trim() || null;
682
+ }
683
+ }
684
+ function shortenId(id) {
685
+ if (id.length <= 12)
686
+ return id;
687
+ return `${id.slice(0, 8)}…${id.slice(-4)}`;
688
+ }
689
+ async function fetchTransactionStatus(transactionId) {
690
+ const response = await nexineAxios.get(`/global/transcation/${transactionId}/status`);
691
+ return {
692
+ status: response.data?.status ?? null,
693
+ orderId: response.data?.orderId ?? null,
694
+ };
695
+ }
696
+ function runPaytrIframeResize() {
697
+ const w = window;
698
+ w.iFrameResize?.({}, `#${PAYTR_IFRAME_ID}`);
699
+ }
700
+ function CheckoutShellHeader() {
701
+ const { branch } = useRaxon();
702
+ return (_jsx("header", { className: "border-b border-gray-100 bg-white", children: _jsx("div", { className: "mx-auto flex max-w-3xl items-center justify-between px-4 py-5 sm:px-6", children: _jsx(Link, { href: "/", className: "flex flex-col items-start gap-1", children: _jsx(GeneralImage, { quality: 85, src: branch?.logoMedia?.relativePath ? `${process.env.NEXT_PUBLIC_STORAGE_URL}/${branch.logoMedia.relativePath}` : '', alt: branch?.tradingName ?? 'Logo', width: 120, height: 36, className: "h-7 w-auto object-contain" }) }) }) }));
703
+ }
704
+ function CheckoutPayView() {
705
+ const searchParams = useSearchParams();
706
+ const { webReturnUrl } = useCheckoutViewConfig();
707
+ const token = searchParams.get('token');
708
+ const providerParam = searchParams.get('provider');
709
+ const transactionId = searchParams.get('transactionId');
710
+ const [garantiRedirectError, setGarantiRedirectError] = useState(null);
711
+ const [garantiRedirecting, setGarantiRedirecting] = useState(false);
712
+ const garantiSubmitRef = useRef(false);
713
+ const isGarantiRedirect = providerParam === 'garanti' &&
714
+ transactionId != null &&
715
+ transactionId.trim() !== '';
716
+ useEffect(() => {
717
+ if (!isGarantiRedirect || !transactionId || garantiSubmitRef.current)
718
+ return;
719
+ const html = consumeGarantiPaymentHtml(transactionId);
720
+ if (!html) {
721
+ setGarantiRedirectError('Garanti ödeme oturumu bulunamadı. Lütfen ödeme adımından tekrar deneyin.');
722
+ return;
723
+ }
724
+ garantiSubmitRef.current = true;
725
+ setGarantiRedirecting(true);
726
+ try {
727
+ submitGarantiPaymentHtml(html);
728
+ }
729
+ catch {
730
+ garantiSubmitRef.current = false;
731
+ setGarantiRedirecting(false);
732
+ setGarantiRedirectError('Garanti ödeme sayfasına yönlendirilemedi. Lütfen tekrar deneyin.');
733
+ }
734
+ }, [isGarantiRedirect, transactionId]);
735
+ useEffect(() => {
736
+ if (!token)
737
+ return;
738
+ const scriptSelector = 'script[data-paytr-iframe-resizer]';
739
+ if (document.querySelector(scriptSelector)) {
740
+ runPaytrIframeResize();
741
+ return;
742
+ }
743
+ const s = document.createElement('script');
744
+ s.src = 'https://www.paytr.com/js/iframeResizer.min.js';
745
+ s.async = true;
746
+ s.dataset.paytrIframeResizer = 'true';
747
+ s.onload = runPaytrIframeResize;
748
+ document.body.appendChild(s);
749
+ }, [token]);
750
+ if (isGarantiRedirect) {
751
+ if (garantiRedirectError) {
752
+ return (_jsx("div", { className: "min-h-screen bg-gray-50 flex flex-col items-center justify-center px-4", children: _jsxs("div", { className: "max-w-md w-full rounded-2xl border border-gray-100 bg-white p-10 text-center shadow-sm", children: [_jsx("h1", { className: "text-xl font-black uppercase tracking-tighter text-gray-900 mb-3", children: "Garanti \u00F6deme" }), _jsx("p", { className: "text-sm text-[#CF0A2C] mb-8 font-medium", children: garantiRedirectError }), _jsx(Link, { href: webReturnUrl, className: "inline-flex justify-center rounded-xl bg-[#CF0A2C] px-8 py-3.5 text-sm font-black uppercase tracking-widest text-white transition hover:bg-[#a80824]", children: "\u00D6demeye d\u00F6n" })] }) }));
753
+ }
754
+ return (_jsx("div", { className: "min-h-screen bg-gray-50 flex flex-col items-center justify-center px-4", children: _jsxs("div", { className: "max-w-md w-full rounded-2xl border border-gray-100 bg-white p-10 text-center shadow-sm", children: [_jsx("div", { className: "mx-auto mb-5 h-10 w-10 animate-spin rounded-full border-2 border-gray-200 border-t-[#CF0A2C]", "aria-hidden": true }), _jsx("span", { className: "text-sm font-black text-[#CF0A2C] uppercase tracking-widest", children: "Garanti" }), _jsx("h1", { className: "mt-2 text-xl font-black uppercase tracking-tighter text-gray-900 mb-3", children: garantiRedirecting ? 'Yönlendiriliyorsunuz' : 'Hazırlanıyor' }), _jsx("p", { className: "text-sm text-gray-600 leading-relaxed", children: "Garanti g\u00FCvenli \u00F6deme sayfas\u0131na aktar\u0131l\u0131yorsunuz. L\u00FCtfen bekleyin." })] }) }));
755
+ }
756
+ if (token) {
757
+ return (_jsx("div", { className: "min-h-screen bg-gray-50", children: _jsxs("div", { className: "max-w-3xl mx-auto px-4 py-10 sm:py-12", children: [_jsxs("div", { className: "mb-8 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between sm:gap-4", children: [_jsxs("div", { children: [_jsx("span", { className: "text-sm font-black text-[#CF0A2C] uppercase tracking-widest", children: "PayTR" }), _jsx("h1", { className: "mt-2 text-2xl font-black text-gray-900 uppercase tracking-tighter", children: "G\u00FCvenli \u00F6deme" })] }), _jsx(Link, { href: webReturnUrl, className: "text-xs font-black uppercase tracking-widest text-gray-900 border-b-2 border-black pb-1 self-start sm:self-auto hover:text-[#CF0A2C] hover:border-[#CF0A2C] transition-colors", children: "\u00D6deme sayfas\u0131na d\u00F6n" })] }), _jsx("div", { className: "rounded-2xl border border-gray-100 bg-white overflow-hidden shadow-sm", children: _jsx("div", { className: "p-2", children: _jsx("iframe", { title: "PayTR g\u00FCvenli \u00F6deme", src: `https://www.paytr.com/odeme/guvenli/${token}`, id: PAYTR_IFRAME_ID, frameBorder: 0, scrolling: "no", className: "w-full min-h-[480px] border-0 rounded-xl", onLoad: runPaytrIframeResize }) }) })] }) }));
758
+ }
759
+ return (_jsx("div", { className: "min-h-screen bg-gray-50 flex flex-col items-center justify-center px-4", children: _jsxs("div", { className: "max-w-md w-full rounded-2xl border border-gray-100 bg-white p-10 text-center shadow-sm", children: [_jsx("h1", { className: "text-xl font-black uppercase tracking-tighter text-gray-900 mb-3", children: "Ge\u00E7ersiz ba\u011Flant\u0131" }), _jsx("p", { className: "text-sm text-gray-600 mb-8 leading-relaxed", children: "\u00D6deme oturumu bulunamad\u0131. L\u00FCtfen \u00F6deme ad\u0131m\u0131ndan tekrar deneyin." }), _jsx(Link, { href: webReturnUrl, className: "inline-flex justify-center rounded-xl bg-[#CF0A2C] px-8 py-3.5 text-sm font-black uppercase tracking-widest text-white transition hover:bg-[#a80824]", children: "\u00D6demeye git" })] }) }));
760
+ }
761
+ function CheckoutResultView() {
762
+ const searchParams = useSearchParams();
763
+ const queryClient = useQueryClient();
764
+ const { webReturnUrl } = useCheckoutViewConfig();
765
+ const statusParam = searchParams.get('status');
766
+ const titleParam = normalizeReturnMessage(searchParams.get('title'));
767
+ const messageParam = normalizeReturnMessage(searchParams.get('message'));
768
+ const transactionId = searchParams.get('transactionId');
769
+ const paymentIdParam = searchParams.get('paymentId');
770
+ const orderIdParam = searchParams.get('orderId');
771
+ const isSuccess = statusParam === 'success';
772
+ const isFailure = statusParam === 'fail' || statusParam === 'error';
773
+ const hasValidStatus = isSuccess || isFailure;
774
+ const [phase, setPhase] = useState(() => {
775
+ if (isFailure)
776
+ return 'error';
777
+ if (isSuccess && orderIdParam)
778
+ return 'success';
779
+ if (isSuccess)
780
+ return 'loading';
781
+ return 'loading';
782
+ });
783
+ const [resolvedOrderId, setResolvedOrderId] = useState(orderIdParam);
784
+ const resolvedPaymentId = paymentIdParam;
785
+ const [errorMessage, setErrorMessage] = useState(isFailure ? messageParam ?? titleParam ?? 'Ödeme tamamlanamadı.' : null);
786
+ const intervalRef = useRef(null);
787
+ const pollFailCountRef = useRef(0);
788
+ const cartInvalidatedRef = useRef(false);
789
+ const clearPollInterval = useCallback(() => {
790
+ if (intervalRef.current != null) {
791
+ clearInterval(intervalRef.current);
792
+ intervalRef.current = null;
793
+ }
794
+ }, []);
795
+ const { detail } = useOrder();
796
+ const orderQuery = detail(resolvedOrderId ?? '');
797
+ const order = orderQuery.data;
798
+ useEffect(() => {
799
+ if (window.self !== window.top) {
800
+ window.top.location.href = window.location.href;
801
+ }
802
+ }, []);
803
+ useEffect(() => {
804
+ if (!isSuccess)
805
+ return;
806
+ if (orderIdParam) {
807
+ setResolvedOrderId(orderIdParam);
808
+ setPhase('success');
809
+ return;
810
+ }
811
+ if (!transactionId) {
812
+ setErrorMessage('İşlem bilgisi bulunamadı.');
813
+ setPhase('error');
814
+ return;
815
+ }
816
+ let cancelled = false;
817
+ setPhase('polling');
818
+ const tick = async () => {
819
+ try {
820
+ const { status: st, orderId } = await fetchTransactionStatus(transactionId);
821
+ pollFailCountRef.current = 0;
822
+ if (cancelled)
823
+ return;
824
+ if (orderId) {
825
+ setResolvedOrderId(orderId);
826
+ }
827
+ if (st === Status.COMPLETED) {
828
+ clearPollInterval();
829
+ if (!cartInvalidatedRef.current) {
830
+ cartInvalidatedRef.current = true;
831
+ await queryClient.invalidateQueries({ queryKey: ['organization', 'cart'] });
832
+ }
833
+ setPhase('success');
834
+ return;
835
+ }
836
+ if (st != null && TERMINAL_FAILURE_STATUSES.has(st)) {
837
+ clearPollInterval();
838
+ setErrorMessage('Ödeme tamamlanamadı veya iptal edildi.');
839
+ setPhase('error');
840
+ }
841
+ }
842
+ catch {
843
+ pollFailCountRef.current += 1;
844
+ if (pollFailCountRef.current >= 5 && !cancelled) {
845
+ clearPollInterval();
846
+ setErrorMessage('Ödeme durumu alınamadı. Lütfen daha sonra siparişlerinizi kontrol edin.');
847
+ setPhase('error');
848
+ }
849
+ }
850
+ };
851
+ void tick();
852
+ intervalRef.current = setInterval(() => void tick(), 3000);
853
+ return () => {
854
+ cancelled = true;
855
+ clearPollInterval();
856
+ };
857
+ }, [isSuccess, transactionId, orderIdParam, clearPollInterval, queryClient]);
858
+ useEffect(() => {
859
+ if (phase !== 'success' || cartInvalidatedRef.current)
860
+ return;
861
+ cartInvalidatedRef.current = true;
862
+ void queryClient.invalidateQueries({ queryKey: ['organization', 'cart'] });
863
+ }, [phase, queryClient]);
864
+ const displayTitle = phase === 'success' ? (titleParam ?? 'Ödeme başarılı') : (titleParam ?? 'Ödeme başarısız');
865
+ const displayMessage = phase === 'success'
866
+ ? (messageParam ?? 'Ödemeniz alındı. Siparişiniz işleme alınacaktır.')
867
+ : (errorMessage ?? messageParam ?? 'İşlem tamamlanamadı.');
868
+ const showOrderLoading = phase === 'success' && resolvedOrderId && orderQuery.isLoading;
869
+ return (_jsxs("div", { className: "min-h-screen bg-gray-50", children: [_jsx(CheckoutShellHeader, {}), _jsxs("main", { className: "mx-auto max-w-2xl px-4 py-10 sm:py-14", children: [(phase === 'loading' || phase === 'polling' || showOrderLoading) && (_jsxs("div", { className: "rounded-2xl border border-gray-100 bg-white p-10 text-center shadow-sm", children: [_jsx(Loader2, { className: "mx-auto mb-5 h-10 w-10 animate-spin text-[#CF0A2C]", "aria-hidden": true }), _jsx("h1", { className: "text-xl font-black uppercase tracking-tighter text-gray-900 mb-3", children: "\u00D6deme onaylan\u0131yor" }), _jsx("p", { className: "text-sm text-gray-600 leading-relaxed", children: "Sipari\u015Finiz olu\u015Fturuluyor. L\u00FCtfen bu sayfada kal\u0131n." })] })), phase === 'success' && !showOrderLoading && (_jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "rounded-2xl border border-gray-100 bg-white p-8 sm:p-10 text-center shadow-sm", children: [_jsx("div", { className: "mx-auto mb-5 inline-flex h-16 w-16 items-center justify-center rounded-full bg-green-50 text-green-600", children: _jsx(CheckCircle2, { size: 32, "aria-hidden": true }) }), _jsx("h1", { className: "text-2xl font-black uppercase tracking-tighter text-gray-900 mb-2", children: displayTitle }), _jsx("p", { className: "text-sm text-gray-600 leading-relaxed", children: displayMessage })] }), _jsxs("div", { className: "rounded-2xl border border-gray-100 bg-white p-6 shadow-sm space-y-4", children: [_jsx("p", { className: "text-xs font-black uppercase tracking-widest text-[#CF0A2C]", children: "\u0130\u015Flem bilgileri" }), _jsxs("dl", { className: "space-y-3 text-sm", children: [resolvedPaymentId ? (_jsxs("div", { className: "flex flex-col gap-0.5 sm:flex-row sm:justify-between sm:gap-4", children: [_jsx("dt", { className: "text-gray-500", children: "\u00D6deme no" }), _jsx("dd", { className: "font-mono font-medium text-gray-900 break-all", title: resolvedPaymentId, children: shortenId(resolvedPaymentId) })] })) : null, transactionId ? (_jsxs("div", { className: "flex flex-col gap-0.5 sm:flex-row sm:justify-between sm:gap-4", children: [_jsx("dt", { className: "text-gray-500", children: "\u0130\u015Flem no" }), _jsx("dd", { className: "font-mono font-medium text-gray-900 break-all", title: transactionId, children: shortenId(transactionId) })] })) : null, resolvedOrderId ? (_jsxs("div", { className: "flex flex-col gap-0.5 sm:flex-row sm:justify-between sm:gap-4", children: [_jsx("dt", { className: "text-gray-500", children: "Sipari\u015F no" }), _jsx("dd", { className: "font-medium text-gray-900", children: order?.orderNumber ? `#${order.orderNumber}` : shortenId(resolvedOrderId) })] })) : null, order?.totalPayAmount != null ? (_jsxs("div", { className: "flex flex-col gap-0.5 sm:flex-row sm:justify-between sm:gap-4 border-t border-gray-100 pt-3", children: [_jsx("dt", { className: "text-gray-500", children: "\u00D6denen tutar" }), _jsx("dd", { className: "font-bold tabular-nums text-[#CF0A2C]", children: order.totalPayAmount.toTry() })] })) : null] })] }), order?.items && order.items.length > 0 ? (_jsxs("div", { className: "rounded-2xl border border-gray-100 bg-white p-6 shadow-sm", children: [_jsx("p", { className: "text-xs font-black uppercase tracking-widest text-[#CF0A2C] mb-4", children: "Sipari\u015F \u00F6zeti" }), _jsx("ul", { className: "space-y-4", children: order.items.map(item => {
870
+ const imageSrc = item.productImage
871
+ ? `${process.env.NEXT_PUBLIC_STORAGE_URL}/${item.productImage.replace(/^\//, '')}`
872
+ : null;
873
+ return (_jsxs("li", { className: "flex gap-4", children: [_jsxs("div", { className: "relative h-16 w-16 shrink-0 overflow-hidden rounded-xl border border-gray-100 bg-gray-50", children: [imageSrc ? (_jsx("img", { src: imageSrc, alt: item.productName ?? item.title ?? 'Ürün', className: "h-full w-full object-cover" })) : (_jsx("div", { className: "flex h-full w-full items-center justify-center text-gray-300", children: _jsx(Package, { size: 24 }) })), _jsx("span", { className: "absolute -bottom-1 -right-1 flex h-5 w-5 items-center justify-center rounded-full bg-[#CF0A2C] text-[10px] font-black text-white", children: item.quantity })] }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("p", { className: "text-sm font-medium text-gray-900", children: item.productName ?? item.title }), item.unitName ? _jsx("p", { className: "text-xs text-gray-500 mt-0.5", children: item.unitName }) : null] })] }, item.id));
874
+ }) })] })) : null, _jsxs("div", { className: "flex flex-col gap-3 sm:flex-row", children: [resolvedOrderId ? (_jsx(Link, { href: `/hesabim/siparislerim/${resolvedOrderId}`, className: "inline-flex flex-1 justify-center rounded-xl bg-[#CF0A2C] px-8 py-3.5 text-sm font-black uppercase tracking-widest text-white transition hover:bg-[#a80824]", children: "Sipari\u015Fi g\u00F6r\u00FCnt\u00FCle" })) : null, _jsx(Link, { href: "/", className: "inline-flex flex-1 justify-center rounded-xl border-2 border-gray-200 px-8 py-3.5 text-sm font-black uppercase tracking-widest text-gray-900 transition hover:border-gray-900", children: "Al\u0131\u015Fveri\u015Fe devam" })] })] })), phase === 'error' && (_jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "rounded-2xl border border-gray-100 bg-white p-8 sm:p-10 text-center shadow-sm", children: [_jsx("div", { className: "mx-auto mb-5 inline-flex h-16 w-16 items-center justify-center rounded-full bg-red-50 text-[#CF0A2C]", children: _jsx(XCircle, { size: 32, "aria-hidden": true }) }), _jsx("h1", { className: "text-2xl font-black uppercase tracking-tighter text-gray-900 mb-2", children: displayTitle }), _jsx("p", { className: "text-sm text-gray-600 leading-relaxed", children: displayMessage })] }), (transactionId || resolvedPaymentId) && (_jsxs("div", { className: "rounded-2xl border border-gray-100 bg-white p-6 shadow-sm space-y-3 text-sm", children: [_jsx("p", { className: "text-xs font-black uppercase tracking-widest text-gray-500", children: "Referans bilgileri" }), transactionId ? (_jsxs("div", { className: "flex flex-col gap-0.5 sm:flex-row sm:justify-between", children: [_jsx("span", { className: "text-gray-500", children: "\u0130\u015Flem no" }), _jsx("span", { className: "font-mono text-gray-900 break-all", title: transactionId, children: shortenId(transactionId) })] })) : null, resolvedPaymentId ? (_jsxs("div", { className: "flex flex-col gap-0.5 sm:flex-row sm:justify-between", children: [_jsx("span", { className: "text-gray-500", children: "\u00D6deme no" }), _jsx("span", { className: "font-mono text-gray-900 break-all", title: resolvedPaymentId, children: shortenId(resolvedPaymentId) })] })) : null] })), _jsxs("div", { className: "flex flex-col gap-3 sm:flex-row", children: [_jsx(Link, { href: webReturnUrl, className: "inline-flex flex-1 justify-center rounded-xl bg-[#CF0A2C] px-8 py-3.5 text-sm font-black uppercase tracking-widest text-white transition hover:bg-[#a80824]", children: "\u00D6demeyi tekrar dene" }), _jsx(Link, { href: "/sepet", className: "inline-flex flex-1 justify-center rounded-xl border-2 border-gray-200 px-8 py-3.5 text-sm font-black uppercase tracking-widest text-gray-900 transition hover:border-gray-900", children: "Sepete d\u00F6n" })] })] })), !hasValidStatus && (_jsxs("div", { className: "rounded-2xl border border-gray-100 bg-white p-10 text-center shadow-sm", children: [_jsx("h1", { className: "text-xl font-black uppercase tracking-tighter text-gray-900 mb-3", children: "Ge\u00E7ersiz ba\u011Flant\u0131" }), _jsx("p", { className: "text-sm text-gray-600 mb-8 leading-relaxed", children: "\u00D6deme sonucu bulunamad\u0131. L\u00FCtfen \u00F6deme ad\u0131m\u0131ndan tekrar deneyin." }), _jsx(Link, { href: webReturnUrl, className: "inline-flex justify-center rounded-xl bg-[#CF0A2C] px-8 py-3.5 text-sm font-black uppercase tracking-widest text-white transition hover:bg-[#a80824]", children: "\u00D6demeye git" })] }))] })] }));
875
+ }
876
+ function CheckoutPageInner() {
877
+ const searchParams = useSearchParams();
878
+ const type = searchParams.get('type');
879
+ const statusParam = searchParams.get('status');
880
+ const token = searchParams.get('token');
881
+ const providerParam = searchParams.get('provider');
882
+ const transactionId = searchParams.get('transactionId');
883
+ const isPaymentResult = statusParam === 'success' || statusParam === 'fail' || statusParam === 'error';
884
+ const isPayFlow = type === 'pay' ||
885
+ Boolean(token) ||
886
+ (providerParam === 'garanti' && Boolean(transactionId?.trim()));
887
+ if (isPaymentResult)
888
+ return _jsx(CheckoutResultView, {});
889
+ if (isPayFlow)
890
+ return _jsx(CheckoutPayView, {});
891
+ return _jsx(CheckoutMainView, {});
892
+ }
893
+ function CheckoutMainView() {
646
894
  const { cart, branch } = useRaxon();
647
895
  const [checkoutStep, setCheckoutStep] = useState('contact');
648
896
  const [confirmedContactEmail, setConfirmedContactEmail] = useState('');
@@ -682,3 +930,10 @@ export default function PaymentPage() {
682
930
  return (_jsxs("div", { className: "flex gap-4", children: [_jsxs("div", { className: "relative shrink-0", children: [_jsx("img", { src: item.images?.[0] ? `${process.env.NEXT_PUBLIC_STORAGE_URL}/${item.images[0]}` : 'https://placehold.co/80x80/f3f4f6/9ca3af?text=Ürün', alt: item.product.name, className: "h-20 w-20 rounded-xl border border-gray-100 object-cover" }), _jsx("div", { className: "absolute -bottom-1 -right-1 flex h-6 w-6 items-center justify-center rounded-full bg-[#CF0A2C] text-[11px] font-black text-white shadow-sm", children: item.quantity })] }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("h3", { className: "text-sm font-medium text-gray-900", children: item.product.name }), variantLine ? (_jsx("p", { className: "mt-1 text-xs text-gray-500", children: variantLine })) : null, _jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-2", children: [showListStrike ? (_jsx("span", { className: "text-xs text-gray-400 line-through tabular-nums", children: listGross.toTry() })) : null, _jsx("span", { className: "text-sm font-bold tabular-nums text-[#CF0A2C]", children: linePay.toTry() })] })] })] }, item.id));
683
931
  }) }), _jsxs("div", { className: "space-y-3 border-t border-gray-100 pt-5", children: [_jsxs("div", { className: "flex items-center justify-between text-sm", children: [_jsxs("span", { className: "flex items-center gap-1 text-gray-600", children: ["Ara toplam", _jsx(HelpCircle, { className: "h-4 w-4 text-gray-400" })] }), _jsx("span", { className: "font-semibold tabular-nums text-gray-900", children: (cart?.info?.basePrice?.total ?? 0).toTry() })] }), cart?.info?.tax && cart.info.tax.length > 0 ? (_jsxs("div", { className: "flex items-center justify-between text-sm", children: [_jsx("span", { className: "text-gray-600", children: "KDV" }), _jsx("span", { className: "font-semibold tabular-nums text-gray-900", children: cart.info.tax.reduce((acc, curr) => acc + curr.tax, 0).toTry() })] })) : null, (cart?.info?.delivery?.pay ?? 0) > 0 ? (_jsxs("div", { className: "flex items-center justify-between text-sm", children: [_jsx("span", { className: "text-gray-600", children: "Kargo" }), _jsx("span", { className: "font-semibold tabular-nums text-gray-900", children: cart?.info?.delivery?.pay?.toTry() })] })) : null, (cart?.info?.discount?.pay ?? 0) > 0 ? (_jsxs("div", { className: "flex items-center justify-between text-sm", children: [_jsx("span", { className: "font-bold text-[#CF0A2C]", children: "\u0130ndirim" }), _jsxs("span", { className: "font-semibold tabular-nums text-[#CF0A2C]", children: ["-", cart?.info?.discount?.pay?.toTry()] })] })) : null, _jsxs("div", { className: "flex flex-col gap-2 pt-1", children: [_jsx(CartPromoCodeSection, { variant: "checkout" }), _jsx("button", { type: "button", className: "text-left text-xs font-black uppercase tracking-widest text-gray-600 underline-offset-2 transition-colors hover:text-[#CF0A2C] hover:underline", children: "Sipari\u015F notu ekle" })] }), _jsxs("div", { className: "flex items-center justify-between border-t border-gray-100 pt-5", children: [_jsx("span", { className: "text-sm font-black uppercase tracking-widest text-gray-900", children: "Toplam" }), _jsx("span", { className: "text-xl font-black tabular-nums text-[#CF0A2C]", children: (cart?.info?.payPrice?.pay ?? 0).toTry() })] })] })] }) })] }) })] }));
684
932
  }
933
+ function CheckoutPageFallback() {
934
+ return (_jsx("div", { className: "min-h-screen bg-gray-50 flex items-center justify-center", children: _jsx(Loader2, { className: "h-10 w-10 animate-spin text-[#CF0A2C]", "aria-label": "Y\u00FCkleniyor" }) }));
935
+ }
936
+ export default function PaymentPage({ webReturnUrl = '/sepet/odeme' }) {
937
+ return (_jsx(CheckoutViewContext.Provider, { value: { webReturnUrl }, children: _jsx(Suspense, { fallback: _jsx(CheckoutPageFallback, {}), children: _jsx(CheckoutPageInner, {}) }) }));
938
+ }
939
+ export { PaymentPage as CheckoutView };
package/dist/hook.d.ts CHANGED
@@ -15,5 +15,6 @@ export * from './core/feature/faq/hook/use.faq';
15
15
  export * from './core/feature/form-submit/hook/use.form.submit';
16
16
  export * from './core/feature/promo-code/hook/use.promo.code';
17
17
  export * from './core/feature/attribute/hook/use.attribute';
18
+ export * from './core/feature/brand/hook/use.brand';
18
19
  export * from './core/feature/invoice/hook/use.invoice';
19
20
  //# sourceMappingURL=hook.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../hook.ts"],"names":[],"mappings":"AAAA,cAAc,mCAAmC,CAAC;AAClD,cAAc,mCAAmC,CAAC;AAClD,cAAc,yCAAyC,CAAC;AACxD,cAAc,wCAAwC,CAAC;AACvD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,mDAAmD,CAAC;AAClE,cAAc,yDAAyD,CAAC;AACxE,cAAc,uDAAuD,CAAC;AACtE,cAAc,qCAAqC,CAAC;AACpD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,yCAAyC,CAAC;AACxD,cAAc,iCAAiC,CAAC;AAChD,cAAc,iDAAiD,CAAC;AAChE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,yCAAyC,CAAC"}
1
+ {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../hook.ts"],"names":[],"mappings":"AAAA,cAAc,mCAAmC,CAAC;AAClD,cAAc,mCAAmC,CAAC;AAClD,cAAc,yCAAyC,CAAC;AACxD,cAAc,wCAAwC,CAAC;AACvD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,mDAAmD,CAAC;AAClE,cAAc,yDAAyD,CAAC;AACxE,cAAc,uDAAuD,CAAC;AACtE,cAAc,qCAAqC,CAAC;AACpD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,yCAAyC,CAAC;AACxD,cAAc,iCAAiC,CAAC;AAChD,cAAc,iDAAiD,CAAC;AAChE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,qCAAqC,CAAC;AACpD,cAAc,yCAAyC,CAAC"}
package/dist/hook.js CHANGED
@@ -15,4 +15,5 @@ export * from './core/feature/faq/hook/use.faq';
15
15
  export * from './core/feature/form-submit/hook/use.form.submit';
16
16
  export * from './core/feature/promo-code/hook/use.promo.code';
17
17
  export * from './core/feature/attribute/hook/use.attribute';
18
+ export * from './core/feature/brand/hook/use.brand';
18
19
  export * from './core/feature/invoice/hook/use.invoice';
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export * from './core/raxon.context';
2
2
  export { nexineAxios } from './core/util/nexine.axios';
3
+ export { AnalyticEventProvider, useAnalyticEvent } from './core/feature/analytic-event/analytic.event.context';
4
+ export type { AnalyticEventProviderProps } from './core/feature/analytic-event/analytic.event.context';
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,sDAAsD,CAAC;AAC/G,YAAY,EAAE,0BAA0B,EAAE,MAAM,sDAAsD,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './core/raxon.context';
2
2
  export { nexineAxios } from './core/util/nexine.axios';
3
+ export { AnalyticEventProvider, useAnalyticEvent } from './core/feature/analytic-event/analytic.event.context';