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

Skip to content

Conversation

@TWilson023
Copy link
Collaborator

@TWilson023 TWilson023 commented Sep 22, 2025

Summary by CodeRabbit

  • New Features
    • Editable profile sections: About You (description with live character counter, industry interests modal, monthly traffic), How You Work (preferred earning structures, sales channels), and enhanced Profile Details (avatar, company/individual flows, payout-aware confirmations).
  • Changes
    • Profile settings restructured into modular sub-forms; Website & Socials page removed; partner summary now shows interests, sales channels, preferred rewards, and traffic labels; UI form variants improved.
  • Backend
    • Profile fields persisted and validated to support new selections and limits.
  • Removed
    • Legacy client page for Website & Socials and related navigation entries.

@vercel
Copy link
Contributor

vercel bot commented Sep 22, 2025

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

Project Deployment Preview Updated (UTC)
dub Ready Ready Preview Sep 24, 2025 8:32pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 22, 2025

Walkthrough

Adds modular partner-profile UI (three new sub-forms and an interests modal), extends Prisma enums/relations and Zod schemas for partner profile fields, updates API/auth and updatePartnerProfile action to persist new relations/fields, adjusts related UI components, and removes the Website & Socials page.

Changes

Cohort / File(s) Summary
Profile page composition
apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/page-client.tsx
Rewrites page to compose ProfileDetailsForm, AboutYouForm, and HowYouWorkForm; removes centralized form/state, unified save flow, and legacy wrappers.
Profile forms
apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/profile-details-form.tsx, apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/about-you-form.tsx, apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/how-you-work-form.tsx, apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/settings-row.tsx
Adds modular forms: profile details (avatar/name/email/country/type/company + Stripe gating), about (description, interests, monthlyTraffic), work preferences (preferredEarningStructures, salesChannels), and reusable SettingsRow.
Industry interests modal & shared UI
apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/industry-interests-modal.tsx, apps/web/ui/shared/max-characters-counter.tsx
New IndustryInterestsModal with selection cap, save/cancel, and scroll progress; new MaxCharactersCounter for live character counts.
Profile catalogs & mappings
apps/web/lib/partners/partner-profile.ts
Adds arrays and lookup maps for industryInterests, monthlyTrafficAmounts, preferredEarningStructures, and salesChannels (ids, labels, icons).
Server action & validation
apps/web/lib/actions/partners/update-partner-profile.ts
Expands update schema via PartnerProfileSchema.partial(), adds runtime check requiring companyName for company profiles, accepts/persists monthlyTraffic and related collections, and updates relation replace logic.
Zod schemas
apps/web/lib/zod/schemas/partners.ts
Introduces PartnerProfileSchema, MAX constants (MAX_PARTNER_DESCRIPTION_LENGTH, MAX_PARTNER_INDUSTRY_INTERESTS), merges profile schema into Partner shapes, and adds PartnerWithProfileSchema.
API & auth shaping
apps/web/lib/api/partners/get-partner-for-program.ts, apps/web/lib/auth/partner.ts
API: aggregate/join new relation fields and return arrays; Auth: eager-load relations and flatten them to primitive arrays on partner objects.
Prisma schema & client exports
packages/prisma/schema/partner.prisma, packages/prisma/client.ts
Adds enums IndustryInterest, PreferredEarningStructure, SalesChannel, MonthlyTraffic; new join models for partner relations; adds monthlyTraffic field; exports new enums from client.
UI adjustments & removals
apps/web/ui/partners/online-presence-form.tsx, apps/web/ui/partners/partner-about.tsx, apps/web/ui/layout/sidebar/partners-sidebar-nav.tsx, apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/sites/page-client.tsx, apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/sites/page.tsx
OnlinePresenceForm: adds variant-aware FormRow behavior; PartnerAbout: renders new profile facets (pills) and updates loading/error text; Sidebar: removes Profile/Payouts nav entries; Sites page & client removed (Website & Socials page deleted).
Icons
packages/ui/src/icons/nucleo/apple.tsx, packages/ui/src/icons/nucleo/index.ts, packages/ui/src/icons/nucleo/cloud.tsx
Adds new Apple and Cloud SVG icons and re-exports them.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant AYF as AboutYouForm
  participant MOD as IndustryInterestsModal
  participant ACT as updatePartnerProfileAction
  participant DB as Database
  participant T as Toast

  U->>AYF: Edit description / monthlyTraffic / open interests
  AYF->>MOD: open modal
  MOD-->>AYF: save(selectedInterests)
  AYF->>ACT: submit(formData)
  ACT->>DB: update partner + replace related relations
  DB-->>ACT: success / error
  alt success
    ACT-->>AYF: ok
    AYF-->>T: success toast
    AYF-->>AYF: reset dirty state
  else error
    ACT-->>AYF: error
    AYF-->>T: error toast
    AYF->>AYF: set form error
  end
