Skip to content

Commit

Permalink
Merge pull request #293 from usagov/stage
Browse files Browse the repository at this point in the history
Sprint 66 release to MAIN
  • Loading branch information
rayestrada authored Aug 27, 2024
2 parents 92622ef + 0bc6a7c commit 8ff09c0
Show file tree
Hide file tree
Showing 37 changed files with 306 additions and 173 deletions.
Binary file added data/Federal_Voter_Registration_en.pdf
Binary file not shown.
File renamed without changes.
File renamed without changes.
61 changes: 61 additions & 0 deletions data/navigation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"back": {
"vote": "Go back to Vote.gov",
"select_state": "Go back to select your state",
"state_reg_options": "Go back to state registration options",
"eligibility_req": "Back to state eligibility requirements",
"reg_options": "Back to registration options",
"personal_info": "Back to personal information",
"address_location": "Back to address and location",
"identification": "Back to identification",
"edit_info": "Edit registration information"
},
"next": {
"next": "Next",
"start": "Continue to the digital form filler on vote.gov",
"reg_options": "Continue to view registration options",
"address_location": "Continue to address and location",
"identification": "Continue to identification",
"political_party": "Continue to political party",
"confirm_info": "Continue to review your information"
},
"step_label_1": "Personal information",
"step_label_2": "Address and location",
"step_label_3": "Identification",
"step_label_4": "Political party",
"step_label_5": "Confirm your information",
"step_label_6": "Print your completed form",
"confirmation": {
"current_name": {
"label": "Current name"
},
"previous_name": {
"label": "Previous name",
"alert": "You have not changed your name, so these fields are blank."
},
"other_info": {
"label": "Other information"
},
"current_address": {
"label": "Home address",
"alert": "You are not registering with a current address, so these fields are blank."
},
"previous_address": {
"label": "Previous address",
"alert": "You are not registering with a change of address, so these fields are blank."
},
"mailing_address": {
"label": "Mailing address",
"alert": "Your mailing address is the same as your home address, so these fields are left blank."
},
"id_label": {
"label": "ID number"
},
"political_party": {
"label": "Political party"
},
"edit": {
"label": "Edit"
}
}
}
33 changes: 33 additions & 0 deletions data/strings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"notRequired": "Not required for your state",
"newWindow": "Go to your state's PDF form in a new tab",
"newTab": "Print your mail-in form in a new tab",
"nameChange": "I have legally changed my name since I last registered in this state.",
"dob": "Date of Birth",
"month": "Month",
"day": "Day",
"year": "Year",
"stateName": "Go to the PDF form on @state_name's website",
"checkReg": "Check your registration",
"checkRegWY": "Find your local office to check your registration",
"learnMore": "Learn more about your voting options",
"backBtn": "Back to Vote.gov",
"backIcon": "back arrow icon",
"forwardIcon": "forward arrow icon",
"stateOnlineName": "Register on @state_name's website",
"confirm": "Confirm and continue",
"selectState": "Select your state or territory",
"selectStateAriaLabel": "State selection dropdown menu",
"lastUpdated": "@state_name information last updated ",
"privacyPolicy": "Privacy policy",
"extlink": "External link opens new window",
"emailLabel": "Voter Contact",
"emailHint": "For example: [email protected]",
"select": "- Select -",
"download": "Download your mail-in form",
"downloadText": "If form does not open in a new tab you can download using the option below.",
"mailDeadlineLabel": "Mail-in registration deadline:",
"inPersonBtn": "Learn more on @state_name's election website",
"inPersonBtnWY": "Find in-person registration locations",
"idSelectionAriaLabel": "Choose identification type"
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ <h2>Sign in</h2>
<section class="usa-section grid-container">

<!-- Embedded REACT app -->
<div class="nvrf-app-container" data-stateId="al" id="root"></div>
<div class="nvrf-app-container" data-privacyPath="https://vote.gov/" data-returnPath='https://vote.gov/register/alabama' data-stateId="al" id="root"></div>
<script type="module" src="/src/main.jsx"></script>

