Skip to content

feat: DR-7735 enterprise#7716

Open
carlagn wants to merge 10 commits intomainfrom
feat/DR-7735-enterprise
Open

feat: DR-7735 enterprise#7716
carlagn wants to merge 10 commits intomainfrom
feat/DR-7735-enterprise

Conversation

@carlagn
Copy link
Copy Markdown
Contributor

@carlagn carlagn commented Mar 27, 2026

Summary by CodeRabbit

  • New Features
    • Launched Enterprise landing page with sections for ORM support options, database showcases, code-quality FAQs, and contact form
    • Added animation component for autoplaying/viewport-aware illustrations
    • Introduced partner logo carousel and carousel item UI
    • Added footer accordion for expandable FAQs
    • Added enterprise tab switcher for solution views
    • Added technology tooltip/button component
    • Extended homepage card visuals to support a new "other" visual type
    • Added a new button style variant ("orm-reverse")

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 27, 2026

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

Project Deployment Actions Updated (UTC)
blog Ready Ready Preview, Comment Mar 27, 2026 2:28pm
docs Ready Ready Preview, Comment Mar 27, 2026 2:28pm
eclipse Ready Ready Preview, Comment Mar 27, 2026 2:28pm
site Ready Ready Preview, Comment Mar 27, 2026 2:28pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 27, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0337c89b-186a-4fa7-a891-7879f3e6e491

📥 Commits

Reviewing files that changed from the base of the PR and between e0fc179 and 9bcd0f6.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (1)
  • apps/site/src/components/enterprise/carousel-item.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/site/src/components/enterprise/carousel-item.tsx

Walkthrough

Adds an Enterprise landing page and multiple supporting client components, introduces Rive-based animation and logo ticker, updates a homepage card type, adds two npm dependencies, augments global types for Tally, and adds a new button variant.

Changes

Cohort / File(s) Summary
Enterprise page & deps
apps/site/package.json, apps/site/src/app/enterprise/page.tsx
Added @rive-app/react-webgl2 and react-intersection-observer deps; new Next.js enterprise page exporting metadata and default SiteHome component assembling hero, logo parade, feature cards, complexities grid, accordions, ORM tabs, and contact form.
Enterprise components
apps/site/src/components/enterprise/...
apps/site/src/components/enterprise/carousel-item.tsx, .../footer-accordion.tsx, .../form.tsx, .../switch-enterprise.tsx
New components: CarouselItem, FooterAccordion, EnterpriseForm (Tally embed + script), and SwitchEnterprise (tabbed desktop layout + hardcoded mobile sections).
Animation & logo UI
apps/site/src/components/animation.tsx, apps/site/src/components/logo-parade.tsx
Added Animation (Rive + intersection observer, autoplay control, play/pause on visibility) and LogoParade (continuous scrolling ticker, pause-on-hover, inline keyframes).
Technology button
apps/site/src/components/technology.tsx
Added Technology tooltip-wrapped button component supporting optional URL and tooltip text.
Homepage card changes
apps/site/src/components/homepage/card-section/card-section.tsx
Extended TwoColumnItem.visualType to include "other" and added optional other?: ReactNode; changed image wrapper to a <div>.
Global types & embed support
apps/site/src/types/global.d.ts
Added global augmentation: Window.Tally?: { loadEmbeds: () => void } and export {} to make it a module.
Button variant
packages/eclipse/src/components/button.tsx
Added new buttonVariants key orm-reverse (Tailwind classset) and exposed it via VariantProps for Button props.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title references a ticket (DR-7735) and mentions 'enterprise', which aligns with the extensive enterprise page and component additions throughout the changeset.

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


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

@argos-ci
Copy link
Copy Markdown

argos-ci bot commented Mar 27, 2026

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Mar 27, 2026, 2:34 PM

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: 6

🧹 Nitpick comments (14)
apps/site/src/components/enterprise/carousel-item.tsx (1)

18-18: Remove ineffective key prop from inside the component.

key should be set where CarouselItem is rendered in a list, not on an internal <Card>. Keeping it here is misleading and has no effect.

