"use client"; import React, { useEffect, useRef, useState } from "react"; import { useAuth } from "@/hooks/useAuth"; import { useRouter } from "next/navigation"; import { apiFetch, API_BASE, resolveToApiOrigin } from "@/lib/api"; import { useSiteSettings } from "@/contexts/SiteSettingsContext"; import { useDismissingState } from "@/hooks/useDismissingState"; type TabId = "organisation" | "branding" | "notifications" | "email" | "legal" | "payments"; const TABS: { id: TabId; label: string }[] = [ { id: "organisation", label: "Organisation" }, { id: "branding", label: "Branding" }, { id: "notifications", label: "Notifications" }, { id: "email", label: "Email" }, { id: "legal", label: "Legal" }, { id: "payments", label: "Payments" }, ]; // Default fee % pre-fill per Yoco plan — the "Up to R50k / Debit" rate, since debit is the // most common consumer card type in SA and small churches likely stay in the lowest volume // tier. Purely a UI convenience for the plan setOrgName(e.target.value)} /> setOrgTagline(e.target.value)} />
setOrgEmail(e.target.value)} /> setOrgPhone(e.target.value)} />
setOrgAddress(e.target.value)} /> setAppBaseUrl(e.target.value)} /> )} {/* ── Branding ─────────────────────────────────────────────────────── */} {activeTab === "branding" && (
setAccentColor(e.target.value)} /> setAccentColor(e.target.value)} />
{currentLogoSrc && (
{/* eslint-disable-next-line @next/next/no-img-element */} Current logo
)} { const file = e.target.files?.[0]; if (!file) return; setLogoFile(file); setLogoPreview(URL.createObjectURL(file)); }} className="text-sm" />
)} {/* ── Notifications ─────────────────────────────────────────────────── */} {activeTab === "notifications" && (
setNotifEmails(e.target.value)} />
)} {/* ── Email / SMTP ──────────────────────────────────────────────────── */} {activeTab === "email" && (

Outgoing email for tickets, payment confirmations, and account notifications. Leave blank to use server environment variables. The password is stored encrypted.

setSmtpHost(e.target.value)} /> setSmtpPort(e.target.value)} />
setSmtpSecure(e.target.checked)} className="rounded" />
setSmtpFrom(e.target.value)} />
setSmtpUser(e.target.value)} autoComplete="username" />
setSmtpPass(e.target.value)} autoComplete="new-password" /> {smtpPassSet && smtpPass === "" && ( ● saved )}
{/* Test connection */}
{smtpTestResult && ( {smtpTestResult.ok ? "✓" : "✗"} {smtpTestResult.message} )}
{smtpTestResult && !smtpTestResult.ok && smtpTestResult.raw && (
Show technical details
{smtpTestResult.raw}
)}
)} {/* ── Legal ─────────────────────────────────────────────────────────── */} {activeTab === "legal" && (

These values populate the Terms of Use and Privacy Policy pages automatically.

setLegalOperatorName(e.target.value)} /> setLegalWebsiteUrl(e.target.value)} /> setLegalEffectiveDate(e.target.value)} />

Information Officer (POPIA)

setLegalIoName(e.target.value)} /> setLegalIoEmail(e.target.value)} />
)} {/* ── Payments (Yoco fees) ─────────────────────────────────────────────── */} {activeTab === "payments" && (

Yoco deducts a processing fee from every card transaction before it reaches your bank account. Reports use the estimate below to show a more accurate payout. Yoco's real rate varies by monthly volume and card type, which this app doesn't track — pick your plan to pre-fill a starting value, then adjust the percentages to match your actual bank statement.

setFeeInPersonPct(e.target.value)} /> setFeeOnlinePct(e.target.value)} />

These fees are always absorbed by the church — they're shown in reports for an accurate payout, never added to what attendees pay.

)}
); }