diff --git a/AGENTS.md b/AGENTS.md index 4cd373c..9a204df 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,5 +1,7 @@ # beenvoice - AI Assistant Rules +> **Canonical architecture reference:** [docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md) (stack, routers, schema, auth). This file may lag behind; prefer ARCHITECTURE.md for facts. + ## Project Overview beenvoice is a professional invoicing application built with the T3 stack (Next.js 15, tRPC, Drizzle/LibSQL, NextAuth.js) and shadcn/ui components. This is a business-critical application where reliability, security, and professional user experience are paramount. diff --git a/README.md b/README.md index e8b2fa1..909325b 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,29 @@ ![beenvoice Logo](public/beenvoice-logo.png) -# beenvoice - Invoicing Made Simple +# beenvoice — Invoicing Made Simple -A modern, professional invoicing application built for freelancers and small businesses. beenvoice provides a clean, efficient way to manage clients and create professional invoices with ease. +Modern invoicing for freelancers and small businesses: clients, businesses, invoices, time tracking, expenses, recurring billing, PDF/email delivery, and optional SSO. -![beenvoice Logo](https://img.shields.io/badge/beenvoice-Invoicing%20Made%20Simple-green?style=for-the-badge) +**Architecture (dense):** [docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md) +**Mobile companion:** [../beenvoice-app/README.md](../beenvoice-app/README.md) -## ✨ Features +## Stack at a glance -- **🔐 Secure Authentication** - Email/password registration and sign-in with better-auth, plus SSO via Authentik OIDC +| Layer | Tech | +|-------|------| +| App | Next.js 16 App Router, React 19 | +| API | tRPC 11 + SuperJSON | +| DB | PostgreSQL, Drizzle ORM | +| Auth | better-auth (email/password, Authentik OIDC, Expo mobile) | +| UI | shadcn/ui, Tailwind v4 | +| Email / PDF | Resend, @react-pdf/renderer | +| Package manager | Bun | + +## Features + +- **🔐 Authentication** — better-auth: email/password, password reset, optional Authentik OIDC, Expo mobile sessions +- **⏱ Time clock** — running timer, one per user; clock-out can append invoice line items +- **🤖 MCP API** — `/api/mcp` for automation via API keys (`bv_…`) - **👥 Client Management** - Create, edit, and manage client information - **🏢 Business Profiles** - Manage your business details, logo, and email settings - **📄 Professional Invoices** - Generate detailed invoices with line items @@ -103,35 +118,19 @@ A modern, professional invoicing application built for freelancers and small bus 7. **Open your browser** Navigate to [http://localhost:3000](http://localhost:3000) -## 🏗️ Project Structure +## 🏗️ Project structure + +See [docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md) for routers, schema, auth, and MCP. ``` beenvoice/ -├── src/ -│ ├── app/ # Next.js App Router pages -│ │ ├── api/ # API routes (better-auth, tRPC) -│ │ ├── auth/ # Authentication pages -│ │ ├── dashboard/ # Main app pages -│ │ │ ├── clients/ # Client management pages -│ │ │ ├── invoices/ # Invoice management pages -│ │ │ └── businesses/ # Business profile pages -│ │ └── _components/ # Page-specific components -│ ├── components/ # Shared UI components -│ │ ├── ui/ # shadcn/ui components -│ │ ├── data/ # Data display components -│ │ ├── forms/ # Form components -│ │ └── layout/ # Layout components -│ ├── server/ # Server-side code -│ │ ├── api/ # tRPC routers -│ │ └── db/ # Database schema and connection -│ ├── lib/ # Utilities (auth, pdf export, etc.) -│ ├── styles/ # Global styles -│ └── trpc/ # tRPC client configuration -├── drizzle/ # Database migrations -├── public/ # Static assets -├── docs/ # Documentation -├── docker-compose.yml # Deployment compose stack -└── docker-compose.dev.yml # Development overrides with exposed PostgreSQL +├── src/app/ # Pages + /api (auth, trpc, mcp, cron, public PDF) +├── src/server/api/ # tRPC routers +├── src/server/db/ # Drizzle schema + pool +├── src/components/ # UI + domain components +├── src/lib/ # auth, PDF, email, branding +├── drizzle/ # SQL migrations +└── docs/ # Architecture + UI guides ``` ## 🎯 Usage @@ -250,15 +249,14 @@ The application uses the following core tables: - **invoices** - Invoice headers with client and business relationships - **invoice_items** - Individual line items with pricing and position ordering -### API Development +### API surface -All API endpoints are built with tRPC for type safety: +- **tRPC** — `/api/trpc` — primary API for web and mobile (session cookies) +- **MCP** — `/api/mcp` — JSON-RPC tools for integrations (API key only) +- **REST auth** — `/api/auth/register`, forgot/reset password (mobile + custom flows) +- **Public** — `/i/[token]`, `/api/i/[token]/pdf` -- **Authentication**: better-auth integration (email/password + OIDC) -- **Clients**: CRUD operations for client management -- **Businesses**: Business profile management -- **Invoices**: Invoice creation, management, and status tracking -- **Validation**: Zod schemas for input validation +All business logic lives in `src/server/api/routers/`. Input validation via Zod. ## 🎨 Customization diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..0ad5abe --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,211 @@ +# beenvoice server architecture + +Dense reference for the Next.js web application and API in `beenvoice/`. Package manager: **Bun**. Database: **PostgreSQL** via Drizzle ORM. + +## Stack + +| Layer | Technology | +|-------|------------| +| Framework | Next.js 16 App Router (`src/app/`) | +| API | tRPC 11 (`/api/trpc`), SuperJSON transformer | +| ORM | Drizzle + `pg` pool | +| Auth | better-auth (email/password, optional Authentik OIDC, Expo plugin for mobile) | +| UI | shadcn/ui, Tailwind CSS v4, Radix primitives | +| Email | Resend | +| PDF | `@react-pdf/renderer` | + +## Request flow + +``` +Browser / Mobile / MCP client + │ + ├─► /api/auth/* → better-auth handler (session cookies) + ├─► /api/trpc/* → createContext() → appRouter + │ ├─ Bearer / x-api-key → api-key auth + │ └─ else → better-auth session + ├─► /api/mcp → API key only → JSON-RPC tools → tRPC caller + ├─► /api/i/[token]/pdf → public invoice PDF + └─► /dashboard/* → RSC + client components (session required in UI) +``` + +**Context** (`src/server/api/trpc.ts`): `protectedProcedure` requires `ctx.session.user`. API-key auth sets `authSource: "api-key"`; `apiKeys.*` mutations require session (cannot manage keys with a key). + +## Directory layout + +``` +src/ +├── app/ # Routes (pages + route handlers) +│ ├── api/ +│ │ ├── auth/ # better-auth catch-all + custom register/reset REST +│ │ ├── trpc/[trpc]/ # tRPC HTTP adapter +│ │ ├── mcp/ # MCP over HTTP (API key) +│ │ ├── i/[token]/pdf/ # Public PDF +│ │ └── cron/ # Recurring invoice generation (CRON_SECRET) +│ ├── auth/ # sign-in, register, forgot/reset password +│ ├── dashboard/ # Authenticated app shell +│ └── i/[token]/ # Public invoice view +├── components/ # Shared UI (ui/, forms/, layout/, data/) +├── hooks/ +├── lib/ # auth.ts, pdf-export, email templates, branding +├── server/ +│ ├── api/ +│ │ ├── root.ts # appRouter composition +│ │ ├── trpc.ts # procedures, context, timing middleware (dev) +│ │ ├── api-keys.ts +│ │ └── routers/ # one file per domain +│ └── db/ +│ ├── schema.ts # all tables (prefix beenvoice_) +│ ├── index.ts # drizzle + pool +│ └── migrate.ts +├── trpc/ # react.tsx (client), server.ts (RSC) +├── env.js # @t3-oss/env-nextjs validation +└── styles/globals.css +drizzle/ # SQL migrations (0000–0014+) +``` + +## tRPC routers + +Root: `src/server/api/root.ts`. All routers use Zod input validation. + +| Namespace | File | Key procedures | +|-----------|------|----------------| +| `clients` | `routers/clients.ts` | getAll, getById, create, update, delete | +| `businesses` | `routers/businesses.ts` | getAll, getById, getDefault, create, update, delete, setDefault, getEmailConfig, updateEmailConfig | +| `invoices` | `routers/invoices.ts` | getAll, getBillable, getById, create, update, delete, updateStatus, bulk*, previewPdf, public token, **getByPublicToken** (public), sendReminder | +| `payments` | `routers/payments.ts` | getByInvoice, create, delete | +| `expenses` | `routers/expenses.ts` | getAll, getById, create, update, delete | +| `invoiceTemplates` | `routers/invoiceTemplates.ts` | CRUD by template type | +| `recurringInvoices` | `routers/recurring-invoices.ts` | CRUD, pause/resume, generateNow; cron helper `generateDueRecurringInvoices` | +| `timeEntries` | `routers/time-entries.ts` | getAll, getRunning, clockIn, updateRunning, clockOut, create, update, delete, getSummary | +| `dashboard` | `routers/dashboard.ts` | getStats | +| `email` | `routers/email.ts` | sendInvoice | +| `settings` | `routers/settings.ts` | profile, theme, animation prefs, export/import data, admin account roles | +| `apiKeys` | `routers/apiKeys.ts` | list, create, revoke (session-only) | + +### Time clock semantics + +- **One running entry per user** — partial unique index on `(createdById)` where `endedAt IS NULL`. +- `clockIn` — optional client, invoice, rate, backdated `startedAt`; resolves rate from input → client default → business default. +- `clockOut` — optional description update; computes hours; if `invoiceId` set, appends line item; else tries latest open invoice for client. +- Outcomes: `linked_to_invoice`, `saved_no_invoice`, `saved_no_client`, `zero_hours`. + +## Database schema + +Single file: `src/server/db/schema.ts`. Table names use `pgTableCreator` → prefix `beenvoice_`. + +### Auth & platform + +| Table | Notes | +|-------|-------| +| `beenvoice_user` | Core user; role for admin features | +| `beenvoice_account` | OAuth/credential accounts (better-auth) | +| `beenvoice_session` | Sessions; unique token | +| `beenvoice_verification_token` | Email verification / reset | +| `beenvoice_api_key` | `bv_` prefix keys; SHA-256 hash stored | +| `beenvoice_sso_provider` | OIDC/SAML config per user | +| `beenvoice_platform_setting` | Singleton (`id = global`) branding/PDF/appearance | + +### Domain + +| Table | FKs | Notes | +|-------|-----|-------| +| `beenvoice_client` | `createdById` → user | defaultHourlyRate, currency | +| `beenvoice_business` | `createdById` | Resend config, `isDefault` | +| `beenvoice_invoice` | client, business?, user | status draft/sent/paid; `publicToken` | +| `beenvoice_invoice_item` | invoice (cascade) | position ordering | +| `beenvoice_invoice_payment` | invoice, user | payment method enum | +| `beenvoice_expense` | business?, client?, invoice? | billable flags | +| `beenvoice_invoice_template` | user | notes/terms templates | +| `beenvoice_recurring_invoice` | client, business?, user | schedule, `nextDueAt` | +| `beenvoice_recurring_invoice_item` | recurring (cascade) | | +| `beenvoice_time_entry` | client?, invoice?, user | `endedAt` null = running | + +Migrations: `bun run db:generate` → `drizzle/`; apply with `db:push` (dev) or `db:migrate` (prod script). + +## Authentication + +**Server** — `src/lib/auth.ts`: + +- `betterAuth` + `drizzleAdapter` (users, sessions, accounts, verification) +- Plugins: `@better-auth/expo` (mobile SecureStore cookies), `nextCookies()`, optional `genericOAuth` (Authentik) +- Email/password with bcrypt (12 rounds); `DISABLE_SIGNUPS=true` blocks registration +- `trustedOrigins`: production URL, `beenvoice://`, `exp://` (Expo) + +**Web client** — `src/lib/auth-client.ts`: `createAuthClient` + `genericOAuthClient`. + +**Routes**: + +- `src/app/api/auth/[...all]/route.ts` — better-auth handler +- Custom REST: `register`, `forgot-password`, `reset-password`, `validate-reset-token` (used by mobile and legacy flows) + +**Session cookies**: `better-auth.session_token` or `__Secure-better-auth.session_token` in production. + +## Mobile API contract + +The Expo app (`beenvoice-app`) does **not** use API keys. It: + +1. Calls the same tRPC endpoints with `Authorization` cookie header from `authClient.getCookie()`. +2. Stores session per account in SecureStore via `@better-auth/expo` (`storagePrefix`: `beenvoice:guest` or `beenvoice:auth:{accountId}`). +3. Requires `trustedOrigins` and matching `BETTER_AUTH_URL` for the host the device can reach. + +Ensure `src/lib/auth.ts` keeps the `expo()` plugin enabled. + +## MCP (machine clients) + +`POST /api/mcp` — JSON-RPC 2.0, protocol `2025-11-25`. + +- **Auth**: API key only (`Authorization: Bearer bv_…` or `x-api-key`). Session cookies rejected. +- **Tools**: ~50 tools mirroring tRPC (invoices, clients, time clock, expenses, etc.) +- Implemented in `src/app/api/mcp/route.ts`; delegates to `createCaller(createContext)`. + +API keys: format `bv_`; stored as SHA-256 hash (`src/server/api/api-keys.ts`). + +## Environment variables + +Validated in `src/env.js`. See `.env.example`. + +| Variable | Required | Notes | +|----------|----------|-------| +| `DATABASE_URL` | yes | PostgreSQL connection string | +| `AUTH_SECRET` | prod | `openssl rand -base64 32` | +| `BETTER_AUTH_URL` | yes | Public URL of API (no trailing path) | +| `NEXT_PUBLIC_APP_URL` | yes | Browser-facing URL | +| `DB_DISABLE_SSL` | local | `true` for Docker dev DB | +| `RESEND_API_KEY`, `RESEND_DOMAIN` | optional | Email; blank disables send | +| `AUTHENTIK_*` | optional | OIDC SSO | +| `DISABLE_SIGNUPS` | optional | `true` blocks registration | +| `CRON_SECRET` | cron route | Protects `/api/cron/generate-recurring` | +| `NEXT_PUBLIC_BRAND_*` | optional | Build-time white-label defaults | + +## Docker + +| File | Use | +|------|-----| +| `docker-compose.yml` | Production: `app` + `db` (Postgres internal) | +| `docker-compose.dev.yml` | Dev: Postgres only, port `${POSTGRES_PORT:-5432}` | + +App image built from `Dockerfile`; runs `next start` on port 3000. + +## Scripts + +```bash +bun run dev # next dev --turbo +bun run build # production build +bun run db:push # push schema (dev) +bun run db:migrate # run migrations +bun run db:studio # Drizzle Studio +bun run check # eslint + tsc +``` + +## Public / unauthenticated surfaces + +- `invoices.getByPublicToken` (tRPC publicProcedure) +- `/i/[token]` page and `/api/i/[token]/pdf` +- Auth REST endpoints for register/reset + +## Related docs + +- [forms-guide.md](./forms-guide.md), [UI_UNIFORMITY_GUIDE.md](./UI_UNIFORMITY_GUIDE.md) +- [data-table-responsive-guide.md](./data-table-responsive-guide.md) +- [email-features.md](./email-features.md) +- Mobile companion: `../beenvoice-app/docs/ARCHITECTURE.md` diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..47e16b7 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,33 @@ +# beenvoice documentation + +## Core + +| Document | Description | +|----------|-------------| +| [ARCHITECTURE.md](./ARCHITECTURE.md) | Server stack, tRPC routers, schema, auth, MCP, Docker, mobile API contract | +| [../README.md](../README.md) | Install, scripts, deployment | + +## UI & product guides + +| Document | Description | +|----------|-------------| +| [forms-guide.md](./forms-guide.md) | Form patterns | +| [UI_UNIFORMITY_GUIDE.md](./UI_UNIFORMITY_GUIDE.md) | Visual consistency | +| [breadcrumbs-guide.md](./breadcrumbs-guide.md) | Navigation breadcrumbs | +| [data-table-responsive-guide.md](./data-table-responsive-guide.md) | Responsive tables | +| [data-table-improvements.md](./data-table-improvements.md) | Table enhancements | +| [RESPONSIVE_TABLE_EXAMPLES.md](./RESPONSIVE_TABLE_EXAMPLES.md) | Table examples | +| [email-features.md](./email-features.md) | Email composer / delivery | + +## Mobile + +| Document | Description | +|----------|-------------| +| [../../beenvoice-app/docs/ARCHITECTURE.md](../../beenvoice-app/docs/ARCHITECTURE.md) | Expo app architecture | +| [../../beenvoice-app/README.md](../../beenvoice-app/README.md) | Mobile setup | + +## Workspace + +| Document | Description | +|----------|-------------| +| [../../README.md](../../README.md) | Meta repo layout, full-stack quick start | diff --git a/src/app/(legal)/layout.tsx b/src/app/(legal)/layout.tsx new file mode 100644 index 0000000..812bb12 --- /dev/null +++ b/src/app/(legal)/layout.tsx @@ -0,0 +1,18 @@ +import type { Metadata } from "next"; + +import { brand } from "~/lib/branding"; + +export const metadata: Metadata = { + title: { + template: `%s | ${brand.name}`, + default: `Legal | ${brand.name}`, + }, +}; + +export default function LegalLayout({ + children, +}: { + children: React.ReactNode; +}) { + return children; +} diff --git a/src/app/(legal)/privacy/page.tsx b/src/app/(legal)/privacy/page.tsx index 7544b8d..966107d 100644 --- a/src/app/(legal)/privacy/page.tsx +++ b/src/app/(legal)/privacy/page.tsx @@ -1,390 +1,18 @@ -import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card"; -import { Button } from "~/components/ui/button"; -import Link from "next/link"; -import { ArrowLeft } from "lucide-react"; +import type { Metadata } from "next"; + +import { PrivacyPolicyContent } from "~/components/legal/privacy-policy-content"; +import { LegalPageShell } from "~/components/legal/legal-page-shell"; +import { brand } from "~/lib/branding"; + +export const metadata: Metadata = { + title: `Privacy Policy | ${brand.name}`, + description: `How ${brand.name} collects, uses, and protects your data.`, +}; export default function PrivacyPolicyPage() { return ( -
- {/* Header */} -
-
-
- - - -
-

