You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

468 lines
17 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. <template>
  2. <div class="setting xl:tw-max-w-[1246px] xl:tw-mx-auto">
  3. <div class="xl:tw-flex xl:tw-justify-between xl:tw-items-start">
  4. <userSidebar :userData="userData" :firstName="firstName" :lastName="lastName" class="tw-hidden xl:tw-block">
  5. </userSidebar>
  6. <!-- <div class="xl:tw-hidden"></div> -->
  7. <div class="tw-bg-white xl:tw-p-[30px] xl:tw-rounded-[20px] xl:tw-min-w-[900px] xl:tw-max-w-[900px]">
  8. <div class="tw-text-[20px] tw-font-bold tw-text-base-primary tw-mb-[20px] md:t24 md:tw-mb-[30px]">
  9. <two-dots class="tw-mr-[30px]"></two-dots>{{ $t("userProfile.setting") }}
  10. </div>
  11. <div class="tw-mb-[30px] md:tw-max-w-[392px]">
  12. <div class="tw-body-2 tw-font-bold tw-text-base-primary tw-mb-[15px] md:t16">
  13. {{ $t('userProfile.account') }}
  14. </div>
  15. <input type="text"
  16. class="tw-h-[40px] tw-w-full tw-border tw-bg-white tw-border-neutral-200 tw-border-solid tw-px-[20px] tw-py-[10px] tw-rounded-[5px] disabled:tw-text-base-disable"
  17. :value="userData.Account" disabled />
  18. </div>
  19. <Transition name="bounce">
  20. <div v-show="SSOShow == 2" :class="['tw-mb-[50px] md:tw-mb-[30px]',SSOShow == 2 ? '':'tw-hidden']">
  21. <div class="tw-body-2 tw-font-medium tw-text-base-primary tw-mb-[15px] md:t16">
  22. {{ $t('userProfile.manageSSO')}}
  23. </div>
  24. <div class="md:tw-flex md:tw-flex-row">
  25. <div
  26. class="tw-w-full tw-border tw-border-solid tw-border-neutral-200 tw-rounded-[10px] tw-grid tw-grid-cols-[auto_71px] tw-items-center tw-gap-[50px] tw-px-[30px] tw-py-[14px] tw-mb-[20px] md:tw-mb-0 md:tw-mr-[20px] md:tw-py-[30px]">
  27. <div class="tw-text-[16px] tw-text-base-primary md:tw-text-[14px]">
  28. Facebook
  29. </div>
  30. <button v-if="facebook.social_schema" @click="openModal('facebook')"
  31. class="tw-bg-warning-background tw-text-warning-default tw-rounded-[12px] tw-px-[16px] tw-py-[9px] tw-whitespace-nowrap">
  32. {{$t('userProfile.SSOUnLink')}}
  33. </button>
  34. <button v-else @click="facebookLogin"
  35. class="tw-bg-warning-default tw-text-white tw-rounded-[12px] tw-px-[16px] tw-py-[9px]">
  36. {{$t('userProfile.SSOLink')}}
  37. </button>
  38. </div>
  39. <div
  40. class="tw-w-full tw-border tw-border-solid tw-border-neutral-200 tw-rounded-[10px] tw-grid tw-grid-cols-[auto_90px] tw-items-center tw-gap-[50px] tw-px-[30px] tw-py-[14px] md:tw-py-[30px]">
  41. <div class="tw-text-[16px] tw-text-base-primary md:tw-text-[14px]">
  42. Google
  43. </div>
  44. <button v-if="google.social_schema" @click.prevent="openModal('google')"
  45. class="tw-bg-warning-background tw-text-warning-default tw-rounded-[12px] tw-px-[16px] tw-py-[9px]">
  46. {{$t('userProfile.SSOUnLink')}}
  47. </button>
  48. <button v-else @click="googleLogin"
  49. class="tw-bg-warning-default tw-text-white tw-rounded-[12px] tw-px-[16px] tw-py-[9px]">
  50. {{$t('userProfile.SSOLink')}}
  51. </button>
  52. </div>
  53. </div>
  54. </div>
  55. </Transition>
  56. <Transition name="bounce">
  57. <div>
  58. <div class="tw-body-2 tw-font-bold tw-text-base-primary tw-mb-[20px] md:t16 md:tw-mb-[15px]">
  59. {{$t('userProfile.resetPassword')}}
  60. </div>
  61. <div class="tw-mb-[20px] md:tw-max-w-[392px] md:tw-mb-[15px]">
  62. <div class="tw-mb-[20px] md:tw-max-w-[392px] md:tw-mb-0">
  63. <div class="tw-text-[16px] tw-text-base-primary tw-mb-[6px] md:tw-text-[14px]">
  64. {{$t('userProfile.oldPassword')}}
  65. </div>
  66. <v-text-field type="password" v-model="userPass.user_old_pass" @blur="checkOldPassword($event)" :rules="[rules.checkPassword, rules.require]"
  67. hide-details dense outlined validate-on-blur></v-text-field>
  68. <!-- <input v-model="userPass.user_old_pass" type="password"
  69. class="tw-h-[40px] tw-w-full tw-border tw-border-neutral-200 tw-border-solid tw-px-[20px] tw-py-[10px] tw-rounded-[5px]" /> -->
  70. </div>
  71. <div v-show="!isOldPassValid" class="tw-footer-body tw-w-full tw-leading-none tw-pt-1" :class="
  72. isOldPassValid
  73. ? 'tw-text-neutrals-400'
  74. : 'tw-text-error-default'
  75. ">
  76. {{ $t('userProfile.passwordsHint') }}
  77. </div>
  78. </div>
  79. <div class="tw-mb-[20px] md:tw-max-w-[392px] md:tw-mb-[15px]">
  80. <!-- <div
  81. class="tw-text-[16px] tw-text-base-primary tw-mb-[6px] md:tw-text-[14px]"
  82. >
  83. New password
  84. </div>
  85. <input
  86. type="text"
  87. class="tw-h-[40px] tw-w-full tw-border tw-border-neutral-200 tw-border-solid tw-px-[20px] tw-py-[10px] tw-rounded-[5px] tw-mb-[6px]"
  88. /> -->
  89. <div>
  90. <div class="tw-text-[16px] tw-text-base-primary tw-mb-[6px] md:tw-text-[14px]">
  91. {{$t('userProfile.newPassword')}}
  92. </div>
  93. <v-text-field v-model="userPass.user_new_pass" :append-icon="showPass ? 'mdi-eye' : 'mdi-eye-off'"
  94. @click:append="showPass = !showPass" @blur="checkPassword($event)"
  95. :type="showPass ? 'text' : 'password'" :rules="[rules.checkPassword, rules.require]" hide-details
  96. dense outlined validate-on-blur></v-text-field>
  97. </div>
  98. <div v-show="!isNewPassValid" class="tw-footer-body tw-w-full tw-leading-none tw-pt-1" :class="
  99. isNewPassValid
  100. ? 'tw-text-neutrals-400'
  101. : 'tw-text-error-default'
  102. ">
  103. {{ $t('userProfile.passwordsHint') }}
  104. </div>
  105. </div>
  106. <div class="tw-mb-[20px] md:tw-max-w-[392px] md:tw-mb-[15px]">
  107. <div>
  108. <div class="tw-text-[16px] tw-text-base-primary tw-mb-[6px] md:tw-text-[14px]">
  109. {{$t('userProfile.confirmPassword')}}
  110. </div>
  111. <v-text-field v-model="confirmPass" :append-icon="showConfirmPass ? 'mdi-eye' : 'mdi-eye-off'"
  112. @click:append="showConfirmPass = !showConfirmPass" :type="showConfirmPass ? 'text' : 'password'"
  113. :rules="[rules.checkConfirmPassword, rules.require]" dense outlined validate-on-blur></v-text-field>
  114. </div>
  115. <!-- <div
  116. class="tw-text-[16px] tw-text-base-primary tw-mb-[6px] md:tw-text-[14px]"
  117. >
  118. Confirm password
  119. </div>
  120. <input
  121. type="text"
  122. class="tw-h-[40px] tw-w-full tw-border tw-border-neutral-200 tw-border-solid tw-px-[20px] tw-py-[10px] tw-rounded-[5px] tw-mb-[6px]"
  123. />
  124. <img
  125. src="~/assets/svg/hidepassword.svg"
  126. class="tw-absolute tw-top-[717px] tw-right-[20px] md:tw-top-[621px] md:tw-left-[359px] xl:tw-left-[777px] xl:tw-top-[650px]"
  127. alt=""
  128. /> -->
  129. </div>
  130. </div>
  131. </Transition>
  132. <Transition name="bounce">
  133. <div
  134. :lass="['tw-mb-[64px] md:tw-flex md:tw-flex-row md:tw-items-center md:tw-mb-[40px]']">
  135. <button @click="resetPassword"
  136. class="tw-text-white tw-bg-primary-1 tw-text-[18px] tw-rounded-[16px] tw-w-full tw-py-[13px] tw-mb-[15px] md:tw-text-[16px] md:tw-w-fit md:tw-px-[16px] md:tw-py-[10px] md:tw-mr-[20px] md:tw-mb-0">
  137. {{$t('userProfile.resetPassword')}}
  138. </button>
  139. <button @click="cancel"
  140. class="tw-text-primary-1 tw-bg-white tw-text-[18px] tw-rounded-[16px] tw-w-full tw-py-[13px] md:tw-text-[16px] md:tw-w-fit md:tw-px-[16px] md:tw-py-[10px]">
  141. {{$t('userProfile.cancel')}}
  142. </button>
  143. </div>
  144. </Transition>
  145. <button @click="openDeleteModal()"
  146. class="tw-text-error-default tw-text-[16px] tw-underline tw-mt-[44px] md:tw-mt-[99px] xl:tw-mt-[39px]">
  147. {{$t('userProfile.deleteAccount')}}
  148. </button>
  149. </div>
  150. </div>
  151. <Transition name="bounce">
  152. <unLinkModal></unLinkModal>
  153. </Transition>
  154. <Transition name="bounce">
  155. <deleteAccountModal :userData="userData"></deleteAccountModal>
  156. </Transition>
  157. </div>
  158. </template>
  159. <script>
  160. import SavedExhibitions from "../../components/user/savedExhibitions.vue";
  161. import SavedExhibitionsDialog from "../../components/user/savedExhibitionsDialog.vue";
  162. import Setting from "../../components/user/Setting.vue";
  163. import SettingDialog from "../../components/user/settingDialog.vue";
  164. import CropImageDialog from "../../components/user/cropImageDialog.vue";
  165. import CompanyInfo from "../../components/user/companyInfo.vue";
  166. import CompanyInfoDialog from "../../components/user/companyInfoDialog.vue";
  167. import ContactInfo from "../../components/user/contactInfo.vue";
  168. import vClickOutside from "v-click-outside";
  169. import BookingList from "../../components/user/bookingList.vue";
  170. import TwoDots from "@/components/TwoDots";
  171. import userSidebar from "@/components/user/userSidebar.vue";
  172. import unLinkModal from "@/components/newComponent/modal/unLinkModal.vue";
  173. import deleteAccountModal from "@/components/newComponent/modal/deleteAccountModal.vue";
  174. export default {
  175. name: "setting",
  176. layout: "profile",
  177. directives: {
  178. clickOutside: vClickOutside.directive,
  179. },
  180. components: {
  181. SavedExhibitions,
  182. SavedExhibitionsDialog,
  183. Setting,
  184. SettingDialog,
  185. CropImageDialog,
  186. CompanyInfo,
  187. CompanyInfoDialog,
  188. ContactInfo,
  189. BookingList,
  190. TwoDots,
  191. userSidebar,
  192. unLinkModal,
  193. deleteAccountModal,
  194. },
  195. data() {
  196. return {
  197. google: {},
  198. facebook: {},
  199. deleteDialogActive: false,
  200. valid: false,
  201. showPass: false,
  202. showConfirmPass: false,
  203. userPass: {
  204. user_old_pass: "",
  205. user_new_pass: "",
  206. },
  207. isNewPassValid: true,
  208. isOldPassValid: true,
  209. firstName: "",
  210. lastName: "",
  211. userData: {},
  212. SSOShow: 0,
  213. confirmPass: "",
  214. deleteAccountImg: require("~/assets/img/deleteAccount.png"),
  215. rules: {
  216. require: (value) => !!value || this.$t("Required."),
  217. email: (v) =>
  218. /^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/.test(
  219. v
  220. ) || this.$t("Invalid email"),
  221. checkPassword: (v) =>
  222. (/(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])/.test(v) &&
  223. v.length >= 8 &&
  224. v.length <= 20) ||
  225. this.$t(
  226. "Passwords must be 8-20 characters with at least 1 number, 1 lower case letter and 1 upper case letter"
  227. ),
  228. checkConfirmPassword: (v) =>
  229. this.confirmPass === this.userPass.user_new_pass ||
  230. this.$t("Your password and confirmation password do not match"),
  231. },
  232. };
  233. },
  234. created() {
  235. //this.geiApiDemo();
  236. this.fetchUserData();
  237. if (process.browser) {
  238. window.addEventListener("resize", this.handleResize);
  239. }
  240. //this.handleResize();
  241. },
  242. mounted() {
  243. this.$nextTick(() => {
  244. window.addEventListener("resize", this.onResize);
  245. });
  246. },
  247. destroyed() {
  248. if (process.browser) {
  249. window.removeEventListener("resize", this.handleResize);
  250. }
  251. },
  252. computed: {
  253. windowWidth() {
  254. if (process.client) {
  255. this.width = window.innerWidth;
  256. }
  257. return this.width;
  258. },
  259. },
  260. methods: {
  261. handleResize() {
  262. if (process.browser) {
  263. this.width = window.innerWidth;
  264. }
  265. },
  266. // geiApiDemo(){
  267. // this.$axios
  268. // .get(
  269. // `/trending/api/Members/Info`
  270. // )
  271. // .then((res) => {
  272. // console.log(JSON.stringify(res));
  273. // })
  274. // .catch((err) => {
  275. // console.log(err);
  276. // });
  277. // },
  278. fetchUserData() {
  279. this.$axios
  280. .get(
  281. `/trending/api/Members/Info`
  282. )
  283. .then((response) => {
  284. //console.log(JSON.stringify(response));
  285. if(response && response.data && response.data.DATA && response.data.DATA.rel){
  286. let data = response.data.DATA.rel
  287. if(data){
  288. this.userData = data;
  289. //console.log("userData:" + this.userData);
  290. this.firstName = this.userData.FirstName;
  291. this.lastName = this.userData.LastName;
  292. // this.facebook =
  293. // res.data.UserSocialRelation.filter(
  294. // (item) => item.social_schema === "facebook"
  295. // )[0] || {};
  296. // this.google =
  297. // res.data.UserSocialRelation.filter(
  298. // (item) => item.social_schema === "google"
  299. // )[0] || {};
  300. // this.checkSSO();
  301. }
  302. }
  303. })
  304. .catch((error) => {
  305. console.log(error);
  306. });
  307. },
  308. removeSocialRelation(schema) {
  309. delete schema.social_id;
  310. this.$axios
  311. .put(
  312. `/member/users/social?jwt=${this.$auth.$storage.getUniversal("jwt").token || ""
  313. }`,
  314. schema
  315. )
  316. .then((result) => {
  317. this.$emit("refetch-user");
  318. })
  319. .catch((err) => {
  320. console.log(err);
  321. });
  322. this.$nextTick(() => {
  323. schema.social_schema === "google"
  324. ? (this.google = {})
  325. : (this.facebook = {});
  326. });
  327. },
  328. facebookLogin() {
  329. this.$auth.loginWith("facebook");
  330. },
  331. googleLogin() {
  332. this.$auth.loginWith("google");
  333. },
  334. resetPassword() {
  335. if (
  336. this.isNewPassValid && this.isOldPassValid &&
  337. this.userPass.user_new_pass !== this.userPass.user_old_pass &&
  338. this.userPass.user_new_pass == this.confirmPass
  339. ) {
  340. this.$axios
  341. .post(
  342. `/trending/api/Members/ResetNewPassword/?Password=${this.userPass.user_new_pass}`
  343. )
  344. .then((response) => {
  345. //(JSON.stringify(response));
  346. if(response && response.data && response.data.DATA && response.data.DATA.rel){
  347. let data = response.data.DATA.rel
  348. if(data){
  349. this.$auth.$storage.removeUniversal("userPicture");
  350. this.$auth.$storage.removeUniversal("userLastName");
  351. this.$auth.$storage.removeUniversal("userAccount");
  352. this.$auth.$storage.removeUniversal("userPassword");
  353. this.$notify({
  354. type: "success",
  355. title: "Awesome!",
  356. text: "Your password has been updated successfully.",
  357. });
  358. setTimeout(() => {
  359. this.$auth.logout();
  360. this.$router.push(this.localePath("/user"));
  361. }, 4000)
  362. }
  363. }
  364. })
  365. .catch((error) => {
  366. console.log(error);
  367. });
  368. }
  369. },
  370. cancel(){
  371. this.userPass.user_old_pass = "",
  372. this.userPass.user_new_pass = "",
  373. this.confirmPass = ""
  374. },
  375. checkOldPassword(v) {
  376. const pass = v.target.value;
  377. this.isOldPassValid =
  378. /(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])/.test(pass) &&
  379. pass.length >= 8 &&
  380. pass.length <= 20;
  381. },
  382. checkPassword(v) {
  383. const pass = v.target.value;
  384. this.isNewPassValid =
  385. /(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])/.test(pass) &&
  386. pass.length >= 8 &&
  387. pass.length <= 20;
  388. },
  389. checkSSO() {
  390. if (Object.keys(this.facebook).length == 0 && Object.keys(this.google).length == 0) {
  391. this.SSOShow = 1;
  392. } else {
  393. this.SSOShow = 2;
  394. }
  395. },
  396. openModal(type) {
  397. if (type == 'google') {
  398. if (Object.keys(this.facebook).length == 0) {
  399. this.$modal.show('unLinkModal');
  400. } else {
  401. this.removeSocialRelation(this.google);
  402. }
  403. }
  404. if (type == 'facebook') {
  405. if (Object.keys(this.google).length == 0) {
  406. this.$modal.show('unLinkModal');
  407. } else {
  408. this.removeSocialRelation(this.facebook);
  409. }
  410. }
  411. },
  412. openDeleteModal() {
  413. this.$modal.show('deleteAccountModal');
  414. }
  415. },
  416. };
  417. </script>
  418. <style scoped lang="scss">
  419. :deep(.v-text-field.v-text-field--enclosed .v-text-field__details) {
  420. padding: 0;
  421. margin: 0;
  422. }
  423. :deep(.v-messages__message) {
  424. font-size: 14px;
  425. }
  426. .v-text-field--outlined::v-deep {
  427. fieldset {
  428. border-color: #e5e5e5;
  429. }
  430. }
  431. .bounce-enter-active {
  432. animation: bounce-in 0.3s ease-out;
  433. }
  434. .bounce-leave-active {
  435. animation: bounce-in 0.3s cubic-bezier(1, 0.5, 0.8, 1) reverse;
  436. }
  437. @keyframes bounce-in {
  438. 0% {
  439. opacity: 0;
  440. transform: translateY(-10px);
  441. }
  442. 50% {
  443. opacity: 0.5;
  444. transform: translateY(-5px);
  445. }
  446. 100% {
  447. opacity: 1;
  448. transform: translateY(0);
  449. }
  450. }
  451. </style>