Merged PR 382: added mobile header nav

Related work items: #5265
This commit is contained in:
Robert Bond
2021-07-27 09:36:02 +00:00
26 changed files with 1870 additions and 112 deletions
+15
View File
@@ -202,6 +202,21 @@ export const getLPA = () => {
});
};
export const getPersonalAccount = () => {
console.log("api_root: ", BASE_URL);
return axios
.get(
BASE_URL + "/api/lookups/personaldetails",
//.get("https://devcrm2016.llcdt.gov.wales/DVPINS/api/data/v8.2/contacts?$select=name",
{ httpsAgent: new https.Agent({ rejectUnauthorized: false }) }
)
.then((res) => res.data)
.catch((error) => {
console.log("thi serror", error);
});
};
function makeid(length) {
var result = "";
var characters =
+181
View File
@@ -0,0 +1,181 @@
import _ from "lodash";
import React, { useState } from "react";
import { useRouter } from "next/router";
import useTranslation from "next-translate/useTranslation";
import {
Field,
reduxForm,
formValueSelector,
getFormSubmitErrors,
} from "redux-form";
import { useDispatch, useSelector, shallowEqual, connect } from "react-redux";
import {
Textfield,
DateField,
DateFieldPicker,
YesNofield,
PickList,
MultiLinefield,
NumericField,
ReadOnlyfield,
DecimalField,
} from "../elements";
const RenderTextfield = ({
id,
className,
rows,
datafieldname,
name,
label,
input,
type,
errorMsg,
meta: { touched, error },
...custom
}) => {
return (
<>
<div
className={
touched && error
? "govuk-form-group govuk-form-group--error"
: "govuk-form-group "
}
>
<label className="govuk-label " htmlFor={id} id={id + "_label"}>
{label}
</label>
{touched && error && (
<span id={id + "-error"} className="govuk-error-message">
<span className="govuk-visually-hidden">Error:</span>{" "}
{touched &&
((error && (
<span>{errorMsg ? errorMsg : error}</span>
)) ||
(warning && <span>{warning}</span>))}
</span>
)}
<input
{...input}
className={className}
name={name}
id={id}
type={type}
/>
</div>
</>
);
};
const ChangePassword = (props) => {
const { footerLinks, pages, handleSubmit, value } = props;
let { t, lang } = useTranslation();
const router = useRouter();
const { locale } = router;
let errorsobj = {};
const onHandleSubmit = (values) => {
console.log(values);
};
const required = (value) => (value ? undefined : "Is required");
const matchInput = (input, allInputs) => {
return input === allInputs.password
? undefined
: "Passwords do not match";
};
const email = (value) =>
value && !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value)
? "Invalid email address"
: undefined;
const phoneNumber = (value) =>
value &&
!/^(?:(?:\(?(?:0(?:0|11)\)?[\s-]?\(?|\+)44\)?[\s-]?(?:\(?0\)?[\s-]?)?)|(?:\(?0))(?:(?:\d{5}\)?[\s-]?\d{4,5})|(?:\d{4}\)?[\s-]?(?:\d{5}|\d{3}[\s-]?\d{3}))|(?:\d{3}\)?[\s-]?\d{3}[\s-]?\d{3,4})|(?:\d{2}\)?[\s-]?\d{4}[\s-]?\d{4}))(?:[\s-]?(?:x|ext\.?|\#)\d{3,4})?$/i.test(
value
)
? "Invalid phone number"
: undefined;
const [hasErrors, setHasErrors] = useState("");
return (
<>
{/* {hasErrors == true ? (
<ShowErrorHeader
hasErrors={hasErrors}
props={props.props.form}
formXML={formXML}
/>
) : (
""
)} */}
<form onSubmit={handleSubmit(onHandleSubmit)}>
<fieldset className="govuk-fieldset">
<Field
name="newpassword"
id="newpassword"
component={RenderTextfield}
type="password"
className="govuk-input govuk-input--width-20"
validate={[required]}
label="New password"
/>
<Field
name="confirmpassword"
id="confirmpassword"
component={RenderTextfield}
type="password"
className="govuk-input govuk-input--width-20"
validate={[matchInput]}
label="Confirm new password"
/>
</fieldset>
<div className="govuk-button-group">
<button
type="submit"
className="govuk-button"
data-module="govuk-button"
>
Continue
</button>
</div>
</form>
</>
);
};
const mapStateToProps = (state) => {
return {
search: state.search,
searchResultsObj: state.searchResultsObj,
formData: state.formData,
appealType: state.appealType,
//form: state.form,
};
};
const mapDispatchToProps = (dispatch) => {
return {
setCurrentSection: (currentSection) => {
dispatch(setCurrentSection(currentSection));
},
};
};
const selector = formValueSelector("changepasswordForm"); // <-- same as form name
export default connect(
mapStateToProps,
mapDispatchToProps
)(
reduxForm({
form: "changepasswordForm",
destroyOnUnmount: false,
})(ChangePassword)
);
+314
View File
@@ -0,0 +1,314 @@
import _ from "lodash";
import Link from "next/link";
import React, { useState } from "react";
import { useRouter } from "next/router";
import useTranslation from "next-translate/useTranslation";
import {
Field,
reduxForm,
formValueSelector,
getFormSubmitErrors,
} from "redux-form";
import { useDispatch, useSelector, shallowEqual, connect } from "react-redux";
import {
Textfield,
DateField,
DateFieldPicker,
YesNofield,
PickList,
MultiLinefield,
NumericField,
ReadOnlyfield,
DecimalField,
} from "../elements";
import BuildCheckPersonalDetails from "./personaldetailsCheck";
const RenderTextfield = ({
id,
className,
rows,
datafieldname,
name,
label,
input,
type,
errorMsg,
meta: { touched, error },
...custom
}) => {
return (
<>
<div
className={
touched && error
? "govuk-form-group govuk-form-group--error"
: "govuk-form-group "
}
>
<label className="govuk-label " htmlFor={id} id={id + "_label"}>
{label}
</label>
{touched && error && (
<span id={id + "-error"} className="govuk-error-message">
<span className="govuk-visually-hidden">Error:</span>{" "}
{touched &&
((error && (
<span>{errorMsg ? errorMsg : error}</span>
)) ||
(warning && <span>{warning}</span>))}
</span>
)}
<input
{...input}
className={className}
name={id}
id={id}
type={type}
/>
</div>
</>
);
};
const PersonalDetails = (props) => {
const { footerLinks, pages, handleSubmit, value } = props;
let { t, lang } = useTranslation();
const router = useRouter();
const { locale } = router;
let errorsobj = {};
const onHandleSubmit = (values) => {
console.log(values);
};
const required = (value) => (value ? undefined : "Is required");
const email = (value) =>
value && !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value)
? "Invalid email address"
: undefined;
const phoneNumber = (value) =>
value &&
!/^(?:(?:\(?(?:0(?:0|11)\)?[\s-]?\(?|\+)44\)?[\s-]?(?:\(?0\)?[\s-]?)?)|(?:\(?0))(?:(?:\d{5}\)?[\s-]?\d{4,5})|(?:\d{4}\)?[\s-]?(?:\d{5}|\d{3}[\s-]?\d{3}))|(?:\d{3}\)?[\s-]?\d{3}[\s-]?\d{3,4})|(?:\d{2}\)?[\s-]?\d{4}[\s-]?\d{4}))(?:[\s-]?(?:x|ext\.?|\#)\d{3,4})?$/i.test(
value
)
? "Invalid phone number"
: undefined;
const [hasErrors, setHasErrors] = useState("");
const [personalDetailsComplete, setPersonalDetailsComplete] =
useState(false);
return (
<>
{/* {hasErrors == true ? (
<ShowErrorHeader
hasErrors={hasErrors}
props={props.props.form}
formXML={formXML}
/>
) : (
""
)} */}
{personalDetailsComplete == false ? (
<form onSubmit={handleSubmit(onHandleSubmit)}>
<fieldset className="govuk-fieldset">
<legend className="govuk-fieldset__legend govuk-fieldset__legend--m">
<h2 className="govuk-fieldset__heading">
About you
</h2>
</legend>
<Field
name="firstname"
id="firstname"
component={RenderTextfield}
type="text"
className="govuk-input govuk-input--width-20"
validate={[required]}
label="First name"
errorMsg="Is required"
/>
<Field
name="lastname"
id="lastname"
component={RenderTextfield}
type="text"
className="govuk-input govuk-input--width-20"
validate={[required]}
label="Last name"
errorMsg="Is required"
/>
<Field
name="email"
id="email"
component={RenderTextfield}
type="email"
className="govuk-input govuk-input--width-20"
validate={[required, email]}
label="Email address"
/>
<Field
name="telephone"
id="telephone"
component={RenderTextfield}
type="number"
className="govuk-input govuk-input--width-20"
validate={[required, phoneNumber]}
label="Telephone"
/>
<Field
name="companygroup"
id="companygroup"
component={RenderTextfield}
type="text"
className="govuk-input govuk-input--width-20"
label="Company/Group"
errorMsg="Is required"
/>
</fieldset>
<fieldset className="govuk-fieldset">
<legend className="govuk-fieldset__legend govuk-fieldset__legend--m">
<h2 className="govuk-fieldset__heading">
What is your address?
</h2>
</legend>
<Field
name="addressline1"
id="addressline1"
component={RenderTextfield}
type="text"
className="govuk-input govuk-input--width-20"
label="Address line 1"
validate={[required]}
errorMsg="Is required"
/>
<Field
name="addressline2"
id="addressline2"
component={RenderTextfield}
type="text"
className="govuk-input govuk-input--width-20"
label="Address line 2"
errorMsg="Is required"
/>
<Field
name="towncity"
id="towncity"
component={RenderTextfield}
type="text"
className="govuk-input govuk-input--width-10"
label="Town/City"
validate={[required]}
errorMsg="Is required"
/>
<Field
name="county"
id="county"
component={RenderTextfield}
type="text"
className="govuk-input govuk-input--width-10"
label="County"
validate={[required]}
errorMsg="Is required"
/>
<Field
name="postcode"
id="postcode"
component={RenderTextfield}
type="text"
className="govuk-input govuk-input--width-5"
label="Postcode"
validate={[required]}
errorMsg="Is required"
/>
</fieldset>
<div className="govuk-button-group">
<button
type="submit"
className="govuk-button"
data-module="govuk-button"
onClick={() => {
setPersonalDetailsComplete(true);
}}
>
Continue
</button>
</div>
</form>
) : (
<>
<BuildCheckPersonalDetails
props={props}
setPersonalDetailsComplete={setPersonalDetailsComplete}
/>
<div className="govuk-button-group">
<button
type="submit"
className="govuk-button"
data-module="govuk-button"
onClick={() => {
setPersonalDetailsComplete(false);
}}
>
Continue
</button>
<Link href="">
<a
onClick={() => {
setPersonalDetailsComplete(false);
}}
className="govuk-link"
>
Go back
</a>
</Link>
</div>
</>
)}
</>
);
};
const mapStateToProps = (state) => {
return {
search: state.search,
searchResultsObj: state.searchResultsObj,
formData: state.formData,
appealType: state.appealType,
accountDetails: state.accountDetails,
//form: state.form,
};
};
const mapDispatchToProps = (dispatch) => {
return {
setCurrentSection: (currentSection) => {
dispatch(setCurrentSection(currentSection));
},
};
};
const selector = formValueSelector("personalDetailsForm"); // <-- same as form name
export default connect(mapStateToProps, mapDispatchToProps, (state) => ({
initialValues: state.accountDetails.accountDetails.data,
search: state.search,
searchResultsObj: state.searchResultsObj,
formData: state.formData,
appealType: state.appealType,
accountDetails: state.accountDetails,
form: state.form,
// pull initial values from account reducer
}))(
reduxForm({
form: "personalDetailsForm",
enableReinitialize: true, // this is needed!!
destroyOnUnmount: false,
})(PersonalDetails)
);
+311
View File
@@ -0,0 +1,311 @@
import _ from "lodash";
import React, { useState } from "react";
import { useRouter } from "next/router";
import useTranslation from "next-translate/useTranslation";
import {
Field,
reduxForm,
formValueSelector,
getFormSubmitErrors,
} from "redux-form";
import { useDispatch, useSelector, shallowEqual, connect } from "react-redux";
const BuildCheckPersonalDetails = (props) => {
const {
footerLinks,
pages,
handleSubmit,
value,
setPersonalDetailsComplete,
} = props;
let { t, lang } = useTranslation();
const router = useRouter();
const { locale } = router;
return (
<>
<h2 className="govuk-heading-m">About you</h2>
<dl className="govuk-summary-list govuk-!-margin-bottom-9">
<div className="govuk-summary-list__row">
<dt className="govuk-summary-list__key">First name</dt>
<dd className="govuk-summary-list__value">
{/* {console.log(
props.props.form["personalDetailsForm"].values[
"firstname"
]
)} */}
</dd>
<dd className="govuk-summary-list__actions">
<a
className="govuk-link"
href="#"
onClick={() => {
setPersonalDetailsComplete(false);
}}
>
Change
<span className="govuk-visually-hidden">
first name
</span>
</a>
</dd>
</div>
<div className="govuk-summary-list__row">
<dt className="govuk-summary-list__key">Last name</dt>
<dd className="govuk-summary-list__value">
{/* {console.log(
props.props.form["personalDetailsForm"].values[
"firstname"
]
)} */}
</dd>
<dd className="govuk-summary-list__actions">
<a
className="govuk-link"
href="#"
onClick={() => {
setPersonalDetailsComplete(false);
}}
>
Change
<span className="govuk-visually-hidden">
{" "}
last name
</span>
</a>
</dd>
</div>
<div className="govuk-summary-list__row">
<dt className="govuk-summary-list__key">Email address</dt>
<dd className="govuk-summary-list__value">
{/* {console.log(
props.props.form["personalDetailsForm"].values[
"firstname"
]
)} */}
</dd>
<dd className="govuk-summary-list__actions">
<a
className="govuk-link"
href="#"
onClick={() => {
setPersonalDetailsComplete(false);
}}
>
Change
<span className="govuk-visually-hidden">
{" "}
email address
</span>
</a>
</dd>
</div>
<div className="govuk-summary-list__row">
<dt className="govuk-summary-list__key">Telephone</dt>
<dd className="govuk-summary-list__value">
{/* {console.log(
props.props.form["personalDetailsForm"].values[
"firstname"
]
)} */}
</dd>
<dd className="govuk-summary-list__actions">
<a
className="govuk-link"
href="#"
onClick={() => {
setPersonalDetailsComplete(false);
}}
>
Change
<span className="govuk-visually-hidden">
telephone
</span>
</a>
</dd>
</div>
<div className="govuk-summary-list__row">
<dt className="govuk-summary-list__key">Company/Group</dt>
<dd className="govuk-summary-list__value">
{/* {console.log(
props.props.form["personalDetailsForm"].values[
"firstname"
]
)} */}
</dd>
<dd className="govuk-summary-list__actions">
<a
className="govuk-link"
href="#"
onClick={() => {
setPersonalDetailsComplete(false);
}}
>
Change
<span className="govuk-visually-hidden">
{" "}
company/group
</span>
</a>
</dd>
</div>
</dl>
<dl className="govuk-summary-list govuk-!-margin-bottom-9">
<h2 className="govuk-heading-m">Your address</h2>
<div className="govuk-summary-list__row">
<dt className="govuk-summary-list__key">Address Line 1</dt>
<dd className="govuk-summary-list__value">
{/* {console.log(
props.props.form["personalDetailsForm"].values[
"firstname"
]
)} */}
</dd>
<dd className="govuk-summary-list__actions">
<a
className="govuk-link"
href="#"
onClick={() => {
setPersonalDetailsComplete(false);
}}
>
Change
<span className="govuk-visually-hidden">
{" "}
address line 1
</span>
</a>
</dd>
</div>
<div className="govuk-summary-list__row">
<dt className="govuk-summary-list__key">Address line 2</dt>
<dd className="govuk-summary-list__value">
{/* {console.log(
props.props.form["personalDetailsForm"].values[
"firstname"
]
)} */}
</dd>
<dd className="govuk-summary-list__actions">
<a
className="govuk-link"
href="#"
onClick={() => {
setPersonalDetailsComplete(false);
}}
>
Change
<span className="govuk-visually-hidden">
{" "}
address line 2
</span>
</a>
</dd>
</div>
<div className="govuk-summary-list__row">
<dt className="govuk-summary-list__key">Town/City</dt>
<dd className="govuk-summary-list__value">
{/* {console.log(
props.props.form["personalDetailsForm"].values[
"firstname"
]
)} */}
</dd>
<dd className="govuk-summary-list__actions">
<a
className="govuk-link"
href="#"
onClick={() => {
setPersonalDetailsComplete(false);
}}
>
Change
<span className="govuk-visually-hidden">
{" "}
town/city
</span>
</a>
</dd>
</div>
<div className="govuk-summary-list__row">
<dt className="govuk-summary-list__key">County</dt>
<dd className="govuk-summary-list__value">
{/* {console.log(
props.props.form["personalDetailsForm"].values[
"firstname"
]
)} */}
</dd>
<dd className="govuk-summary-list__actions">
<a
className="govuk-link"
href="#"
onClick={() => {
setPersonalDetailsComplete(false);
}}
>
Change
<span className="govuk-visually-hidden">
{" "}
county
</span>
</a>
</dd>
</div>
<div className="govuk-summary-list__row">
<dt className="govuk-summary-list__key">Postcode</dt>
<dd className="govuk-summary-list__value">
{/* {console.log(
props.props.form["personalDetailsForm"].values[
"firstname"
]
)} */}
</dd>
<dd className="govuk-summary-list__actions">
<a
className="govuk-link"
href="#"
onClick={() => {
setPersonalDetailsComplete(false);
}}
>
Change
<span className="govuk-visually-hidden">
{" "}
postcode
</span>
</a>
</dd>
</div>
</dl>
</>
);
};
const mapStateToProps = (state) => {
return {
search: state.search,
searchResultsObj: state.searchResultsObj,
formData: state.formData,
appealType: state.appealType,
accountDetails: state.accountDetails,
//form: state.form,
};
};
const mapDispatchToProps = (dispatch) => {
return {
setCurrentSection: (currentSection) => {
dispatch(setCurrentSection(currentSection));
},
};
};
const selector = formValueSelector("personalDetailsForm"); // <-- same as form name
export default connect(
mapStateToProps,
mapDispatchToProps
)(BuildCheckPersonalDetails);
+264
View File
@@ -0,0 +1,264 @@
import _ from "lodash";
import React, { useState } from "react";
import { useRouter } from "next/router";
import useTranslation from "next-translate/useTranslation";
import {
Field,
reduxForm,
formValueSelector,
getFormSubmitErrors,
} from "redux-form";
import { useDispatch, useSelector, shallowEqual, connect } from "react-redux";
import {
Textfield,
DateField,
DateFieldPicker,
YesNofield,
PickList,
MultiLinefield,
NumericField,
ReadOnlyfield,
DecimalField,
} from "../elements";
const RenderTextfield = ({
id,
className,
rows,
datafieldname,
name,
label,
input,
type,
errorMsg,
meta: { touched, error },
...custom
}) => {
return (
<>
<div
className={
touched && error
? "govuk-form-group govuk-form-group--error"
: "govuk-form-group "
}
>
<label className="govuk-label " htmlFor={id} id={id + "_label"}>
{label}
</label>
{touched && error && (
<span id={id + "-error"} className="govuk-error-message">
<span className="govuk-visually-hidden">Error:</span>{" "}
{touched &&
((error && (
<span>{errorMsg ? errorMsg : error}</span>
)) ||
(warning && <span>{warning}</span>))}
</span>
)}
<input
{...input}
className={className}
name={name}
id={id}
type={type}
/>
</div>
</>
);
};
const RegisterForm = (props) => {
const { footerLinks, pages, handleSubmit, value } = props;
let { t, lang } = useTranslation();
const router = useRouter();
const { locale } = router;
let errorsobj = {};
const onHandleSubmit = (values) => {
console.log(values);
};
const required = (value) => (value ? undefined : "Is required");
const email = (value) =>
value && !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value)
? "Invalid email address"
: undefined;
const phoneNumber = (value) =>
value &&
!/^(?:(?:\(?(?:0(?:0|11)\)?[\s-]?\(?|\+)44\)?[\s-]?(?:\(?0\)?[\s-]?)?)|(?:\(?0))(?:(?:\d{5}\)?[\s-]?\d{4,5})|(?:\d{4}\)?[\s-]?(?:\d{5}|\d{3}[\s-]?\d{3}))|(?:\d{3}\)?[\s-]?\d{3}[\s-]?\d{3,4})|(?:\d{2}\)?[\s-]?\d{4}[\s-]?\d{4}))(?:[\s-]?(?:x|ext\.?|\#)\d{3,4})?$/i.test(
value
)
? "Invalid phone number"
: undefined;
const [hasErrors, setHasErrors] = useState("");
return (
<>
{/* {hasErrors == true ? (
<ShowErrorHeader
hasErrors={hasErrors}
props={props.props.form}
formXML={formXML}
/>
) : (
""
)} */}
<form onSubmit={handleSubmit(onHandleSubmit)}>
<fieldset className="govuk-fieldset">
<legend className="govuk-fieldset__legend govuk-fieldset__legend--m">
<h2 className="govuk-fieldset__heading">About you</h2>
</legend>
<Field
name="firstname"
id="firstname"
component={RenderTextfield}
type="text"
className="govuk-input govuk-input--width-20"
validate={[required]}
label="First name"
errorMsg="Is required"
/>
<Field
name="lastname"
id="lastname"
component={RenderTextfield}
type="text"
className="govuk-input govuk-input--width-20"
validate={[required]}
label="Last name"
errorMsg="Is required"
/>
<Field
name="email"
id="email"
component={RenderTextfield}
type="email"
className="govuk-input govuk-input--width-20"
validate={[required, email]}
label="Email address"
/>
<Field
name="telephone"
id="telephone"
component={RenderTextfield}
type="number"
className="govuk-input govuk-input--width-20"
validate={[required, phoneNumber]}
label="Telephone"
/>
<Field
name="companygroup"
id="companygroup"
component={RenderTextfield}
type="text"
className="govuk-input govuk-input--width-20"
label="Company/Group"
errorMsg="Is required"
/>
</fieldset>
<fieldset className="govuk-fieldset">
<legend className="govuk-fieldset__legend govuk-fieldset__legend--m">
<h2 className="govuk-fieldset__heading">
What is your address?
</h2>
</legend>
<Field
name="addressline1"
id="addressline1"
component={RenderTextfield}
type="text"
className="govuk-input govuk-input--width-20"
label="Address line 1"
validate={[required]}
errorMsg="Is required"
/>
<Field
name="addressline2"
id="addressline2"
component={RenderTextfield}
type="text"
className="govuk-input govuk-input--width-20"
label="Address line 2"
errorMsg="Is required"
/>
<Field
name="towncity"
id="towncity"
component={RenderTextfield}
type="text"
className="govuk-input govuk-input--width-10"
label="Town/City"
validate={[required]}
errorMsg="Is required"
/>
<Field
name="county"
id="county"
component={RenderTextfield}
type="text"
className="govuk-input govuk-input--width-10"
label="County"
validate={[required]}
errorMsg="Is required"
/>
<Field
name="postcode"
id="postcode"
component={RenderTextfield}
type="text"
className="govuk-input govuk-input--width-5"
label="Postcode"
validate={[required]}
errorMsg="Is required"
/>
</fieldset>
<div className="govuk-button-group">
<button
type="submit"
className="govuk-button"
data-module="govuk-button"
>
Continue
</button>
</div>
</form>
</>
);
};
const mapStateToProps = (state) => {
return {
search: state.search,
searchResultsObj: state.searchResultsObj,
formData: state.formData,
appealType: state.appealType,
//form: state.form,
};
};
const mapDispatchToProps = (dispatch) => {
return {
setCurrentSection: (currentSection) => {
dispatch(setCurrentSection(currentSection));
},
};
};
const selector = formValueSelector("accountRegisterForm"); // <-- same as form name
export default connect(
mapStateToProps,
mapDispatchToProps
)(
reduxForm({
form: "accountRegisterForm",
destroyOnUnmount: false,
})(RegisterForm)
);
+32
View File
@@ -166,6 +166,38 @@ const Breadcrumbs = (props) => {
) : (
""
)}
{router.pathname == "/account/personaldetails" ? (
<>
<li className="govuk-breadcrumbs__list-item">
<Link href="/myportal">
<a className="govuk-breadcrumbs__link">
My Portal
</a>
</Link>
</li>
<li className="govuk-breadcrumbs__list-item">
Your account
</li>
</>
) : (
""
)}
{router.pathname == "/account/changepassword" ? (
<>
<li className="govuk-breadcrumbs__list-item">
<Link href="/myportal">
<a className="govuk-breadcrumbs__link">
My Portal
</a>
</Link>
</li>
<li className="govuk-breadcrumbs__list-item">
Update your password
</li>
</>
) : (
""
)}
{!_.isEmpty(slug) ? (
<>
<li className="govuk-breadcrumbs__list-item">
+1 -1
View File
@@ -43,7 +43,7 @@ const RenderTextfield = ({
};
export function Textfield(props) {
const { name, label } = props;
const { name, label, validate } = props;
const required = (value) => (value ? undefined : "Required");
return (
+120 -24
View File
@@ -60,7 +60,7 @@ export default function Header({ courseName }) {
</Link>
</div>
<div className="govuk-header__content govuk-!-width-two-thirds govuk-!-margin-top-3">
<div className="govuk-header__content govuk-!-width-one-half govuk-!-margin-top-3">
<Link href="/">
<a
onClick={() => {
@@ -74,32 +74,128 @@ export default function Header({ courseName }) {
</Link>
</div>
<div className="languageSwitch">
{router.path}
<Link
href={
locale == "en" ? router.pathname : router.pathname
}
locale={locale == "en" ? "cy" : "en"}
>
<a
className="govuk-header__link "
lang={locale == "en" ? "cy" : "en"}
hrefLang={locale == "en" ? "cy" : "en"}
data-journey-click={
<div className="mobileNav">
<div className="mobileMenu">
<input
type="radio"
id="mobileMenu-1"
name="mobileMenu-group-1"
/>
<label htmlFor="mobileMenu-1">
{t("common:mobile-nav-label")} <i></i>
</label>
<div className="mobileMenu close-mobileMenu">
<input
type="radio"
id="mobileMenu-close"
name="mobileMenu-group-1"
/>
<label htmlFor="mobileMenu-close">
{t("common:mobile-nav-label")} <i></i>
</label>
</div>
<div className="content">
<ul>
{router.pathname != "/" ? (
<li>
<Link href="/">
<a
onClick={() => {
window.localStorage.clear();
}}
className="govuk-header__link "
>
{t("common:signout-label")}
</a>
</Link>
</li>
) : (
""
)}
<li>
<Link
href={
locale == "en"
? router.pathname
: router.pathname
}
locale={
locale == "en" ? "cy" : "en"
}
>
<a
className="govuk-header__link "
lang={
locale == "en" ? "cy" : "en"
}
hrefLang={
locale == "en" ? "cy" : "en"
}
data-journey-click={
locale == "en"
? "link - click:lang-select:Cymraeg"
: "link - click:lang-select:English"
}
aria-label={
locale == "en"
? "Dewiswch Cymraeg"
: "Select English"
}
>
{" "}
{t("common:available-in")}
</a>
</Link>
</li>
</ul>
</div>
</div>
</div>
<div className="fullNav">
{router.pathname != "/" ? (
<Link href="/">
<a
onClick={() => {
window.localStorage.clear();
}}
className="govuk-header__link govuk-!-margin-right-3"
>
{t("common:signout-label")}
</a>
</Link>
) : (
""
)}
<Link
href={
locale == "en"
? "link - click:lang-select:Cymraeg"
: "link - click:lang-select:English"
}
aria-label={
locale == "en"
? "Dewiswch Cymraeg"
: "Select English"
? router.pathname
: router.pathname
}
locale={locale == "en" ? "cy" : "en"}
>
{" "}
{t("common:available-in")}
</a>
</Link>
<a
className="govuk-header__link "
lang={locale == "en" ? "cy" : "en"}
hrefLang={locale == "en" ? "cy" : "en"}
data-journey-click={
locale == "en"
? "link - click:lang-select:Cymraeg"
: "link - click:lang-select:English"
}
aria-label={
locale == "en"
? "Dewiswch Cymraeg"
: "Select English"
}
>
{" "}
{t("common:available-in")}
</a>
</Link>
</div>
</div>
</div>
</header>
+1 -1
View File
@@ -70,7 +70,7 @@ export default function Login() {
<div className="govuk-form-group govuk-!-margin-top-4">
<p className="govuk-body-s">
{t("home:login-card-register-label")}{" "}
<Link href="/">
<Link href="/account/register">
<a>{t("home:login-card-register-link")}</a>
</Link>
</p>
+34 -34
View File
@@ -2,41 +2,41 @@ import Link from "next/link";
import { useRouter } from "next/router";
import { useContext } from "react";
import useTranslation from "next-translate/useTranslation";
import MakeNewAppeal from "./myportal/makenewappeal";
import MyCases from "./myportal/mycases";
import SearchCases from "./myportal/searchcases";
import AwaitingSubmission from "./myportal/awaitingsubmission";
import MyRepresentations from "./myportal/myrepresentations";
import WatchedCases from "./myportal/watchedcases";
import MakeNewAppeal from "./myportal/makenewappeal";
import MyCases from "./myportal/mycases";
import SearchCases from "./myportal/searchcases";
import AwaitingSubmission from "./myportal/awaitingsubmission";
import MyRepresentations from "./myportal/myrepresentations";
import WatchedCases from "./myportal/watchedcases";
import YourAccount from "./myportal/youraccount";
export default function MyPortal({ children, pages }) {
let { t } = useTranslation();
let { t } = useTranslation();
const router = useRouter();
const { locale } = router;
const router = useRouter();
const { locale } = router;
return (
<main
className="govuk-main-wrapper govuk-main-wrapper--auto-spacing"
id="main-content"
role="main"
>
<div className="govuk-grid-row">
<div className="govuk-grid-column-full">
<div className="flex-container grid-row govuk-body ">
<MakeNewAppeal />
<MyCases/>
<SearchCases/>
<AwaitingSubmission/>
<MyRepresentations/>
<WatchedCases/>
</div>
</div>
</div>
</main>
);
}
return (
<main
className="govuk-main-wrapper govuk-main-wrapper--auto-spacing"
id="main-content"
role="main"
>
<div className="govuk-grid-row">
<div className="govuk-grid-column-full">
<div className="flex-container grid-row govuk-body ">
<MakeNewAppeal />
<MyCases />
<SearchCases />
<AwaitingSubmission />
<MyRepresentations />
<WatchedCases />
</div>
<div className="flex-container grid-row govuk-body ">
<YourAccount />
</div>
</div>
</div>
</main>
);
}
+46
View File
@@ -0,0 +1,46 @@
import Link from "next/link";
import { useRouter } from "next/router";
import useTranslation from "next-translate/useTranslation";
export default function YourAccount() {
let { t } = useTranslation();
const router = useRouter();
const { locale } = router;
return (
<>
<div className="card" id="casescomment-card">
<div className="card-body">
<h3 className="heading-small card-heading">Your details</h3>
<p className="govuk-body-s">
You can change your address and contact details
</p>
<div>
<Link href="/account/personaldetails">
<a className="govuk-button-secondary">
Edit your account details
</a>
</Link>
</div>
</div>
</div>
<div className="card" id="casescomment-card">
<div className="card-body">
<h3 className="heading-small card-heading">
Change your password
</h3>
<p className="govuk-body-s">You can change your password</p>
<div>
<Link href="/account/changepassword">
<a className="govuk-button-secondary">
Update your password
</a>
</Link>
</div>
</div>
</div>
</>
);
}
+5 -21
View File
@@ -51,27 +51,11 @@ let BuildCheckRow = (props) => {
{rows[0].value}
</dt>
<dd className="govuk-summary-list__value">
{fieldtype[0].value ==
"{5B773807-9FB2-42db-97C3-7A91EFF8ADFF}"
? props.props.form["appealForm"].values[
datafieldname[0].value
] != null
? props.props.form["appealForm"].values[
datafieldname[0].value
].getDate() +
"/" +
(props.props.form["appealForm"].values[
datafieldname[0].value
].getMonth() +
1) +
"/" +
props.props.form["appealForm"].values[
datafieldname[0].value
].getFullYear()
: ""
: props.props.form["appealForm"].values[
datafieldname[0].value
]}
{
props.props.form["appealForm"].values[
datafieldname[0].value
]
}
</dd>
<dd className="govuk-summary-list__actions">
<a
+3 -1
View File
@@ -11,5 +11,7 @@
"footer-privacy-link": "Rhybudd Preifatrwydd",
"footer-cookies-link": "Chwcis",
"footer-accessibility-link": "Hygyrchedd",
"footer-feedback-link": "Adborth"
"footer-feedback-link": "Adborth",
"mobile-nav-label": "Dewislen",
"signout-label": "Cofrestrwch allan"
}
+3 -1
View File
@@ -11,5 +11,7 @@
"footer-privacy-link": "Privacy Notice",
"footer-cookies-link": "Cookies",
"footer-accessibility-link": "Accessibility",
"footer-feedback-link": "Feedback"
"footer-feedback-link": "Feedback",
"mobile-nav-label": "Menu",
"signout-label": "Sign out"
}
+1
View File
@@ -27,6 +27,7 @@
"next-i18next": "^8.5.1",
"next-redux-wrapper": "^7.0.2",
"next-translate": "^1.0.7",
"pm2": "^5.1.0",
"react": "17.0.2",
"react-cookie-consent": "^6.2.4",
"react-datepicker": "^4.1.1",
+102
View File
@@ -0,0 +1,102 @@
import Link from "next/link";
import _ from "lodash";
import Head from "next/head";
import Header from "../../components/header";
import Banner from "../../components/banner";
import CookieBanner from "../../components/cookieBanner";
import Breadcrumbs from "../../components/breadcrumbs";
import Footer from "../../components/footer";
import { useSelector, shallowEqual, connect } from "react-redux";
import { wrapper } from "../../store/store";
import Cookies from "cookies";
import { useRouter } from "next/router";
import { useState } from "react";
import useTranslation from "next-translate/useTranslation";
import jsonpath from "jsonpath";
import { reduxForm, formValueSelector } from "redux-form";
import ChangePassword from "../../components/account/changepassword";
import xpath from "xpath";
import {
setAppealType,
setAppealTypeTitle,
setAppealTypeID,
setAppealLPA,
getAppealTypeObj,
} from "../../store/appealType/action";
import { getAppealsTypes, getLPA } from "../../actions";
import { setLPA } from "../../store/lpa/action";
const Home = (props) => {
const { footerLinks, pages, formData } = props;
let { t, lang } = useTranslation();
const router = useRouter();
const { locale } = router;
const { appealtypes } = router.query;
const { appealType, LPAData } = props;
return (
<div>
<Head>
<title>
{t("search:page-title")} - {t("common:service-name")}
</title>
</Head>
<div id="page_wrapper">
<CookieBanner />
<Header courseName={t("common:service-name")} />
<div className="govuk-grid-row">
<div className="govuk-grid-column-full">
<div className="govuk-width-container">
<Banner />
<Breadcrumbs slug={appealtypes} />
<main
className="govuk-main-wrapper--auto-spacing"
id="main-content"
role="main"
>
<div className="govuk-grid-row">
<div className="govuk-grid-column-two-thirds">
<h1>Change password</h1>
<ChangePassword props={props} />
</div>
</div>
</main>
</div>
</div>
</div>
<Footer footerLinks={footerLinks} />
</div>
</div>
);
};
export const getServerSideProps = wrapper.getServerSideProps(
(store) =>
async ({ query, req, res }) => {
const appealTypeData = await getAppealsTypes();
const lpaData = await getLPA();
console.log("appeal types", appealTypeData);
console.log("lpa typeswwwww", lpaData);
store.dispatch(setAppealType(appealTypeData));
store.dispatch(setLPA(lpaData));
}
);
const mapStateToProps = (state) => {
return {
search: state.search,
searchResultsObj: state.searchResultsObj,
formData: state.formData,
appealType: state.appealType,
LPAData: state.LPAData,
form: state.form,
};
};
export default connect(mapStateToProps)(Home);
+94
View File
@@ -0,0 +1,94 @@
import Link from "next/link";
import _ from "lodash";
import Head from "next/head";
import Header from "../../components/header";
import Banner from "../../components/banner";
import CookieBanner from "../../components/cookieBanner";
import Breadcrumbs from "../../components/breadcrumbs";
import Footer from "../../components/footer";
import { useSelector, shallowEqual, connect } from "react-redux";
import { wrapper } from "../../store/store";
import Cookies from "cookies";
import { useRouter } from "next/router";
import { useState } from "react";
import useTranslation from "next-translate/useTranslation";
import jsonpath from "jsonpath";
import { reduxForm, formValueSelector } from "redux-form";
import PersonalDetails from "../../components/account/personaldetails";
import xpath from "xpath";
import { setAccountDetails } from "../../store/accountDetails/action";
import { getPersonalAccount } from "../../actions";
import { setLPA } from "../../store/lpa/action";
const Home = (props) => {
const { footerLinks, formData } = props;
let { t, lang } = useTranslation();
const router = useRouter();
const { locale } = router;
const { appealtypes } = router.query;
const { appealType, LPAData } = props;
return (
<div>
<Head>
<title>
{t("search:page-title")} - {t("common:service-name")}
</title>
</Head>
<div id="page_wrapper">
<CookieBanner />
<Header courseName={t("common:service-name")} />
<div className="govuk-grid-row">
<div className="govuk-grid-column-full">
<div className="govuk-width-container">
<Banner />
<Breadcrumbs slug={appealtypes} />
<main
className="govuk-main-wrapper--auto-spacing"
id="main-content"
role="main"
>
<div className="govuk-grid-row">
<div className="govuk-grid-column-two-thirds">
<h1>Your account</h1>
<PersonalDetails props={props} />
</div>
</div>
</main>
</div>
</div>
</div>
<Footer footerLinks={footerLinks} />
</div>
</div>
);
};
export const getServerSideProps = wrapper.getServerSideProps(
(store) =>
async ({ query, req, res }) => {
const accountDetails = await getPersonalAccount();
console.log("perosnal: ", accountDetails);
store.dispatch(setAccountDetails(accountDetails));
}
);
const mapStateToProps = (state) => {
return {
search: state.search,
searchResultsObj: state.searchResultsObj,
formData: state.formData,
appealType: state.appealType,
LPAData: state.LPAData,
form: state.form,
accountDetails: state.accountDetails,
};
};
export default connect(mapStateToProps)(Home);
+152
View File
@@ -0,0 +1,152 @@
import Link from "next/link";
import _ from "lodash";
import Head from "next/head";
import Header from "../../components/header";
import Banner from "../../components/banner";
import CookieBanner from "../../components/cookieBanner";
import Breadcrumbs from "../../components/breadcrumbs";
import Footer from "../../components/footer";
import { useSelector, shallowEqual, connect } from "react-redux";
import { wrapper } from "../../store/store";
import Cookies from "cookies";
import { useRouter } from "next/router";
import { useState } from "react";
import useTranslation from "next-translate/useTranslation";
import jsonpath from "jsonpath";
import { reduxForm, formValueSelector } from "redux-form";
import RegisterForm from "../../components/account/registerform";
import xpath from "xpath";
import {
setAppealType,
setAppealTypeTitle,
setAppealTypeID,
setAppealLPA,
getAppealTypeObj,
} from "../../store/appealType/action";
import { getAppealsTypes, getLPA } from "../../actions";
import { setLPA } from "../../store/lpa/action";
const Home = (props) => {
const { footerLinks, pages, formData } = props;
let { t, lang } = useTranslation();
const router = useRouter();
const { locale } = router;
const { appealtypes } = router.query;
const { appealType, LPAData } = props;
return (
<div>
<Head>
<title>
{t("search:page-title")} - {t("common:service-name")}
</title>
</Head>
<div id="page_wrapper">
<CookieBanner />
<Header courseName={t("common:service-name")} />
<div className="govuk-grid-row">
<div className="govuk-grid-column-full">
<div className="govuk-width-container">
<Banner />
<Breadcrumbs slug={appealtypes} />
<main
className="govuk-main-wrapper--auto-spacing"
id="main-content"
role="main"
>
<div className="govuk-grid-row">
<div className="govuk-grid-column-two-thirds">
<h1>Create a new account</h1>
<RegisterForm props={props} />
</div>
<div className="govuk-grid-column-one-third">
<h2 className="govuk-heading-m">
Help
</h2>
<h3>
Companies or submissions by more
than one individual (groups)
</h3>
<p className="govuk-body">
If you are submitting an appeal or
representation from a company e.g.
&quot;Acme Inc&quot; or a group of
people e.g. &quot;Residents of 1-10
High street&quot;, you should enter
the name of the company or group in
the Company/Group field. You will be
deemed as acting as their
representative.
</p>
<h3>
Enforcement appeals by married/civil
partnership couples
</h3>
<p className="govuk-body">
You should not enter a group name.
You need only enter your
partner&apos;s name on the appeal
form itself as an additional
appellant.
</p>
<h3>
Other appeals by married/civil
partnership couples
</h3>
<p className="govuk-body">
For any other type of appeal, for
example a planning appeal, you
should enter a group name when
creating your account e.g. &quot;Mr
and Mrs Smith&quot;, if that is the
name on the application.
</p>
</div>
</div>
</main>
</div>
</div>
</div>
<Footer footerLinks={footerLinks} />
</div>
</div>
);
};
export const getServerSideProps = wrapper.getServerSideProps(
(store) =>
async ({ query, req, res }) => {
const appealTypeData = await getAppealsTypes();
const lpaData = await getLPA();
console.log("appeal types", appealTypeData);
console.log("lpa typeswwwww", lpaData);
store.dispatch(setAppealType(appealTypeData));
store.dispatch(setLPA(lpaData));
}
);
const mapStateToProps = (state) => {
return {
search: state.search,
searchResultsObj: state.searchResultsObj,
formData: state.formData,
appealType: state.appealType,
LPAData: state.LPAData,
form: state.form,
};
};
export default connect(mapStateToProps)(Home);
+17
View File
@@ -0,0 +1,17 @@
const ApiResponse = (req, res) => {
res.statusCode = 200;
res.json({
data: {
firstname: "Steve",
lastname: "Johnson",
email: "steve@test.co.uk",
telephone: "0000000000",
companygroup: "Test Company",
addressline1: "1 Test Street",
towncity: "TestTown",
county: "Test County",
postcode: "TN12 12N",
},
});
};
export default ApiResponse;
+11 -10
View File
@@ -111,15 +111,15 @@ let Home = (props) => {
<div id="page_wrapper">
<CookieBanner />
<Header courseName={t("common:service-name")} />
<main
className="govuk-main-wrapper govuk-main-wrapper--auto-spacing"
id="main-content"
role="main"
>
<div className="govuk-width-container">
<Banner />
<Breadcrumbs slug={appealtypes} formTitle={formTitle} />
<div className="govuk-width-container">
<Banner />
<Breadcrumbs slug={appealtypes} formTitle={formTitle} />
<main
className="govuk-main-wrapper--auto-spacing"
id="main-content"
role="main"
>
{props.appealType.currentSection == 9999 ? (
<CompleteAppeal />
) : props.appealType.currentSection ==
@@ -141,8 +141,9 @@ let Home = (props) => {
props={props}
/>
)}
</div>
</main>
</main>
</div>
<Footer footerLinks={footerLinks} />
</div>
</div>
+13 -12
View File
@@ -49,26 +49,27 @@ const Home = (props) => {
<div id="page_wrapper">
<CookieBanner />
<Header courseName={t("common:service-name")} />
<main
className="govuk-main-wrapper govuk-main-wrapper--auto-spacing"
id="main-content"
role="main"
>
<div className="govuk-grid-row">
<div className="govuk-grid-column-full">
<div className="govuk-width-container">
<Banner />
<Breadcrumbs slug={appealtypes} />
<div className="govuk-grid-row">
<div className="govuk-grid-column-full">
<div className="govuk-width-container">
<Banner />
<Breadcrumbs slug={appealtypes} />
<main
className="govuk-main-wrapper--auto-spacing"
id="main-content"
role="main"
>
<h1>New Appeal</h1>
<CreateCase
LPAData={props.LPAData}
appealType={props.setAppealType}
/>
</div>
</main>
</div>
</div>
</main>
</div>
<Footer footerLinks={footerLinks} />
</div>
</div>
+17
View File
@@ -0,0 +1,17 @@
export const AccountDetailsDataActionTypes = {
GETACCOUNTDETAILSDATA: "GETACCOUNTDETAILSDATA",
SETACCOUNTDETAILSDATA: "SETACCOUNTDETAILSDATA",
};
export const getAccountDetailsObj = () => (dispatch) => {
return dispatch({
type: AccountDetailsDataActionTypes.GETACCOUNTDETAILSDATA,
});
};
export const setAccountDetails = (accountDetails) => (dispatch) => {
return dispatch({
type: AccountDetailsDataActionTypes.SETACCOUNTDETAILSDATA,
accountDetails: accountDetails,
});
};
+20
View File
@@ -0,0 +1,20 @@
import { AccountDetailsDataActionTypes } from "./action";
const AccountDetailsDataInitialState = {
accountDetails: {},
};
export default function reducer(
state = AccountDetailsDataInitialState,
action
) {
switch (action.type) {
case AccountDetailsDataActionTypes.SETACCOUNTDETAILSDATA:
return {
...state,
accountDetails: action.accountDetails,
};
default:
return state;
}
}
+4 -1
View File
@@ -6,6 +6,7 @@ import searchResultsObj from "./searchOutput/reducer";
import formData from "./formData/reducer";
import appealType from "./appealType/reducer";
import LPAData from "./lpa/reducer";
import accountDetails from "./accountDetails/reducer";
import { reducer as formReducer } from "redux-form";
import autoMergeLevel2 from "redux-persist/lib/stateReconciler/autoMergeLevel2";
@@ -16,6 +17,7 @@ const combinedReducer = combineReducers({
formData,
appealType,
LPAData,
accountDetails,
form: formReducer,
});
@@ -81,8 +83,9 @@ const makeStore = ({ isServer }) => {
"searchResults",
"formData",
"appealType",
"form",
"LPAData",
"accountDetails",
"form",
],
storage,
stateReconciler: autoMergeLevel2, // if needed, use a safer storage
+2 -2
View File
@@ -22,7 +22,7 @@
}
&.card-3 {
flex-basis: 44%;
flex-basis: 46%;
min-height: 300px;
// &:nth-child(3n-1) {
@@ -41,7 +41,7 @@
margin-left: 3%;
}
&.card-3 {
flex-basis: 31%;
flex-basis: 31.1%;
min-height: 300px;
&:nth-child(2n-2) {
+107 -4
View File
@@ -106,6 +106,109 @@ a {
color: #fff;
box-shadow: none;
}
//nav drop down
.mobileNav {
display: none;
@media screen and (max-width: 900px) {
display: block;
position: relative;
clear: both;
margin-top: 40px;
margin-right: -10px;
.mobileMenu {
float: left;
position: relative;
}
.mobileMenu label {
background-color: black;
padding: 10px 30px;
cursor: pointer;
text-align: center;
display: block;
position: relative;
}
.mobileMenu label i {
font-style: normal;
font-size: 10px;
color: white;
position: absolute;
right: 18px;
top: 13px;
}
.mobileMenu [type="radio"] {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
margin: 0;
z-index: 1;
}
.content {
position: absolute;
top: 100%;
opacity: 0;
background: #333;
color: white;
padding: 20px 10px;
width: 140px;
right: 0px;
}
.content ul {
margin: 0;
padding: 0;
list-style: none;
}
.content a {
color: white;
display: block;
white-space: nowrap;
text-decoration: none;
border-bottom: 1px solid #999;
padding: 5px;
padding: 20px 10px;
&.govuk-header__link {
background-color: inherit;
}
}
[type="radio"]:checked ~ label {
z-index: 2;
}
[type="radio"]:checked ~ label ~ .content {
z-index: 1;
opacity: 1;
}
.close-mobileMenu {
position: absolute;
z-index: -1;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.close-mobileMenu label {
background: #333;
color: white;
}
[type="radio"]:checked ~ label ~ .close-mobileMenu {
z-index: 3;
}
}
}
.fullNav {
display: block;
@media screen and (max-width: 900px) {
display: none;
}
}
}
.header__logo {
@@ -126,10 +229,10 @@ a {
width: 22% !important;
}
nav {
// margin-top: 60px;
// margin-bottom: 40px;
}
// nav {
// // margin-top: 60px;
// // margin-bottom: 40px;
// }
.govuk-footer {
padding-top: 0px;