</section>
Expand Down
1 change: 1 addition & 0 deletions nvrf/assets/cards.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"uuid":"0ac52b5d-4381-4b4e-830e-38319f3a3757","lang":"en","heading":"I am already registered in @state_name and need to change my information.","body":"\u003Cp\u003EReport a change to registration information, such as name, address, or political party.\u003C\/p\u003E","button_label":"Change registration information","image_url":""},{"uuid":"3abd804c-2787-44f9-a06b-ad6d63ca797f","lang":"en","heading":"I am registering in @state_name for the first time.","body":"\u003Cp\u003ERegister for the first time in this state. We recommend having your driver\u2019s license or non-driver identification number available.\u003C\/p\u003E","button_label":"Begin new registration","image_url":""}]
1 change: 1 addition & 0 deletions nvrf/assets/fields.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions nvrf/assets/pages.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions nvrf/assets/states.json

Large diffs are not rendered by default.

Binary file removed public/files/Federal_Voter_Registration_ENG.pdf
Binary file not shown.
8 changes: 7 additions & 1 deletion public/theme/assets/styles/nvrf.css
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,13 @@
padding-bottom: .5rem;
}

.nvrf-app-container .usa-step-indicator__segment--complete {
.nvrf-app-container .step-indicator-no-select {
&:focus {
outline: none;
}
}

.nvrf-app-container .step-indicator-select {
cursor: pointer;
background-color: transparent;
color: transparent;
Expand Down
17 changes: 11 additions & 6 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { useState, useEffect } from 'react'
import Eligibility from 'Views/Eligibility.jsx';
import PathSelection from 'Views/PathSelection.jsx';
import MultiStepForm from 'Views/MultiStepForm.jsx';
import {fetchData, sanitizeDOM} from 'Utils/JsonHelper.jsx';
import {fetchData, fetchStaticData, sanitizeDOM} from 'Utils/JsonHelper.jsx';
import { HelmetProvider } from "react-helmet-async";
import {getFieldValue} from "Utils/fieldParser.jsx";

const currentStateId = document.getElementById('root').getAttribute('data-stateId');
const returnPath = document.getElementById('root').getAttribute('data-returnPath');
const privacyPath = document.getElementById('root').getAttribute('data-privacyPath');

function App() {
const [states, setStates] = useState('');
Expand All @@ -19,10 +21,10 @@ function App() {
useEffect(() => {
fetchData("states.json", setStates);
fetchData("pages.json", setContent);
fetchData("navigation.json", setNavContent);
fetchData("cards.json", setCards);
fetchData("fields.json", setFieldContent);
fetchData("strings.json", setStringContent)
fetchStaticData("navigation.json", setNavContent);
fetchStaticData("strings.json", setStringContent)
}, []);

useEffect(() => {
Expand Down Expand Up @@ -95,7 +97,7 @@ function App() {

return (
<HelmetProvider>
<section className="usa-prose">
<section>
<a name="scroll-to-top"
id="scroll-to-top"
tabIndex={-1}
Expand All @@ -117,6 +119,7 @@ function App() {
fieldContent={fieldContent}
hasConfirmed={hasConfirmed}
confirmCheckbox={confirmCheckbox}
returnPath={returnPath}
/>}
{step === 2 &&
<PathSelection
Expand Down Expand Up @@ -146,13 +149,15 @@ function App() {
/>}

{step >= 1 &&
<div className="text-base usa-prose margin-top-5 maxw-tablet margin-x-auto">
<div className="text-base margin-top-5 maxw-tablet margin-x-auto">
<p>{getFieldValue(content, "2c597df4-53b6-4ef5-8301-7817b04e1099", "omb_number")}
<br/>
{lastUpdatedText.replace("@state_name", stateData.name)}
<span dangerouslySetInnerHTML= {{__html: lastUpdatedSanitized}}/>
</p>
<p><a href="privacy" target="_blank">{stringContent.privacyPolicy}</a></p>
{privacyPath && (
<p><a href={privacyPath} target="_blank">{stringContent.privacyPolicy}</a></p>
)}
</div>
}
</section>
Expand Down
2 changes: 1 addition & 1 deletion src/Components/Buttons/NextButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ function NextButton(props) {

return (
<>
<Button className={props.noMarginTop ? 'next-button mobile-width' : 'next-button mobile-width margin-top-5'} data-test="nextBtn" type={props.type} onClick={props.onClick}>
<Button className={'next-button mobile-width'} data-test="nextBtn" type={props.type} onClick={props.onClick}>
<span>{props.text}</span>
<Icon.ArrowForward aria-label={props.stringContent.forwardIcon} style={{margin: "-3px -3px -3px 4px"}}/>
</Button>
Expand Down
16 changes: 10 additions & 6 deletions src/Components/FieldContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,17 @@ function FieldContainer({ fieldType, inputData, saveFieldData, fieldData, string
<Label className="text-bold" htmlFor={inputData.id}>
{inputData.label}{(parseInt(inputData.required) === 1) && <span>*</span>}
</Label>
<span className="usa-hint" id={`${inputData.id}` + '-hint'}>
{inputData.help_text}
</span>
{inputData.help_text && (
<span className="usa-hint" id={`${inputData.id}-hint`}>
{inputData.help_text}
</span>
)}
{renderField(fieldType)}
<span id={`${inputData.id}` + '_error'} role="alert" className={'error-text'} data-test="errorText">
{inputData.error_msg}
</span>
{inputData.error_msg && (
<span id={`${inputData.id}` + '_error'} role="alert" className={'error-text'} data-test="errorText">
{inputData.error_msg}
</span>
)}
</div>
</>
)
Expand Down
3 changes: 1 addition & 2 deletions src/Components/Fields/CurrentSuffix.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {getField} from "Utils/fieldParser";
function CurrentSuffix(props){
const uuid = "eeff4fa1-00f2-474b-a791-1a4146dab11a";
const field = getField(props.fieldContent, uuid);
const stateField = getField(props.stateData.nvrf_fields, field.uuid);

return (
<FieldContainer
Expand All @@ -15,7 +14,7 @@ function CurrentSuffix(props){
required: "0",
label: field.label,
options: field.options,
value: stateField.value,
value:props.fieldData['suffix'],
}} saveFieldData={props.saveFieldData} fieldData={props.fieldData} stringContent={props.stringContent} />
)
}
Expand Down
2 changes: 1 addition & 1 deletion src/Components/Fields/CurrentTitle.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {getField} from "Utils/fieldParser";
function CurrentTitle(props){
const uuid = "86a544cd-cfe9-456a-b634-176a37a38d6d";
const field = getField(props.fieldContent, uuid);
const stateField = getField(props.stateData.nvrf_fields, field.uuid);

return (
<FieldContainer
Expand All @@ -17,6 +16,7 @@ function CurrentTitle(props){
options: field.options,
error_msg: field.error_msg,
help_text: field.help_text,
value:props.fieldData['title'],
}} saveFieldData={props.saveFieldData} fieldData={props.fieldData} stringContent={props.stringContent}/>
)
}
Expand Down
21 changes: 21 additions & 0 deletions src/Components/Fields/PreviousSuffix.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from "react";
import FieldContainer from 'Components/FieldContainer';
import {getField} from "Utils/fieldParser";

function PreviousSuffix(props){
const uuid = "09cb2989-d302-4a01-bb3a-33173adcffb2";
const field = getField(props.fieldContent, uuid);
return (
<FieldContainer
fieldType={'select'} inputData={{
id: 'prev_suffix',
dataTest: 'select',
required: "0",
label: field.label,
options: field.options,
value:props.fieldData['prev_suffix'],
}} saveFieldData={props.saveFieldData} fieldData={props.fieldData} stringContent={props.stringContent}/>
)
}

export default PreviousSuffix;
1 change: 1 addition & 0 deletions src/Components/Fields/PreviousTitle.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ function PreviousTitle(props){
options: field.options,
error_msg: field.error_msg,
help_text: field.help_text,
value:props.fieldData['prev_title'],
}} saveFieldData={props.saveFieldData} fieldData={props.fieldData} stringContent={props.stringContent}/>
)
}
Expand Down
23 changes: 23 additions & 0 deletions src/Components/Fields/RaceEthnicity.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from "react";
import FieldContainer from 'Components/FieldContainer';
import {getField} from "Utils/fieldParser";

function RaceEthnicity(props){
const uuid = "2bfff6c6-6782-4b14-ac45-642efd278f6a";
const field = getField(props.fieldContent, uuid);
const stateField = getField(props.stateData.nvrf_fields, field.uuid);
return (
<FieldContainer
fieldType={'select'} inputData={{
id: 'race',
dataTest: 'select',
required: stateField.required,
label: field.label,
options: field.options,
value:props.fieldData['race'],
error_msg: field.error_msg,
}} saveFieldData={props.saveFieldData} fieldData={props.fieldData} stringContent={props.stringContent}/>
)
}

export default RaceEthnicity;
28 changes: 28 additions & 0 deletions src/Components/Fields/SSNFull.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from "react";
import FieldContainer from 'Components/FieldContainer';
import {getField} from "Utils/fieldParser";

function SSNFull(props){
const uuid = "fe8cf91e-f872-4ed7-848c-09c99a7d83c8";
const field = getField(props.fieldContent, uuid);
const stateField = getField(props.stateData.nvrf_fields, field.uuid);

return (
<FieldContainer
fieldType={'text'} inputData={{
id: 'ssn_number',
dataTest: 'ssn',
label: field.label,
required: stateField.required,
error_msg: field.error_msg,
help_text: field.help_text,
type: 'numeric',
inputMode: 'number',
maxLength: 9,
minLength: 9,
check: 'check value length',
}} saveFieldData={props.saveFieldData} fieldData={props.fieldData}/>
)
}

export default SSNFull;
47 changes: 21 additions & 26 deletions src/Components/ProgressBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,36 +25,31 @@ function ProgressBar(props) {

const setStep = props.setStep;

const finalStep = Object.keys(stepMessage).length;

const styles = (step) => {
if (props.step < finalStep && stepProgress(step) === "complete") {
return "step-indicator-select"
}
return "step-indicator-no-select";
}

return (
<>
<div aria-live="polite" aria-atomic="true" className="usa-sr-only">{currentStepMessage}</div>
<StepIndicator centered className="margin-top-4" headingLevel="h2">
<StepIndicatorStep label={props.content.step_label_1} status={stepProgress(1)}
tabIndex={stepProgress(1) === "complete" ? 0 : null}
onKeyDown={(e) => {if (e.key === "Enter" && stepProgress(1) === "complete") {setStep(1)}}}
onClick={stepProgress(1) === "complete" ? handleGoBackSteps(props.step - 1) : null}/>

<StepIndicatorStep label={props.content.step_label_2} status={stepProgress(2)}
tabIndex={stepProgress(2) === "complete" ? 0 : null}
onKeyDown={(e) => {if (e.key === "Enter" && stepProgress(2) === "complete") {setStep(2)}}}
onClick={stepProgress(2) === "complete" ? handleGoBackSteps(props.step - 2) : null}/>

<StepIndicatorStep label={props.content.step_label_3} status={stepProgress(3)}
tabIndex={stepProgress(3) === "complete" ? 0 : null}
onKeyDown={(e) => {if (e.key === "Enter" && stepProgress(3) === "complete") {setStep(3)}}}
onClick={stepProgress(3) === "complete" ? handleGoBackSteps(props.step - 3) : null}/>

<StepIndicatorStep label={props.content.step_label_4} status={stepProgress(4)}
tabIndex={stepProgress(4) === "complete" ? 0 : null}
onKeyDown={(e) => {if (e.key === "Enter" && stepProgress(4) === "complete") {setStep(4)}}}
onClick={stepProgress(4) === "complete" ? handleGoBackSteps(props.step - 4) : null}/>

<StepIndicatorStep label={props.content.step_label_5} status={stepProgress(5)}
tabIndex={stepProgress(5) === "complete" ? 0 : null}
onKeyDown={(e) => {if (e.key === "Enter" && stepProgress(5) === "complete") {setStep(5)}}}
onClick={stepProgress(5) === "complete" ? handleGoBackSteps(props.step - 5) : null}/>

<StepIndicatorStep label={props.content.step_label_6} status={stepProgress(6)}/>

{Object.keys(stepMessage)
.map((step) => parseInt(step)) // step is originally a string, so convert to int
.map((step) => (

<StepIndicatorStep key={step} className={styles(step)} label={props.content[`step_label_${step}`]} status={stepProgress(step)}
tabIndex={stepProgress(step) === "complete" ? 0 : null}
onKeyDown={(e) => {if (e.key === "Enter" && stepProgress(step) === "complete") {setStep(step)}}}
onClick={stepProgress(step) === "complete" && props.step !== finalStep ? handleGoBackSteps(props.step - step) : null}/>

))}

</StepIndicator>
</>
);
Expand Down
Loading

0 comments on commit 8ff09c0

Please sign in to comment.