Batch commit of the pending working tree on security/audit-fixes-2026-07. Major areas: - Outbound webhooks / Zapier: schema + signed delivery with retries, public v1 API (REST-hook subscribe/unsubscribe), settings UI, cron drain. - Deploy hardening: email via SMTP2GO (Resend fully removed), verified DB TLS (DATABASE_SSL=require + DATABASE_CA), storage fails loud in production when Spaces is unconfigured instead of silently using ephemeral disk. - Integrations & features (concurrent work): accounting (QuickBooks/Xero), e-signature (DocuSign/Dropbox Sign), PayPal, geocoding/maps, onboarding, expanded legal pages. - DB migrations 0006–0009. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
64 lines
2.4 KiB
TypeScript
64 lines
2.4 KiB
TypeScript
"use client"
|
|
|
|
import { motion } from "framer-motion"
|
|
import { CreditCard, LogIn } from "lucide-react"
|
|
|
|
// Only integrations that genuinely exist in the product are listed here.
|
|
// - Stripe: real payment processing (checkout + rent collection).
|
|
// - Google: real sign-in via OAuth (Better Auth Google provider).
|
|
// We deliberately do NOT advertise connectors we haven't built.
|
|
const TOOLS = [
|
|
{ name: "Stripe", icon: CreditCard, color: "text-violet-400", bg: "bg-violet-500/10 border-violet-500/20", desc: "Payments & rent collection" },
|
|
{ name: "Google", icon: LogIn, color: "text-blue-400", bg: "bg-blue-500/10 border-blue-500/20", desc: "Sign in with Google (OAuth)" },
|
|
]
|
|
|
|
function ToolBadge({ name, icon: Icon, color, bg, desc }: typeof TOOLS[0]) {
|
|
return (
|
|
<motion.div
|
|
whileHover={{ scale: 1.03, y: -2 }}
|
|
transition={{ type: "spring", stiffness: 300 }}
|
|
className={`flex items-center gap-3 rounded-xl border px-5 py-4 ${bg} cursor-default`}
|
|
>
|
|
<div className="flex h-10 w-10 items-center justify-center rounded-lg bg-black/20">
|
|
<Icon className={`h-5 w-5 ${color}`} />
|
|
</div>
|
|
<div>
|
|
<p className="text-sm font-semibold text-white">{name}</p>
|
|
<p className="text-xs text-white/40">{desc}</p>
|
|
</div>
|
|
</motion.div>
|
|
)
|
|
}
|
|
|
|
export function Integrations() {
|
|
return (
|
|
<section className="py-14 sm:py-20 overflow-hidden">
|
|
<div className="mx-auto max-w-3xl px-4 sm:px-6">
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 20 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
className="text-center"
|
|
>
|
|
<p className="text-xs font-semibold uppercase tracking-widest text-indigo-400 mb-3">Integrations</p>
|
|
<h2 className="text-3xl font-bold text-white sm:text-4xl">
|
|
Works with the tools you already use
|
|
</h2>
|
|
<p className="mt-4 text-white/50 max-w-xl mx-auto">
|
|
Take rent payments with Stripe and let landlords sign in with Google — no extra setup, no fragile connectors.
|
|
</p>
|
|
</motion.div>
|
|
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 16 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
className="mt-10 grid gap-4 sm:grid-cols-2 max-w-xl mx-auto"
|
|
>
|
|
{TOOLS.map((t) => <ToolBadge key={t.name} {...t} />)}
|
|
</motion.div>
|
|
</div>
|
|
</section>
|
|
)
|
|
}
|