Loading
sequenceDiagram
  autonumber
  actor U as User
  participant PDF as ProfileDetailsForm
  participant MOD as StripeChangeConfirmModal
  participant ACT as updatePartnerProfileAction
  participant DB as Database
  participant T as Toast

  U->>PDF: Modify avatar/name/email/country/profileType/companyName
  PDF->>PDF: detect payouts & stripe connection
  alt country/profileType change requires confirmation
    PDF->>MOD: open confirmation
    alt confirm
      MOD-->>PDF: proceed
    else cancel
      MOD-->>PDF: abort
    end
  end
  PDF->>ACT: submit(formData)
  ACT->>DB: update partner + nested relations
  DB-->>ACT: success / error
  alt success
    ACT-->>PDF: ok
    PDF-->>T: show success or verification prompt
    PDF-->>PDF: reset form
  else error
    ACT-->>PDF: error
    PDF-->>T: show error / merge-accounts toast
    PDF->>PDF: set field/root errors
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • steven-tey
  • devkiran

Poem

I nibble code like clover sweet,
Enums and forms all hop to meet.
Interests pill, traffic shows,
Save, toast, reset — the rabbit knows.
Hooray — the profile blooms complete! 🐇✨

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 “Partner profile updates” directly reflects the primary scope of the changes, which introduce new profile fields, UI components, API actions, and schema updates to enhance partner profile functionality.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch partner-profile-updates

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e1be047 and e3c7e8e.

📒 Files selected for processing (1)
  • apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/profile-details-form.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/profile-details-form.tsx
⏰ 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

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.

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

🧹 Nitpick comments (4)
packages/ui/src/icons/nucleo/cloud.tsx (1)

12-28: Deduplicate SVG attributes; remove redundant fill and push shared stroke to the group

Both paths repeat identical stroke and fill props, while the parent group sets an unused fill. Centralize shared attributes on the and simplify the paths.

Apply this diff:

-      <g fill="currentColor">
-        <path
-          d="M13.464,6.891c-.186-2.314-2.102-4.141-4.464-4.141-2.485,0-4.5,2.015-4.5,4.5,0,.35,.049,.686,.124,1.013-1.597,.067-2.874,1.374-2.874,2.987,0,1.657,1.343,3,3,3h7.75c2.071,0,3.75-1.679,3.75-3.75,0-1.736-1.185-3.182-2.786-3.609Z"
-          fill="none"
-          stroke="currentColor"
-          strokeLinecap="round"
-          strokeLinejoin="round"
-          strokeWidth="1.5"
-        />
-        <path
-          d="M9.705,8c.687-.767,1.684-1.25,2.795-1.25,.333,0,.657,.059,.964,.141"
-          fill="none"
-          stroke="currentColor"
-          strokeLinecap="round"
-          strokeLinejoin="round"
-          strokeWidth="1.5"
-        />
+      <g fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.5">
+        <path d="M13.464,6.891c-.186-2.314-2.102-4.141-4.464-4.141-2.485,0-4.5,2.015-4.5,4.5,0,.35,.049,.686,.124,1.013-1.597,.067-2.874,1.374-2.874,2.987,0,1.657,1.343,3,3,3h7.75c2.071,0,3.75-1.679,3.75-3.75,0-1.736-1.185-3.182-2.786-3.609Z" />
+        <path d="M9.705,8c.687-.767,1.684-1.25,2.795-1.25,.333,0,.657,.059,.964,.141" />
       </g>
apps/web/lib/actions/partners/update-partner-profile.ts (3)

97-122: Avoid shadowing outer name and improve readability in map callbacks

The callback param name shadows the outer name field. Rename to value (or similar) in each map to reduce confusion.

Apply this diff:

-          ...(industryInterests && {
+          ...(industryInterests && {
             industryInterests: {
               deleteMany: {},
-              create: industryInterests.map((name) => ({
-                industryInterest: name,
+              create: industryInterests.map((value) => ({
+                industryInterest: value,
               })),
             },
           }),
 
-          ...(preferredEarningStructures && {
+          ...(preferredEarningStructures && {
             preferredEarningStructures: {
               deleteMany: {},
-              create: preferredEarningStructures.map((name) => ({
-                preferredEarningStructure: name,
+              create: preferredEarningStructures.map((value) => ({
+                preferredEarningStructure: value,
               })),
             },
           }),
 
-          ...(salesChannels && {
+          ...(salesChannels && {
             salesChannels: {
               deleteMany: {},
-              create: salesChannels.map((name) => ({
-                salesChannel: name,
+              create: salesChannels.map((value) => ({
+                salesChannel: value,
               })),
             },
           }),

181-184: Harden error handling: error is unknown

Accessing error.message directly can throw if error isn’t an Error. Guard it to avoid masking the real failure.

Apply this diff:

-    } catch (error) {
-      console.error(error);
-
-      throw new Error(error.message);
-    }
+    } catch (error) {
+      console.error(error);
+      const message =
+        error instanceof Error ? error.message : "Failed to update partner profile";
+      throw new Error(message);
+    }

225-228: Align error messaging with actual constraints (include company name)

You also gate on companyName changes, but the message mentions only country/profile type. Include company name to reduce confusion.

-      "Since you've already received payouts on Dub, you cannot change your country or profile type. Please contact support to update those fields.",
+      "Since you've already received payouts on Dub, you cannot change your country, profile type, or company name. Please contact support to update those fields.",
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 177b929 and e1be047.

📒 Files selected for processing (7)
  • apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/profile-details-form.tsx (1 hunks)
  • apps/web/lib/actions/partners/update-partner-profile.ts (7 hunks)
  • apps/web/lib/partners/partner-profile.ts (1 hunks)
  • apps/web/lib/zod/schemas/partners.ts (5 hunks)
  • packages/prisma/schema/partner.prisma (4 hunks)
  • packages/ui/src/icons/nucleo/cloud.tsx (1 hunks)
  • packages/ui/src/icons/nucleo/index.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/prisma/schema/partner.prisma
  • apps/web/lib/partners/partner-profile.ts
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2025-09-17T17:44:03.965Z
Learnt from: TWilson023
PR: dubinc/dub#2857
File: apps/web/lib/actions/partners/update-program.ts:96-0
Timestamp: 2025-09-17T17:44:03.965Z
Learning: In apps/web/lib/actions/partners/update-program.ts, the team prefers to keep the messagingEnabledAt update logic simple by allowing client-provided timestamps rather than implementing server-controlled timestamp logic to avoid added complexity.

Applied to files:

  • apps/web/lib/actions/partners/update-partner-profile.ts
📚 Learning: 2025-07-30T15:25:13.936Z
Learnt from: TWilson023
PR: dubinc/dub#2673
File: apps/web/ui/partners/rewards/add-edit-reward-sheet.tsx:56-66
Timestamp: 2025-07-30T15:25:13.936Z
Learning: In apps/web/ui/partners/rewards/add-edit-reward-sheet.tsx, the form schema uses partial condition objects to allow users to add empty/unconfigured condition fields without type errors, while submission validation uses strict schemas to ensure data integrity. This two-stage validation pattern improves UX by allowing progressive completion of complex forms.

Applied to files:

  • apps/web/lib/actions/partners/update-partner-profile.ts
📚 Learning: 2025-09-24T15:57:55.259Z
Learnt from: TWilson023
PR: dubinc/dub#2872
File: apps/web/lib/actions/partners/update-partner-profile.ts:97-104
Timestamp: 2025-09-24T15:57:55.259Z
Learning: In the Dub codebase, the team prefers to maintain consistency with existing patterns for database operations, even if there are theoretical improvements available. The deleteMany: {} pattern for relation updates is an accepted approach that the team considers low-risk.

Applied to files:

  • apps/web/lib/actions/partners/update-partner-profile.ts
📚 Learning: 2025-09-24T15:51:28.818Z
Learnt from: TWilson023
PR: dubinc/dub#2872
File: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/profile-details-form.tsx:218-219
Timestamp: 2025-09-24T15:51:28.818Z
Learning: In the Dub codebase, OG_AVATAR_URL concatenation with partner names follows a consistent pattern throughout the application where names are used directly without URL encoding. This is an established codebase-wide pattern.

Applied to files:

  • apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/profile-details-form.tsx
📚 Learning: 2025-07-30T15:29:54.131Z
Learnt from: TWilson023
PR: dubinc/dub#2673
File: apps/web/ui/partners/rewards/rewards-logic.tsx:268-275
Timestamp: 2025-07-30T15:29:54.131Z
Learning: In apps/web/ui/partners/rewards/rewards-logic.tsx, when setting the entity field in a reward condition, dependent fields (attribute, operator, value) should be reset rather than preserved because different entities (customer vs sale) have different available attributes. Maintaining existing fields when the entity changes would create invalid state combinations and confusing UX.

Applied to files:

  • apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/profile-details-form.tsx
📚 Learning: 2025-09-24T15:50:16.387Z
Learnt from: TWilson023
PR: dubinc/dub#2872
File: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/profile-details-form.tsx:180-189
Timestamp: 2025-09-24T15:50:16.387Z
Learning: TWilson023 prefers to keep security vulnerability fixes separate from refactoring PRs when the vulnerable code is existing and was only moved/relocated rather than newly introduced.

Applied to files:

  • apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/profile-details-form.tsx
🧬 Code graph analysis (3)
apps/web/lib/actions/partners/update-partner-profile.ts (2)
apps/web/lib/zod/schemas/misc.ts (1)
  • uploadedImageSchema (117-129)
apps/web/lib/zod/schemas/partners.ts (2)
  • MAX_PARTNER_DESCRIPTION_LENGTH (271-271)
  • PartnerProfileSchema (245-269)
apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/profile-details-form.tsx (8)
packages/prisma/client.ts (1)
  • PartnerProfileType (19-19)
apps/web/lib/types.ts (2)
  • PartnerProps (428-428)
  • PayoutsCount (458-462)
apps/web/ui/partners/online-presence-form.tsx (2)
  • useOnlinePresenceForm (70-83)
  • OnlinePresenceForm (89-414)
apps/web/ui/modals/confirm-modal.tsx (1)
  • useConfirmModal (105-118)
apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/settings-row.tsx (1)
  • SettingsRow (3-23)
apps/web/lib/actions/partners/update-partner-profile.ts (1)
  • updatePartnerProfileAction (42-185)
packages/utils/src/constants/misc.ts (1)
  • OG_AVATAR_URL (29-29)
apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/page-client.tsx (1)
  • ProfileForm (183-463)
apps/web/lib/zod/schemas/partners.ts (1)
packages/prisma/client.ts (4)
  • MonthlyTraffic (15-15)
  • IndustryInterest (13-13)
  • PreferredEarningStructure (23-23)
  • SalesChannel (28-28)
⏰ 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)
packages/ui/src/icons/nucleo/cloud.tsx (1)

5-11: Good prop override order

Placing {...props} after explicit width/height lets consumers override defaults cleanly.

packages/ui/src/icons/nucleo/index.ts (1)

2-2: Re-exports look good and keep alphabetical order

Apple and Cloud are added in the expected spots without naming conflicts.

Also applies to: 61-61

apps/web/lib/zod/schemas/partners.ts (2)

243-269: Good: enum array validation + de-dup guards added

The uniqueness refinements on industryInterests, preferredEarningStructures, and salesChannels will prevent Prisma join unique violations and align inputs with DB constraints.


271-299: Description length mismatch: updates capped at 500 but read schema allows 5000

MAX_PARTNER_DESCRIPTION_LENGTH is 500 here, and update actions enforce it, while PartnerSchema still permits 5000 to avoid breaking reads. This can reject updates for existing partners whose description > 500 if the client sends the field unchanged.

To avoid accidental failures:

  • Ensure clients only send description when changed (undefined otherwise), or
  • Backfill/truncate existing descriptions > 500, or
  • Temporarily accept >500 server-side unless changed.

Would you like a follow-up migration plan to normalize existing descriptions > 500?

@steven-tey steven-tey merged commit dc3a6f8 into main Sep 24, 2025
7 of 8 checks passed
@steven-tey steven-tey deleted the partner-profile-updates branch September 24, 2025 20:35
This was referenced Oct 5, 2025
@coderabbitai coderabbitai bot mentioned this pull request Nov 10, 2025
@coderabbitai coderabbitai bot mentioned this pull request Dec 22, 2025
@coderabbitai coderabbitai bot mentioned this pull request Jan 2, 2026
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