Privacy Policy

-

- Last updated: {new Date().toLocaleDateString()} -

-
-
-
-
- - {/* Content */} -
-
- - - Introduction - - -

- beenvoice ("we", "our", or "us") - is committed to protecting your privacy. This Privacy Policy - explains how we collect, use, disclose, and safeguard your - information when you use our invoicing platform and services. -

-

- Please read this Privacy Policy carefully. If you do not agree - with the terms of this Privacy Policy, please do not access or - use our Service. -

-
-
- - - - Information We Collect - - -

Personal Information

-

- We may collect personal information that you voluntarily provide - to us when you: -

-
    -
  • Register for an account
  • -
  • Create invoices or manage client information
  • -
  • Contact us for support
  • -
  • Subscribe to our newsletters or communications
  • -
- -

This personal information may include:

-
    -
  • Name and contact information (email, phone, address)
  • -
  • Business information and tax details
  • -
  • Client information you input into the system
  • -
  • Financial information related to your invoices
  • -
  • - Payment information (processed securely by third-party - providers) -
  • -
- -

Automatically Collected Information

-

- We may automatically collect certain information when you visit - our Service: -

-
    -
  • - Device information (IP address, browser type, operating - system) -
  • -
  • Usage data (pages visited, time spent, features used)
  • -
  • Log files and analytics data
  • -
  • Cookies and similar tracking technologies
  • -
