author | Giulio Cesare Solaroli <giulio.cesare@clipperz.com> | 2013-08-30 15:56:53 (UTC) |
---|---|---|
committer | Giulio Cesare Solaroli <giulio.cesare@clipperz.com> | 2013-08-30 21:23:42 (UTC) |
commit | 20bea94ab6b91c85b171dcf86baba0a64169d508 (patch) (unidiff) | |
tree | 6e38e91498dcdb861620eba1e237d1026fe79cc5 /frontend/delta/js/Clipperz/PM/UI/Components/RegistrationWizard.js | |
parent | bde3c7b98523112ade9c5bbf7390c4ecb494cd2e (diff) | |
download | clipperz-20bea94ab6b91c85b171dcf86baba0a64169d508.zip clipperz-20bea94ab6b91c85b171dcf86baba0a64169d508.tar.gz clipperz-20bea94ab6b91c85b171dcf86baba0a64169d508.tar.bz2 |
First release of /delta version
Diffstat (limited to 'frontend/delta/js/Clipperz/PM/UI/Components/RegistrationWizard.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/delta/js/Clipperz/PM/UI/Components/RegistrationWizard.js | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/RegistrationWizard.js b/frontend/delta/js/Clipperz/PM/UI/Components/RegistrationWizard.js new file mode 100644 index 0000000..051dcc5 --- a/dev/null +++ b/frontend/delta/js/Clipperz/PM/UI/Components/RegistrationWizard.js | |||
@@ -0,0 +1,240 @@ | |||
1 | /* | ||
2 | |||
3 | Copyright 2008-2013 Clipperz Srl | ||
4 | |||
5 | This file is part of Clipperz, the online password manager. | ||
6 | For further information about its features and functionalities please | ||
7 | refer to http://www.clipperz.com. | ||
8 | |||
9 | * Clipperz is free software: you can redistribute it and/or modify it | ||
10 | under the terms of the GNU Affero General Public License as published | ||
11 | by the Free Software Foundation, either version 3 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | * Clipperz is distributed in the hope that it will be useful, but | ||
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
17 | See the GNU Affero General Public License for more details. | ||
18 | |||
19 | * You should have received a copy of the GNU Affero General Public | ||
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | ||
21 | |||
22 | */ | ||
23 | |||
24 | Clipperz.PM.UI.Components.RegistrationWizard = React.createClass({ | ||
25 | |||
26 | getDefaultProps: function () { | ||
27 | return { | ||
28 | steps: [ | ||
29 | {name:'CREDENTIALS', label:'registration', _label:'credentials',description:"Choose your credentails"}, | ||
30 | {name:'PASSWORD_VERIFICATION', label:'registration', _label:'verify', description:"Verify your passphrase"}, | ||
31 | {name:'TERMS_OF_SERVICE', label:'registration', _label:'terms', description:"Check our terms of service"} | ||
32 | ], | ||
33 | disabled: false, | ||
34 | template: Clipperz.PM.UI.Components.PageTemplate | ||
35 | } | ||
36 | }, | ||
37 | |||
38 | getInitialState: function () { | ||
39 | return { | ||
40 | currentStep: this.props['steps'][0]['name'], | ||
41 | username: '', | ||
42 | passphrase: '', | ||
43 | verify_passphrase: '', | ||
44 | no_password_recovery: false, | ||
45 | agree_terms_of_service: false | ||
46 | }; | ||
47 | }, | ||
48 | |||
49 | 'propTypes': { | ||
50 | // steps: React.PropTypes.array, | ||
51 | disabled:React.PropTypes.bool, | ||
52 | template:React.PropTypes.func | ||
53 | }, | ||
54 | |||
55 | //========================================================================= | ||
56 | |||
57 | currentStepIndex: function () { | ||
58 | return this.indexOfStepNamed(this.state['currentStep']); | ||
59 | }, | ||
60 | |||
61 | indexOfStepNamed: function (aStepName) { | ||
62 | var stepConfiguration; | ||
63 | varresult; | ||
64 | |||
65 | stepConfiguration = this.props['steps'].filter(function (aConfig) { return aConfig['name'] == aStepName})[0]; | ||
66 | result = this.props['steps'].indexOf(stepConfiguration); | ||
67 | return result; | ||
68 | }, | ||
69 | |||
70 | //========================================================================= | ||
71 | |||
72 | statusClassForStep: function (aStep) { | ||
73 | varcurrentStepIndex = this.currentStepIndex(); | ||
74 | var stepIndex = this.indexOfStepNamed(aStep['name']); | ||
75 | varresult; | ||
76 | |||
77 | if (stepIndex < currentStepIndex) { | ||
78 | result = 'left'; | ||
79 | } else if (stepIndex == currentStepIndex) { | ||
80 | result = 'center'; | ||
81 | } else { | ||
82 | result = 'right'; | ||
83 | } | ||
84 | |||
85 | return result; | ||
86 | }, | ||
87 | |||
88 | //========================================================================= | ||
89 | |||
90 | handleBackClick: function (anEvent) { | ||
91 | var nextStep; | ||
92 | anEvent.preventDefault(); | ||
93 | |||
94 | if (this.currentStepIndex() > 0) { | ||
95 | nextStep = this.props['steps'][this.currentStepIndex() - 1]; | ||
96 | this.setState({currentStep: nextStep['name']}); | ||
97 | } else { | ||
98 | MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'goBack'); | ||
99 | } | ||
100 | }, | ||
101 | |||
102 | handleForwardClick: function (anEvent) { | ||
103 | var nextStep; | ||
104 | anEvent.preventDefault(); | ||
105 | |||
106 | if (this.canMoveForward()) { | ||
107 | |||
108 | if (this.currentStepIndex() < this.props['steps'].length - 1) { | ||
109 | nextStep = this.props['steps'][this.currentStepIndex() + 1]; | ||
110 | this.setState({currentStep: nextStep['name']}); | ||
111 | } else { | ||
112 | MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'registerNewUser', { | ||
113 | username: this.state['username'], | ||
114 | passphrase: this.state['passphrase'] | ||
115 | }) | ||
116 | } | ||
117 | } | ||
118 | }, | ||
119 | |||
120 | //------------------------------------------------------------------------- | ||
121 | |||
122 | canMoveForward: function () { | ||
123 | var result; | ||
124 | var currentStep; | ||
125 | |||
126 | result = false; | ||
127 | currentStep = this.state['currentStep']; | ||
128 | if (currentStep == 'CREDENTIALS') { | ||
129 | result = ((this.state['username'] != '') && (this.state['passphrase'] != '')); | ||
130 | } else if (currentStep == 'PASSWORD_VERIFICATION') { | ||
131 | result = (this.state['passphrase'] == this.state['verify_passphrase']); | ||
132 | } else if (currentStep == 'TERMS_OF_SERVICE') { | ||
133 | result = (this.state['no_password_recovery'] && this.state['agree_terms_of_service']); | ||
134 | } | ||
135 | |||
136 | return result && !this.props['disabled']; | ||
137 | }, | ||
138 | |||
139 | //========================================================================= | ||
140 | |||
141 | handleChange: function (anEvent) { | ||
142 | varrefs = this.refs; | ||
143 | var refName = MochiKit.Base.filter(function (aRefName) { return refs[aRefName].getDOMNode() == anEvent.target}, MochiKit.Base.keys(this.refs))[0]; | ||
144 | var newState = {}; | ||
145 | |||
146 | if ((event.target.type == 'checkbox') || (event.target.type == 'radio')) { | ||
147 | newState[refName] = event.target.checked; | ||
148 | } else { | ||
149 | newState[refName] = event.target.value; | ||
150 | } | ||
151 | this.setState(newState); | ||
152 | }, | ||
153 | |||
154 | //========================================================================= | ||
155 | |||
156 | renderIndexStep: function (aStep) { | ||
157 | returnReact.DOM.div({'className':'stepIndexItem ' + this.statusClassForStep(aStep)}, '.'); | ||
158 | }, | ||
159 | |||
160 | renderButtons: function () { | ||
161 | return [ | ||
162 | React.DOM.a({className:'back button step_' + (this.currentStepIndex() - 1), onClick:this.handleBackClick}, '<<'), | ||
163 | React.DOM.a({className:'forward button step_' + (this.currentStepIndex() + 1) + ' ' + (this.canMoveForward() ? 'enabled' : 'disabled'), onClick:this.handleForwardClick}, '>>') | ||
164 | ]; | ||
165 | }, | ||
166 | |||
167 | render_CREDENTIALS: function () { | ||
168 | returnReact.DOM.div(null,[ | ||
169 | React.DOM.label({'for':'name'}, "username"), | ||
170 | React.DOM.input({'type':'text', 'name':'name', 'ref':'username', 'placeholder':"username", 'key':'username', 'autoCapitalize':'none'/*, value:this.state.username*/}), | ||
171 | React.DOM.label({'for':'passphrase'}, "passphrase"), | ||
172 | React.DOM.input({'type':'password', 'name':'passphrase', 'ref':'passphrase', 'placeholder':"passphrase", 'key':'passphrase'/*, value:this.state.passphrase*/}) | ||
173 | ]); | ||
174 | }, | ||
175 | |||
176 | render_PASSWORD_VERIFICATION: function () { | ||
177 | returnReact.DOM.div(null,[ | ||
178 | React.DOM.label({'for':'verify_passphrase'}, "passphrase"), | ||
179 | React.DOM.input({'type':'password', 'name':'verify_passphrase', 'ref':'verify_passphrase', 'placeholder':"verify passphrase", 'key':'verify_passphrase'}) | ||
180 | ]); | ||
181 | }, | ||
182 | |||
183 | render_TERMS_OF_SERVICE: function () { | ||
184 | returnReact.DOM.div(null, [ | ||
185 | React.DOM.div({className:'checkboxBlock'}, [ | ||
186 | React.DOM.label({'for':'no_password_recovery'}, "I understand that Clipperz will not be able to recover a lost passphrase."), | ||
187 | React.DOM.input({'type':'checkbox', 'name':'no_password_recovery', 'ref':'no_password_recovery', 'key':'no_password_recovery'}), | ||
188 | React.DOM.p(null, "I understand that Clipperz will not be able to recover a lost passphrase.") | ||
189 | ]), | ||
190 | React.DOM.div({className:'checkboxBlock'}, [ | ||
191 | React.DOM.label({'for':'agree_terms_of_service'}, "I have read and agreed to the Terms of Service."), | ||
192 | React.DOM.input({'type':'checkbox', 'name':'agree_terms_of_service', 'ref':'agree_terms_of_service', 'key':'agree_terms_of_service'}), | ||
193 | React.DOM.p(null, [ | ||
194 | "I have read and agreed to the ", | ||
195 | React.DOM.a({href:'https://clipperz.com/terms_service/', target:'_blank'}, "Terms of Service.") | ||
196 | ]) | ||
197 | ]) | ||
198 | ]); | ||
199 | }, | ||
200 | |||
201 | renderStep: function (aStep) { | ||
202 | returnReact.DOM.div({'className':'step' + ' ' + aStep['name'] + ' ' + this.statusClassForStep(aStep) + ' step_' + this.currentStepIndex()}, [ | ||
203 | React.DOM.h1(null, aStep['label']), | ||
204 | React.DOM.p(null, aStep['description']), | ||
205 | this['render_' + aStep['name']].apply(), | ||
206 | React.DOM.div({'className':'stepIndex'}, MochiKit.Base.map(this.renderIndexStep, this.props['steps'])), | ||
207 | React.DOM.div({'className':'buttons'}, this.renderButtons()) | ||
208 | ]); | ||
209 | }, | ||
210 | |||
211 | _render: function () { | ||
212 | returnReact.DOM.div({'className':'registrationForm'},[ | ||
213 | React.DOM.form({onChange: this.handleChange}, [ | ||
214 | React.DOM.div({'className':'steps'}, MochiKit.Base.map(this.renderStep, this.props['steps'])) | ||
215 | ]) | ||
216 | ]); | ||
217 | }, | ||
218 | |||
219 | render: function () { | ||
220 | returnnew this.props.template({'innerComponent': this._render()}); | ||
221 | }, | ||
222 | |||
223 | //========================================================================= | ||
224 | |||
225 | setInitialFocus: function () { | ||
226 | this.refs['username'].getDOMNode().focus(); | ||
227 | }, | ||
228 | |||
229 | componentDidUpdate: function (prevProps, prevState, rootNode) { | ||
230 | if (prevState['currentStep'] != this.state['currentStep']) { | ||
231 | if (this.state['currentStep'] == 'CREDENTIALS') { | ||
232 | this.refs['passphrase'].getDOMNode().select(); | ||
233 | } else if (this.state['currentStep'] == 'PASSWORD_VERIFICATION') { | ||
234 | this.refs['verify_passphrase'].getDOMNode().select(); | ||
235 | } | ||
236 | } | ||
237 | } | ||
238 | |||
239 | //========================================================================= | ||
240 | }); | ||