mirror of https://github.com/sylv/micro.git
106 lines
3.4 KiB
TypeScript
106 lines
3.4 KiB
TypeScript
import { useMutation, useQuery } from '@apollo/client';
|
|
import { FC, useEffect } from 'react';
|
|
import { graphql } from '../../../@generated';
|
|
import { Container } from '../../../components/container';
|
|
import { Error } from '../../../components/error';
|
|
import { PageLoader } from '../../../components/page-loader';
|
|
import { Time } from '../../../components/time';
|
|
import { Title } from '../../../components/title';
|
|
import { useToasts } from '../../../components/toast';
|
|
import type { SignupData } from '../../../containers/signup-form';
|
|
import { SignupForm } from '../../../containers/signup-form';
|
|
import { getErrorMessage } from '../../../helpers/get-error-message.helper';
|
|
import { navigate, prefetch } from '../../../helpers/routing';
|
|
import { useAsync } from '../../../hooks/useAsync';
|
|
import { useConfig } from '../../../hooks/useConfig';
|
|
import { PageProps } from '../../../renderer/types';
|
|
|
|
const GetInvite = graphql(`
|
|
query GetInvite($inviteId: ID!) {
|
|
invite(inviteId: $inviteId) {
|
|
id
|
|
expiresAt
|
|
}
|
|
}
|
|
`);
|
|
|
|
const CreateUser = graphql(`
|
|
mutation CreateUser($user: CreateUserDto!) {
|
|
createUser(data: $user) {
|
|
id
|
|
}
|
|
}
|
|
`);
|
|
|
|
export const Page: FC<PageProps> = ({ routeParams }) => {
|
|
const config = useConfig();
|
|
const createToast = useToasts();
|
|
const inviteToken = routeParams.inviteToken;
|
|
const invite = useQuery(GetInvite, { skip: !inviteToken, variables: { inviteId: inviteToken! } });
|
|
const expiresAt = invite.data?.invite.expiresAt;
|
|
|
|
useEffect(() => {
|
|
prefetch('/login');
|
|
}, []);
|
|
|
|
const [createUserMutation] = useMutation(CreateUser);
|
|
const [onSubmit] = useAsync(async (data: SignupData) => {
|
|
try {
|
|
if (!inviteToken) return;
|
|
await createUserMutation({
|
|
variables: {
|
|
user: {
|
|
...data,
|
|
invite: inviteToken,
|
|
},
|
|
},
|
|
});
|
|
|
|
navigate('/login');
|
|
createToast({ text: 'Account created successfully. Please sign in.' });
|
|
} catch (error) {
|
|
const message = getErrorMessage(error);
|
|
if (message) {
|
|
createToast({ text: message, error: true });
|
|
}
|
|
}
|
|
});
|
|
|
|
if (invite.error || config.error) {
|
|
return <Error error={invite.error || config.error} />;
|
|
}
|
|
|
|
if (!invite.data || !config.data) {
|
|
return <PageLoader title="You're Invited" />;
|
|
}
|
|
|
|
return (
|
|
<Container centerY>
|
|
<Title>You're Invited</Title>
|
|
<h1 className="text-4xl font-bold text-center mb-6 md:hidden">Sign Up</h1>
|
|
{expiresAt && (
|
|
<p className="mt-2 mb-2 text-xs text-center text-gray-600 md:hidden">
|
|
This invite will expire <Time date={expiresAt} />.
|
|
</p>
|
|
)}
|
|
<div className="grid flex-row-reverse grid-cols-6 gap-12">
|
|
<div className="col-span-6 md:col-span-2">
|
|
<SignupForm onSubmit={onSubmit} />
|
|
</div>
|
|
<div className="flex-col justify-center hidden col-span-6 md:flex md:col-span-4">
|
|
<h1 className="mb-2 text-4xl font-bold">Welcome to Micro</h1>
|
|
<p>
|
|
You have been invited to try out micro, an invite-only file sharing service with support for ShareX. Create
|
|
an account, then download the ShareX config and start uploading with your favourite vanity domain.
|
|
</p>
|
|
{expiresAt && (
|
|
<p className="mt-2 text-xs text-gray-600">
|
|
This invite will expire <Time date={expiresAt} />.
|
|
</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</Container>
|
|
);
|
|
};
|