From 3a70ecd82ea1e0fd9041bd3f2583e4f740e6d98e Mon Sep 17 00:00:00 2001 From: Mayank Bansal Date: Tue, 4 Nov 2025 05:09:22 +0530 Subject: [PATCH 1/9] feat: add new step two for introduction --- .../new-join-steps/new-step-two.hbs | 48 ++++++++ app/components/new-join-steps/new-step-two.js | 108 ++++++++++++++++++ app/components/new-stepper.hbs | 7 ++ app/constants/new-join-form.js | 11 +- 4 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 app/components/new-join-steps/new-step-two.hbs create mode 100644 app/components/new-join-steps/new-step-two.js diff --git a/app/components/new-join-steps/new-step-two.hbs b/app/components/new-join-steps/new-step-two.hbs new file mode 100644 index 00000000..b91320a1 --- /dev/null +++ b/app/components/new-join-steps/new-step-two.hbs @@ -0,0 +1,48 @@ +
+
+

{{this.heading}}

+

{{this.subHeading}}

+
+ + + {{#if this.errorMessage.skills}} +
{{this.errorMessage.skills}}
+ {{/if}} + + + {{#if this.errorMessage.company}} +
{{this.errorMessage.company}}
+ {{/if}} + + + +
0/500 words
+ {{!--

Share your background, experiences, and what drives you (100-500 words)

--}} + + {{#if this.errorMessage.introduction}} +
{{this.errorMessage.introduction}}
+ {{/if}} +
\ No newline at end of file diff --git a/app/components/new-join-steps/new-step-two.js b/app/components/new-join-steps/new-step-two.js new file mode 100644 index 00000000..fc5a8720 --- /dev/null +++ b/app/components/new-join-steps/new-step-two.js @@ -0,0 +1,108 @@ +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; +import { action } from '@ember/object'; +import { validator } from '../../utils/validator'; +import { debounce } from '@ember/runloop'; +import { JOIN_DEBOUNCE_TIME } from '../../constants/join'; +import { NEW_FORM_STEPS, NEW_STEP_LIMITS } from '../../constants/new-join-form'; + +export default class NewStepTwoComponent extends Component { + @tracked data = JSON.parse(localStorage.getItem('newStepTwoData')) ?? { + skills: '', + company: '', + introduction: '', + }; + + @tracked errorMessage = { + skills: '', + company: '', + introduction: '', + }; + + heading = NEW_FORM_STEPS.headings[this.currentStep - 1]; + subHeading = NEW_FORM_STEPS.subheadings[this.currentStep - 1]; + + isValid; + setIsValid; + setIsPreValid; + + constructor(...args) { + super(...args); + this.isValid = this.args.isValid; + this.setIsValid = this.args.setIsValid; + this.setIsPreValid = this.args.setIsPreValid; + const validated = this.isDataValid(); + localStorage.setItem('isValid', validated); + this.setIsPreValid(validated); + } + + isDataValid() { + for (let field in this.data) { + if (field === 'introduction') { + const wordCount = this.data[field].trim().split(/\s+/).length; + if ( + wordCount < NEW_STEP_LIMITS.stepTwo.introduction.min || + wordCount > NEW_STEP_LIMITS.stepTwo.introduction.max + ) { + return false; + } + } else { + const { isValid } = validator( + this.data[field], + NEW_STEP_LIMITS.stepTwo[field], + ); + if (!isValid) { + return false; + } + } + } + return true; + } + + @action inputHandler(e) { + this.setIsPreValid(false); + + const setValToLocalStorage = () => { + this.data = { ...this.data, [e.target.name]: e.target.value }; + localStorage.setItem('newStepTwoData', JSON.stringify(this.data)); + + const field = e.target.name; + if (field === 'introduction') { + const wordCount = this.data[field].trim().split(/\s+/).length; + if (wordCount < NEW_STEP_LIMITS.stepTwo.introduction.min) { + this.errorMessage = { + ...this.errorMessage, + [field]: `At least ${NEW_STEP_LIMITS.stepTwo.introduction.min - wordCount} more word(s) required`, + }; + } else if (wordCount > NEW_STEP_LIMITS.stepTwo.introduction.max) { + this.errorMessage = { + ...this.errorMessage, + [field]: `Maximum ${NEW_STEP_LIMITS.stepTwo.introduction.max} words allowed`, + }; + } else { + this.errorMessage = { + ...this.errorMessage, + [field]: '', + }; + } + } else { + const { isValid, remainingWords } = validator( + this.data[field], + NEW_STEP_LIMITS.stepTwo[field], + ); + this.errorMessage = { + ...this.errorMessage, + [field]: isValid + ? '' + : `At least, ${remainingWords} more word(s) required`, + }; + } + + const isAllValid = this.isDataValid(); + this.setIsValid(isAllValid); + localStorage.setItem('isValid', isAllValid); + }; + + debounce(this.data, setValToLocalStorage, JOIN_DEBOUNCE_TIME); + } +} diff --git a/app/components/new-stepper.hbs b/app/components/new-stepper.hbs index 9c6ae4de..594581df 100644 --- a/app/components/new-stepper.hbs +++ b/app/components/new-stepper.hbs @@ -30,6 +30,13 @@ @isValid={{this.isValid}} @setIsValid={{this.setIsValid}} /> + + {{else if (eq this.currentStep 2)}} + {{/if}} diff --git a/app/constants/new-join-form.js b/app/constants/new-join-form.js index 6911a135..dd38e2d4 100644 --- a/app/constants/new-join-form.js +++ b/app/constants/new-join-form.js @@ -1,7 +1,11 @@ export const NEW_FORM_STEPS = { - headings: ['Upload Professional Headshot and Complete Personal Details'], + headings: [ + 'Upload Professional Headshot and Complete Personal Details', + 'More personal details please', + ], subheadings: [ 'Please provide accurate information for verification purposes.', + 'Introduce and help us get to know you better', ], }; @@ -21,6 +25,11 @@ export const NEW_STEP_LIMITS = { city: { min: 1 }, role: { min: 1 }, }, + stepTwo: { + skills: 5, + company: 1, + introduction: { min: 100, max: 500 }, + }, }; export const STEP_DATA_STORAGE_KEY = { From 4e9fe8a3b0d6d3ba6945a37a092002589916ba5b Mon Sep 17 00:00:00 2001 From: Mayank Bansal Date: Tue, 4 Nov 2025 15:09:39 +0530 Subject: [PATCH 2/9] feat: add step three for interests --- .../new-join-steps/new-step-three.hbs | 38 ++++++++ .../new-join-steps/new-step-three.js | 90 +++++++++++++++++++ .../new-join-steps/new-step-two.hbs | 86 +++++++++--------- app/components/new-join-steps/new-step-two.js | 62 +++++++------ app/components/new-stepper.hbs | 7 ++ app/constants/new-join-form.js | 6 ++ 6 files changed, 220 insertions(+), 69 deletions(-) create mode 100644 app/components/new-join-steps/new-step-three.hbs create mode 100644 app/components/new-join-steps/new-step-three.js diff --git a/app/components/new-join-steps/new-step-three.hbs b/app/components/new-join-steps/new-step-three.hbs new file mode 100644 index 00000000..8ab34a1c --- /dev/null +++ b/app/components/new-join-steps/new-step-three.hbs @@ -0,0 +1,38 @@ +
+

{{this.heading}}

+

{{this.subHeading}}

+
+ +
+
+

What do you do for fun? Your hobbies/interests?

+ +
{{this.wordCount.hobbies}}/{{this.maxWords.hobbies}} words
+ {{#if this.errorMessage.hobbies}} +
{{this.errorMessage.hobbies}}
+ {{/if}} +
+ +
+

Fun fact about you

+ +
{{this.wordCount.funFact}}/{{this.maxWords.funFact}} words
+ {{#if this.errorMessage.funFact}} +
{{this.errorMessage.funFact}}
+ {{/if}} +
+
\ No newline at end of file diff --git a/app/components/new-join-steps/new-step-three.js b/app/components/new-join-steps/new-step-three.js new file mode 100644 index 00000000..e8f57710 --- /dev/null +++ b/app/components/new-join-steps/new-step-three.js @@ -0,0 +1,90 @@ +import { action } from '@ember/object'; +import { debounce } from '@ember/runloop'; +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; +import { JOIN_DEBOUNCE_TIME } from '../../constants/join'; +import { NEW_FORM_STEPS, NEW_STEP_LIMITS } from '../../constants/new-join-form'; +import { validateWordCount } from '../../utils/validator'; + +export default class NewStepThreeComponent extends Component { + @tracked data = JSON.parse(localStorage.getItem('newStepThreeData')) ?? { + hobbies: '', + funFact: '', + }; + + @tracked errorMessage = { + hobbies: '', + funFact: '', + }; + + @tracked wordCount = { + hobbies: + this?.data?.hobbies?.trim()?.split(/\s+/).filter(Boolean).length || 0, + funFact: + this?.data?.funFact?.trim()?.split(/\s+/).filter(Boolean).length || 0, + }; + + maxWords = { + hobbies: NEW_STEP_LIMITS.stepThree.hobbies.max, + funFact: NEW_STEP_LIMITS.stepThree.funFact.max, + }; + + isValid; + setIsValid; + setIsPreValid; + + heading = NEW_FORM_STEPS.headings[2]; + subHeading = NEW_FORM_STEPS.subheadings[2]; + + constructor(...args) { + super(...args); + this.isValid = this.args.isValid; + this.setIsValid = this.args.setIsValid; + this.setIsPreValid = this.args.setIsPreValid; + const validated = this.isDataValid(); + localStorage.setItem('isValid', validated); + this.setIsPreValid(validated); + } + + isDataValid() { + for (let field in this.data) { + const { isValid } = validateWordCount( + this.data[field], + NEW_STEP_LIMITS.stepThree[field], + ); + if (!isValid) return false; + } + return true; + } + + @action inputHandler(e) { + this.setIsPreValid(false); + + const setValToLocalStorage = () => { + this.data = { ...this.data, [e.target.name]: e.target.value }; + localStorage.setItem('newStepThreeData', JSON.stringify(this.data)); + + // Only validate the changed field + const field = e.target.name; + const { isValid, wordCount, remainingToMin } = validateWordCount( + this.data[field], + NEW_STEP_LIMITS.stepThree[field], + ); + this.wordCount = { ...this.wordCount, [field]: wordCount }; + this.errorMessage = { + ...this.errorMessage, + [field]: isValid + ? '' + : remainingToMin + ? `At least, ${remainingToMin} more word(s) required` + : `Maximum ${NEW_STEP_LIMITS.stepThree[field].max} words allowed`, + }; + + const isAllValid = this.isDataValid(); + this.setIsValid(isAllValid); + localStorage.setItem('isValid', isAllValid); + }; + + debounce(this.data, setValToLocalStorage, JOIN_DEBOUNCE_TIME); + } +} diff --git a/app/components/new-join-steps/new-step-two.hbs b/app/components/new-join-steps/new-step-two.hbs index b91320a1..629b9d3f 100644 --- a/app/components/new-join-steps/new-step-two.hbs +++ b/app/components/new-join-steps/new-step-two.hbs @@ -1,48 +1,54 @@
-
-

{{this.heading}}

-

{{this.subHeading}}

-
- - - {{#if this.errorMessage.skills}} -
{{this.errorMessage.skills}}
- {{/if}} +
+

{{this.heading}}

+

{{this.subHeading}}

+
- - {{#if this.errorMessage.company}} -
{{this.errorMessage.company}}
- {{/if}} +
+
+ + {{#if this.errorMessage.skills}} +
{{this.errorMessage.skills}}
+ {{/if}} +
- + + /> + {{#if this.errorMessage.company}} +
{{this.errorMessage.company}}
+ {{/if}} +
+
-
0/500 words
- {{!--

Share your background, experiences, and what drives you (100-500 words)

--}} +

Please introduce yourself

+ +
{{this.wordCount.introduction}}/{{this.maxWords.introduction}} words
+

Share your background, experiences, and what drives you.

- {{#if this.errorMessage.introduction}} -
{{this.errorMessage.introduction}}
- {{/if}} + {{#if this.errorMessage.introduction}} +
{{this.errorMessage.introduction}}
+ {{/if}} \ No newline at end of file diff --git a/app/components/new-join-steps/new-step-two.js b/app/components/new-join-steps/new-step-two.js index fc5a8720..3f72b711 100644 --- a/app/components/new-join-steps/new-step-two.js +++ b/app/components/new-join-steps/new-step-two.js @@ -1,10 +1,10 @@ -import Component from '@glimmer/component'; -import { tracked } from '@glimmer/tracking'; import { action } from '@ember/object'; -import { validator } from '../../utils/validator'; import { debounce } from '@ember/runloop'; +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; import { JOIN_DEBOUNCE_TIME } from '../../constants/join'; import { NEW_FORM_STEPS, NEW_STEP_LIMITS } from '../../constants/new-join-form'; +import { validateWordCount, validator } from '../../utils/validator'; export default class NewStepTwoComponent extends Component { @tracked data = JSON.parse(localStorage.getItem('newStepTwoData')) ?? { @@ -19,8 +19,18 @@ export default class NewStepTwoComponent extends Component { introduction: '', }; - heading = NEW_FORM_STEPS.headings[this.currentStep - 1]; - subHeading = NEW_FORM_STEPS.subheadings[this.currentStep - 1]; + @tracked wordCount = { + introduction: + this?.data?.introduction?.trim()?.split(/\s+/).filter(Boolean).length || + 0, + }; + + maxWords = { + introduction: NEW_STEP_LIMITS.stepTwo.introduction.max, + }; + + heading = NEW_FORM_STEPS.headings[1]; + subHeading = NEW_FORM_STEPS.subheadings[1]; isValid; setIsValid; @@ -39,13 +49,11 @@ export default class NewStepTwoComponent extends Component { isDataValid() { for (let field in this.data) { if (field === 'introduction') { - const wordCount = this.data[field].trim().split(/\s+/).length; - if ( - wordCount < NEW_STEP_LIMITS.stepTwo.introduction.min || - wordCount > NEW_STEP_LIMITS.stepTwo.introduction.max - ) { - return false; - } + const { isValid } = validateWordCount( + this.data[field], + NEW_STEP_LIMITS.stepTwo.introduction, + ); + if (!isValid) return false; } else { const { isValid } = validator( this.data[field], @@ -68,23 +76,19 @@ export default class NewStepTwoComponent extends Component { const field = e.target.name; if (field === 'introduction') { - const wordCount = this.data[field].trim().split(/\s+/).length; - if (wordCount < NEW_STEP_LIMITS.stepTwo.introduction.min) { - this.errorMessage = { - ...this.errorMessage, - [field]: `At least ${NEW_STEP_LIMITS.stepTwo.introduction.min - wordCount} more word(s) required`, - }; - } else if (wordCount > NEW_STEP_LIMITS.stepTwo.introduction.max) { - this.errorMessage = { - ...this.errorMessage, - [field]: `Maximum ${NEW_STEP_LIMITS.stepTwo.introduction.max} words allowed`, - }; - } else { - this.errorMessage = { - ...this.errorMessage, - [field]: '', - }; - } + const { isValid, wordCount, remainingToMin } = validateWordCount( + this.data[field], + NEW_STEP_LIMITS.stepTwo.introduction, + ); + this.wordCount = { ...this.wordCount, introduction: wordCount }; + this.errorMessage = { + ...this.errorMessage, + [field]: isValid + ? '' + : remainingToMin + ? `At least ${remainingToMin} more word(s) required` + : `Maximum ${NEW_STEP_LIMITS.stepTwo.introduction.max} words allowed`, + }; } else { const { isValid, remainingWords } = validator( this.data[field], diff --git a/app/components/new-stepper.hbs b/app/components/new-stepper.hbs index 594581df..d40869ca 100644 --- a/app/components/new-stepper.hbs +++ b/app/components/new-stepper.hbs @@ -37,6 +37,13 @@ @isValid={{this.isValid}} @setIsValid={{this.setIsValid}} /> + + {{else if (eq this.currentStep 3)}} + {{/if}} diff --git a/app/constants/new-join-form.js b/app/constants/new-join-form.js index dd38e2d4..3b273c10 100644 --- a/app/constants/new-join-form.js +++ b/app/constants/new-join-form.js @@ -2,10 +2,12 @@ export const NEW_FORM_STEPS = { headings: [ 'Upload Professional Headshot and Complete Personal Details', 'More personal details please', + 'Your hobbies, interests, fun fact', ], subheadings: [ 'Please provide accurate information for verification purposes.', 'Introduce and help us get to know you better', + 'Show us your funny and interesting side', ], }; @@ -30,6 +32,10 @@ export const NEW_STEP_LIMITS = { company: 1, introduction: { min: 100, max: 500 }, }, + stepThree: { + hobbies: { min: 100, max: 500 }, + funFact: { min: 100, max: 500 }, + }, }; export const STEP_DATA_STORAGE_KEY = { From 99ed2b6fd5ce4e049796b5c77b132ae1759eb366 Mon Sep 17 00:00:00 2001 From: Mayank Bansal Date: Tue, 4 Nov 2025 18:17:11 +0530 Subject: [PATCH 3/9] feat: add base step class to handle input validation and local storage sync --- .../new-join-steps/new-step-three.hbs | 4 +- .../new-join-steps/new-step-three.js | 90 ++----------- .../new-join-steps/new-step-two.hbs | 4 +- app/components/new-join-steps/new-step-two.js | 118 ++---------------- app/components/new-stepper.hbs | 4 + app/constants/new-join-form.js | 3 +- 6 files changed, 25 insertions(+), 198 deletions(-) diff --git a/app/components/new-join-steps/new-step-three.hbs b/app/components/new-join-steps/new-step-three.hbs index 8ab34a1c..43d8c901 100644 --- a/app/components/new-join-steps/new-step-three.hbs +++ b/app/components/new-join-steps/new-step-three.hbs @@ -1,6 +1,6 @@
-

{{this.heading}}

-

{{this.subHeading}}

+

{{@heading}}

+

{{@subHeading}}

diff --git a/app/components/new-join-steps/new-step-three.js b/app/components/new-join-steps/new-step-three.js index e8f57710..9b88406f 100644 --- a/app/components/new-join-steps/new-step-three.js +++ b/app/components/new-join-steps/new-step-three.js @@ -1,90 +1,14 @@ -import { action } from '@ember/object'; -import { debounce } from '@ember/runloop'; -import Component from '@glimmer/component'; -import { tracked } from '@glimmer/tracking'; -import { JOIN_DEBOUNCE_TIME } from '../../constants/join'; -import { NEW_FORM_STEPS, NEW_STEP_LIMITS } from '../../constants/new-join-form'; -import { validateWordCount } from '../../utils/validator'; +import BaseStepComponent from './base-step'; +import { NEW_STEP_LIMITS } from '../../constants/new-join-form'; -export default class NewStepThreeComponent extends Component { - @tracked data = JSON.parse(localStorage.getItem('newStepThreeData')) ?? { - hobbies: '', - funFact: '', +export default class NewStepThreeComponent extends BaseStepComponent { + storageKey = 'newStepThreeData'; + validationMap = { + hobbies: NEW_STEP_LIMITS.stepThree.hobbies, + funFact: NEW_STEP_LIMITS.stepThree.funFact, }; - - @tracked errorMessage = { - hobbies: '', - funFact: '', - }; - - @tracked wordCount = { - hobbies: - this?.data?.hobbies?.trim()?.split(/\s+/).filter(Boolean).length || 0, - funFact: - this?.data?.funFact?.trim()?.split(/\s+/).filter(Boolean).length || 0, - }; - maxWords = { hobbies: NEW_STEP_LIMITS.stepThree.hobbies.max, funFact: NEW_STEP_LIMITS.stepThree.funFact.max, }; - - isValid; - setIsValid; - setIsPreValid; - - heading = NEW_FORM_STEPS.headings[2]; - subHeading = NEW_FORM_STEPS.subheadings[2]; - - constructor(...args) { - super(...args); - this.isValid = this.args.isValid; - this.setIsValid = this.args.setIsValid; - this.setIsPreValid = this.args.setIsPreValid; - const validated = this.isDataValid(); - localStorage.setItem('isValid', validated); - this.setIsPreValid(validated); - } - - isDataValid() { - for (let field in this.data) { - const { isValid } = validateWordCount( - this.data[field], - NEW_STEP_LIMITS.stepThree[field], - ); - if (!isValid) return false; - } - return true; - } - - @action inputHandler(e) { - this.setIsPreValid(false); - - const setValToLocalStorage = () => { - this.data = { ...this.data, [e.target.name]: e.target.value }; - localStorage.setItem('newStepThreeData', JSON.stringify(this.data)); - - // Only validate the changed field - const field = e.target.name; - const { isValid, wordCount, remainingToMin } = validateWordCount( - this.data[field], - NEW_STEP_LIMITS.stepThree[field], - ); - this.wordCount = { ...this.wordCount, [field]: wordCount }; - this.errorMessage = { - ...this.errorMessage, - [field]: isValid - ? '' - : remainingToMin - ? `At least, ${remainingToMin} more word(s) required` - : `Maximum ${NEW_STEP_LIMITS.stepThree[field].max} words allowed`, - }; - - const isAllValid = this.isDataValid(); - this.setIsValid(isAllValid); - localStorage.setItem('isValid', isAllValid); - }; - - debounce(this.data, setValToLocalStorage, JOIN_DEBOUNCE_TIME); - } } diff --git a/app/components/new-join-steps/new-step-two.hbs b/app/components/new-join-steps/new-step-two.hbs index 629b9d3f..4d947d99 100644 --- a/app/components/new-join-steps/new-step-two.hbs +++ b/app/components/new-join-steps/new-step-two.hbs @@ -1,7 +1,7 @@
-

{{this.heading}}

-

{{this.subHeading}}

+

{{@heading}}

+

{{@subHeading}}

diff --git a/app/components/new-join-steps/new-step-two.js b/app/components/new-join-steps/new-step-two.js index 3f72b711..813ed5a4 100644 --- a/app/components/new-join-steps/new-step-two.js +++ b/app/components/new-join-steps/new-step-two.js @@ -1,112 +1,12 @@ -import { action } from '@ember/object'; -import { debounce } from '@ember/runloop'; -import Component from '@glimmer/component'; -import { tracked } from '@glimmer/tracking'; -import { JOIN_DEBOUNCE_TIME } from '../../constants/join'; -import { NEW_FORM_STEPS, NEW_STEP_LIMITS } from '../../constants/new-join-form'; -import { validateWordCount, validator } from '../../utils/validator'; +import BaseStepComponent from './base-step'; +import { NEW_STEP_LIMITS } from '../../constants/new-join-form'; -export default class NewStepTwoComponent extends Component { - @tracked data = JSON.parse(localStorage.getItem('newStepTwoData')) ?? { - skills: '', - company: '', - introduction: '', +export default class NewStepTwoComponent extends BaseStepComponent { + storageKey = 'newStepTwoData'; + validationMap = { + skills: NEW_STEP_LIMITS.stepTwo.skills, + company: NEW_STEP_LIMITS.stepTwo.company, + introduction: NEW_STEP_LIMITS.stepTwo.introduction, }; - - @tracked errorMessage = { - skills: '', - company: '', - introduction: '', - }; - - @tracked wordCount = { - introduction: - this?.data?.introduction?.trim()?.split(/\s+/).filter(Boolean).length || - 0, - }; - - maxWords = { - introduction: NEW_STEP_LIMITS.stepTwo.introduction.max, - }; - - heading = NEW_FORM_STEPS.headings[1]; - subHeading = NEW_FORM_STEPS.subheadings[1]; - - isValid; - setIsValid; - setIsPreValid; - - constructor(...args) { - super(...args); - this.isValid = this.args.isValid; - this.setIsValid = this.args.setIsValid; - this.setIsPreValid = this.args.setIsPreValid; - const validated = this.isDataValid(); - localStorage.setItem('isValid', validated); - this.setIsPreValid(validated); - } - - isDataValid() { - for (let field in this.data) { - if (field === 'introduction') { - const { isValid } = validateWordCount( - this.data[field], - NEW_STEP_LIMITS.stepTwo.introduction, - ); - if (!isValid) return false; - } else { - const { isValid } = validator( - this.data[field], - NEW_STEP_LIMITS.stepTwo[field], - ); - if (!isValid) { - return false; - } - } - } - return true; - } - - @action inputHandler(e) { - this.setIsPreValid(false); - - const setValToLocalStorage = () => { - this.data = { ...this.data, [e.target.name]: e.target.value }; - localStorage.setItem('newStepTwoData', JSON.stringify(this.data)); - - const field = e.target.name; - if (field === 'introduction') { - const { isValid, wordCount, remainingToMin } = validateWordCount( - this.data[field], - NEW_STEP_LIMITS.stepTwo.introduction, - ); - this.wordCount = { ...this.wordCount, introduction: wordCount }; - this.errorMessage = { - ...this.errorMessage, - [field]: isValid - ? '' - : remainingToMin - ? `At least ${remainingToMin} more word(s) required` - : `Maximum ${NEW_STEP_LIMITS.stepTwo.introduction.max} words allowed`, - }; - } else { - const { isValid, remainingWords } = validator( - this.data[field], - NEW_STEP_LIMITS.stepTwo[field], - ); - this.errorMessage = { - ...this.errorMessage, - [field]: isValid - ? '' - : `At least, ${remainingWords} more word(s) required`, - }; - } - - const isAllValid = this.isDataValid(); - this.setIsValid(isAllValid); - localStorage.setItem('isValid', isAllValid); - }; - - debounce(this.data, setValToLocalStorage, JOIN_DEBOUNCE_TIME); - } + maxWords = { introduction: NEW_STEP_LIMITS.stepTwo.introduction.max }; } diff --git a/app/components/new-stepper.hbs b/app/components/new-stepper.hbs index d40869ca..ecb753fd 100644 --- a/app/components/new-stepper.hbs +++ b/app/components/new-stepper.hbs @@ -36,6 +36,8 @@ @setIsPreValid={{this.setIsPreValid}} @isValid={{this.isValid}} @setIsValid={{this.setIsValid}} + @heading={{this.currentHeading}} + @subHeading={{this.currentSubheading}} /> {{else if (eq this.currentStep 3)}} @@ -43,6 +45,8 @@ @setIsPreValid={{this.setIsPreValid}} @isValid={{this.isValid}} @setIsValid={{this.setIsValid}} + @heading={{this.currentHeading}} + @subHeading={{this.currentSubheading}} /> {{/if}} diff --git a/app/constants/new-join-form.js b/app/constants/new-join-form.js index 3b273c10..49b22e31 100644 --- a/app/constants/new-join-form.js +++ b/app/constants/new-join-form.js @@ -28,8 +28,7 @@ export const NEW_STEP_LIMITS = { role: { min: 1 }, }, stepTwo: { - skills: 5, - company: 1, + skills: { min: 5, max: 20 }, introduction: { min: 100, max: 500 }, }, stepThree: { From 2478f760445e270b3982450af9463bc90530a886 Mon Sep 17 00:00:00 2001 From: Mayank Bansal Date: Tue, 4 Nov 2025 21:00:03 +0530 Subject: [PATCH 4/9] fix: postIntialization in new step one --- app/constants/new-join-form.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/constants/new-join-form.js b/app/constants/new-join-form.js index 49b22e31..1fab4739 100644 --- a/app/constants/new-join-form.js +++ b/app/constants/new-join-form.js @@ -29,6 +29,7 @@ export const NEW_STEP_LIMITS = { }, stepTwo: { skills: { min: 5, max: 20 }, + company: { min: 1 }, introduction: { min: 100, max: 500 }, }, stepThree: { From 93969aa479dacd5860a56674793a5dae17ed38a2 Mon Sep 17 00:00:00 2001 From: Mayank Bansal Date: Wed, 5 Nov 2025 18:40:25 +0530 Subject: [PATCH 5/9] fix: grid styling for step two and three --- .../new-join-steps/new-step-three.hbs | 68 +++++++++--------- .../new-join-steps/new-step-two.hbs | 69 +++++++------------ 2 files changed, 60 insertions(+), 77 deletions(-) diff --git a/app/components/new-join-steps/new-step-three.hbs b/app/components/new-join-steps/new-step-three.hbs index 43d8c901..4e6ecfad 100644 --- a/app/components/new-join-steps/new-step-three.hbs +++ b/app/components/new-join-steps/new-step-three.hbs @@ -1,38 +1,38 @@ -
-

{{@heading}}

-

{{@subHeading}}

-
- -
-
-

What do you do for fun? Your hobbies/interests?

- -
{{this.wordCount.hobbies}}/{{this.maxWords.hobbies}} words
- {{#if this.errorMessage.hobbies}} -
{{this.errorMessage.hobbies}}
- {{/if}} +
+
+

{{@heading}}

+

{{@subHeading}}

-
-

Fun fact about you

- -
{{this.wordCount.funFact}}/{{this.maxWords.funFact}} words
- {{#if this.errorMessage.funFact}} -
{{this.errorMessage.funFact}}
- {{/if}} +
+
+ +
{{this.wordCount.hobbies}}/{{this.maxWords.hobbies}} words
+ {{#if this.errorMessage.hobbies}} +
{{this.errorMessage.hobbies}}
+ {{/if}} +
+ +
+ +
{{this.wordCount.funFact}}/{{this.maxWords.funFact}} words
+ {{#if this.errorMessage.funFact}} +
{{this.errorMessage.funFact}}
+ {{/if}} +
\ No newline at end of file diff --git a/app/components/new-join-steps/new-step-two.hbs b/app/components/new-join-steps/new-step-two.hbs index 4d947d99..451601e5 100644 --- a/app/components/new-join-steps/new-step-two.hbs +++ b/app/components/new-join-steps/new-step-two.hbs @@ -1,54 +1,37 @@
-

{{@heading}}

-

{{@subHeading}}

+

{{@heading}}

+

{{@subHeading}}

-
-
- - {{#if this.errorMessage.skills}} +
+
+
+ + {{#if this.errorMessage.skills}}
{{this.errorMessage.skills}}
- {{/if}} -
+ {{/if}} +
-
- - {{#if this.errorMessage.company}} +
+ + {{#if this.errorMessage.company}}
{{this.errorMessage.company}}
+ {{/if}} +
+
+
+ +
{{this.wordCount.introduction}}/{{this.maxWords.introduction}} words
+ + {{#if this.errorMessage.introduction}} +
{{this.errorMessage.introduction}}
{{/if}}
- -

Please introduce yourself

- -
{{this.wordCount.introduction}}/{{this.maxWords.introduction}} words
-

Share your background, experiences, and what drives you.

- - {{#if this.errorMessage.introduction}} -
{{this.errorMessage.introduction}}
- {{/if}}
\ No newline at end of file From fe14c9285c7c33bbcf3fb128a6119ea7d65721ac Mon Sep 17 00:00:00 2001 From: Mayank Bansal Date: Fri, 7 Nov 2025 17:48:05 +0530 Subject: [PATCH 6/9] refactor: remove redundant max words --- app/components/new-join-steps/new-step-three.hbs | 12 ++++++------ app/components/new-join-steps/new-step-three.js | 4 ---- app/components/new-join-steps/new-step-two.hbs | 12 ++++++------ app/components/new-join-steps/new-step-two.js | 1 - 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/app/components/new-join-steps/new-step-three.hbs b/app/components/new-join-steps/new-step-three.hbs index 4e6ecfad..dc47323e 100644 --- a/app/components/new-join-steps/new-step-three.hbs +++ b/app/components/new-join-steps/new-step-three.hbs @@ -1,7 +1,7 @@
-

{{@heading}}

-

{{@subHeading}}

+

{{@heading}}

+

{{@subHeading}}

@@ -14,9 +14,9 @@ @value={{this.data.hobbies}} @onInput={{this.inputHandler}} /> -
{{this.wordCount.hobbies}}/{{this.maxWords.hobbies}} words
+
{{this.wordCount.hobbies}}/{{this.validationMap.hobbies.max}} words
{{#if this.errorMessage.hobbies}} -
{{this.errorMessage.hobbies}}
+
{{this.errorMessage.hobbies}}
{{/if}}
@@ -29,9 +29,9 @@ @value={{this.data.funFact}} @onInput={{this.inputHandler}} /> -
{{this.wordCount.funFact}}/{{this.maxWords.funFact}} words
+
{{this.wordCount.funFact}}/{{this.validationMap.funFact.max}} words
{{#if this.errorMessage.funFact}} -
{{this.errorMessage.funFact}}
+
{{this.errorMessage.funFact}}
{{/if}}
diff --git a/app/components/new-join-steps/new-step-three.js b/app/components/new-join-steps/new-step-three.js index 9b88406f..e52570f7 100644 --- a/app/components/new-join-steps/new-step-three.js +++ b/app/components/new-join-steps/new-step-three.js @@ -7,8 +7,4 @@ export default class NewStepThreeComponent extends BaseStepComponent { hobbies: NEW_STEP_LIMITS.stepThree.hobbies, funFact: NEW_STEP_LIMITS.stepThree.funFact, }; - maxWords = { - hobbies: NEW_STEP_LIMITS.stepThree.hobbies.max, - funFact: NEW_STEP_LIMITS.stepThree.funFact.max, - }; } diff --git a/app/components/new-join-steps/new-step-two.hbs b/app/components/new-join-steps/new-step-two.hbs index 451601e5..360b5670 100644 --- a/app/components/new-join-steps/new-step-two.hbs +++ b/app/components/new-join-steps/new-step-two.hbs @@ -1,7 +1,7 @@
-

{{@heading}}

-

{{@subHeading}}

+

{{@heading}}

+

{{@subHeading}}

@@ -10,7 +10,7 @@ {{#if this.errorMessage.skills}} -
{{this.errorMessage.skills}}
+
{{this.errorMessage.skills}}
{{/if}}
@@ -19,7 +19,7 @@ @placeHolder='Institution or company name' @type='text' @required={{true}} @value={{this.data.company}} @onInput={{this.inputHandler}} /> {{#if this.errorMessage.company}} -
{{this.errorMessage.company}}
+
{{this.errorMessage.company}}
{{/if}}
@@ -27,10 +27,10 @@ -
{{this.wordCount.introduction}}/{{this.maxWords.introduction}} words
+
{{this.wordCount.introduction}}/{{this.validationMap.introduction.max}} words
{{#if this.errorMessage.introduction}} -
{{this.errorMessage.introduction}}
+
{{this.errorMessage.introduction}}
{{/if}}
diff --git a/app/components/new-join-steps/new-step-two.js b/app/components/new-join-steps/new-step-two.js index 813ed5a4..67ad7da6 100644 --- a/app/components/new-join-steps/new-step-two.js +++ b/app/components/new-join-steps/new-step-two.js @@ -8,5 +8,4 @@ export default class NewStepTwoComponent extends BaseStepComponent { company: NEW_STEP_LIMITS.stepTwo.company, introduction: NEW_STEP_LIMITS.stepTwo.introduction, }; - maxWords = { introduction: NEW_STEP_LIMITS.stepTwo.introduction.max }; } From 34dfc52b2a8b1c321d8c6f68407a95fcc9a395c9 Mon Sep 17 00:00:00 2001 From: Mayank Bansal Date: Fri, 7 Nov 2025 17:58:43 +0530 Subject: [PATCH 7/9] fix: lint issue and form headings --- app/constants/new-join-form.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/constants/new-join-form.js b/app/constants/new-join-form.js index 1fab4739..126625cc 100644 --- a/app/constants/new-join-form.js +++ b/app/constants/new-join-form.js @@ -1,7 +1,7 @@ export const NEW_FORM_STEPS = { headings: [ 'Upload Professional Headshot and Complete Personal Details', - 'More personal details please', + 'Additional Personal Information', 'Your hobbies, interests, fun fact', ], subheadings: [ From ee06d8a7afd32f8a742db36f7660b8483932ec2c Mon Sep 17 00:00:00 2001 From: Mayank Bansal Date: Mon, 10 Nov 2025 01:53:44 +0530 Subject: [PATCH 8/9] refactor: use constant for storage keys --- app/components/new-join-steps/new-step-three.hbs | 4 ++-- app/components/new-join-steps/new-step-three.js | 9 ++++++--- app/components/new-join-steps/new-step-two.hbs | 2 +- app/components/new-join-steps/new-step-two.js | 9 ++++++--- app/constants/new-join-form.js | 2 ++ 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/app/components/new-join-steps/new-step-three.hbs b/app/components/new-join-steps/new-step-three.hbs index dc47323e..7614c45f 100644 --- a/app/components/new-join-steps/new-step-three.hbs +++ b/app/components/new-join-steps/new-step-three.hbs @@ -14,7 +14,7 @@ @value={{this.data.hobbies}} @onInput={{this.inputHandler}} /> -
{{this.wordCount.hobbies}}/{{this.validationMap.hobbies.max}} words
+
{{this.wordCount.hobbies}}/{{this.stepValidation.hobbies.max}} words
{{#if this.errorMessage.hobbies}}
{{this.errorMessage.hobbies}}
{{/if}} @@ -29,7 +29,7 @@ @value={{this.data.funFact}} @onInput={{this.inputHandler}} /> -
{{this.wordCount.funFact}}/{{this.validationMap.funFact.max}} words
+
{{this.wordCount.funFact}}/{{this.stepValidation.funFact.max}} words
{{#if this.errorMessage.funFact}}
{{this.errorMessage.funFact}}
{{/if}} diff --git a/app/components/new-join-steps/new-step-three.js b/app/components/new-join-steps/new-step-three.js index e52570f7..0c3fd6b2 100644 --- a/app/components/new-join-steps/new-step-three.js +++ b/app/components/new-join-steps/new-step-three.js @@ -1,9 +1,12 @@ import BaseStepComponent from './base-step'; -import { NEW_STEP_LIMITS } from '../../constants/new-join-form'; +import { + NEW_STEP_LIMITS, + STEP_DATA_STORAGE_KEY, +} from '../../constants/new-join-form'; export default class NewStepThreeComponent extends BaseStepComponent { - storageKey = 'newStepThreeData'; - validationMap = { + storageKey = STEP_DATA_STORAGE_KEY.stepThree; + stepValidation = { hobbies: NEW_STEP_LIMITS.stepThree.hobbies, funFact: NEW_STEP_LIMITS.stepThree.funFact, }; diff --git a/app/components/new-join-steps/new-step-two.hbs b/app/components/new-join-steps/new-step-two.hbs index 360b5670..c96c5175 100644 --- a/app/components/new-join-steps/new-step-two.hbs +++ b/app/components/new-join-steps/new-step-two.hbs @@ -27,7 +27,7 @@ -
{{this.wordCount.introduction}}/{{this.validationMap.introduction.max}} words
+
{{this.wordCount.introduction}}/{{this.stepValidation.introduction.max}} words
{{#if this.errorMessage.introduction}}
{{this.errorMessage.introduction}}
diff --git a/app/components/new-join-steps/new-step-two.js b/app/components/new-join-steps/new-step-two.js index 67ad7da6..edb38294 100644 --- a/app/components/new-join-steps/new-step-two.js +++ b/app/components/new-join-steps/new-step-two.js @@ -1,9 +1,12 @@ import BaseStepComponent from './base-step'; -import { NEW_STEP_LIMITS } from '../../constants/new-join-form'; +import { + NEW_STEP_LIMITS, + STEP_DATA_STORAGE_KEY, +} from '../../constants/new-join-form'; export default class NewStepTwoComponent extends BaseStepComponent { - storageKey = 'newStepTwoData'; - validationMap = { + storageKey = STEP_DATA_STORAGE_KEY.stepTwo; + stepValidation = { skills: NEW_STEP_LIMITS.stepTwo.skills, company: NEW_STEP_LIMITS.stepTwo.company, introduction: NEW_STEP_LIMITS.stepTwo.introduction, diff --git a/app/constants/new-join-form.js b/app/constants/new-join-form.js index 126625cc..5c1aadcd 100644 --- a/app/constants/new-join-form.js +++ b/app/constants/new-join-form.js @@ -40,4 +40,6 @@ export const NEW_STEP_LIMITS = { export const STEP_DATA_STORAGE_KEY = { stepOne: 'newStepOneData', + stepTwo: 'newStepTwoData', + stepThree: 'newStepThreeData', }; From f7aa606c9361e22f22fc5950b964e1765f5da842 Mon Sep 17 00:00:00 2001 From: Mayank Bansal Date: Wed, 12 Nov 2025 02:08:05 +0530 Subject: [PATCH 9/9] feat: add new step four and five for social links and whyRds [Onboarding-Form] (#1086) * feat: add new step for social links * feat: add snew step four for social links * feat: add new step fivve for stepper * fix: styling for selectt in new step five * refactor: replace hardcoded storage keys with constants * feat: add review step for new stepper [Onboarding-Form] (#1087) * feat: add review step for new stepper * feat: add thank you screen for new stepper * refactor: use structure for step data and replace hardcoded storage keys * refactor: use getter func for review step button --- .../new-join-steps/new-step-five.hbs | 33 +++ .../new-join-steps/new-step-five.js | 16 ++ .../new-join-steps/new-step-four.hbs | 62 ++++++ .../new-join-steps/new-step-four.js | 80 +++++++ .../new-join-steps/new-step-six.hbs | 207 ++++++++++++++++++ app/components/new-join-steps/new-step-six.js | 57 +++++ .../new-join-steps/thank-you-screen.hbs | 33 +++ app/components/new-stepper.hbs | 54 +++-- app/components/new-stepper.js | 29 ++- app/constants/new-join-form.js | 22 ++ app/styles/new-stepper.module.css | 54 ++++- 11 files changed, 616 insertions(+), 31 deletions(-) create mode 100644 app/components/new-join-steps/new-step-five.hbs create mode 100644 app/components/new-join-steps/new-step-five.js create mode 100644 app/components/new-join-steps/new-step-four.hbs create mode 100644 app/components/new-join-steps/new-step-four.js create mode 100644 app/components/new-join-steps/new-step-six.hbs create mode 100644 app/components/new-join-steps/new-step-six.js create mode 100644 app/components/new-join-steps/thank-you-screen.hbs diff --git a/app/components/new-join-steps/new-step-five.hbs b/app/components/new-join-steps/new-step-five.hbs new file mode 100644 index 00000000..ded36fdc --- /dev/null +++ b/app/components/new-join-steps/new-step-five.hbs @@ -0,0 +1,33 @@ +
+
+

{{@heading}}

+

{{@subHeading}}

+
+ + + {{#if this.errorMessage.whyRds}} +
{{this.errorMessage.whyRds}}
+ {{/if}} + +
+
+ + {{#if this.errorMessage.numberOfHours}} +
{{this.errorMessage.numberOfHours}}
+ {{/if}} +
+ +
+ + {{#if this.errorMessage.foundFrom}} +
{{this.errorMessage.foundFrom}}
+ {{/if}} +
+
+
\ No newline at end of file diff --git a/app/components/new-join-steps/new-step-five.js b/app/components/new-join-steps/new-step-five.js new file mode 100644 index 00000000..71a35326 --- /dev/null +++ b/app/components/new-join-steps/new-step-five.js @@ -0,0 +1,16 @@ +import BaseStepComponent from './base-step'; +import { + NEW_STEP_LIMITS, + STEP_DATA_STORAGE_KEY, +} from '../../constants/new-join-form'; +import { heardFrom } from '../../constants/social-data'; + +export default class NewStepFiveComponent extends BaseStepComponent { + storageKey = STEP_DATA_STORAGE_KEY.stepFive; + heardFrom = heardFrom; + + stepValidation = { + whyRds: NEW_STEP_LIMITS.stepFive.whyRds, + foundFrom: NEW_STEP_LIMITS.stepFive.foundFrom, + }; +} diff --git a/app/components/new-join-steps/new-step-four.hbs b/app/components/new-join-steps/new-step-four.hbs new file mode 100644 index 00000000..40106a44 --- /dev/null +++ b/app/components/new-join-steps/new-step-four.hbs @@ -0,0 +1,62 @@ +
+
+

{{@heading}}

+

{{@subHeading}}

+
+ + + {{#if this.errorMessage.phoneNumber}} +
{{this.errorMessage.phoneNumber}}
+ {{/if}} + + + {{#if this.errorMessage.twitter}} +
{{this.errorMessage.twitter}}
+ {{/if}} + + {{#if this.showGitHub}} + + {{#if this.errorMessage.github}} +
{{this.errorMessage.github}}
+ {{/if}} + {{/if}} + + + {{#if this.errorMessage.linkedin}} +
{{this.errorMessage.linkedin}}
+ {{/if}} + + + {{#if this.errorMessage.instagram}} +
{{this.errorMessage.instagram}}
+ {{/if}} + + + {{#if this.errorMessage.peerlist}} +
{{this.errorMessage.peerlist}}
+ {{/if}} + + {{#if this.showBehance}} + + {{#if this.errorMessage.behance}} +
{{this.errorMessage.behance}}
+ {{/if}} + {{/if}} + + {{#if this.showDribble}} + + {{#if this.errorMessage.dribble}} +
{{this.errorMessage.dribble}}
+ {{/if}} + {{/if}} +
\ No newline at end of file diff --git a/app/components/new-join-steps/new-step-four.js b/app/components/new-join-steps/new-step-four.js new file mode 100644 index 00000000..bae00758 --- /dev/null +++ b/app/components/new-join-steps/new-step-four.js @@ -0,0 +1,80 @@ +import BaseStepComponent from './base-step'; +import { + NEW_STEP_LIMITS, + STEP_DATA_STORAGE_KEY, +} from '../../constants/new-join-form'; +import { phoneNumberRegex } from '../../constants/regex'; + +export default class NewStepFourComponent extends BaseStepComponent { + storageKey = STEP_DATA_STORAGE_KEY.stepFour; + + stepValidation = { + phoneNumber: NEW_STEP_LIMITS.stepFour.phoneNumber, + twitter: NEW_STEP_LIMITS.stepFour.twitter, + linkedin: NEW_STEP_LIMITS.stepFour.linkedin, + instagram: NEW_STEP_LIMITS.stepFour.instagram, + peerlist: NEW_STEP_LIMITS.stepFour.peerlist, + }; + + get userRole() { + const stepOneData = JSON.parse( + localStorage.getItem('newStepOneData') || '{}', + ); + return stepOneData.role || ''; + } + + postLoadInitialize() { + if (this.userRole === 'Developer') { + this.stepValidation.github = NEW_STEP_LIMITS.stepFour.github; + } + + if (this.userRole === 'Designer') { + this.stepValidation.behance = NEW_STEP_LIMITS.stepFour.behance; + this.stepValidation.dribble = NEW_STEP_LIMITS.stepFour.dribble; + } + + // re-calculate the errorMessage and wordCount for new input fields + this.errorMessage = Object.fromEntries( + Object.keys(this.stepValidation).map((k) => [k, '']), + ); + + this.wordCount = Object.fromEntries( + Object.keys(this.stepValidation).map((k) => { + let val = this.data[k] || ''; + return [k, val.trim().split(/\s+/).filter(Boolean).length || 0]; + }), + ); + } + + get showGitHub() { + return this.userRole === 'Developer'; + } + + get showBehance() { + return this.userRole === 'Designer'; + } + + get showDribble() { + return this.userRole === 'Designer'; + } + + validateField(field, value) { + if (field === 'phoneNumber') { + const trimmedValue = value?.trim() || ''; + const isValid = trimmedValue && phoneNumberRegex.test(trimmedValue); + return { + isValid, + wordCount: 0, + }; + } + return super.validateField(field, value); + } + + formatError(field, result) { + if (field === 'phoneNumber') { + if (result.isValid) return ''; + return 'Please enter a valid phone number (e.g., +91 80000 00000)'; + } + return super.formatError(field, result); + } +} diff --git a/app/components/new-join-steps/new-step-six.hbs b/app/components/new-join-steps/new-step-six.hbs new file mode 100644 index 00000000..cb18d7d5 --- /dev/null +++ b/app/components/new-join-steps/new-step-six.hbs @@ -0,0 +1,207 @@ +
+
+

{{@heading}}

+

{{@subHeading}}

+
+ +
+
+

Personal Information

+ +
+
+
+ Full Name: + + {{if this.stepData.one.fullName this.stepData.one.fullName 'Not provided'}} + +
+
+ Location: + + {{this.locationDisplay}} + +
+
+ Applying as: + + {{if this.stepData.one.role this.stepData.one.role 'Not provided'}} + +
+
+ Profile Image: + + Not uploaded + +
+
+
+ +
+
+

Professional Details

+ +
+
+
+ Skills: + + {{if this.stepData.two.skills this.stepData.two.skills 'Not provided'}} + +
+
+ Institution/Company: + + {{if this.stepData.two.company this.stepData.two.company 'Not provided'}} + +
+
+ Introduction: + + {{if this.stepData.two.introduction this.stepData.two.introduction 'Not provided'}} + +
+
+
+ +
+
+

Hobbies & Interests

+ +
+
+
+ Hobbies: + + {{if this.stepData.three.hobbies this.stepData.three.hobbies 'Not provided'}} + +
+
+ Fun Fact: + + {{if this.stepData.three.funFact this.stepData.three.funFact 'Not provided'}} + +
+
+
+ +
+
+

Social Profiles

+ +
+
+
+ Phone Number: + + {{if this.stepData.four.phoneNumber this.stepData.four.phoneNumber 'Not provided'}} + +
+
+ Twitter: + + {{if this.stepData.four.twitter this.stepData.four.twitter 'Not provided'}} + +
+ {{#if this.showGitHub}} +
+ GitHub: + + {{if this.stepData.four.github this.stepData.four.github 'Not provided'}} + +
+ {{/if}} +
+ LinkedIn: + + {{if this.stepData.four.linkedin this.stepData.four.linkedin 'Not provided'}} + +
+
+ Instagram: + + {{if this.stepData.four.instagram this.stepData.four.instagram 'Not uploaded'}} + +
+
+ Peerlist: + + {{if this.stepData.four.peerlist this.stepData.four.peerlist 'Not provided'}} + +
+ {{#if this.showBehance}} +
+ Behance: + + {{if this.stepData.four.behance this.stepData.four.behance 'Not provided'}} + +
+ {{/if}} + {{#if this.showDribble}} +
+ Dribble: + + {{if this.stepData.four.dribble this.stepData.four.dribble 'Not provided'}} + +
+ {{/if}} +
+
+ +
+
+

Why Real Dev Squad?

+ +
+
+
+ Why you want to join Real Dev Squad?: + + {{if this.stepData.five.whyRds this.stepData.five.whyRds 'Not provided'}} + +
+
+ Hours per week: + + {{if this.stepData.five.numberOfHours this.stepData.five.numberOfHours 'Not provided'}} + +
+
+ How did you hear about us?: + + {{if this.stepData.five.foundFrom this.stepData.five.foundFrom 'Not provided'}} + +
+
+
+
diff --git a/app/components/new-join-steps/new-step-six.js b/app/components/new-join-steps/new-step-six.js new file mode 100644 index 00000000..9928e663 --- /dev/null +++ b/app/components/new-join-steps/new-step-six.js @@ -0,0 +1,57 @@ +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; +import { getLocalStorageItem } from '../../utils/storage'; +import { STEP_DATA_STORAGE_KEY } from '../../constants/new-join-form'; + +export default class NewStepSixComponent extends Component { + @tracked stepData = { + one: {}, + two: {}, + three: {}, + four: {}, + five: {}, + }; + + constructor(...args) { + super(...args); + this.loadAllStepData(); + } + + loadAllStepData() { + this.stepData.one = JSON.parse( + getLocalStorageItem(STEP_DATA_STORAGE_KEY.stepOne), + ); + this.stepData.two = JSON.parse( + getLocalStorageItem(STEP_DATA_STORAGE_KEY.stepTwo), + ); + this.stepData.three = JSON.parse( + getLocalStorageItem(STEP_DATA_STORAGE_KEY.stepThree), + ); + this.stepData.four = JSON.parse( + getLocalStorageItem(STEP_DATA_STORAGE_KEY.stepFour), + ); + this.stepData.five = JSON.parse( + getLocalStorageItem(STEP_DATA_STORAGE_KEY.stepFive), + ); + } + + get userRole() { + return this.stepData.one.role || ''; + } + + get showGitHub() { + return this.userRole === 'Developer'; + } + + get showBehance() { + return this.userRole === 'Designer'; + } + + get showDribble() { + return this.userRole === 'Designer'; + } + + get locationDisplay() { + return `${this.stepData.one.city}, ${this.stepData.one.state}, ${this.stepData.one.country}`; + } +} diff --git a/app/components/new-join-steps/thank-you-screen.hbs b/app/components/new-join-steps/thank-you-screen.hbs new file mode 100644 index 00000000..b014fad5 --- /dev/null +++ b/app/components/new-join-steps/thank-you-screen.hbs @@ -0,0 +1,33 @@ +
+ + +
+

{{@firstName}}, thank you for applying to RDS.

+

Great work filling up the application. However, it takes more to join us early.

+
+ +
+
+ Head over to Application Tracking Page. +
+ +
+ Checkout AI review and and edit your application to improve application rank. +
+ +
+ Complete quests to improve your ranking and increase your chances of early reviews. +
+
+ +
+

Application ID

+

{{@applicationId}}

+
+ +
+ +
+
\ No newline at end of file diff --git a/app/components/new-stepper.hbs b/app/components/new-stepper.hbs index 013ca6e8..f2962269 100644 --- a/app/components/new-stepper.hbs +++ b/app/components/new-stepper.hbs @@ -1,6 +1,5 @@
- - {{#if (not-eq this.currentStep this.MIN_STEP)}} + {{#if (and (not-eq this.currentStep this.MIN_STEP) (not-eq this.currentStep 7))}} {{/if}} @@ -13,39 +12,46 @@ @disabled={{not this.joinApplicationTerms.hasUserAcceptedTerms}} />
- {{else if (eq this.currentStep 1)}} - - {{else if (eq this.currentStep 2)}} - - - {{else if (eq this.currentStep 3)}} - + {{else if (eq this.currentStep 2)}} + + + {{else if (eq this.currentStep 3)}} + + + {{else if (eq this.currentStep 4)}} + + + {{else if (eq this.currentStep 5)}} + + + {{else if (eq this.currentStep 6)}} + + + {{else if (eq this.currentStep 7)}} + {{/if}} - {{#if (not-eq this.currentStep this.MIN_STEP)}} + {{#if (and (not-eq this.currentStep this.MIN_STEP) (not-eq this.currentStep 7))}}
{{#if this.showPreviousButton}} {{/if}} - +
{{/if}} \ No newline at end of file diff --git a/app/components/new-stepper.js b/app/components/new-stepper.js index 919c6803..ff0cc434 100644 --- a/app/components/new-stepper.js +++ b/app/components/new-stepper.js @@ -8,6 +8,7 @@ import { getLocalStorageItem, setLocalStorageItem } from '../utils/storage'; export default class NewStepperComponent extends Component { MIN_STEP = 0; MAX_STEP = 6; + applicationId = '4gchuf690'; @service login; @service router; @@ -36,7 +37,6 @@ export default class NewStepperComponent extends Component { updateQueryParam(step) { const existingQueryParams = this.router.currentRoute?.queryParams; - this.router.transitionTo('join', { queryParams: { ...existingQueryParams, @@ -57,10 +57,18 @@ export default class NewStepperComponent extends Component { return NEW_FORM_STEPS.subheadings[this.currentStep - 1] ?? ''; } + get firstName() { + return localStorage.getItem('first_name') ?? ''; + } + get isNextButtonDisabled() { return !(this.preValid || this.isValid); } + get isReviewStep() { + return this.currentStep === this.MAX_STEP; + } + @action incrementStep() { if (this.currentStep < this.MAX_STEP) { const nextStep = this.currentStep + 1; @@ -85,4 +93,23 @@ export default class NewStepperComponent extends Component { sessionStorage.setItem('last_name', this.login.userData.last_name); this.incrementStep(); } + + @action navigateToStep(stepNumber) { + if (stepNumber >= this.MIN_STEP + 1 && stepNumber <= this.MAX_STEP) { + this.isValid = false; + this.preValid = false; + this.currentStep = stepNumber; + setLocalStorageItem('currentStep', String(stepNumber)); + setLocalStorageItem('isValid', 'false'); + this.updateQueryParam(stepNumber); + } + } + + @action handleSubmit() { + // ToDo: handle create application + console.log('Submit application for review'); + this.currentStep = this.MAX_STEP + 1; + setLocalStorageItem('currentStep', String(this.currentStep)); + this.updateQueryParam(this.currentStep); + } } diff --git a/app/constants/new-join-form.js b/app/constants/new-join-form.js index 91ce46ba..0cfb9fb6 100644 --- a/app/constants/new-join-form.js +++ b/app/constants/new-join-form.js @@ -3,11 +3,17 @@ export const NEW_FORM_STEPS = { 'Upload Professional Headshot and Complete Personal Details', 'Additional Personal Information', 'Your hobbies, interests, fun fact', + 'Connect your social profiles', + 'Why Real Dev Squad?', + 'Review and Submit', ], subheadings: [ 'Please provide accurate information for verification purposes.', 'Introduce and help us get to know you better', 'Show us your funny and interesting side', + 'Share your social media and professional profiles', + 'Tell us why you want to join our community', + 'Review your answers before submitting.', ], }; @@ -36,10 +42,26 @@ export const NEW_STEP_LIMITS = { hobbies: { min: 100, max: 500 }, funFact: { min: 100, max: 500 }, }, + stepFour: { + phoneNumber: { min: 1 }, + twitter: { min: 1 }, + github: { min: 1 }, + linkedin: { min: 1 }, + instagram: { min: 0 }, + peerlist: { min: 1 }, + behance: { min: 1 }, + dribble: { min: 1 }, + }, + stepFive: { + whyRds: { min: 100 }, + foundFrom: { min: 1 }, + }, }; export const STEP_DATA_STORAGE_KEY = { stepOne: 'newStepOneData', stepTwo: 'newStepTwoData', stepThree: 'newStepThreeData', + stepFour: 'newStepFourData', + stepFive: 'newStepFiveData', }; diff --git a/app/styles/new-stepper.module.css b/app/styles/new-stepper.module.css index b9da0542..10f1aec8 100644 --- a/app/styles/new-stepper.module.css +++ b/app/styles/new-stepper.module.css @@ -23,7 +23,8 @@ justify-self: end; } -.welcome-screen { +.welcome-screen, +.thank-you-screen { width: 90%; margin: 0 auto 2rem; display: flex; @@ -37,7 +38,8 @@ justify-content: center; } -.welcome-screen__info-item--bullet { +.welcome-screen__info-item--bullet, +.thank-you-screen__info-item--bullet { display: flex; align-items: center; margin-bottom: 1rem; @@ -46,7 +48,8 @@ line-height: 1.5; } -.welcome-screen__info-item--bullet::before { +.welcome-screen__info-item--bullet::before, +.thank-you-screen__info-item--bullet::before { content: "•"; color: var(--color-pink); font-size: 1.5rem; @@ -67,7 +70,8 @@ line-height: 1.5; } -.welcome-screen__actions { +.welcome-screen__actions, +.thank-you-screen__actions { display: flex; justify-content: center; } @@ -405,6 +409,38 @@ border-top: 1px solid var(--color-lightgrey); } +.thank-you-screen { + align-items: center; + text-align: center; + margin: 2rem auto 0; +} + +.thank-you-screen__info-container { + text-align: start; + margin-block: 1.5rem; +} + +.thank-you-screen__logo { + display: flex; + justify-content: center; + align-items: center; + width: 3rem; + height: 3em; + border-radius: 50%; + background-color: var(--color-navyblue); + color: var(--color-white); +} + +.application-id h3 { + font-size: 1rem; + font-weight: 500; +} + +.application-id p { + font-size: 1.25rem; + font-weight: 700; +} + @media screen and (width <=1280px) { .new-stepper__form, .form-header, @@ -440,7 +476,8 @@ grid-template-columns: 1fr; } - .welcome-screen { + .welcome-screen, + .thank-you-screen { margin: 1rem auto; padding: 1.5rem; } @@ -476,6 +513,10 @@ text-align: left; max-width: 100%; } + + .form-header__text { + line-height: 1.5; + } } @media screen and (width <=480px) { @@ -493,7 +534,8 @@ padding: 1rem; } - .welcome-screen { + .welcome-screen, + .thank-you-screen { margin: 0.5rem auto 1rem; padding: 1rem; }