-
-
- - - - How We Use Your Information - - -

We use the information we collect to:

-
    -
  • Provide, operate, and maintain our Service
  • -
  • Process your transactions and manage your account
  • -
  • Improve and personalize your experience
  • -
  • - Communicate with you about your account and our services -
  • -
  • Send you technical notices and support messages
  • -
  • Respond to your comments, questions, and requests
  • -
  • Monitor usage and analyze trends
  • -
  • - Detect, prevent, and address technical issues and security - breaches -
  • -
  • Comply with legal obligations
  • -
-
-
- - - - How We Share Your Information - - -

- We do not sell, trade, or rent your personal information to - third parties. We may share your information in the following - circumstances: -

- -

Service Providers

-

- We may share your information with trusted third-party service - providers who assist us in operating our Service, such as: -

-
    -
  • Cloud hosting and storage providers
  • -
  • Payment processors
  • -
  • Email service providers
  • -
  • Analytics and monitoring services
  • -
- -

Legal Requirements

-

- We may disclose your information if required to do so by law or - in response to: -

-
    -
  • Legal processes (subpoenas, court orders)
  • -
  • Government requests
  • -
  • Law enforcement investigations
  • -
  • Protection of our rights, property, or safety
  • -
- -

Business Transfers

-

- In the event of a merger, acquisition, or sale of assets, your - information may be transferred as part of that transaction. -

