Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@devkiran
Copy link
Collaborator

@devkiran devkiran commented Sep 23, 2025

Summary by CodeRabbit

  • New Features

    • Domain input is normalized (trimmed, lowercased) before validation to reduce accidental errors.
  • Bug Fixes

    • Improved domain format validation with clearer messaging (e.g., “Please enter a valid domain (eg: acme.com)”).
    • Duplicate domains now show inline field errors instead of transient toasts.
    • Domain field errors clear automatically as you edit, improving form usability.

@vercel
Copy link
Contributor

vercel bot commented Sep 23, 2025

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

Project Deployment Preview Updated (UTC)
dub Ready Ready Preview Sep 23, 2025 6:18pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 23, 2025

Walkthrough

Adds a domain-format validator and integrates it into Zod schema and a modal form; the modal now normalizes domains, uses per-field errors (setError/clearErrors/formState.errors) for invalid or duplicate domains, and passes field errors to the Input component.

Changes

Cohort / File(s) Summary of Changes
Domain validation utility
apps/web/lib/api/domains/is-valid-domain.ts
Added export const isValidDomainFormat(domain: string) that tests the domain against the existing regex (format-only check); left isValidDomain unchanged.
Schema validation updates
apps/web/lib/zod/schemas/groups.ts
Replaced direct regex check with isValidDomainFormat in additionalPartnerLinkSchema; updated error message to "Please enter a valid domain (eg: acme.com)." and removed validDomainRegex import.
Form validation & UX (modal)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/links/add-edit-group-additional-link-modal.tsx
Normalizes domain (trim/lowercase) before validation; uses isValidDomainFormat on submit; uses setError/clearErrors/formState.errors from useForm; clears domain errors on change; replaces toast for duplicate domain with per-field setError; passes field error into Input via error prop.

Sequence Diagram(s)

sequenceDiagram
  actor User
  participant Modal as Add/Edit Link Modal
  participant Form as react-hook-form
  participant Validator as isValidDomainFormat

  User->>Modal: Type domain
  Modal->>Form: setValue + clearErrors('domain')
  User->>Modal: Submit
  Modal->>Modal: normalize domain (trim, toLowerCase)
  Modal->>Validator: isValidDomainFormat(domainNormalized)
  alt Invalid format
    Modal->>Form: setError('domain', { message: "Please enter a valid domain (eg: acme.com)." })
    Form-->>User: Render field error via Input
  else Valid format
    Modal->>Modal: check for duplicates (compare normalized)
    alt Duplicate found
      Modal->>Form: setError('domain', { message: "Domain already exists" })
      Form-->>User: Render field error via Input
    else No duplicate
      Modal->>Modal: proceed with submission (persist)
      Modal-->>User: success / close
    end
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • steven-tey

Poem

I nibble on dots and tidy the line,
Lowercase, trimmed—every domain looks fine.
Field errors whisper, no toasty alarm,
clearErrors and setError keep form calm.
Hop, submit, and flourish — a rabbit's small charm. 🐇✨

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ 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 "Add domain validation to the group additional links" accurately and concisely summarizes the primary change in the PR — introducing domain-format validation and related handling for group additional links — and is specific enough for a reviewer to understand the main intent without extra noise.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-additional-links

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

❤️ Share

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

@devkiran devkiran requested a review from steven-tey September 23, 2025 17:48
Copy link
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: 2

🧹 Nitpick comments (3)
apps/web/lib/zod/schemas/groups.ts (1)

28-30: Normalize the domain in-schema to avoid dupes and casing/whitespace issues.

Add trim + lowercase before refine so both UI and API get consistent, canonical domains.

   domain: z
-    .string()
-    .min(1, "domain is required")
+    .string()
+    .trim()
+    .toLowerCase()
+    .min(1, "domain is required")
     .refine((v) => isValidDomainFormat(v), {
       message: "Please enter a valid domain (eg: acme.com).",
     }),
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/links/add-edit-group-additional-link-modal.tsx (2)

40-53: Use zodResolver with additionalPartnerLinkSchema to DRY validation and apply schema transforms.

