ui/src/pages/Install/components/FourthStep/index.tsx (376 lines of code) (raw):
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { FC, FormEvent } from 'react';
import { Form, Button } from 'react-bootstrap';
import { useTranslation } from 'react-i18next';
import type { FormDataType } from '@/common/interface';
import Pattern from '@/common/pattern';
import Progress from '../Progress';
interface Props {
data: FormDataType;
changeCallback: (value: FormDataType) => void;
nextCallback: () => void;
visible: boolean;
}
const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
const { t } = useTranslation('translation', { keyPrefix: 'install' });
const checkValidated = (): boolean => {
let bol = true;
const {
site_name,
site_url,
confirm_password,
contact_email,
name,
password,
email,
} = data;
const nameRegex = /^[\w.-\s]{2,30}$/;
if (!site_name.value) {
bol = false;
data.site_name = {
value: '',
isInvalid: true,
errorMsg: t('site_name.msg'),
};
}
if (site_name.value && site_name.value.length > 30) {
bol = false;
data.site_url = {
value: site_name.value,
isInvalid: true,
errorMsg: t('site_name.msg_max_length'),
};
}
if (!site_url.value) {
bol = false;
data.site_url = {
value: '',
isInvalid: true,
errorMsg: t('site_name.msg.empty'),
};
}
const reg = /^(http|https):\/\//g;
if (site_url.value && !site_url.value.match(reg)) {
bol = false;
data.site_url = {
value: site_url.value,
isInvalid: true,
errorMsg: t('site_url.msg.incorrect'),
};
} else if (site_url.value.length > 512) {
bol = false;
data.site_url = {
value: site_url.value,
isInvalid: true,
errorMsg: t('site_url.msg.max_length'),
};
}
if (!contact_email.value) {
bol = false;
data.contact_email = {
value: '',
isInvalid: true,
errorMsg: t('contact_email.msg.empty'),
};
}
if (contact_email.value && !Pattern.email.test(contact_email.value)) {
bol = false;
data.contact_email = {
value: contact_email.value,
isInvalid: true,
errorMsg: t('contact_email.msg.incorrect'),
};
}
if (!name.value) {
bol = false;
data.name = {
value: '',
isInvalid: true,
errorMsg: t('admin_name.msg'),
};
} else if (name.value.length < 2 || name.value.length > 30) {
bol = false;
data.name = {
value: name.value,
isInvalid: true,
errorMsg: t('admin_name.msg_max_length'),
};
} else if (!nameRegex.test(name.value)) {
bol = false;
data.name = {
value: name.value,
isInvalid: true,
errorMsg: t('admin_name.character'),
};
}
if (!password.value) {
bol = false;
data.password = {
value: '',
isInvalid: true,
errorMsg: t('admin_password.msg'),
};
}
if (password.value && password.value.length < 4) {
bol = false;
data.password = {
value: data.password.value,
isInvalid: true,
errorMsg: t('admin_password.msg_min_length'),
};
}
if (password.value && password.value.length > 32) {
bol = false;
data.password = {
value: data.password.value,
isInvalid: true,
errorMsg: t('admin_password.msg_max_length'),
};
}
if (confirm_password.value !== password.value) {
bol = false;
data.confirm_password = {
value: '',
isInvalid: true,
errorMsg: t('admin_confirm_password.msg'),
};
}
if (!email.value) {
bol = false;
data.email = {
value: '',
isInvalid: true,
errorMsg: t('admin_email.msg.empty'),
};
}
if (email.value && !Pattern.email.test(email.value)) {
bol = false;
data.email = {
value: email.value,
isInvalid: true,
errorMsg: t('admin_email.msg.incorrect'),
};
}
changeCallback({
...data,
});
return bol;
};
const handleSubmit = (event: FormEvent) => {
event.preventDefault();
event.stopPropagation();
if (!checkValidated()) {
return;
}
nextCallback();
};
if (!visible) return null;
return (
<Form noValidate onSubmit={handleSubmit}>
<h5>{t('site_information')}</h5>
<Form.Group controlId="site_name" className="mb-3">
<Form.Label>{t('site_name.label')}</Form.Label>
<Form.Control
required
value={data.site_name.value}
isInvalid={data.site_name.isInvalid}
onChange={(e) => {
changeCallback({
site_name: {
value: e.target.value,
isInvalid: false,
errorMsg: '',
},
});
}}
/>
<Form.Control.Feedback type="invalid">
{data.site_name.errorMsg}
</Form.Control.Feedback>
</Form.Group>
<Form.Group controlId="site_url" className="mb-3">
<Form.Label>{t('site_url.label')}</Form.Label>
<Form.Control
required
value={data.site_url.value}
isInvalid={data.site_url.isInvalid}
onChange={(e) => {
changeCallback({
site_url: {
value: e.target.value,
isInvalid: false,
errorMsg: '',
},
});
}}
/>
<Form.Text>{t('site_url.text')}</Form.Text>
<Form.Control.Feedback type="invalid">
{data.site_url.errorMsg}
</Form.Control.Feedback>
</Form.Group>
<Form.Group controlId="contact_email" className="mb-3">
<Form.Label>{t('contact_email.label')}</Form.Label>
<Form.Control
required
type="email"
value={data.contact_email.value}
isInvalid={data.contact_email.isInvalid}
onChange={(e) => {
changeCallback({
contact_email: {
value: e.target.value,
isInvalid: false,
errorMsg: '',
},
});
}}
/>
<Form.Text>{t('contact_email.text')}</Form.Text>
<Form.Control.Feedback type="invalid">
{data.contact_email.errorMsg}
</Form.Control.Feedback>
</Form.Group>
<h5>{t('login_required.label')}</h5>
<Form.Group controlId="login_required" className="mb-3">
<Form.Label>{t('login_required.label')}</Form.Label>
<Form.Check
type="switch"
id="login_required"
label={t('login_required.switch')}
checked={data.login_required.value}
onChange={(e) => {
changeCallback({
login_required: {
value: e.target.checked,
isInvalid: false,
errorMsg: '',
},
});
}}
/>
<Form.Text>{t('login_required.text')}</Form.Text>
</Form.Group>
<Form.Group controlId="external_content_display" className="mb-3">
<Form.Label>
{t('external_content_display.label', { keyPrefix: 'admin.legal' })}
</Form.Label>
<Form.Select
value={data.external_content_display.value}
onChange={(e) => {
changeCallback({
external_content_display: {
value: e.target.value,
isInvalid: false,
errorMsg: '',
},
});
}}>
<option value="always_display">
{t('external_content_display.always_display', {
keyPrefix: 'admin.legal',
})}
</option>
<option value="ask_before_display">
{t('external_content_display.ask_before_display', {
keyPrefix: 'admin.legal',
})}
</option>
</Form.Select>
<Form.Text>
{t('external_content_display.text', { keyPrefix: 'admin.legal' })}
</Form.Text>
</Form.Group>
<h5>{t('admin_account')}</h5>
<Form.Group controlId="name" className="mb-3">
<Form.Label>{t('admin_name.label')}</Form.Label>
<Form.Control
required
value={data.name.value}
isInvalid={data.name.isInvalid}
onChange={(e) => {
changeCallback({
name: {
value: e.target.value,
isInvalid: false,
errorMsg: '',
},
});
}}
/>
<Form.Control.Feedback type="invalid">
{data.name.errorMsg}
</Form.Control.Feedback>
</Form.Group>
<Form.Group controlId="password" className="mb-3">
<Form.Label>{t('admin_password.label')}</Form.Label>
<Form.Control
required
type="password"
value={data.password.value}
isInvalid={data.password.isInvalid}
onChange={(e) => {
changeCallback({
password: {
value: e.target.value,
isInvalid: false,
errorMsg: '',
},
});
}}
/>
<Form.Text>{t('admin_password.text')}</Form.Text>
<Form.Control.Feedback type="invalid">
{data.password.errorMsg}
</Form.Control.Feedback>
</Form.Group>
<Form.Group controlId="confirm_password" className="mb-3">
<Form.Label>{t('admin_confirm_password.label')}</Form.Label>
<Form.Control
required
type="password"
value={data.confirm_password.value}
isInvalid={data.confirm_password.isInvalid}
onChange={(e) => {
changeCallback({
confirm_password: {
value: e.target.value,
isInvalid: false,
errorMsg: '',
},
});
}}
/>
<Form.Text>{t('admin_confirm_password.text')}</Form.Text>
<Form.Control.Feedback type="invalid">
{data.confirm_password.errorMsg}
</Form.Control.Feedback>
</Form.Group>
<Form.Group controlId="email" className="mb-3">
<Form.Label>{t('admin_email.label')}</Form.Label>
<Form.Control
required
value={data.email.value}
isInvalid={data.email.isInvalid}
onChange={(e) => {
changeCallback({
email: {
value: e.target.value,
isInvalid: false,
errorMsg: '',
},
});
}}
/>
<Form.Text>{t('admin_email.text')}</Form.Text>
<Form.Control.Feedback type="invalid">
{data.email.errorMsg}
</Form.Control.Feedback>
</Form.Group>
<div className="d-flex align-items-center justify-content-between">
<Progress step={4} />
<Button type="submit">{t('next')}</Button>
</div>
</Form>
);
};
export default Index;