From ba45cfeec1fe825e2c03ad21d3122fb59961439c Mon Sep 17 00:00:00 2001 From: Michael Chihlas Date: Tue, 12 May 2026 05:23:43 +0000 Subject: [PATCH] feat(legal): add /policies, /contact, /promotions pages + MarketingFooter (#165) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the three legal/contact pages needed for Stripe live-mode site review: /policies (consolidated customer policies — refunds, cancellation, legal restrictions, promotions), /contact (phone (470) 949-4131 + support/sales/billing/security inboxes), /promotions (stub satisfying §6.2 cross-ref). Extracts the existing landing footer into components/common/MarketingFooter.tsx and mounts it on /pricing and /contact-sales so all four legal links are reachable from every marketing surface. Privacy and Terms closing sections updated to point at /contact + /policies; stale hello@ mailto removed. Co-Authored-By: Claude Opus 4.7 Co-authored-by: Michael Chihlas Co-committed-by: Michael Chihlas --- .../src/components/common/MarketingFooter.tsx | 35 ++++ frontend/src/pages/ContactPage.tsx | 88 ++++++++ frontend/src/pages/ContactSalesPage.tsx | 3 + frontend/src/pages/LandingPage.tsx | 25 +-- frontend/src/pages/PoliciesPage.tsx | 194 ++++++++++++++++++ frontend/src/pages/PricingPage.tsx | 3 + frontend/src/pages/PrivacyPage.tsx | 2 +- frontend/src/pages/PromotionsPage.tsx | 37 ++++ frontend/src/pages/TermsPage.tsx | 2 +- frontend/src/router.tsx | 18 ++ 10 files changed, 382 insertions(+), 25 deletions(-) create mode 100644 frontend/src/components/common/MarketingFooter.tsx create mode 100644 frontend/src/pages/ContactPage.tsx create mode 100644 frontend/src/pages/PoliciesPage.tsx create mode 100644 frontend/src/pages/PromotionsPage.tsx diff --git a/frontend/src/components/common/MarketingFooter.tsx b/frontend/src/components/common/MarketingFooter.tsx new file mode 100644 index 00000000..978a7cdf --- /dev/null +++ b/frontend/src/components/common/MarketingFooter.tsx @@ -0,0 +1,35 @@ +import { Link } from 'react-router-dom' + +// Styles live in src/styles/landing.css under `.landing-footer*`. The component +// must be rendered inside a `.landing-page` wrapper so the `--lp-*` CSS +// variables resolve. All current marketing surfaces (LandingPage, +// PricingPage, ContactSalesPage) already provide that wrapper. +export function MarketingFooter() { + return ( +
+
+
+
+ + + + + + + + +
+ © 2026 ResolutionFlow +
+
    +
  • Privacy
  • +
  • Terms
  • +
  • Policies
  • +
  • Contact
  • +
+
+
+ ) +} + +export default MarketingFooter diff --git a/frontend/src/pages/ContactPage.tsx b/frontend/src/pages/ContactPage.tsx new file mode 100644 index 00000000..e7d68adf --- /dev/null +++ b/frontend/src/pages/ContactPage.tsx @@ -0,0 +1,88 @@ +import { Link } from 'react-router-dom' +import { PageMeta } from '@/components/common/PageMeta' + +export default function ContactPage() { + return ( + <> + +
+
+ ← Back to home +

Contact ResolutionFlow

+

+ We respond to customer inquiries Monday through Friday during U.S. business hours, excluding federal holidays. Email is the fastest path to a response. +

+ +
+
+

Phone

+

+ (470) 949-4131 +

+

Monday–Friday, 9:00 AM–5:00 PM ET, excluding U.S. federal holidays.

+
+ +
+

Email

+ +
+ +
+

Response times

+
    +
  • General support: within one (1) business day
  • +
  • Billing or account access: within one (1) business day
  • +
  • Security disclosures: within twenty-four (24) hours, including weekends
  • +
+
+ +
+

Mailing address

+ {/* TODO: replace with full mailing address once P.O. Box is set up. */} +

+ Available on request. Email{' '} + support@resolutionflow.com{' '} + and we will provide our current mailing address. +

+
+ +
+

Sales and demos

+

+ Interested in a guided demo or Enterprise pricing? Use our{' '} + sales contact form{' '} + to book a time directly. +

+
+ +
+

Related

+
    +
  • Customer Policies — billing, refunds, cancellation, and promotions
  • +
  • Terms of Service
  • +
  • Privacy Policy
  • +
+
+
+
+
+ + ) +} diff --git a/frontend/src/pages/ContactSalesPage.tsx b/frontend/src/pages/ContactSalesPage.tsx index dd083ba6..3e7665f7 100644 --- a/frontend/src/pages/ContactSalesPage.tsx +++ b/frontend/src/pages/ContactSalesPage.tsx @@ -3,6 +3,7 @@ import { Link } from 'react-router-dom' import { salesApi, type SalesLeadSource } from '@/api/sales' import { PageMeta } from '@/components/common/PageMeta' +import { MarketingFooter } from '@/components/common/MarketingFooter' import { useAppConfig } from '@/hooks/useAppConfig' import '@/styles/landing.css' @@ -342,6 +343,8 @@ export function ContactSalesPage() { )} + + ) diff --git a/frontend/src/pages/LandingPage.tsx b/frontend/src/pages/LandingPage.tsx index 3559f5d9..3c352033 100644 --- a/frontend/src/pages/LandingPage.tsx +++ b/frontend/src/pages/LandingPage.tsx @@ -2,6 +2,7 @@ import { useState, useEffect, useRef } from 'react' import { Link } from 'react-router-dom' import { PageMeta } from '@/components/common/PageMeta' import { useAppConfig } from '@/hooks/useAppConfig' +import { MarketingFooter } from '@/components/common/MarketingFooter' import '@/styles/landing.css' const FAQ_ITEMS = [ @@ -410,29 +411,7 @@ export default function LandingPage() { - {/* Footer */} -
-
-
-
- - - - - - - - -
- © 2026 ResolutionFlow -
- -
-
+ diff --git a/frontend/src/pages/PoliciesPage.tsx b/frontend/src/pages/PoliciesPage.tsx new file mode 100644 index 00000000..eaabb472 --- /dev/null +++ b/frontend/src/pages/PoliciesPage.tsx @@ -0,0 +1,194 @@ +import { Link } from 'react-router-dom' +import { PageMeta } from '@/components/common/PageMeta' + +export default function PoliciesPage() { + return ( + <> + +
+
+ ← Back to home +

Customer Policies

+

Last updated: May 7, 2026

+

Operator: ResolutionFlow, LLC (the “Company”), operator of ResolutionFlow (“Service”).

+

Product: ResolutionFlow — a software-as-a-service troubleshooting platform for Managed Service Providers (MSPs).

+ +

+ This document consolidates the policies that govern your use of ResolutionFlow, including how to contact us, how billing works, how to cancel, how refunds and disputes are handled, the legal restrictions that apply, and the terms of any promotional offers. It is intended to satisfy the disclosure requirements of our payment processors (including Stripe) and to give customers clear, accessible answers to common billing and account questions. +

+

+ ResolutionFlow is a digital subscription service. We do not sell or ship physical goods, so a return policy does not apply; the section on refunds below covers all circumstances in which money may be returned. +

+ +
+ +
+ {/* Section 1 */} +
+

1. Customer Service Contact

+

We respond to customer inquiries during standard business hours, Monday through Friday, excluding U.S. federal holidays. The fastest path to a response is email.

+ + + {/* TODO: replace with full mailing address once P.O. Box is set up. */} +

Mailing address: available on request — email support@resolutionflow.com.

+

Web contact form: resolutionflow.com/contact

+ +

Target response times:

+
    +
  • General support: within one (1) business day
  • +
  • Billing or account access issues: within one (1) business day
  • +
  • Security disclosures: within twenty-four (24) hours, including weekends
  • +
+

Customers on the Enterprise plan have additional contact channels and service levels defined in their order form.

+
+ + {/* Section 2 */} +
+

2. Return Policy

+

ResolutionFlow is a software-as-a-service product delivered electronically. Because no physical goods are sold or shipped, no return policy applies. All refund-related questions are governed by Section 3 (Refund and Dispute Policy) below.

+
+ + {/* Section 3 */} +
+

3. Refund and Dispute Policy

+ +

3.1 Subscription model

+

ResolutionFlow is sold as a recurring monthly subscription. The Service is billed in advance: the first charge occurs at the end of any free trial period (or immediately if no trial applies), and subsequent charges occur on the same day each month until the subscription is cancelled. There are currently no annual subscription terms; if and when annual terms become available, refund handling for those terms will be specified at the point of sale.

+ +

3.2 Free trial

+

New customers receive a 14-day free trial of the Pro plan. No charge is made during the trial. If the customer does not cancel before the trial ends, the subscription converts automatically to a paid plan at the price disclosed at signup. Cancelling before the trial ends prevents any charge. The trial is intended to be the customer’s primary opportunity to evaluate the Service before paying.

+ +

3.3 Refund policy

+

Monthly subscriptions are non-refundable. Because the customer can cancel at any time and is never billed for a future period after cancellation, we do not issue refunds for partial months, unused features, or change-of-mind cancellations made after the billing date. This is the standard model for B2B SaaS and is consistent with how the Service is priced and delivered.

+

We will issue a refund or credit at our discretion in the following circumstances:

+
    +
  • Duplicate or accidental charge. If a customer is charged twice for the same billing period, or charged after a verifiable cancellation that we failed to process, we refund the erroneous charge in full.
  • +
  • Fraudulent charge. If a customer demonstrates that their payment method was used without authorization, we cooperate with the cardholder and the issuing bank to resolve the dispute and refund or reverse the charge as appropriate.
  • +
  • Material Service failure. If the Service is materially unavailable for an extended period due to our fault, we may issue a service credit applied to the next billing cycle. Credits are not paid as cash refunds.
  • +
  • Annual prepayments (when offered). If annual prepayment becomes available in the future, the refund terms for those subscriptions will be disclosed at the point of sale.
  • +
+

Refunds, where issued, are returned to the original payment method used for the charge. Refund processing typically completes within five (5) to ten (10) business days, depending on the customer’s bank or card issuer.

+ +

3.4 Disputes and chargebacks

+

If you believe a charge is incorrect, please contact billing@resolutionflow.com before initiating a chargeback with your bank or card issuer. We can almost always resolve billing questions faster than the dispute process and without affecting your account standing.

+

If a chargeback is filed against an active subscription, the associated account may be suspended pending resolution to prevent further charges. We respond to chargeback inquiries from card networks with the records we maintain, including signup records, billing history, login activity, and product usage. We do not retaliate against customers for filing legitimate disputes; suspensions during a dispute are operational, not punitive.

+

Customers who repeatedly file chargebacks for charges that they previously authorized and used may be permanently banned from the Service.

+ +

3.5 Enterprise refunds

+

Customers on the Enterprise plan are governed by the refund and dispute terms in their executed order form or master services agreement. Where those terms conflict with this section, the order form or MSA controls.

+
+ + {/* Section 4 */} +
+

4. Cancellation Policy

+ +

4.1 How to cancel

+

Customers can cancel their subscription at any time, without contacting support, through one of the following routes:

+
    +
  1. Account settings → Billing → Manage subscription, which opens the Stripe Customer Portal and allows the customer to cancel directly.
  2. +
  3. Email billing@resolutionflow.com from the email address on file. We will process the cancellation within one (1) business day and confirm by reply.
  4. +
+

Customers on the Enterprise plan should follow the cancellation procedure specified in their order form or MSA.

+ +

4.2 What happens when you cancel

+
    +
  • No future charges. Your subscription will not renew. The card on file will not be charged again.
  • +
  • Access continues until the end of the current billing period. If you cancel mid-month, you retain full access to the Service until the end of the period you have already paid for. We do not lock you out early.
  • +
  • Trial cancellations. Cancelling during a free trial ends the trial immediately. No charge is made.
  • +
  • No partial refunds. Per Section 3.3, the unused portion of the current billing period is not refunded.
  • +
+ +

4.3 What happens to your data

+

For a period of thirty (30) days after the end of the current billing period, your account is retained in a read-only state. During this window you can:

+
    +
  • Reactivate the subscription and resume work without any data loss.
  • +
  • Export your sessions, flows, and documentation in any of the supported export formats (Markdown, plain text, HTML, PDF, or PSA-formatted notes).
  • +
  • Request a copy of your data by emailing security@resolutionflow.com.
  • +
+

After thirty (30) days, all customer-generated content is permanently deleted from production systems. Backups are purged within ninety (90) days. Some metadata may be retained as required for tax, legal, or fraud-prevention obligations.

+ +

4.4 Reactivation

+

A cancelled account can be reactivated within the thirty (30) day retention window by signing in and re-subscribing. Beyond that window, the customer can sign up again, but prior data will not be available.

+
+ + {/* Section 5 */} + + + {/* Section 6 */} +
+

6. Promotions: Terms and Conditions

+

From time to time we may offer promotional pricing, extended trials, referral credits, free upgrades, or other promotional benefits (“Promotions”). The following general terms apply to all Promotions, in addition to any specific terms disclosed at the time the Promotion is offered:

+ +

6.1 General terms

+
    +
  • Promotions apply only to the specific accounts, plans, and billing periods identified at the time of the offer.
  • +
  • Promotions cannot be combined with other Promotions unless we expressly state otherwise.
  • +
  • Promotional pricing applies for the period stated in the offer. After that period, the subscription renews at the then-current standard price for the applicable plan unless cancelled.
  • +
  • Promotional credits and discounts have no cash value and are not transferable, refundable, or redeemable for currency.
  • +
  • Customers must be in good standing (no overdue balances, no active chargebacks, no policy violations) to receive or continue receiving a Promotion.
  • +
  • We may modify or discontinue a Promotion at any time, except where doing so would be inconsistent with the terms disclosed at the time the customer accepted the Promotion.
  • +
  • We reserve the right to revoke a Promotion and recover its value if we determine, in good faith, that the customer obtained the Promotion through fraud, duplicate accounts, abuse, or violation of these terms.
  • +
+ +

6.2 Active promotions

+

A current list of active Promotions, along with their specific terms, is published at resolutionflow.com/promotions. Where there is any inconsistency between the general terms above and the specific terms of an individual Promotion, the specific terms control for that Promotion only.

+

If no Promotions are active, that page will state so.

+
+ + {/* Section 7 */} +
+

7. Changes to These Policies

+

We may update these policies from time to time. Material changes will be announced by email to the address on file for the account at least fifteen (15) days before they take effect, and the “Last updated” date at the top of this document will be revised. Continued use of the Service after the effective date of a change constitutes acceptance of the updated policies. Customers who do not accept a material change may cancel under Section 4 before the effective date.

+
+ + {/* Section 8 */} +
+

8. Relationship to Other Agreements

+

These policies are part of, and incorporated into, the ResolutionFlow Terms of Service and the Privacy Policy. Where these policies conflict with the Terms of Service or Privacy Policy, the Terms of Service control for matters of contract formation, liability, warranties, and dispute resolution; the Privacy Policy controls for matters of personal data handling; and these policies control for matters of billing, refunds, cancellation, customer service contact, legal restrictions, and Promotions.

+

For Enterprise customers operating under an executed order form or master services agreement, that agreement controls in the event of any conflict with these policies.

+
+ +
+ +

+ Questions about these policies? Email{' '} + billing@resolutionflow.com{' '} + or use the contact form at{' '} + resolutionflow.com/contact. +

+
+
+
+ + ) +} diff --git a/frontend/src/pages/PricingPage.tsx b/frontend/src/pages/PricingPage.tsx index 6abdd4bf..8632e2d2 100644 --- a/frontend/src/pages/PricingPage.tsx +++ b/frontend/src/pages/PricingPage.tsx @@ -3,6 +3,7 @@ import { Link } from 'react-router-dom' import { plansApi, type PublicPlanResponse } from '@/api/plans' import { PageMeta } from '@/components/common/PageMeta' +import { MarketingFooter } from '@/components/common/MarketingFooter' import { useAppConfig } from '@/hooks/useAppConfig' import '@/styles/landing.css' @@ -431,6 +432,8 @@ export function PricingPage() { > Built on Stripe + AWS · Encrypted in transit and at rest + + ) diff --git a/frontend/src/pages/PrivacyPage.tsx b/frontend/src/pages/PrivacyPage.tsx index 8e7662a5..1478bbca 100644 --- a/frontend/src/pages/PrivacyPage.tsx +++ b/frontend/src/pages/PrivacyPage.tsx @@ -34,7 +34,7 @@ export default function PrivacyPage() {

5. Contact

-

Questions about this policy? Email us at hello@resolutionflow.com.

+

Questions about this policy? Email security@resolutionflow.com or visit our contact page. Billing, cancellation, refund, and promotional terms are governed by our Customer Policies.

diff --git a/frontend/src/pages/PromotionsPage.tsx b/frontend/src/pages/PromotionsPage.tsx new file mode 100644 index 00000000..132ad10b --- /dev/null +++ b/frontend/src/pages/PromotionsPage.tsx @@ -0,0 +1,37 @@ +import { Link } from 'react-router-dom' +import { PageMeta } from '@/components/common/PageMeta' + +export default function PromotionsPage() { + return ( + <> + +
+
+ ← Back to home +

Promotions

+

Last updated: May 7, 2026

+ +
+
+

Current promotions

+

No promotions are currently active.

+

+ Promotional offers, when running, will be listed on this page with their specific terms (eligible plans, duration, redemption rules, expiration). The general terms that apply to all promotions are described in{' '} + Section 6 of our Customer Policies. +

+
+ +
+

Questions

+

+ Email{' '} + billing@resolutionflow.com{' '} + for questions about a promotion you received by email, or to ask about upcoming offers. +

+
+
+
+
+ + ) +} diff --git a/frontend/src/pages/TermsPage.tsx b/frontend/src/pages/TermsPage.tsx index 65dfba59..cd65338e 100644 --- a/frontend/src/pages/TermsPage.tsx +++ b/frontend/src/pages/TermsPage.tsx @@ -39,7 +39,7 @@ export default function TermsPage() {

6. Contact

-

Questions about these terms? Email us at hello@resolutionflow.com.

+

Questions about these terms? Email support@resolutionflow.com or visit our contact page. Billing, cancellation, refund, and promotional terms are governed by our Customer Policies.

diff --git a/frontend/src/router.tsx b/frontend/src/router.tsx index e535969a..02ce56f2 100644 --- a/frontend/src/router.tsx +++ b/frontend/src/router.tsx @@ -24,6 +24,9 @@ const PrivacyPage = lazyWithRetry(() => import('@/pages/PrivacyPage')) const TermsPage = lazyWithRetry(() => import('@/pages/TermsPage')) const PricingPage = lazyWithRetry(() => import('@/pages/PricingPage')) const ContactSalesPage = lazyWithRetry(() => import('@/pages/ContactSalesPage')) +const ContactPage = lazyWithRetry(() => import('@/pages/ContactPage')) +const PoliciesPage = lazyWithRetry(() => import('@/pages/PoliciesPage')) +const PromotionsPage = lazyWithRetry(() => import('@/pages/PromotionsPage')) // Standalone auth pages const VerifyEmailPage = lazyWithRetry(() => import('@/pages/VerifyEmailPage')) @@ -145,6 +148,21 @@ export const router = sentryCreateBrowserRouter([ element: page(ContactSalesPage), errorElement: , }, + { + path: '/contact', + element: page(ContactPage), + errorElement: , + }, + { + path: '/policies', + element: page(PoliciesPage), + errorElement: , + }, + { + path: '/promotions', + element: page(PromotionsPage), + errorElement: , + }, { path: '/login', element: ,