diff --git a/app/src/pages/MembershipPage.jsx b/app/src/pages/MembershipPage.jsx new file mode 100644 index 0000000..1391d9b --- /dev/null +++ b/app/src/pages/MembershipPage.jsx @@ -0,0 +1,92 @@ +import { useState, useEffect } from 'react'; +import { useNav, useAuth, useToast } from '../../teknav-ui.jsx'; +import { iconNode } from '../../src/lib/icon.jsx'; +import crownIcon from '../../src/assets/icons/crown.svg'; +import bookOpenIcon from '../../src/assets/icons/book-open.svg'; +import gradCapIcon from '../../src/assets/icons/graduation-cap.svg'; + +export function MembershipPage() { + const { navigate } = useNav(); + const { user } = useAuth(); + const toast = useToast(); + const [loading, setLoading] = useState(false); + const [status, setStatus] = useState(null); + + useEffect(() => { + fetch('/api/v1/membership/status', { credentials: 'include' }) + .then((r) => r.ok ? r.json() : null) + .then((d) => d && setStatus(d)) + .catch(() => {}); + }, []); + + const subscribe = async () => { + if (!user) { navigate('/login'); return; } + setLoading(true); + try { + const res = await fetch('/api/v1/membership/subscribe', { + method: 'POST', credentials: 'include', + headers: { 'Content-Type': 'application/json' }, + }); + const data = await res.json(); + if (data.redirectUrl) { + window.location.href = data.redirectUrl; + } else { + toast(data.error === 'payment_unavailable' ? 'درگاه پرداخت در دسترس نیست' : 'خطا در اتصال به درگاه پرداخت'); + setLoading(false); + } + } catch { + toast('خطا در ارتباط با سرور'); + setLoading(false); + } + }; + + const isPremium = status?.active; + + return ( +
+ تجربه بدون تبلیغ، مقالههای اختصاصی، دورههای کوتاه و گزارشهای عمیق برای خوانندگان حرفهای. +
+ + {isPremium && ( +{body}
+