Skip to content

Lewis/policies#83

Merged
carhartlewis merged 2 commits intomainfrom
lewis/policies
Feb 26, 2025
Merged

Lewis/policies#83
carhartlewis merged 2 commits intomainfrom
lewis/policies

Conversation

@carhartlewis
Copy link
Copy Markdown
Contributor

@carhartlewis carhartlewis commented Feb 26, 2025

Summary by CodeRabbit

  • New Features

    • Introduced revamped policy management screens with an enhanced rich text editor that provides live status feedback.
    • Launched new website sections and components (e.g., call-to-action, benefits, and workflow guides) to boost user engagement.
  • Refactor

    • Streamlined underlying logic by removing unused elements and reorganizing component structures.
    • Optimized navigation and page routing for a smoother user experience.
  • Style

    • Improved responsive layouts and updated theme defaults for a more consistent dark mode appearance.
    • Refined visual design details for enhanced clarity and usability.
  • Chores

    • Updated configuration settings and streamlined logging for cleaner operation.

… and editor components

- Reorganize policies directory structure with new (overview) and editor routes
- Move policy-related hooks, actions, and types into more specific directories
- Implement new PolicyEditor and RichTextEditor components with enhanced functionality
- Add SaveStatus component for tracking editor save state
- Create default and extended editor extensions
- Improve type safety and code organization for policy management
- Update Biome configuration to disable import sorting
…rm sections

- Add new landing page components: WhyUs, OurSolution, HowItWorks, and CTA
- Implement responsive design with Tailwind CSS and Shadcn UI
- Update layout and styling for improved visual hierarchy
- Add new marketing assets and images for platform features
- Set default theme to dark mode
- Enhance waitlist form with improved UX and styling
- Optimize header and navigation components
@vercel
Copy link
Copy Markdown

vercel Bot commented Feb 26, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
comp-portal ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 26, 2025 8:51pm
web ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 26, 2025 8:51pm
1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
app ⬜️ Skipped (Inspect) Feb 26, 2025 8:51pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 26, 2025

Walkthrough

This pull request encompasses a broad refactor across the project. It removes unused React hooks and outdated components, updates module import paths, and introduces new components—especially for policy management and rich text editing. Several UI components and layouts have been improved, while global styles, configuration settings, and a database seed script have been updated. The overall changes streamline the codebase, reorganize file structures, and refresh styling and functionality for both web and app contexts.

Changes

