Created
May 14, 2021 13:47
-
-
Save mmpataki/a5d5d5e0c34ff87783de8bd5a13b6071 to your computer and use it in GitHub Desktop.
storyteller pattern
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class AadharDetailsStory { | |
constructor(args) { this.args = args; } | |
title() { return "Enter your Aadhar ID" } | |
moral() { return { ...this.args, aadharid: this.aadharid.value } } | |
async isCompleted() { return this.aadharid.value && this.aadharid.value.length == 12 } | |
getQuestions() { return "Enter a valid aadhar id" } | |
nextStoryName() { return OTPVerifyStory } | |
preDestroy() { this.status.innerText = 'validating aadhar details...'; return new Promise(res => setTimeout(() => res(), 1000)) } | |
tell() { | |
return render('aadhar', { | |
ele: 'div', children: [ | |
{ ele: 'span', iden: 'status', attribs: { style: 'display: block'} }, | |
{ ele: 'input', iden: 'aadharid', label: 'Aadhar ID' } | |
] | |
}, (id, ele) => this[id] = ele) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<body> | |
<style> | |
.storyboard-content { padding: 10px; } | |
.storyboard-titlebar { padding: 10px 0px; } | |
.storyboard-errmsg { color: red; } | |
.storyboard-title { font-weight: bolder; font-size: 1.1em; } | |
input, select { display: block; margin: 5px 10px; padding: 5px; min-width: 200px; } | |
button { padding: 5px 10px; margin-right: 10px; } | |
</style> | |
<div id="storyBoard"></div> | |
<script> | |
let storyTeller = new StoryTeller(document.getElementById('storyBoard'), PinCodeStory, {}) | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class LocationPickerStory { | |
constructor(args) { this.args = args; } | |
title() { return "Pick a location for vaccination" } | |
moral() { return { ...this.args, location: this.location.value } } | |
async isCompleted() { return true } | |
getQuestions() { return "Pick a valid location" } | |
nextStoryName() { return SummaryStory } | |
tell() { | |
return render('loc', { | |
ele: 'div', children: [ | |
{ ele: 'select', iden: 'location', label: 'Available Locations', children: Array.from({ length: 10 }, (v, i) => ({ ele: 'option', text: `loc ${i}`})) } | |
] | |
}, (id, ele) => this[id] = ele) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class OTPVerifyStory { | |
constructor(args) { this.args = args; } | |
title() { return "Enter the OTP" } | |
moral() { return { ...this.args } } | |
isCompleted() { return new Promise(res => setTimeout(() => res(true), 3000)) } | |
getQuestions() { return "Enter a valid PAN no" } | |
nextStoryName() { return LocationPickerStory } | |
preDestroy() { return new Promise(res => setTimeout(() => res(), 3000)) } | |
tell() { | |
let id, reset = () => { | |
alert('OTP (re)sent to your registerd mobile number') | |
let cntr = 60; | |
this.reset.disabled = true | |
setTimeout(() => { this.reset.disabled = false; this.reset.innerText = 'Resend OTP'; clearInterval(id)}, 60 * 1000) | |
id = setInterval(() => { this.reset.innerText = `Resend OTP in ${--cntr}s`}, 1000) | |
} | |
let x = render('pan', { | |
ele: 'div', children: [ | |
{ ele: 'input', iden: 'panno', label: 'OTP (sent to your registered number)' }, | |
{ ele: 'button', iden: 'reset', text: 'resend otp', attribs: { disabled: true}, evnts: { click: reset} } | |
] | |
}, (id, ele) => this[id] = ele) | |
reset() | |
return x | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PanDetailsStory { | |
constructor(args) { this.args = args; } | |
title() { return "Enter your PAN number" } | |
moral() { return { ...this.args, panno: this.panno.value } } | |
async isCompleted() { return this.panno.value && this.panno.value.length == 10 } | |
getQuestions() { return "Enter a valid PAN no" } | |
nextStoryName() { return OTPVerifyStory } | |
preDestroy() { this.status.innerText = 'validating PAN details...'; return new Promise(res => setTimeout(() => res(), 1000)) } | |
tell() { | |
return render('pan', { | |
ele: 'div', children: [ | |
{ ele: 'span', iden: 'status', attribs: { style: 'display: block'} }, | |
{ ele: 'input', iden: 'panno', label: 'PAN no' } | |
] | |
}, (id, ele) => this[id] = ele) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PinCodeStory { | |
title() { return "Enter your pincode" } | |
moral() { return { pin: this.pincode.value, idtype: this.idtype.value } } | |
async isCompleted() { return this.pincode.value && this.pincode.value.length == 6 } | |
getQuestions() { return "Enter a valid pincode" } | |
nextStoryName() { return { 'aadhar': AadharDetailsStory, 'pan': PanDetailsStory }[this.idtype.value] } | |
tell() { | |
return render('pincode', { | |
ele: 'div', children: [ | |
{ ele: 'input', iden: 'pincode', label: 'PIN code' }, | |
{ | |
ele: 'select', iden: 'idtype', label: 'Pick a government id proof type', | |
children: [ | |
{ ele: 'option', text: 'aadhar' }, | |
{ ele: 'option', text: 'pan' } | |
] | |
} | |
] | |
}, (id, ele) => this[id] = ele) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class StoryTeller { | |
constructor(storyBoardElement, firstStoryClass, args) { | |
this.stack = []; | |
render('storyboard', { | |
ele: 'div', | |
children: [{ | |
ele: 'div', classList: 'titlebar', children: [ | |
{ ele: 'button', iden: 'backbtn', attribs: { innerHTML: '←' }, evnts: { click: () => this.back() } }, | |
{ ele: 'span', classList: 'title', text: '', iden: 'title' } | |
] | |
}, | |
{ ele: 'div', classList: 'errmsg', iden: 'errmsg' }, | |
{ ele: 'div', classList: 'content', iden: 'storyBoard' }, | |
{ ele: 'button', text: 'Next', iden: 'nextbtn', evnts: { click: () => this.next() } } | |
] | |
}, (id, ele) => this[id] = ele, storyBoardElement) | |
this.tell(new firstStoryClass(args)) | |
} | |
back() { | |
this.stack.pop() | |
this.tell() | |
} | |
next() { | |
let story = this.stack[this.stack.length - 1] | |
this.nextbtn.disabled = true | |
story.isCompleted().then(val => { | |
if(!val) { | |
this.nextbtn.disabled = false | |
return (this.errmsg.innerHTML = story.getQuestions()) | |
} | |
let func = story.preDestroy ? story.preDestroy() : Promise.resolve() | |
func.then(() => { | |
if (story.nextStoryName()) | |
this.tell(new (story.nextStoryName())(story.moral())) | |
}) | |
}) | |
} | |
tell(story) { | |
if (story) this.stack.push(story) | |
story = story || this.stack[this.stack.length - 1] | |
story.ele = story.ele || story.tell(); | |
this.nextbtn.disabled = false | |
this.storyBoard.innerHTML = this.errmsg.innerHTML = '' | |
this.nextbtn.style.display = (!story.nextStoryName) ? "none" : 'block'; | |
this.backbtn.style.display = this.stack.length < 2 ? 'none' : 'inline-block'; | |
this.title.innerHTML = story.title(); | |
this.storyBoard.appendChild(story.ele) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class SummaryStory { | |
constructor(args) { this.args = args } | |
title() { return "Your ticket for vaccination" } | |
tell() { | |
return render('pan', { | |
ele: 'pre', | |
attribs: { innerText: JSON.stringify(this.args, undefined, ' ') } | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment