add review and booking policies
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { formatCurrency, PLAN_PRICES } from '@rentaldrivego/types'
|
||||
import { EMPLOYEE_PROFILE_KEY, apiFetch } from '@/lib/api'
|
||||
import { useDashboardI18n } from '@/components/I18nProvider'
|
||||
@@ -35,6 +35,13 @@ interface ProviderAvailability {
|
||||
paypal: boolean
|
||||
}
|
||||
|
||||
interface PlanFeature {
|
||||
id: string
|
||||
plan: Plan
|
||||
label: string
|
||||
sortOrder: number
|
||||
}
|
||||
|
||||
interface EmployeeProfile {
|
||||
role?: string
|
||||
}
|
||||
@@ -69,6 +76,8 @@ export default function SubscriptionPage() {
|
||||
const currency = 'MAD'
|
||||
const [provider, setProvider] = useState<'AMANPAY' | 'PAYPAL'>('AMANPAY')
|
||||
const [providerAvailability, setProviderAvailability] = useState<ProviderAvailability>({ amanpay: false, paypal: false })
|
||||
const [planPrices, setPlanPrices] = useState<Record<string, Record<string, Record<string, number>>>>(PLAN_PRICES)
|
||||
const [planFeaturesList, setPlanFeaturesList] = useState<PlanFeature[]>([])
|
||||
const [paying, setPaying] = useState(false)
|
||||
const [cancelling, setCancelling] = useState(false)
|
||||
const copy = {
|
||||
@@ -228,6 +237,15 @@ export default function SubscriptionPage() {
|
||||
})
|
||||
}, [router])
|
||||
|
||||
const fetchPlanData = useCallback(async () => {
|
||||
const [prices, features] = await Promise.all([
|
||||
apiFetch<Record<string, Record<string, Record<string, number>>>>('/subscriptions/plans'),
|
||||
apiFetch<PlanFeature[]>('/subscriptions/features'),
|
||||
])
|
||||
if (prices && Object.keys(prices).length > 0) setPlanPrices(prices)
|
||||
if (features) setPlanFeaturesList(features)
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (canViewPage !== true) return
|
||||
|
||||
@@ -235,6 +253,7 @@ export default function SubscriptionPage() {
|
||||
apiFetch<Subscription | null>('/subscriptions/me'),
|
||||
apiFetch<Invoice[]>('/subscriptions/invoices'),
|
||||
apiFetch<ProviderAvailability>('/subscriptions/providers'),
|
||||
fetchPlanData(),
|
||||
])
|
||||
.then(([sub, inv, availability]) => {
|
||||
setProviderAvailability(availability)
|
||||
@@ -250,7 +269,21 @@ export default function SubscriptionPage() {
|
||||
})
|
||||
.catch((err) => setError(err.message))
|
||||
.finally(() => setLoading(false))
|
||||
}, [canViewPage])
|
||||
}, [canViewPage, fetchPlanData])
|
||||
|
||||
useEffect(() => {
|
||||
if (canViewPage !== true) return
|
||||
const handleFocus = () => { fetchPlanData().catch(() => {}) }
|
||||
const handleVisibility = () => {
|
||||
if (document.visibilityState === 'visible') fetchPlanData().catch(() => {})
|
||||
}
|
||||
window.addEventListener('focus', handleFocus)
|
||||
document.addEventListener('visibilitychange', handleVisibility)
|
||||
return () => {
|
||||
window.removeEventListener('focus', handleFocus)
|
||||
document.removeEventListener('visibilitychange', handleVisibility)
|
||||
}
|
||||
}, [canViewPage, fetchPlanData])
|
||||
|
||||
if (canViewPage !== true) {
|
||||
return null
|
||||
@@ -309,7 +342,7 @@ export default function SubscriptionPage() {
|
||||
}
|
||||
}
|
||||
|
||||
const planPrice = PLAN_PRICES[selectedPlan]?.[billingPeriod]?.[currency]
|
||||
const planPrice = planPrices[selectedPlan]?.[billingPeriod]?.[currency]
|
||||
const daysLeft = subscription?.trialEndAt
|
||||
? Math.ceil((new Date(subscription.trialEndAt).getTime() - Date.now()) / 86400000)
|
||||
: null
|
||||
@@ -402,8 +435,9 @@ export default function SubscriptionPage() {
|
||||
{/* Plan cards */}
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
{PLANS.map((plan) => {
|
||||
const price = PLAN_PRICES[plan]?.[billingPeriod]?.[currency]
|
||||
const price = planPrices[plan]?.[billingPeriod]?.[currency]
|
||||
const isActive = subscription?.plan === plan && subscription?.status === 'ACTIVE'
|
||||
const features = planFeaturesList.filter((f) => f.plan === plan)
|
||||
return (
|
||||
<button
|
||||
key={plan}
|
||||
@@ -423,11 +457,17 @@ export default function SubscriptionPage() {
|
||||
<span className="text-sm font-normal text-slate-500">/{billingPeriod === 'MONTHLY' ? copy.perMonthShort : copy.perYearShort}</span>
|
||||
</p>
|
||||
<ul className="mt-3 space-y-1">
|
||||
{copy.planFeatures[plan].map((f) => (
|
||||
<li key={f} className="text-xs text-slate-600 flex items-center gap-1.5">
|
||||
<span className="text-green-500">✓</span> {f}
|
||||
</li>
|
||||
))}
|
||||
{features.length > 0
|
||||
? features.map((f) => (
|
||||
<li key={f.id} className="text-xs text-slate-600 flex items-center gap-1.5">
|
||||
<span className="text-green-500">✓</span> {f.label}
|
||||
</li>
|
||||
))
|
||||
: copy.planFeatures[plan].map((f) => (
|
||||
<li key={f} className="text-xs text-slate-600 flex items-center gap-1.5">
|
||||
<span className="text-green-500">✓</span> {f}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</button>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user