File(s) Change Summary
apps/app/src/app/[locale]/(app)/(dashboard)/policies/(overview)/hooks/usePolicies.ts
apps/app/src/app/[locale]/(app)/(dashboard)/policies/(overview)/hooks/usePolicy.ts
Removed unused React hooks in usePolicies.ts and updated import paths in usePolicy.ts for reorganized modules.
apps/app/src/app/[locale]/(app)/(dashboard)/policies/[policyId]/components/PolicyDetails.tsx
.../components/PolicyHeader.tsx
Deleted legacy PolicyDetails and PolicyHeader components that previously handled policy viewing and editing.
apps/app/src/app/[locale]/(app)/(dashboard)/policies/[policyId]/editor/** (multiple files) In the editor folder: removed logging and revalidation in update-policy.ts; introduced new PolicyDetails and PolicyHeader components; added a new page (page.tsx) with async policy editor and metadata functions; updated layout and modified a page to return a static message.
apps/app/src/components/editor/** (extensions.ts, headers/status.tsx, policy-editor.tsx, rich-text-editor.tsx) Added new rich text editor components and extensions; refactored PolicyEditor to use the new RichTextEditor and updated props with an optional onSave callback.
apps/web/src/app/(home)/** (layout.tsx, page.tsx) Updated home layout by adding w-full to <main> and removing the footer; overhauled the Home page structure and messaging; introduced new components (WhyUs, OurSolution, HowItWorks, CTA).
apps/web/src/app/components/** (compliance-section.tsx, cta.tsx, how-it-works.tsx, logo-header.tsx, main-nav.tsx, our-solution.tsx, site-header.tsx, waitlist-form.tsx, why-us.tsx) Added new UI components (ComplianceSection, CTA, HowItWorks, OurSolution, WhyUs) and modified existing ones (LogoHeader, MainNav, SiteHeader, WaitlistForm) for improved styling and layout.
apps/web/src/app/layout.tsx Changed Provider’s default theme from “system” to “dark” and removed the system enable flag.
biome.json
packages/db/prisma/seed.js
packages/ui/src/** (badge.tsx, button.tsx, editor.css, globals.css)
Disabled auto-import organization in biome configuration; updated seed script to link evidence records; revised badge and button variants; adjusted editor padding; updated global color variables and added new utility CSS classes.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant P as PolicyEditor Page
    participant A as Auth Service
    participant D as PolicyDetails Component
    U->>P: Navigate to Policy Editor
    P->>P: Await params (locale, policyId) & set locale
    P->>A: Call auth() for session
    A-->>P: Return session with organizationId
    alt Organization exists
        P->>D: Render PolicyDetails with policyId
    else Organization missing
        P->>U: Redirect to "/"
    end
Loading

Poem

I'm a little rabbit, swift and bright,
Hopping through code from day to night.
Unused hooks gone, new paths unfurled,
Components reborn to change our world.
With tips and text, our code does sing—
A rabbit’s celebration of every new thing!

✨ Finishing Touches
  • 📝 Generate Docstrings

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@carhartlewis carhartlewis merged commit 9077180 into main Feb 26, 2025
Copy link
Copy Markdown

@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: 5

🔭 Outside diff range comments (1)
apps/web/src/app/(home)/layout.tsx (1)

1-1: 🛠️ Refactor suggestion

Remove unused import.

The SiteFooter component is imported but not used in this file. According to the AI summary, it was removed from the layout, but the import statement wasn't cleaned up.

-import { SiteFooter } from "../components/site-footer";
🧹 Nitpick comments (22)
packages/ui/src/editor.css (1)

69-74: Notice the removal of vertical padding from .ProseMirror.

The removal of the py-6 utility class (previously providing vertical padding) reduces vertical spacing within the editor component. Please verify that this change is intentional and aligns with the new design expectations for the RichTextEditor. Confirm that overall readability and content spacing aren’t adversely affected across different screen sizes.

packages/ui/src/components/badge.tsx (1)

18-19: Fix redundant border class in the marketing variant.

There appears to be a duplicate border class in the styling: border border. One of these should be removed to avoid redundancy.

- "flex items-center opacity-80 px-3 font-mono gap-2 whitespace-nowrap border border bg-primary/10 text-primary hover:bg-primary/5 before:content-[''] before:absolute before:left-0 before:top-0 before:bottom-0 before:w-0.5 before:bg-primary",
+ "flex items-center opacity-80 px-3 font-mono gap-2 whitespace-nowrap border bg-primary/10 text-primary hover:bg-primary/5 before:content-[''] before:absolute before:left-0 before:top-0 before:bottom-0 before:w-0.5 before:bg-primary",

Otherwise, the new marketing variant is well-structured and provides a consistent visual style that aligns with the existing variant patterns. The use of pseudo-elements for the left accent bar is an elegant approach.

apps/app/src/components/editor/headers/status.tsx (3)

7-17: Consider using the imported Badge component instead of custom styling.

The component imports Badge from "@bubba/ui/badge" but doesn't use it. For consistency with your UI library, consider replacing the custom div with the Badge component.

export function SaveStatus({ saveStatus }: SaveStatusProps) {
  return (
    <div className="mx-auto w-full">
      <div className="flex justify-end">
-        <div className="flex items-center gap-1 bg-accent/60 px-2 py-1 rounded-md">
-          <span className="text-muted-foreground text-xs">{saveStatus}</span>
-        </div>
+        <Badge variant="secondary" className="text-muted-foreground text-xs">
+          {saveStatus}
+        </Badge>
      </div>
    </div>
  );
}

7-17: Add ARIA attributes for better accessibility.

For users with screen readers, status changes should be announced. Consider adding appropriate ARIA attributes.

export function SaveStatus({ saveStatus }: SaveStatusProps) {
  return (
    <div className="mx-auto w-full">
      <div className="flex justify-end">
        <div 
          className="flex items-center gap-1 bg-accent/60 px-2 py-1 rounded-md"
+         role="status"
+         aria-live="polite"
        >
          <span className="text-muted-foreground text-xs">{saveStatus}</span>
        </div>
      </div>
    </div>
  );
}

9-15: Consider adding visual indicators beyond just text.

For better usability, consider adding status-specific icons or colors to help users quickly identify the current state.

You could add different colors or icons for each status to make the state more immediately apparent:

<div className="flex justify-end">
  <div className={`flex items-center gap-1 px-2 py-1 rounded-md ${
-   "bg-accent/60"
+   saveStatus === "Saved" ? "bg-green-100" : 
+   saveStatus === "Saving" ? "bg-blue-100" : "bg-amber-100"
  }`}>
+   {saveStatus === "Saved" && <CheckIcon className="h-3 w-3" />}
+   {saveStatus === "Saving" && <SpinnerIcon className="h-3 w-3 animate-spin" />}
+   {saveStatus === "Unsaved" && <AlertIcon className="h-3 w-3" />}
    <span className="text-muted-foreground text-xs">{saveStatus}</span>
  </div>
</div>

Note: You would need to import the appropriate icons.

apps/app/src/app/[locale]/(app)/(dashboard)/policies/[policyId]/editor/components/PolicyHeader.tsx (1)

1-17: Well-structured status indicator component

This is a clean implementation of a save status indicator component with proper typing and focused responsibility.

Consider enhancing the visual differentiation between statuses by using different colors or icons for each state. For example:

- <div className="flex items-center gap-1 bg-accent/60 px-2 py-1 rounded-md">
-   <span className="text-muted-foreground text-xs">{saveStatus}</span>
+ <div className={cn("flex items-center gap-1 px-2 py-1 rounded-md", {
+   "bg-green-100 dark:bg-green-900/20": saveStatus === "Saved",
+   "bg-yellow-100 dark:bg-yellow-900/20": saveStatus === "Saving",
+   "bg-red-100 dark:bg-red-900/20": saveStatus === "Unsaved",
+ })}>
+   <span className={cn("text-xs", {
+     "text-green-700 dark:text-green-300": saveStatus === "Saved",
+     "text-yellow-700 dark:text-yellow-300": saveStatus === "Saving",
+     "text-red-700 dark:text-red-300": saveStatus === "Unsaved",
+   })}>{saveStatus}</span>

This would require importing the cn utility which appears to be used elsewhere in the project.

packages/db/prisma/seed.js (1)

299-325: Improved bidirectional relationship for evidence and control requirements.

The update enhances the seed function by establishing a proper two-way relationship between evidence records and control requirements. Previously, evidence creation didn't update the control requirement with the evidence ID.

This bidirectional linking creates better data consistency and simplifies future queries, making it easier to navigate between related entities.

apps/app/src/app/[locale]/(app)/(dashboard)/policies/[policyId]/editor/components/PolicyDetails.tsx (1)

55-70: Comprehensive error handling in save functionality.

The save implementation properly:

  • Updates status during the saving process
  • Handles errors gracefully
  • Provides feedback through state updates

Consider adding a toast notification or more visible feedback for users when an error occurs during saving, beyond just changing the status.

packages/ui/src/globals.css (4)

7-7: Slightly reduced brightness.

Changing the background from 100% to 98% brightness is generally fine, but please confirm that the new shade meets your intended visual design and user accessibility requirements.


52-52: Check card background in dark mode.

Confirm that reduced brightness (228 10% 10%) does not degrade text or component visibility on cards.


58-58: Revised secondary color.

Observe that the secondary color changed to 225 10% 20%. If used for text or backgrounds, validate its readability.


64-64: Destructive color altered.

Updating destructive to 0 60% 50% might feel less urgent than before. Ensure it remains attention-grabbing enough for destructive actions.

apps/app/src/components/editor/rich-text-editor.tsx (1)

46-83: Save state and debouncing logic.

Using a debounced callback to delay save calls is a solid approach. However, if multiple quick edits happen, saves might overlap. Consider a cancellation or concurrency management approach if needed.

apps/app/src/components/editor/policy-editor.tsx (1)

20-20: Consider removing unused local state.
editorContent is stored but never read. If not needed for additional logic, removing it can simplify the code.

-  const [editorContent, setEditorContent] = useState<JSONContent | null>(null);
...
-  const handleUpdate = (updatedContent: JSONContent) => {
-    setEditorContent(updatedContent);
-  };
+  // Remove this state if not needed, or use it if you plan to utilize the stored content later.
apps/web/src/app/components/cta.tsx (1)

5-45: LGTM! Well-structured CTA component with good visual hierarchy.

The implementation effectively separates decorative background elements from interactive content and uses proper z-indexing. The responsive design approach and use of Balancer for text wrapping are good practices.

Consider adding an aria-label or role="region" with an aria-labelledby attribute to the outer div for better accessibility:

-    <div className="relative overflow-hidden bg-background py-24">
+    <div className="relative overflow-hidden bg-background py-24" aria-label="Call to action section">
apps/web/src/app/components/compliance-section.tsx (1)

39-39: Consider conditional priority for images.

Setting priority={true} marks all instances of this component as high priority for loading, which might not be optimal if there are multiple instances on a page. Consider making this a prop or setting it only for the first or most important instance.

- priority={true}
+ priority={index === 0}

Or add it as a prop:

interface ComplianceSectionProps {
  title: string;
  description: string;
  image: string;
  alt: string;
  index?: number;
  totalItems?: number;
+ priority?: boolean;
}

// Then in the component:
- priority={true}
+ priority={priority}
apps/web/src/app/components/how-it-works.tsx (2)

26-37: Consider refactoring image rendering for consistency and maintainability

The component has inconsistent image dimensions across different positions:

  • Top image: height=400 (line 31)
  • Bottom image: height=200 (line 54)
  • Mobile image: height hardcoded to 200px via className (line 72)

This could lead to visual inconsistencies or layout shifts.

// Create a reusable image component to ensure consistency
+function StepImage({ src, alt, priority, position }) {
+  const isDesktop = position !== "mobile";
+  return (
+    <Image
+      src={src}
+      alt={alt}
+      width={400}
+      height={position === "top" ? 400 : 200}
+      quality={100}
+      priority={priority}
+      loading={isDesktop ? undefined : "lazy"}
+      className={cn(
+        "object-contain", 
+        !isDesktop && "w-full h-[200px]"
+      )}
+    />
+  );
+}

Also applies to: 49-60, 63-75


140-176: Reduce code duplication in responsive layout handling

The component duplicates the WorkflowStep component for mobile and desktop views. Consider refactoring to use CSS for responsive behavior instead of duplicating component instances.

<div className="flex flex-col justify-between md:h-full">
  <div className="border-b">
    {steps[1] && (
-     <WorkflowStep
-       {...steps[1]}
-       imagePosition="top"
-       className="md:block hidden"
-     />
-    )}
-
-    {steps[1] && (
-     <WorkflowStep
-       {...steps[1]}
-       className="md:hidden block"
-       imagePosition="bottom"
-     />
+     <WorkflowStep
+       {...steps[1]}
+       imagePosition={{mobile: "bottom", desktop: "top"}}
+       className="block"
      />
    )}
  </div>

  {/* Step 3 - bottom middle */}
  <div className="border-b md:border-none">
    {steps[2] && (
-     <WorkflowStep
-       {...steps[2]}
-       imagePosition="top"
-       className="md:block hidden"
-     />
-    )}
-    {steps[2] && (
-     <WorkflowStep
-       {...steps[2]}
-       className="md:hidden block"
-       imagePosition="bottom"
+     <WorkflowStep
+       {...steps[2]}
+       imagePosition={{mobile: "bottom", desktop: "top"}}
+       className="block"
      />
    )}
  </div>