-
-
- - - - Data Security - - -

- We implement appropriate technical and organizational security - measures to protect your information: -

-
    -
  • Encryption of data in transit and at rest
  • -
  • Secure access controls and authentication
  • -
  • Regular security assessments and updates
  • -
  • Employee training on data protection
  • -
  • Incident response procedures
  • -
-

- However, no method of transmission over the internet or - electronic storage is 100% secure. While we strive to protect - your information, we cannot guarantee absolute security. -

-
-
- - - - Data Retention - - -

- We retain your personal information only for as long as - necessary to fulfill the purposes outlined in this Privacy - Policy, unless a longer retention period is required by law. -

-

- Factors we consider when determining retention periods include: -

-
    -
  • The nature and sensitivity of the information
  • -
  • Legal and regulatory requirements
  • -
  • Business and operational needs
  • -
  • Your account status and activity
  • -
-
-
- - - - Your Rights and Choices - - -

- Depending on your location, you may have the following rights - regarding your personal information: -

- -

Access and Portability

-
    -
  • Request access to your personal information
  • -
  • Receive a copy of your data in a portable format
  • -
- -

Correction and Updates

-
    -
  • Correct inaccurate or incomplete information
  • -
  • Update your account information at any time
  • -
- -

Deletion

-
    -
  • Request deletion of your personal information
  • -
  • Close your account and remove your data
  • -
- -

Restriction and Objection

-
    -
  • Restrict the processing of your information
  • -
  • Object to certain uses of your data
  • -
- -

- To exercise these rights, please contact us using the - information provided in the "Contact Us" section - below. -

-
-
- - - - Cookies and Tracking Technologies - - -

We use cookies and similar technologies to:

-
    -
  • Remember your preferences and settings
  • -
  • Authenticate your account
  • -
  • Analyze usage patterns and improve our Service
  • -
  • Provide personalized content and features
  • -
- -

- You can control cookies through your browser settings. However, - disabling cookies may affect the functionality of our Service. -

- -

Types of Cookies We Use

-
    -
  • - Essential Cookies: Required for the Service - to function properly -
  • -
  • - Analytics Cookies: Help us understand how you - use our Service -
  • -
  • - Preference Cookies: Remember your settings - and preferences -
  • -
-
-
- - - - Third-Party Links and Services - - -

- Our Service may contain links to third-party websites or - integrate with third-party services. We are not responsible for - the privacy practices of these third parties. -

-

- We encourage you to read the privacy policies of any third-party - services you use in connection with our Service. -

-
-
- - - - Children's Privacy - - -

- Our Service is not intended for children under the age of 13. We - do not knowingly collect personal information from children - under 13. -

-

- If you are a parent or guardian and believe your child has - provided us with personal information, please contact us - immediately so we can remove such information. -

-
-
- - - - International Data Transfers - - -

- Your information may be transferred to and processed in - countries other than your own. We ensure that such transfers - comply with applicable data protection laws. -

-

- When we transfer your information internationally, we implement - appropriate safeguards to protect your data, including: -

-
    -
  • Standard contractual clauses
  • -
  • Adequacy decisions by relevant authorities
  • -
  • Certified privacy frameworks
  • -
-
-
- - - - Changes to This Privacy Policy - - -

- We may update this Privacy Policy from time to time. We will - notify you of any material changes by: -

-
    -
  • Posting the updated policy on our Service
  • -
  • Sending you an email notification
  • -
  • Displaying a prominent notice on our Service
  • -
-

- Your continued use of our Service after any changes indicates - your acceptance of the updated Privacy Policy. -

-
-
- - - - Contact Us - - -

- If you have questions about this Privacy Policy or our privacy - practices, please contact us at: -

-
    -
  • Email: privacy@beenvoice.com
  • -
  • Address: [Your Business Address]
  • -
-

- We will respond to your inquiries within a reasonable timeframe - and in accordance with applicable law. -

-
-
-
-
-
+ + + ); } diff --git a/src/app/(legal)/terms/page.tsx b/src/app/(legal)/terms/page.tsx index 533506f..ed1ecd7 100644 --- a/src/app/(legal)/terms/page.tsx +++ b/src/app/(legal)/terms/page.tsx @@ -1,307 +1,18 @@ -import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card"; -import { Button } from "~/components/ui/button"; -import Link from "next/link"; -import { ArrowLeft } from "lucide-react"; +import type { Metadata } from "next"; + +import { LegalPageShell } from "~/components/legal/legal-page-shell"; +import { TermsOfServiceContent } from "~/components/legal/terms-of-service-content"; +import { brand } from "~/lib/branding"; + +export const metadata: Metadata = { + title: `Terms of Service | ${brand.name}`, + description: `Terms governing your use of the ${brand.name} platform.`, +}; export default function TermsOfServicePage() { return ( -
- {/* Header */} -
-
-
- - - -
-

Terms of Service

-

- Last updated: {new Date().toLocaleDateString()} -

-
-
-
-
- - {/* Content */} -
-
- - - Agreement to Terms - - -

- These Terms of Service ("Terms") govern your use of - the beenvoice platform and services (the "Service") - operated by beenvoice ("us", "we", or - "our"). -

-

- By accessing or using our Service, you agree to be bound by - these Terms. If you disagree with any part of these terms, then - you may not access the Service. -

-
-
- - - - Description of Service - - -

- beenvoice is a web-based invoicing platform that allows users - to: -

-
    -
  • Create and manage professional invoices
  • -
  • Track client information and billing details
  • -
  • Monitor payment status and financial metrics
  • -
  • Generate reports and analytics
  • -
  • Manage business profiles and settings
  • -
-
-
- - - - User Accounts - - -

- When you create an account with us, you must provide information - that is accurate, complete, and current at all times. You are - responsible for safeguarding the password and for all activities - that occur under your account. -

-

- You agree not to disclose your password to any third party. You - must notify us immediately upon becoming aware of any breach of - security or unauthorized use of your account. -

-
-
- - - - Acceptable Use - - -

You agree not to use the Service:

-
    -
  • - For any unlawful purpose or to solicit others to perform - unlawful acts -
  • -
  • - To violate any international, federal, provincial, or state - regulations, rules, laws, or local ordinances -
  • -
  • - To infringe upon or violate our intellectual property rights - or the intellectual property rights of others -
  • -
  • - To harass, abuse, insult, harm, defame, slander, disparage, - intimidate, or discriminate -
  • -
  • To submit false or misleading information
  • -
  • - To upload or transmit viruses or any other type of malicious - code -
  • -
  • - To spam, phish, pharm, pretext, spider, crawl, or scrape -
  • -
  • For any obscene or immoral purpose
  • -
  • - To interfere with or circumvent the security features of the - Service -
  • -
-
-
- - - - Data and Privacy - - -

- Your privacy is important to us. Please review our Privacy - Policy, which also governs your use of the Service, to - understand our practices. -

-

- You retain ownership of your data. We will not sell, rent, or - share your personal information with third parties without your - explicit consent, except as described in our Privacy Policy. -

-

- You are responsible for backing up your data. While we implement - regular backups, we recommend you maintain your own copies of - important information. -

