profit-planet-frontend/src/app/profile/components/userAbo.tsx
DeathKaioken b164f73b43 feat: abo
2026-02-18 11:17:07 +01:00

107 lines
4.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React from 'react'
import { useMyAboStatus } from '../hooks/getAbo'
type Props = {
onAboChange?: (aboId: string | number | null) => void
}
export default function UserAbo({ onAboChange }: Props) {
const { hasAbo, abonement, loading, error } = useMyAboStatus()
React.useEffect(() => {
if (!onAboChange) return
onAboChange(abonement?.id ?? null)
}, [abonement?.id, onAboChange])
if (loading) {
return (
<section className="space-y-4">
<h2 className="text-lg font-semibold text-gray-900">My Subscriptions</h2>
<div className="rounded-md border border-white/60 bg-white/70 backdrop-blur-md p-4 text-sm text-gray-600 shadow-lg">
Loading subscriptions
</div>
</section>
)
}
if (error) {
return (
<section className="space-y-4">
<h2 className="text-lg font-semibold text-gray-900">My Subscriptions</h2>
<div className="rounded-md border border-red-200 bg-red-50/80 backdrop-blur-md p-4 text-sm text-red-700">
{error}
</div>
</section>
)
}
return (
<section className="space-y-4">
<h2 className="text-lg font-semibold text-gray-900">My Subscription</h2>
{(!hasAbo || !abonement) ? (
<div className="rounded-md border border-white/60 bg-white/70 backdrop-blur-md p-4 text-sm text-gray-600 shadow-lg">
You currently dont have an active subscription.
</div>
) : (
<div className="grid gap-3 sm:gap-4">
{(() => {
const status = (abonement.status || 'active') as 'active' | 'paused' | 'canceled'
const nextBilling = abonement.nextBillingAt ? new Date(abonement.nextBillingAt).toLocaleDateString() : '—'
const started = abonement.startedAt ? new Date(abonement.startedAt).toLocaleDateString() : '—'
const coffees = (abonement.pack_breakdown || abonement.items || []).map((it, i) => (
<span
key={i}
className="inline-flex items-center gap-1.5 rounded-full bg-white text-[#1C2B4A] px-3 py-1.5 text-xs font-medium border border-gray-200 shadow-sm ring-1 ring-gray-100 hover:shadow-md hover:ring-gray-200 transition"
>
{/* coffee name */}
<span className="truncate max-w-[14rem]">{it.coffeeName || `Coffee #${it.coffeeId}`}</span>
{/* packs pill — CHANGED COLORS TO MATCH ACTIVE BADGE */}
<span className="inline-flex items-center rounded-full bg-green-100 text-green-800 px-2 py-0.5 text-[10px] font-semibold border border-green-200">
{it.quantity} packs
</span>
</span>
))
return (
<div key={abonement.id} className="rounded-lg border border-white/60 bg-white/70 backdrop-blur-md p-4 shadow-lg">
<div className="flex items-center justify-between">
<div>
<p className="text-sm font-medium text-gray-900">{abonement.name || 'Coffee Subscription'}</p>
<p className="text-xs text-gray-600">
Next billing: {nextBilling}
{' • '}Frequency: {abonement.frequency ?? '—'}
{' • '}Country: {(abonement.country ?? '').toUpperCase() || '—'}
{' • '}Started: {started}
</p>
</div>
<span
className={`inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${
status === 'active'
? 'bg-green-100 text-green-800'
: status === 'paused'
? 'bg-amber-100 text-amber-800'
: 'bg-gray-100 text-gray-700'
}`}
>
{status.charAt(0).toUpperCase() + status.slice(1)}
</span>
</div>
<div className="mt-3">
<p className="text-xs font-semibold text-gray-700 mb-1">Coffees</p>
<div className="flex flex-wrap gap-2">
{coffees}
</div>
</div>
<div className="mt-3 flex gap-2">
<button className="rounded-md border border-gray-300 px-3 py-1.5 text-xs text-gray-700 hover:bg-gray-50">
Current plan
</button>
</div>
</div>
)
})()}
</div>
)}
</section>
)
}