Import source: app/src/pages/MembershipPage
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
@@ -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 (
|
||||||
|
<div style={{ paddingTop: 80, background: '#FAF7F0', minHeight: '100vh', fontFamily: 'Vazirmatn,sans-serif', direction: 'rtl' }}>
|
||||||
|
<div style={{ maxWidth: 900, margin: '0 auto', padding: '44px 24px' }}>
|
||||||
|
<h1 style={{ fontSize: 32, fontWeight: 900, color: '#263238', margin: '0 0 8px' }}>عضویت پریمیوم تکناو</h1>
|
||||||
|
<p style={{ color: '#5F6B6D', lineHeight: 1.9, marginBottom: 28 }}>
|
||||||
|
تجربه بدون تبلیغ، مقالههای اختصاصی، دورههای کوتاه و گزارشهای عمیق برای خوانندگان حرفهای.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{isPremium && (
|
||||||
|
<div style={{ background: '#0F6B7318', border: '1px solid #0F6B7340', borderRadius: 12, padding: '16px 20px', marginBottom: 28, color: '#0F6B73', fontWeight: 700 }}>
|
||||||
|
✓ شما در حال حاضر عضو ویژه هستید
|
||||||
|
{status?.expiresAt && ` — اعتبار تا ${new Date(status.expiresAt).toLocaleDateString('fa-IR')}`}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit,minmax(240px,1fr))', gap: 16, marginBottom: 32 }}>
|
||||||
|
{[
|
||||||
|
[crownIcon, 'بدون تبلیغ', 'خواندن آرام و سریعتر بدون جایگاههای تبلیغاتی.'],
|
||||||
|
[bookOpenIcon, 'محتوای اختصاصی', 'تحلیلهای عمیقتر و پروندههای تخصصی برای اعضا.'],
|
||||||
|
[gradCapIcon, 'تخفیف دورهها', 'دسترسی زودتر و تخفیف روی دورههای فارسی تکناو.'],
|
||||||
|
].map(([icon, title, body]) => (
|
||||||
|
<section key={title} style={{ background: '#fff', border: '1px solid #E4DDD2', borderRadius: 12, padding: 20 }}>
|
||||||
|
<div style={{ fontSize: 24, marginBottom: 8 }}>{iconNode(icon)}</div>
|
||||||
|
<h2 style={{ margin: '0 0 8px', fontSize: 18, color: '#263238' }}>{title}</h2>
|
||||||
|
<p style={{ margin: 0, color: '#5F6B6D', lineHeight: 1.8 }}>{body}</p>
|
||||||
|
</section>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{!isPremium && (
|
||||||
|
<div style={{ textAlign: 'center' }}>
|
||||||
|
<div style={{ fontSize: 13, color: '#5F6B6D', marginBottom: 16 }}>
|
||||||
|
سالانه — ۵۰۰,۰۰۰ تومان
|
||||||
|
</div>
|
||||||
|
<button onClick={subscribe} disabled={loading} style={{
|
||||||
|
background: 'linear-gradient(135deg, #D49A2A, #B8821E)', color: '#fff',
|
||||||
|
border: 'none', borderRadius: 10, padding: '14px 36px', fontSize: 16, fontWeight: 700,
|
||||||
|
cursor: loading ? 'not-allowed' : 'pointer', opacity: loading ? 0.7 : 1,
|
||||||
|
fontFamily: 'Vazirmatn,sans-serif',
|
||||||
|
}}>
|
||||||
|
{loading ? 'در حال اتصال به درگاه...' : 'شروع عضویت ویژه'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user