-
-
- - - - Payment Terms - - -

- Some aspects of the Service may require payment. You will be - charged according to your subscription plan. All fees are - non-refundable unless otherwise stated. -

-

- We may change our fees at any time. We will provide you with - reasonable notice of any fee changes by posting the new fees on - the Service or sending you email notification. -

-

- If you fail to pay any fees when due, we may suspend or - terminate your access to the Service until payment is made. -

-
-
- - - - Intellectual Property Rights - - -

- The Service and its original content, features, and - functionality are and will remain the exclusive property of - beenvoice and its licensors. The Service is protected by - copyright, trademark, and other laws. -

-

- Our trademarks and trade dress may not be used in connection - with any product or service without our prior written consent. -

-
-
- - - - Termination - - -

- We may terminate or suspend your account and bar access to the - Service immediately, without prior notice or liability, under - our sole discretion, for any reason whatsoever and without - limitation, including but not limited to a breach of the Terms. -

-

- If you wish to terminate your account, you may simply - discontinue using the Service and contact us to request account - deletion. -

-

- Upon termination, your right to use the Service will cease - immediately. If you wish to terminate your account, you may - simply discontinue using the Service. -

-
-
- - - - Disclaimer of Warranties - - -

- The information on this Service is provided on an "as - is" basis. To the fullest extent permitted by law, we - exclude all representations, warranties, and conditions relating - to our Service and the use of this Service. -

-

- Nothing in this disclaimer will limit or exclude our or your - liability for death or personal injury resulting from - negligence, fraud, or fraudulent misrepresentation. -

-
-
- - - - Limitation of Liability - - -

- In no event shall beenvoice, nor its directors, employees, - partners, agents, suppliers, or affiliates, be liable for any - indirect, incidental, special, consequential, or punitive - damages, including without limitation, loss of profits, data, - use, goodwill, or other intangible losses, resulting from your - use of the Service. -

-
-
- - - - Governing Law - - -

- These Terms shall be interpreted and governed by the laws of the - jurisdiction in which beenvoice operates, without regard to its - conflict of law provisions. -

-

- Our failure to enforce any right or provision of these Terms - will not be considered a waiver of those rights. -

-
-
- - - - Changes to Terms - - -

- We reserve the right, at our sole discretion, to modify or - replace these Terms at any time. If a revision is material, we - will provide at least 30 days notice prior to any new terms - taking effect. -

-

- What constitutes a material change will be determined at our - sole discretion. By continuing to access or use our Service - after any revisions become effective, you agree to be bound by - the revised terms. -

-
-
- - - - Contact Information - - -

- If you have any questions about these Terms of Service, please - contact us at: -

-
    -
  • Email: legal@beenvoice.com
  • -
  • Address: [Your Business Address]
  • -
-
-
-
-
-
+ + + ); } diff --git a/src/app/auth/forgot-password/page.tsx b/src/app/auth/forgot-password/page.tsx index 8c9c290..6d330ab 100644 --- a/src/app/auth/forgot-password/page.tsx +++ b/src/app/auth/forgot-password/page.tsx @@ -7,7 +7,7 @@ import { Button } from "~/components/ui/button"; import { Label } from "~/components/ui/label"; import { toast } from "sonner"; import { Logo } from "~/components/branding/logo"; -import { LegalModal } from "~/components/ui/legal-modal"; +import { LegalAgreementNotice } from "~/components/legal/legal-links"; import { Mail, ArrowRight, @@ -347,27 +347,10 @@ function ForgotPasswordForm() { -
- By using our service, you agree to our{" "} - - Terms of Service - - } - />{" "} - and{" "} - - Privacy Policy - - } - /> - . -
+ diff --git a/src/app/auth/register/page.tsx b/src/app/auth/register/page.tsx index 79f8caf..3b7f436 100644 --- a/src/app/auth/register/page.tsx +++ b/src/app/auth/register/page.tsx @@ -8,7 +8,7 @@ import { Button } from "~/components/ui/button"; import { Label } from "~/components/ui/label"; import { toast } from "sonner"; import { Logo } from "~/components/branding/logo"; -import { LegalModal } from "~/components/ui/legal-modal"; +import { LegalAgreementNotice } from "~/components/legal/legal-links"; import { Mail, Lock, ArrowRight, User } from "lucide-react"; function RegisterForm() { @@ -151,19 +151,7 @@ function RegisterForm() {

-

- By creating an account you agree to our{" "} - Terms} - />{" "} - and{" "} - Privacy Policy} - /> - . -

+ diff --git a/src/app/auth/reset-password/page.tsx b/src/app/auth/reset-password/page.tsx index 9c0eee1..5dd2d3e 100644 --- a/src/app/auth/reset-password/page.tsx +++ b/src/app/auth/reset-password/page.tsx @@ -8,7 +8,7 @@ import { Button } from "~/components/ui/button"; import { Label } from "~/components/ui/label"; import { toast } from "sonner"; import { Logo } from "~/components/branding/logo"; -import { LegalModal } from "~/components/ui/legal-modal"; +import { LegalAgreementNotice } from "~/components/legal/legal-links"; import { Lock, ArrowRight, @@ -425,27 +425,10 @@ function ResetPasswordForm() { -
- By resetting your password, you agree to our{" "} - - Terms of Service - - } - />{" "} - and{" "} - - Privacy Policy - - } - /> - . -
+ diff --git a/src/app/auth/signin/signin-form.tsx b/src/app/auth/signin/signin-form.tsx index add6aba..d2425a2 100644 --- a/src/app/auth/signin/signin-form.tsx +++ b/src/app/auth/signin/signin-form.tsx @@ -9,7 +9,7 @@ import { Button } from "~/components/ui/button"; import { Label } from "~/components/ui/label"; import { toast } from "sonner"; import { Logo } from "~/components/branding/logo"; -import { LegalModal } from "~/components/ui/legal-modal"; +import { LegalAgreementNotice } from "~/components/legal/legal-links"; import { env } from "~/env"; import { Mail, Lock, ArrowRight, Shield } from "lucide-react"; @@ -167,19 +167,7 @@ export function SignInForm({ allowRegistration }: SignInFormProps) {

)} -

- By signing in you agree to our{" "} - Terms} - />{" "} - and{" "} - Privacy Policy} - /> - . -

