feat(core): impl invitation link (#11181)

feat(core): add invitee to getInviteInfoQuery

feat(core): enable invitation link

refactor(core): replace AcceptInviteService to InvitationService
This commit is contained in:
JimmFly
2025-03-26 02:45:12 +00:00
parent 64b25dfd89
commit 014556b61f
19 changed files with 409 additions and 116 deletions
@@ -113,53 +113,62 @@ export const LinkInvite = ({
return (
<>
<div className={styles.modalSubTitle}>
{t['com.affine.payment.member.team.invite.link-expiration']()}
</div>
<Menu
items={items}
contentOptions={{
style: {
width: 'var(--radix-dropdown-menu-trigger-width)',
},
}}
>
<MenuTrigger style={{ width: '100%' }}>
{currentSelectedLabel}
</MenuTrigger>
</Menu>
<div className={styles.modalSubTitle}>
{t['com.affine.payment.member.team.invite.invitation-link']()}
</div>
<div className={styles.invitationLinkContent}>
<Input
value={
invitationLink
? invitationLink.link
: 'https://your-app.com/invite/xxxxxxxx'
}
inputMode="none"
disabled
inputStyle={{
fontSize: cssVar('fontXs'),
color: cssVarV2(
invitationLink ? 'text/primary' : 'text/placeholder'
),
backgroundColor: cssVarV2('layer/background/primary'),
<div className={styles.invitationLinkContainer}>
<div className={styles.modalSubTitle}>
{t['com.affine.payment.member.team.invite.link-expiration']()}
</div>
<Menu
items={items}
contentOptions={{
style: {
width: 'var(--radix-dropdown-menu-trigger-width)',
},
}}
/>
{invitationLink ? (
<>
<Button onClick={onCopy} variant="secondary">
{t['com.affine.payment.member.team.invite.copy']()}
>
<MenuTrigger style={{ width: '100%' }}>
{currentSelectedLabel}
</MenuTrigger>
</Menu>
</div>
<div className={styles.invitationLinkContainer}>
<div className={styles.modalSubTitle}>
{t['com.affine.payment.member.team.invite.invitation-link']()}
</div>
<div className={styles.invitationLinkContent}>
<Input
value={
invitationLink
? invitationLink.link
: 'https://your-app.com/invite/xxxxxxxx'
}
inputMode="none"
disabled
inputStyle={{
fontSize: cssVar('fontXs'),
color: cssVarV2(
invitationLink ? 'text/primary' : 'text/placeholder'
),
backgroundColor: cssVarV2('layer/background/primary'),
}}
/>
{invitationLink ? (
<>
<Button onClick={onCopy} variant="secondary">
{t['com.affine.payment.member.team.invite.copy']()}
</Button>
<IconButton icon={<CloseIcon />} onClick={onReset} />
</>
) : (
<Button onClick={onGenerate} variant="secondary">
{t['com.affine.payment.member.team.invite.generate']()}
</Button>
<IconButton icon={<CloseIcon />} onClick={onReset} />
</>
) : (
<Button onClick={onGenerate} variant="secondary">
{t['com.affine.payment.member.team.invite.generate']()}
</Button>
)}
)}
</div>
<p className={styles.invitationLinkDescription}>
{t[
'com.affine.payment.member.team.invite.invitation-link.description'
]()}
</p>
</div>
</>
);
@@ -15,7 +15,7 @@ export const ModalContent = ({
inviteEmail,
setInviteEmail,
inviteMethod,
// onInviteMethodChange,
onInviteMethodChange,
handleConfirm,
isMutating,
isValidEmail,
@@ -48,7 +48,7 @@ export const ModalContent = ({
<RadioGroup
width={'100%'}
value={inviteMethod}
// onChange={onInviteMethodChange}
onChange={onInviteMethodChange}
items={[
{
label: (
@@ -65,13 +65,10 @@ export const ModalContent = ({
label: (
<RadioItem
icon={<LinkIcon className={styles.iconStyle} />}
label={`${t['com.affine.payment.member.team.invite.invite-link']()}(Coming soon)`}
label={t['com.affine.payment.member.team.invite.invite-link']()}
/>
),
value: 'link',
style: {
cursor: 'not-allowed',
},
},
]}
/>
@@ -81,6 +81,12 @@ export const modalSubTitle = style({
fontWeight: '500',
});
export const invitationLinkContainer = style({
display: 'flex',
flexDirection: 'column',
gap: '8px',
});
export const radioItem = style({
display: 'flex',
alignItems: 'center',
@@ -107,3 +113,8 @@ export const invitationLinkContent = style({
display: 'flex',
gap: '8px',
});
export const invitationLinkDescription = style({
color: cssVarV2('text/secondary'),
fontSize: cssVar('fontSm'),
});