From 8f4e3cfd4ce30e0a58580893eeffc5497a32c924 Mon Sep 17 00:00:00 2001 From: arsam Date: Fri, 18 Sep 2026 23:25:19 +0330 Subject: [PATCH] Import source: app/src/pages/MembershipPage Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality. --- app/src/pages/MembershipPage.jsx | 92 ++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 app/src/pages/MembershipPage.jsx 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 && ( +
+ ✓ شما در حال حاضر عضو ویژه هستید + {status?.expiresAt && ` — اعتبار تا ${new Date(status.expiresAt).toLocaleDateString('fa-IR')}`} +
+ )} + +
+ {[ + [crownIcon, 'بدون تبلیغ', 'خواندن آرام و سریع‌تر بدون جایگاه‌های تبلیغاتی.'], + [bookOpenIcon, 'محتوای اختصاصی', 'تحلیل‌های عمیق‌تر و پرونده‌های تخصصی برای اعضا.'], + [gradCapIcon, 'تخفیف دوره‌ها', 'دسترسی زودتر و تخفیف روی دوره‌های فارسی تکناو.'], + ].map(([icon, title, body]) => ( +
+
{iconNode(icon)}
+

{title}

+

{body}

+
+ ))} +
+ + {!isPremium && ( +
+
+ سالانه — ۵۰۰,۰۰۰ تومان +
+ +
+ )} +
+
+ ); +}