feat: add invitation link limits

This commit is contained in:
2026-07-03 04:59:34 -07:00
parent fb15d4db47
commit 9fd2088a2a
20 changed files with 4968 additions and 15 deletions

View File

@@ -8,6 +8,14 @@ import { Button } from "@/components/ui/button";
import { Dialog } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Select } from "@/components/ui/select";
import {
DEFAULT_INVITATION_MAX_USES,
DEFAULT_INVITATION_VALIDITY_DAYS,
MAX_INVITATION_MAX_USES,
MAX_INVITATION_VALIDITY_DAYS,
MIN_INVITATION_MAX_USES,
MIN_INVITATION_VALIDITY_DAYS,
} from "@/modules/core/invitation-limits";
import type { ApiResult } from "@/modules/core/server/api";
import type { Organization, OrganizationInvitation, RoleDefinition } from "@/modules/core/types";
@@ -64,7 +72,9 @@ export function OrganizationInviteDialog({
headers: { "content-type": "application/json" },
body: JSON.stringify({
email: String(formData.get("email") ?? ""),
maxUses: Number(formData.get("maxUses") ?? DEFAULT_INVITATION_MAX_USES),
roleId,
validityDays: Number(formData.get("validityDays") ?? DEFAULT_INVITATION_VALIDITY_DAYS),
}),
});
const result = (await response.json()) as ApiResult<{ invitation: OrganizationInvitation }>;
@@ -84,7 +94,7 @@ export function OrganizationInviteDialog({
return (
<Dialog
description={`生成 ${organization.name} 的邀请链接,可限定邮箱并指定入组角色。`}
description={`生成 ${organization.name} 的邀请链接,可限定邮箱入组角色、有效期和使用次数`}
onClose={closeDialog}
open={open}
title="发起机构邀请"
@@ -109,6 +119,26 @@ export function OrganizationInviteDialog({
required
/>
</label>
<div className="grid gap-3 sm:grid-cols-2">
<Input
defaultValue={DEFAULT_INVITATION_VALIDITY_DAYS}
label="有效期(天)"
max={MAX_INVITATION_VALIDITY_DAYS}
min={MIN_INVITATION_VALIDITY_DAYS}
name="validityDays"
required
type="number"
/>
<Input
defaultValue={DEFAULT_INVITATION_MAX_USES}
label="最大使用次数"
max={MAX_INVITATION_MAX_USES}
min={MIN_INVITATION_MAX_USES}
name="maxUses"
required
type="number"
/>
</div>
{message ? (
<p className="rounded-md bg-secondary px-3 py-2 text-sm text-secondary-foreground" role="status">
{message}