Cosmetics, mostly, and a few small bugs fixes
[vchess.git] / client / src / components / UpsertUser.vue
CommitLineData
c66a829b
BA
1<template lang="pug">
2div
910d631b
BA
3 input#modalUser.modal(
4 type="checkbox"
5 @change="trySetEnterTime($event)"
6 )
42a92848 7 div#upsertDiv(
910d631b
BA
8 role="dialog"
9 data-checkbox="modalUser"
10 )
c66a829b
BA
11 .card
12 label.modal-close(for="modalUser")
8bbf9c02
BA
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 | )
725da57f 28 div(@keyup.enter="onSubmit()")
c66a829b
BA
29 div(v-show="stage!='Login'")
30 fieldset
09d37571
BA
31 label(for="u_username") {{ st.tr["User name"] }}
32 input#u_username(
910d631b 33 type="text"
09d37571 34 v-model="user.name"
910d631b 35 )
c66a829b 36 fieldset
09d37571
BA
37 label(for="u_useremail") {{ st.tr["Email"] }}
38 input#u_useremail(
910d631b 39 type="email"
09d37571 40 v-model="user.email"
910d631b 41 )
c66a829b 42 fieldset
602d6bef 43 label(for="notifyNew") {{ st.tr["Notifications by email"] }}
910d631b
BA
44 input#notifyNew(
45 type="checkbox"
09d37571 46 v-model="user.notify"
910d631b 47 )
c66a829b
BA
48 div(v-show="stage=='Login'")
49 fieldset
5fe7e71c 50 label(for="nameOrEmail") {{ st.tr["Name or Email"] }}
910d631b
BA
51 input#nameOrEmail(
52 type="text"
53 v-model="nameOrEmail"
54 )
8bbf9c02
BA
55 button#submitBtn(@click="onSubmit()")
56 | {{ st.tr[submitMessage] }}
9a3049f3 57 #dialog.text-center {{ st.tr[infoMsg] }}
c66a829b
BA
58</template>
59
60<script>
61import { store } from "@/store";
f05815d7
BA
62import { checkNameEmail } from "@/data/userCheck";
63import { ajax } from "@/utils/ajax";
42a92848 64import { processModalClick } from "@/utils/modalClick.js";
c66a829b 65export default {
6808d7a1 66 name: "my-upsert-user",
f05815d7
BA
67 data: function() {
68 return {
f05815d7 69 nameOrEmail: "", //for login
deca03e8 70 logStage: "Login", //or Register
f05815d7
BA
71 infoMsg: "",
72 enterTime: Number.MAX_SAFE_INTEGER, //for a basic anti-bot strategy
09d37571
BA
73 st: store.state,
74 user: {}
f05815d7
BA
75 };
76 },
42a92848
BA
77 mounted: function() {
78 document.getElementById("upsertDiv")
79 .addEventListener("click", processModalClick);
80 },
dac39588
BA
81 watch: {
82 nameOrEmail: function(newValue) {
6808d7a1 83 if (newValue.indexOf("@") >= 0) {
09d37571
BA
84 this.user.email = newValue;
85 this.user.name = "";
6808d7a1 86 } else {
09d37571
BA
87 this.user.name = newValue;
88 this.user.email = "";
dac39588 89 }
6808d7a1 90 }
dac39588 91 },
f05815d7
BA
92 computed: {
93 submitMessage: function() {
6808d7a1 94 switch (this.stage) {
f05815d7
BA
95 case "Login":
96 return "Go";
97 case "Register":
98 return "Send";
99 case "Update":
100 return "Apply";
101 }
6808d7a1 102 return "Never reached";
f05815d7 103 },
deca03e8 104 stage: function() {
a3ac374b 105 return this.st.user.id > 0 ? "Update" : this.logStage;
6808d7a1 106 }
f05815d7
BA
107 },
108 methods: {
109 trySetEnterTime: function(event) {
6808d7a1 110 if (event.target.checked) {
9a3049f3 111 this.infoMsg = "";
f05815d7 112 this.enterTime = Date.now();
09d37571
BA
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 };
9a3049f3 119 }
f05815d7
BA
120 },
121 toggleStage: function() {
122 // Loop login <--> register (update is for logged-in users)
6808d7a1 123 this.logStage = this.logStage == "Login" ? "Register" : "Login";
f05815d7
BA
124 },
125 ajaxUrl: function() {
6808d7a1 126 switch (this.stage) {
f05815d7
BA
127 case "Login":
128 return "/sendtoken";
129 case "Register":
130 return "/register";
131 case "Update":
132 return "/update";
133 }
6808d7a1 134 return "Never reached";
f05815d7
BA
135 },
136 ajaxMethod: function() {
6808d7a1 137 switch (this.stage) {
f05815d7
BA
138 case "Login":
139 return "GET";
140 case "Register":
141 return "POST";
142 case "Update":
143 return "PUT";
144 }
6808d7a1 145 return "Never reached";
f05815d7
BA
146 },
147 infoMessage: function() {
6808d7a1 148 switch (this.stage) {
f05815d7
BA
149 case "Login":
150 return "Connection token sent. Check your emails!";
151 case "Register":
f0c68a04 152 return "Registration complete! Please check your emails now";
f05815d7
BA
153 case "Update":
154 return "Modifications applied!";
155 }
6808d7a1 156 return "Never reached";
f05815d7
BA
157 },
158 onSubmit: function() {
159 // Basic anti-bot strategy:
160 const exitTime = Date.now();
6808d7a1 161 if (this.stage == "Register" && exitTime - this.enterTime < 5000) return;
f05815d7 162 let error = undefined;
6808d7a1
BA
163 if (this.stage == "Login") {
164 const type = this.nameOrEmail.indexOf("@") >= 0 ? "email" : "name";
165 error = checkNameEmail({ [type]: this.nameOrEmail });
0705a80c
BA
166 }
167 else error = checkNameEmail(this.user);
6808d7a1 168 if (error) {
866842c3 169 alert(this.st.tr[error]);
6808d7a1 170 return;
f05815d7 171 }
f05815d7 172 this.infoMsg = "Processing... Please wait";
6808d7a1
BA
173 ajax(
174 this.ajaxUrl(),
175 this.ajaxMethod(),
e57c4de4
BA
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);
09d37571 195 }
f05815d7
BA
196 }
197 );
198 },
deca03e8 199 doLogout: function() {
a3ac374b
BA
200 document.getElementById("modalUser").checked = false;
201 this.$router.push("/logout");
6808d7a1
BA
202 }
203 }
c66a829b
BA
204};
205</script>
9a3049f3
BA
206
207<style lang="sass" scoped>
208[type="checkbox"].modal+div .card
e71161fb 209 max-width: 450px
9a3049f3 210 max-height: 100%
910d631b 211
8bbf9c02
BA
212h3.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
9a3049f3
BA
228#dialog
229 padding: 5px
230 color: blue
231</style>