+ diff --git a/src/app/dashboard/settings/_components/settings-content.tsx b/src/app/dashboard/settings/_components/settings-content.tsx index 066200a..a6eddb4 100644 --- a/src/app/dashboard/settings/_components/settings-content.tsx +++ b/src/app/dashboard/settings/_components/settings-content.tsx @@ -29,6 +29,7 @@ import { useAuthSession } from "~/hooks/use-auth-session"; import * as React from "react"; import { useState } from "react"; +import Link from "next/link"; import { toast } from "sonner"; import { AlertDialog, @@ -84,6 +85,7 @@ import { import { useAppearance } from "~/components/providers/appearance-provider"; import { bodyFontPreferences, + brand, colorModes, colorThemes, type ColorTheme, @@ -701,6 +703,27 @@ export function SettingsContent() { )} + + + + + + Legal + + + Review how we handle your data and the terms for using{" "} + {brand.name} + + + + + + + diff --git a/src/app/page.tsx b/src/app/page.tsx index fc5b352..875f035 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -97,10 +97,10 @@ export default function HomePage() { © 2026 {brand.name}
- Privacy + Privacy Policy - Terms + Terms of Service
diff --git a/src/components/legal/legal-links.tsx b/src/components/legal/legal-links.tsx new file mode 100644 index 0000000..c6f448f --- /dev/null +++ b/src/components/legal/legal-links.tsx @@ -0,0 +1,43 @@ +import Link from "next/link"; + +import { cn } from "~/lib/utils"; + +type LegalLinksProps = { + className?: string; + linkClassName?: string; +}; + +export function LegalLinks({ className, linkClassName }: LegalLinksProps) { + const linkStyles = cn( + "text-foreground font-medium hover:underline", + linkClassName, + ); + + return ( + + + Terms of Service + + {" and "} + + Privacy Policy + + + ); +} + +type LegalAgreementNoticeProps = { + action: string; + className?: string; +}; + +export function LegalAgreementNotice({ + action, + className, +}: LegalAgreementNoticeProps) { + return ( +

+ By {action}, you agree to our . +

+ ); +} diff --git a/src/components/legal/legal-page-shell.tsx b/src/components/legal/legal-page-shell.tsx new file mode 100644 index 0000000..0f97486 --- /dev/null +++ b/src/components/legal/legal-page-shell.tsx @@ -0,0 +1,39 @@ +import Link from "next/link"; +import { ArrowLeft } from "lucide-react"; + +import { Button } from "~/components/ui/button"; +import { LEGAL_LAST_UPDATED } from "~/lib/legal"; + +type LegalPageShellProps = { + title: string; + children: React.ReactNode; +}; + +export function LegalPageShell({ title, children }: LegalPageShellProps) { + return ( +
+
+
+
+ + + +
+

{title}

+

+ Last updated: {LEGAL_LAST_UPDATED} +

+
+
+
+
+ +
+
{children}
+
+
+ ); +} diff --git a/src/components/legal/privacy-policy-content.tsx b/src/components/legal/privacy-policy-content.tsx new file mode 100644 index 0000000..6a9b427 --- /dev/null +++ b/src/components/legal/privacy-policy-content.tsx @@ -0,0 +1,373 @@ +import Link from "next/link"; + +import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card"; +import { + LEGAL_PRIVACY_EMAIL, + LEGAL_TERMS_EMAIL, + LEGAL_WEBSITE, +} from "~/lib/legal"; +import { brand } from "~/lib/branding"; + +export function PrivacyPolicyContent() { + return ( + <> + + + Introduction + + +

+ {brand.name} ("we", "our", or "us") is + committed to protecting your privacy. This Privacy Policy explains + how we collect, use, disclose, and safeguard your information when + you use our invoicing platform and services. +

+

+ Please read this Privacy Policy carefully. If you do not agree with + the terms of this Privacy Policy, please do not access or use our + Service. +

+
+
+ + + + Information We Collect + + +

Personal Information

+

+ We may collect personal information that you voluntarily provide to + us when you: +

+
    +
  • Register for an account
  • +
  • Create invoices or manage client information
  • +
  • Track time entries and billing activity
  • +
  • Contact us for support
  • +
  • Subscribe to our newsletters or communications
  • +
+ +

This personal information may include:

+
    +
  • Name and contact information (email, phone, address)
  • +
  • Business information and tax details
  • +
  • Client information you input into the system
  • +
  • Financial information related to your invoices
  • +
  • + Payment information (processed securely by third-party providers) +
  • +
+ +

Automatically Collected Information

+

+ We may automatically collect certain information when you visit our + Service: +

+
    +
  • + Device information (IP address, browser type, operating system) +
  • +
  • Usage data (pages visited, time spent, features used)
  • +
  • Log files and analytics data
  • +
  • Cookies and similar tracking technologies
  • +
+
+
+ + + + How We Use Your Information + + +

We use the information we collect to:

+
    +
  • Provide, operate, and maintain our Service
  • +
  • Process your transactions and manage your account
  • +
  • Improve and personalize your experience
  • +
  • Communicate with you about your account and our services
  • +
  • Send you technical notices and support messages
  • +
  • Respond to your comments, questions, and requests
  • +
  • Monitor usage and analyze trends
  • +
  • + Detect, prevent, and address technical issues and security + breaches +
  • +
  • Comply with legal obligations
  • +
+
+
+ + + + How We Share Your Information + + +

+ We do not sell, trade, or rent your personal information to third + parties. We may share your information in the following + circumstances: +

+ +

Service Providers

+

+ We may share your information with trusted third-party service + providers who assist us in operating our Service, such as: +

+
    +
  • Cloud hosting and storage providers
  • +
  • Payment processors
  • +
  • Email service providers
  • +
  • Analytics and monitoring services
  • +
+ +

Legal Requirements

+

+ We may disclose your information if required to do so by law or in + response to: +

+
    +
  • Legal processes (subpoenas, court orders)
  • +
  • Government requests
  • +
  • Law enforcement investigations
  • +
  • Protection of our rights, property, or safety
  • +
+ +

Business Transfers

+

+ In the event of a merger, acquisition, or sale of assets, your + information may be transferred as part of that transaction. +

+
+
+ + + + Data Security + + +

+ We implement appropriate technical and organizational security + measures to protect your information: +

+
    +
  • Encryption of data in transit and at rest
  • +
  • Secure access controls and authentication
  • +
  • Regular security assessments and updates
  • +
  • Employee training on data protection
  • +
  • Incident response procedures
  • +
+

+ However, no method of transmission over the internet or electronic + storage is 100% secure. While we strive to protect your information, + we cannot guarantee absolute security. +

+
+
+ + + + Data Retention + + +

+ We retain your personal information only for as long as necessary to + fulfill the purposes outlined in this Privacy Policy, unless a + longer retention period is required by law. +

+

+ Factors we consider when determining retention periods include: +

+
    +
  • The nature and sensitivity of the information
  • +
  • Legal and regulatory requirements
  • +
  • Business and operational needs
  • +
  • Your account status and activity
  • +
+
+
+ + + + Your Rights and Choices + + +

+ Depending on your location, you may have the following rights + regarding your personal information: +

+ +

Access and Portability

+
    +
  • Request access to your personal information
  • +
  • Receive a copy of your data in a portable format
  • +
+ +

Correction and Updates

+
    +
  • Correct inaccurate or incomplete information
  • +
  • Update your account information at any time
  • +
+ +

Deletion

+
    +
  • Request deletion of your personal information
  • +
  • Close your account and remove your data
  • +
+ +

Restriction and Objection

+
    +
  • Restrict the processing of your information
  • +
  • Object to certain uses of your data
  • +
+ +

+ To exercise these rights, please contact us using the information + provided in the "Contact Us" section below. +

+
+
+ + + + Cookies and Tracking Technologies + + +

We use cookies and similar technologies to:

+
    +
  • Remember your preferences and settings
  • +
  • Authenticate your account
  • +
  • Analyze usage patterns and improve our Service
  • +
  • Provide personalized content and features
  • +
+ +

+ You can control cookies through your browser settings. However, + disabling cookies may affect the functionality of our Service. +

+ +

Types of Cookies We Use

+
    +
  • + Essential Cookies: Required for the Service to + function properly +
  • +
  • + Analytics Cookies: Help us understand how you use + our Service +
  • +
  • + Preference Cookies: Remember your settings and + preferences +
  • +
+
+
+ + + + Third-Party Links and Services + + +

+ Our Service may contain links to third-party websites or integrate + with third-party services. We are not responsible for the privacy + practices of these third parties. +

+

+ We encourage you to read the privacy policies of any third-party + services you use in connection with our Service. +

+
+
+ + + + Children's Privacy + + +

+ Our Service is not intended for children under the age of 13. We do + not knowingly collect personal information from children under 13. +

+

+ If you are a parent or guardian and believe your child has provided + us with personal information, please contact us immediately so we + can remove such information. +

+
+
+ + + + International Data Transfers + + +

+ Your information may be transferred to and processed in countries + other than your own. We ensure that such transfers comply with + applicable data protection laws. +

+

+ When we transfer your information internationally, we implement + appropriate safeguards to protect your data, including: +

+
    +
  • Standard contractual clauses
  • +
  • Adequacy decisions by relevant authorities
  • +
  • Certified privacy frameworks
  • +
+
+
+ + + + Changes to This Privacy Policy + + +

+ We may update this Privacy Policy from time to time. We will notify + you of any material changes by: +

+
    +
  • Posting the updated policy on our Service
  • +
  • Sending you an email notification
  • +
  • Displaying a prominent notice on our Service
  • +
+

+ Your continued use of our Service after any changes indicates your + acceptance of the updated Privacy Policy. +

+
+
+ + + + Contact Us + + +

+ If you have questions about this Privacy Policy or our privacy + practices, please contact us at: +

+ +

+ We will respond to your inquiries within a reasonable timeframe and + in accordance with applicable law. +

+
+
+ + ); +} diff --git a/src/components/legal/terms-of-service-content.tsx b/src/components/legal/terms-of-service-content.tsx new file mode 100644 index 0000000..aee8e58 --- /dev/null +++ b/src/components/legal/terms-of-service-content.tsx @@ -0,0 +1,291 @@ +import Link from "next/link"; + +import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card"; +import { + LEGAL_PRIVACY_EMAIL, + LEGAL_TERMS_EMAIL, + LEGAL_WEBSITE, +} from "~/lib/legal"; +import { brand } from "~/lib/branding"; + +export function TermsOfServiceContent() { + return ( + <> + + + Agreement to Terms + + +

+ These Terms of Service ("Terms") govern your use of the{" "} + {brand.name} platform and services (the "Service") operated + by {brand.name} ("us", "we", or "our"). +

+

+ By accessing or using our Service, you agree to be bound by these + Terms. If you disagree with any part of these terms, then you may not + access the Service. +

+
+
+ + + + Description of Service + + +

+ {brand.name} is a web-based invoicing platform that allows users to: +

+
    +
  • Create and manage professional invoices
  • +
  • Track client information and billing details
  • +
  • Clock time and convert entries into billable work
  • +
  • Monitor payment status and financial metrics
  • +
  • Generate reports and analytics
  • +
  • Manage business profiles and settings
  • +
+
+
+ + + + User Accounts + + +

+ When you create an account with us, you must provide information that + is accurate, complete, and current at all times. You are responsible + for safeguarding the password and for all activities that occur + under your account. +

+

+ You agree not to disclose your password to any third party. You must + notify us immediately upon becoming aware of any breach of security + or unauthorized use of your account. +

+
+
+ + + + Acceptable Use + + +

You agree not to use the Service:

+
    +
  • + For any unlawful purpose or to solicit others to perform unlawful + acts +
  • +
  • + To violate any international, federal, provincial, or state + regulations, rules, laws, or local ordinances +
  • +
  • + To infringe upon or violate our intellectual property rights or + the intellectual property rights of others +
  • +
  • + To harass, abuse, insult, harm, defame, slander, disparage, + intimidate, or discriminate +
  • +
  • To submit false or misleading information
  • +
  • + To upload or transmit viruses or any other type of malicious code +
  • +
  • To spam, phish, pharm, pretext, spider, crawl, or scrape
  • +
  • For any obscene or immoral purpose
  • +
  • + To interfere with or circumvent the security features of the + Service +
  • +
+
+
+ + + + Data and Privacy + + +

+ Your privacy is important to us. Please review our{" "} + Privacy Policy, which also governs your + use of the Service, to understand our practices. +

+

+ You retain ownership of your data. We will not sell, rent, or share + your personal information with third parties without your explicit + consent, except as described in our Privacy Policy. +

+

+ You are responsible for backing up your data. While we implement + regular backups, we recommend you maintain your own copies of + important information. +

+
+
+ + + + Payment Terms + + +

+ Some aspects of the Service may require payment. You will be charged + according to your subscription plan. All fees are non-refundable + unless otherwise stated. +

+

+ We may change our fees at any time. We will provide you with + reasonable notice of any fee changes by posting the new fees on the + Service or sending you email notification. +

+

+ If you fail to pay any fees when due, we may suspend or terminate + your access to the Service until payment is made. +

+
+
+ + + + Intellectual Property Rights + + +

+ The Service and its original content, features, and functionality + are and will remain the exclusive property of {brand.name} and its + licensors. The Service is protected by copyright, trademark, and + other laws. +

+

+ Our trademarks and trade dress may not be used in connection with + any product or service without our prior written consent. +

+
+
+ + + + Termination + + +

+ We may terminate or suspend your account and bar access to the + Service immediately, without prior notice or liability, under our + sole discretion, for any reason whatsoever and without limitation, + including but not limited to a breach of the Terms. +

+

+ If you wish to terminate your account, you may discontinue using the + Service and contact us to request account deletion. +

+

+ Upon termination, your right to use the Service will cease + immediately. +

+
+
+ + + + Disclaimer of Warranties + + +

+ The information on this Service is provided on an "as is" + basis. To the fullest extent permitted by law, we exclude all + representations, warranties, and conditions relating to our Service + and the use of this Service. +

+

+ Nothing in this disclaimer will limit or exclude our or your + liability for death or personal injury resulting from negligence, + fraud, or fraudulent misrepresentation. +

+
+
+ + + + Limitation of Liability + + +

+ In no event shall {brand.name}, nor its directors, employees, + partners, agents, suppliers, or affiliates, be liable for any + indirect, incidental, special, consequential, or punitive damages, + including without limitation, loss of profits, data, use, goodwill, or + other intangible losses, resulting from your use of the Service. +

+
+
+ + + + Governing Law + + +

+ These Terms shall be interpreted and governed by the laws of the + jurisdiction in which {brand.name} operates, without regard to its + conflict of law provisions. +

+

+ Our failure to enforce any right or provision of these Terms will + not be considered a waiver of those rights. +

+
+
+ + + + Changes to Terms + + +

+ We reserve the right, at our sole discretion, to modify or replace + these Terms at any time. If a revision is material, we will provide + at least 30 days notice prior to any new terms taking effect. +

+

+ What constitutes a material change will be determined at our sole + discretion. By continuing to access or use our Service after any + revisions become effective, you agree to be bound by the revised + terms. +

+
+
+ + + + Contact Information + + +

+ If you have any questions about these Terms of Service, please + contact us at: +

+ +
+
+ + ); +} diff --git a/src/components/ui/legal-modal.tsx b/src/components/ui/legal-modal.tsx deleted file mode 100644 index fc3ff2b..0000000 --- a/src/components/ui/legal-modal.tsx +++ /dev/null @@ -1,350 +0,0 @@ -"use client"; - -import { useState } from "react"; -import { - Dialog, - DialogContent, - DialogHeader, - DialogTitle, -} from "~/components/ui/dialog"; -import { Button } from "~/components/ui/button"; -import { ScrollArea } from "~/components/ui/scroll-area"; -import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card"; -import { X } from "lucide-react"; - -interface LegalModalProps { - type: "terms" | "privacy"; - trigger: React.ReactNode; -} - -export function LegalModal({ type, trigger }: LegalModalProps) { - const [open, setOpen] = useState(false); - - const isTerms = type === "terms"; - const title = isTerms ? "Terms of Service" : "Privacy Policy"; - - return ( - - setOpen(true)}> - {trigger} - - - - - {title} - - - - - {isTerms ? : } - -
- -
-
-
- ); -} - -function TermsContent() { - return ( -
- - - Agreement to Terms - - -

- These Terms of Service ("Terms") govern your use of the - beenvoice platform and services (the "Service") operated - by beenvoice ("us", "we", or "our"). -

-

- By accessing or using our Service, you agree to be bound by these - Terms. If you disagree with any part of these terms, then you may - not access the Service. -

-
-
- - - - Description of Service - - -

- beenvoice is a web-based invoicing platform that allows users to: -

-
    -
  • Create and manage professional invoices
  • -
  • Track client information and billing details
  • -
  • Monitor payment status and financial metrics
  • -
  • Generate reports and analytics
  • -
  • Manage business profiles and settings
  • -
-
-
- - - - User Accounts - - -

- When you create an account with us, you must provide information - that is accurate, complete, and current at all times. You are - responsible for safeguarding the password and for all activities - that occur under your account. -

-

- You agree not to disclose your password to any third party. You must - notify us immediately upon becoming aware of any breach of security - or unauthorized use of your account. -

-
-
- - - - Acceptable Use - - -

You agree not to use the Service:

-
    -
  • - For any unlawful purpose or to solicit others to perform unlawful - acts -
  • -
  • - To violate any international, federal, provincial, or state - regulations, rules, laws, or local ordinances -
  • -
  • - To infringe upon or violate our intellectual property rights or - the intellectual property rights of others -
  • -
  • - To harass, abuse, insult, harm, defame, slander, disparage, - intimidate, or discriminate -
  • -
  • To submit false or misleading information
  • -
  • - To upload or transmit viruses or any other type of malicious code -
  • -
  • To spam, phish, pharm, pretext, spider, crawl, or scrape
  • -
  • For any obscene or immoral purpose
  • -
  • - To interfere with or circumvent the security features of the - Service -
  • -
-
-
- - - - Payment Terms - - -

- Some aspects of the Service may require payment. You will be charged - according to your subscription plan. All fees are non-refundable - unless otherwise stated. -

-

- We may change our fees at any time. We will provide you with - reasonable notice of any fee changes by posting the new fees on the - Service or sending you email notification. -

-
-
- - - - Termination - - -

- We may terminate or suspend your account and bar access to the - Service immediately, without prior notice or liability, under our - sole discretion, for any reason whatsoever and without limitation, - including but not limited to a breach of the Terms. -

-

- If you wish to terminate your account, you may simply discontinue - using the Service and contact us to request account deletion. -

-
-
- - - - Contact Information - - -

- If you have any questions about these Terms of Service, please - contact us at: -

-
    -
  • Email: legal@beenvoice.com
  • -
-
-
-
- ); -} - -function PrivacyContent() { - return ( -
- - - Information We Collect - - -

Personal Information

-

- We may collect personal information that you voluntarily provide to - us when you: -

-
    -
  • Register for an account
  • -
  • Create invoices or manage client information
  • -
  • Contact us for support
  • -
-

This personal information may include:

-
    -
  • Name and contact information (email, phone, address)
  • -
  • Business information and tax details
  • -
  • Client information you input into the system
  • -
  • Financial information related to your invoices
  • -
-
-
- - - - How We Use Your Information - - -

We use the information we collect to:

-
    -
  • Provide, operate, and maintain our Service
  • -
  • Process your transactions and manage your account
  • -
  • Improve and personalize your experience
  • -
  • Communicate with you about your account and our services
  • -
  • Send you technical notices and support messages
  • -
  • Respond to your comments, questions, and requests
  • -
  • Monitor usage and analyze trends
  • -
  • - Detect, prevent, and address technical issues and security - breaches -
  • -
-
-
- - - - How We Share Your Information - - -

- We do not sell, trade, or rent your personal information to third - parties. We may share your information in the following - circumstances: -

- -

Service Providers

-

- We may share your information with trusted third-party service - providers who assist us in operating our Service, such as: -

-
    -
  • Cloud hosting and storage providers
  • -
  • Payment processors
  • -
  • Email service providers
  • -
  • Analytics and monitoring services
  • -
- -

Legal Requirements

-

- We may disclose your information if required to do so by law or in - response to: -

-
    -
  • Legal processes (subpoenas, court orders)
  • -
  • Government requests
  • -
  • Law enforcement investigations
  • -
  • Protection of our rights, property, or safety
  • -
-
-
- - - - Data Security - - -

- We implement appropriate technical and organizational security - measures to protect your information: -

-
    -
  • Encryption of data in transit and at rest
  • -
  • Secure access controls and authentication
  • -
  • Regular security assessments and updates
  • -
  • Employee training on data protection
  • -
  • Incident response procedures
  • -
-
-
- - - - Your Rights and Choices - - -

- Depending on your location, you may have the following rights - regarding your personal information: -

-
    -
  • Request access to your personal information
  • -
  • Correct inaccurate or incomplete information
  • -
  • Request deletion of your personal information
  • -
  • Restrict the processing of your information
  • -
  • Object to certain uses of your data
  • -
-

- To exercise these rights, please contact us at - privacy@beenvoice.com. -

-
-
- - - - Contact Us - - -

- If you have questions about this Privacy Policy or our privacy - practices, please contact us at: -

-
    -
  • Email: privacy@beenvoice.com
  • -
-
-
-
- ); -} diff --git a/src/lib/legal.ts b/src/lib/legal.ts new file mode 100644 index 0000000..deb8732 --- /dev/null +++ b/src/lib/legal.ts @@ -0,0 +1,5 @@ +export const LEGAL_LAST_UPDATED = "June 18, 2026"; + +export const LEGAL_PRIVACY_EMAIL = "privacy@beenvoice.com"; +export const LEGAL_TERMS_EMAIL = "legal@beenvoice.com"; +export const LEGAL_WEBSITE = "https://beenvoice.com";