import { useEffect, useState } from 'react'; import type { PointsBalance, PackageInfo } from '../lib/api'; import { getPointsBalance, getPackages, invalidatePointsCache } from '../lib/api'; interface Props { locale: string; dashboard: { brandName: string; navHome: string; navStore: string; navDivination: string; navManual: string; navAuto: string; navHistory: string; navLanguage: string; navSettings: string; logout: string }; store: { title: string; currentPoints: string; pointsLabel: string; rulesTitle: string; rule1: string; rule2: string; rule3: string; popularLabel: string; popularText: string; stepsTitle: string; step1: string; step2: string; step3: string; sideTitle: string; sideDesc: string }; pricing: { p1Name: string; p1Badge: string; p1Price: string; p1Credits: string; p1Desc: string; p2Name: string; p2Price: string; p2Credits: string; p2Desc: string; p3Name: string; p3Badge: string; p3Price: string; p3Credits: string; p3Desc: string; p4Name: string; p4Price: string; p4Credits: string; p4Desc: string; buyNow: string }; } interface PackageDisplay { name: string; badge: string; price: string; credits: string; desc: string; featured: boolean; productCode: string; appStoreProductId: string; starterEligible: boolean; isStarter: boolean; } // Map product codes to display names from pricing translations const PRODUCT_CODE_MAP: Record = { 'new_user_pack': 'p1', // 新人专享包 60积分 'starter_pack': 'p2', // 入门补充包 100积分 'popular_pack': 'p3', // 常用加量包 210积分 'premium_pack': 'p4', // 高频进阶包 415积分 }; function SidePanel({ s }: { s: Props['store'] }) { return (
shopping_cart

{s.sideTitle}

{s.sideDesc}

{s.popularLabel}

{s.popularText}

{s.stepsTitle}

1{s.step1}
2{s.step2}
3{s.step3}
); } export default function StorePage({ store: s, pricing: p }: Props) { const [points, setPoints] = useState(null); const [packages, setPackages] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { setLoading(true); Promise.all([ getPointsBalance(), getPackages(), ]) .then(([pointsData, packagesData]) => { setPoints(pointsData); // Map backend packages to display format const displayPkgs: PackageDisplay[] = packagesData.packages.map((pkg) => { const key = PRODUCT_CODE_MAP[pkg.productCode] || 'p1'; return { name: p[`${key}Name` as keyof typeof p] || pkg.productCode, badge: pkg.isStarter ? (pkg.starterEligible ? p.p1Badge : '') : '', price: p[`${key}Price` as keyof typeof p] || '', credits: `${pkg.credits} ${s.pointsLabel}`, desc: p[`${key}Desc` as keyof typeof p] || '', featured: pkg.productCode === 'popular_pack', // 只有常用加量包是推荐 productCode: pkg.productCode, appStoreProductId: pkg.appStoreProductId, starterEligible: pkg.starterEligible, isStarter: pkg.isStarter, }; }); // Sort by sortOrder displayPkgs.sort((a, b) => { const pkgA = packagesData.packages.find(pkg => pkg.productCode === a.productCode); const pkgB = packagesData.packages.find(pkg => pkg.productCode === b.productCode); return (pkgA?.sortOrder || 0) - (pkgB?.sortOrder || 0); }); setPackages(displayPkgs); }) .catch(() => { // Fallback to static data if API fails setPoints({ balance: 0, frozenBalance: 0, availableBalance: 0, runCost: 20, canRun: false }); setPackages([]); }) .finally(() => setLoading(false)); }, [p, s.pointsLabel]); return (

{s.title}

{/* Top: Points hero + rules */}
account_balance_wallet

{s.currentPoints}

{loading ? '...' : points?.balance ?? 0} {s.pointsLabel}

info {s.rulesTitle}

{s.rule1}

{s.rule2}

{s.rule3}

{/* Mobile: Side panel below rules (visible only on mobile) */}
{/* Body: Packages + side panel (desktop) */}
{loading ? (
{s.sideDesc}
) : (
{packages.map((pkg) => (
{pkg.name} {pkg.badge && {pkg.badge}}

{pkg.price}

{pkg.credits}

{pkg.desc}

))}
)}
{/* Desktop: Side panel (visible only on xl+) */}
); }