@skroz/frontend 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/Auth.js +19 -36
- package/dist/auth/AuthButtons.d.ts +22 -0
- package/dist/auth/AuthButtons.js +29 -0
- package/dist/auth/AuthFooterLinks.js +9 -25
- package/dist/auth/AuthModal.d.ts +9 -0
- package/dist/auth/AuthModal.js +5 -0
- package/dist/auth/Forgot.js +47 -59
- package/dist/auth/Login.js +33 -48
- package/dist/auth/LoginForm.js +18 -47
- package/dist/auth/LogoutButton.d.ts +3 -0
- package/dist/auth/LogoutButton.js +39 -0
- package/dist/auth/RecoverPassword.js +64 -80
- package/dist/auth/Register.js +47 -55
- package/dist/auth/ResendLinkButton.d.ts +3 -3
- package/dist/auth/ResendLinkButton.js +39 -40
- package/dist/auth/__tests__/Login.test.d.ts +1 -0
- package/dist/auth/__tests__/Login.test.js +75 -0
- package/dist/auth/index.d.ts +3 -0
- package/dist/auth/index.js +11 -22
- package/dist/graphql/ForgotMutation.graphql.d.ts +2 -2
- package/dist/graphql/ForgotMutation.graphql.js +5 -7
- package/dist/graphql/LoginMutation.graphql.d.ts +5 -5
- package/dist/graphql/LoginMutation.graphql.js +6 -8
- package/dist/graphql/LogoutButtonMutation.graphql.d.ts +18 -0
- package/dist/graphql/LogoutButtonMutation.graphql.js +55 -0
- package/dist/graphql/RecoverPasswordMutation.graphql.d.ts +2 -2
- package/dist/graphql/RecoverPasswordMutation.graphql.js +5 -7
- package/dist/graphql/RegisterMutation.graphql.d.ts +7 -6
- package/dist/graphql/RegisterMutation.graphql.js +15 -10
- package/dist/graphql/ResendLinkButtonMutation.graphql.d.ts +2 -2
- package/dist/graphql/ResendLinkButtonMutation.graphql.js +5 -7
- package/dist/index.d.ts +0 -1
- package/dist/index.js +3 -20
- package/dist/ui/AreYouSure.js +9 -23
- package/dist/ui/FormError.js +9 -14
- package/dist/ui/FormItem.js +8 -22
- package/dist/ui/H.d.ts +1 -1
- package/dist/ui/H.js +15 -32
- package/dist/ui/Panel.d.ts +1 -1
- package/dist/ui/Panel.js +6 -23
- package/dist/ui/SeoHead.js +7 -13
- package/dist/ui/index.js +6 -18
- package/dist/utils/FrontendContext.js +6 -25
- package/dist/utils/getError.js +12 -20
- package/dist/utils/handleFormErrors.js +20 -29
- package/dist/utils/index.js +5 -28
- package/dist/utils/isObject.js +2 -6
- package/dist/utils/limitExpiresAt.js +9 -12
- package/package.json +8 -6
- package/src/auth/Auth.tsx +2 -2
- package/src/auth/AuthButtons.tsx +127 -0
- package/src/auth/AuthModal.tsx +28 -0
- package/src/auth/Forgot.tsx +29 -22
- package/src/auth/Login.tsx +25 -10
- package/src/auth/LoginForm.tsx +4 -4
- package/src/auth/LogoutButton.tsx +53 -0
- package/src/auth/RecoverPassword.tsx +34 -24
- package/src/auth/Register.tsx +29 -13
- package/src/auth/ResendLinkButton.tsx +34 -23
- package/src/auth/__tests__/Login.test.tsx +99 -0
- package/src/auth/index.ts +3 -0
- package/src/graphql/ForgotMutation.graphql.ts +77 -77
- package/src/graphql/LoginMutation.graphql.ts +73 -73
- package/src/graphql/LogoutButtonMutation.graphql.ts +74 -0
- package/src/graphql/RecoverPasswordMutation.graphql.ts +70 -74
- package/src/graphql/RegisterMutation.graphql.ts +81 -73
- package/src/graphql/ResendLinkButtonMutation.graphql.ts +77 -77
- package/src/index.ts +0 -1
- package/src/styles/auth.less +22 -7
- package/src/ui/H.tsx +1 -1
- package/src/ui/Panel.tsx +1 -1
- package/src/utils/limitExpiresAt.ts +3 -1
- package/dist/graphql/index.d.ts +0 -5
- package/dist/graphql/index.js +0 -16
- package/src/graphql/index.ts +0 -5
|
@@ -1,30 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.FrontendProvider = exports.useFrontendConfig = void 0;
|
|
15
|
-
var jsx_runtime_1 = require("react/jsx-runtime");
|
|
16
|
-
var react_1 = require("react");
|
|
17
|
-
var defaultConfig = {
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext } from 'react';
|
|
3
|
+
const defaultConfig = {
|
|
18
4
|
loginPath: '/login',
|
|
19
5
|
registerPath: '/register',
|
|
20
6
|
forgotPasswordPath: '/forgot',
|
|
21
7
|
defaultPath: '/',
|
|
22
8
|
};
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
var FrontendProvider = function (_a) {
|
|
27
|
-
var config = _a.config, children = _a.children;
|
|
28
|
-
return ((0, jsx_runtime_1.jsx)(FrontendContext.Provider, __assign({ value: __assign(__assign({}, defaultConfig), config) }, { children: children })));
|
|
29
|
-
};
|
|
30
|
-
exports.FrontendProvider = FrontendProvider;
|
|
9
|
+
const FrontendContext = createContext(defaultConfig);
|
|
10
|
+
export const useFrontendConfig = () => useContext(FrontendContext);
|
|
11
|
+
export const FrontendProvider = ({ config, children }) => (_jsx(FrontendContext.Provider, { value: { ...defaultConfig, ...config }, children: children }));
|
package/dist/utils/getError.js
CHANGED
|
@@ -1,21 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return isObject(constraint) &&
|
|
12
|
-
'code' in constraint &&
|
|
13
|
-
typeof constraint.code === 'string' &&
|
|
14
|
-
'message' in constraint &&
|
|
15
|
-
typeof constraint.message === 'string';
|
|
16
|
-
});
|
|
17
|
-
};
|
|
18
|
-
var getError = function (error) {
|
|
1
|
+
const DEFAULT_CODE = 'no_code';
|
|
2
|
+
const DEFAULT_MESSAGE = 'Error';
|
|
3
|
+
const isObject = (value) => typeof value === 'object' && !Array.isArray(value) && value !== null;
|
|
4
|
+
const isData = (value) => isObject(value) &&
|
|
5
|
+
Object.values(value).every((constraint) => isObject(constraint) &&
|
|
6
|
+
'code' in constraint &&
|
|
7
|
+
typeof constraint.code === 'string' &&
|
|
8
|
+
'message' in constraint &&
|
|
9
|
+
typeof constraint.message === 'string');
|
|
10
|
+
const getError = (error) => {
|
|
19
11
|
// Trying to find the message of an error
|
|
20
12
|
if (!isObject(error) ||
|
|
21
13
|
!('message' in error) ||
|
|
@@ -36,7 +28,7 @@ var getError = function (error) {
|
|
|
36
28
|
message: error.message,
|
|
37
29
|
};
|
|
38
30
|
}
|
|
39
|
-
|
|
31
|
+
const firstError = error.source.errors[0];
|
|
40
32
|
// Trying to find the message of the GraphQL error
|
|
41
33
|
if (!isObject(firstError) ||
|
|
42
34
|
!('message' in firstError) ||
|
|
@@ -70,4 +62,4 @@ var getError = function (error) {
|
|
|
70
62
|
data: firstError.extensions.data,
|
|
71
63
|
};
|
|
72
64
|
};
|
|
73
|
-
|
|
65
|
+
export default getError;
|
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.formatArgumentValidationError = void 0;
|
|
7
|
-
var getError_1 = __importDefault(require("./getError"));
|
|
8
|
-
var isObject_1 = __importDefault(require("./isObject"));
|
|
1
|
+
import getError from './getError';
|
|
2
|
+
import isObject from './isObject';
|
|
9
3
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
const handleFormErrors = (form, error) => {
|
|
5
|
+
const { message, data } = getError(error);
|
|
12
6
|
if (data) {
|
|
13
|
-
Object.entries(data).forEach(
|
|
14
|
-
var key = _a[0], constraint = _a[1];
|
|
7
|
+
Object.entries(data).forEach(([key, constraint]) => {
|
|
15
8
|
form.errors.set(key, constraint.message);
|
|
16
9
|
});
|
|
17
10
|
}
|
|
@@ -22,41 +15,39 @@ var handleFormErrors = function (form, error) {
|
|
|
22
15
|
/**
|
|
23
16
|
* Formats the argument validation error to the field/message map.
|
|
24
17
|
*/
|
|
25
|
-
|
|
26
|
-
if (messages === void 0) { messages = {}; }
|
|
18
|
+
export const formatArgumentValidationError = (error, messages = {}) => {
|
|
27
19
|
// Check if validationErrors is exists
|
|
28
20
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
29
|
-
|
|
30
|
-
if (!(
|
|
21
|
+
const e = error;
|
|
22
|
+
if (!isObject(e.source) ||
|
|
31
23
|
!Array.isArray(e.source.errors) ||
|
|
32
24
|
e.source.errors.length === 0 ||
|
|
33
|
-
!(
|
|
25
|
+
!isObject(e.source.errors[0]) ||
|
|
34
26
|
e.source.errors[0].message !== 'Argument Validation Error' ||
|
|
35
|
-
!(
|
|
36
|
-
!(
|
|
27
|
+
!isObject(e.source.errors[0].extensions) ||
|
|
28
|
+
!isObject(e.source.errors[0].extensions.exception) ||
|
|
37
29
|
!Array.isArray(e.source.errors[0].extensions.exception.validationErrors))
|
|
38
30
|
return {};
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
validationErrors.forEach(
|
|
31
|
+
const { validationErrors } = e.source.errors[0].extensions.exception;
|
|
32
|
+
const errors = {};
|
|
33
|
+
validationErrors.forEach((validationError) => {
|
|
42
34
|
// Check if validationError has property and constraints
|
|
43
|
-
if (!(
|
|
35
|
+
if (!isObject(validationError) ||
|
|
44
36
|
typeof validationError.property !== 'string' ||
|
|
45
|
-
!(
|
|
37
|
+
!isObject(validationError.constraints))
|
|
46
38
|
return;
|
|
47
39
|
// Check if constraints has key/value
|
|
48
|
-
|
|
40
|
+
const constraints = Object.entries(validationError.constraints);
|
|
49
41
|
if (constraints.length === 0)
|
|
50
42
|
return;
|
|
51
|
-
|
|
43
|
+
const [key, message] = constraints[0];
|
|
52
44
|
if (typeof message !== 'string')
|
|
53
45
|
return;
|
|
54
|
-
|
|
46
|
+
const customMessage = messages[validationError.property]
|
|
55
47
|
? messages[validationError.property][key]
|
|
56
48
|
: undefined;
|
|
57
49
|
errors[validationError.property] = customMessage || message;
|
|
58
50
|
});
|
|
59
51
|
return errors;
|
|
60
52
|
};
|
|
61
|
-
|
|
62
|
-
exports.default = handleFormErrors;
|
|
53
|
+
export default handleFormErrors;
|
package/dist/utils/index.js
CHANGED
|
@@ -1,28 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
-
};
|
|
19
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.isObject = exports.handleFormErrors = exports.getError = void 0;
|
|
21
|
-
var getError_1 = require("./getError");
|
|
22
|
-
Object.defineProperty(exports, "getError", { enumerable: true, get: function () { return __importDefault(getError_1).default; } });
|
|
23
|
-
var handleFormErrors_1 = require("./handleFormErrors");
|
|
24
|
-
Object.defineProperty(exports, "handleFormErrors", { enumerable: true, get: function () { return __importDefault(handleFormErrors_1).default; } });
|
|
25
|
-
var isObject_1 = require("./isObject");
|
|
26
|
-
Object.defineProperty(exports, "isObject", { enumerable: true, get: function () { return __importDefault(isObject_1).default; } });
|
|
27
|
-
__exportStar(require("./limitExpiresAt"), exports);
|
|
28
|
-
__exportStar(require("./FrontendContext"), exports);
|
|
1
|
+
export { default as getError } from './getError';
|
|
2
|
+
export { default as handleFormErrors } from './handleFormErrors';
|
|
3
|
+
export { default as isObject } from './isObject';
|
|
4
|
+
export * from './limitExpiresAt';
|
|
5
|
+
export * from './FrontendContext';
|
package/dist/utils/isObject.js
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var isObject = function (value) {
|
|
4
|
-
return typeof value === 'object' && value !== null;
|
|
5
|
-
};
|
|
6
|
-
exports.default = isObject;
|
|
1
|
+
const isObject = (value) => typeof value === 'object' && value !== null;
|
|
2
|
+
export default isObject;
|
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.getLimitExpiresIn = exports.getLimitExpiresAt = exports.setLimitExpiresAt = void 0;
|
|
4
|
-
var LIMIT_EXPIRES_AT_KEY = 'lea';
|
|
5
|
-
var setLimitExpiresAt = function (value) {
|
|
1
|
+
const LIMIT_EXPIRES_AT_KEY = 'lea';
|
|
2
|
+
export const setLimitExpiresAt = (value) => {
|
|
6
3
|
if (typeof window === 'undefined')
|
|
7
4
|
return;
|
|
8
|
-
|
|
5
|
+
console.log('--- setLimitExpiresAt call:', { value });
|
|
6
|
+
if (value === undefined || value === null)
|
|
7
|
+
return;
|
|
8
|
+
window.sessionStorage.setItem(LIMIT_EXPIRES_AT_KEY, String(value));
|
|
9
9
|
};
|
|
10
|
-
|
|
11
|
-
var getLimitExpiresAt = function () {
|
|
10
|
+
export const getLimitExpiresAt = () => {
|
|
12
11
|
if (typeof window === 'undefined')
|
|
13
12
|
return 0;
|
|
14
|
-
|
|
13
|
+
const value = window.sessionStorage.getItem(LIMIT_EXPIRES_AT_KEY);
|
|
15
14
|
return Number(value) || 0;
|
|
16
15
|
};
|
|
17
|
-
|
|
18
|
-
var getLimitExpiresIn = function () { return (0, exports.getLimitExpiresAt)() - Date.now(); };
|
|
19
|
-
exports.getLimitExpiresIn = getLimitExpiresIn;
|
|
16
|
+
export const getLimitExpiresIn = () => getLimitExpiresAt() - Date.now();
|
package/package.json
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skroz/frontend",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"main": "
|
|
6
|
-
"types": "
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
7
|
"files": [
|
|
8
8
|
"dist",
|
|
9
9
|
"src"
|
|
10
10
|
],
|
|
11
11
|
"scripts": {
|
|
12
|
-
"clean": "
|
|
12
|
+
"clean": "rm -rf dist",
|
|
13
13
|
"build": "yarn clean && tsc",
|
|
14
|
+
"relay": "node scripts/regenerate-relay.js",
|
|
15
|
+
"gen-schema": "npx get-graphql-schema http://localhost:4000/graphql > schema.graphql",
|
|
14
16
|
"lint": "eslint --fix ."
|
|
15
17
|
},
|
|
16
18
|
"peerDependencies": {
|
|
@@ -39,10 +41,10 @@
|
|
|
39
41
|
"react-dom": "18.3.1",
|
|
40
42
|
"react-relay": "17.0.0",
|
|
41
43
|
"rimraf": "4.4.1",
|
|
42
|
-
"typescript": "
|
|
44
|
+
"typescript": "latest"
|
|
43
45
|
},
|
|
44
46
|
"publishConfig": {
|
|
45
47
|
"access": "public"
|
|
46
48
|
},
|
|
47
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "e7ce7163def41ef1fee71f0d0a1bec12661e100a"
|
|
48
50
|
}
|
package/src/auth/Auth.tsx
CHANGED
|
@@ -6,7 +6,7 @@ import { useTranslation } from 'next-i18next';
|
|
|
6
6
|
import Login from './Login';
|
|
7
7
|
import Register from './Register';
|
|
8
8
|
import Forgot from './Forgot';
|
|
9
|
-
import {
|
|
9
|
+
import { AuthInput } from "../graphql/RegisterMutation.graphql";
|
|
10
10
|
|
|
11
11
|
interface AuthProps {
|
|
12
12
|
authType: 'login' | 'register' | 'forgot';
|
|
@@ -22,7 +22,7 @@ const Auth: React.FC<AuthProps> = ({ authType, setAuthType, onFinish }) => {
|
|
|
22
22
|
let initialEmail = router.query.email;
|
|
23
23
|
if (typeof initialEmail !== 'string') initialEmail = '';
|
|
24
24
|
|
|
25
|
-
const { form } = useForm<
|
|
25
|
+
const { form } = useForm<AuthInput>({
|
|
26
26
|
email: initialEmail || '',
|
|
27
27
|
password: '',
|
|
28
28
|
isPrivacyPolicyAgree: false,
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { Button } from 'antd';
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
|
+
import { useTranslation } from 'next-i18next';
|
|
4
|
+
import { ButtonType } from 'antd/es/button/buttonHelpers';
|
|
5
|
+
import { SizeType } from 'antd/es/config-provider/SizeContext';
|
|
6
|
+
import Link from 'next/link';
|
|
7
|
+
import AuthModal from './AuthModal';
|
|
8
|
+
import { useFrontendConfig } from '../utils/FrontendContext';
|
|
9
|
+
|
|
10
|
+
interface AuthButtonsProps {
|
|
11
|
+
modal: boolean;
|
|
12
|
+
showLogin: boolean;
|
|
13
|
+
loginTitle?: React.ReactNode;
|
|
14
|
+
loginIcon?: React.ReactNode;
|
|
15
|
+
loginClassName?: string;
|
|
16
|
+
registerTitle?: React.ReactNode;
|
|
17
|
+
loginButtonType: ButtonType;
|
|
18
|
+
registerButtonType?: ButtonType;
|
|
19
|
+
showRegister: boolean;
|
|
20
|
+
fantastic?: boolean;
|
|
21
|
+
registerClassName?: string;
|
|
22
|
+
registerBlock?: boolean;
|
|
23
|
+
buttonSize?: SizeType;
|
|
24
|
+
className?: string;
|
|
25
|
+
reversed?: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const AuthButtons: React.FC<AuthButtonsProps> = ({
|
|
29
|
+
modal,
|
|
30
|
+
loginButtonType,
|
|
31
|
+
registerButtonType = 'primary',
|
|
32
|
+
showLogin,
|
|
33
|
+
loginIcon,
|
|
34
|
+
loginClassName,
|
|
35
|
+
showRegister,
|
|
36
|
+
fantastic,
|
|
37
|
+
loginTitle,
|
|
38
|
+
registerTitle,
|
|
39
|
+
registerClassName = '',
|
|
40
|
+
buttonSize = 'middle',
|
|
41
|
+
registerBlock,
|
|
42
|
+
className = '',
|
|
43
|
+
reversed = false,
|
|
44
|
+
}) => {
|
|
45
|
+
const { t } = useTranslation('common');
|
|
46
|
+
const config = useFrontendConfig();
|
|
47
|
+
const [visible, setVisible] = useState(false);
|
|
48
|
+
const [authType, setAuthType] = useState<'login' | 'register' | 'forgot'>(
|
|
49
|
+
'login'
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
const loginButton = (
|
|
53
|
+
<div className={`auth-buttons-item ${loginClassName || ''}`}>
|
|
54
|
+
<Button
|
|
55
|
+
type={loginButtonType}
|
|
56
|
+
shape={loginTitle !== false ? 'round' : 'circle'}
|
|
57
|
+
size={buttonSize}
|
|
58
|
+
icon={loginIcon}
|
|
59
|
+
onClick={
|
|
60
|
+
modal
|
|
61
|
+
? () => {
|
|
62
|
+
setVisible(true);
|
|
63
|
+
setAuthType('login');
|
|
64
|
+
}
|
|
65
|
+
: undefined
|
|
66
|
+
}
|
|
67
|
+
>
|
|
68
|
+
{loginTitle !== false ? loginTitle || t('buttons.login') : ''}
|
|
69
|
+
</Button>
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const loginButtonContainer = modal ? (
|
|
74
|
+
loginButton
|
|
75
|
+
) : (
|
|
76
|
+
<Link href={config.loginPath || '/login'} passHref legacyBehavior>
|
|
77
|
+
{loginButton}
|
|
78
|
+
</Link>
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const registerButton = (
|
|
82
|
+
<div className="auth-buttons-item">
|
|
83
|
+
<Button
|
|
84
|
+
shape="round"
|
|
85
|
+
className={registerClassName}
|
|
86
|
+
size={buttonSize}
|
|
87
|
+
type={registerButtonType}
|
|
88
|
+
block={registerBlock}
|
|
89
|
+
onClick={
|
|
90
|
+
modal
|
|
91
|
+
? () => {
|
|
92
|
+
setVisible(true);
|
|
93
|
+
setAuthType('register');
|
|
94
|
+
}
|
|
95
|
+
: undefined
|
|
96
|
+
}
|
|
97
|
+
>
|
|
98
|
+
{registerTitle || t('buttons.register')}
|
|
99
|
+
</Button>
|
|
100
|
+
</div>
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
const registerButtonContainer = modal ? (
|
|
104
|
+
registerButton
|
|
105
|
+
) : (
|
|
106
|
+
<Link href={config.registerPath || '/register'} passHref legacyBehavior>
|
|
107
|
+
{registerButton}
|
|
108
|
+
</Link>
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<div className={`auth-buttons ${fantastic ? 'fantastic' : ''} ${reversed ? 'is-reversed' : ''} ${className}`}>
|
|
113
|
+
{showLogin && loginButtonContainer}
|
|
114
|
+
{showRegister && registerButtonContainer}
|
|
115
|
+
{modal && (
|
|
116
|
+
<AuthModal
|
|
117
|
+
authType={authType}
|
|
118
|
+
visible={visible}
|
|
119
|
+
onClose={() => setVisible(false)}
|
|
120
|
+
setAuthType={setAuthType}
|
|
121
|
+
/>
|
|
122
|
+
)}
|
|
123
|
+
</div>
|
|
124
|
+
);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export default AuthButtons;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Modal } from 'antd';
|
|
3
|
+
import Auth from './Auth';
|
|
4
|
+
|
|
5
|
+
interface AuthModalProps {
|
|
6
|
+
visible: boolean;
|
|
7
|
+
authType: 'login' | 'register' | 'forgot';
|
|
8
|
+
setAuthType: (type: 'login' | 'register' | 'forgot') => void;
|
|
9
|
+
onClose: () => void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const AuthModal: React.FC<AuthModalProps> = ({
|
|
13
|
+
visible,
|
|
14
|
+
authType,
|
|
15
|
+
onClose,
|
|
16
|
+
setAuthType,
|
|
17
|
+
}) => (
|
|
18
|
+
<Modal
|
|
19
|
+
open={visible}
|
|
20
|
+
onCancel={onClose}
|
|
21
|
+
footer={false}
|
|
22
|
+
style={{ top: 10 }}
|
|
23
|
+
>
|
|
24
|
+
<Auth authType={authType} setAuthType={setAuthType} onFinish={onClose} />
|
|
25
|
+
</Modal>
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
export default AuthModal;
|
package/src/auth/Forgot.tsx
CHANGED
|
@@ -5,13 +5,13 @@ import { UserOutlined } from '@ant-design/icons';
|
|
|
5
5
|
import { useTranslation } from 'next-i18next';
|
|
6
6
|
import Link from 'next/link';
|
|
7
7
|
import { useExistingForm } from '@os-design/form';
|
|
8
|
-
import {
|
|
8
|
+
import { useMutation } from 'react-relay';
|
|
9
9
|
import { setLimitExpiresAt } from '../utils/limitExpiresAt';
|
|
10
10
|
import handleFormErrors from '../utils/handleFormErrors';
|
|
11
11
|
import H from '../ui/H';
|
|
12
12
|
import { useFrontendConfig } from '../utils/FrontendContext';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
13
|
+
import { AuthInput } from '../graphql/RegisterMutation.graphql';
|
|
14
|
+
import ForgotMutationNode, {
|
|
15
15
|
ForgotMutation,
|
|
16
16
|
} from '../graphql/ForgotMutation.graphql';
|
|
17
17
|
import FormItem from '../ui/FormItem';
|
|
@@ -22,21 +22,30 @@ interface ForgotProps {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
const Forgot: React.FC<ForgotProps> = ({ onFinish, onLoginClick }) => {
|
|
25
|
-
const { t } = useTranslation();
|
|
25
|
+
const { t } = useTranslation('common');
|
|
26
26
|
const router = useRouter();
|
|
27
27
|
const config = useFrontendConfig();
|
|
28
28
|
|
|
29
|
-
const { form, useValue, Field } = useExistingForm<
|
|
29
|
+
const { form, useValue, Field } = useExistingForm<AuthInput>();
|
|
30
30
|
const email = useValue('email');
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
/*
|
|
33
|
+
SKROZ_PROTECTION NOTE:
|
|
34
|
+
The Relay compiler has generated artifacts for this mutation.
|
|
35
|
+
Explicit import of ForgotMutationNode is used.
|
|
36
|
+
|
|
37
|
+
Mutation definition (for reference/regeneration):
|
|
38
|
+
graphql`
|
|
39
|
+
mutation ForgotMutation($input: SendTokenInput!) {
|
|
40
|
+
sendToken(input: $input) {
|
|
41
|
+
codeIsSent
|
|
42
|
+
limitExpiresAt
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
`
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
const [commit, loading] = useMutation<ForgotMutation>(ForgotMutationNode);
|
|
40
49
|
|
|
41
50
|
const forgotPasswordHandler = useCallback(() => {
|
|
42
51
|
commit({
|
|
@@ -47,9 +56,9 @@ const Forgot: React.FC<ForgotProps> = ({ onFinish, onLoginClick }) => {
|
|
|
47
56
|
},
|
|
48
57
|
onError: (error) => handleFormErrors(form, error),
|
|
49
58
|
onCompleted: (res: any) => {
|
|
50
|
-
setLimitExpiresAt(res.sendToken.limitExpiresAt
|
|
59
|
+
setLimitExpiresAt(res.sendToken.limitExpiresAt);
|
|
51
60
|
if (!res.sendToken.codeIsSent)
|
|
52
|
-
message.error(t('
|
|
61
|
+
message.error(t('auth.forgotSendError'));
|
|
53
62
|
router.push(`/recovery?email=${email}`);
|
|
54
63
|
onFinish();
|
|
55
64
|
},
|
|
@@ -58,17 +67,17 @@ const Forgot: React.FC<ForgotProps> = ({ onFinish, onLoginClick }) => {
|
|
|
58
67
|
|
|
59
68
|
const loginButton = (
|
|
60
69
|
<Button type='link' onClick={onLoginClick} shape='round'>
|
|
61
|
-
{t('
|
|
70
|
+
{t('buttons.login')}
|
|
62
71
|
</Button>
|
|
63
72
|
);
|
|
64
73
|
|
|
65
74
|
return (
|
|
66
75
|
<div className='auth no-text-selection'>
|
|
67
76
|
<H type='h1' textAlign='center'>
|
|
68
|
-
{t('
|
|
77
|
+
{t('auth.forgotTitle')}
|
|
69
78
|
</H>
|
|
70
79
|
<div className='auth-subtitle'>
|
|
71
|
-
{t('
|
|
80
|
+
{t('auth.forgotSubtitle')}{' '}
|
|
72
81
|
{onLoginClick ? (
|
|
73
82
|
loginButton
|
|
74
83
|
) : (
|
|
@@ -111,14 +120,12 @@ const Forgot: React.FC<ForgotProps> = ({ onFinish, onLoginClick }) => {
|
|
|
111
120
|
loading={loading}
|
|
112
121
|
onClick={forgotPasswordHandler}
|
|
113
122
|
>
|
|
114
|
-
{t('
|
|
123
|
+
{t('auth.forgotSendInstructions')}
|
|
115
124
|
</Button>
|
|
116
125
|
</div>
|
|
117
126
|
|
|
118
127
|
<div className='auth-footer'>
|
|
119
|
-
<div className='auth-footer-issues'>
|
|
120
|
-
{t('common:auth.forgotIssues')}
|
|
121
|
-
</div>
|
|
128
|
+
<div className='auth-footer-issues'>{t('auth.forgotIssues')}</div>
|
|
122
129
|
</div>
|
|
123
130
|
</div>
|
|
124
131
|
);
|
package/src/auth/Login.tsx
CHANGED
|
@@ -6,9 +6,9 @@ import Link from 'next/link';
|
|
|
6
6
|
import { useMutation } from 'react-relay';
|
|
7
7
|
import { useExistingForm } from '@os-design/form';
|
|
8
8
|
import LoginMutationNode, {
|
|
9
|
-
RegisterInput,
|
|
10
9
|
LoginMutation,
|
|
11
10
|
LoginMutation$data,
|
|
11
|
+
AuthInput,
|
|
12
12
|
} from '../graphql/LoginMutation.graphql';
|
|
13
13
|
import handleFormErrors from '../utils/handleFormErrors';
|
|
14
14
|
import AuthFooterLinks from './AuthFooterLinks';
|
|
@@ -16,6 +16,21 @@ import H from '../ui/H';
|
|
|
16
16
|
import { useFrontendConfig } from '../utils/FrontendContext';
|
|
17
17
|
import LoginForm from './LoginForm';
|
|
18
18
|
|
|
19
|
+
/*
|
|
20
|
+
SKROZ_PROTECTION NOTE:
|
|
21
|
+
The Relay compiler has generated artifacts for this mutation.
|
|
22
|
+
Explicit import of LoginMutationNode is used.
|
|
23
|
+
|
|
24
|
+
Mutation definition (for reference/regeneration):
|
|
25
|
+
graphql`
|
|
26
|
+
mutation LoginMutation($input: AuthInput!) {
|
|
27
|
+
login(input: $input) {
|
|
28
|
+
ok
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
`
|
|
32
|
+
*/
|
|
33
|
+
|
|
19
34
|
interface LoginProps {
|
|
20
35
|
onFinish: () => void;
|
|
21
36
|
isModal: boolean;
|
|
@@ -23,9 +38,9 @@ interface LoginProps {
|
|
|
23
38
|
}
|
|
24
39
|
|
|
25
40
|
const Login: React.FC<LoginProps> = ({ onFinish, onForgotClick, isModal }) => {
|
|
26
|
-
const { t } = useTranslation();
|
|
41
|
+
const { t } = useTranslation('common');
|
|
27
42
|
const router = useRouter();
|
|
28
|
-
const { form } = useExistingForm<
|
|
43
|
+
const { form } = useExistingForm<AuthInput>();
|
|
29
44
|
const config = useFrontendConfig();
|
|
30
45
|
|
|
31
46
|
const [commit, loading] = useMutation<LoginMutation>(LoginMutationNode);
|
|
@@ -42,11 +57,11 @@ const Login: React.FC<LoginProps> = ({ onFinish, onForgotClick, isModal }) => {
|
|
|
42
57
|
},
|
|
43
58
|
onCompleted: (res: LoginMutation$data) => {
|
|
44
59
|
if (!res.login.ok) {
|
|
45
|
-
message.error(t('
|
|
60
|
+
message.error(t('auth.loginError'));
|
|
46
61
|
return;
|
|
47
62
|
}
|
|
48
63
|
onFinish();
|
|
49
|
-
message.success(t('
|
|
64
|
+
message.success(t('auth.loginSuccess'));
|
|
50
65
|
router.reload();
|
|
51
66
|
},
|
|
52
67
|
});
|
|
@@ -54,23 +69,23 @@ const Login: React.FC<LoginProps> = ({ onFinish, onForgotClick, isModal }) => {
|
|
|
54
69
|
|
|
55
70
|
const forgotButton = (
|
|
56
71
|
<Button type='link' onClick={onForgotClick}>
|
|
57
|
-
{t('
|
|
72
|
+
{t('auth.forgot')}
|
|
58
73
|
</Button>
|
|
59
74
|
);
|
|
60
75
|
const registerButton = (
|
|
61
76
|
<Button type='link' shape='round' className='register-link'>
|
|
62
|
-
{t('
|
|
77
|
+
{t('buttons.register')}
|
|
63
78
|
</Button>
|
|
64
79
|
);
|
|
65
80
|
|
|
66
81
|
return (
|
|
67
82
|
<div className='auth no-text-selection'>
|
|
68
83
|
<H type='h1' textAlign='center'>
|
|
69
|
-
{t('
|
|
84
|
+
{t('auth.loginTitle')}
|
|
70
85
|
</H>
|
|
71
86
|
{!isModal && (
|
|
72
87
|
<div className='auth-subtitle'>
|
|
73
|
-
{t('
|
|
88
|
+
{t('auth.loginSubtitle')}{' '}
|
|
74
89
|
<Link href={config.registerPath || '/register'} passHref>
|
|
75
90
|
{registerButton}
|
|
76
91
|
</Link>
|
|
@@ -85,7 +100,7 @@ const Login: React.FC<LoginProps> = ({ onFinish, onForgotClick, isModal }) => {
|
|
|
85
100
|
loading={loading}
|
|
86
101
|
onClick={loginHandler}
|
|
87
102
|
>
|
|
88
|
-
{t('
|
|
103
|
+
{t('buttons.login')}
|
|
89
104
|
</Button>
|
|
90
105
|
</div>
|
|
91
106
|
<div className='auth-footer'>
|