Compare commits

...

4 Commits

Author SHA1 Message Date
Henry
e18cc32eb7 feat: unpause all members on pro activation 2025-09-18 22:08:12 +01:00
Henry
51354ad763 chore: add translations 2025-09-18 21:42:51 +01:00
Henry
6cb2c9a6a6 feat: add paused badge to member table 2025-09-18 21:40:59 +01:00
Henry
315fbb05f5 feat: add paused member status 2025-09-18 21:19:38 +01:00
20 changed files with 2699 additions and 9 deletions

View File

@@ -295,6 +295,7 @@ checksums:
Password%20Changed/singular: 1fcebe9ddb46f722a57f195efddc695d
Password%20must%20be%20at%20least%208%20characters/singular: 4c30501d085eaccea47af34212bb26a7
Passwords%20do%20not%20match/singular: 37ca1f4e0afc9a0b8e9617f767103c92
Paused/singular: edb1f7b7219e1c9b7aa67159090d6991
Payment%20frequency/singular: 63ded0e4ffb462ca8bd33d38e4691d86
Pending/singular: 030a6f3395d5d4efddd3cc67d6009039
per%20user%2Fmonth/singular: 72af182c1ba6df6732640f4d8a78d360

View File

@@ -1280,6 +1280,10 @@ msgstr "Passwort muss mindestens 8 Zeichen lang sein"
msgid "Passwords do not match"
msgstr "Passwörter stimmen nicht überein"
#: src/views/members/index.tsx:134
msgid "Paused"
msgstr "Pausiert"
#: src/views/home/components/Pricing.tsx:102
msgid "Payment frequency"
msgstr "Zahlungshäufigkeit"

File diff suppressed because one or more lines are too long

View File

@@ -1370,6 +1370,10 @@ msgstr "Password must be at least 8 characters"
msgid "Passwords do not match"
msgstr "Passwords do not match"
#: src/views/members/index.tsx:134
msgid "Paused"
msgstr "Paused"
#: src/views/home/components/Pricing.tsx:102
msgid "Payment frequency"
msgstr "Payment frequency"

File diff suppressed because one or more lines are too long

View File

@@ -1280,6 +1280,10 @@ msgstr "La contraseña debe tener al menos 8 caracteres"
msgid "Passwords do not match"
msgstr "Las contraseñas no coinciden"
#: src/views/members/index.tsx:134
msgid "Paused"
msgstr "Pausado"
#: src/views/home/components/Pricing.tsx:102
msgid "Payment frequency"
msgstr "Frecuencia de pago"

File diff suppressed because one or more lines are too long

View File

@@ -1280,6 +1280,10 @@ msgstr "Le mot de passe doit comporter au moins 8 caractères"
msgid "Passwords do not match"
msgstr "Les mots de passe ne correspondent pas"
#: src/views/members/index.tsx:134
msgid "Paused"
msgstr "En pause"
#: src/views/home/components/Pricing.tsx:102
msgid "Payment frequency"
msgstr "Fréquence de paiement"

File diff suppressed because one or more lines are too long

View File

@@ -1280,6 +1280,10 @@ msgstr "La password deve contenere almeno 8 caratteri"
msgid "Passwords do not match"
msgstr "Le password non corrispondono"
#: src/views/members/index.tsx:134
msgid "Paused"
msgstr "In pausa"
#: src/views/home/components/Pricing.tsx:102
msgid "Payment frequency"
msgstr "Frequenza di pagamento"

File diff suppressed because one or more lines are too long

View File

@@ -1280,6 +1280,10 @@ msgstr "Wachtwoord moet minimaal 8 tekens bevatten"
msgid "Passwords do not match"
msgstr "Wachtwoorden komen niet overeen"
#: src/views/members/index.tsx:134
msgid "Paused"
msgstr "Gepauzeerd"
#: src/views/home/components/Pricing.tsx:102
msgid "Payment frequency"
msgstr "Betalingsfrequentie"

File diff suppressed because one or more lines are too long

View File

@@ -129,9 +129,9 @@ export default function MembersPage() {
{memberRole &&
memberRole.charAt(0).toUpperCase() + memberRole.slice(1)}
</span>
{memberStatus === "invited" && (
{(memberStatus === "invited" || memberStatus === "paused") && (
<span className="mt-1 inline-flex items-center rounded-md bg-gray-500/10 px-1.5 py-0.5 text-[10px] font-medium text-gray-400 ring-1 ring-inset ring-gray-500/20 sm:ml-2 sm:mt-0 sm:text-[11px]">
{t`Pending`}
{memberStatus === "invited" ? t`Pending` : t`Paused`}
</span>
)}
</div>

View File

@@ -220,6 +220,19 @@ export const initAuth = (db: dbClient) => {
console.log(
`Pro subscription ${stripeSubscription.id} activated with unlimited seats`,
);
const workspace = await workspaceRepo.getByPublicId(
db,
subscription.referenceId,
);
if (workspace?.id) {
await memberRepo.unpauseAllMembers(db, workspace.id);
console.log(
`Unpausing all members for workspace ${workspace.id}`,
);
}
}
},
},

View File

@@ -0,0 +1 @@
ALTER TYPE "public"."member_status" ADD VALUE 'paused';

File diff suppressed because it is too large Load Diff

View File

@@ -99,6 +99,13 @@
"when": 1757535838766,
"tag": "20250910202358_AddCascadeSetNullToReferenceIdOnSubsriptions",
"breakpoints": true
},
{
"idx": 14,
"version": "7",
"when": 1758226671081,
"tag": "20250918201751_AddPausedMemberStatus",
"breakpoints": true
}
]
}

View File

@@ -95,3 +95,15 @@ export const softDelete = async (
return result;
};
export const unpauseAllMembers = async (db: dbClient, workspaceId: number) => {
await db
.update(workspaceMembers)
.set({ status: "active" })
.where(
and(
eq(workspaceMembers.workspaceId, workspaceId),
eq(workspaceMembers.status, "paused"),
),
);
};

View File

@@ -19,7 +19,12 @@ export const memberRoles = ["admin", "member", "guest"] as const;
export type MemberRole = (typeof memberRoles)[number];
export const memberRoleEnum = pgEnum("role", memberRoles);
export const memberStatuses = ["invited", "active", "removed"] as const;
export const memberStatuses = [
"invited",
"active",
"removed",
"paused",
] as const;
export type MemberStatus = (typeof memberStatuses)[number];
export const memberStatusEnum = pgEnum("member_status", memberStatuses);