feat: add invite user form
This commit is contained in:
parent
7f33e2de0d
commit
e0e044945f
@ -5,28 +5,81 @@ import { CommonWrapper } from '@/components/CommonWrapper';
|
|||||||
import { ScrollArea } from '@/components/ui/scroll-area';
|
import { ScrollArea } from '@/components/ui/scroll-area';
|
||||||
import { useCurrentWorkspace } from '../../store/user';
|
import { useCurrentWorkspace } from '../../store/user';
|
||||||
import { CommonHeader } from '@/components/CommonHeader';
|
import { CommonHeader } from '@/components/CommonHeader';
|
||||||
import { Card, CardContent, CardHeader } from '@/components/ui/card';
|
import {
|
||||||
|
Card,
|
||||||
|
CardContent,
|
||||||
|
CardFooter,
|
||||||
|
CardHeader,
|
||||||
|
} from '@/components/ui/card';
|
||||||
import { Typography } from 'antd';
|
import { Typography } from 'antd';
|
||||||
import { AppRouterOutput, trpc } from '@/api/trpc';
|
import {
|
||||||
|
AppRouterOutput,
|
||||||
|
defaultErrorHandler,
|
||||||
|
defaultSuccessHandler,
|
||||||
|
trpc,
|
||||||
|
} from '@/api/trpc';
|
||||||
import { createColumnHelper, DataTable } from '@/components/DataTable';
|
import { createColumnHelper, DataTable } from '@/components/DataTable';
|
||||||
import { useMemo } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import { get } from 'lodash-es';
|
import { get } from 'lodash-es';
|
||||||
import { Badge } from '@/components/ui/badge';
|
import { Badge } from '@/components/ui/badge';
|
||||||
|
import { Input } from '@/components/ui/input';
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormDescription,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from '@/components/ui/form';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
import { useEventWithLoading } from '@/hooks/useEvent';
|
||||||
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
export const Route = createFileRoute('/settings/workspace')({
|
export const Route = createFileRoute('/settings/workspace')({
|
||||||
beforeLoad: routeAuthBeforeLoad,
|
beforeLoad: routeAuthBeforeLoad,
|
||||||
component: PageComponent,
|
component: PageComponent,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const inviteFormSchema = z.object({
|
||||||
|
email: z.string().email(),
|
||||||
|
});
|
||||||
|
|
||||||
|
type InviteFormValues = z.infer<typeof inviteFormSchema>;
|
||||||
|
|
||||||
type MemberInfo = AppRouterOutput['workspace']['members'][number];
|
type MemberInfo = AppRouterOutput['workspace']['members'][number];
|
||||||
const columnHelper = createColumnHelper<MemberInfo>();
|
const columnHelper = createColumnHelper<MemberInfo>();
|
||||||
|
|
||||||
function PageComponent() {
|
function PageComponent() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { id, name } = useCurrentWorkspace();
|
const { id: workspaceId, name } = useCurrentWorkspace();
|
||||||
const { data: members = [] } = trpc.workspace.members.useQuery({
|
const { data: members = [], refetch: refetchMembers } =
|
||||||
workspaceId: id,
|
trpc.workspace.members.useQuery({
|
||||||
|
workspaceId,
|
||||||
});
|
});
|
||||||
|
const form = useForm<InviteFormValues>({
|
||||||
|
resolver: zodResolver(inviteFormSchema),
|
||||||
|
defaultValues: {
|
||||||
|
email: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const inviteMutation = trpc.workspace.invite.useMutation({
|
||||||
|
onSuccess: defaultSuccessHandler,
|
||||||
|
onError: defaultErrorHandler,
|
||||||
|
});
|
||||||
|
|
||||||
|
const [handleInvite, isLoading] = useEventWithLoading(
|
||||||
|
async (values: InviteFormValues) => {
|
||||||
|
await inviteMutation.mutateAsync({
|
||||||
|
workspaceId,
|
||||||
|
targetUserEmail: values.email,
|
||||||
|
});
|
||||||
|
|
||||||
|
refetchMembers();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const columns = useMemo(() => {
|
const columns = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
@ -72,13 +125,45 @@ function PageComponent() {
|
|||||||
<span className="mr-2">{t('Workspace ID')}:</span>
|
<span className="mr-2">{t('Workspace ID')}:</span>
|
||||||
<span>
|
<span>
|
||||||
<Typography.Text code={true} copyable={true}>
|
<Typography.Text code={true} copyable={true}>
|
||||||
{id}
|
{workspaceId}
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
<Form {...form}>
|
||||||
|
<form onSubmit={form.handleSubmit(handleInvite)}>
|
||||||
|
<Card>
|
||||||
|
<CardHeader className="text-lg font-bold">
|
||||||
|
{t('Invite new members by email address')}
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="email"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="max-w-[320px]">
|
||||||
|
<FormLabel />
|
||||||
|
<FormControl>
|
||||||
|
<Input placeholder="jane@example.com" {...field} />
|
||||||
|
</FormControl>
|
||||||
|
<FormDescription />
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</CardContent>
|
||||||
|
|
||||||
|
<CardFooter>
|
||||||
|
<Button type="submit" loading={isLoading}>
|
||||||
|
{t('Invite')}
|
||||||
|
</Button>
|
||||||
|
</CardFooter>
|
||||||
|
</Card>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader className="text-lg font-bold">
|
<CardHeader className="text-lg font-bold">
|
||||||
{t('Members')}
|
{t('Members')}
|
||||||
|
Loading…
Reference in New Issue
Block a user