@@ -1,58 +1,27 @@
|
|||||||
import React, {useCallback, useEffect, useRef, useState} from "react";
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import {Button, Card, Checkbox, Col, Form, Input, Modal, Row, Space} from "antd";
|
import {Button, Card, Checkbox, Col, Form, Input, Modal, notification, Row, Space} from "antd";
|
||||||
import Markdown from "react-markdown";
|
import Markdown from "react-markdown";
|
||||||
import {createStructuredSelector} from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import {selectCurrentEula, selectCurrentUser} from "../../redux/user/user.selectors";
|
import { selectCurrentEula, selectCurrentUser } from "../../redux/user/user.selectors";
|
||||||
import {connect} from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import {FormDatePicker} from "../form-date-picker/form-date-picker.component";
|
import { FormDatePicker } from "../form-date-picker/form-date-picker.component";
|
||||||
import {INSERT_EULA_ACCEPTANCE} from "../../graphql/user.queries";
|
import { INSERT_EULA_ACCEPTANCE } from "../../graphql/user.queries";
|
||||||
import {useMutation} from "@apollo/client";
|
import { useMutation } from "@apollo/client";
|
||||||
import {acceptEula} from "../../redux/user/user.actions";
|
import { acceptEula } from "../../redux/user/user.actions";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import day from '../../utils/day';
|
||||||
|
|
||||||
|
import './eula.styles.scss';
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const Eula = ({ currentEula, currentUser, acceptEula }) => {
|
||||||
currentEula: selectCurrentEula,
|
const [formReady, setFormReady] = useState(false);
|
||||||
currentUser: selectCurrentUser,
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
|
||||||
acceptEula: () => dispatch(acceptEula()),
|
|
||||||
});
|
|
||||||
|
|
||||||
export function Eula({currentEula, currentUser, acceptEula}) {
|
|
||||||
const [formReady, setFormReady] = useState(false); // [formReady, setFormReady
|
|
||||||
const [hasEverScrolledToBottom, setHasEverScrolledToBottom] = useState(false);
|
const [hasEverScrolledToBottom, setHasEverScrolledToBottom] = useState(false);
|
||||||
const [insertEulaAcceptance] = useMutation(INSERT_EULA_ACCEPTANCE);
|
const [insertEulaAcceptance] = useMutation(INSERT_EULA_ACCEPTANCE);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const markdownDivRef = useRef(null);
|
const markdownCardRef = useRef(null);
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const [api, contextHolder] = notification.useNotification();
|
||||||
|
|
||||||
const handleAccept = async ({acceptTerms, ...formValues}) => {
|
|
||||||
|
|
||||||
const eulaId = currentEula.id;
|
|
||||||
const useremail = currentUser.email;
|
|
||||||
|
|
||||||
try {
|
|
||||||
await insertEulaAcceptance({
|
|
||||||
variables: {
|
|
||||||
eulaAcceptance: {
|
|
||||||
eulaid: eulaId,
|
|
||||||
useremail,
|
|
||||||
...formValues,
|
|
||||||
date_accepted: new Date(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
acceptEula();
|
|
||||||
} catch (err) {
|
|
||||||
// Pop notification with error, pop console
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
//R
|
|
||||||
// setIsModalOpen(false);
|
|
||||||
//Insert and Dispatch the action to recheck force acceptance.
|
|
||||||
};
|
|
||||||
const handleScroll = (e) => {
|
const handleScroll = (e) => {
|
||||||
const bottom = e.target.scrollHeight - 100 <= e.target.scrollTop + e.target.clientHeight;
|
const bottom = e.target.scrollHeight - 100 <= e.target.scrollTop + e.target.clientHeight;
|
||||||
if (bottom && !hasEverScrolledToBottom) {
|
if (bottom && !hasEverScrolledToBottom) {
|
||||||
@@ -61,135 +30,197 @@ export function Eula({currentEula, currentUser, acceptEula}) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleChange = useCallback(() => {
|
const handleChange = useCallback(() => {
|
||||||
form.validateFields({
|
form.validateFields({ validateOnly: true })
|
||||||
validateOnly: true,
|
.then(() => setFormReady(hasEverScrolledToBottom))
|
||||||
}).then(() => {
|
.catch(() => setFormReady(false));
|
||||||
setFormReady(hasEverScrolledToBottom);
|
|
||||||
}).catch(() => {
|
|
||||||
setFormReady(false);
|
|
||||||
});
|
|
||||||
}, [form, hasEverScrolledToBottom]);
|
}, [form, hasEverScrolledToBottom]);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
handleChange();
|
handleChange();
|
||||||
}, [handleChange, hasEverScrolledToBottom, form]);
|
}, [handleChange, hasEverScrolledToBottom, form]);
|
||||||
|
|
||||||
|
const onFinish = async ({ acceptTerms, ...formValues }) => {
|
||||||
|
const eulaId = currentEula.id;
|
||||||
|
const useremail = currentUser.email;
|
||||||
|
|
||||||
return <Modal
|
try {
|
||||||
title="Terms and Conditions"
|
const { accepted_terms, ...otherFormValues } = formValues;
|
||||||
style={{top: 20}}
|
await insertEulaAcceptance({
|
||||||
width={'100vh'}
|
variables: {
|
||||||
open={currentEula}
|
eulaAcceptance: {
|
||||||
footer={() => (
|
eulaid: eulaId,
|
||||||
<Button style={{width: '100%'}} form='tosForm' type="primary" size='large' htmlType="submit"
|
useremail,
|
||||||
disabled={!formReady}>Accept</Button>
|
...otherFormValues,
|
||||||
)}
|
date_accepted: new Date(),
|
||||||
closable={false}
|
}
|
||||||
>
|
}
|
||||||
<Space direction='vertical'>
|
});
|
||||||
<Card type='inner' style={{
|
acceptEula();
|
||||||
maxHeight: '50vh',
|
} catch (err) {
|
||||||
overflowY: 'auto',
|
api.error({
|
||||||
backgroundColor: 'lightgray',
|
message: t('eula.errors.acceptance.message'),
|
||||||
}} onScroll={handleScroll} ref={markdownDivRef}>
|
description: t('eula.errors.acceptance.description'),
|
||||||
<div id='markdowndiv' style={{
|
placement: 'bottomRight',
|
||||||
padding: '0 10px 0 10px'
|
duration: 5000,
|
||||||
}}>
|
|
||||||
<Markdown children={currentEula?.content?.replace(/\\n/g, '\n')}/>
|
});
|
||||||
</div>
|
console.log(`${t('eula.errors.acceptance.message')}`);
|
||||||
</Card>
|
console.dir({
|
||||||
<Card type='inner' title='Acknowledgement'>
|
message: err.message,
|
||||||
<Form id='tosForm' onChange={handleChange} onFinish={handleAccept} form={form}>
|
stack: err.stack,
|
||||||
<Row gutter={24}>
|
});
|
||||||
<Col span={12}>
|
}
|
||||||
<Form.Item
|
};
|
||||||
label="First Name"
|
|
||||||
name="first_name"
|
return (
|
||||||
rules={[{required: true, message: 'Please input your first name!'}]}
|
<>
|
||||||
>
|
{contextHolder}
|
||||||
<Input placeholder="First Name" aria-label="First Name"/>
|
<Modal
|
||||||
</Form.Item>
|
title={t('eula.titles.modal')}
|
||||||
</Col>
|
className='eula-modal'
|
||||||
<Col span={12}>
|
width={'100vh'}
|
||||||
<Form.Item
|
open={currentEula}
|
||||||
label="Last Name"
|
footer={() => (
|
||||||
name="last_name"
|
<Button
|
||||||
rules={[{required: true, message: 'Please input your last name!'}]}
|
className='eula-accept-button'
|
||||||
>
|
form='tosForm'
|
||||||
<Input placeholder="Last Name" aria-label="Last Name"/>
|
type="primary"
|
||||||
</Form.Item>
|
size='large'
|
||||||
</Col>
|
htmlType="submit"
|
||||||
</Row>
|
disabled={!formReady}
|
||||||
<Row gutter={24}>
|
children={t('eula.buttons.accept')}
|
||||||
<Col span={12}>
|
/>
|
||||||
<Form.Item
|
)}
|
||||||
label="Legal Business Name"
|
closable={false}
|
||||||
name="business_name"
|
>
|
||||||
rules={[{required: true, message: 'Please input your legal business name!'}]}
|
<Space direction='vertical'>
|
||||||
>
|
<Card type='inner' className='eula-markdown-card' onScroll={handleScroll} ref={markdownCardRef}>
|
||||||
<Input placeholder="Legal Business Name" aria-label="Legal Business Name"/>
|
<div id='markdowndiv' className='eula-markdown-div'>
|
||||||
</Form.Item>
|
<Markdown children={currentEula?.content?.replace(/\\n/g, '\n')} />
|
||||||
</Col>
|
</div>
|
||||||
<Col span={12}>
|
</Card>
|
||||||
<Form.Item
|
<EulaFormComponent form={form} handleChange={handleChange} onFinish={onFinish} t={t} />
|
||||||
label="Phone"
|
{!hasEverScrolledToBottom && (
|
||||||
name="phone_number"
|
<Card className='eula-never-scrolled' type='inner'>
|
||||||
rules={[
|
<h3>{t('eula.content.never_scrolled')}</h3>
|
||||||
{
|
</Card>
|
||||||
pattern: /^(\+\d{1,2}\s?)?1?-?\.?\s?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/,
|
)}
|
||||||
message: 'Please enter a valid phone number!'
|
</Space>
|
||||||
}
|
</Modal>
|
||||||
]}
|
</>
|
||||||
>
|
)
|
||||||
<Input placeholder="Phone" aria-label="Phone"/>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
<Row gutter={24}>
|
|
||||||
<Col span={12}>
|
|
||||||
<Form.Item
|
|
||||||
label="Address"
|
|
||||||
name="address"
|
|
||||||
>
|
|
||||||
<Input placeholder="Address" aria-label="Address"/>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
<Col span={12}>
|
|
||||||
<Form.Item
|
|
||||||
label="Date"
|
|
||||||
name="date_accepted"
|
|
||||||
rules={[{required: true},]}
|
|
||||||
>
|
|
||||||
<FormDatePicker onChange={handleChange} onlyFuture/>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
<Row gutter={24}>
|
|
||||||
<Col span={24}>
|
|
||||||
<Form.Item
|
|
||||||
name="acceptTerms"
|
|
||||||
valuePropName="checked"
|
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
validator: (_, value) =>
|
|
||||||
value ? Promise.resolve() : Promise.reject(new Error('You must accept the terms and conditions')),
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<Checkbox aria-label="Accept Terms">I accept the terms and conditions</Checkbox>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</Form>
|
|
||||||
</Card>
|
|
||||||
{!hasEverScrolledToBottom && (
|
|
||||||
<Card style={{textAlign: 'center'}} type='inner'>
|
|
||||||
<h3>You must scroll to the bottom of the Terms and Conditions before accepting.</h3>
|
|
||||||
</Card>
|
|
||||||
)}
|
|
||||||
</Space>
|
|
||||||
</Modal>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const EulaFormComponent = ({ form, handleChange, onFinish, t }) => (
|
||||||
|
<Card type='inner' title={t('eula.titles.upper_card')}>
|
||||||
|
<Form id='tosForm' onChange={handleChange} onFinish={onFinish} form={form}>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
label={t('eula.labels.first_name')}
|
||||||
|
name="first_name"
|
||||||
|
rules={[{ required: true, message: t('eula.messages.first_name') }]}
|
||||||
|
>
|
||||||
|
<Input placeholder={t('eula.labels.first_name')}
|
||||||
|
aria-label={t('eula.labels.first_name')} />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
label={t('eula.labels.last_name')}
|
||||||
|
name="last_name"
|
||||||
|
rules={[{ required: true, message: t('eula.messages.last_name') }]}
|
||||||
|
>
|
||||||
|
<Input placeholder={t('eula.labels.last_name')}
|
||||||
|
aria-label={t('eula.labels.last_name')} />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
label={t('eula.labels.business_name')}
|
||||||
|
name="business_name"
|
||||||
|
rules={[{ required: true, message: t('eula.messages.business_name') }]}
|
||||||
|
>
|
||||||
|
<Input placeholder={t('eula.labels.business_name')}
|
||||||
|
aria-label={t('eula.labels.business_name')} />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
label={t('eula.labels.phone_number')}
|
||||||
|
name="phone_number"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
pattern: /^(\+\d{1,2}\s?)?1?-?\.?\s?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/,
|
||||||
|
message: t('eula.messages.phone_number'),
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Input placeholder={t('eula.labels.phone_number')}
|
||||||
|
aria-label={t('eula.labels.phone_number')} />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
label={t('eula.labels.address')}
|
||||||
|
name="address"
|
||||||
|
>
|
||||||
|
<Input placeholder={t('eula.labels.address')} aria-label={t('eula.labels.address')} />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
label={t('eula.labels.date_accepted')}
|
||||||
|
name="date_accepted"
|
||||||
|
rules={[
|
||||||
|
{ required: true },
|
||||||
|
{
|
||||||
|
validator: (_, value) => {
|
||||||
|
if (day(value).isSame(day(), 'day')) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(t('eula.messages.date_accepted')));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<FormDatePicker onChange={handleChange} onlyFuture
|
||||||
|
aria-label={t('eula.labels.date_accepted')} />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={24}>
|
||||||
|
<Form.Item
|
||||||
|
name="accepted_terms"
|
||||||
|
valuePropName="checked"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
validator: (_, value) =>
|
||||||
|
value ? Promise.resolve() : Promise.reject(new Error(t('eula.messages.accepted_terms'))),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Checkbox
|
||||||
|
aria-label={t('eula.labels.accepted_terms')}>{t('eula.labels.accepted_terms')}</Checkbox>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Form>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
currentEula: selectCurrentEula,
|
||||||
|
currentUser: selectCurrentUser,
|
||||||
|
});
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
acceptEula: () => dispatch(acceptEula()),
|
||||||
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(Eula);
|
export default connect(mapStateToProps, mapDispatchToProps)(Eula);
|
||||||
21
client/src/components/eula/eula.styles.scss
Normal file
21
client/src/components/eula/eula.styles.scss
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
.eula-modal {
|
||||||
|
top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eula-markdown-card {
|
||||||
|
max-height: 50vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
background-color: lightgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eula-markdown-div {
|
||||||
|
padding: 0 10px 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eula-never-scrolled {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eula-accept-button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
@@ -933,6 +933,41 @@
|
|||||||
"updated": "Document updated successfully. "
|
"updated": "Document updated successfully. "
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"eula": {
|
||||||
|
"titles": {
|
||||||
|
"modal": "Terms and Conditions",
|
||||||
|
"upper_card": "Acknowledgement"
|
||||||
|
},
|
||||||
|
"messages": {
|
||||||
|
"first_name": "Please enter your first name.",
|
||||||
|
"last_name": "Please enter your last name.",
|
||||||
|
"business_name": "Please enter your legal business name.",
|
||||||
|
"phone_number": "Please enter your phone number.",
|
||||||
|
"date_accepted": "Please enter Today's Date.",
|
||||||
|
"accepted_terms": "Please accept the terms and conditions of this agreement."
|
||||||
|
},
|
||||||
|
"buttons": {
|
||||||
|
"accept": "Accept EULA"
|
||||||
|
},
|
||||||
|
"labels": {
|
||||||
|
"first_name": "First Name",
|
||||||
|
"last_name": "Last Name",
|
||||||
|
"business_name": "Legal Business Name",
|
||||||
|
"phone_number": "Phone Number",
|
||||||
|
"address": "Address",
|
||||||
|
"date_accepted": "Date Accepted",
|
||||||
|
"accepted_terms": "I accept the terms and conditions of this agreement."
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"never_scrolled": "You must scroll to the bottom of the Terms and Conditions before accepting."
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"acceptance": {
|
||||||
|
"message": "Eula Acceptance Error",
|
||||||
|
"description": "Something went wrong while accepting the EULA. Please try again."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"emails": {
|
"emails": {
|
||||||
"errors": {
|
"errors": {
|
||||||
"notsent": "Email not sent. Error encountered while sending {{message}}"
|
"notsent": "Email not sent. Error encountered while sending {{message}}"
|
||||||
|
|||||||
@@ -933,6 +933,41 @@
|
|||||||
"updated": ""
|
"updated": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"eula": {
|
||||||
|
"titles": {
|
||||||
|
"modal": "Terms and Conditions",
|
||||||
|
"upper_card": "Acknowledgement"
|
||||||
|
},
|
||||||
|
"messages": {
|
||||||
|
"first_name": "Please enter your first name.",
|
||||||
|
"last_name": "Please enter your last name.",
|
||||||
|
"business_name": "Please enter your legal business name.",
|
||||||
|
"phone_number": "Please enter your phone number.",
|
||||||
|
"date_accepted": "Please enter Today's Date.",
|
||||||
|
"accepted_terms": "Please accept the terms and conditions of this agreement."
|
||||||
|
},
|
||||||
|
"buttons": {
|
||||||
|
"accept": "Accept EULA"
|
||||||
|
},
|
||||||
|
"labels": {
|
||||||
|
"first_name": "First Name",
|
||||||
|
"last_name": "Last Name",
|
||||||
|
"business_name": "Legal Business Name",
|
||||||
|
"phone_number": "Phone Number",
|
||||||
|
"address": "Address",
|
||||||
|
"date_accepted": "Date Accepted",
|
||||||
|
"accepted_terms": "I accept the terms and conditions of this agreement."
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"never_scrolled": "You must scroll to the bottom of the Terms and Conditions before accepting."
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"acceptance": {
|
||||||
|
"message": "Eula Acceptance Error",
|
||||||
|
"description": "Something went wrong while accepting the EULA. Please try again."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"emails": {
|
"emails": {
|
||||||
"errors": {
|
"errors": {
|
||||||
"notsent": "Correo electrónico no enviado Se encontró un error al enviar {{message}}"
|
"notsent": "Correo electrónico no enviado Se encontró un error al enviar {{message}}"
|
||||||
|
|||||||
@@ -933,6 +933,41 @@
|
|||||||
"updated": ""
|
"updated": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"eula": {
|
||||||
|
"titles": {
|
||||||
|
"modal": "Terms and Conditions",
|
||||||
|
"upper_card": "Acknowledgement"
|
||||||
|
},
|
||||||
|
"messages": {
|
||||||
|
"first_name": "Please enter your first name.",
|
||||||
|
"last_name": "Please enter your last name.",
|
||||||
|
"business_name": "Please enter your legal business name.",
|
||||||
|
"phone_number": "Please enter your phone number.",
|
||||||
|
"date_accepted": "Please enter Today's Date.",
|
||||||
|
"accepted_terms": "Please accept the terms and conditions of this agreement."
|
||||||
|
},
|
||||||
|
"buttons": {
|
||||||
|
"accept": "Accept EULA"
|
||||||
|
},
|
||||||
|
"labels": {
|
||||||
|
"first_name": "First Name",
|
||||||
|
"last_name": "Last Name",
|
||||||
|
"business_name": "Legal Business Name",
|
||||||
|
"phone_number": "Phone Number",
|
||||||
|
"address": "Address",
|
||||||
|
"date_accepted": "Date Accepted",
|
||||||
|
"accepted_terms": "I accept the terms and conditions of this agreement."
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"never_scrolled": "You must scroll to the bottom of the Terms and Conditions before accepting."
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"acceptance": {
|
||||||
|
"message": "Eula Acceptance Error",
|
||||||
|
"description": "Something went wrong while accepting the EULA. Please try again."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"emails": {
|
"emails": {
|
||||||
"errors": {
|
"errors": {
|
||||||
"notsent": "Courriel non envoyé. Erreur rencontrée lors de l'envoi de {{message}}"
|
"notsent": "Courriel non envoyé. Erreur rencontrée lors de l'envoi de {{message}}"
|
||||||
|
|||||||
Reference in New Issue
Block a user