mirror of
https://github.com/casdoor/casdoor.git
synced 2025-05-23 02:35:49 +08:00
feat: add terms of use in signin page (#1476)
* feat: extract terms of use renderer * fix: layout * fix: form styling * fix: required state * feat: application terms of use setting * fix: refactor getTermsOfUseContent * fix: refactor renderers
This commit is contained in:
parent
f5b7f8cb45
commit
d10b1347a8
@ -14,7 +14,7 @@
|
||||
|
||||
import React from "react";
|
||||
import {Link} from "react-router-dom";
|
||||
import {Tag, Tooltip, message, theme} from "antd";
|
||||
import {Checkbox, Form, Modal, Tag, Tooltip, message, theme} from "antd";
|
||||
import {QuestionCircleTwoTone} from "@ant-design/icons";
|
||||
import {isMobile as isMobileDevice} from "react-device-detect";
|
||||
import "./i18n";
|
||||
@ -509,6 +509,69 @@ export function isMobile() {
|
||||
return isMobileDevice;
|
||||
}
|
||||
|
||||
export function getTermsOfUseContent(url, setTermsOfUseContent) {
|
||||
fetch(url, {
|
||||
method: "GET",
|
||||
}).then(r => {
|
||||
r.text().then(setTermsOfUseContent);
|
||||
});
|
||||
}
|
||||
|
||||
export function isAgreementRequired(application) {
|
||||
if (application) {
|
||||
const agreementItem = application.signupItems.find(item => item.name === "Agreement");
|
||||
if (agreementItem.rule === "None" || !agreementItem.rule) {
|
||||
return false;
|
||||
}
|
||||
if (agreementItem && agreementItem.required) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function renderAgreement(required, onClick, noStyle, layout) {
|
||||
return (
|
||||
<Form.Item
|
||||
name="agreement"
|
||||
key="agreement"
|
||||
valuePropName="checked"
|
||||
rules={[
|
||||
{
|
||||
required: required,
|
||||
message: i18next.t("signup:Please accept the agreement!"),
|
||||
},
|
||||
]}
|
||||
{...layout}
|
||||
noStyle={noStyle}
|
||||
>
|
||||
<Checkbox style={{float: "left"}}>
|
||||
{i18next.t("signup:Accept")}
|
||||
<a onClick={onClick}>
|
||||
{i18next.t("signup:Terms of Use")}
|
||||
</a>
|
||||
</Checkbox>
|
||||
</Form.Item>
|
||||
);
|
||||
}
|
||||
|
||||
export function renderModal(isOpen, onOk, onCancel, doc) {
|
||||
return (
|
||||
<Modal
|
||||
title={i18next.t("signup:Terms of Use")}
|
||||
open={isOpen}
|
||||
width={"55vw"}
|
||||
closable={false}
|
||||
okText={i18next.t("signup:Accept")}
|
||||
cancelText={i18next.t("signup:Decline")}
|
||||
onOk={onOk}
|
||||
onCancel={onCancel}
|
||||
>
|
||||
<iframe title={"terms"} style={{border: 0, width: "100%", height: "60vh"}} srcDoc={doc} />
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export function getFormattedDate(date) {
|
||||
if (date === undefined) {
|
||||
return null;
|
||||
|
@ -186,6 +186,11 @@ class SignupTable extends React.Component {
|
||||
{id: "Normal", name: "Normal"},
|
||||
{id: "No verification", name: "No verification"},
|
||||
];
|
||||
} else if (record.name === "Agreement") {
|
||||
options = [
|
||||
{id: "None", name: "None"},
|
||||
{id: "Signin", name: "Signin"},
|
||||
];
|
||||
}
|
||||
|
||||
if (options.length === 0) {
|
||||
|
@ -53,12 +53,16 @@ class LoginPage extends React.Component {
|
||||
samlResponse: "",
|
||||
relayState: "",
|
||||
redirectUrl: "",
|
||||
isTermsOfUseVisible: false,
|
||||
termsOfUseContent: "",
|
||||
};
|
||||
|
||||
if (this.state.type === "cas" && props.match?.params.casApplicationName !== undefined) {
|
||||
this.state.owner = props.match?.params.owner;
|
||||
this.state.applicationName = props.match?.params.casApplicationName;
|
||||
}
|
||||
|
||||
this.form = React.createRef();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -122,7 +126,9 @@ class LoginPage extends React.Component {
|
||||
this.onUpdateApplication(application);
|
||||
this.setState({
|
||||
application: application,
|
||||
});
|
||||
}, () => Setting.getTermsOfUseContent(this.state.application.termsOfUse, res => {
|
||||
this.setState({termsOfUseContent: res});
|
||||
}));
|
||||
});
|
||||
} else {
|
||||
OrganizationBackend.getDefaultApplication("admin", this.state.owner)
|
||||
@ -132,7 +138,9 @@ class LoginPage extends React.Component {
|
||||
this.setState({
|
||||
application: res.data,
|
||||
applicationName: res.data.name,
|
||||
});
|
||||
}, () => Setting.getTermsOfUseContent(this.state.application.termsOfUse, res => {
|
||||
this.setState({termsOfUseContent: res});
|
||||
}));
|
||||
} else {
|
||||
this.onUpdateApplication(null);
|
||||
Setting.showMessage("error", res.msg);
|
||||
@ -383,6 +391,7 @@ class LoginPage extends React.Component {
|
||||
onFinish={(values) => {this.onFinish(values);}}
|
||||
style={{width: "300px"}}
|
||||
size="large"
|
||||
ref={this.form}
|
||||
>
|
||||
<Form.Item
|
||||
hidden={true}
|
||||
@ -456,11 +465,20 @@ class LoginPage extends React.Component {
|
||||
}
|
||||
</Row>
|
||||
<Form.Item>
|
||||
<Form.Item name="autoSignin" valuePropName="checked" noStyle>
|
||||
<Checkbox style={{float: "left"}} disabled={!application.enablePassword}>
|
||||
{i18next.t("login:Auto sign in")}
|
||||
</Checkbox>
|
||||
</Form.Item>
|
||||
{
|
||||
Setting.isAgreementRequired(application) ?
|
||||
Setting.renderAgreement(true, () => {
|
||||
this.setState({
|
||||
isTermsOfUseVisible: true,
|
||||
});
|
||||
}, true) : (
|
||||
<Form.Item name="autoSignin" valuePropName="checked" noStyle>
|
||||
<Checkbox style={{float: "left"}} disabled={!application.enablePassword}>
|
||||
{i18next.t("login:Auto sign in")}
|
||||
</Checkbox>
|
||||
</Form.Item>
|
||||
)
|
||||
}
|
||||
{
|
||||
Setting.renderForgetLink(application, i18next.t("login:Forgot password?"))
|
||||
}
|
||||
@ -827,6 +845,19 @@ class LoginPage extends React.Component {
|
||||
{
|
||||
this.renderForm(application)
|
||||
}
|
||||
{
|
||||
Setting.renderModal(this.state.isTermsOfUseVisible, () => {
|
||||
this.form.current.setFieldsValue({agreement: true});
|
||||
this.setState({
|
||||
isTermsOfUseVisible: false,
|
||||
});
|
||||
}, () => {
|
||||
this.form.current.setFieldsValue({agreement: false});
|
||||
this.setState({
|
||||
isTermsOfUseVisible: false,
|
||||
});
|
||||
}, this.state.termsOfUseContent)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -13,8 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import {Link} from "react-router-dom";
|
||||
import {Button, Checkbox, Form, Input, Modal, Result} from "antd";
|
||||
import {Button, Form, Input, Result} from "antd";
|
||||
import * as Setting from "../Setting";
|
||||
import * as AuthBackend from "./AuthBackend";
|
||||
import * as ProviderButton from "./ProviderButton";
|
||||
@ -113,7 +112,9 @@ class SignupPage extends React.Component {
|
||||
});
|
||||
|
||||
if (application !== null && application !== undefined) {
|
||||
this.getTermsofuseContent(application.termsOfUse);
|
||||
Setting.getTermsOfUseContent(application.termsOfUse, res => {
|
||||
this.setState({termsOfUseContent: res});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -134,16 +135,6 @@ class SignupPage extends React.Component {
|
||||
return this.props.application ?? this.state.application;
|
||||
}
|
||||
|
||||
getTermsofuseContent(url) {
|
||||
fetch(url, {
|
||||
method: "GET",
|
||||
}).then(r => {
|
||||
r.text().then(res => {
|
||||
this.setState({termsOfUseContent: res});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onUpdateAccount(account) {
|
||||
this.props.onUpdateAccount(account);
|
||||
}
|
||||
@ -484,58 +475,28 @@ class SignupPage extends React.Component {
|
||||
);
|
||||
} else if (signupItem.name === "Agreement") {
|
||||
return (
|
||||
<Form.Item
|
||||
name="agreement"
|
||||
key="agreement"
|
||||
valuePropName="checked"
|
||||
rules={[
|
||||
{
|
||||
required: required,
|
||||
message: i18next.t("signup:Please accept the agreement!"),
|
||||
},
|
||||
]}
|
||||
{...tailFormItemLayout}
|
||||
>
|
||||
<Checkbox>
|
||||
{i18next.t("signup:Accept")}
|
||||
<Link onClick={() => {
|
||||
this.setState({
|
||||
isTermsOfUseVisible: true,
|
||||
});
|
||||
}}>
|
||||
{i18next.t("signup:Terms of Use")}
|
||||
</Link>
|
||||
</Checkbox>
|
||||
</Form.Item>
|
||||
Setting.renderAgreement(Setting.isAgreementRequired(application), () => {
|
||||
this.setState({
|
||||
isTermsOfUseVisible: true,
|
||||
});
|
||||
}, false, tailFormItemLayout)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
renderModal() {
|
||||
return (
|
||||
<Modal
|
||||
title={i18next.t("signup:Terms of Use")}
|
||||
open={this.state.isTermsOfUseVisible}
|
||||
width={"55vw"}
|
||||
closable={false}
|
||||
okText={i18next.t("signup:Accept")}
|
||||
cancelText={i18next.t("signup:Decline")}
|
||||
onOk={() => {
|
||||
this.form.current.setFieldsValue({agreement: true});
|
||||
this.setState({
|
||||
isTermsOfUseVisible: false,
|
||||
});
|
||||
}}
|
||||
onCancel={() => {
|
||||
this.form.current.setFieldsValue({agreement: false});
|
||||
this.setState({
|
||||
isTermsOfUseVisible: false,
|
||||
});
|
||||
this.props.history.goBack();
|
||||
}}
|
||||
>
|
||||
<iframe title={"terms"} style={{border: 0, width: "100%", height: "60vh"}} srcDoc={this.state.termsOfUseContent} />
|
||||
</Modal>
|
||||
Setting.renderModal(this.state.isTermsOfUseVisible, () => {
|
||||
this.form.current.setFieldsValue({agreement: true});
|
||||
this.setState({
|
||||
isTermsOfUseVisible: false,
|
||||
});
|
||||
}, () => {
|
||||
this.form.current.setFieldsValue({agreement: false});
|
||||
this.setState({
|
||||
isTermsOfUseVisible: false,
|
||||
});
|
||||
}, this.state.termsOfUseContent)
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user