ifixkart-storefront/app/payments/page.tsx

176 lines
6.5 KiB
TypeScript
Raw Permalink 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.

'use client';
import React, { useEffect, useMemo, useState } from 'react';
import Link from 'next/link';
import { CreditCard, Landmark, RefreshCw, ShieldCheck, Smartphone, Wallet } from 'lucide-react';
import { AnnouncementBar } from '@/layout/AnnouncementBar';
import { Header } from '@/layout/Header';
import { Navbar } from '@/layout/Navbar';
import { Footer } from '@/layout/Footer';
import { StickyHeaderSpacer } from '@/components/StickyHeaderSpacer';
import { FloatingButtons } from '@/components/FloatingButtons';
import {
storefrontService,
type FooterInfo,
type StorefrontSettings,
MOCK_FOOTER_INFO,
} from '@/services/api/storefrontService';
import { buildPaymentsDoc } from '@/lib/paymentsContent';
import { PaymentMethodBadges } from '@/components/PaymentMethodBadges';
const HIGHLIGHT_ICONS = {
cards: CreditCard,
upi: Smartphone,
netbanking: Landmark,
wallets: Wallet,
} as const;
function telHref(phone: string): string {
return `tel:${phone.replace(/[^\d+]/g, '')}`;
}
export default function PaymentsPage() {
const [footer, setFooter] = useState<FooterInfo>(MOCK_FOOTER_INFO);
const [settings, setSettings] = useState<StorefrontSettings>({ store_name: 'iFixKart' });
useEffect(() => {
let cancelled = false;
Promise.all([
storefrontService.getFooterInfo(),
storefrontService.getSettings(),
]).then(([info, store]) => {
if (cancelled) return;
if (info) setFooter(info);
if (store) setSettings(store);
});
return () => {
cancelled = true;
};
}, []);
const storeName = settings.store_name || 'iFixKart';
const phone = footer.phone || settings.support_phone || '';
const email = footer.email || '';
const doc = useMemo(() => buildPaymentsDoc(storeName), [storeName]);
const methods = (footer.payment_methods || []).filter((p) => p?.name || p?.icon_url);
return (
<div className="min-h-screen bg-[#F8F9FB] text-[#1E293B] flex flex-col font-sans">
<AnnouncementBar />
<Header />
<StickyHeaderSpacer />
<Navbar />
<main className="flex-grow py-10 pb-20">
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-[900px]">
<h1 className="text-[28px] md:text-[32px] font-bold text-[#1E293B]">
{doc.heading}
</h1>
<p className="text-[14px] text-gray-500 mt-2 max-w-2xl">{doc.intro}</p>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 mt-8">
{doc.highlights.map((item) => {
const Icon =
HIGHLIGHT_ICONS[item.id as keyof typeof HIGHLIGHT_ICONS] || CreditCard;
return (
<div
key={item.id}
className="bg-white border border-gray-200 rounded-xl p-5"
>
<div className="w-10 h-10 rounded-lg bg-primary/10 text-primary flex items-center justify-center mb-3">
<Icon className="w-5 h-5" />
</div>
<h2 className="text-[16px] font-bold text-[#1E293B]">{item.title}</h2>
<p className="text-[13px] text-gray-500 mt-1 leading-relaxed">
{item.detail}
</p>
</div>
);
})}
</div>
<div className="mt-4 bg-white border border-gray-200 rounded-xl p-5">
<h2 className="text-[13px] font-bold text-[#1E293B]">We accept</h2>
<PaymentMethodBadges methods={methods} className="mt-3" />
</div>
<article className="mt-8 bg-white border border-gray-200 rounded-xl overflow-hidden">
<div className="p-6 md:p-8">
<div className="flex items-center gap-2 text-primary mb-6">
<ShieldCheck className="w-5 h-5" />
<p className="text-[13px] font-semibold">
Checkout is processed on a secure payment page. Last updated: 11 September 2026
</p>
</div>
<div className="space-y-7">
{doc.sections.map((section) => (
<section key={section.id} id={section.id}>
<h3 className="text-[16px] font-bold text-[#1E293B] mb-2">
{section.title}
</h3>
{section.paragraphs.map((p, i) => (
<p
key={i}
className="text-[14px] text-gray-600 leading-relaxed mb-3 last:mb-0"
>
{p}
</p>
))}
</section>
))}
</div>
<section className="mt-8 pt-6 border-t border-gray-100">
<div className="flex items-center gap-2 mb-2">
<RefreshCw className="w-4 h-4 text-gray-400" />
<h3 className="text-[16px] font-bold text-[#1E293B]">Need help with a payment?</h3>
</div>
<p className="text-[14px] text-gray-600 leading-relaxed">
Share your order number and payment reference with {storeName} support. You can
also read{' '}
<Link href="/faqs" className="text-primary font-semibold hover:underline">
payment FAQs
</Link>{' '}
or our{' '}
<Link href="/terms" className="text-primary font-semibold hover:underline">
Terms &amp; Policy
</Link>
.
</p>
<div className="mt-3 text-[14px] text-[#1E293B] space-y-1">
{email ? (
<p>
Email:{' '}
<a
href={`mailto:${email}`}
className="text-primary font-semibold hover:underline"
>
{email}
</a>
</p>
) : null}
{phone ? (
<p>
Phone:{' '}
<a
href={telHref(phone)}
className="text-primary font-semibold hover:underline"
>
{phone}
</a>
</p>
) : null}
<p className="text-gray-500">Monday to Saturday, 10:00 AM 6:30 PM</p>
</div>
</section>
</div>
</article>
</div>
</main>
<Footer />
<FloatingButtons />
</div>
);
}