diff --git a/.windsurfrules b/.windsurfrules
new file mode 100644
index 0000000..2117545
--- /dev/null
+++ b/.windsurfrules
@@ -0,0 +1,13 @@
+You are a Staff Engineer and an Expert in ReactJS, NextJS, JavaScript, TypeScript, HTML, CSS, NodeJS, Prisma, Postgres, and modern UI/UX frameworks (e.g., TailwindCSS, Shadcn, Radix). You are also great at scalling things. You are thoughtful, give nuanced answers, and are brilliant at reasoning. You carefully provide accurate, factual, thoughtful answers, and are a genius at reasoning.
+
+- Follow the user’s requirements carefully & to the letter.
+- First think step-by-step - describe your plan for what to build in pseudocode, written out in great detail.
+- Always write correct, best practice, bug free, fully functional and working code also it should be aligned to listed rules down below at Code Implementation Guidelines .
+- Focus on easy and readability code, over being performant.
+- Fully implement all requested functionality.
+- Leave NO todo’s, placeholders or missing pieces.
+- Ensure code is complete! Verify thoroughly finalised.
+- Include all required imports, and ensure proper naming of key components.
+- Be concise Minimize any other prose.
+- If you think there might not be a correct answer, you say so.
+- If you do not know the answer, say so, instead of guessing.
diff --git a/apps/web/prisma/migrations/20250323114242_add_team_invites/migration.sql b/apps/web/prisma/migrations/20250323114242_add_team_invites/migration.sql
new file mode 100644
index 0000000..e6a1997
--- /dev/null
+++ b/apps/web/prisma/migrations/20250323114242_add_team_invites/migration.sql
@@ -0,0 +1,14 @@
+-- CreateTable
+CREATE TABLE "TeamInvite" (
+ "id" TEXT NOT NULL,
+ "teamId" INTEGER NOT NULL,
+ "email" TEXT NOT NULL,
+ "role" "Role" NOT NULL,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "TeamInvite_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateIndex
+CREATE UNIQUE INDEX "TeamInvite_teamId_email_key" ON "TeamInvite"("teamId", "email");
diff --git a/apps/web/prisma/migrations/20250323115457_add_created_at_for_users/migration.sql b/apps/web/prisma/migrations/20250323115457_add_created_at_for_users/migration.sql
new file mode 100644
index 0000000..eb3480e
--- /dev/null
+++ b/apps/web/prisma/migrations/20250323115457_add_created_at_for_users/migration.sql
@@ -0,0 +1,2 @@
+-- AlterTable
+ALTER TABLE "User" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
diff --git a/apps/web/prisma/migrations/20250325113154_add_team_invites_foreign_key_to_team/migration.sql b/apps/web/prisma/migrations/20250325113154_add_team_invites_foreign_key_to_team/migration.sql
new file mode 100644
index 0000000..37d56a0
--- /dev/null
+++ b/apps/web/prisma/migrations/20250325113154_add_team_invites_foreign_key_to_team/migration.sql
@@ -0,0 +1,2 @@
+-- AddForeignKey
+ALTER TABLE "TeamInvite" ADD CONSTRAINT "TeamInvite_teamId_fkey" FOREIGN KEY ("teamId") REFERENCES "Team"("id") ON DELETE CASCADE ON UPDATE CASCADE;
diff --git a/apps/web/prisma/schema.prisma b/apps/web/prisma/schema.prisma
index a68a10f..e26228f 100644
--- a/apps/web/prisma/schema.prisma
+++ b/apps/web/prisma/schema.prisma
@@ -85,6 +85,7 @@ model User {
emailVerified DateTime?
image String?
isBetaUser Boolean @default(false)
+ createdAt DateTime @default(now())
accounts Account[]
sessions Session[]
teamUsers TeamUser[]
@@ -112,7 +113,21 @@ model Team {
campaigns Campaign[]
templates Template[]
dailyEmailUsages DailyEmailUsage[]
- Subscription Subscription[]
+ subscription Subscription[]
+ invites TeamInvite[]
+}
+
+model TeamInvite {
+ id String @id @default(cuid())
+ teamId Int
+ email String
+ role Role
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+
+ team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
+
+ @@unique([teamId, email])
}
model Subscription {
diff --git a/apps/web/src/app/(dashboard)/settings/billing/page.tsx b/apps/web/src/app/(dashboard)/settings/billing/page.tsx
index c72ac9c..77b30d4 100644
--- a/apps/web/src/app/(dashboard)/settings/billing/page.tsx
+++ b/apps/web/src/app/(dashboard)/settings/billing/page.tsx
@@ -9,8 +9,9 @@ import { useTeam } from "~/providers/team-context";
import { api } from "~/trpc/react";
import { PlanDetails } from "~/components/payments/PlanDetails";
import { UpgradeButton } from "~/components/payments/UpgradeButton";
+
export default function SettingsPage() {
- const { currentTeam } = useTeam();
+ const { currentTeam, currentIsAdmin } = useTeam();
const manageSessionUrl = api.billing.getManageSessionUrl.useMutation();
const updateBillingEmailMutation =
api.billing.updateBillingEmail.useMutation();
@@ -47,6 +48,10 @@ export default function SettingsPage() {
const paymentMethod = JSON.parse(subscription?.paymentMethod || "{}");
+ if (!currentIsAdmin) {
+ return null;
+ }
+
if (!currentTeam?.plan) {
return (