Better Ball rules. Buggish but almost OK Synchrone variant
[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")
9a3049f3 13 h3.section {{ st.tr[stage] }}
725da57f 14 div(@keyup.enter="onSubmit()")
c66a829b
BA
15 div(v-show="stage!='Login'")
16 fieldset
09d37571
BA
17 label(for="u_username") {{ st.tr["User name"] }}
18 input#u_username(
910d631b 19 type="text"
09d37571 20 v-model="user.name"
910d631b 21 )
c66a829b 22 fieldset
09d37571
BA
23 label(for="u_useremail") {{ st.tr["Email"] }}
24 input#u_useremail(
910d631b 25 type="email"
09d37571 26 v-model="user.email"
910d631b 27 )
c66a829b 28 fieldset
602d6bef 29 label(for="notifyNew") {{ st.tr["Notifications by email"] }}
910d631b
BA
30 input#notifyNew(
31 type="checkbox"
09d37571 32 v-model="user.notify"
910d631b 33 )
c66a829b
BA
34 div(v-show="stage=='Login'")
35 fieldset
5fe7e71c 36 label(for="nameOrEmail") {{ st.tr["Name or Email"] }}
910d631b
BA
37 input#nameOrEmail(
38 type="text"
39 v-model="nameOrEmail"
40 )
c66a829b 41 .button-group
9a3049f3 42 button(@click="onSubmit()")
602d6bef 43 span {{ st.tr[submitMessage] }}
910d631b
BA
44 button(
45 v-if="stage!='Update'"
46 type="button"
47 @click="toggleStage()"
48 )
602d6bef 49 span {{ st.tr[stage=="Login" ? "Register" : "Login"] }}
910d631b
BA
50 button(
51 v-else type="button"
52 @click="doLogout()"
53 )
602d6bef 54 span {{ st.tr["Logout"] }}
9a3049f3 55 #dialog.text-center {{ st.tr[infoMsg] }}
c66a829b
BA
56</template>
57
58<script>
59import { store } from "@/store";
f05815d7
BA
60import { checkNameEmail } from "@/data/userCheck";
61import { ajax } from "@/utils/ajax";
42a92848 62import { processModalClick } from "@/utils/modalClick.js";
c66a829b 63export default {
6808d7a1 64 name: "my-upsert-user",
f05815d7
BA
65 data: function() {
66 return {
f05815d7 67 nameOrEmail: "", //for login
deca03e8 68 logStage: "Login", //or Register
f05815d7
BA
69 infoMsg: "",
70 enterTime: Number.MAX_SAFE_INTEGER, //for a basic anti-bot strategy
09d37571
BA
71 st: store.state,
72 user: {}
f05815d7
BA
73 };
74 },
42a92848
BA
75 mounted: function() {
76 document.getElementById("upsertDiv")
77 .addEventListener("click", processModalClick);
78 },
dac39588
BA
79 watch: {
80 nameOrEmail: function(newValue) {
6808d7a1 81 if (newValue.indexOf("@") >= 0) {
09d37571
BA
82 this.user.email = newValue;
83 this.user.name = "";
6808d7a1 84 } else {
09d37571
BA
85 this.user.name = newValue;
86 this.user.email = "";
dac39588 87 }
6808d7a1 88 }
dac39588 89 },
f05815d7
BA
90 computed: {
91 submitMessage: function() {
6808d7a1 92 switch (this.stage) {
f05815d7
BA
93 case "Login":
94 return "Go";
95 case "Register":
96 return "Send";
97 case "Update":
98 return "Apply";
99 }
6808d7a1 100 return "Never reached";
f05815d7 101 },
deca03e8 102 stage: function() {
a3ac374b 103 return this.st.user.id > 0 ? "Update" : this.logStage;
6808d7a1 104 }
f05815d7
BA
105 },
106 methods: {
107 trySetEnterTime: function(event) {
6808d7a1 108 if (event.target.checked) {
9a3049f3 109 this.infoMsg = "";
f05815d7 110 this.enterTime = Date.now();
09d37571
BA
111 document.getElementById("u_username").focus();
112 this.user = {
113 name: this.st.user.name,
114 email: this.st.user.email,
115 notify: this.st.user.notify
116 };
9a3049f3 117 }
f05815d7
BA
118 },
119 toggleStage: function() {
120 // Loop login <--> register (update is for logged-in users)
6808d7a1 121 this.logStage = this.logStage == "Login" ? "Register" : "Login";
f05815d7
BA
122 },
123 ajaxUrl: function() {
6808d7a1 124 switch (this.stage) {
f05815d7
BA
125 case "Login":
126 return "/sendtoken";
127 case "Register":
128 return "/register";
129 case "Update":
130 return "/update";
131 }
6808d7a1 132 return "Never reached";
f05815d7
BA
133 },
134 ajaxMethod: function() {
6808d7a1 135 switch (this.stage) {
f05815d7
BA
136 case "Login":
137 return "GET";
138 case "Register":
139 return "POST";
140 case "Update":
141 return "PUT";
142 }
6808d7a1 143 return "Never reached";
f05815d7
BA
144 },
145 infoMessage: function() {
6808d7a1 146 switch (this.stage) {
f05815d7
BA
147 case "Login":
148 return "Connection token sent. Check your emails!";
149 case "Register":
f0c68a04 150 return "Registration complete! Please check your emails now";
f05815d7
BA
151 case "Update":
152 return "Modifications applied!";
153 }
6808d7a1 154 return "Never reached";
f05815d7
BA
155 },
156 onSubmit: function() {
157 // Basic anti-bot strategy:
158 const exitTime = Date.now();
6808d7a1 159 if (this.stage == "Register" && exitTime - this.enterTime < 5000) return;
f05815d7 160 let error = undefined;
6808d7a1
BA
161 if (this.stage == "Login") {
162 const type = this.nameOrEmail.indexOf("@") >= 0 ? "email" : "name";
163 error = checkNameEmail({ [type]: this.nameOrEmail });
09d37571 164 } else error = checkNameEmail(this.user);
6808d7a1 165 if (error) {
866842c3 166 alert(this.st.tr[error]);
6808d7a1 167 return;
f05815d7 168 }
f05815d7 169 this.infoMsg = "Processing... Please wait";
6808d7a1
BA
170 ajax(
171 this.ajaxUrl(),
172 this.ajaxMethod(),
e57c4de4
BA
173 {
174 credentials: true,
175 data: (
176 this.stage == "Login"
177 ? { nameOrEmail: this.nameOrEmail }
178 : this.user
179 ),
180 success: () => {
181 this.infoMsg = this.infoMessage();
182 if (this.stage != "Update") this.nameOrEmail = "";
183 else {
184 this.st.user.name = this.user.name;
185 this.st.user.email = this.user.email;
186 this.st.user.notify = this.user.notify;
187 }
188 },
189 error: (err) => {
190 this.infoMsg = "";
191 alert(err);
09d37571 192 }
f05815d7
BA
193 }
194 );
195 },
deca03e8 196 doLogout: function() {
a3ac374b
BA
197 document.getElementById("modalUser").checked = false;
198 this.$router.push("/logout");
6808d7a1
BA
199 }
200 }
c66a829b
BA
201};
202</script>
9a3049f3
BA
203
204<style lang="sass" scoped>
205[type="checkbox"].modal+div .card
e71161fb 206 max-width: 450px
9a3049f3 207 max-height: 100%
910d631b 208
9a3049f3
BA
209#dialog
210 padding: 5px
211 color: blue
212</style>