</div>

This would require updating the WorkflowStep component to handle the responsive behavior internally:

interface WorkflowStepProps {
  // ...
-  imagePosition?: "top" | "bottom";
+  imagePosition?: "top" | "bottom" | {mobile: "top" | "bottom", desktop: "top" | "bottom"};
  // ...
}
apps/web/src/app/components/our-solution.tsx (4)

25-29: Enhance accessibility with aria-label for icon buttons

The icon-only elements should have accessible labels for screen readers.

<div
  className={cn(
    "p-1 rounded-full mt-0.5",
    isPositive
      ? "bg-primary/10 text-primary border border-primary"
      : "bg-destructive/10 text-destructive",
  )}
+  aria-label={isPositive ? "Positive point" : "Negative point"}
+  role="img"
>
  {isPositive ? <Check size={12} /> : <X size={12} />}
</div>

27-28: Make text styling more consistent

The text color for negative items is set to text-muted-foreground, but positive items don't have a specific text color class, which could lead to inconsistency.

-<p className={cn("text-md", isPositive ? "" : "text-muted-foreground")}>
+<p className={cn("text-md", isPositive ? "text-foreground" : "text-muted-foreground")}>
  {text}
</p>

76-76: Review padding for mobile responsiveness

The component uses a fixed horizontal padding of px-16, which might be too large for small mobile screens.

