Skip to content

add pricing calculator#214

Merged
KMKoushik merged 3 commits intomainfrom
km/2025-09-06-landing-page-update
Sep 6, 2025
Merged

add pricing calculator#214
KMKoushik merged 3 commits intomainfrom
km/2025-09-06-landing-page-update

Conversation

@KMKoushik
Copy link
Copy Markdown
Member

@KMKoushik KMKoushik commented Sep 5, 2025

Summary by CodeRabbit

  • New Features
    • Added an interactive Pricing Calculator, SiteFooter, and live Status badge.
  • Enhancements
    • Replaced hero images with optimized light/dark WEBP variants.
    • Feature cards now show theme-aware light/dark images.
    • GitHub links updated to point to the usesend/usesend repo.
    • Refreshed pricing copy for clearer messaging.
  • Style
    • Adjusted card foreground colors for improved readability in both themes.

@vercel
Copy link
Copy Markdown

vercel bot commented Sep 5, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
unsend-marketing Ready Ready Preview Comment Sep 6, 2025 0:54am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Sep 5, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Adds a PricingCalculator UI component, a SiteFooter, and a StatusBadge; updates FeatureCard to support light/dark images and switches hero/assets to webp; changes repository constants (unsend → usesend) in several components; adjusts a design token in globals.css and integrates the pricing calculator into the marketing page.

Changes

