Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/app/(main)/invite/InviteForm.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.container {
margin: 0 auto;
max-width: 400px;
padding: 20px;
}

.form {
background: var(--base50);
border-radius: 8px;
padding: 20px;
}

@media screen and (max-width: 768px) {
.container {
margin: 0;
padding: 10px;
}

.form {
padding: 15px;
}
}
57 changes: 57 additions & 0 deletions src/app/(main)/invite/InviteForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
'use client';
import { Form, FormRow, FormInput, FormButtons, TextField, Button } from 'react-basics';
import { useApi, useMessages, useModified } from '@/components/hooks';
import styles from './InviteForm.module.css';
import { useRouter, useSearchParams } from 'next/navigation';

export function InviteForm() {
const searchParams = useSearchParams();
const router = useRouter();
const accessCode = searchParams.get('accessCode');
const { formatMessage, labels } = useMessages();
const { post, useMutation } = useApi();

const { mutate, error } = useMutation({
mutationFn: (data: any) => post('/teams/join', data),
});

const { touch } = useModified();

const handleSubmit = async (data: any) => {
mutate(data, {
onSuccess: async () => {
touch('teams:members');
},
});
Comment on lines +20 to +25
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: No navigation or user feedback after successful team join - users may not know the operation completed

};
const onClose = () => {
router.replace('/dashboard');
};
return (
<div className={styles.container}>
<div className={styles.form}>
<Form
onSubmit={handleSubmit}
error={error}
values={{
accessCode: accessCode || '',
}}
autoComplete="off"
preventSubmit={false}
>
<FormRow label={formatMessage(labels.accessCode)}>
<FormInput name="accessCode" rules={{ required: formatMessage(labels.required) }}>
<TextField autoComplete="off" />
</FormInput>
</FormRow>
<FormButtons flex>
<Button type="submit" variant="primary">
{formatMessage(labels.join)}
</Button>
<Button onClick={onClose}>{formatMessage(labels.cancel)}</Button>
</FormButtons>
</Form>
</div>
</div>
);
}
11 changes: 11 additions & 0 deletions src/app/(main)/invite/InvitePage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
'use client';

import { InviteForm } from './InviteForm';

export default function InvitePage() {
return (
<section style={{ marginBottom: 60 }}>
<InviteForm />
</section>
);
}
10 changes: 10 additions & 0 deletions src/app/(main)/invite/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Metadata } from 'next';
import InvitePage from './InvitePage';

export const metadata: Metadata = {
title: 'Join team',
};

export default function () {
return <InvitePage />;
}
9 changes: 9 additions & 0 deletions src/app/(main)/teams/[teamId]/settings/team/TeamEditForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ export function TeamEditForm({ teamId, allowEdit }: { teamId: string; allowEdit?
</Flexbox>
</FormRow>
)}
<FormRow label={formatMessage(labels.invitationLink)}>
<Flexbox gap={10}>
<TextField
value={`${window.location.host}/invite?accessCode=${accessCode}`}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Using window.location.host in a Next.js component can cause hydration errors since window is undefined during server-side rendering. Consider using useEffect to set this value client-side only.

readOnly
allowCopy
/>
</Flexbox>
</FormRow>
Comment on lines +74 to +82
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: The invitation link is shown regardless of cloudMode or allowEdit permissions, while the access code field above is conditionally rendered. Consider if this should have similar conditional logic.

{allowEdit && (
<FormButtons>
<SubmitButton variant="primary">{formatMessage(labels.save)}</SubmitButton>
Expand Down
1 change: 1 addition & 0 deletions src/components/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const labels = defineMessages({
member: { id: 'label.member', defaultMessage: 'Member' },
members: { id: 'label.members', defaultMessage: 'Members' },
accessCode: { id: 'label.access-code', defaultMessage: 'Access code' },
invitationLink: { id: 'label.invitation-link', defaultMessage: 'Invitation link' },
teamId: { id: 'label.team-id', defaultMessage: 'Team ID' },
team: { id: 'label.team', defaultMessage: 'Team' },
teamName: { id: 'label.team-name', defaultMessage: 'Team name' },
Expand Down
1 change: 1 addition & 0 deletions src/lang/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@
"label.websites": "Websites",
"label.window": "Window",
"label.yesterday": "Yesterday",
"label.invitation-link": "Invitation link",
"message.action-confirmation": "Type {confirmation} in the box below to confirm.",
"message.active-users": "{x} current {x, plural, one {visitor} other {visitors}}",
"message.collected-data": "Collected data",
Expand Down
1 change: 1 addition & 0 deletions src/lang/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@
"label.websites": "网站",
"label.window": "窗口",
"label.yesterday": "昨天",
"label.invitation-link": "邀请链接",
"message.action-confirmation": "请在下方输入框中输入 {confirmation} 以确认操作。",
"message.active-users": "当前在线 {x} 位访客",
"message.collected-data": "已收集的数据",
Expand Down