From cd253291fefdb8bc55e9cd32b686a7dd74a387a8 Mon Sep 17 00:00:00 2001 From: thedittya471 Date: Tue, 14 Jul 2026 15:29:39 +0530 Subject: [PATCH] feat: collaborator user search autocomplete, form scheduling & limits lockout UI --- README.md | 52 +- apps/api/src/server.ts | 6 +- apps/api/tsup.config.ts | 4 +- apps/web/app/(auth)/layout.tsx | 16 +- apps/web/app/(auth)/signIn/page.tsx | 38 +- apps/web/app/(auth)/signUp/page.tsx | 41 +- .../app/dashboard/analytics/[formId]/page.tsx | 149 +- apps/web/app/dashboard/analytics/page.tsx | 93 +- apps/web/app/dashboard/layout.tsx | 46 +- apps/web/app/dashboard/page.tsx | 93 +- apps/web/app/dashboard/pricing/page.tsx | 41 +- .../app/dashboard/sketches/[formId]/page.tsx | 155 +- apps/web/app/dashboard/sketches/page.tsx | 31 +- apps/web/app/forms/[formId]/page.tsx | 70 +- apps/web/components/Sidebar.tsx | 26 +- .../components/analytics/AnalyticsSidebar.tsx | 4 +- .../components/analytics/DeviceBreakdown.tsx | 31 +- .../web/components/analytics/DowBreakdown.tsx | 8 +- .../analytics/FieldCompletionRates.tsx | 8 +- .../components/analytics/HourlyHeatmap.tsx | 23 +- apps/web/components/analytics/MetricsGrid.tsx | 8 +- .../analytics/QuestionDistribution.tsx | 66 +- .../components/analytics/ResponseTimeline.tsx | 13 +- apps/web/components/analytics/StatsRow.tsx | 4 +- .../analytics/SubmissionDetailModal.tsx | 18 +- .../components/analytics/SubmissionsTable.tsx | 31 +- .../components/analytics/TrafficSources.tsx | 40 +- .../web/components/analytics/UpgradeModal.tsx | 26 +- apps/web/components/builder/BuilderHeader.tsx | 47 +- .../components/builder/DeleteFormDialog.tsx | 11 +- .../web/components/builder/FieldInspector.tsx | 65 +- apps/web/components/builder/FieldSidebar.tsx | 12 +- apps/web/components/builder/FormFieldNode.tsx | 46 +- .../components/builder/FormSettingsDialog.tsx | 236 +++ .../builder/ShareCollaboratorsDialog.tsx | 95 +- apps/web/components/builder/UnsavedDialog.tsx | 11 +- .../builder/mobile/MobileAddFieldSheet.tsx | 18 +- .../builder/mobile/MobileFieldEditorSheet.tsx | 9 +- .../builder/mobile/MobileFieldList.tsx | 21 +- apps/web/components/forms/FormErrorState.tsx | 44 +- apps/web/components/forms/FormHeader.tsx | 19 +- .../web/components/forms/FormLoadingState.tsx | 4 +- apps/web/components/forms/FormQuestion.tsx | 61 +- apps/web/components/forms/FormThankYou.tsx | 7 +- apps/web/components/landing/ArticleTrio.tsx | 13 +- apps/web/components/landing/CutDropOff.tsx | 5 +- apps/web/components/landing/FooterSunset.tsx | 12 +- apps/web/components/landing/HeroSunset.tsx | 4 +- apps/web/components/landing/HowItWorks.tsx | 32 +- .../components/landing/LandingNavSunset.tsx | 8 +- .../web/components/landing/NetworkSection.tsx | 5 +- .../components/landing/StepIntoCanvasFlow.tsx | 13 +- apps/web/components/landing/TrackInApp.tsx | 4 +- apps/web/components/ui/accordion.tsx | 26 +- apps/web/components/ui/alert-dialog.tsx | 70 +- apps/web/components/ui/alert.tsx | 30 +- apps/web/components/ui/aspect-ratio.tsx | 12 +- apps/web/components/ui/avatar.tsx | 36 +- apps/web/components/ui/badge.tsx | 33 +- apps/web/components/ui/breadcrumb.tsx | 41 +- apps/web/components/ui/button-group.tsx | 33 +- apps/web/components/ui/button.tsx | 29 +- apps/web/components/ui/calendar.tsx | 120 +- apps/web/components/ui/card.tsx | 43 +- apps/web/components/ui/carousel.tsx | 151 +- apps/web/components/ui/chart.tsx | 187 +-- apps/web/components/ui/checkbox.tsx | 21 +- apps/web/components/ui/collapsible.tsx | 26 +- apps/web/components/ui/command.tsx | 87 +- apps/web/components/ui/context-menu.tsx | 104 +- apps/web/components/ui/dialog.tsx | 64 +- apps/web/components/ui/drawer.tsx | 57 +- apps/web/components/ui/dropdown-menu.tsx | 103 +- apps/web/components/ui/empty.tsx | 40 +- apps/web/components/ui/field.tsx | 124 +- apps/web/components/ui/form.tsx | 97 +- apps/web/components/ui/hover-card.tsx | 28 +- apps/web/components/ui/input-group.tsx | 88 +- apps/web/components/ui/input-otp.tsx | 41 +- apps/web/components/ui/input.tsx | 10 +- apps/web/components/ui/item.tsx | 81 +- apps/web/components/ui/kbd.tsx | 10 +- apps/web/components/ui/label.tsx | 19 +- apps/web/components/ui/menubar.tsx | 110 +- apps/web/components/ui/navigation-menu.tsx | 55 +- apps/web/components/ui/pagination.tsx | 61 +- apps/web/components/ui/popover.tsx | 32 +- apps/web/components/ui/progress.tsx | 17 +- apps/web/components/ui/radio-group.tsx | 18 +- apps/web/components/ui/resizable.tsx | 31 +- apps/web/components/ui/scroll-area.tsx | 22 +- apps/web/components/ui/select.tsx | 69 +- apps/web/components/ui/separator.tsx | 14 +- apps/web/components/ui/sheet.tsx | 55 +- apps/web/components/ui/sidebar.tsx | 302 ++-- apps/web/components/ui/skeleton.tsx | 6 +- apps/web/components/ui/slider.tsx | 29 +- apps/web/components/ui/sonner.tsx | 12 +- apps/web/components/ui/spinner.tsx | 8 +- apps/web/components/ui/switch.tsx | 21 +- apps/web/components/ui/table.tsx | 60 +- apps/web/components/ui/tabs.tsx | 42 +- apps/web/components/ui/textarea.tsx | 10 +- apps/web/components/ui/toggle-group.tsx | 33 +- apps/web/components/ui/toggle.tsx | 21 +- apps/web/components/ui/tooltip.tsx | 28 +- apps/web/hooks/api/analytics/index.ts | 176 +-- apps/web/hooks/api/auth/index.ts | 10 +- apps/web/hooks/api/form/index.ts | 1061 +++++++------- apps/web/hooks/api/user/index.ts | 53 +- apps/web/hooks/use-mobile.ts | 22 +- apps/web/hooks/useDebounce.ts | 54 +- apps/web/lib/auth-client.ts | 4 +- apps/web/lib/utils.ts | 6 +- apps/web/middleware.ts | 7 +- apps/web/providers/dashboard-provider.tsx | 18 +- apps/web/trpc/create-client.ts | 2 +- .../database/drizzle/0010_fine_the_spike.sql | 2 + .../database/drizzle/meta/0010_snapshot.json | 1281 +++++++++++++++++ packages/database/drizzle/meta/_journal.json | 7 + packages/database/index.ts | 6 +- packages/database/models/auth.ts | 100 +- packages/database/models/form-collaborator.ts | 45 +- packages/database/models/form-field-view.ts | 28 +- packages/database/models/form-field.ts | 104 +- packages/database/models/form-submission.ts | 48 +- packages/database/models/form-view.ts | 27 +- packages/database/models/form.ts | 49 +- packages/database/schema.ts | 1 - packages/logger/index.ts | 7 +- packages/services/analytics/index.ts | 621 ++++---- packages/services/analytics/model.ts | 130 +- packages/services/env.ts | 2 +- packages/services/form-field/index.ts | 382 ++--- packages/services/form-field/model.ts | 184 +-- packages/services/form-submission/index.ts | 202 +-- packages/services/form-submission/model.ts | 76 +- packages/services/form/index.ts | 494 ++++--- packages/services/form/model.ts | 228 +-- packages/trpc/client/index.ts | 1 - packages/trpc/server/auth.ts | 89 +- packages/trpc/server/context.ts | 46 +- packages/trpc/server/index.ts | 1 - .../trpc/server/routes/analytics/model.ts | 2 +- .../trpc/server/routes/analytics/route.ts | 115 +- packages/trpc/server/routes/form/model.ts | 144 +- packages/trpc/server/routes/form/route.ts | 572 ++++---- packages/trpc/server/routes/user/route.ts | 88 +- packages/trpc/server/trpc.ts | 59 +- 149 files changed, 6169 insertions(+), 5195 deletions(-) create mode 100644 apps/web/components/builder/FormSettingsDialog.tsx create mode 100644 packages/database/drizzle/0010_fine_the_spike.sql create mode 100644 packages/database/drizzle/meta/0010_snapshot.json diff --git a/README.md b/README.md index 5a71388..4a0262c 100644 --- a/README.md +++ b/README.md @@ -22,18 +22,18 @@ Drag fields onto an open canvas, connect them like nodes, watch responses light ## Tech stack -| Layer | Choice | -| --- | --- | -| Monorepo | Turborepo + pnpm workspaces | -| Web app | Next.js 16 (App Router, Turbopack), React 19, Tailwind v4, Radix UI primitives, Motion | -| Canvas builder | `@xyflow/react` | -| Charts | Recharts (lazy-loaded per route) | -| API | Express 5 + tRPC 11 (OpenAPI generated via `trpc-to-openapi`) | -| Auth | Better Auth with email/password, Google OAuth, GitHub OAuth, signed cookie cache | -| DB | PostgreSQL via Drizzle ORM, `pg` connection pool, migrations via `drizzle-kit` | -| Validation | Zod (shared between client, server, and OpenAPI schema) | -| State / data | TanStack Query (tRPC React Query adapter) | -| Logging | Winston | +| Layer | Choice | +| -------------- | -------------------------------------------------------------------------------------- | +| Monorepo | Turborepo + pnpm workspaces | +| Web app | Next.js 16 (App Router, Turbopack), React 19, Tailwind v4, Radix UI primitives, Motion | +| Canvas builder | `@xyflow/react` | +| Charts | Recharts (lazy-loaded per route) | +| API | Express 5 + tRPC 11 (OpenAPI generated via `trpc-to-openapi`) | +| Auth | Better Auth with email/password, Google OAuth, GitHub OAuth, signed cookie cache | +| DB | PostgreSQL via Drizzle ORM, `pg` connection pool, migrations via `drizzle-kit` | +| Validation | Zod (shared between client, server, and OpenAPI schema) | +| State / data | TanStack Query (tRPC React Query adapter) | +| Logging | Winston | ## Architecture @@ -123,12 +123,12 @@ pnpm dev This boots, in parallel: -| URL | What | -| --- | --- | -| `http://localhost:3000` | Next.js studio (web) | -| `http://localhost:8000/trpc` | tRPC HTTP endpoint | -| `http://localhost:8000/docs` | Auto-generated Scalar API reference | -| `http://localhost:8000/openapi.json` | OpenAPI 3.1 spec | +| URL | What | +| ------------------------------------ | ----------------------------------- | +| `http://localhost:3000` | Next.js studio (web) | +| `http://localhost:8000/trpc` | tRPC HTTP endpoint | +| `http://localhost:8000/docs` | Auto-generated Scalar API reference | +| `http://localhost:8000/openapi.json` | OpenAPI 3.1 spec | Sign up at `/signUp`, build a form, publish it, share `/forms/`, watch responses populate `/dashboard/analytics`. @@ -136,15 +136,15 @@ Sign up at `/signUp`, build a form, publish it, share `/forms/`, watch respo All scripts are turbo-orchestrated and `dotenv -- ...` wrapped so workspaces share the root env. -| Script | What it does | -| --- | --- | -| `pnpm dev` | Run every workspace's dev task | -| `pnpm build` | Build the API and the web app for production | -| `pnpm lint` | ESLint across all workspaces (zero-warning) | -| `pnpm check-types` | TypeScript no-emit type-check | -| `pnpm format` | Prettier across `**/*.{ts,tsx,md}` | +| Script | What it does | +| ------------------ | ------------------------------------------------ | +| `pnpm dev` | Run every workspace's dev task | +| `pnpm build` | Build the API and the web app for production | +| `pnpm lint` | ESLint across all workspaces (zero-warning) | +| `pnpm check-types` | TypeScript no-emit type-check | +| `pnpm format` | Prettier across `**/*.{ts,tsx,md}` | | `pnpm db:generate` | Generate a Drizzle migration from schema changes | -| `pnpm db:migrate` | Apply pending migrations | +| `pnpm db:migrate` | Apply pending migrations | Filter to a single workspace with `pnpm -F web