Settings.jsx 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. import React, { Component } from "react";
  2. import PropTypes from "prop-types";
  3. import { connect } from "react-redux";
  4. import CustomInput from "./CustomInput.jsx";
  5. import CustomErrors from "./CustomErrors.jsx";
  6. import io from "../../io";
  7. @connect(state => ({
  8. user: {
  9. userId: state.user.get("userId"),
  10. },
  11. }))
  12. export default class Settings extends Component {
  13. static propTypes = {
  14. user: PropTypes.object,
  15. };
  16. static defaultProps = {
  17. user: {
  18. userId: "",
  19. },
  20. };
  21. constructor(props) {
  22. super(props);
  23. this.state = {
  24. email: "",
  25. username: "",
  26. currentPassword: "",
  27. newPassword: "",
  28. newPasswordAgain: "",
  29. passwordLinked: false,
  30. gitHubLinked: false,
  31. inputInvalid: {
  32. email: true,
  33. username: true,
  34. newPassword: true,
  35. },
  36. errors: [],
  37. savedValue: {
  38. email: "",
  39. username: "",
  40. },
  41. };
  42. this.customInputs = {};
  43. io.getSocket(socket => {
  44. socket.emit("users.findBySession", res => {
  45. if (res.status === "success") {
  46. this.setState({
  47. email: res.data.email.address,
  48. username: res.data.username,
  49. passwordLinked: res.data.password,
  50. gitHubLinked: res.data.github,
  51. savedValue: {
  52. email: res.data.email.address,
  53. username: res.data.username,
  54. },
  55. }, () => {
  56. this.customInputs.email.triggerChangeEvent(true);
  57. this.customInputs.username.triggerChangeEvent(true);
  58. });
  59. } else {
  60. this.state.errors = ["You are currently not logged in."];
  61. }
  62. });
  63. socket.on("event:user.username.changed", username => {
  64. this.setState({
  65. username,
  66. savedValue: {
  67. username,
  68. },
  69. }, () => {
  70. this.customInputs.username.triggerChangeEvent(true);
  71. });
  72. });
  73. // TODO Email changed event?
  74. socket.on("event:user.linkPassword", () => {
  75. this.setState({
  76. passwordLinked: true,
  77. });
  78. });
  79. socket.on("event:user.linkGitHub", () => {
  80. this.setState({
  81. gitHubLinked: true,
  82. });
  83. });
  84. socket.on("event:user.unlinkPassword", () => {
  85. this.setState({
  86. passwordLinked: false,
  87. });
  88. });
  89. socket.on("event:user.unlinkGitHub", () => {
  90. this.setState({
  91. gitHubLinked: false,
  92. });
  93. });
  94. });
  95. }
  96. updateField(field, event) {
  97. this.setState({
  98. [field]: event.target.value,
  99. });
  100. }
  101. /* githubRedirect() {
  102. localStorage.setItem("github_redirect", window.location.pathname);
  103. } */
  104. isTheSame = (type) => {
  105. return this.state[type] === this.state.savedValue[type];
  106. };
  107. saveChanges = () => {
  108. if (CustomInput.hasInvalidInput(this.state.inputInvalid, ["username", "email"])) {
  109. alert("Input invalid. Fix before continuing.");
  110. } else if (this.isTheSame("username") && this.isTheSame("email")) {
  111. alert("Nothing has changed.");
  112. } else {
  113. this.setState({ errors: [] });
  114. const email = this.state.email;
  115. const username = this.state.username;
  116. io.getSocket(socket => {
  117. if (!this.isTheSame("email")) {
  118. socket.emit("users.updateEmail", this.props.user.userId, email, res => {
  119. if (res.status === "success") {
  120. alert("Success!");
  121. } else {
  122. this.setState({
  123. errors: this.state.errors.concat([res.message]),
  124. });
  125. }
  126. });
  127. }
  128. if (!this.isTheSame("username")) {
  129. socket.emit("users.updateUsername", this.props.user.userId, username, res => {
  130. if (res.status === "success") {
  131. alert("Success!");
  132. } else {
  133. this.setState({
  134. errors: this.state.errors.concat([res.message]),
  135. });
  136. }
  137. });
  138. }
  139. });
  140. }
  141. };
  142. changePassword = () => {
  143. if (CustomInput.hasInvalidInput(this.state.inputInvalid, ["newPassword"])) {
  144. alert("Input invalid. Fix before continuing.");
  145. } else if (!this.state.passwordLinked) {
  146. alert("You don't have a password yet");
  147. } else {
  148. this.setState({ errors: [] });
  149. const newPassword = this.state.newPassword;
  150. io.getSocket(socket => {
  151. socket.emit("users.updatePassword", newPassword, res => {
  152. if (res.status === "success") {
  153. alert("Success!");
  154. } else {
  155. this.setState({
  156. errors: this.state.errors.concat([res.message]),
  157. });
  158. }
  159. });
  160. });
  161. }
  162. };
  163. validationCallback = CustomInput.validationCallback(this);
  164. render() {
  165. return (
  166. <div>
  167. <CustomErrors errors={ this.state.errors } />
  168. <div>
  169. <h2>General</h2>
  170. <CustomInput label="Email" placeholder="Email" inputType="email" type="email" name="email" value={ this.state.email } customInputEvents={ { onChange: event => this.updateField("email", event) } } validationCallback={ this.validationCallback } onRef={ ref => (this.customInputs.email = ref) } />
  171. <CustomInput label="Username" placeholder="Username" inputType="text" type="username" name="username" value={ this.state.username } customInputEvents={ { onChange: event => this.updateField("username", event) } } validationCallback={ this.validationCallback } onRef={ ref => (this.customInputs.username = ref) } />
  172. <button onClick={ this.saveChanges }>Save changes</button>
  173. </div>
  174. <div>
  175. <h2>Security</h2>
  176. <CustomInput label="New password" placeholder="New password" inputType="password" type="password" name="newPassword" value={ this.state.newPassword } customInputEvents={ { onChange: event => this.updateField("newPassword", event) } } validationCallback={ this.validationCallback } />
  177. <button onClick={ this.changePassword }>Change password</button>
  178. <button>Link GitHub account</button>
  179. <button>Log out everywhere</button>
  180. </div>
  181. </div>
  182. );
  183. }
  184. }