Consolidate audit-fixes branch: webhooks, integrations, and deploy hardening
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>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
969d5d4c8a
commit
c9968531e4
@@ -0,0 +1,101 @@
|
||||
import { LegalPage, Section, LegalContact } from "@/components/marketing/legal"
|
||||
import { LEGAL } from "@/lib/legal"
|
||||
|
||||
export const metadata = {
|
||||
title: "Acceptable Use Policy",
|
||||
description: `The rules that govern acceptable use of the ${LEGAL.service} platform and the activities that are prohibited.`,
|
||||
alternates: { canonical: "/acceptable-use" },
|
||||
}
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<LegalPage
|
||||
title="Acceptable Use Policy"
|
||||
subtitle={`This Acceptable Use Policy sets out the rules for using the ${LEGAL.service} platform. It is designed to keep the Service safe, lawful, and reliable for everyone.`}
|
||||
>
|
||||
<Section heading="1. Overview and scope">
|
||||
<p>
|
||||
This Acceptable Use Policy (the <strong>Policy</strong>) applies to all access to and use of the{" "}
|
||||
{LEGAL.service} platform (the <strong>Service</strong>) operated by {LEGAL.entity} (<strong>we</strong>,{" "}
|
||||
<strong>us</strong>, or <strong>our</strong>). It applies to you as the account holder (a landlord or
|
||||
property manager), whom we refer to as <strong>you</strong> or <strong>Customer</strong>, and to anyone who
|
||||
accesses the Service through your account.
|
||||
</p>
|
||||
<p>
|
||||
This Policy forms part of, and is incorporated by reference into, our{" "}
|
||||
<a href="/terms">Terms of Service</a>. Capitalized terms that are not defined here have the meaning given
|
||||
to them in the Terms. Violating this Policy is a violation of the Terms and may result in enforcement action
|
||||
as described below.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="2. Prohibited activities">
|
||||
<p>When using the Service, you must not, and must not permit any third party to:</p>
|
||||
<ul>
|
||||
<li>Use the Service for any illegal, fraudulent, or unauthorized purpose, or in any way that violates applicable law or regulation.</li>
|
||||
<li>Violate any housing, fair-housing, anti-discrimination, or landlord-tenant laws, including using the Service to discriminate against any Tenant or applicant on a protected basis.</li>
|
||||
<li>Harass, threaten, defame, or otherwise engage in abusive or unlawful contact with any <strong>Tenant</strong> or other individual through the Service.</li>
|
||||
<li>Upload, store, or transmit content that is infringing, unlawful, defamatory, obscene, or that contains viruses, malware, or other malicious code.</li>
|
||||
<li>Gain or attempt to gain unauthorized access to the Service, to other accounts, or to any systems or networks connected to the Service, including through scraping or automated bulk access.</li>
|
||||
<li>Probe, scan, or test the vulnerability of the Service, or circumvent, disable, or otherwise interfere with any security features or access controls.</li>
|
||||
<li>Reverse engineer, decompile, or disassemble any part of the Service, or attempt to derive its source code, except to the extent this restriction is prohibited by applicable law.</li>
|
||||
<li>Interfere with, disrupt, or place an unreasonable load on the Service or its infrastructure, or attempt to overload or degrade it.</li>
|
||||
<li>Use the email or notification features of the Service to send spam, unsolicited bulk messages, or any unlawful, deceptive, or harassing communications.</li>
|
||||
<li>Misuse <strong>Tenant</strong> personal data, including using it for any purpose other than the lawful management of the relevant tenancy or in a manner inconsistent with your obligations to that Tenant.</li>
|
||||
</ul>
|
||||
</Section>
|
||||
|
||||
<Section heading="3. Data and privacy responsibilities">
|
||||
<p>
|
||||
You may only upload or process <strong>Tenant</strong> personal data, or any other personal data, for which
|
||||
you have a lawful basis and, where required, the necessary consent. You must not upload special-category or
|
||||
sensitive personal data unless doing so is lawful and appropriate for your purposes.
|
||||
</p>
|
||||
<p>
|
||||
For personal data you process through the Service, you act as the <strong>data controller</strong> and are
|
||||
responsible for complying with applicable data-protection laws. Our respective obligations are set out in
|
||||
our <a href="/dpa">Data Processing Addendum</a>, and our data practices are described in our{" "}
|
||||
<a href="/privacy">Privacy Policy</a>.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="4. Security and vulnerability reporting">
|
||||
<p>
|
||||
You must not conduct any unauthorized security testing against the Service. If you discover a security
|
||||
vulnerability or a potential weakness, please report it responsibly to{" "}
|
||||
<a href={`mailto:${LEGAL.securityEmail}`}>{LEGAL.securityEmail}</a> and give us a reasonable opportunity to
|
||||
investigate and remediate it before disclosing it to others. We appreciate good-faith reports and will not
|
||||
pursue action against researchers who act responsibly and within the law.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="5. Usage limits and fair use">
|
||||
<p>
|
||||
You must respect the usage limits, quotas, and rate limits associated with your plan, and you must use the
|
||||
Service in a manner consistent with fair use. You must not abuse, circumvent, or attempt to exceed any API
|
||||
rate limits, or use automated means to consume a disproportionate share of resources. We may apply
|
||||
technical or contractual measures to protect the Service and other Customers from excessive or abusive use.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="6. Enforcement">
|
||||
<p>
|
||||
We may investigate suspected violations of this Policy and take any action we consider appropriate,
|
||||
including removing or disabling access to offending content, throttling usage, suspending or terminating
|
||||
accounts, and cooperating with law-enforcement authorities or other third parties. We may act with or
|
||||
without notice depending on the severity of the violation and the risk to the Service or others. Suspension
|
||||
and termination are further described in our <a href="/terms">Terms of Service</a>.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="7. Reporting abuse">
|
||||
<p>
|
||||
If you become aware of any use of the Service that violates this Policy, please report it to us so that we
|
||||
can investigate.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<LegalContact email={LEGAL.contactEmail} />
|
||||
</LegalPage>
|
||||
)
|
||||
}
|
||||
@@ -1,20 +1,29 @@
|
||||
import Link from "next/link"
|
||||
import { ArrowRight, Code2, Lock, Zap, BookOpen } from "lucide-react"
|
||||
import { Code2, Lock, Zap, BookOpen, Webhook } from "lucide-react"
|
||||
import { WEBHOOK_EVENTS } from "@/lib/webhooks/events"
|
||||
|
||||
export const metadata = {
|
||||
title: "API Docs — Property Management Network",
|
||||
title: "API Docs",
|
||||
description: "Property Management Network REST API documentation for developers.",
|
||||
alternates: { canonical: "/api-docs" },
|
||||
}
|
||||
|
||||
// The real, deployed origin. Falls back to a placeholder only when the env var
|
||||
// isn't set (e.g. local docs previews).
|
||||
const BASE_URL = `${process.env.NEXT_PUBLIC_APP_URL ?? "https://your-app-url"}/api/v1`
|
||||
|
||||
const ENDPOINTS = [
|
||||
{ method: "GET", path: "/api/properties", desc: "List all properties for the authenticated landlord" },
|
||||
{ method: "POST", path: "/api/properties", desc: "Create a new property" },
|
||||
{ method: "GET", path: "/api/tenants", desc: "List all tenants with lease status" },
|
||||
{ method: "GET", path: "/api/payments", desc: "List rent payments with filters (status, date range)" },
|
||||
{ method: "POST", path: "/api/payments", desc: "Record a new payment manually" },
|
||||
{ method: "GET", path: "/api/maintenance", desc: "List all maintenance requests" },
|
||||
{ method: "POST", path: "/api/maintenance", desc: "Create a maintenance request" },
|
||||
{ method: "PATCH", path: "/api/maintenance/:id", desc: "Update request status or assign to contractor" },
|
||||
{ method: "GET", path: "/properties", desc: "List all properties for the authenticated account" },
|
||||
{ method: "POST", path: "/properties", desc: "Create a new property" },
|
||||
{ method: "GET", path: "/tenants", desc: "List tenants with their unit and lease status" },
|
||||
{ method: "GET", path: "/payments", desc: "List rent payments (filter by status, tenant_id, from/to date range)" },
|
||||
{ method: "POST", path: "/payments", desc: "Record a rent payment" },
|
||||
{ method: "GET", path: "/maintenance", desc: "List maintenance requests (filter by status, priority, property_id)" },
|
||||
{ method: "POST", path: "/maintenance", desc: "Create a maintenance request" },
|
||||
{ method: "PATCH", path: "/maintenance/:id", desc: "Update a maintenance request's status or fields" },
|
||||
{ method: "GET", path: "/webhooks", desc: "List webhook subscriptions" },
|
||||
{ method: "POST", path: "/webhooks", desc: "Create a webhook subscription (Zapier REST Hook subscribe)" },
|
||||
{ method: "DELETE", path: "/webhooks/:id", desc: "Delete a webhook subscription (Zapier REST Hook unsubscribe)" },
|
||||
]
|
||||
|
||||
const METHOD_COLORS: Record<string, string> = {
|
||||
@@ -41,7 +50,7 @@ export default function ApiDocsPage() {
|
||||
</p>
|
||||
<div className="mt-6 inline-flex items-center gap-2 rounded-xl border border-white/10 bg-white/[0.04] px-4 py-2.5">
|
||||
<span className="text-xs font-mono text-white/40">Base URL:</span>
|
||||
<code className="text-xs font-mono text-indigo-300">https://api.propertymanagement.network/v1</code>
|
||||
<code className="text-xs font-mono text-indigo-300">{BASE_URL}</code>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -54,13 +63,15 @@ export default function ApiDocsPage() {
|
||||
</h2>
|
||||
<div className="rounded-2xl border border-white/[0.06] bg-[#111118] p-6">
|
||||
<p className="text-sm text-white/60 mb-4 leading-relaxed">
|
||||
All API requests require a Bearer token in the Authorization header. Generate your API key from
|
||||
the <Link href="/login" className="text-indigo-400 hover:text-indigo-300 underline underline-offset-2">dashboard settings</Link>.
|
||||
All API requests require a Bearer API key in the Authorization header. Keys look like{" "}
|
||||
<code className="text-indigo-300 font-mono text-xs">pmn_live_…</code> and are generated from{" "}
|
||||
<Link href="/login" className="text-indigo-400 hover:text-indigo-300 underline underline-offset-2">Settings → API keys</Link>{" "}
|
||||
inside your dashboard. The plaintext key is shown only once at creation, so store it securely.
|
||||
</p>
|
||||
<div className="rounded-xl bg-[#0a0a12] border border-white/[0.06] p-4 font-mono text-xs text-emerald-300">
|
||||
<p className="text-white/30 mb-1"># Example request</p>
|
||||
<p>curl https://api.propertymanagement.network/v1/properties \</p>
|
||||
<p className="pl-4">-H "Authorization: Bearer YOUR_API_KEY"</p>
|
||||
<p>curl {BASE_URL}/properties \</p>
|
||||
<p className="pl-4">-H "Authorization: Bearer pmn_live_..."</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -91,27 +102,98 @@ export default function ApiDocsPage() {
|
||||
<BookOpen className="h-5 w-5 text-blue-400" /> Response Format
|
||||
</h2>
|
||||
<div className="rounded-2xl border border-white/[0.06] bg-[#111118] p-6">
|
||||
<p className="text-sm text-white/60 mb-4">All responses are JSON. Successful responses return a <code className="text-indigo-300 font-mono text-xs">data</code> field. Errors return an <code className="text-red-300 font-mono text-xs">error</code> field with a message and code.</p>
|
||||
<p className="text-sm text-white/60 mb-4">
|
||||
All responses are JSON. List endpoints return a <code className="text-indigo-300 font-mono text-xs">data</code> array
|
||||
with a <code className="text-indigo-300 font-mono text-xs">count</code>. Single-record and create responses return a{" "}
|
||||
<code className="text-indigo-300 font-mono text-xs">data</code> object (create returns HTTP 201). Errors return an{" "}
|
||||
<code className="text-red-300 font-mono text-xs">error</code> object with a numeric <code className="text-red-300 font-mono text-xs">code</code> and a <code className="text-red-300 font-mono text-xs">message</code>.
|
||||
</p>
|
||||
<div className="rounded-xl bg-[#0a0a12] border border-white/[0.06] p-4 font-mono text-xs leading-relaxed">
|
||||
<p className="text-white/30">// Success</p>
|
||||
<p className="text-white/30">{"// Success (list)"}</p>
|
||||
<p className="text-emerald-300">{"{"} "data": [...], "count": 12 {"}"}</p>
|
||||
<br />
|
||||
<p className="text-white/30">// Error</p>
|
||||
<p className="text-white/30">{"// Success (single / create)"}</p>
|
||||
<p className="text-emerald-300">{"{"} "data": {"{"} ... {"}"} {"}"}</p>
|
||||
<br />
|
||||
<p className="text-white/30">{"// Error"}</p>
|
||||
<p className="text-red-300">{"{"} "error": {"{"} "code": 401, "message": "Unauthorized" {"}"} {"}"}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Coming soon banner */}
|
||||
<div className="rounded-2xl border border-indigo-500/20 bg-indigo-500/5 p-6 text-center">
|
||||
<p className="text-sm font-semibold text-indigo-300 mb-1">Full SDK coming soon</p>
|
||||
<p className="text-xs text-white/40 mb-4">We're building official JavaScript and Python SDKs. Join the waitlist to be notified.</p>
|
||||
<Link
|
||||
href="/signup"
|
||||
className="inline-flex items-center gap-2 rounded-lg bg-indigo-600 px-5 py-2 text-xs font-semibold text-white hover:bg-indigo-500 transition"
|
||||
>
|
||||
Join waitlist <ArrowRight className="h-3.5 w-3.5" />
|
||||
</Link>
|
||||
{/* Webhooks */}
|
||||
<div id="webhooks" className="scroll-mt-24">
|
||||
<h2 className="text-xl font-bold text-white mb-4 flex items-center gap-2">
|
||||
<Webhook className="h-5 w-5 text-emerald-400" /> Webhooks
|
||||
</h2>
|
||||
<div className="space-y-4">
|
||||
<div className="rounded-2xl border border-white/[0.06] bg-[#111118] p-6">
|
||||
<p className="text-sm text-white/60 leading-relaxed">
|
||||
Subscribe to real-time events instead of polling. Add endpoints in{" "}
|
||||
<Link href="/login" className="text-indigo-400 hover:text-indigo-300 underline underline-offset-2">Settings → Webhooks</Link>{" "}
|
||||
(or via the <code className="text-indigo-300 font-mono text-xs">/webhooks</code> API), and we'll POST a
|
||||
signed JSON payload the moment something happens. This is the same mechanism that powers our{" "}
|
||||
<span className="text-white/80 font-medium">Zapier</span> integration — Zapier subscribes and unsubscribes
|
||||
through the <code className="text-indigo-300 font-mono text-xs">POST /webhooks</code> and{" "}
|
||||
<code className="text-indigo-300 font-mono text-xs">DELETE /webhooks/:id</code> endpoints (the REST Hook pattern).
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Events */}
|
||||
<div className="rounded-2xl border border-white/[0.06] bg-[#111118] overflow-hidden">
|
||||
<div className="border-b border-white/[0.06] px-6 py-3">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-white/40">Available events</p>
|
||||
</div>
|
||||
{WEBHOOK_EVENTS.map((ev, i) => (
|
||||
<div
|
||||
key={ev.id}
|
||||
className={`flex items-start gap-4 px-6 py-3 ${i !== WEBHOOK_EVENTS.length - 1 ? "border-b border-white/[0.04]" : ""}`}
|
||||
>
|
||||
<code className="shrink-0 rounded-md bg-emerald-500/10 px-2.5 py-1 text-[11px] font-bold font-mono text-emerald-400">
|
||||
{ev.id}
|
||||
</code>
|
||||
<p className="text-xs text-white/50 mt-0.5">{ev.description}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Payload + signature */}
|
||||
<div className="rounded-2xl border border-white/[0.06] bg-[#111118] p-6">
|
||||
<p className="text-sm font-semibold text-white mb-2">Payload & signature</p>
|
||||
<p className="text-sm text-white/60 mb-4 leading-relaxed">
|
||||
Each request body is a JSON envelope. Every delivery carries an{" "}
|
||||
<code className="text-indigo-300 font-mono text-xs">X-PMN-Signature</code> header —{" "}
|
||||
<code className="text-indigo-300 font-mono text-xs">t=<unix>,v1=<hex></code> — where{" "}
|
||||
<code className="text-indigo-300 font-mono text-xs">v1</code> is the HMAC-SHA256 of{" "}
|
||||
<code className="text-indigo-300 font-mono text-xs">{"`${t}.${rawBody}`"}</code> keyed with your endpoint's
|
||||
signing secret. Recompute it and compare in constant time; reject if the timestamp is stale.
|
||||
</p>
|
||||
<div className="rounded-xl bg-[#0a0a12] border border-white/[0.06] p-4 font-mono text-xs leading-relaxed text-white/70">
|
||||
<p className="text-white/30">{"// POST body"}</p>
|
||||
<p className="text-emerald-300">{"{"}</p>
|
||||
<p className="pl-4">"id": "evt_9f2c…",</p>
|
||||
<p className="pl-4">"event": "tenant.created",</p>
|
||||
<p className="pl-4">"created_at": "2026-07-02T12:00:00.000Z",</p>
|
||||
<p className="pl-4">"data": {"{"} "tenant": {"{"} … {"}"} {"}"}</p>
|
||||
<p className="text-emerald-300">{"}"}</p>
|
||||
<p className="mt-2 text-white/30">{"# Headers"}</p>
|
||||
<p>X-PMN-Event: tenant.created</p>
|
||||
<p>X-PMN-Delivery: <delivery id></p>
|
||||
<p>X-PMN-Signature: t=1751457600,v1=1a2b3c…</p>
|
||||
</div>
|
||||
<p className="text-xs text-white/40 mt-4">
|
||||
Respond with any <span className="text-white/70">2xx</span> to acknowledge. Non-2xx or timeouts are retried
|
||||
with exponential backoff (up to 5 attempts); a test event is available from the dashboard.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* SDK note */}
|
||||
<div className="rounded-2xl border border-white/[0.06] bg-white/[0.02] p-6 text-center">
|
||||
<p className="text-xs text-white/40">
|
||||
Official client SDKs are not yet available. Call the endpoints directly over HTTP with any language or HTTP client.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,77 +1,129 @@
|
||||
import { LegalPage, Section, LegalContact } from "@/components/marketing/legal"
|
||||
import { LEGAL } from "@/lib/legal"
|
||||
|
||||
export const metadata = {
|
||||
title: "Cookie Policy — Property Management Network",
|
||||
description: "How Property Management Network uses cookies and similar tracking technologies.",
|
||||
title: "Cookie Policy",
|
||||
description:
|
||||
"How we use cookies and similar technologies, what we deliberately avoid, and how to manage them in your browser.",
|
||||
alternates: { canonical: "/cookie-policy" },
|
||||
}
|
||||
|
||||
const SECTIONS = [
|
||||
const COOKIE_ROWS: { name: string; type: string; purpose: string; expires: string }[] = [
|
||||
{
|
||||
title: "What are cookies?",
|
||||
body: "Cookies are small text files stored on your device by your browser when you visit a website. They help websites remember your preferences, keep you logged in, and understand how the site is being used.",
|
||||
name: "session",
|
||||
type: "Strictly necessary",
|
||||
purpose: "Keeps you signed in and maintains your authenticated session",
|
||||
expires: "On sign-out or after inactivity",
|
||||
},
|
||||
{
|
||||
title: "Cookies we use",
|
||||
body: "We use the following types of cookies: (1) Essential cookies — required for the application to function, such as session authentication tokens. Without these, you cannot log in. (2) Analytics cookies — we use Vercel Analytics (privacy-preserving, no personal data stored) to understand page performance. (3) Preference cookies — we store your dashboard preferences (dark/light mode, column visibility) in browser localStorage.",
|
||||
name: "preferences (localStorage)",
|
||||
type: "Preference",
|
||||
purpose: "Stores interface preferences such as layout and theme in your browser",
|
||||
expires: "Persistent until cleared",
|
||||
},
|
||||
{
|
||||
title: "Third-party cookies",
|
||||
body: "Stripe may set cookies when you make a payment for fraud prevention and PCI compliance purposes. We do not use advertising, retargeting, or social media tracking cookies.",
|
||||
},
|
||||
{
|
||||
title: "How to control cookies",
|
||||
body: "You can manage cookies through your browser settings. Most browsers allow you to block or delete cookies. Note that blocking essential cookies will prevent you from logging in to Property Management Network. For analytics cookies, you can opt out by enabling the Do Not Track header in your browser.",
|
||||
},
|
||||
{
|
||||
title: "Cookie retention",
|
||||
body: "Session cookies expire when you close your browser. Authentication tokens are refreshed automatically and expire after 7 days of inactivity. Analytics data is retained for 90 days in aggregate, with no individual identifiers stored.",
|
||||
},
|
||||
{
|
||||
title: "Changes to this policy",
|
||||
body: "We may update this Cookie Policy as we add new features. Significant changes will be announced via the in-app notification banner. The date at the bottom of this page reflects the most recent update.",
|
||||
},
|
||||
{
|
||||
title: "Contact",
|
||||
body: "For questions about cookies or this policy, contact us at privacy@propertymanagement.network.",
|
||||
name: "__stripe_*",
|
||||
type: "Strictly necessary (Stripe)",
|
||||
purpose: "Set by Stripe to prevent payment fraud during checkout",
|
||||
expires: "Session or up to one year",
|
||||
},
|
||||
]
|
||||
|
||||
export default function CookiePolicyPage() {
|
||||
export default function Page() {
|
||||
return (
|
||||
<div className="bg-[#09090b] text-white min-h-screen">
|
||||
<div className="mx-auto max-w-3xl px-6 pt-32 pb-24">
|
||||
<div className="mb-10">
|
||||
<h1 className="text-3xl font-bold text-white mb-2">Cookie Policy</h1>
|
||||
<p className="text-xs text-white/30">Last updated: April 2026</p>
|
||||
</div>
|
||||
<LegalPage
|
||||
title="Cookie Policy"
|
||||
subtitle="This policy explains how we use cookies and similar technologies within the Service."
|
||||
>
|
||||
<Section heading="What are cookies">
|
||||
<p>
|
||||
Cookies are small text files that a website stores on your device through your browser.
|
||||
Similar technologies, such as browser <strong>localStorage</strong>, allow a site to store
|
||||
data locally in a comparable way. These technologies help a website keep you signed in,
|
||||
remember your preferences, and operate securely. This policy describes how{" "}
|
||||
<strong>{LEGAL.entity}</strong> uses them within <strong>{LEGAL.service}</strong> (the{" "}
|
||||
<strong>Service</strong>).
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<div className="space-y-8">
|
||||
{SECTIONS.map((s) => (
|
||||
<div key={s.title}>
|
||||
<h2 className="text-base font-semibold text-white mb-2">{s.title}</h2>
|
||||
<p className="text-sm text-white/50 leading-relaxed">{s.body}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<Section heading="Cookies and similar technologies we use">
|
||||
<p>We use only the following limited set of technologies:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Strictly necessary authentication and session cookies</strong>—required to
|
||||
sign you in and to maintain your secure session. The Service cannot function without
|
||||
these.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Preference storage in browser localStorage</strong>—used to remember
|
||||
interface preferences, such as layout and theme, on your device.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Stripe cookies</strong>—set by Stripe during payment to help prevent fraud
|
||||
and to support secure checkout.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Cloudflare Turnstile challenge cookie</strong>—a challenge cookie that may
|
||||
be set on authentication pages to distinguish genuine users from automated bots.
|
||||
</li>
|
||||
</ul>
|
||||
</Section>
|
||||
|
||||
{/* Cookie types summary table */}
|
||||
<div className="mt-10 rounded-2xl border border-white/[0.06] bg-[#111118] overflow-hidden">
|
||||
<div className="px-5 py-3.5 border-b border-white/[0.04]">
|
||||
<p className="text-xs font-semibold uppercase tracking-wider text-white/30">Cookie Summary</p>
|
||||
<Section heading="What we do not use">
|
||||
<p>
|
||||
We do <strong>not</strong> use advertising, retargeting, or cross-site tracking cookies, and
|
||||
we do <strong>not</strong> use third-party analytics cookies. We do not build advertising
|
||||
profiles or share cookie data with advertising networks.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="Managing cookies">
|
||||
<p>
|
||||
Most browsers allow you to view, block, or delete cookies through their settings. Because
|
||||
our authentication and session cookies are <strong>strictly necessary</strong>, blocking
|
||||
them will prevent you from signing in to and using the Service. You can adjust your browser
|
||||
settings at any time to control non-essential storage.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="Retention">
|
||||
<p>
|
||||
<strong>Session</strong> cookies are temporary and are cleared when your session ends, while{" "}
|
||||
<strong>persistent</strong> storage remains on your device until it expires or you remove
|
||||
it. Authentication sessions expire after a period of inactivity, after which you will be
|
||||
asked to sign in again.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="Changes">
|
||||
<p>
|
||||
We may update this Cookie Policy as the Service evolves. When we make material changes, we
|
||||
will update the date shown above. Please review this page periodically to stay informed.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<LegalContact email={LEGAL.privacyEmail} />
|
||||
|
||||
<div className="rounded-2xl border border-white/[0.06] bg-[#111118] overflow-hidden">
|
||||
<div className="px-5 py-3.5 border-b border-white/[0.04]">
|
||||
<p className="text-xs font-semibold uppercase tracking-wider text-white/30">
|
||||
Cookie summary
|
||||
</p>
|
||||
</div>
|
||||
{COOKIE_ROWS.map((row, i, arr) => (
|
||||
<div
|
||||
key={row.name}
|
||||
className={`grid grid-cols-1 gap-1 px-5 py-3.5 text-xs sm:grid-cols-4 sm:gap-4 ${
|
||||
i !== arr.length - 1 ? "border-b border-white/[0.04]" : ""
|
||||
}`}
|
||||
>
|
||||
<code className="font-mono text-indigo-300">{row.name}</code>
|
||||
<span className="text-white/60">{row.type}</span>
|
||||
<span className="text-white/40 sm:col-span-1">{row.purpose}</span>
|
||||
<span className="text-white/40">{row.expires}</span>
|
||||
</div>
|
||||
{[
|
||||
{ name: "pf_session", type: "Essential", purpose: "Authentication session token", expires: "7 days" },
|
||||
{ name: "pf_prefs", type: "Preference", purpose: "Dashboard layout preferences", expires: "1 year" },
|
||||
{ name: "_vercel_*", type: "Analytics", purpose: "Anonymous page performance data", expires: "90 days" },
|
||||
{ name: "__stripe_*", type: "Third-party", purpose: "Stripe payment fraud prevention", expires: "Session" },
|
||||
].map((row, i, arr) => (
|
||||
<div key={row.name} className={`grid grid-cols-4 gap-4 px-5 py-3.5 text-xs ${i !== arr.length - 1 ? "border-b border-white/[0.04]" : ""}`}>
|
||||
<code className="font-mono text-indigo-300">{row.name}</code>
|
||||
<span className="text-white/60">{row.type}</span>
|
||||
<span className="text-white/40 col-span-1">{row.purpose}</span>
|
||||
<span className="text-white/40">{row.expires}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</LegalPage>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
import { LegalPage, Section, Callout, LegalContact } from "@/components/marketing/legal"
|
||||
import { LEGAL } from "@/lib/legal"
|
||||
|
||||
export const metadata = {
|
||||
title: "Disclaimer",
|
||||
description:
|
||||
"Important limitations on the information and outputs provided by the Service, including AI-generated content and financial reports.",
|
||||
alternates: { canonical: "/disclaimer" },
|
||||
}
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<LegalPage
|
||||
title="Disclaimer"
|
||||
subtitle="Please read these important limitations regarding the information and outputs provided by the Service."
|
||||
>
|
||||
<Callout>
|
||||
<strong>{LEGAL.service}</strong> (the <strong>Service</strong>) and all of its outputs are
|
||||
provided for general informational purposes only and do <strong>not</strong> constitute
|
||||
professional advice. You should not rely on them as a substitute for advice from a qualified
|
||||
professional.
|
||||
</Callout>
|
||||
|
||||
<Section heading="General information only">
|
||||
<p>
|
||||
The information made available through the Service is provided by{" "}
|
||||
<strong>{LEGAL.entity}</strong> (<strong>we</strong>, <strong>us</strong>, or{" "}
|
||||
<strong>our</strong>) for general informational purposes. While we aim to keep the Service
|
||||
useful and reliable, we make no representations or warranties as to the accuracy,
|
||||
completeness, or timeliness of any information or output.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="No professional advice">
|
||||
<p>
|
||||
Nothing provided through the Service constitutes <strong>legal</strong>,{" "}
|
||||
<strong>tax</strong>, <strong>financial</strong>, <strong>accounting</strong>, or{" "}
|
||||
<strong>real-estate</strong> advice. You (the account holder, referred to as{" "}
|
||||
<strong>you</strong> or the <strong>Customer</strong>) should consult qualified
|
||||
professionals before making any decision based on the Service.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="AI-generated content">
|
||||
<p>
|
||||
Some features generate content using artificial intelligence. AI-generated content may be{" "}
|
||||
<strong>inaccurate, incomplete, or outdated</strong>, and may not reflect your specific
|
||||
circumstances. You must independently verify any AI-generated content before relying on it.
|
||||
The <strong>Customer</strong> is solely responsible for any decision made using such
|
||||
content.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="Financial figures and reports">
|
||||
<p>
|
||||
Any financial figures, summaries, and reports produced by the Service are provided for
|
||||
convenience only. You should verify them against your own official records. These outputs
|
||||
are <strong>not</strong> a substitute for professional accounting, bookkeeping, or audit
|
||||
services.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="Legal and regulatory compliance">
|
||||
<p>
|
||||
The <strong>Customer</strong> is solely responsible for complying with all applicable laws
|
||||
and regulations, including <strong>housing</strong>, <strong>fair-housing</strong>,{" "}
|
||||
<strong>landlord-tenant</strong>, <strong>tax</strong>, and{" "}
|
||||
<strong>data-protection</strong> laws. The Service is a tool to assist you and does not
|
||||
ensure or guarantee your compliance with any legal obligation.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="Third-party content and links">
|
||||
<p>
|
||||
The Service may include content from, or links to, third-party websites and services. We do
|
||||
not control and are not responsible for the content, accuracy, or practices of any third
|
||||
party. The inclusion of any link or third-party content does not imply endorsement.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="No warranty and limitation of liability">
|
||||
<p>
|
||||
The Service is provided on an <strong>“as is”</strong> and{" "}
|
||||
<strong>“as available”</strong> basis, without warranties of any kind, whether
|
||||
express or implied, to the fullest extent permitted by law. This page is a summary only. The
|
||||
full warranty disclaimer and the limitation of liability, including any liability cap, are
|
||||
set out in our <a href="/terms">Terms of Service</a>, which govern your use of the Service.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<LegalContact email={LEGAL.legalEmail} />
|
||||
</LegalPage>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
import Link from "next/link"
|
||||
import { LegalPage, Section, Callout, LegalContact } from "@/components/marketing/legal"
|
||||
import { LEGAL } from "@/lib/legal"
|
||||
|
||||
export const metadata = {
|
||||
title: "Data Processing Addendum",
|
||||
description: `The Data Processing Addendum governing how ${LEGAL.entity} processes personal data on behalf of Customers using ${LEGAL.service}.`,
|
||||
alternates: { canonical: "/dpa" },
|
||||
}
|
||||
|
||||
export default function DpaPage() {
|
||||
return (
|
||||
<LegalPage
|
||||
title="Data Processing Addendum"
|
||||
subtitle={`This Data Processing Addendum sets out the terms on which ${LEGAL.entity} processes personal data on behalf of Customers of ${LEGAL.service}.`}
|
||||
>
|
||||
<Callout>
|
||||
This DPA forms part of the{" "}
|
||||
<Link href="/terms">Terms of Service</Link> between you and {LEGAL.entity} and
|
||||
applies wherever we process personal data on the Customer’s behalf (for
|
||||
example, Tenant personal data managed through the Service). Where there is a
|
||||
conflict between this DPA and the Terms in respect of the processing of personal
|
||||
data, this DPA prevails.
|
||||
</Callout>
|
||||
|
||||
<Section id="roles" heading="1. Introduction and roles">
|
||||
<p>
|
||||
In this DPA, <strong>Customer</strong> (also <strong>you</strong>) means the
|
||||
account holder using {LEGAL.service}. <strong>We</strong>, <strong>us</strong>,
|
||||
and <strong>our</strong> mean {LEGAL.entity}. A <strong>Tenant</strong> means a
|
||||
data subject whose personal data the Customer manages through the Service.
|
||||
</p>
|
||||
<p>
|
||||
With respect to Tenant personal data and other personal data that the Customer
|
||||
submits to the Service, the Customer acts as the data{" "}
|
||||
<strong>controller</strong> and we act as the data{" "}
|
||||
<strong>processor</strong>, processing that personal data solely on the
|
||||
Customer’s behalf. With respect to the Customer’s own account data
|
||||
(for example, the name and contact details of the account holder and billing
|
||||
information), we act as a <strong>controller</strong> in our own right, as
|
||||
described in our{" "}
|
||||
<Link href="/privacy">Privacy Policy</Link>.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section id="definitions" heading="2. Definitions">
|
||||
<p>Unless otherwise defined here, the following terms have the meanings given below:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Controller</strong> means the entity that determines the purposes and
|
||||
means of the processing of personal data.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Processor</strong> means the entity that processes personal data on
|
||||
behalf of the controller.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Personal Data</strong> means any information relating to an identified
|
||||
or identifiable natural person that is processed under this DPA.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Data Subject</strong> means the identified or identifiable natural
|
||||
person to whom Personal Data relates.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Processing</strong> means any operation performed on Personal Data,
|
||||
whether or not by automated means, including collection, storage, use, and
|
||||
deletion.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Sub-processor</strong> means any third party engaged by us to process
|
||||
Personal Data on behalf of the Customer.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Applicable Data Protection Law</strong> means all laws and regulations
|
||||
applicable to the processing of Personal Data under this DPA, including the EU
|
||||
General Data Protection Regulation (Regulation (EU) 2016/679) (the{" "}
|
||||
<strong>GDPR</strong>) and the United Kingdom General Data Protection
|
||||
Regulation (the <strong>UK GDPR</strong>).
|
||||
</li>
|
||||
<li>
|
||||
<strong>Standard Contractual Clauses</strong> means the standard data
|
||||
protection clauses approved by the European Commission (or the equivalent UK
|
||||
transfer mechanism) for the transfer of Personal Data to processors
|
||||
established in third countries.
|
||||
</li>
|
||||
</ul>
|
||||
</Section>
|
||||
|
||||
<Section id="details" heading="3. Details of the processing">
|
||||
<p>
|
||||
The subject matter, duration, nature, and purpose of the processing, and the
|
||||
types of Personal Data and categories of Data Subjects, are as follows:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Subject matter:</strong> the provision of the Service to the Customer.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Duration:</strong> the term of the agreement between the Customer and
|
||||
us, plus the deletion window described in Section 11.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Nature and purpose:</strong> hosting, storage, and processing of
|
||||
Personal Data as necessary to operate the property-management features of the
|
||||
Service.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Types of Personal Data:</strong> names, contact details, tenancy
|
||||
information, lease information, and payment-status data.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Categories of Data Subjects:</strong> the Customer’s Tenants and
|
||||
contacts.
|
||||
</li>
|
||||
</ul>
|
||||
</Section>
|
||||
|
||||
<Section id="obligations" heading="4. Our obligations as processor">
|
||||
<p>When acting as a processor on the Customer’s behalf, we shall:</p>
|
||||
<ul>
|
||||
<li>
|
||||
process Personal Data only on the Customer’s documented instructions,
|
||||
including with regard to international transfers, unless required to do
|
||||
otherwise by law (in which case we shall inform the Customer of that legal
|
||||
requirement before processing, unless prohibited from doing so);
|
||||
</li>
|
||||
<li>
|
||||
ensure that persons authorized to process Personal Data have committed
|
||||
themselves to confidentiality or are under an appropriate statutory obligation
|
||||
of confidentiality;
|
||||
</li>
|
||||
<li>
|
||||
implement appropriate technical and organizational measures to ensure a level
|
||||
of security appropriate to the risk, in accordance with Article 32 of the
|
||||
GDPR;
|
||||
</li>
|
||||
<li>
|
||||
taking into account the nature of the processing, assist the Customer by
|
||||
appropriate technical and organizational measures in responding to requests
|
||||
from Data Subjects seeking to exercise their rights;
|
||||
</li>
|
||||
<li>
|
||||
assist the Customer in ensuring compliance with its obligations relating to
|
||||
the security of processing, personal-data breach notification, data-protection
|
||||
impact assessments (DPIAs), and prior consultations with supervisory
|
||||
authorities;
|
||||
</li>
|
||||
<li>
|
||||
make available to the Customer the information necessary to demonstrate
|
||||
compliance with the obligations set out in this DPA.
|
||||
</li>
|
||||
</ul>
|
||||
</Section>
|
||||
|
||||
<Section id="subprocessors" heading="5. Sub-processors">
|
||||
<p>
|
||||
The Customer provides a general authorization for us to engage Sub-processors to
|
||||
process Personal Data in connection with the Service. Our current Sub-processors
|
||||
are listed on our{" "}
|
||||
<Link href="/subprocessors">Sub-processors</Link> page.
|
||||
</p>
|
||||
<p>
|
||||
Where we engage a Sub-processor, we impose data-protection obligations that are
|
||||
substantially equivalent to those set out in this DPA. We give the Customer prior
|
||||
notice of any intended addition or replacement of a Sub-processor, and the
|
||||
Customer may object to the change on legitimate data-protection grounds. We remain
|
||||
responsible for the performance of each Sub-processor’s obligations.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section id="transfers" heading="6. International transfers">
|
||||
<p>
|
||||
Where processing of Personal Data involves a transfer to a country outside the
|
||||
European Economic Area or the United Kingdom that has not been recognized as
|
||||
providing an adequate level of protection, we implement an appropriate transfer
|
||||
mechanism, such as the Standard Contractual Clauses or another lawful mechanism
|
||||
recognized under Applicable Data Protection Law.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section id="rights" heading="7. Data-subject rights">
|
||||
<p>
|
||||
Taking into account the nature of the processing, we assist the Customer, as
|
||||
controller, by appropriate technical and organizational measures, insofar as
|
||||
this is possible, in fulfilling the Customer’s obligation to respond to
|
||||
requests from Data Subjects exercising their rights under Applicable Data
|
||||
Protection Law. Where we receive a request directly from a Data Subject in
|
||||
respect of Personal Data processed on the Customer’s behalf, we shall,
|
||||
unless legally required to respond, forward that request to the Customer without
|
||||
undue delay.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section id="breach" heading="8. Personal-data breach">
|
||||
<p>
|
||||
We shall notify the Customer without undue delay after becoming aware of a
|
||||
personal-data breach affecting Personal Data processed on the Customer’s
|
||||
behalf. That notification shall, to the extent available, describe the nature of
|
||||
the breach, its likely consequences, and the measures taken or proposed to
|
||||
address it, so that the Customer can meet its own notification obligations.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section id="audit" heading="9. Audit">
|
||||
<p>
|
||||
We make available to the Customer the information necessary to demonstrate
|
||||
compliance with this DPA and allow for and contribute to audits, including
|
||||
inspections, conducted by the Customer or an auditor mandated by the Customer.
|
||||
Audits are subject to reasonable prior written notice, are conducted during
|
||||
normal business hours in a manner that does not disrupt our operations, and are
|
||||
subject to appropriate confidentiality obligations.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section id="deletion" heading="10. Return and deletion">
|
||||
<p>
|
||||
Upon termination or expiry of the agreement, we shall, at the Customer’s
|
||||
choice, delete or return all Personal Data processed on the Customer’s
|
||||
behalf, and delete existing copies, within {LEGAL.dataDeletionDays} days, save
|
||||
where retention of the Personal Data is required by Applicable Data Protection
|
||||
Law or other law, in which case we shall protect that Personal Data and process
|
||||
it only as necessary for the purpose that requires its retention.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section id="liability" heading="11. Liability">
|
||||
<p>
|
||||
Each party’s liability under or in connection with this DPA is subject to
|
||||
the exclusions and limitations of liability set out in the{" "}
|
||||
<Link href="/terms">Terms of Service</Link>.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section id="execution" heading="12. Execution">
|
||||
<p>
|
||||
This DPA is incorporated into, and forms part of, the Terms of Service and takes
|
||||
effect upon the Customer’s acceptance of the Terms and use of the Service.
|
||||
A countersigned copy of this DPA is available on request by contacting{" "}
|
||||
<a href={`mailto:${LEGAL.dpoEmail}`}>{LEGAL.dpoEmail}</a>.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<LegalContact email={LEGAL.dpoEmail} />
|
||||
</LegalPage>
|
||||
)
|
||||
}
|
||||
+144
-127
@@ -1,145 +1,162 @@
|
||||
import Link from "next/link"
|
||||
import { LegalPage, Section, LegalContact } from "@/components/marketing/legal"
|
||||
import { LEGAL } from "@/lib/legal"
|
||||
|
||||
export const metadata = {
|
||||
title: "GDPR Compliance — Property Management Network",
|
||||
description: "Property Management Network's commitment to GDPR compliance and your data rights as a data subject.",
|
||||
title: "GDPR & Data Rights",
|
||||
description: `How ${LEGAL.entity} complies with the GDPR and UK GDPR, and the data rights available to you as a data subject.`,
|
||||
alternates: { canonical: "/gdpr" },
|
||||
}
|
||||
|
||||
const RIGHTS = [
|
||||
{ right: "Right of access", desc: "You can request a full export of all data we hold about you at any time from your account settings." },
|
||||
{ right: "Right to rectification", desc: "You can update your personal information directly in your account settings, or contact us to correct inaccurate data." },
|
||||
{ right: "Right to erasure", desc: "You can permanently delete your account and all associated data from the settings page. Deletion is irreversible and processed within 30 days." },
|
||||
{ right: "Right to data portability", desc: "You can export your data in machine-readable JSON or CSV format from the dashboard at any time." },
|
||||
{ right: "Right to restriction", desc: "You may request that we restrict processing of your data while a dispute is being resolved." },
|
||||
{ right: "Right to object", desc: "You may object to processing where we rely on legitimate interest. You can opt out of analytics tracking by enabling Do Not Track in your browser." },
|
||||
]
|
||||
|
||||
export default function GdprPage() {
|
||||
return (
|
||||
<div className="bg-[#09090b] text-white min-h-screen">
|
||||
<div className="mx-auto max-w-3xl px-6 pt-32 pb-24">
|
||||
<div className="mb-10">
|
||||
<div className="inline-flex items-center gap-2 rounded-full border border-emerald-500/30 bg-emerald-500/10 px-3 py-1 text-xs font-medium text-emerald-300 mb-4">
|
||||
EU GDPR Compliant
|
||||
</div>
|
||||
<h1 className="text-3xl font-bold text-white mb-2">GDPR Compliance</h1>
|
||||
<p className="text-xs text-white/30">Last updated: April 2026</p>
|
||||
</div>
|
||||
<LegalPage
|
||||
title="GDPR & Data Rights"
|
||||
subtitle={`Our commitment to the General Data Protection Regulation and the UK GDPR, and the rights available to you when ${LEGAL.entity} processes your personal data.`}
|
||||
>
|
||||
<Section id="introduction" heading="1. Introduction">
|
||||
<p>
|
||||
{LEGAL.entity} is committed to protecting personal data and to complying with the
|
||||
General Data Protection Regulation (Regulation (EU) 2016/679) (the{" "}
|
||||
<strong>GDPR</strong>) and the United Kingdom General Data Protection Regulation
|
||||
(the <strong>UK GDPR</strong>) where applicable. This page explains the rights
|
||||
available to individuals whose personal data we process and how those rights may
|
||||
be exercised in connection with {LEGAL.service}.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<div className="space-y-8 text-sm text-white/50 leading-relaxed">
|
||||
<div>
|
||||
<h2 className="text-base font-semibold text-white mb-2">Who we are</h2>
|
||||
<p>
|
||||
Property Management Network ("we", "us", "our") is the data controller for personal data collected through our platform.
|
||||
We are committed to complying with the General Data Protection Regulation (EU) 2016/679 (GDPR)
|
||||
and the UK GDPR where applicable.
|
||||
</p>
|
||||
</div>
|
||||
<Section id="rights" heading="2. Your rights under the GDPR and UK GDPR">
|
||||
<p>
|
||||
Subject to the conditions in Applicable Data Protection Law, you have the
|
||||
following rights:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Right of access</strong> — to obtain confirmation of whether we
|
||||
process your personal data and to receive a copy of it.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Right to rectification</strong> — to have inaccurate personal
|
||||
data corrected and incomplete data completed.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Right to erasure</strong> — to have your personal data deleted in
|
||||
certain circumstances.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Right to restriction of processing</strong> — to limit how we
|
||||
process your personal data in certain circumstances.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Right to data portability</strong> — to receive your personal
|
||||
data in a structured, commonly used, machine-readable format.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Right to object</strong> — to object to processing that relies on
|
||||
our legitimate interests.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Right to withdraw consent</strong> — where processing is based on
|
||||
consent, to withdraw that consent at any time.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Right to lodge a complaint</strong> — to lodge a complaint with a
|
||||
supervisory authority.
|
||||
</li>
|
||||
</ul>
|
||||
</Section>
|
||||
|
||||
<div>
|
||||
<h2 className="text-base font-semibold text-white mb-2">What data we process</h2>
|
||||
<p className="mb-3">We process the following categories of personal data:</p>
|
||||
<ul className="space-y-2">
|
||||
{[
|
||||
"Account data: name, email address, password hash",
|
||||
"Property data: addresses, rental amounts, lease terms you enter",
|
||||
"Tenant data: names, emails, phone numbers you provide as a landlord",
|
||||
"Payment data: payment amounts, dates, and status (card details handled by Stripe, not us)",
|
||||
"Usage data: pages visited, features used — anonymised via Vercel Analytics",
|
||||
].map((item) => (
|
||||
<li key={item} className="flex items-start gap-2">
|
||||
<span className="mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full bg-indigo-400" />
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<Section id="legal-bases" heading="3. Legal bases for processing">
|
||||
<p>
|
||||
We process personal data on one or more of the following legal bases, depending
|
||||
on the context:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Contract</strong> — where processing is necessary to provide the
|
||||
Service you have requested.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Legitimate interests</strong> — where processing is necessary for
|
||||
our legitimate interests, such as securing and improving the Service, provided
|
||||
those interests are not overridden by your rights.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Consent</strong> — where you have given consent for a specific
|
||||
purpose.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Legal obligation</strong> — where processing is necessary to
|
||||
comply with a legal obligation to which we are subject.
|
||||
</li>
|
||||
</ul>
|
||||
</Section>
|
||||
|
||||
<div>
|
||||
<h2 className="text-base font-semibold text-white mb-2">Legal basis for processing</h2>
|
||||
<p>
|
||||
We process personal data on the following legal bases: (1) Contract — data necessary to provide the service you signed up for.
|
||||
(2) Legitimate interest — anonymous analytics to improve the product. (3) Legal obligation — where required by applicable law.
|
||||
We do not process data on the basis of consent for core functionality.
|
||||
</p>
|
||||
</div>
|
||||
<Section id="storage" heading="4. Data storage and international transfers">
|
||||
<p>
|
||||
Personal data is stored in a managed PostgreSQL database hosted on DigitalOcean,
|
||||
with an EU region available. Uploaded files are stored privately in DigitalOcean
|
||||
Spaces. Access isolation is enforced at the application layer: every request is
|
||||
authenticated and scoped to the relevant account so that data is not accessible
|
||||
to other users. Where personal data is transferred to a country that has not been
|
||||
recognized as providing an adequate level of protection, the transfer is protected
|
||||
by Standard Contractual Clauses or another lawful transfer mechanism.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<div>
|
||||
<h2 className="text-base font-semibold text-white mb-2">Data storage and transfers</h2>
|
||||
<p>
|
||||
Your data is stored in Supabase (PostgreSQL), with servers located in the EU (Frankfurt, Germany) by default.
|
||||
Row-level security (RLS) policies ensure only you can access your data. We do not transfer personal data outside
|
||||
the EEA except where strictly necessary for integrated services (e.g. Stripe for payment processing,
|
||||
which is covered by Standard Contractual Clauses).
|
||||
</p>
|
||||
</div>
|
||||
<Section id="retention" heading="5. Data retention">
|
||||
<p>
|
||||
We retain personal data for as long as it is needed to provide the Service. Upon
|
||||
deletion of an account, associated personal data is deleted within{" "}
|
||||
{LEGAL.dataDeletionDays} days, except where a longer retention period is required
|
||||
by law (for example, certain financial records that must be kept for tax
|
||||
purposes).
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<div>
|
||||
<h2 className="text-base font-semibold text-white mb-2">Your rights under GDPR</h2>
|
||||
<p className="mb-5">As a data subject, you have the following rights:</p>
|
||||
<div className="space-y-4">
|
||||
{RIGHTS.map((r) => (
|
||||
<div key={r.right} className="rounded-xl border border-white/[0.06] bg-[#111118] p-4">
|
||||
<p className="text-sm font-semibold text-white mb-1">{r.right}</p>
|
||||
<p className="text-xs text-white/50 leading-relaxed">{r.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<Section id="breach" heading="6. Personal-data breach notification">
|
||||
<p>
|
||||
In the event of a personal-data breach, we notify affected users and, where
|
||||
required, the relevant supervisory authority within 72 hours of becoming aware of
|
||||
the breach, consistent with Article 33 of the GDPR.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<div>
|
||||
<h2 className="text-base font-semibold text-white mb-2">Data retention</h2>
|
||||
<p>
|
||||
We retain account data for as long as your account is active. Upon deletion, all personal data is purged within 30 days,
|
||||
except where retention is required by law (e.g. financial records may be retained for up to 7 years for tax compliance).
|
||||
</p>
|
||||
</div>
|
||||
<Section id="subprocessors" heading="7. Sub-processors">
|
||||
<p>
|
||||
We use vetted third-party sub-processors to help operate the Service. Our current
|
||||
sub-processors are listed on our{" "}
|
||||
<Link href="/subprocessors">Sub-processors</Link> page, and the terms governing
|
||||
their engagement are set out in our{" "}
|
||||
<Link href="/dpa">Data Processing Addendum</Link>.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<div>
|
||||
<h2 className="text-base font-semibold text-white mb-2">Data breach notification</h2>
|
||||
<p>
|
||||
In the event of a data breach affecting your personal data, we will notify affected users within 72 hours of becoming aware,
|
||||
in accordance with GDPR Article 33 obligations.
|
||||
</p>
|
||||
</div>
|
||||
<Section id="exercise" heading="8. How to exercise your rights">
|
||||
<p>
|
||||
To exercise any of the rights described above, contact us at{" "}
|
||||
<a href={`mailto:${LEGAL.privacyEmail}`}>{LEGAL.privacyEmail}</a>. For
|
||||
data-protection matters, you may also contact our data-protection team at{" "}
|
||||
<a href={`mailto:${LEGAL.dpoEmail}`}>{LEGAL.dpoEmail}</a>. You also have the right
|
||||
to lodge a complaint with your local supervisory authority (for example, the
|
||||
Information Commissioner’s Office in the United Kingdom, or your national
|
||||
data-protection authority in the European Union).
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<div>
|
||||
<h2 className="text-base font-semibold text-white mb-2">Sub-processors</h2>
|
||||
<div className="rounded-2xl border border-white/[0.06] bg-[#111118] overflow-hidden">
|
||||
{[
|
||||
{ name: "Supabase", purpose: "Database & file storage", location: "EU (Frankfurt)" },
|
||||
{ name: "Stripe", purpose: "Payment processing", location: "US (SCCs in place)" },
|
||||
{ name: "Resend", purpose: "Transactional email", location: "US (SCCs in place)" },
|
||||
{ name: "Vercel", purpose: "Hosting & edge network", location: "Global (anonymised data only)" },
|
||||
].map((sp, i, arr) => (
|
||||
<div key={sp.name} className={`grid grid-cols-3 gap-4 px-5 py-3.5 text-xs ${i !== arr.length - 1 ? "border-b border-white/[0.04]" : ""}`}>
|
||||
<span className="font-semibold text-white">{sp.name}</span>
|
||||
<span className="text-white/50">{sp.purpose}</span>
|
||||
<span className="text-white/40">{sp.location}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<Section id="roles" heading="9. Roles: controller versus processor">
|
||||
<p>
|
||||
Where you use the Service to manage the personal data of your Tenants, you act as
|
||||
the data <strong>controller</strong> and we act as the data{" "}
|
||||
<strong>processor</strong>, processing that personal data on your documented
|
||||
instructions under our{" "}
|
||||
<Link href="/dpa">Data Processing Addendum</Link>. Where we process your own
|
||||
account data, we act as a <strong>controller</strong>, as described in our{" "}
|
||||
<Link href="/privacy">Privacy Policy</Link>.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<div>
|
||||
<h2 className="text-base font-semibold text-white mb-2">Contact & complaints</h2>
|
||||
<p>
|
||||
To exercise any of your rights or to raise a data protection concern, contact our Data Protection lead at{" "}
|
||||
<a href="mailto:privacy@propertymanagement.network" className="text-indigo-400 hover:text-indigo-300">
|
||||
privacy@propertymanagement.network
|
||||
</a>
|
||||
. You also have the right to lodge a complaint with your local supervisory authority (e.g. the ICO in the UK,
|
||||
or your national DPA in the EU).
|
||||
</p>
|
||||
<p className="mt-4">
|
||||
See also our{" "}
|
||||
<Link href="/privacy" className="text-indigo-400 hover:text-indigo-300">Privacy Policy</Link>{" "}
|
||||
and{" "}
|
||||
<Link href="/cookie-policy" className="text-indigo-400 hover:text-indigo-300">Cookie Policy</Link>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<LegalContact email={LEGAL.dpoEmail} />
|
||||
</LegalPage>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,9 +1,23 @@
|
||||
import { Navbar } from "@/components/marketing/navbar"
|
||||
import { Footer } from "@/components/marketing/footer"
|
||||
import { StructuredData } from "@/components/marketing/structured-data"
|
||||
import { getSession, isAdminUser } from "@/lib/session"
|
||||
import { getMaintenanceMode } from "@/lib/settings"
|
||||
import { MaintenanceScreen } from "@/components/shared/maintenance-screen"
|
||||
|
||||
export default async function MarketingLayout({ children }: { children: React.ReactNode }) {
|
||||
// Site maintenance mode: show the maintenance screen to everyone except admins.
|
||||
const maintenance = await getMaintenanceMode()
|
||||
if (maintenance.enabled) {
|
||||
const session = await getSession()
|
||||
if (!isAdminUser(session?.user)) {
|
||||
return <MaintenanceScreen message={maintenance.message} />
|
||||
}
|
||||
}
|
||||
|
||||
export default function MarketingLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<div className="min-h-screen bg-[#09090b] text-white">
|
||||
<StructuredData />
|
||||
<Navbar />
|
||||
{children}
|
||||
<Footer />
|
||||
|
||||
@@ -7,10 +7,18 @@ import { Testimonials } from "@/components/marketing/testimonials"
|
||||
import { PricingSection } from "@/components/marketing/pricing-section"
|
||||
import { FAQ } from "@/components/marketing/faq"
|
||||
import { CtaBanner } from "@/components/marketing/cta-banner"
|
||||
import { annualEnabled } from "@/lib/stripe/plans"
|
||||
|
||||
export const metadata = {
|
||||
title: "Property Management Network — Property management without the chaos",
|
||||
description: "Track rent, manage maintenance, monitor leases, and keep expenses organised. Built for independent landlords.",
|
||||
title: { absolute: "Property Management Software for Independent Landlords" },
|
||||
description: "Track rent, manage maintenance, monitor leases, and keep expenses organised — all in one dashboard built for independent landlords. Free to start.",
|
||||
alternates: { canonical: "/" },
|
||||
openGraph: {
|
||||
title: "Property management without the chaos",
|
||||
description: "Track rent, manage maintenance, monitor leases, and keep expenses organised — all in one dashboard built for independent landlords. Free to start.",
|
||||
url: "/",
|
||||
type: "website",
|
||||
},
|
||||
}
|
||||
|
||||
export default function LandingPage() {
|
||||
@@ -22,7 +30,7 @@ export default function LandingPage() {
|
||||
<Features />
|
||||
<HowItWorks />
|
||||
<Testimonials />
|
||||
<PricingSection />
|
||||
<PricingSection annualEnabled={annualEnabled()} />
|
||||
<FAQ />
|
||||
<CtaBanner />
|
||||
</>
|
||||
|
||||
@@ -1,17 +1,254 @@
|
||||
export const metadata = { title: "Privacy Policy — Property Management Network" }
|
||||
import { LegalPage, Section, Callout, LegalContact } from "@/components/marketing/legal"
|
||||
import { LEGAL, SUBPROCESSORS } from "@/lib/legal"
|
||||
|
||||
export default function PrivacyPage() {
|
||||
export const metadata = {
|
||||
title: "Privacy Policy",
|
||||
description:
|
||||
"How we collect, use, share, and protect personal data, and the privacy rights available to you under the GDPR and California law.",
|
||||
alternates: { canonical: "/privacy" },
|
||||
}
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<div className="mx-auto max-w-3xl px-6 py-24">
|
||||
<h1 className="text-3xl font-bold text-white mb-8">Privacy Policy</h1>
|
||||
<p className="text-white/50 text-sm leading-relaxed">
|
||||
This Privacy Policy describes how Property Management Network collects, uses, and protects your information.
|
||||
We collect only the data necessary to provide the service (account info, property data you enter,
|
||||
and usage analytics). Your data is stored securely in Supabase with row-level security —
|
||||
no other user can access your records. We do not sell your data to third parties.
|
||||
Files you upload are stored in private buckets and accessible only to you.
|
||||
For questions, contact us at support@propertymanagement.network.
|
||||
</p>
|
||||
</div>
|
||||
<LegalPage
|
||||
title="Privacy Policy"
|
||||
subtitle="This policy explains what personal data we process, why, how we protect it, and the rights you may exercise."
|
||||
>
|
||||
<Section heading="Introduction and scope">
|
||||
<p>
|
||||
<strong>{LEGAL.service}</strong> (the <strong>Service</strong>) is operated by{" "}
|
||||
<strong>{LEGAL.entity}</strong> (<strong>we</strong>, <strong>us</strong>, or{" "}
|
||||
<strong>our</strong>). This Privacy Policy describes how we handle personal data when you
|
||||
(the account holder, referred to as <strong>you</strong> or the{" "}
|
||||
<strong>Customer</strong>—typically a landlord or property manager) use the Service,
|
||||
and how we handle personal data relating to a <strong>Tenant</strong>, meaning an end user
|
||||
whose data the Customer manages within the Service.
|
||||
</p>
|
||||
<p>
|
||||
We act in two distinct roles. We are the <strong>controller</strong> of the account and
|
||||
profile data that relates to your use of the Service. We are a <strong>processor</strong>{" "}
|
||||
of the property, unit, Tenant, lease, and financial records that the Customer enters,
|
||||
because the Customer determines the purposes and means of that processing. Our processing
|
||||
of that data on the Customer’s behalf is governed by our{" "}
|
||||
<a href="/dpa">Data Processing Addendum</a>.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="Information we collect">
|
||||
<p>We collect the following categories of information:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Account and profile data</strong>—such as your name, email address,
|
||||
password credentials, organization details, and preferences.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Portfolio data you enter</strong>—property, unit, Tenant, lease, rent,
|
||||
maintenance, and expense records that the Customer creates or uploads to the Service.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Payment metadata</strong>—billing information processed through Stripe.
|
||||
Stripe handles card details directly; we never receive or store full card numbers.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Usage and device or log data</strong>—such as IP address, browser type,
|
||||
device information, pages accessed, and timestamps generated when you use the Service.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Cookies and similar technologies</strong>—as described in our{" "}
|
||||
<a href="/cookie-policy">Cookie Policy</a>.
|
||||
</li>
|
||||
</ul>
|
||||
</Section>
|
||||
|
||||
<Section heading="How we use information">
|
||||
<p>We use personal data to:</p>
|
||||
<ul>
|
||||
<li>Provide, operate, maintain, and improve the Service;</li>
|
||||
<li>Process billing, subscriptions, and payments through Stripe;</li>
|
||||
<li>Protect the Service through security monitoring and fraud prevention;</li>
|
||||
<li>Respond to support requests and communicate with you about your account;</li>
|
||||
<li>
|
||||
Generate optional AI insights when you choose to use AI features (described below); and
|
||||
</li>
|
||||
<li>Comply with legal obligations and enforce our agreements.</li>
|
||||
</ul>
|
||||
</Section>
|
||||
|
||||
<Section heading="Legal bases for processing">
|
||||
<p>
|
||||
Where the General Data Protection Regulation (GDPR) applies, we rely on the following legal
|
||||
bases:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Performance of a contract</strong>—to provide the Service you have signed
|
||||
up for and to administer your account and billing.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Legitimate interests</strong>—to secure, maintain, and improve the Service
|
||||
and to prevent fraud and abuse, provided such interests are not overridden by your
|
||||
rights.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Consent</strong>—where you have given it, for example when you choose to use
|
||||
optional features such as AI insights or optional sign-in providers.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Legal obligation</strong>—to comply with applicable laws, including the
|
||||
retention of certain financial records.
|
||||
</li>
|
||||
</ul>
|
||||
</Section>
|
||||
|
||||
<Section heading="AI processing">
|
||||
<p>
|
||||
When you choose to use AI features, the relevant portfolio data is sent to{" "}
|
||||
<strong>OpenAI</strong> on a per-request basis in order to generate the requested insight.
|
||||
That data is <strong>not used to train models</strong>. AI features are optional: if you do
|
||||
not use them, no portfolio data is transmitted to OpenAI. See our{" "}
|
||||
<a href="/subprocessors">sub-processors</a> page for further detail.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="How we share information">
|
||||
<p>We share personal data only in the limited circumstances described below.</p>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Service providers and sub-processors</strong>—we engage trusted vendors to
|
||||
host, operate, and support the Service. Our current sub-processors include{" "}
|
||||
{SUBPROCESSORS.map((sp, i) => (
|
||||
<span key={sp.name}>
|
||||
<strong>{sp.name}</strong>
|
||||
{i < SUBPROCESSORS.length - 1 ? ", " : ""}
|
||||
</span>
|
||||
))}
|
||||
. The full, current list is maintained on our{" "}
|
||||
<a href="/subprocessors">sub-processors</a> page.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Legal and safety</strong>—where required to comply with law, respond to
|
||||
lawful requests, or protect the rights, property, or safety of any person.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Business transfers</strong>—in connection with a merger, acquisition,
|
||||
financing, or sale of assets, subject to this policy.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
We do <strong>not</strong> sell or rent personal data.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="International data transfers">
|
||||
<p>
|
||||
Personal data may be processed in countries other than the one in which it was collected,
|
||||
including the United States. Where we transfer personal data across borders, we rely on
|
||||
appropriate safeguards such as the <strong>Standard Contractual Clauses</strong> approved by
|
||||
the European Commission, together with supplementary measures where required.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="Data retention">
|
||||
<p>
|
||||
We retain personal data for as long as your account remains active. Following account
|
||||
deletion, we delete or anonymize personal data within{" "}
|
||||
<strong>{LEGAL.dataDeletionDays} days</strong>, except where a longer retention period is
|
||||
required by law or for legitimate business purposes such as the retention of financial and
|
||||
tax records.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="Security">
|
||||
<p>
|
||||
We protect personal data using encryption in transit and at rest, and we enforce access
|
||||
isolation at the <strong>application layer</strong>: every request is authenticated and
|
||||
scoped to the relevant account, so that one account cannot access another account’s
|
||||
records. Uploaded files are stored privately and served only through authenticated,
|
||||
per-account access. We also employ authentication controls and automated bot protection on
|
||||
our sign-in forms. No method of transmission or storage is <strong>100% secure</strong>, and
|
||||
we cannot guarantee absolute security.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="Your privacy rights">
|
||||
<p>
|
||||
Depending on where you live, you may have the following rights in relation to your personal
|
||||
data.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Rights under the GDPR.</strong> If you are in the European Economic Area or the
|
||||
United Kingdom, you may request:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Access to your personal data;</li>
|
||||
<li>Rectification of inaccurate or incomplete data;</li>
|
||||
<li>Erasure of your data;</li>
|
||||
<li>Restriction of processing;</li>
|
||||
<li>Portability of the data you have provided;</li>
|
||||
<li>To object to certain processing;</li>
|
||||
<li>To withdraw consent where processing is based on consent; and</li>
|
||||
<li>To lodge a complaint with a supervisory authority.</li>
|
||||
</ul>
|
||||
<p>
|
||||
<strong>Rights under California law (CCPA and CPRA).</strong> If you are a California
|
||||
resident, you may request to know, delete, and correct the personal information we hold
|
||||
about you, and to opt out of any sale or sharing of personal information. We do{" "}
|
||||
<strong>not</strong> sell or share personal information for cross-context behavioral
|
||||
advertising.
|
||||
</p>
|
||||
<p>
|
||||
To exercise any of these rights, contact us at{" "}
|
||||
<a href={`mailto:${LEGAL.privacyEmail}`}>{LEGAL.privacyEmail}</a>. We will respond within
|
||||
the timeframe required by applicable law and may need to verify your identity before acting
|
||||
on your request. For further detail on data rights, see our{" "}
|
||||
<a href="/gdpr">GDPR and Data Rights</a> page.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="Notice to Tenants">
|
||||
<p>
|
||||
If you are a <strong>Tenant</strong>, your landlord or property manager (the{" "}
|
||||
<strong>Customer</strong>) is the <strong>controller</strong> of the data held about you
|
||||
within the Service, and we act as a <strong>processor</strong> on their behalf. Please
|
||||
direct requests to access, correct, or delete your data to the Customer who manages your
|
||||
tenancy. We will assist that Customer in responding, as set out in our{" "}
|
||||
<a href="/dpa">Data Processing Addendum</a>.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="Children">
|
||||
<p>
|
||||
The Service is not directed to children, and we do not knowingly collect personal data from
|
||||
children. If you believe a child has provided us with personal data, please contact us so
|
||||
that we can delete it.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="Changes to this policy">
|
||||
<p>
|
||||
We may update this Privacy Policy from time to time. When we make material changes, we will
|
||||
update the date shown above and, where appropriate, provide additional notice. Your
|
||||
continued use of the Service after an update constitutes acceptance of the revised policy.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Callout>
|
||||
This Privacy Policy should be read together with our <a href="/terms">Terms of Service</a>,{" "}
|
||||
<a href="/cookie-policy">Cookie Policy</a>, and{" "}
|
||||
<a href="/dpa">Data Processing Addendum</a>.
|
||||
</Callout>
|
||||
|
||||
<LegalContact email={LEGAL.privacyEmail}>
|
||||
{
|
||||
"If you have questions about this policy or wish to exercise your privacy rights, contact us at "
|
||||
}
|
||||
</LegalContact>
|
||||
<Section heading="Data protection contact">
|
||||
<p>
|
||||
For data-protection matters specifically, you may also contact our data protection team at{" "}
|
||||
<a href={`mailto:${LEGAL.dpoEmail}`}>{LEGAL.dpoEmail}</a>.
|
||||
</p>
|
||||
</Section>
|
||||
</LegalPage>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
import { LegalPage, Section, Callout, LegalContact } from "@/components/marketing/legal"
|
||||
import { LEGAL } from "@/lib/legal"
|
||||
|
||||
export const metadata = {
|
||||
title: "Refund & Cancellation Policy",
|
||||
description: `How subscriptions, cancellations, and refunds work for the ${LEGAL.service} platform.`,
|
||||
alternates: { canonical: "/refund-policy" },
|
||||
}
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<LegalPage
|
||||
title="Refund & Cancellation Policy"
|
||||
subtitle={`This policy explains how billing, cancellations, and refunds work for the ${LEGAL.service} platform. It forms part of our Terms of Service.`}
|
||||
>
|
||||
<Section heading="1. Overview">
|
||||
<p>
|
||||
This Refund & Cancellation Policy (the <strong>Policy</strong>) describes how subscriptions to the{" "}
|
||||
{LEGAL.service} platform (the <strong>Service</strong>), operated by {LEGAL.entity} (<strong>we</strong>,{" "}
|
||||
<strong>us</strong>, or <strong>our</strong>), are billed, how you (the <strong>Customer</strong>) may
|
||||
cancel, and when refunds are available. This Policy forms part of our <a href="/terms">Terms of
|
||||
Service</a>. In the event of any conflict, the Terms of Service govern.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="2. Subscription billing">
|
||||
<p>
|
||||
The Service is offered under the <strong>Starter</strong> (free), <strong>Pro</strong> ($29 per month),{" "}
|
||||
<strong>Landlord</strong> ($59 per month), and <strong>Lifetime</strong> ($199 one-time) plans. Monthly
|
||||
recurring plans are billed in advance at the start of each billing cycle through our payment processor,{" "}
|
||||
<strong>Stripe</strong>, and renew automatically until cancelled.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="3. Cancellation">
|
||||
<p>
|
||||
You may cancel a paid subscription at any time from your billing settings or through the Stripe customer
|
||||
portal. When you cancel a monthly plan, your subscription remains active and you retain access until the end
|
||||
of the billing period you have already paid for; it will not renew for the following period.
|
||||
</p>
|
||||
<p>
|
||||
Because monthly plans are billed in advance, <strong>we do not provide partial-period refunds for the
|
||||
unused portion of a monthly billing cycle</strong> unless required by applicable law or expressly granted by
|
||||
us.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="4. Refunds">
|
||||
<p>
|
||||
Except as expressly stated in this Policy or required by applicable law, monthly subscription fees are
|
||||
generally <strong>non-refundable</strong>. We may, at our sole discretion, grant a refund or credit in
|
||||
individual cases, for example in the event of an extended service outage or a billing error.
|
||||
</p>
|
||||
<p>
|
||||
To request a refund or raise a billing concern, contact us at{" "}
|
||||
<a href={`mailto:${LEGAL.contactEmail}`}>{LEGAL.contactEmail}</a> with your account details and a
|
||||
description of the issue, and we will review your request.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="5. Lifetime plan">
|
||||
<p>
|
||||
The <strong>Lifetime</strong> plan is a single, one-time charge rather than a recurring subscription. The
|
||||
Lifetime plan is refundable if you request a refund within {LEGAL.lifetimeRefundDays} days of the date of
|
||||
purchase. After the {LEGAL.lifetimeRefundDays}-day window has passed, the Lifetime plan is{" "}
|
||||
<strong>non-refundable</strong>, except where a refund is required by applicable law.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="6. Failed payments and past-due accounts">
|
||||
<p>
|
||||
If a scheduled payment fails, we and Stripe may attempt to charge your payment method again over a short
|
||||
period (a process known as dunning). If payment remains unsuccessful and your account becomes past due, we
|
||||
may downgrade your account to the free plan, suspend paid features, or ultimately suspend access to the
|
||||
Service until the outstanding amount is paid.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="7. Price changes">
|
||||
<p>
|
||||
We may change the fees for a plan from time to time. If a price change affects your subscription, we will
|
||||
provide advance notice, and the new price will take effect on your next billing cycle. If you do not wish to
|
||||
accept a price change, you may cancel before it takes effect.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="8. Chargebacks">
|
||||
<p>
|
||||
If you believe you have been charged in error, please contact us at{" "}
|
||||
<a href={`mailto:${LEGAL.contactEmail}`}>{LEGAL.contactEmail}</a> before initiating a chargeback with your
|
||||
bank or card issuer, so that we can resolve the matter quickly. Initiating a chargeback or payment dispute
|
||||
without first contacting us may lead to suspension or termination of your account while the dispute is
|
||||
investigated.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="9. Statutory consumer rights">
|
||||
<p>
|
||||
If you are a consumer in the European Union, the United Kingdom, or another jurisdiction that grants a
|
||||
statutory right of withdrawal or cancellation, you may have rights that are additional to those described in
|
||||
this Policy. <strong>Nothing in this Policy limits or overrides any non-waivable statutory rights you may
|
||||
have as a consumer under applicable law.</strong>
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Callout>
|
||||
<strong>In short:</strong> you may cancel a monthly plan at any time and keep access until the end of the
|
||||
period you have paid for, monthly fees are otherwise non-refundable, and the Lifetime plan is refundable
|
||||
within {LEGAL.lifetimeRefundDays} days of purchase.
|
||||
</Callout>
|
||||
|
||||
<LegalContact email={LEGAL.legalEmail} />
|
||||
</LegalPage>
|
||||
)
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
export const metadata = {
|
||||
title: "System Status — Property Management Network",
|
||||
description: "Real-time status of all Property Management Network services.",
|
||||
}
|
||||
|
||||
const SERVICES = [
|
||||
{ name: "Web Application", status: "operational", uptime: "99.98%" },
|
||||
{ name: "API Gateway", status: "operational", uptime: "99.97%" },
|
||||
{ name: "Database (Supabase)", status: "operational", uptime: "99.99%" },
|
||||
{ name: "Payment Processing (Stripe)", status: "operational", uptime: "99.95%" },
|
||||
{ name: "Email Delivery (Resend)", status: "operational", uptime: "99.96%" },
|
||||
{ name: "File Storage", status: "operational", uptime: "99.99%" },
|
||||
{ name: "Tenant Portal", status: "operational", uptime: "99.97%" },
|
||||
{ name: "Webhook Delivery", status: "operational", uptime: "99.90%" },
|
||||
]
|
||||
|
||||
const INCIDENTS = [
|
||||
{
|
||||
date: "2026-03-28",
|
||||
title: "Resolved: Delayed email notifications",
|
||||
detail: "Email notifications were delayed by up to 12 minutes due to a Resend upstream issue. Fully resolved at 14:32 UTC.",
|
||||
severity: "minor",
|
||||
},
|
||||
{
|
||||
date: "2026-02-14",
|
||||
title: "Resolved: Slow dashboard load times",
|
||||
detail: "Database query optimisations were deployed to fix a slow index scan affecting dashboards with 50+ units. Resolved in 45 minutes.",
|
||||
severity: "minor",
|
||||
},
|
||||
]
|
||||
|
||||
export default function StatusPage() {
|
||||
const allOperational = SERVICES.every((s) => s.status === "operational")
|
||||
|
||||
return (
|
||||
<div className="bg-[#09090b] text-white min-h-screen">
|
||||
<div className="mx-auto max-w-3xl px-6 pt-32 pb-24">
|
||||
{/* Header */}
|
||||
<div className="mb-10">
|
||||
<h1 className="text-3xl font-bold text-white mb-2">System Status</h1>
|
||||
<p className="text-white/40 text-sm">Real-time health of all Property Management Network services.</p>
|
||||
</div>
|
||||
|
||||
{/* Overall status */}
|
||||
<div className={`flex items-center gap-3 rounded-2xl border p-5 mb-8 ${allOperational ? "border-emerald-500/20 bg-emerald-500/5" : "border-red-500/20 bg-red-500/5"}`}>
|
||||
<div className={`relative flex h-3 w-3`}>
|
||||
<span className={`animate-ping absolute inline-flex h-full w-full rounded-full opacity-75 ${allOperational ? "bg-emerald-400" : "bg-red-400"}`} />
|
||||
<span className={`relative inline-flex rounded-full h-3 w-3 ${allOperational ? "bg-emerald-400" : "bg-red-400"}`} />
|
||||
</div>
|
||||
<div>
|
||||
<p className={`font-semibold text-sm ${allOperational ? "text-emerald-300" : "text-red-300"}`}>
|
||||
{allOperational ? "All systems operational" : "Partial outage detected"}
|
||||
</p>
|
||||
<p className="text-xs text-white/30 mt-0.5">Last checked: just now</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Services */}
|
||||
<div className="rounded-2xl border border-white/[0.06] bg-[#111118] overflow-hidden mb-10">
|
||||
<div className="px-5 py-3.5 border-b border-white/[0.04]">
|
||||
<p className="text-xs font-semibold uppercase tracking-wider text-white/30">Services</p>
|
||||
</div>
|
||||
{SERVICES.map((svc, i) => (
|
||||
<div key={svc.name} className={`flex items-center justify-between px-4 sm:px-5 py-3.5 sm:py-4 gap-3 ${i !== SERVICES.length - 1 ? "border-b border-white/[0.04]" : ""}`}>
|
||||
<div className="flex items-center gap-2 min-w-0">
|
||||
<div className={`shrink-0 h-2 w-2 rounded-full ${svc.status === "operational" ? "bg-emerald-400" : svc.status === "degraded" ? "bg-amber-400" : "bg-red-400"}`} />
|
||||
<span className="text-sm text-white/80 truncate">{svc.name}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3 sm:gap-6 shrink-0">
|
||||
<span className="hidden sm:block text-xs text-white/30 tabular-nums">{svc.uptime} uptime</span>
|
||||
<span className={`text-xs font-medium capitalize ${svc.status === "operational" ? "text-emerald-400" : svc.status === "degraded" ? "text-amber-400" : "text-red-400"}`}>
|
||||
{svc.status}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Uptime graph placeholder */}
|
||||
<div className="rounded-2xl border border-white/[0.06] bg-[#111118] p-5 mb-10">
|
||||
<p className="text-xs font-semibold uppercase tracking-wider text-white/30 mb-4">90-day uptime</p>
|
||||
<div className="flex gap-px sm:gap-0.5 h-6 sm:h-8 items-end">
|
||||
{Array.from({ length: 90 }).map((_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="flex-1 rounded-sm bg-emerald-500/70"
|
||||
style={{ height: `${Math.random() > 0.03 ? 100 : Math.floor(Math.random() * 60 + 20)}%` }}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex justify-between mt-2 text-[10px] text-white/20">
|
||||
<span>90 days ago</span>
|
||||
<span>Today</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Incidents */}
|
||||
<div>
|
||||
<h2 className="text-lg font-bold text-white mb-4">Past Incidents</h2>
|
||||
<div className="space-y-3">
|
||||
{INCIDENTS.map((inc) => (
|
||||
<div key={inc.date} className="rounded-2xl border border-white/[0.06] bg-[#111118] p-5">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<span className="text-[10px] font-medium px-2 py-0.5 rounded-full bg-amber-500/10 text-amber-400 uppercase">
|
||||
{inc.severity}
|
||||
</span>
|
||||
<span className="text-xs text-white/30">{inc.date}</span>
|
||||
</div>
|
||||
<p className="text-sm font-semibold text-white mb-1">{inc.title}</p>
|
||||
<p className="text-xs text-white/50 leading-relaxed">{inc.detail}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import Link from "next/link"
|
||||
import { LegalPage, Section, LegalContact } from "@/components/marketing/legal"
|
||||
import { LEGAL, SUBPROCESSORS } from "@/lib/legal"
|
||||
|
||||
export const metadata = {
|
||||
title: "Sub-processors",
|
||||
description: `The third-party sub-processors that ${LEGAL.entity} engages to process personal data on behalf of Customers of ${LEGAL.service}.`,
|
||||
alternates: { canonical: "/subprocessors" },
|
||||
}
|
||||
|
||||
export default function SubprocessorsPage() {
|
||||
return (
|
||||
<LegalPage
|
||||
title="Sub-processors"
|
||||
subtitle={`The third parties that ${LEGAL.entity} engages to process personal data on behalf of Customers of ${LEGAL.service}.`}
|
||||
>
|
||||
<Section id="overview" heading="1. Overview">
|
||||
<p>
|
||||
A <strong>sub-processor</strong> is a third party that we engage to process
|
||||
personal data on behalf of the Customer in connection with the Service. When the
|
||||
Customer uses {LEGAL.service}, the Customer grants us a general authorization to
|
||||
engage the sub-processors listed below under the terms of our{" "}
|
||||
<Link href="/dpa">Data Processing Addendum</Link>. Each sub-processor is bound by
|
||||
data-protection obligations that are substantially equivalent to those we owe the
|
||||
Customer.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section id="current" heading="2. Current sub-processors">
|
||||
<p>
|
||||
The following third parties are the sub-processors currently engaged to process
|
||||
personal data on the Customer’s behalf:
|
||||
</p>
|
||||
<div className="rounded-2xl border border-white/[0.06] bg-[#111118] overflow-hidden">
|
||||
<div className="hidden sm:grid grid-cols-[1.2fr_2fr_1.4fr] gap-4 border-b border-white/[0.08] px-5 py-3 text-xs font-semibold uppercase tracking-wider text-white/40">
|
||||
<span>Sub-processor</span>
|
||||
<span>Purpose</span>
|
||||
<span>Location</span>
|
||||
</div>
|
||||
{SUBPROCESSORS.map((sp, i) => (
|
||||
<div
|
||||
key={sp.name}
|
||||
className={`grid grid-cols-1 gap-1 px-5 py-4 text-sm sm:grid-cols-[1.2fr_2fr_1.4fr] sm:gap-4 ${
|
||||
i !== SUBPROCESSORS.length - 1 ? "border-b border-white/[0.04]" : ""
|
||||
}`}
|
||||
>
|
||||
<span className="text-white/80 font-medium">{sp.name}</span>
|
||||
<span className="text-white/50">{sp.purpose}</span>
|
||||
<span className="text-white/50">{sp.location}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<Section id="changes" heading="3. Changes to this list">
|
||||
<p>
|
||||
We update this page whenever our sub-processors change. The Customer may request
|
||||
to be notified of additions to, or replacements of, our sub-processors, and may
|
||||
object to a change on legitimate data-protection grounds, as described in our{" "}
|
||||
<Link href="/dpa">Data Processing Addendum</Link>.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<LegalContact email={LEGAL.dpoEmail} />
|
||||
</LegalPage>
|
||||
)
|
||||
}
|
||||
@@ -2,15 +2,16 @@ import Link from "next/link"
|
||||
import { Building2, CheckCircle2, Smartphone, Bell, FileText, ArrowRight } from "lucide-react"
|
||||
|
||||
export const metadata = {
|
||||
title: "Tenant Portal — Property Management Network",
|
||||
title: "Tenant Portal",
|
||||
description: "Give your tenants a dedicated portal to pay rent, submit maintenance requests, and view lease details.",
|
||||
alternates: { canonical: "/tenant-portal-info" },
|
||||
}
|
||||
|
||||
const FEATURES = [
|
||||
{ icon: CheckCircle2, color: "text-emerald-400", bg: "bg-emerald-500/10 border-emerald-500/20", title: "Online Rent Payment", desc: "Tenants pay rent securely via Stripe — card or bank transfer. Auto-receipts sent by email." },
|
||||
{ icon: FileText, color: "text-indigo-400", bg: "bg-indigo-500/10 border-indigo-500/20", title: "Lease Documents", desc: "View and download lease agreements, addendums, and move-in checklists anytime." },
|
||||
{ icon: Building2, color: "text-violet-400", bg: "bg-violet-500/10 border-violet-500/20", title: "Maintenance Requests", desc: "Submit maintenance issues with photos. Track status from open → in progress → resolved." },
|
||||
{ icon: Bell, color: "text-amber-400", bg: "bg-amber-500/10 border-amber-500/20", title: "Smart Notifications", desc: "Rent due reminders, request updates, and landlord messages via email or WhatsApp." },
|
||||
{ icon: Bell, color: "text-amber-400", bg: "bg-amber-500/10 border-amber-500/20", title: "Smart Notifications", desc: "Rent due reminders, request updates, and landlord messages delivered by email." },
|
||||
{ icon: Smartphone, color: "text-blue-400", bg: "bg-blue-500/10 border-blue-500/20", title: "Mobile Friendly", desc: "Works perfectly on any device — no app download needed, just a secure link." },
|
||||
{ icon: FileText, color: "text-rose-400", bg: "bg-rose-500/10 border-rose-500/20", title: "Payment History", desc: "Full history of all payments and receipts. Great for tenant records and disputes." },
|
||||
]
|
||||
@@ -98,7 +99,7 @@ export default function TenantPortalInfoPage() {
|
||||
<div className="border-t border-white/[0.06] py-20">
|
||||
<div className="mx-auto max-w-2xl px-6 text-center">
|
||||
<h2 className="text-2xl font-bold text-white mb-4">Ready to give tenants a better experience?</h2>
|
||||
<p className="text-white/40 mb-8">Free plan includes up to 2 properties and unlimited tenant portal access.</p>
|
||||
<p className="text-white/40 mb-8">Free plan includes 1 property and unlimited tenant portal access.</p>
|
||||
<Link
|
||||
href="/signup"
|
||||
className="inline-flex items-center gap-2 rounded-xl bg-indigo-600 px-8 py-3.5 text-sm font-semibold text-white hover:bg-indigo-500 transition-all hover:shadow-lg hover:shadow-indigo-500/25"
|
||||
|
||||
+304
-13
@@ -1,17 +1,308 @@
|
||||
export const metadata = { title: "Terms of Service — Property Management Network" }
|
||||
import { LegalPage, Section, LegalContact } from "@/components/marketing/legal"
|
||||
import { LEGAL } from "@/lib/legal"
|
||||
|
||||
export default function TermsPage() {
|
||||
export const metadata = {
|
||||
title: "Terms of Service",
|
||||
description: `The terms and conditions that govern your access to and use of the ${LEGAL.service} platform.`,
|
||||
alternates: { canonical: "/terms" },
|
||||
}
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<div className="mx-auto max-w-3xl px-6 py-24">
|
||||
<h1 className="text-3xl font-bold text-white mb-8">Terms of Service</h1>
|
||||
<p className="text-white/50 text-sm leading-relaxed">
|
||||
By using Property Management Network you agree to these terms. Property Management Network is provided as-is for property
|
||||
management purposes. You are responsible for the accuracy of data you enter. Subscription fees
|
||||
are billed monthly or as a one-time charge through Stripe. You may cancel at any time —
|
||||
cancellation takes effect at the end of your billing period. Lifetime plans are non-refundable
|
||||
after 14 days. We reserve the right to suspend accounts that violate these terms.
|
||||
For questions, contact us at support@propertymanagement.network.
|
||||
</p>
|
||||
</div>
|
||||
<LegalPage
|
||||
title="Terms of Service"
|
||||
subtitle={`These Terms of Service govern your access to and use of the ${LEGAL.service} platform. Please read them carefully, because they form a binding agreement between you and ${LEGAL.entity}.`}
|
||||
>
|
||||
<Section heading="1. Agreement to these Terms">
|
||||
<p>
|
||||
These Terms of Service (the <strong>Terms</strong>) form a legally binding agreement between you and{" "}
|
||||
{LEGAL.entity} (<strong>we</strong>, <strong>us</strong>, or <strong>our</strong>) and govern your access
|
||||
to and use of the {LEGAL.service} platform, together with all related websites, applications, features,
|
||||
and services (collectively, the <strong>Service</strong>). By creating an account, accessing, or using the
|
||||
Service, you agree to be bound by these Terms. If you do not agree, you must not access or use the Service.
|
||||
</p>
|
||||
<p>
|
||||
You represent that you are at least 18 years of age (or the age of legal majority in your jurisdiction) and
|
||||
are capable of forming a binding contract. If you use the Service on behalf of a company, organization, or
|
||||
other legal entity, you represent and warrant that you have the authority to bind that entity to these
|
||||
Terms, and in that case <strong>you</strong> and <strong>Customer</strong> refer to that entity.
|
||||
</p>
|
||||
<p>
|
||||
Throughout these Terms, <strong>you</strong> or <strong>Customer</strong> means the account holder (a
|
||||
landlord or property manager); <strong>Tenant</strong> means an end user whose data the Customer manages;
|
||||
and <strong>Customer Content</strong> means the data the Customer enters into or uploads to the Service.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="2. Description of the Service">
|
||||
<p>
|
||||
The Service is a software-as-a-service platform that helps landlords and property managers manage rental
|
||||
properties, including features for organizing properties and units, tracking tenancies and leases,
|
||||
recording payments and expenses, storing documents, sending notifications, generating AI-assisted
|
||||
insights, and sharing information with Tenants through a token-based Tenant portal.
|
||||
</p>
|
||||
<p>
|
||||
We may add, modify, or discontinue features of the Service from time to time. The Service is provided as an
|
||||
online tool and is not a substitute for professional legal, financial, tax, accounting, or
|
||||
property-management advice.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="3. Accounts and registration">
|
||||
<p>
|
||||
To use most features of the Service, you must create an account. You agree to provide accurate, current,
|
||||
and complete information during registration and to keep that information up to date. You may register
|
||||
using an email address and password or, where offered, through optional Google sign-in.
|
||||
</p>
|
||||
<p>
|
||||
You are responsible for safeguarding your account credentials and for restricting access to your account.
|
||||
You must keep your password confidential and notify us promptly at{" "}
|
||||
<a href={`mailto:${LEGAL.securityEmail}`}>{LEGAL.securityEmail}</a> if you suspect any unauthorized use of
|
||||
your account. You are responsible for all activity that occurs under your account, whether or not
|
||||
authorized by you, to the extent permitted by applicable law.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="4. Subscriptions, plans, and billing">
|
||||
<p>
|
||||
The Service is offered under several plans: <strong>Starter</strong> (free), <strong>Pro</strong> ($29 per
|
||||
month), <strong>Landlord</strong> ($59 per month), and <strong>Lifetime</strong> ($199 as a one-time
|
||||
charge). The features and limits associated with each plan are described on our pricing page and may be
|
||||
updated from time to time.
|
||||
</p>
|
||||
<p>
|
||||
Paid subscriptions are billed in advance through our payment processor, <strong>Stripe</strong>. By
|
||||
providing a payment method, you authorize us and Stripe to charge the applicable fees, together with any
|
||||
applicable taxes, to that payment method. Monthly subscriptions renew automatically at the end of each
|
||||
billing cycle until cancelled. You are responsible for all taxes, duties, and similar charges associated
|
||||
with your use of the Service, other than taxes based on our net income.
|
||||
</p>
|
||||
<p>
|
||||
We may change our fees or introduce new charges. If we increase the fees for a plan you are subscribed to,
|
||||
we will provide prior notice, and the change will take effect on your next billing cycle. Your continued
|
||||
use of the Service after a price change takes effect constitutes acceptance of the new fees. Cancellations
|
||||
and refunds are governed by our <a href="/refund-policy">Refund & Cancellation Policy</a>.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="5. Customer Content and responsibilities">
|
||||
<p>
|
||||
As between you and us, you retain all rights in and ownership of your <strong>Customer Content</strong>. You
|
||||
grant us a limited, non-exclusive, worldwide license to host, store, process, transmit, display, and
|
||||
otherwise use the Customer Content solely as necessary to provide, secure, and improve the Service and to
|
||||
comply with your instructions and applicable law.
|
||||
</p>
|
||||
<p>
|
||||
You are solely responsible for the accuracy, quality, and legality of your Customer Content and for the
|
||||
means by which you acquired it. Where you enter or upload personal data relating to a{" "}
|
||||
<strong>Tenant</strong> or any other individual, you represent and warrant that you have a lawful basis and,
|
||||
where required, the necessary consent to do so, and that your use of the Service complies with all
|
||||
applicable data-protection, housing, and landlord-tenant laws.
|
||||
</p>
|
||||
<p>
|
||||
For personal data that you process through the Service, you act as the <strong>data controller</strong> and
|
||||
we act as your processor. Our respective obligations are set out in our{" "}
|
||||
<a href="/dpa">Data Processing Addendum</a>, and our general data practices are described in our{" "}
|
||||
<a href="/privacy">Privacy Policy</a>.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="6. Acceptable use">
|
||||
<p>
|
||||
Your use of the Service must comply with our <a href="/acceptable-use">Acceptable Use Policy</a>, which is
|
||||
incorporated into these Terms by reference. Among other things, you must not use the Service for any
|
||||
unlawful purpose, to violate housing, fair-housing, anti-discrimination, or landlord-tenant laws, to harass
|
||||
Tenants, or to compromise the security or integrity of the Service. A violation of the Acceptable Use Policy
|
||||
is a violation of these Terms.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="7. Tenant portal">
|
||||
<p>
|
||||
The Service includes a token-based <strong>Tenant portal</strong> that allows you to share selected
|
||||
information with a Tenant through a secure link. You control what information is shared and with whom, and
|
||||
you are responsible for distributing token links only to the intended recipients and for revoking access
|
||||
when it is no longer appropriate. We are not responsible for information disclosed as a result of your
|
||||
sharing decisions or your handling of token links.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="8. Intellectual property">
|
||||
<p>
|
||||
The Service, including all software, designs, text, graphics, and other materials that we provide (but
|
||||
excluding Customer Content), is owned by us or our licensors and is protected by intellectual-property
|
||||
laws. Subject to your compliance with these Terms, we grant you a limited, revocable, non-exclusive,
|
||||
non-transferable license to access and use the Service for your internal business purposes during the term
|
||||
of your subscription. All rights not expressly granted are reserved.
|
||||
</p>
|
||||
<p>
|
||||
If you choose to provide us with suggestions, ideas, or other feedback about the Service, you grant us a
|
||||
perpetual, irrevocable, worldwide, royalty-free license to use and incorporate that feedback into the
|
||||
Service without any obligation or compensation to you.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="9. Third-party services">
|
||||
<p>
|
||||
The Service relies on and integrates with third-party services, including <strong>Stripe</strong> for
|
||||
payments, <strong>OpenAI</strong> for AI features, <strong>SMTP2GO</strong> for email delivery,{" "}
|
||||
<strong>DigitalOcean</strong> for hosting and storage, and optional <strong>Google</strong> sign-in. Your
|
||||
use of those services may be subject to their own terms and policies. We do not control and are not
|
||||
responsible for third-party services, and we make no warranties regarding them. A current list of the
|
||||
third parties that process personal data on our behalf is available on our{" "}
|
||||
<a href="/subprocessors">Sub-processors</a> page.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="10. AI features">
|
||||
<p>
|
||||
Certain features of the Service use artificial-intelligence models (provided by OpenAI) to generate
|
||||
insights, summaries, and suggestions. <strong>AI-generated outputs may be inaccurate, incomplete, or
|
||||
otherwise unreliable, are provided for informational purposes only, and do not constitute legal, financial,
|
||||
tax, or professional advice.</strong> You are responsible for reviewing and independently verifying any
|
||||
AI-generated output before relying on it. Please review our <a href="/disclaimer">Disclaimer</a> for
|
||||
further information.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="11. Privacy">
|
||||
<p>
|
||||
Our collection and use of personal information in connection with the Service is described in our{" "}
|
||||
<a href="/privacy">Privacy Policy</a>. By using the Service, you acknowledge that you have read and
|
||||
understood our Privacy Policy.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="12. Suspension and termination">
|
||||
<p>
|
||||
You may cancel your subscription or close your account at any time as described in our{" "}
|
||||
<a href="/refund-policy">Refund & Cancellation Policy</a>. We may suspend or terminate your access to
|
||||
the Service, in whole or in part, if you breach these Terms, if your use poses a security, legal, or
|
||||
operational risk, if required by law, or if you fail to pay fees when due.
|
||||
</p>
|
||||
<p>
|
||||
Upon termination, your right to access and use the Service ceases. For a period of{" "}
|
||||
{LEGAL.dataDeletionDays} days following termination, and where technically feasible, you may request an
|
||||
export of your Customer Content, after which we may delete or de-identify it in accordance with our{" "}
|
||||
<a href="/privacy">Privacy Policy</a> and <a href="/dpa">Data Processing Addendum</a>. Provisions that by
|
||||
their nature should survive termination will survive.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="13. Disclaimer of warranties">
|
||||
<p>
|
||||
<strong>
|
||||
THE SERVICE IS PROVIDED ON AN “AS IS” AND “AS AVAILABLE” BASIS, WITHOUT
|
||||
WARRANTIES OF ANY KIND, WHETHER EXPRESS, IMPLIED, OR STATUTORY.
|
||||
</strong>{" "}
|
||||
To the maximum extent permitted by applicable law, we disclaim all warranties, including any implied
|
||||
warranties of merchantability, fitness for a particular purpose, title, and non-infringement, and any
|
||||
warranties arising out of course of dealing or usage of trade.
|
||||
</p>
|
||||
<p>
|
||||
<strong>
|
||||
We do not warrant that the Service will be uninterrupted, secure, error-free, or free of harmful
|
||||
components, or that any AI-generated output or other results obtained through the Service will be accurate
|
||||
or reliable.
|
||||
</strong>{" "}
|
||||
Some jurisdictions do not allow the exclusion of certain warranties, so some of the above exclusions may not
|
||||
apply to you.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="14. Limitation of liability">
|
||||
<p>
|
||||
<strong>
|
||||
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL WE BE LIABLE FOR ANY INDIRECT,
|
||||
INCIDENTAL, SPECIAL, CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE DAMAGES, OR FOR ANY LOSS OF PROFITS, REVENUE,
|
||||
DATA, GOODWILL, OR BUSINESS OPPORTUNITIES, ARISING OUT OF OR RELATING TO THESE TERMS OR THE SERVICE,
|
||||
WHETHER BASED ON CONTRACT, TORT, OR ANY OTHER LEGAL THEORY, EVEN IF WE HAVE BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
</strong>
|
||||
</p>
|
||||
<p>
|
||||
<strong>
|
||||
OUR TOTAL AGGREGATE LIABILITY ARISING OUT OF OR RELATING TO THESE TERMS OR THE SERVICE WILL NOT EXCEED THE
|
||||
GREATER OF (A) THE TOTAL FEES YOU PAID TO US FOR THE SERVICE IN THE TWELVE (12) MONTHS IMMEDIATELY
|
||||
PRECEDING THE EVENT GIVING RISE TO THE CLAIM, OR (B) ONE HUNDRED U.S. DOLLARS (USD 100).
|
||||
</strong>{" "}
|
||||
Some jurisdictions do not allow the limitation or exclusion of liability for certain damages, so some of the
|
||||
above limitations may not apply to you.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="15. Indemnification">
|
||||
<p>
|
||||
You agree to defend, indemnify, and hold harmless {LEGAL.entity} and its officers, directors, employees,
|
||||
and agents from and against any claims, liabilities, damages, losses, and expenses (including reasonable
|
||||
legal fees) arising out of or relating to: (a) your Customer Content; (b) your use of the Service; (c) your
|
||||
violation of these Terms or applicable law; and (d) any claim brought by a Tenant or other third party
|
||||
arising out of your use of the Service or your handling of their data.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="16. Changes to the Service and to these Terms">
|
||||
<p>
|
||||
We may modify, update, or discontinue the Service or any part of it at any time. We may also revise these
|
||||
Terms from time to time. When we make material changes, we will provide notice by reasonable means, such as
|
||||
by posting the updated Terms with a new effective date or by notifying you through the Service or by email.
|
||||
Your continued use of the Service after the changes take effect constitutes acceptance of the revised
|
||||
Terms.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="17. Governing law and dispute resolution">
|
||||
<p>
|
||||
These Terms and any dispute arising out of or relating to them or the Service are governed by the laws of{" "}
|
||||
{LEGAL.governingLaw}, without regard to its conflict-of-laws principles. Subject to the arbitration
|
||||
provision below, the parties submit to the exclusive jurisdiction and venue of {LEGAL.forum}.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Informal resolution.</strong> Before initiating any formal proceeding, you agree to first contact
|
||||
us at <a href={`mailto:${LEGAL.legalEmail}`}>{LEGAL.legalEmail}</a> and to attempt in good faith to resolve
|
||||
the dispute informally. Most concerns can be resolved this way.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Binding arbitration and class-action waiver.</strong> To the fullest extent permitted by applicable
|
||||
law, any dispute that is not resolved informally will be settled by final and binding arbitration on an
|
||||
individual basis, rather than in court, except that either party may bring an individual claim in
|
||||
small-claims court. <strong>YOU AND WE EACH WAIVE ANY RIGHT TO A JURY TRIAL AND TO PARTICIPATE IN A CLASS,
|
||||
COLLECTIVE, OR REPRESENTATIVE ACTION.</strong> Arbitration will be conducted by a recognized arbitration
|
||||
body under its applicable rules, and judgment on the award may be entered in any court of competent
|
||||
jurisdiction.
|
||||
</p>
|
||||
<p>
|
||||
Nothing in this section limits any statutory rights that cannot be waived under the law that applies to you.
|
||||
Consumers in certain jurisdictions may have non-waivable rights to bring claims in their local courts or
|
||||
before their local authorities, and this section does not override those rights.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section heading="18. Miscellaneous">
|
||||
<p>
|
||||
These Terms, together with the policies incorporated by reference (including the{" "}
|
||||
<a href="/acceptable-use">Acceptable Use Policy</a>, <a href="/privacy">Privacy Policy</a>,{" "}
|
||||
<a href="/dpa">Data Processing Addendum</a>, and <a href="/refund-policy">Refund & Cancellation
|
||||
Policy</a>), constitute the entire agreement between you and us regarding the Service and supersede all
|
||||
prior agreements on that subject.
|
||||
</p>
|
||||
<p>
|
||||
If any provision of these Terms is held to be invalid or unenforceable, that provision will be limited or
|
||||
eliminated to the minimum extent necessary, and the remaining provisions will remain in full force and
|
||||
effect. You may not assign or transfer these Terms without our prior written consent; we may assign these
|
||||
Terms in connection with a merger, acquisition, or sale of assets. Our failure to enforce any provision is
|
||||
not a waiver of our right to do so later.
|
||||
</p>
|
||||
<p>
|
||||
We will not be liable for any failure or delay in performance caused by events beyond our reasonable
|
||||
control, including acts of God, natural disasters, outages, or the failure of third-party services (a{" "}
|
||||
<strong>force majeure</strong> event). Notices to you may be given through the Service or by email to the
|
||||
address associated with your account; notices to us must be sent to{" "}
|
||||
<a href={`mailto:${LEGAL.legalEmail}`}>{LEGAL.legalEmail}</a>.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<LegalContact email={LEGAL.legalEmail} />
|
||||
</LegalPage>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user