diff --git a/src/components/ProductDetailPage.js b/src/components/ProductDetailPage.js index 8ef6b04..a83168c 100644 --- a/src/components/ProductDetailPage.js +++ b/src/components/ProductDetailPage.js @@ -11,10 +11,60 @@ const ProductDetail = ({ willDo, setWillDo, subscriptions, product, requestLogin const [showSubscriptionSelector, setShowSubscriptionSelector] = useState(false); const [showNamingInput, setShowNamingInput] = useState(false); - const [customName, setCustomName] = useState(''); const navigate = useNavigate(); + const [customName, setCustomName] = useState(''); + const [status, setStatus] = useState('idle'); // 'idle' | 'checking' | 'available' | 'unavailable' | 'error' + + + const tokenCookie = document.cookie.split('; ').find(row => row.startsWith('token=')); + const token = tokenCookie ? tokenCookie.split('=')[1] : ''; + + + // Helper panggil API kamu (GET + token header) + async function checkProductAvailability(name, token) { + const url = `https://bot.kediritechnopark.com/webhook/store_production/check_p_availability?productId=${product.id}&name=${encodeURIComponent(name)}`; + const res = await fetch(url, { + method: 'GET', + headers: { + Authorization: `Bearer ${token}`, + Accept: 'application/json', + }, + }); + if (!res.ok) throw new Error(`Server error ${res.status}`); + const data = await res.json(); // expected: { allowed: true|false } + return Boolean(data.allowed); + } + // Auto check saat user mengetik (debounce) + useEffect(() => { + if (product.unique_name == false) return; + + const name = customName.trim(); + if (!name) { + setStatus('idle'); + return; + } + let cancelled = false; + setStatus('checking'); + + const t = setTimeout(async () => { + try { + const allowed = await checkProductAvailability(name, token); + if (cancelled) return; + setStatus(allowed ? 'available' : 'unavailable'); + } catch (e) { + if (cancelled) return; + setStatus('error'); + } + }, 500); + + return () => { + cancelled = true; + clearTimeout(t); + }; + }, [customName, token]); + const onCheckout = () => { const tokenCookie = document.cookie.split('; ').find(row => row.startsWith('token=')); const token = tokenCookie ? tokenCookie.split('=')[1] : ''; @@ -29,7 +79,7 @@ const ProductDetail = ({ willDo, setWillDo, subscriptions, product, requestLogin subscriptions.some(sub => String(sub.product_id) === String(product.id) || String(sub.product_parent_id) === String(product.id) ); - console.log(hasMatchingSubscription) + // ✅ Check subscription first if (hasMatchingSubscription) { const matching = subscriptions.filter(sub => @@ -86,7 +136,7 @@ const ProductDetail = ({ willDo, setWillDo, subscriptions, product, requestLogin if (product.children && product.children.length > 0) { // don’t redirect yet → go to child selector - setShowSubscriptionSelector(false); + setShowSubscriptionSelector(false); setShowNamingInput(false); setShowChildSelector(true); @@ -126,26 +176,38 @@ const ProductDetail = ({ willDo, setWillDo, subscriptions, product, requestLogin }; useEffect(() => { - if (!product.executeCheckout && willDo === 'checkout') { + if (willDo === 'checkout') { onCheckout(); } - else if (product.children && product.children.length > 0) { - setShowChildSelector(true); - } - else { - - const tokenCookie = document.cookie.split('; ').find(row => row.startsWith('token=')); - const token = tokenCookie ? tokenCookie.split('=')[1] : ''; - const encodedName = encodeURIComponent(product.name); - const itemsParam = JSON.stringify([product.id]); - - window.location.href = `https://checkout.kediritechnopark.com/?token=${token}&itemsId=${itemsParam}&set_name=${encodedName}&redirect_uri=https://kediritechnopark.com/products&redirect_failed=https://kediritechnopark.com`; - } if (setWillDo) setWillDo(''); }, []); const priceColor = product.price === 0 ? '#059669' : '#2563eb'; + // Komponen kecil untuk menampilkan status teks + const StatusLine = () => { + if (status === 'idle') return null; + const map = { + checking: 'Memeriksa…', + available: 'Nama tersedia', + unavailable: 'Nama tidak tersedia', + error: 'Gagal memeriksa. Coba lagi.', + }; + const color = + status === 'available' + ? '#16a34a' + : status === 'unavailable' + ? '#dc2626' + : status === 'checking' + ? '#2563eb' + : '#6b7280'; + return ( +