-<div className={cn("container mx-auto px-16 py-24", className)}>
+<div className={cn("container mx-auto px-4 md:px-16 py-12 md:py-24", className)}>

94-124: Make column headings customizable and add empty state handling

The column headings "The Problem" and "Our Solution" are hardcoded. Consider making them customizable via props and add handling for empty arrays.

interface OurSolutionProps {
  title?: string;
  subtitle?: string;
+ problemsTitle?: string;
+ solutionsTitle?: string;
  problems?: Array<{ id: string; text: string }>;
  solutions?: Array<{ id: string; text: string }>;
  className?: string;
}

export default function OurSolution({
  title = "Every framework you need to win deals",
  subtitle = "Most compliance solutions are closed, costly, and complex. We're building an open-source platform to make SOC 2, ISO 27001, and GDPR accessible and affordable.",
+ problemsTitle = "The Problem",
+ solutionsTitle = "Our Solution",
  problems = [ /* ... */ ],
  solutions = [ /* ... */ ],
  className,
}: OurSolutionProps) {
  // ...

  <div className="grid md:grid-cols-2 gap-8 md:gap-12 mt-8">
    <div className="rounded-lg space-y-4">
      <h3 className="text-2xl font-medium border-b border-border pb-4">
-       The Problem
+       {problemsTitle}
      </h3>
      <div>
-       {problems.map((problem) => (
+       {problems.length > 0 ? problems.map((problem) => (
          <ProblemSolutionItem
            key={problem.id}
            text={problem.text}
            isPositive={false}
          />
-       ))}
+       )) : (
+         <p className="text-muted-foreground py-4">No problems defined.</p>
+       )}
      </div>
    </div>

    <div className="rounded-lg space-y-4">
      <h3 className="text-2xl font-medium border-b border-border pb-4">
-       Our Solution
+       {solutionsTitle}
      </h3>
      <div>
-       {solutions.map((solution) => (
+       {solutions.length > 0 ? solutions.map((solution) => (
          <ProblemSolutionItem
            key={solution.id}
            text={solution.text}
            isPositive={true}
          />
-       ))}
+       )) : (
+         <p className="text-muted-foreground py-4">No solutions defined.</p>
+       )}
      </div>
    </div>
  </div>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6e2b94f and fbab166.

⛔ Files ignored due to path filters (10)
  • apps/web/public/assets/compliance-made-easy.png is excluded by !**/*.png
  • apps/web/public/assets/cta-bg.png is excluded by !**/*.png
  • apps/web/public/assets/enterprise-platform.png is excluded by !**/*.png
  • apps/web/public/assets/evidence.png is excluded by !**/*.png
  • apps/web/public/assets/export-audit.png is excluded by !**/*.png
  • apps/web/public/assets/one-platform.png is excluded by !**/*.png
  • apps/web/public/assets/overview.png is excluded by !**/*.png
  • apps/web/public/assets/security-and-compliance.png is excluded by !**/*.png
  • apps/web/public/assets/tech-stack.png is excluded by !**/*.png
  • apps/web/public/assets/upload-evidence.png is excluded by !**/*.png
📒 Files selected for processing (32)
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/(overview)/hooks/usePolicies.ts (0 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/(overview)/hooks/usePolicy.ts (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/[policyId]/components/PolicyDetails.tsx (0 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/[policyId]/components/PolicyHeader.tsx (0 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/[policyId]/editor/actions/update-policy.ts (0 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/[policyId]/editor/components/PolicyDetails.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/[policyId]/editor/components/PolicyHeader.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/[policyId]/editor/page.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/[policyId]/layout.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/[policyId]/page.tsx (2 hunks)
  • apps/app/src/components/editor/extensions.ts (1 hunks)
  • apps/app/src/components/editor/headers/status.tsx (1 hunks)
  • apps/app/src/components/editor/policy-editor.tsx (1 hunks)
  • apps/app/src/components/editor/rich-text-editor.tsx (1 hunks)
  • apps/web/src/app/(home)/layout.tsx (1 hunks)
  • apps/web/src/app/(home)/page.tsx (1 hunks)
  • apps/web/src/app/components/compliance-section.tsx (1 hunks)
  • apps/web/src/app/components/cta.tsx (1 hunks)
  • apps/web/src/app/components/how-it-works.tsx (1 hunks)
  • apps/web/src/app/components/logo-header.tsx (1 hunks)
  • apps/web/src/app/components/main-nav.tsx (1 hunks)
  • apps/web/src/app/components/our-solution.tsx (1 hunks)
  • apps/web/src/app/components/site-header.tsx (1 hunks)
  • apps/web/src/app/components/waitlist-form.tsx (2 hunks)
  • apps/web/src/app/components/why-us.tsx (1 hunks)
  • apps/web/src/app/layout.tsx (1 hunks)
  • biome.json (2 hunks)
  • packages/db/prisma/seed.js (2 hunks)
  • packages/ui/src/components/badge.tsx (2 hunks)
  • packages/ui/src/components/button.tsx (2 hunks)
  • packages/ui/src/editor.css (1 hunks)
  • packages/ui/src/globals.css (3 hunks)
💤 Files with no reviewable changes (4)
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/(overview)/hooks/usePolicies.ts
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/[policyId]/components/PolicyHeader.tsx
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/[policyId]/components/PolicyDetails.tsx
  • apps/app/src/app/[locale]/(app)/(dashboard)/policies/[policyId]/editor/actions/update-policy.ts
🔇 Additional comments (60)
apps/web/src/app/components/site-header.tsx (2)

5-5: CSS class simplification appears intentional.

The header element's CSS classes have been simplified by removing border-grid, z-50, and border-b classes. This styling change aligns with the broader refactoring mentioned in the PR summary. The component appears more streamlined while maintaining its core positioning properties.


1-13: ModeSwitcher component has been removed.

The ModeSwitcher import and its associated JSX elements have been completely removed from this component. This appears to be an intentional simplification of the UI as part of the broader refactoring effort described in the PR summary.

Is this change intentional? Please confirm that the mode-switching functionality is either no longer needed or has been implemented elsewhere in the application.

packages/ui/src/components/button.tsx (2)

13-13: Reduced width of left border decoration in default button variant.

The pseudo-element width has been decreased from before:w-2 to before:w-1, making the left border decoration thinner. This is a visual styling change that creates a more subtle accent on the left side of default buttons.


23-23: Reduced width of left border decoration in action button variant.

Similar to the default variant change, the pseudo-element width has been decreased from before:w-2 to before:w-1 for the action variant. This change ensures consistent styling between button variants and creates a more refined look for the action buttons.

packages/ui/src/components/badge.tsx (1)

6-6: Good addition of the relative positioning.

Adding the relative class to the base styles is a good decision as it provides positioning context for any absolute positioned elements within the badge, particularly for the pseudo-elements used in the new marketing variant.

apps/app/src/components/editor/headers/status.tsx (1)

1-5: Good interface definition with proper typing.

The interface with string literal types for saveStatus provides clear type safety and documents the expected values.

apps/app/src/components/editor/extensions.ts (4)

1-23: Good organization of imports for Tiptap extensions.

The imports are well-structured and provide a comprehensive set of rich text editing capabilities.


24-57: Well-documented default extensions with thoughtful configuration.

The defaultExtensions array provides essential text formatting features with appropriate configurations. The JSDoc comment clearly explains its purpose.


73-83: Appropriate simplified extension set for basic editors.

The starterExtensions array provides a good minimal set using StarterKit with additional Underline and Link extensions.


85-90: Clear utility function for customizing extensions.

The createExtensions function provides a clean way to extend the default set with custom extensions.

apps/web/src/app/layout.tsx (1)

38-38: Verify intention behind theme change

The defaultTheme has been changed from "system" to "dark" and the enableSystem prop has been removed. This means the application will no longer respect the user's system theme preference and will always default to dark mode.

Was this change intentional? Consider that respecting system theme preferences is a common accessibility practice.

biome.json (2)

4-4: Import organization disabled

The organizeImports setting has been changed from enabled: true to enabled: false. This means Biome will no longer automatically organize import statements in the codebase.

This could lead to inconsistent import organization across files. Was this change intentional, perhaps due to conflicts with other tools or specific import ordering requirements?


7-10: Formatting improvement for ignore array

The ignore array has been reformatted for better readability while maintaining the same content.

apps/app/src/app/[locale]/(app)/(dashboard)/policies/(overview)/hooks/usePolicy.ts (1)

4-6: Path updates for project reorganization

The import paths have been updated to reflect the reorganization of policy-related functionality into an editor subdirectory, maintaining a clearer separation of concerns in the codebase.

apps/app/src/app/[locale]/(app)/(dashboard)/policies/[policyId]/page.tsx (1)

7-7: Function renamed from PolicyDetailsPage to PolicyDetails.

The function has been renamed while maintaining the same parameter structure.

apps/app/src/app/[locale]/(app)/(dashboard)/policies/[policyId]/layout.tsx (2)

9-50: Well-structured layout component with proper navigation.

This layout component effectively:

  • Handles authentication and redirects
  • Fetches policy data
  • Provides navigation between policy overview and editor
  • Properly renders children components

52-67: Effective caching implementation for policy data.

The getPolicy function is properly cached using unstable_cache, which improves performance by reducing redundant database queries.

Just note that unstable_cache is marked as unstable API in Next.js, so be prepared for potential changes in future Next.js versions.

apps/app/src/app/[locale]/(app)/(dashboard)/policies/[policyId]/editor/components/PolicyDetails.tsx (2)

16-81: Well-implemented PolicyDetails component with appropriate loading and error states.

The component effectively:

  • Manages loading states with skeleton UI
  • Handles policy content formatting
  • Implements proper save mechanics with status tracking
  • Redirects when policy isn't found

49-53: Robust content formatting with type checking.

The content formatting logic handles various potential data structures safely, ensuring the editor receives properly formatted content regardless of how it's stored.

packages/ui/src/globals.css (8)

50-50: Adjusting dark background hue.

Ensure this new hue (228 10.2% 9.61%) remains consistent with your dark theme contrast goals.


54-54: Popover dark styling.

Again, verify that the updated popover background (228 10% 10%) provides sufficient contrast and maintains a coherent dark mode appearance.


60-62: Muted and accent choices.

Lines 60-62 introduce 225 10% 20% for muted and accent, plus a new muted-foreground of 210 1.1% 64.7%. Double-check the palette for clarity and avoid confusion between muted and accent usage.


66-68: Revised border, input, and ring values.

Shifting border and input to 225-based hues and ring to 151 100% 43% influences focus/hover states. Confirm that each color remains functional in your UI flows.


116-123: New .grid-pattern utility class.

The CSS grid pattern is a neat visual effect. Looks good. Confirm no performance or layout conflicts arise where the pattern is used.


125-138: New .grid-fade-mask utility class.

Excellent approach for creating a gradual mask effect. Check cross-browser compatibility for both mask-image and -webkit-mask-image.


140-149: New .dotted-border utility class.

A straightforward dotted border using repeating linear gradients. It’s concise and reusable—no issues noted.


151-160: New .shaped-gradient utility class.

A well-defined radial gradient for decorative backgrounds. This should be very flexible for accenting headers or sections.

apps/app/src/components/editor/rich-text-editor.tsx (7)

1-23: Imports and initial setup.

Bringing in TipTap, React hooks, icons, and a custom “use client” directive is fine. Watch for bundle size; ensure these imports remain necessary. Otherwise, this part looks good.


25-34: RichTextEditorProps interface.

Clear definitions of optional props, including readOnly, placeholder, and saveDebounceMs, provide good flexibility. Nice job.


36-45: Editor component signature and defaults.

Establishing default values (readOnly, placeholder, etc.) is clean. No concerns here.


85-109: Editor configuration and onUpdate callback.

The default extensions and onUpdate logic look correct. Good job setting up focus states and maintaining a “Saved” vs. “Unsaved” status. No major issues found.


111-125: Initializing editor content.

Nice use of try/catch for error handling. The fallback to a safe “empty doc” scenario ensures no runtime meltdown if content is invalid. This code is correct and robust.


127-129: Loading state.

Displaying a placeholder during editor init is user-friendly. Nothing to add here.


131-221: Bubble menu and final render.

Offering bold/italic/underline, list toggles, etc., in a bubble menu is intuitive. The SaveStatus component to show saving state is helpful as well. Overall, a polished, well-structured implementation.

apps/app/src/app/[locale]/(app)/(dashboard)/policies/[policyId]/editor/page.tsx (3)

1-6: Import statements and dependencies.

Retrieving auth, i18n, and hooking in PolicyDetails is straightforward. No issues here.


8-24: PolicyEditor function logic.

Awaiting params, checking session, and redirecting if the org ID is missing is neat. This ensures secure access. Looks good.


26-39: generateMetadata function.

Properly setting locale and returning a translated title. Straightforward and essential for SEO. Good implementation.

apps/app/src/components/editor/policy-editor.tsx (7)

5-5: Import appears valid and aligns with the new editor usage.
No issues with importing the RichTextEditor component as intended.


11-11: Optional onSave type is clear.
Defining it as an optional Promise-based callback is a good design choice for asynchronous saves.


18-18: Destructuring onSave is consistent with the prop definition.
Ensures a clear handoff for the save logic. No concerns here.


24-27: Fallback content initialization is sensible.
Providing a default paragraph ensures the editor always has a valid starting point.


30-32: handleUpdate callback updates local state.
The callback pattern is appropriate. But be mindful that editorContent is currently not consumed elsewhere.


34-44: Validate contentToSave.content before casting.
Casting to JSONContent[] is convenient but may cause runtime issues if the structure is invalid. Consider an additional check to ensure contentToSave.content is an array.


46-52: RichTextEditor integration looks correct.
Passing initial content, update, and save handlers, plus the readOnly flag, is straightforward and consistent with typical usage.

apps/web/src/app/(home)/layout.tsx (1)

12-12: LGTM!

Adding the w-full class to ensure the main content takes the full width of its container is a good improvement.

apps/web/src/app/components/main-nav.tsx (2)

8-8: LGTM!

The change from right margin to top margin improves the vertical spacing of the navigation component.


10-10: Verify logo appearance with width-only constraint.

The LogoHeader component now has only a width constraint (w-48) without a height constraint. Verify that the logo maintains its proper aspect ratio and appearance without an explicit height.

apps/web/src/app/components/waitlist-form.tsx (4)

66-66: UI consistency improvement with added height.

Adding the h-12 class ensures the input field has a consistent height with the button, creating a more polished appearance.


70-70: Enhanced form validation with required attribute.

Adding the required attribute improves user experience by ensuring email submission before form processing, reducing unnecessary server requests.


82-82: Button height standardization.

The explicit h-12 class ensures consistent height between the button and input field, creating a visually balanced form row.


87-87: Improved loading state text.

Changed from "Joining..." to "Please wait..." which is a more universally appropriate message while the form submission is processing.

apps/web/src/app/components/logo-header.tsx (2)

5-8: Logo dimensions and fill properties updated.

The SVG dimensions have been reduced from 334×70 to 220×40, making it more compact. The fill has been changed from "none" to "currentColor" which allows the logo to inherit colors from parent elements, improving theme compatibility.


12-19: Simplified SVG structure with direct path definitions.

The previous complex SVG structure with clip paths has been replaced with two direct path elements. This simplification makes the SVG more maintainable and potentially improves rendering performance.

apps/web/src/app/components/why-us.tsx (3)

6-28: Well-structured data array for dynamic content rendering.

The sections array is well-organized, containing all necessary information for each marketing section including titles, descriptions, and image paths, making the component maintainable and easy to extend.


48-57: Effective use of dynamic rendering for marketing sections.

The component efficiently maps through the sections array to render multiple ComplianceSection components, passing the appropriate props including an index for tracking. This pattern promotes DRY code principles and simplifies future content updates.


59-105: Responsive grid layout for feature highlights.

The two-column grid layout with appropriate spacing and borders creates a clean visual separation between features. The consistent structure for each feature (image followed by title and description) enhances readability and user experience.

apps/web/src/app/(home)/page.tsx (3)

3-6: New component imports enhance page structure.

The addition of specialized component imports (WhyUs, OurSolution, HowItWorks, CTA) indicates a more modular approach to page composition, improving code organization and maintenance.


11-20: Improved headline and messaging for better marketing clarity.

The headline change to "Open Source Compliance Automation Platform" and the updated description provide a clearer value proposition. The increased font size (md:text-6xl) and adjusted spacing improve visual hierarchy.


25-39: Enhanced page structure with logical content sections.

The restructured layout with distinct sections (WaitlistForm, WhyUs, OurSolution, HowItWorks, CTA) creates a natural user flow through the marketing content. The gradient background between sections adds visual interest and helps separate content areas.

apps/web/src/app/components/how-it-works.tsx (1)

132-184: Add error handling for missing steps

The component doesn't handle the case where steps array has fewer than 4 items. Consider adding a check to avoid rendering errors.

<div className="grid grid-cols-1 md:grid-cols-3 border">
+  {steps.length < 4 && <div className="text-muted-foreground p-4">Not enough steps provided. Expected at least 4 steps.</div>}
+  {steps.length >= 4 && (
+    <>
      <div className="flex md:h-full md:border-r border-b md:border-b-0">
        {steps[0] && (
          <WorkflowStep {...steps[0]} imagePosition="bottom" />
        )}
      </div>
      
      {/* Rest of the grid layout */}
+    </>
+  )}
</div>

Comment on lines +59 to +71
/**
* Extended extensions that include table support
*/
export const extendedExtensions = [
...defaultExtensions,
Table.configure({
resizable: true,
allowTableNodeSelection: true,
}),
TableRow,
TableHeader,
TableCell,
];
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove duplicate table extensions in extendedExtensions.

Table-related extensions (Table, TableRow, TableHeader, TableCell) are already included in defaultExtensions (lines 50-56), making their inclusion here redundant and potentially problematic.

export const extendedExtensions = [
  ...defaultExtensions,
-  Table.configure({
-    resizable: true,
-    allowTableNodeSelection: true,
-  }),
-  TableRow,
-  TableHeader,
-  TableCell,
];
📝 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
/**
* Extended extensions that include table support
*/
export const extendedExtensions = [
...defaultExtensions,
Table.configure({
resizable: true,
allowTableNodeSelection: true,
}),
TableRow,
TableHeader,
TableCell,
];
/**
* Extended extensions that include table support
*/
export const extendedExtensions = [
...defaultExtensions,
];

}

return <PolicyDetails policyId={policyId} />;
return <>Hi</>;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Empty placeholder needs implementation.

The page is returning just "Hi" instead of rendering meaningful content. This appears to be an incomplete implementation.

This page should likely render appropriate policy content or components. Consider implementing the actual policy details view or adding a proper redirect if this page is being replaced by another route.

Comment on lines +33 to +35
src={image}
alt={title}
width={600}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use the provided alt prop instead of title for image accessibility.

The alt attribute for the Image component is using the title prop instead of the alt prop that's specifically provided in the props interface. This doesn't follow accessibility best practices.

<Image
  src={image}
- alt={title}
+ alt={alt}
  width={600}
📝 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
src={image}
alt={title}
width={600}
src={image}
alt={alt}
width={600}

alt={title}
width={600}
height={600}
sizes="(max-height: 150px) 150px, 600px, (max-width: 400px) 400px, 600px"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix the sizes attribute syntax.

The sizes attribute has syntax issues. It's trying to mix max-height and max-width conditions, which isn't the correct format for the sizes attribute.

- sizes="(max-height: 150px) 150px, 600px, (max-width: 400px) 400px, 600px"
+ sizes="(max-width: 400px) 400px, 600px"
📝 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
sizes="(max-height: 150px) 150px, 600px, (max-width: 400px) 400px, 600px"
sizes="(max-width: 400px) 400px, 600px"

Comment on lines +89 to +117
steps = [
{
stepNumber: 1,
title: "Connect your tech stack",
description:
"Easily integrate with your existing tools like AWS, GCP, Azure, GitHub, Slack and more.",
image: "/assets/tech-stack.png",
},
{
stepNumber: 2,
title: "Get an instant overview",
description:
"Get real-time insights into security gaps, misconfigurations, and compliance deviations.",
image: "/assets/overview.png",
},
{
stepNumber: 3,
title: "Immediate action",
description:
"Receive immediate actions your company can take to help get you compliant.",
image: "/assets/upload-evidence.png",
},
{
stepNumber: 4,
title: "Effortless audit preparation",
description:
"Generate comprehensive reports and evidence logs for auditors with one click.",
image: "/assets/export-audit.png",
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify asset paths exist

The component references several asset paths like "/assets/tech-stack.png". Make sure these files exist in your public directory to avoid 404 errors.


🏁 Script executed:

#!/bin/bash
# Check if the image files referenced in the component exist
echo "Checking for image files in public directory..."
for img in "tech-stack.png" "overview.png" "upload-evidence.png" "export-audit.png"; do
  if [ -f "public/assets/$img" ]; then
    echo "✅ Found: public/assets/$img"
  else
    echo "❌ Missing: public/assets/$img"
  fi
done

Length of output: 987


Asset Paths Issue: Update Required to Prevent 404 Errors

The asset files referenced in the component ("/assets/tech-stack.png", "/assets/overview.png", "/assets/upload-evidence.png", and "/assets/export-audit.png") were not found in the public/assets directory. Please address this by either adding the missing image files or updating the paths accordingly.

  • Missing files:
    • public/assets/tech-stack.png
    • public/assets/overview.png
    • public/assets/upload-evidence.png
    • public/assets/export-audit.png

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