Proposed fix
-    <Card
-      key={card.title}
+    <Card
       className={cn(
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/components/enterprise/carousel-item.tsx` at line 18, Remove the
ineffective key prop from inside the CarouselItem component: delete the internal
prop key={card.title} on the <Card> rendered by CarouselItem and ensure callers
provide a key when rendering <CarouselItem> in a list (e.g., key={card.title} at
the place where CarouselItem is mapped/instantiated). Update any tests or usages
that assumed an internal key to verify keys are applied by the parent renderers
instead.
apps/site/src/app/enterprise/page.tsx (3)

4-4: Unused import: Script from next/script.

This import isn't used in this file since EnterpriseForm handles the Tally script internally.

-import Script from "next/script";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/app/enterprise/page.tsx` at line 4, Remove the unused import of
Script from next/script in the module (the identifier Script is not referenced);
since EnterpriseForm handles the Tally script internally, delete the line
importing Script to avoid unused-import lint errors and keep the file imports
minimal.

475-475: Remove commented-out code before merging.

This comment references a component that's either not implemented or being deferred. Either implement it or remove the comment to keep the codebase clean.

-      {/* <CarouselItem className="bg-background-default" card={development_efficiency[0]} /> use this item inside the carousel */}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/app/enterprise/page.tsx` at line 475, Remove the leftover
commented-out JSX referencing CarouselItem and development_efficiency: either
implement the CarouselItem usage inside the carousel or delete the comment line
entirely; locate the commented line that reads "<CarouselItem
className="bg-background-default" card={development_efficiency[0]} />" near the
carousel rendering and either replace it with the proper CarouselItem component
usage (ensuring props match CarouselItem's signature) or remove the comment so
no dead/commented JSX remains.

279-279: Component name SiteHome doesn't reflect its purpose.

This is the enterprise page, but the component is named SiteHome. Consider renaming to EnterprisePage or similar for clarity.

-export default function SiteHome() {
+export default function EnterprisePage() {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/app/enterprise/page.tsx` at line 279, The component is
misnamed: rename the default-exported function SiteHome to a clearer name like
EnterprisePage (update the function declaration and the export default to
EnterprisePage) and then update any references/imports/usages of SiteHome
elsewhere in the repo to the new name (search for SiteHome and replace with
EnterprisePage); ensure file-level React/Next conventions remain valid after
renaming (e.g., default export matches the function name) and run type checks to
catch any missed references.
apps/site/src/components/technology.tsx (1)

10-10: Unused import: useState is imported but never used.

This import can be safely removed to keep the code clean.

-import { useState } from "react";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/components/technology.tsx` at line 10, The import list in
components/technology.tsx includes an unused symbol `useState`; remove
`useState` from the import statement (i.e., only import what is actually used)
so the module no longer contains the unused import and lints cleanly—look for
the import line that currently reads `import { useState } from "react";` and
update it to import only the needed React symbols or remove the line if none are
required.
apps/site/src/components/logo-parade.tsx (2)

2-2: Unused import: useRef is imported but never used.

-import { useState, useRef } from "react";
+import { useState } from "react";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/components/logo-parade.tsx` at line 2, The import list in
logo-parade.tsx includes an unused symbol useRef; remove useRef from the import
statement (leave useState) or if you intended to use a ref, add its usage inside
the LogoParade component (e.g., create and reference a ref via useRef in the
component). Update the import line that currently reads import { useState,
useRef } from "react" to only import what’s used.

105-105: Unused variables: speeds, speed, and setSpeed.

These are defined but never used. The animation duration is hardcoded to 110s on line 132 instead of using the speeds object. Either remove these unused variables or wire them up to make speed configurable.

♻️ Option 1: Remove unused code
-const speeds = { slow: "100s", normal: "30s", fast: "15s" };
 export default function LogoParade() {
-  const [speed, setSpeed] = useState("normal");
   const [paused, setPaused] = useState(false);
♻️ Option 2: Use the speed configuration
         style={{
-          animation: `scroll-left 110s linear infinite`,
+          animation: `scroll-left ${speeds[speed]} linear infinite`,

Also applies to: 115-116

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/components/logo-parade.tsx` at line 105, The component defines
unused variables speeds, speed, and setSpeed (in LogoParade) while the marquee
animationDuration is hardcoded to "110s"; either remove the speeds object and
the useState hook (speed, setSpeed) and related unused imports, or wire them up
by replacing the hardcoded "110s" with a dynamic value derived from
speeds[speed], ensure the useState default (e.g., "normal") is used, and update
any controls or JSX that should call setSpeed so the animationDuration updates
when speed changes.
apps/site/src/components/enterprise/form.tsx (1)

16-17: Use proper typing instead of @ts-ignore.

Since you've declared Tally on the Window interface in global.d.ts, you can access it through window.Tally with optional chaining. This provides type safety and removes the need for the ignore comment.

     <Script
       src="https://tally.so/widgets/embed.js"
-      //@ts-ignore
-      onLoad={() => Tally.loadEmbeds()}
+      onLoad={() => window.Tally?.loadEmbeds()}
     />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/components/enterprise/form.tsx` around lines 16 - 17, Replace
the use of the `@ts-ignore` and direct `Tally` reference in the `onLoad` handler
with a type-safe access via the declared global `Tally` on `window` (use
optional chaining to safely call the embed loader). Update the `onLoad` callback
that currently calls `Tally.loadEmbeds()` to call the `loadEmbeds` method
through `window` (e.g., using optional chaining) so TypeScript recognizes the
global from `global.d.ts` and no `@ts-ignore` is needed; ensure you reference
`onLoad` and the `Tally` global when making this change.
apps/site/src/components/enterprise/switch-enterprise.tsx (2)

36-55: Significant JSX duplication across desktop and mobile views.

The card rendering logic (icon + title + description) is repeated three times with minimal differences. Extracting a ContentCard sub-component would reduce duplication and make future styling changes easier to maintain.

♻️ Example extraction
const ContentCard = ({ box, idx }: { box: ContentBox; idx: number }) => (
  <div className="flex flex-col gap-4 relative z-2" key={idx}>
    <div className="flex gap-4 items-center">
      <Action color="orm" size="4xl">
        <i className={cn("text-foreground-orm-strong text-2xl", box.icon)} />
      </Action>
      <h3 className="text-foreground-neutral font-sans-display text-xl stretch-display mt-0 mb-1 font-bold line-clamp-2 hover:line-clamp-none">
        {box.title}
      </h3>
    </div>
    <p className="text-foreground-neutral dark:text-foreground-neutral-weak text-sm font-normal m-0">
      {box.description}
    </p>
  </div>
);

Also applies to: 61-80, 93-112

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/components/enterprise/switch-enterprise.tsx` around lines 36 -
55, Duplicate JSX for the card (icon + title + description) should be extracted
into a small reusable component (e.g., ContentCard) and used in place of the
repeated blocks around the map calls; create a ContentCard component that
accepts props { box, idx } and renders the same structure (Action, <i
className={cn(..., box.icon)} />, title h3, and description p) and then replace
each occurrence (the map rendering over content[activeTab] and the two other
identical blocks) with <ContentCard box={box} idx={idx} /> (ensure the key is
applied to the outermost element inside ContentCard or to the map wrapper,
preserve existing classNames and imports like Action and cn).

9-9: Consider defining a proper type instead of Array<any>.

Using any loses type safety and IDE autocompletion. A simple interface would improve maintainability:

interface ContentBox {
  icon: string;
  title: string;
  description: string;
}

content: ContentBox[][];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/components/enterprise/switch-enterprise.tsx` at line 9, The
field currently typed as "content: Array<any>;" loses type safety—define a
dedicated interface (e.g., ContentBox with properties icon: string, title:
string, description: string) and replace the loose Array<any> usage by typing
the content field as ContentBox[][] (or ContentBox[] if it’s a
single-dimensional array) so the "content" property in switch-enterprise.tsx is
strongly typed and provides proper IDE autocompletion.
apps/site/src/components/animation.tsx (4)

32-33: Remove debug console logs before shipping.

These console.log and console.error calls are useful during development but should be removed (or replaced with proper observability/error tracking) for production code. They add noise to the browser console and can leak internal details.

♻️ Proposed fix
   const { rive, RiveComponent } = useRive({
     src: `/animations/${name}.riv`,
     autoplay: autoplay || false,
-    onLoad: () => console.log("Rive loaded successfully"),
-    onLoadError: (e) => console.error("Rive load error:", e),
     layout: new Layout({
       fit: fit,
       alignment: Alignment.Center,
     }),
   });

If you need error tracking in production, consider integrating with your error monitoring service instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/components/animation.tsx` around lines 32 - 33, Remove the
debug console statements in the Rive component props: eliminate the onLoad: ()
=> console.log("Rive loaded successfully") and onLoadError: (e) =>
console.error("Rive load error:", e) calls; either remove the onLoad handler
entirely and replace onLoadError with a call to your observability API (e.g.,
captureException(e) / telemetry.report(e)) or no-op handlers if you must keep
the props (refer to the onLoad and onLoadError properties in the animation
component) so no debug console output is emitted in production.

51-51: Remove leftover debug comment.

The // <- this comment appears to be a development note that should be cleaned up before merging. The cleanup function itself is a good practice for preventing orphaned playback.

🧹 Proposed cleanup
-    return () => rive?.pause(); // <- this
+    return () => rive?.pause();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/components/animation.tsx` at line 51, Remove the leftover dev
comment after the cleanup return in the animation component; specifically edit
the cleanup returned by the effect (the line containing "return () =>
rive?.pause();") to remove the trailing "// <- this" comment so the file
(apps/site/src/components/animation.tsx) only contains the cleanup function with
no inline debug note.

23-23: Redundant state: isVisible simply mirrors isInView.

The isVisible state and its synchronization effect add unnecessary complexity. The useInView hook already provides the reactive isInView boolean you can use directly in your playback effect. This eliminates one state variable and one effect.

♻️ Proposed simplification
-  const [isVisible, setVisible] = useState<boolean>(false);
-
   const [reference, isInView] = useInView({
     threshold: threshold ?? 0.2,
   });
   
   // ... useRive hook ...

-  useEffect(() => {
-    if (isInView) setVisible(true);
-    else setVisible(false);
-  }, [isInView]);
-
   useEffect(() => {
     if (rive) {
-      if (isVisible) {
+      if (isInView) {
         rive.play();
       } else rive.pause();
     }
     return () => rive?.pause();
-  }, [isVisible, rive]);
+  }, [isInView, rive]);

Also applies to: 40-43

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/components/animation.tsx` at line 23, The isVisible state and
its setter (isVisible / setVisible) are redundant because useInView already
exposes isInView; remove the useState declaration and the effect that syncs
isVisible with isInView, then update the playback/useEffect logic that currently
references isVisible to use isInView directly (keep the useInView hook and any
refs intact). Ensure no leftover references to setVisible remain and remove any
now-unused imports/variables.

59-59: Simplify the style prop assignment.

The spread syntax {...{ style: style }} is unnecessarily verbose. You can directly assign the prop, which is clearer and more idiomatic.

♻️ Proposed simplification
     <div
       ref={reference}
       data-testid="rive-animation"
       className={className}
-      {...{ style: style }}
+      style={style}
     >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/components/animation.tsx` at line 59, Replace the verbose
spread assignment {...{ style: style }} with a direct prop assignment
style={style} in the component (look for the JSX element rendering the style
prop in animation.tsx, e.g., within the Animation component or the element that
currently uses {...{ style: style }}), ensuring the prop name remains "style"
and the value remains the same variable.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/site/src/app/enterprise/page.tsx`:
- Around line 145-196: The enterprises array contains identical placeholder
descriptions for every feature; update each object in the enterprises array
(match by title values like "Dedicated support", "Risk and compliance", "Custom
solutions", etc.) to provide a unique, concise description that accurately
reflects that feature's value proposition (keep tone/length consistent and
adjust any related UI copy if needed); ensure you edit the description property
for each entry rather than duplicating the placeholder text.
- Around line 274-277: The exported metadata object for the enterprise page
currently uses SITE_HOME_TITLE and SITE_HOME_DESCRIPTION which are for the
homepage; create enterprise-specific constants (e.g., SITE_ENTERPRISE_TITLE and
SITE_ENTERPRISE_DESCRIPTION) and replace the values used in the export const
metadata to reference those enterprise constants so the enterprise landing page
has correct SEO title and description.

In `@apps/site/src/components/animation.tsx`:
- Line 26: The current truthy check for the threshold value (the line setting
"threshold: threshold ? threshold : 0.2") incorrectly treats 0 as falsy and
replaces it with 0.2; update the assignment to use nullish coalescing so only
null/undefined fall back to 0.2, keeping explicit 0 values intact (locate the
threshold variable/prop usage in animation.tsx where the object property
"threshold" is assigned).

In `@apps/site/src/components/enterprise/carousel-item.tsx`:
- Around line 7-15: The component destructures a prop "last = false" but the
props type annotation (the object with "card" and optional "className") does not
include "last", causing a TypeScript error; either add "last?: boolean" to the
props type or remove "last" from the destructuring if it's unused—update the
props type definition adjacent to the destructured params in carousel-item.tsx
(the object containing card: { title, description, icon } and className?) to
include last?: boolean, or delete the "last = false" entry from the parameter
list and any references to "last" inside the component.

In `@apps/site/src/components/logo-parade.tsx`:
- Line 36: The url property in the logo object in
apps/site/src/components/logo-parade.tsx contains a leading space ("
https://www.panther.co/") which will produce a malformed link; remove the
leading whitespace so the url value is "https://www.panther.co/" (update the url
string in the logo object or wherever the url property is defined in the
LogoParade component).

In `@apps/site/src/components/technology.tsx`:
- Line 31: The className in the Technology component contains conflicting
font-family utilities ("font-sans-display!" and "font-mono!"); decide which font
family is intended and remove the other from the class list (look for the
className string in apps/site/src/components/technology.tsx where those tokens
appear) so only a single font-family utility remains and the "!"/important
modifiers are preserved only for the chosen font.

---

Nitpick comments:
In `@apps/site/src/app/enterprise/page.tsx`:
- Line 4: Remove the unused import of Script from next/script in the module (the
identifier Script is not referenced); since EnterpriseForm handles the Tally
script internally, delete the line importing Script to avoid unused-import lint
errors and keep the file imports minimal.
- Line 475: Remove the leftover commented-out JSX referencing CarouselItem and
development_efficiency: either implement the CarouselItem usage inside the
carousel or delete the comment line entirely; locate the commented line that
reads "<CarouselItem className="bg-background-default"
card={development_efficiency[0]} />" near the carousel rendering and either
replace it with the proper CarouselItem component usage (ensuring props match
CarouselItem's signature) or remove the comment so no dead/commented JSX
remains.
- Line 279: The component is misnamed: rename the default-exported function
SiteHome to a clearer name like EnterprisePage (update the function declaration
and the export default to EnterprisePage) and then update any
references/imports/usages of SiteHome elsewhere in the repo to the new name
(search for SiteHome and replace with EnterprisePage); ensure file-level
React/Next conventions remain valid after renaming (e.g., default export matches
the function name) and run type checks to catch any missed references.

In `@apps/site/src/components/animation.tsx`:
- Around line 32-33: Remove the debug console statements in the Rive component
props: eliminate the onLoad: () => console.log("Rive loaded successfully") and
onLoadError: (e) => console.error("Rive load error:", e) calls; either remove
the onLoad handler entirely and replace onLoadError with a call to your
observability API (e.g., captureException(e) / telemetry.report(e)) or no-op
handlers if you must keep the props (refer to the onLoad and onLoadError
properties in the animation component) so no debug console output is emitted in
production.
- Line 51: Remove the leftover dev comment after the cleanup return in the
animation component; specifically edit the cleanup returned by the effect (the
line containing "return () => rive?.pause();") to remove the trailing "// <-
this" comment so the file (apps/site/src/components/animation.tsx) only contains
the cleanup function with no inline debug note.
- Line 23: The isVisible state and its setter (isVisible / setVisible) are
redundant because useInView already exposes isInView; remove the useState
declaration and the effect that syncs isVisible with isInView, then update the
playback/useEffect logic that currently references isVisible to use isInView
directly (keep the useInView hook and any refs intact). Ensure no leftover
references to setVisible remain and remove any now-unused imports/variables.
- Line 59: Replace the verbose spread assignment {...{ style: style }} with a
direct prop assignment style={style} in the component (look for the JSX element
rendering the style prop in animation.tsx, e.g., within the Animation component
or the element that currently uses {...{ style: style }}), ensuring the prop
name remains "style" and the value remains the same variable.

In `@apps/site/src/components/enterprise/carousel-item.tsx`:
- Line 18: Remove the ineffective key prop from inside the CarouselItem
component: delete the internal prop key={card.title} on the <Card> rendered by
CarouselItem and ensure callers provide a key when rendering <CarouselItem> in a
list (e.g., key={card.title} at the place where CarouselItem is
mapped/instantiated). Update any tests or usages that assumed an internal key to
verify keys are applied by the parent renderers instead.

In `@apps/site/src/components/enterprise/form.tsx`:
- Around line 16-17: Replace the use of the `@ts-ignore` and direct `Tally`
reference in the `onLoad` handler with a type-safe access via the declared
global `Tally` on `window` (use optional chaining to safely call the embed
loader). Update the `onLoad` callback that currently calls `Tally.loadEmbeds()`
to call the `loadEmbeds` method through `window` (e.g., using optional chaining)
so TypeScript recognizes the global from `global.d.ts` and no `@ts-ignore` is
needed; ensure you reference `onLoad` and the `Tally` global when making this
change.

In `@apps/site/src/components/enterprise/switch-enterprise.tsx`:
- Around line 36-55: Duplicate JSX for the card (icon + title + description)
should be extracted into a small reusable component (e.g., ContentCard) and used
in place of the repeated blocks around the map calls; create a ContentCard
component that accepts props { box, idx } and renders the same structure
(Action, <i className={cn(..., box.icon)} />, title h3, and description p) and
then replace each occurrence (the map rendering over content[activeTab] and the
two other identical blocks) with <ContentCard box={box} idx={idx} /> (ensure the
key is applied to the outermost element inside ContentCard or to the map
wrapper, preserve existing classNames and imports like Action and cn).
- Line 9: The field currently typed as "content: Array<any>;" loses type
safety—define a dedicated interface (e.g., ContentBox with properties icon:
string, title: string, description: string) and replace the loose Array<any>
usage by typing the content field as ContentBox[][] (or ContentBox[] if it’s a
single-dimensional array) so the "content" property in switch-enterprise.tsx is
strongly typed and provides proper IDE autocompletion.

In `@apps/site/src/components/logo-parade.tsx`:
- Line 2: The import list in logo-parade.tsx includes an unused symbol useRef;
remove useRef from the import statement (leave useState) or if you intended to
use a ref, add its usage inside the LogoParade component (e.g., create and
reference a ref via useRef in the component). Update the import line that
currently reads import { useState, useRef } from "react" to only import what’s
used.
- Line 105: The component defines unused variables speeds, speed, and setSpeed
(in LogoParade) while the marquee animationDuration is hardcoded to "110s";
either remove the speeds object and the useState hook (speed, setSpeed) and
related unused imports, or wire them up by replacing the hardcoded "110s" with a
dynamic value derived from speeds[speed], ensure the useState default (e.g.,
"normal") is used, and update any controls or JSX that should call setSpeed so
the animationDuration updates when speed changes.

In `@apps/site/src/components/technology.tsx`:
- Line 10: The import list in components/technology.tsx includes an unused
symbol `useState`; remove `useState` from the import statement (i.e., only
import what is actually used) so the module no longer contains the unused import
and lints cleanly—look for the import line that currently reads `import {
useState } from "react";` and update it to import only the needed React symbols
or remove the line if none are required.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: bef2f3c3-d71c-4633-9f91-e81a7e49db73

📥 Commits

Reviewing files that changed from the base of the PR and between 6f79795 and e0fc179.

⛔ Files ignored due to path filters (15)
  • apps/site/public/icons/technologies/mariadb.svg is excluded by !**/*.svg
  • apps/site/public/icons/technologies/mariadbdark.svg is excluded by !**/*.svg
  • apps/site/public/icons/technologies/mongodb copy.svg is excluded by !**/*.svg
  • apps/site/public/icons/technologies/mongodbsimple.svg is excluded by !**/*.svg
  • apps/site/public/icons/technologies/mssql.svg is excluded by !**/*.svg
  • apps/site/public/icons/technologies/mysql copy.svg is excluded by !**/*.svg
  • apps/site/public/icons/technologies/mysqlsimple.svg is excluded by !**/*.svg
  • apps/site/public/illustrations/enterprise/Illustrations/Diagrams/Code/Type3.svg is excluded by !**/*.svg
  • apps/site/public/illustrations/enterprise/enterprise_0.svg is excluded by !**/*.svg
  • apps/site/public/illustrations/enterprise/enterprise_0_light.svg is excluded by !**/*.svg
  • apps/site/public/illustrations/enterprise/enterprise_1.svg is excluded by !**/*.svg
  • apps/site/public/illustrations/enterprise/enterprise_1_light.svg is excluded by !**/*.svg
  • apps/site/public/illustrations/enterprise/enterprise_2.svg is excluded by !**/*.svg
  • apps/site/public/illustrations/enterprise/enterprise_2_light.svg is excluded by !**/*.svg
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (13)
  • apps/site/package.json
  • apps/site/public/animations/enterprise/build_fortify_grow.riv
  • apps/site/src/app/enterprise/page.tsx
  • apps/site/src/components/animation.tsx
  • apps/site/src/components/enterprise/carousel-item.tsx
  • apps/site/src/components/enterprise/footer-accordion.tsx
  • apps/site/src/components/enterprise/form.tsx
  • apps/site/src/components/enterprise/switch-enterprise.tsx
  • apps/site/src/components/homepage/card-section/card-section.tsx
  • apps/site/src/components/logo-parade.tsx
  • apps/site/src/components/technology.tsx
  • apps/site/src/types/global.d.ts
  • packages/eclipse/src/components/button.tsx

Comment on lines +145 to +196
description:
"Obtain the level of dedicated support from a team that understands and caters to the complexities and demands of large-scale enterprise operations.",
icon: "fa-regular fa-headset", // or "fa-light fa-headset"
},
{
title: "Risk and compliance",
description:
"Obtain the level of dedicated support from a team that understands and caters to the complexities and demands of large-scale enterprise operations.",
icon: "fa-regular fa-file-contract", // or "fa-light fa-file-contract"
},
{
title: "Custom solutions",
description:
"Obtain the level of dedicated support from a team that understands and caters to the complexities and demands of large-scale enterprise operations.",
icon: "fa-regular fa-wrench", // or "fa-light fa-wrench"
},
{
title: "Priority resolution",
description:
"Obtain the level of dedicated support from a team that understands and caters to the complexities and demands of large-scale enterprise operations.",
icon: "fa-regular fa-check-to-slot", // or "fa-light fa-circle-check"
},
{
title: "Advanced security",
description:
"Obtain the level of dedicated support from a team that understands and caters to the complexities and demands of large-scale enterprise operations.",
icon: "fa-regular fa-shield-exclamation", // or "fa-light fa-shield-exclamation"
},
{
title: "Performance optimization",
description:
"Obtain the level of dedicated support from a team that understands and caters to the complexities and demands of large-scale enterprise operations.",
icon: "fa-regular fa-chart-line-up", // or "fa-light fa-chart-line-up"
},
{
title: "Expert scalability consultation",
description:
"Obtain the level of dedicated support from a team that understands and caters to the complexities and demands of large-scale enterprise operations.",
icon: "fa-regular fa-up-right-and-down-left-from-center", // or "fa-light fa-arrow-trend-up"
},
{
title: "Comprehensive team training",
description:
"Obtain the level of dedicated support from a team that understands and caters to the complexities and demands of large-scale enterprise operations.",
icon: "fa-regular fa-screen-users", // or "fa-light fa-people-group"
},
{
title: "Influential feedback loop",
description:
"Obtain the level of dedicated support from a team that understands and caters to the complexities and demands of large-scale enterprise operations.",
icon: "fa-regular fa-repeat", // or "fa-light fa-repeat"
},
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 | 🟡 Minor

All enterprise feature descriptions are identical placeholder text.

Every item in the enterprises array has the exact same description: "Obtain the level of dedicated support from a team that understands...". This appears to be placeholder content that needs to be updated with unique descriptions for each feature.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/app/enterprise/page.tsx` around lines 145 - 196, The
enterprises array contains identical placeholder descriptions for every feature;
update each object in the enterprises array (match by title values like
"Dedicated support", "Risk and compliance", "Custom solutions", etc.) to provide
a unique, concise description that accurately reflects that feature's value
proposition (keep tone/length consistent and adjust any related UI copy if
needed); ensure you edit the description property for each entry rather than
duplicating the placeholder text.

Comment on lines +274 to +277
export const metadata: Metadata = {
title: SITE_HOME_TITLE,
description: SITE_HOME_DESCRIPTION,
};
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

Metadata appears to be for the homepage, not the enterprise page.

Using SITE_HOME_TITLE and SITE_HOME_DESCRIPTION for the enterprise landing page will result in incorrect SEO metadata. Consider creating enterprise-specific title and description constants.

+const ENTERPRISE_TITLE = "Enterprise & Solution Providers | Prisma";
+const ENTERPRISE_DESCRIPTION = "Prisma acts as your comprehensive enterprise data toolset, simplifying database interactions and reducing complexity.";

 export const metadata: Metadata = {
-  title: SITE_HOME_TITLE,
-  description: SITE_HOME_DESCRIPTION,
+  title: ENTERPRISE_TITLE,
+  description: ENTERPRISE_DESCRIPTION,
 };
📝 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
export const metadata: Metadata = {
title: SITE_HOME_TITLE,
description: SITE_HOME_DESCRIPTION,
};
const ENTERPRISE_TITLE = "Enterprise & Solution Providers | Prisma";
const ENTERPRISE_DESCRIPTION = "Prisma acts as your comprehensive enterprise data toolset, simplifying database interactions and reducing complexity.";
export const metadata: Metadata = {
title: ENTERPRISE_TITLE,
description: ENTERPRISE_DESCRIPTION,
};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/app/enterprise/page.tsx` around lines 274 - 277, The exported
metadata object for the enterprise page currently uses SITE_HOME_TITLE and
SITE_HOME_DESCRIPTION which are for the homepage; create enterprise-specific
constants (e.g., SITE_ENTERPRISE_TITLE and SITE_ENTERPRISE_DESCRIPTION) and
replace the values used in the export const metadata to reference those
enterprise constants so the enterprise landing page has correct SEO title and
description.

const [isVisible, setVisible] = useState<boolean>(false);

const [reference, isInView] = useInView({
threshold: threshold ? threshold : 0.2,
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 | 🟡 Minor

Subtle bug: falsy check excludes valid threshold={0}.

Using threshold ? threshold : 0.2 means a threshold of 0 (which is a valid value meaning "trigger as soon as any pixel is visible") will incorrectly fall back to 0.2. Use nullish coalescing (??) to only substitute when the value is undefined or null.

🐛 Proposed fix
   const [reference, isInView] = useInView({
-    threshold: threshold ? threshold : 0.2,
+    threshold: threshold ?? 0.2,
   });
📝 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
threshold: threshold ? threshold : 0.2,
const [reference, isInView] = useInView({
threshold: threshold ?? 0.2,
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/components/animation.tsx` at line 26, The current truthy check
for the threshold value (the line setting "threshold: threshold ? threshold :
0.2") incorrectly treats 0 as falsy and replaces it with 0.2; update the
assignment to use nullish coalescing so only null/undefined fall back to 0.2,
keeping explicit 0 values intact (locate the threshold variable/prop usage in
animation.tsx where the object property "threshold" is assigned).

{
label: "Panther",
imageUrl: `/icons/companies/panther.svg`,
url: " https://www.panther.co/",
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 | 🟡 Minor

Bug: Leading whitespace in URL will cause a malformed link.

The Panther URL has a leading space which would result in a broken or malformed link if this URL is used for navigation.

-    url: " https://www.panther.co/",
+    url: "https://www.panther.co/",
📝 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
url: " https://www.panther.co/",
url: "https://www.panther.co/",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/components/logo-parade.tsx` at line 36, The url property in the
logo object in apps/site/src/components/logo-parade.tsx contains a leading space
(" https://www.panther.co/") which will produce a malformed link; remove the
leading whitespace so the url value is "https://www.panther.co/" (update the url
string in the logo object or wherever the url property is defined in the
LogoParade component).

variant="default-stronger"
href={url}
className={cn(
"font-sans-display! font-normal! text-base! font-mono! w-[75px]! h-[75px]!",
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 | 🟡 Minor

Conflicting font-family classes detected.

The className includes both font-sans-display! and font-mono! which are mutually exclusive font-family declarations. The last one applied will win, but this appears unintentional and creates confusing code.

-              "font-sans-display! font-normal! text-base! font-mono! w-[75px]! h-[75px]!",
+              "font-mono! font-normal! text-base! w-[75px]! h-[75px]!",

Determine which font family is actually intended and remove the conflicting one.

📝 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
"font-sans-display! font-normal! text-base! font-mono! w-[75px]! h-[75px]!",
"font-mono! font-normal! text-base! w-[75px]! h-[75px]!",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/components/technology.tsx` at line 31, The className in the
Technology component contains conflicting font-family utilities
("font-sans-display!" and "font-mono!"); decide which font family is intended
and remove the other from the class list (look for the className string in
apps/site/src/components/technology.tsx where those tokens appear) so only a
single font-family utility remains and the "!"/important modifiers are preserved
only for the chosen font.

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