Donation page update and Subscription update on Admin Dashboard

This commit is contained in:
Koncept Kit
2025-12-11 23:14:23 +07:00
parent f33cdff321
commit 44f2be5d84
6 changed files with 858 additions and 16 deletions

View File

@@ -15,15 +15,16 @@ import {
DialogTitle,
} from '../components/ui/dialog';
import Navbar from '../components/Navbar';
import { CheckCircle, CreditCard, Loader2, Heart } from 'lucide-react';
import { CheckCircle, CreditCard, Loader2, Heart, AlertCircle } from 'lucide-react';
import { toast } from 'sonner';
const Plans = () => {
const { user } = useAuth();
const { user, loading: authLoading } = useAuth();
const navigate = useNavigate();
const [plans, setPlans] = useState([]);
const [loading, setLoading] = useState(true);
const [processingPlanId, setProcessingPlanId] = useState(null);
const [statusInfo, setStatusInfo] = useState(null);
// Amount selection dialog state
const [amountDialogOpen, setAmountDialogOpen] = useState(false);
@@ -34,6 +35,65 @@ const Plans = () => {
fetchPlans();
}, []);
// Status-based access control
useEffect(() => {
if (!authLoading && user) {
// Define status-to-message mapping
const statusMessages = {
pending_email: {
title: "Email Verification Required",
message: "Please verify your email address before selecting a membership plan. Check your inbox for the verification link.",
action: null,
canView: true,
canSubscribe: false
},
pending_approval: {
title: "Application Under Review",
message: "Your application is being reviewed by our admin team. You'll receive an email once approved to proceed with payment.",
action: null,
canView: true,
canSubscribe: false
},
pre_approved: {
title: "Application Under Review",
message: "Your application is being reviewed by our admin team. You'll receive an email once approved to proceed with payment.",
action: null,
canView: true,
canSubscribe: false
},
payment_pending: {
title: null,
message: null,
canView: true,
canSubscribe: true
},
active: {
title: "Already a Member",
message: "You already have an active membership. Visit your dashboard to view your membership details.",
action: "Go to Dashboard",
actionLink: "/dashboard",
canView: true,
canSubscribe: false
},
inactive: {
title: "Membership Inactive",
message: "Your membership has expired. Please select a plan below to renew your membership.",
action: null,
canView: true,
canSubscribe: true
}
};
const userStatus = statusMessages[user.status];
setStatusInfo(userStatus || {
title: "Access Restricted",
message: "Please contact support for assistance with your account.",
canView: true,
canSubscribe: false
});
}
}, [user, authLoading]);
const fetchPlans = async () => {
try {
const response = await api.get('/subscriptions/plans');
@@ -141,6 +201,31 @@ const Plans = () => {
</p>
</div>
{/* Status Banner */}
{statusInfo && statusInfo.title && (
<Card className="max-w-3xl mx-auto mb-8 p-6 bg-gradient-to-r from-[#f1eef9] to-[#DDD8EB]/30 border-2 border-[#664fa3]">
<div className="flex items-start gap-4">
<AlertCircle className="h-6 w-6 text-[#664fa3] flex-shrink-0 mt-1" />
<div className="flex-1">
<h3 className="text-xl font-semibold text-[#422268] mb-2" style={{ fontFamily: "'Inter', sans-serif" }}>
{statusInfo.title}
</h3>
<p className="text-[#664fa3] mb-4" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
{statusInfo.message}
</p>
{statusInfo.action && statusInfo.actionLink && (
<Button
onClick={() => navigate(statusInfo.actionLink)}
className="bg-[#664fa3] text-white hover:bg-[#422268] rounded-full"
>
{statusInfo.action}
</Button>
)}
</div>
</div>
</Card>
)}
{loading ? (
<div className="text-center py-20">
<Loader2 className="h-12 w-12 text-[#664fa3] mx-auto mb-4 animate-spin" />
@@ -220,8 +305,8 @@ const Plans = () => {
{/* CTA Button */}
<Button
onClick={() => handleSelectPlan(plan)}
disabled={processingPlanId === plan.id}
className="w-full bg-[#DDD8EB] text-[#422268] hover:bg-white rounded-full py-6 text-lg font-semibold"
disabled={processingPlanId === plan.id || (statusInfo && !statusInfo.canSubscribe)}
className="w-full bg-[#DDD8EB] text-[#422268] hover:bg-white rounded-full py-6 text-lg font-semibold disabled:opacity-50 disabled:cursor-not-allowed"
data-testid={`subscribe-button-${plan.id}`}
>
{processingPlanId === plan.id ? (
@@ -229,6 +314,8 @@ const Plans = () => {
<Loader2 className="mr-2 h-5 w-5 animate-spin" />
Processing...
</>
) : statusInfo && !statusInfo.canSubscribe ? (
'Approval Required'
) : (
'Choose Amount & Subscribe'
)}