Skip to content

fix(ui): calendly height + prominent share bar - #2410

Merged
smakosh merged 2 commits into
mainfrom
fix/calendly-ui-share-button
May 25, 2026
Merged

smakosh merged 2 commits into
mainfrom
fix/calendly-ui-share-button

Conversation

@smakosh

@smakosh smakosh commented May 25, 2026 •

Copy link
Copy Markdown
Member

Branched off latest main. Two apps/ui fixes.

1. Enterprise Calendly widget rendered as a sliver / loaded forever

The inline embed container had only min-h-[700px]. Calendly injects an iframe with height:100%, and a percentage height needs a definite parent height, so it collapsed to a thin strip with a perpetual loading spinner below it (per the reported screenshot).

Fixes in calendly-inline.tsx:

  • Explicit responsive height on the container (h-[1040px] mobile / sm:h-[720px]) so the iframe fills it.
  • Guard against double-initialization (re-initializing into the same node leaves Calendly stuck on its spinner).
  • Theme the widget for dark mode (background_color / text_color) and hide_gdpr_banner, so the white panel no longer clashes with the dark page.
  • Added an "Open the scheduler in a new tab" fallback link.

2. Token cost calculator share button was easy to miss

Replaced the small, right-aligned "Share Results" dropdown with a prominent share bar.

  • frontend-design: branded blue gradient panel, icon badge, clear hierarchy — it now reads as a deliberate moment, not an afterthought.
  • marketing psychology: IKEA effect + social proof (the visitor built the comparison, so the CTA frames it as "Share your X% savings" — a flex worth posting), and EAST / Hick's Law (Copy, X, and LinkedIn are now one-click visible actions instead of buried in a dropdown), lowering friction to drive organic/referral sharing.

Testing

  • pnpm format ✅
  • pnpm turbo run build --filter=ui ✅ (13/13)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Enhanced social sharing with direct copy link, X, and LinkedIn buttons in the token cost calculator.
    • Improved Calendly widget with dark mode support and direct scheduler link in text prompt.
  • Style

    • Updated Calendly container with improved border and background styling.

Review Change Stack

- Calendly inline embed now sets an explicit responsive height on the
  container (the injected iframe uses height:100%, which collapsed with
  only a min-height, causing the tiny strip + endless spinner). Also
  guard against double-init, theme the widget for dark mode, and add an
  "open in new tab" fallback link.
- Replace the hidden "Share Results" dropdown on the token cost
  calculator with a prominent share bar: branded gradient, savings-led
  copy, and one-click Copy / X / LinkedIn actions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 25, 2026 •

Copy link
Copy Markdown
Contributor

Walkthrough

Two independent UI component refinements: Calendly inline widget initialization is now guarded by a per-mount ref and applies dark-mode-aware theming; token calculator share UI is simplified from a dropdown menu to an inline bar with copy and social-link buttons.

Changes

Calendly Inline Widget Enhancement

Layer / File(s) Summary
Widget initialization with theme parameters
apps/ui/src/components/enterprise/calendly-inline.tsx
initializedRef ensures Calendly widget initialization runs once per mount after the script loads and container ref is available; widgetUrl is built with query parameters to hide GDPR banner and set dark-mode-aware primary color, background, and text colors from the document root class.
Container and scheduler link UI
apps/ui/src/components/enterprise/calendly-inline.tsx
Rendered container gains explicit height styling and visual classes; a new paragraph with an external link (opening in new tab) prompts users to navigate to the Calendly scheduler.

Token Calculator Share UI Simplification

Layer / File(s) Summary
Share bar UI replacement
apps/ui/src/components/token-cost-calculator/token-cost-calculator-client.tsx
Dropdown-menu imports are removed; dropdown share controls are replaced with an inline share bar containing a copy-link button (toggling to "Copied!" via copied state and handleCopy) and direct external link buttons for X and LinkedIn (using existing xShareUrl and linkedinShareUrl).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • theopenco/llmgateway#2408: Updates the same CalendlyInline and token-cost-calculator components with overlapping UI and logic changes.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the two main changes: Calendly height fix and a prominent share bar redesign.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/calendly-ui-share-button

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.