This centralizes messages and picks up the schema’s trim/lowercase transform automatically.

   } = useForm<PartnerGroupAdditionalLink>({
+    resolver: zodResolver(additionalPartnerLinkSchema),
     defaultValues: {
       domain: link?.domain || "",
       validationMode: link?.validationMode || "domain",
     },
   });

Add imports (outside this hunk):

import { zodResolver } from "@hookform/resolvers/zod";
import { additionalPartnerLinkSchema } from "@/lib/zod/schemas/groups";

131-134: Mark the field dirty on change (helps form UX/state).

-                setValue("domain", e.target.value);
+                setValue("domain", e.target.value, { shouldDirty: true });
                 clearErrors("domain");
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 18d42d6 and 9ff23f8.

📒 Files selected for processing (3)
  • apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/links/add-edit-group-additional-link-modal.tsx (3 hunks)
  • apps/web/lib/api/domains/is-valid-domain.ts (1 hunks)
  • apps/web/lib/zod/schemas/groups.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/links/add-edit-group-additional-link-modal.tsx (2)
apps/web/lib/types.ts (1)
  • PartnerGroupAdditionalLink (550-552)
apps/web/lib/api/domains/is-valid-domain.ts (1)
  • isValidDomainFormat (11-13)
apps/web/lib/zod/schemas/groups.ts (1)
apps/web/lib/api/domains/is-valid-domain.ts (1)
  • isValidDomainFormat (11-13)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (3)
apps/web/lib/zod/schemas/groups.ts (1)

1-1: Good swap to a single source of truth for format validation.

apps/web/lib/api/domains/is-valid-domain.ts (1)

11-13: LGTM: clean, focused format-only validator.

Separates format check from product restrictions without changing behavior.

apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/links/add-edit-group-additional-link-modal.tsx (1)

138-139: LGTM: error wired to form state.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/links/add-edit-group-additional-link-modal.tsx (2)

40-53: Optional: register domain field (or use Controller) for better RHF state

Current watch/setValue works, but registering the domain (or using Controller) will keep touched/dirty/validation state in sync without manual handling.


138-141: Mark domain as dirty on change

Keeps formState accurate for navigation guards and UI prompts.

-                setValue("domain", e.target.value);
+                setValue("domain", e.target.value, { shouldDirty: true });
                 clearErrors("domain");
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9ff23f8 and 87b94be.

📒 Files selected for processing (1)
  • apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/links/add-edit-group-additional-link-modal.tsx (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/links/add-edit-group-additional-link-modal.tsx (2)
apps/web/lib/types.ts (1)
  • PartnerGroupAdditionalLink (550-552)
apps/web/lib/api/domains/is-valid-domain.ts (1)
  • isValidDomainFormat (11-13)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (4)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/links/add-edit-group-additional-link-modal.tsx (4)

3-3: LGTM: using the domain-format validator

Import and usage look correct.


58-69: Nice: normalize before validating and write back canonical value

This addresses earlier feedback and avoids false negatives.


145-145: LGTM: piping field error to Input

Passing errors.domain?.message is consistent with the manual validation above.


70-79: Normalize duplicate check (case/whitespace-insensitive) and standardize error type

As written, “Acme.com” and “acme.com” can coexist. Compare normalized values and use the same manual error type used above.

Apply:

-    const existingDomains = additionalLinks.map((l) => l.domain);
+    const existingDomains = additionalLinks.map(
+      (l) => (l.domain || "").trim().toLowerCase(),
+    );

-    if (
-      existingDomains.includes(domainNormalized) &&
-      domainNormalized !== link?.domain
-    ) {
+    if (
+      existingDomains.includes(domainNormalized) &&
+      domainNormalized !== link?.domain?.trim().toLowerCase()
+    ) {
       setError("domain", {
-        type: "value",
+        type: "manual",
         message: `Domain ${domainNormalized} has already been added as a link domain`,
       });
     }

@steven-tey steven-tey merged commit 99b7c98 into main Sep 23, 2025
8 checks passed
@steven-tey steven-tey deleted the fix-additional-links branch September 23, 2025 18:47
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.

3 participants