Cosmetics, mostly, and a few small bugs fixes
[vchess.git] / client / src / components / UpsertUser.vue
1 <template lang="pug">
2 div
3 input#modalUser.modal(
4 type="checkbox"
5 @change="trySetEnterTime($event)"
6 )
7 div#upsertDiv(
8 role="dialog"
9 data-checkbox="modalUser"
10 )
11 .card
12 label.modal-close(for="modalUser")
13 h3.section
14 span.title {{ st.tr[stage] }}
15 | (
16 span.link(
17 v-if="stage!='Update'"
18 @click="toggleStage()"
19 )
20 | {{ st.tr[stage=="Login" ? "Register" : "Login"] }}
21 span.link(
22 v-else
23 @click="doLogout()"
24 )
25 | {{ st.tr["Logout"] }}
26 img(src="/images/icons/rightArrow.svg")
27 | )
28 div(@keyup.enter="onSubmit()")
29 div(v-show="stage!='Login'")
30 fieldset
31 label(for="u_username") {{ st.tr["User name"] }}
32 input#u_username(
33 type="text"
34 v-model="user.name"
35 )
36 fieldset
37 label(for="u_useremail") {{ st.tr["Email"] }}
38 input#u_useremail(
39 type="email"
40 v-model="user.email"
41 )
42 fieldset
43 label(for="notifyNew") {{ st.tr["Notifications by email"] }}
44 input#notifyNew(
45 type="checkbox"
46 v-model="user.notify"
47 )
48 div(v-show="stage=='Login'")
49 fieldset
50 label(for="nameOrEmail") {{ st.tr["Name or Email"] }}
51 input#nameOrEmail(
52 type="text"
53 v-model="nameOrEmail"
54 )
55 button#submitBtn(@click="onSubmit()")
56 | {{ st.tr[submitMessage] }}
57 #dialog.text-center {{ st.tr[infoMsg] }}
58 </template>
59
60 <script>
61 import { store } from "@/store";
62 import { checkNameEmail } from "@/data/userCheck";
63 import { ajax } from "@/utils/ajax";
64 import { processModalClick } from "@/utils/modalClick.js";
65 export default {
66 name: "my-upsert-user",
67 data: function() {
68 return {
69 nameOrEmail: "", //for login
70 logStage: "Login", //or Register
71 infoMsg: "",
72 enterTime: Number.MAX_SAFE_INTEGER, //for a basic anti-bot strategy
73 st: store.state,
74 user: {}
75 };
76 },
77 mounted: function() {
78 document.getElementById("upsertDiv")
79 .addEventListener("click", processModalClick);
80 },
81 watch: {
82 nameOrEmail: function(newValue) {
83 if (newValue.indexOf("@") >= 0) {
84 this.user.email = newValue;
85 this.user.name = "";
86 } else {
87 this.user.name = newValue;
88 this.user.email = "";
89 }
90 }
91 },
92 computed: {
93 submitMessage: function() {
94 switch (this.stage) {
95 case "Login":
96 return "Go";
97 case "Register":
98 return "Send";
99 case "Update":
100 return "Apply";
101 }
102 return "Never reached";
103 },
104 stage: function() {
105 return this.st.user.id > 0 ? "Update" : this.logStage;
106 }
107 },
108 methods: {
109 trySetEnterTime: function(event) {
110 if (event.target.checked) {
111 this.infoMsg = "";
112 this.enterTime = Date.now();
113 document.getElementById("u_username").focus();
114 this.user = {
115 name: this.st.user.name,
116 email: this.st.user.email,
117 notify: this.st.user.notify
118 };
119 }
120 },
121 toggleStage: function() {
122 // Loop login <--> register (update is for logged-in users)
123 this.logStage = this.logStage == "Login" ? "Register" : "Login";
124 },
125 ajaxUrl: function() {
126 switch (this.stage) {
127 case "Login":
128 return "/sendtoken";
129 case "Register":
130 return "/register";
131 case "Update":
132 return "/update";
133 }
134 return "Never reached";
135 },
136 ajaxMethod: function() {
137 switch (this.stage) {
138 case "Login":
139 return "GET";
140 case "Register":
141 return "POST";
142 case "Update":
143 return "PUT";
144 }
145 return "Never reached";
146 },
147 infoMessage: function() {
148 switch (this.stage) {
149 case "Login":
150 return "Connection token sent. Check your emails!";
151 case "Register":
152 return "Registration complete! Please check your emails now";
153 case "Update":
154 return "Modifications applied!";
155 }
156 return "Never reached";
157 },
158 onSubmit: function() {
159 // Basic anti-bot strategy:
160 const exitTime = Date.now();
161 if (this.stage == "Register" && exitTime - this.enterTime < 5000) return;
162 let error = undefined;
163 if (this.stage == "Login") {
164 const type = this.nameOrEmail.indexOf("@") >= 0 ? "email" : "name";
165 error = checkNameEmail({ [type]: this.nameOrEmail });
166 }
167 else error = checkNameEmail(this.user);
168 if (error) {
169 alert(this.st.tr[error]);
170 return;
171 }
172 this.infoMsg = "Processing... Please wait";
173 ajax(
174 this.ajaxUrl(),
175 this.ajaxMethod(),
176 {
177 credentials: true,
178 data: (
179 this.stage == "Login"
180 ? { nameOrEmail: this.nameOrEmail }
181 : this.user
182 ),
183 success: () => {
184 this.infoMsg = this.infoMessage();
185 if (this.stage != "Update") this.nameOrEmail = "";
186 else {
187 this.st.user.name = this.user.name;
188 this.st.user.email = this.user.email;
189 this.st.user.notify = this.user.notify;
190 }
191 },
192 error: (err) => {
193 this.infoMsg = "";
194 alert(err);
195 }
196 }
197 );
198 },
199 doLogout: function() {
200 document.getElementById("modalUser").checked = false;
201 this.$router.push("/logout");
202 }
203 }
204 };
205 </script>
206
207 <style lang="sass" scoped>
208 [type="checkbox"].modal+div .card
209 max-width: 450px
210 max-height: 100%
211
212 h3.section
213 span.title
214 padding-right: 10px
215 span.link
216 color: darkred
217 font-size: 0.8em
218 text-decoration: underline
219 cursor: pointer
220 img
221 height: 1em
222 padding-left: 5px
223
224 #submitBtn
225 width: 50%
226 margin: 0 auto
227
228 #dialog
229 padding: 5px
230 color: blue
231 </style>