Step toward a one-page application
[vchess.git] / public / javascripts / components / upsertUser.js
1 // Logic to login, or create / update a user (and also logout)
2 vv = Vue.component('my-upsert-user', {
3 data: function() {
4 return {
5 user: user, //initialized with global user object
6 nameOrEmail: "", //for login
7 stage: (!user.email ? "Login" : "Update"),
8 infoMsg: "",
9 enterTime: Number.MAX_SAFE_INTEGER, //for a basic anti-bot strategy
10 };
11 },
12 template: `
13 <div>
14 <input id="modalUser" class="modal" type="checkbox"
15 @change="trySetEnterTime"/>
16 <div role="dialog">
17 <div class="card">
18 <label class="modal-close" for="modalUser"></label>
19 <h3>{{ stage }}</h3>
20 <form id="userForm" @submit.prevent="onSubmit()">
21 <div v-show="stage!='Login'">
22 <fieldset>
23 <label for="username">Name</label>
24 <input id="username" type="text" v-model="user.name"/>
25 </fieldset>
26 <fieldset>
27 <label for="useremail">Email</label>
28 <input id="useremail" type="email" v-model="user.email"/>
29 </fieldset>
30 <fieldset>
31 <label for="notifyNew">Notify new moves &amp; games</label>
32 <input id="notifyNew" type="checkbox" v-model="user.notify"/>
33 </fieldset>
34 </div>
35 <div v-show="stage=='Login'">
36 <fieldset>
37 <label for="nameOrEmail">Name or Email</label>
38 <input id="nameOrEmail" type="text" v-model="nameOrEmail"/>
39 </fieldset>
40 </div>
41 </form>
42 <div class="button-group">
43 <button id="submit" @click="onSubmit()">
44 <span>{{ submitMessage }}</span>
45 <i class="material-icons">send</i>
46 </button>
47 <button v-if="stage!='Update'" @click="toggleStage()">
48 <span>{{ stage=="Login" ? "Register" : "Login" }}</span>
49 </button>
50 <button v-if="stage=='Update'" onClick="location.replace('/logout')">
51 <span>Logout</span>
52 </button>
53 </div>
54 <div id="dialog" :style="{display: displayInfo}">{{ infoMsg }}</div>
55 </div>
56 </div>
57 </div>
58 `,
59 computed: {
60 submitMessage: function() {
61 switch (this.stage)
62 {
63 case "Login":
64 return "Go";
65 case "Register":
66 return "Send";
67 case "Update":
68 return "Apply";
69 }
70 },
71 displayInfo: function() {
72 return (this.infoMsg.length > 0 ? "block" : "none");
73 },
74 },
75 methods: {
76 trySetEnterTime: function(event) {
77 if (!!event.target.checked)
78 this.enterTime = Date.now();
79 },
80 toggleStage: function() {
81 // Loop login <--> register (update is for logged-in users)
82 this.stage = (this.stage == "Login" ? "Register" : "Login");
83 },
84 ajaxUrl: function() {
85 switch (this.stage)
86 {
87 case "Login":
88 return "/sendtoken";
89 case "Register":
90 return "/register";
91 case "Update":
92 return "/update";
93 }
94 },
95 ajaxMethod: function() {
96 switch (this.stage)
97 {
98 case "Login":
99 return "GET";
100 case "Register":
101 return "POST";
102 case "Update":
103 return "PUT";
104 }
105 },
106 infoMessage: function() {
107 switch (this.stage)
108 {
109 case "Login":
110 return "Connection token sent. Check your emails!";
111 case "Register":
112 return "Registration complete! Please check your emails.";
113 case "Update":
114 return "Modifications applied!";
115 }
116 },
117 onSubmit: function() {
118 // Basic anti-bot strategy:
119 const exitTime = Date.now();
120 if (this.stage == "Register" && exitTime - this.enterTime < 5000)
121 return; //silently return, in (curious) case of it was legitimate
122 let error = undefined;
123 if (this.stage == 'Login')
124 {
125 const type = (this.nameOrEmail.indexOf('@') >= 0 ? "email" : "name");
126 error = checkNameEmail({[type]: this.nameOrEmail});
127 }
128 else
129 error = checkNameEmail(this.user);
130 if (!!error)
131 return alert(error);
132 this.infoMsg = "Processing... Please wait";
133 ajax(this.ajaxUrl(), this.ajaxMethod(),
134 this.stage == "Login" ? { nameOrEmail: this.nameOrEmail } : this.user,
135 res => {
136 this.infoMsg = this.infoMessage();
137 if (this.stage != "Update")
138 {
139 this.nameOrEmail = "";
140 this.user["email"] = "";
141 this.user["name"] = "";
142 }
143 setTimeout(() => {
144 this.infoMsg = "";
145 if (this.stage == "Register")
146 this.stage = "Login";
147 document.getElementById("modalUser").checked = false;
148 }, 2000);
149 },
150 err => {
151 this.infoMsg = "";
152 alert(err);
153 }
154 );
155 },
156 }
157 });