Cohort / File(s) Summary
Marketing page & integration
apps/marketing/src/app/page.tsx
Replaced hero PNGs with WEBP, updated features to pass imageLightSrc/imageDarkSrc, swapped Footer for new SiteFooter, updated pricing copy, and renders PricingCalculator.
Feature card theming API
apps/marketing/src/components/FeatureCard.tsx
Introduces FeatureCardProps with imageLightSrc/imageDarkSrc (keeps deprecated imageSrc), renders theme-aware images (light/dark) with overflow clipping and a bottom gradient overlay.
New pricing UI
apps/marketing/src/components/PricingCalculator.tsx
Adds client-side slider-based pricing estimator (marketing + transactional), computes line items and min-monthly spend, accessible labels, exported as named and default.
Footer & branding
apps/marketing/src/components/SiteFooter.tsx
Adds new SiteFooter component rendering logo/links/status and current year; internal links via Next.js Link, external open in new tab.
Status & uptime
apps/marketing/src/components/StatusBadge.tsx
Adds StatusBadge client component that fetches uptime data, derives `operational
Repo constant updates
apps/marketing/src/components/GitHubStarsButton.tsx, apps/marketing/src/components/TopNav.tsx
Updated REPO constant from unsend-dev/unsend to usesend/usesend (affects REPO_URL / API_URL usage).
Design tokens
packages/ui/styles/globals.css
Adjusted --card-foreground values for light and dark themes; no other token changes.
Misc (exports/types)
apps/marketing/src/components/FeatureCard.tsx
Public API change: FeatureCard prop signature updated to accept imageLightSrc/imageDarkSrc; imageSrc marked deprecated.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Page as Marketing Page
  participant PC as PricingCalculator
  participant UI as Pricing UI

  User->>Page: Open /pricing section
  Page->>PC: Mount PricingCalculator
  PC->>UI: Render sliders + initial calculations
  User->>PC: Drag Marketing slider
  PC->>PC: Recompute marketingCost, subtotal, totalDue
  PC->>UI: Update displayed values
  User->>PC: Drag Transactional slider
  PC->>PC: Recompute transactionalCost, subtotal, totalDue
  PC->>UI: Update displayed values
Loading
sequenceDiagram
  autonumber
  participant Badge as StatusBadge
  participant API as Uptime API
  participant UI as Badge UI

  Badge->>API: fetch(baseUrl + /api/status-page/heartbeat/...)
  API-->>Badge: JSON response
  Badge->>Badge: Heuristics -> (operational|degraded|down|unknown)
  Badge->>UI: Render color dot + label + link
  Note right of Badge: Polls every 60s (useEffect + cleanup)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • add rebrand landing page #211 — Overlapping marketing UI changes: page, FeatureCard, TopNav, and GitHubStarsButton modifications (shared file targets and repo constant edits).
  • add pricing calculator #214 — Adds PricingCalculator and FeatureCard theme/image updates; closely matches the new pricing UI and image format changes.
  • rebrand to useSend #210 — Repository-wide rebrand edits from unsendusesend; related to REPO constant updates in this PR.

Poem

I nibble code beneath the moonlit stack,
Two sliders hum and images switch track.
A footer planted, status dot aglow,
WebP sprites hop where PNGs used to show.
My whiskers twitch — deploy, then snack! 🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 63b054a and b2e89c1.

📒 Files selected for processing (6)
  • apps/marketing/src/app/page.tsx (9 hunks)
  • apps/marketing/src/components/FeatureCard.tsx (2 hunks)
  • apps/marketing/src/components/GitHubStarsButton.tsx (1 hunks)
  • apps/marketing/src/components/SiteFooter.tsx (1 hunks)
  • apps/marketing/src/components/StatusBadge.tsx (1 hunks)
  • apps/marketing/src/components/TopNav.tsx (1 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch km/2025-09-06-landing-page-update

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying unsend with  Cloudflare Pages  Cloudflare Pages

Latest commit: 63b054a
Status:🚫  Build failed.

View logs

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (6)
apps/marketing/src/components/FeatureCard.tsx (2)

30-43: Add sizes for next/image with fill to avoid layout warnings and improve responsiveness.

Apply:

                 <Image
                   src={(imageLightSrc || imageDarkSrc)!}
                   alt={title || "Feature image"}
                   fill
+                  sizes="(min-width: 640px) 50vw, 100vw"
                   className="object-cover dark:hidden rounded-t-xl"
                   priority={false}
                 />
                 <Image
                   src={(imageDarkSrc || imageLightSrc)!}
                   alt={title || "Feature image"}
                   fill
+                  sizes="(min-width: 640px) 50vw, 100vw"
                   className="object-cover hidden dark:block rounded-t-xl"
                   priority={false}
                 />

56-69: Use webp fallbacks (to match page hero) and add sizes.

Aligns with the new assets and keeps performance consistent.

-                <Image
-                  src="/hero-light.png"
+                <Image
+                  src="/hero-light.webp"
                   alt="Feature image"
                   fill
+                  sizes="(min-width: 640px) 50vw, 100vw"
                   className="object-cover dark:hidden rounded-t-xl"
                   priority={false}
                 />
-                <Image
-                  src="/hero-dark.png"
+                <Image
+                  src="/hero-dark.webp"
                   alt="Feature image"
                   fill
+                  sizes="(min-width: 640px) 50vw, 100vw"
                   className="object-cover hidden dark:block rounded-t-xl"
                   priority={false}
                 />
apps/marketing/src/components/PricingCalculator.tsx (3)

91-94: Fix comment to match the actual defaults.

-  // Defaults chosen to total $10: 8000*$0.001 + 5000*$0.0004 = 10
+  // Defaults chosen to total $10: 5000*$0.001 + 12500*$0.0004 = 10

135-168: Optional: Use Intl.NumberFormat for currency for locale-safe formatting.

+  const fmtUSD = React.useMemo(
+    () => new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }),
+    []
+  );
...
-                  ${marketingCost.toFixed(2)}
+                  {fmtUSD.format(marketingCost)}
...
-                  @ ${MARKETING_RATE.toFixed(4)} each
+                  @ {MARKETING_RATE.toFixed(4)} each
...
-                  ${transactionalCost.toFixed(2)}
+                  {fmtUSD.format(transactionalCost)}
...
-                  @ ${TRANSACTIONAL_RATE.toFixed(4)} each
+                  @ {TRANSACTIONAL_RATE.toFixed(4)} each
...
-                  ${totalDue.toFixed(2)}
+                  {fmtUSD.format(totalDue)}

70-79: Optional: Prevent tooltip clipping at the slider edges.

Clamp the badge position a bit inside the track.

-        {dragging && (
+        {dragging && (
           <div
-            className="pointer-events-none absolute -top-9 left-0 -translate-x-1/2"
-            style={{ left: `${percent}%` }}
+            className="pointer-events-none absolute -top-9 left-0"
+            style={{ left: `${Math.min(97, Math.max(3, percent))}%`, transform: "translateX(-50%)" }}
           >
apps/marketing/src/app/page.tsx (1)

377-377: Polish the pricing subheading copy.

Capitalize and consider an em dash for readability.

-            pay for what you use, the most affordable email platform
+            Pay for what you use — the most affordable email platform
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 79d1eba and 63b054a.

⛔ Files ignored due to path filters (2)
  • apps/marketing/public/hero-dark.png is excluded by !**/*.png
  • apps/marketing/public/hero-light.png is excluded by !**/*.png
📒 Files selected for processing (4)
  • apps/marketing/src/app/page.tsx (7 hunks)
  • apps/marketing/src/components/FeatureCard.tsx (1 hunks)
  • apps/marketing/src/components/PricingCalculator.tsx (1 hunks)
  • packages/ui/styles/globals.css (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

Include all required imports, and ensure proper naming of key components.

Files:

  • apps/marketing/src/components/PricingCalculator.tsx
  • apps/marketing/src/app/page.tsx
  • apps/marketing/src/components/FeatureCard.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Prefer TypeScript for implementation files (TypeScript-first)
ESLint must pass with zero warnings using @usesend/eslint-config before PRs

Files:

  • apps/marketing/src/components/PricingCalculator.tsx
  • apps/marketing/src/app/page.tsx
  • apps/marketing/src/components/FeatureCard.tsx
**/*.{ts,tsx,md}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,md}: Use 2-space indentation and keep semicolons as enforced by Prettier 3
Run Prettier 3 formatting (pnpm format) over TypeScript and Markdown files

Files:

  • apps/marketing/src/components/PricingCalculator.tsx
  • apps/marketing/src/app/page.tsx
  • apps/marketing/src/components/FeatureCard.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Name React component files in PascalCase (e.g., AppSideBar.tsx)

Files:

  • apps/marketing/src/components/PricingCalculator.tsx
  • apps/marketing/src/app/page.tsx
  • apps/marketing/src/components/FeatureCard.tsx
🧬 Code graph analysis (1)
apps/marketing/src/app/page.tsx (1)
apps/marketing/src/components/PricingCalculator.tsx (1)
  • PricingCalculator (85-175)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (7)
packages/ui/styles/globals.css (1)

12-12: Contrast passes WCAG standards
Computed contrast ratios are ~8.1:1 against the light background and ~13.8:1 against the dark background—both exceed the 4.5:1 minimum.

apps/marketing/src/components/FeatureCard.tsx (1)

5-15: API extension looks good.

Prop typing and deprecation strategy are clear and backward-compatible.

Also applies to: 19-23

apps/marketing/src/app/page.tsx (5)

8-8: LGTM: PricingCalculator import.


65-65: LGTM: Switch to webp hero assets.

Good perf improvement and consistency with other imagery.

Also applies to: 75-75


226-228: LGTM: Migration to light/dark image variants for features.

Prop usage matches the updated FeatureCard API.

Also applies to: 234-236, 277-279


396-398: LGTM: PricingCalculator placement under the pricing cards.


157-173: Domains whitelist not needed with unoptimized static export
apps/marketing/next.config.js already sets images.unoptimized: true for output: "export", so Next.js will render plain <img> tags and bypass the image‐optimization pipeline (including domain checks) (nextjs.org, vercel.com)

Likely an incorrect or invalid review comment.

@KMKoushik KMKoushik merged commit 69470a4 into main Sep 6, 2025
3 of 5 checks passed
@KMKoushik KMKoushik deleted the km/2025-09-06-landing-page-update branch September 6, 2025 00:53
KMKoushik added a commit that referenced this pull request Sep 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant