Skip to content

Add survey to Onboarding Users#171

Open
jfcsantos wants to merge 15 commits intomainfrom
jsantos/profile-survey
Open

Add survey to Onboarding Users#171
jfcsantos wants to merge 15 commits intomainfrom
jsantos/profile-survey

Conversation

@jfcsantos
Copy link
Contributor

@jfcsantos jfcsantos commented Feb 13, 2026

Summary

  • Add welcome survey modal using Typeform that displays for new users on the profile page
  • Survey shows after user signup only. Once submitted or dismissed we store it in db and never show it again.
  • Track survey completion status in the database to only show the modal once
  • Integrate with tRPC to persist completion state

Changes

  • New component: WelcomeTypeformModal - embedded Typeform widget in a responsive modal dialog
  • Database: Added completed_welcome_form boolean column to kilocode_users table
  • API: New markWelcomeFormCompleted tRPC mutation to record when users complete/skip the survey
  • Profile page: Conditionally render the modal for users who haven't completed the form

Implementation Details

Screenshot 2026-02-13 at 12 15 38

@jfcsantos jfcsantos marked this pull request as ready for review February 13, 2026 12:33
<Dialog
open={isOpen}
onOpenChange={open => {
if (!open) handleSkip();
Copy link
Contributor

Choose a reason for hiding this comment

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

WARNING: Closing the dialog marks the welcome form as completed

onOpenChange calls handleSkip() whenever open becomes false, and handleSkip() calls markWelcomeFormCompleted. That means a user can be persisted as completed_welcome_form=true without ever submitting the Typeform (e.g. clicking the X). If this is intended, consider renaming the mutation/state to reflect “dismissed” rather than “completed”; otherwise, only call the mutation from onSubmit.

}}
>
<DialogContent
className="h-[50vh] max-w-[90vw] overflow-hidden p-0 sm:h-[400px] sm:max-w-xl [&>button]:rounded-md [&>button]:p-2 [&>button]:text-black [&>button]:transition-colors [&>button]:hover:bg-black/10 [&>button]:hover:text-black/60"
Copy link
Contributor

Choose a reason for hiding this comment

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

WARNING: Close button styling likely breaks dark-mode visibility

The DialogContent class overrides the direct child button styles with [&>button]:text-black / hover:text-black/60. Since the app is dark-mode only, this can make the close (X) control very low-contrast or effectively invisible on a dark dialog background. Consider using text-foreground (and matching hover colors) or removing the forced text color override.

@kiloconnect
Copy link
Contributor

kiloconnect bot commented Feb 13, 2026

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (10 files)
  • src/app/(app)/profile/page.tsx
  • src/app/api/cloud-agent/sessions/prepare/route.test.ts
  • src/components/profile/WelcomeTypeformModal.tsx
  • src/db/migrations/0013_chilly_richard_fisk.sql
  • src/db/migrations/meta/0013_snapshot.json
  • src/db/migrations/meta/_journal.json
  • src/db/schema.ts
  • src/lib/token.test.ts
  • src/routers/user-router.ts
  • src/tests/helpers/user.helper.ts

is_bot: boolean().default(false).notNull(),
default_model: text(),
cohorts: jsonb().$type<Record<string, number>>().default({}).notNull(),
completed_welcome_form: boolean().default(false).notNull(),
Copy link
Contributor

@iscekic iscekic Feb 13, 2026

Choose a reason for hiding this comment

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

Should we default to false? This way every user is going to see it, not just new users. 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hmm, could be useful info but I'm guessing we don't want that for existing users @emilieschario?
if we don't we can just update the migration to set it true for existing users, what do you think?

ALTER TABLE "kilocode_users" ADD COLUMN "completed_welcome_form" boolean DEFAULT false NOT NULL;
UPDATE "kilocode_users" SET "completed_welcome_form" = true;

Copy link
Contributor

Choose a reason for hiding this comment

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

let's make sure we only show to new users

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll push the migration update to set that field to true for all existing users.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the bot may have a good point about theming

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's weird because dark mode on the modal wasn't triggering for me until I forced it in the browser console, regardless it should look good now

<Widget
id={WELCOME_FORM_ID}
style={{ width: '100%', height: '100%', minHeight: '400px' }}
className="my-form"
Copy link
Contributor

Choose a reason for hiding this comment

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

This class seems redundant?

onPointerDownOutside={e => e.preventDefault()}
onEscapeKeyDown={e => e.preventDefault()}
>
<DialogTitle className="sr-only">Welcome to the app</DialogTitle>
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
<DialogTitle className="sr-only">Welcome to the app</DialogTitle>
<DialogTitle className="sr-only">Welcome to Kilo</DialogTitle>

<DialogTitle className="sr-only">Welcome to the app</DialogTitle>
<Widget
id={WELCOME_FORM_ID}
style={{ width: '100%', height: '100%', minHeight: '400px' }}
Copy link
Contributor

Choose a reason for hiding this comment

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

Styles here and above are a bit weird, but I guess that's what we need to use because of the library?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it actually works fine without this.

@jfcsantos jfcsantos requested a review from iscekic February 13, 2026 14:42
email: userEmail,
}}
onSubmit={handleComplete}
onClose={handleSkip}
Copy link
Contributor

Choose a reason for hiding this comment

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

WARNING: Closing the Typeform widget also marks the welcome form as completed

Even if you later change the dialog behavior, onClose={handleSkip} currently calls the same completion mutation as submit. If the intent is to only persist completion on submit, consider removing this handler or changing it to record a distinct "dismissed" state.

@@ -0,0 +1,2 @@
ALTER TABLE "kilocode_users" ADD COLUMN "completed_welcome_form" boolean DEFAULT false NOT NULL;
UPDATE "kilocode_users" SET "completed_welcome_form" = true; No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

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

WARNING: Migration may mark users created during deploy as completed

UPDATE "kilocode_users" SET "completed_welcome_form" = true; will also affect any rows inserted after the ALTER TABLE but before the update runs (e.g. users signing up during the migration window), so they may not see the welcome modal even though they're "new". If that edge-case matters, a safer pattern is: add the column nullable/no default → backfill existing rows → then set NOT NULL + DEFAULT false.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is such an edge case and the only fix (I believe) would be to add a timestamp to make sure we capture users created in-between. I'm okay with this current approach

@jfcsantos
Copy link
Contributor Author

@iscekic might giving this another look?

@@ -0,0 +1 @@
ALTER TABLE "kilocode_users" ADD COLUMN "completed_welcome_form" boolean DEFAULT false NOT NULL; No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

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

WARNING: Migration defaults completed_welcome_form to false for all existing users

ALTER TABLE ... ADD COLUMN ... DEFAULT false NOT NULL will make every pre-existing row effectively have completed_welcome_form=false, so the modal will show for everyone until they close/submit it. If the intended behavior is “only new users see this”, the migration likely needs an explicit backfill for existing users (or a separate “dismissed_at/created_at cutoff” approach).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sorry @iscekic I lost the update on the merge conflict with main...fixing it now

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