|
@@ -1,8 +1,12 @@
|
|
|
-import React from 'react';
|
|
|
|
|
|
|
+import React, { useCallback, useState } from 'react';
|
|
|
|
|
|
|
|
import { useTranslation } from 'next-i18next';
|
|
import { useTranslation } from 'next-i18next';
|
|
|
|
|
+import { useRouter } from 'next/router';
|
|
|
|
|
+
|
|
|
|
|
+import { apiv3Post } from '~/client/util/apiv3-client';
|
|
|
|
|
+
|
|
|
|
|
+import { useCurrentUser } from '../stores/context';
|
|
|
|
|
|
|
|
-import { useCsrfToken, useCurrentUser } from '../stores/context';
|
|
|
|
|
|
|
|
|
|
export type InvitedFormProps = {
|
|
export type InvitedFormProps = {
|
|
|
invitedFormUsername: string,
|
|
invitedFormUsername: string,
|
|
@@ -10,23 +14,79 @@ export type InvitedFormProps = {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export const InvitedForm = (props: InvitedFormProps): JSX.Element => {
|
|
export const InvitedForm = (props: InvitedFormProps): JSX.Element => {
|
|
|
|
|
+
|
|
|
const { t } = useTranslation();
|
|
const { t } = useTranslation();
|
|
|
- const { data: csrfToken } = useCsrfToken();
|
|
|
|
|
|
|
+ const router = useRouter();
|
|
|
const { data: user } = useCurrentUser();
|
|
const { data: user } = useCurrentUser();
|
|
|
|
|
+ const [isConnectSuccess, setIsConnectSuccess] = useState<boolean>(false);
|
|
|
|
|
+ const [loginErrors, setLoginErrors] = useState<Error[]>([]);
|
|
|
|
|
|
|
|
const { invitedFormUsername, invitedFormName } = props;
|
|
const { invitedFormUsername, invitedFormName } = props;
|
|
|
|
|
|
|
|
|
|
+ const submitHandler = useCallback(async(e) => {
|
|
|
|
|
+ e.preventDefault();
|
|
|
|
|
+
|
|
|
|
|
+ const formData = e.target.elements;
|
|
|
|
|
+
|
|
|
|
|
+ const {
|
|
|
|
|
+ 'invitedForm[name]': { value: name },
|
|
|
|
|
+ 'invitedForm[password]': { value: password },
|
|
|
|
|
+ 'invitedForm[username]': { value: username },
|
|
|
|
|
+ } = formData;
|
|
|
|
|
+
|
|
|
|
|
+ const invitedForm = {
|
|
|
|
|
+ name,
|
|
|
|
|
+ password,
|
|
|
|
|
+ username,
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await apiv3Post('/invited', { invitedForm });
|
|
|
|
|
+ setIsConnectSuccess(true);
|
|
|
|
|
+ const { redirectTo } = res.data;
|
|
|
|
|
+ router.push(redirectTo);
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (err) {
|
|
|
|
|
+ setLoginErrors(err);
|
|
|
|
|
+ }
|
|
|
|
|
+ }, [router]);
|
|
|
|
|
+
|
|
|
|
|
+ const formNotification = useCallback(() => {
|
|
|
|
|
+
|
|
|
|
|
+ if (isConnectSuccess) {
|
|
|
|
|
+ return (
|
|
|
|
|
+ <p className="alert alert-success">
|
|
|
|
|
+ <strong>{ t('message.successfully_connected') }</strong><br></br>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return (
|
|
|
|
|
+ <>
|
|
|
|
|
+ { loginErrors != null && loginErrors.length > 0 ? (
|
|
|
|
|
+ <p className="alert alert-danger">
|
|
|
|
|
+ { loginErrors.map((err, index) => {
|
|
|
|
|
+ return <span key={index}>{ t(err.message) }<br/></span>;
|
|
|
|
|
+ }) }
|
|
|
|
|
+ </p>
|
|
|
|
|
+ ) : (
|
|
|
|
|
+ <p className="alert alert-success">
|
|
|
|
|
+ <strong>{ t('invited.discription_heading') }</strong><br></br>
|
|
|
|
|
+ <small>{ t('invited.discription') }</small>
|
|
|
|
|
+ </p>
|
|
|
|
|
+ ) }
|
|
|
|
|
+ </>
|
|
|
|
|
+ );
|
|
|
|
|
+ }, [isConnectSuccess, loginErrors, t]);
|
|
|
|
|
+
|
|
|
if (user == null) {
|
|
if (user == null) {
|
|
|
return <></>;
|
|
return <></>;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
- <div className="noLogin-dialog p-3 mx-auto" id="noLogin-dialog">
|
|
|
|
|
- <p className="alert alert-success">
|
|
|
|
|
- <strong>{ t('invited.discription_heading') }</strong><br></br>
|
|
|
|
|
- <small>{ t('invited.discription') }</small>
|
|
|
|
|
- </p>
|
|
|
|
|
- <form role="form" action="/invited/activateInvited" method="post" id="invited-form">
|
|
|
|
|
|
|
+ <div className="noLogin-dialog px-3 pb-3 mx-auto" id="noLogin-dialog">
|
|
|
|
|
+ { formNotification() }
|
|
|
|
|
+ <form role="form" onSubmit={submitHandler} id="invited-form">
|
|
|
{/* Email Form */}
|
|
{/* Email Form */}
|
|
|
<div className="input-group">
|
|
<div className="input-group">
|
|
|
<div className="input-group-prepend">
|
|
<div className="input-group-prepend">
|
|
@@ -89,11 +149,11 @@ export const InvitedForm = (props: InvitedFormProps): JSX.Element => {
|
|
|
placeholder={t('Password')}
|
|
placeholder={t('Password')}
|
|
|
name="invitedForm[password]"
|
|
name="invitedForm[password]"
|
|
|
required
|
|
required
|
|
|
|
|
+ minLength={6}
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
{/* Create Button */}
|
|
{/* Create Button */}
|
|
|
- <div className="input-group justify-content-center d-flex mt-5">
|
|
|
|
|
- <input type="hidden" name="_csrf" value={csrfToken} />
|
|
|
|
|
|
|
+ <div className="input-group justify-content-center d-flex mt-4">
|
|
|
<button type="submit" className="btn btn-fill" id="register">
|
|
<button type="submit" className="btn btn-fill" id="register">
|
|
|
<div className="eff"></div>
|
|
<div className="eff"></div>
|
|
|
<span className="btn-label"><i className="icon-user-follow"></i></span>
|
|
<span className="btn-label"><i className="icon-user-follow"></i></span>
|
|
@@ -101,7 +161,7 @@ export const InvitedForm = (props: InvitedFormProps): JSX.Element => {
|
|
|
</button>
|
|
</button>
|
|
|
</div>
|
|
</div>
|
|
|
</form>
|
|
</form>
|
|
|
- <div className="input-group mt-5 d-flex justify-content-center">
|
|
|
|
|
|
|
+ <div className="input-group mt-4 d-flex justify-content-center">
|
|
|
<a href="https://growi.org" className="link-growi-org">
|
|
<a href="https://growi.org" className="link-growi-org">
|
|
|
<span className="growi">GROWI</span>.<span className="org">ORG</span>
|
|
<span className="growi">GROWI</span>.<span className="org">ORG</span>
|
|
|
</a>
|
|
</a>
|