@smakosh smakosh self-assigned this May 25, 2026
@smakosh
smakosh enabled auto-merge May 25, 2026 19:23

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/ui/src/components/enterprise/calendly-inline.tsx`:
- Around line 47-58: The code sets initializedRef.current = true before
constructing widgetUrl and calling window.Calendly.initInlineWidget, which can
permanently block re-init if URL parsing or init throws; change the flow to
perform the URL construction and call window.Calendly.initInlineWidget first
(wrap these steps in a try/catch to handle errors) and only set
initializedRef.current = true after init completes successfully, ensuring
failures do not leave initializedRef stuck true; reference the initializedRef,
widgetUrl, and window.Calendly.initInlineWidget symbols when making this change.
- Around line 83-90: Replace the raw anchor in the CalendlyInline component with
Next.js' Link: import Link from "next/link", swap the <a href={url} ...>Open the
scheduler</a> for <Link href={url} ...>Open the scheduler</Link>, preserving
className, target="_blank" and rel="noopener noreferrer" props (and any other
props like aria attributes) so behavior and styling remain the same; update any
surrounding code that expects an HTMLAnchorElement if necessary (e.g., event
handlers) to use the Link component instead.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3d5f61e1-e1cf-4e10-ba48-4358ad971e94

📥 Commits

Reviewing files that changed from the base of the PR and between 2aa6ab2 and 710821d.

📒 Files selected for processing (2)
  • apps/ui/src/components/enterprise/calendly-inline.tsx
  • apps/ui/src/components/token-cost-calculator/token-cost-calculator-client.tsx

Comment on lines +47 to +58
initializedRef.current = true;

const widgetUrl = new URL(url);
widgetUrl.searchParams.set("hide_gdpr_banner", "1");
widgetUrl.searchParams.set("primary_color", "2563eb");
if (document.documentElement.classList.contains("dark")) {
widgetUrl.searchParams.set("background_color", "0a0a0a");
widgetUrl.searchParams.set("text_color", "e4e4e7");
}

window.Calendly.initInlineWidget({
url,
url: widgetUrl.toString(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Set initializedRef only after successful widget init.

initializedRef.current = true happens before URL parsing/init. If either throws, the component is permanently locked out of re-initialization for that mount.

Proposed fix
-		initializedRef.current = true;
-
-		const widgetUrl = new URL(url);
+		const widgetUrl = new URL(url);
 		widgetUrl.searchParams.set("hide_gdpr_banner", "1");
 		widgetUrl.searchParams.set("primary_color", "2563eb");
 		if (document.documentElement.classList.contains("dark")) {
 			widgetUrl.searchParams.set("background_color", "0a0a0a");
 			widgetUrl.searchParams.set("text_color", "e4e4e7");
 		}
 
 		window.Calendly.initInlineWidget({
 			url: widgetUrl.toString(),
 			parentElement: container,
 			prefill: { name, email },
 		});
+		initializedRef.current = true;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
initializedRef.current = true;
const widgetUrl = new URL(url);
widgetUrl.searchParams.set("hide_gdpr_banner", "1");
widgetUrl.searchParams.set("primary_color", "2563eb");
if (document.documentElement.classList.contains("dark")) {
widgetUrl.searchParams.set("background_color", "0a0a0a");
widgetUrl.searchParams.set("text_color", "e4e4e7");
}
window.Calendly.initInlineWidget({
url,
url: widgetUrl.toString(),
const widgetUrl = new URL(url);
widgetUrl.searchParams.set("hide_gdpr_banner", "1");
widgetUrl.searchParams.set("primary_color", "2563eb");
if (document.documentElement.classList.contains("dark")) {
widgetUrl.searchParams.set("background_color", "0a0a0a");
widgetUrl.searchParams.set("text_color", "e4e4e7");
}
window.Calendly.initInlineWidget({
url: widgetUrl.toString(),
parentElement: container,
prefill: { name, email },
});
initializedRef.current = true;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/ui/src/components/enterprise/calendly-inline.tsx` around lines 47 - 58,
The code sets initializedRef.current = true before constructing widgetUrl and
calling window.Calendly.initInlineWidget, which can permanently block re-init if
URL parsing or init throws; change the flow to perform the URL construction and
call window.Calendly.initInlineWidget first (wrap these steps in a try/catch to
handle errors) and only set initializedRef.current = true after init completes
successfully, ensuring failures do not leave initializedRef stuck true;
reference the initializedRef, widgetUrl, and window.Calendly.initInlineWidget
symbols when making this change.

Comment on lines +83 to +90
<a
href={url}
target="_blank"
rel="noopener noreferrer"
className="font-medium text-blue-600 underline-offset-4 hover:underline dark:text-blue-400"
>
Open the scheduler
</a>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Use next/link instead of a raw anchor in apps/ui.

Switch this link to Link to match repo frontend navigation standards.

Proposed fix
+import Link from "next/link";
...
-				<a
+				<Link
 					href={url}
 					target="_blank"
 					rel="noopener noreferrer"
 					className="font-medium text-blue-600 underline-offset-4 hover:underline dark:text-blue-400"
 				>
 					Open the scheduler
-				</a>
+				</Link>

As per coding guidelines, "Use next/link for links and next/navigation's router for programmatic navigation".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/ui/src/components/enterprise/calendly-inline.tsx` around lines 83 - 90,
Replace the raw anchor in the CalendlyInline component with Next.js' Link:
import Link from "next/link", swap the <a href={url} ...>Open the scheduler</a>
for <Link href={url} ...>Open the scheduler</Link>, preserving className,
target="_blank" and rel="noopener noreferrer" props (and any other props like
aria attributes) so behavior and styling remain the same; update any surrounding
code that expects an HTMLAnchorElement if necessary (e.g., event handlers) to
use the Link component instead.

@smakosh
smakosh added this pull request to the merge queue May 25, 2026
Merged via the queue into main with commit 7efd3b9 May 25, 2026
12 checks passed
@smakosh
smakosh deleted the fix/calendly-ui-share-button branch May 25, 2026 19:41
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