From e1b9d9c15d0a9301a613569a6d08e122ddce737f Mon Sep 17 00:00:00 2001 From: ThienPhamVan Date: Mon, 30 Mar 2026 14:09:41 +0700 Subject: [PATCH] Update Account --- assets/styles/_variables.scss | 73 +++++ assets/styles/main.scss | 1 + components/OtpInput.vue | 115 +++++++ components/template/email.js | 182 +++++++++++ constants/company.js | 2 +- pages/account/auth.vue | 219 ++++++++----- pages/account/recovery.vue | 580 ++++++++++++++++++++++++++-------- pages/signin.vue | 42 +-- pages/signup.vue | 78 ++--- plugins/common.js | 15 + plugins/connection.js | 2 +- 11 files changed, 1029 insertions(+), 280 deletions(-) create mode 100644 assets/styles/_variables.scss create mode 100644 components/OtpInput.vue create mode 100644 components/template/email.js diff --git a/assets/styles/_variables.scss b/assets/styles/_variables.scss new file mode 100644 index 0000000..c845c27 --- /dev/null +++ b/assets/styles/_variables.scss @@ -0,0 +1,73 @@ +:root { + /* ===== PRIMARY (GREEN) ===== */ + --primary-50: #f0fdf4; + --primary-100: #dcfce7; + --primary-200: #bbf7d0; + --primary-300: #86efac; + --primary-400: #4ade80; + --primary-500: #22c55e; + --primary-600: #16a34a; /* MAIN */ + --primary-700: #15803d; + --primary-800: #166534; + --primary-900: #14532d; + + /* ===== SEMANTIC ===== */ + --color-primary: var(--primary-600); + --color-primary-hover: var(--primary-700); + --color-primary-active: var(--primary-800); + + /* ===== TEXT (NEUTRAL - QUAN TRỌNG) ===== */ + --text-primary: #1f2937; /* gray-800 */ + --text-secondary: #6b7280; /* gray-500 */ + --text-light: #ffffff; + + /* ===== BACKGROUND ===== */ + --bg-primary: #ffffff; + --bg-secondary: #f9fafb; /* nhẹ hơn để không bị xanh quá */ + --bg-accent: var(--primary-50); + + /* ===== BORDER ===== */ + --border-light: #e5e7eb; + --border-default: #d1d5db; + + /* ===== STATE ===== */ + --color-error: #ef4444; + --color-success: #22c55e; + + /* ===== SHADOW ===== */ + --shadow-card: 0 4px 20px rgba(0, 0, 0, 0.08); + + /* ===== BUTTON ===== */ + --btn-primary-bg: var(--primary-600); + --btn-primary-hover: var(--primary-700); + --btn-primary-active: var(--primary-800); + --btn-primary-text: #ffffff; + + --btn-secondary-bg: var(--primary-100); + --btn-secondary-hover: var(--primary-200); + --btn-secondary-text: var(--primary-700); + + --btn-disabled-bg: #e5e7eb; + --btn-disabled-text: #9ca3af; + + /* ===== TEXT ===== */ + --text-primary: #1f2937; + --text-secondary: #6b7280; + --text-muted: #9ca3af; + + --text-on-primary: #ffffff; /* chữ trên nền xanh */ + --text-link: var(--primary-600); + --text-link-hover: var(--primary-700); + + /* ===== BORDER ===== */ + --border-default: #d1d5db; + --border-focus: var(--primary-600); + + /* ===== STATE ===== */ + --state-success: var(--primary-500); + --state-error: #ef4444; + --state-warning: #f59e0b; + + /* ===== LAYOUT ===== */ + --layout-full-height: 100dvh; +} diff --git a/assets/styles/main.scss b/assets/styles/main.scss index 526f867..92e5452 100644 --- a/assets/styles/main.scss +++ b/assets/styles/main.scss @@ -1,6 +1,7 @@ // Import Bulma's core @import "~bulma/sass/utilities/_all"; +@import "./variables"; // Set your colors $primary: #107FFB; // #4285F4; // #0F9D58; // #009047; $primary-invert: findColorInvert($primary); diff --git a/components/OtpInput.vue b/components/OtpInput.vue new file mode 100644 index 0000000..7c8c4e8 --- /dev/null +++ b/components/OtpInput.vue @@ -0,0 +1,115 @@ + + + + + diff --git a/components/template/email.js b/components/template/email.js new file mode 100644 index 0000000..4b3e11a --- /dev/null +++ b/components/template/email.js @@ -0,0 +1,182 @@ +import { COMPANY } from '~/constants/company'; + +export default function sendVerificationEmail( + customer, + emailCustomer, + code, + urlVerify, + companyName = COMPANY.name, + office = COMPANY.address, + website = COMPANY.website, + emailCompany = COMPANY.email.support, + hotline = COMPANY.phone.hotline, +) { + return ` +
+
+
+ Logo +
+
+

Xác thực tài khoản người dùng

+

Kính gửi quý khách hàng: ${customer}

+

${companyName} xin chân thành cảm ơn đến Quý khách đã tin tưởng và sử dụng dịch vụ của chúng tôi.

+

Hệ thống đã tiếp nhận yêu cầu đăng ký tài khoản từ Quý khách.

+ + + + + + + + + + + + + + + + +
THÔNG TIN TÀI KHOẢN
Email đăng nhập:${emailCustomer}
Mã xác thực:${code}
Link xác nhận đăng ký + :Xác nhận đăng ký +
+

+ Chú ý: +
+ Các thông tin + ${companyName} + đã cung cấp rất quan trọng, Quý khách vui lòng bảo mật nghiêm ngặt các thông tin này. +

+

+ Trân trọng cảm ơn Quý khách! +

+
+
+

${companyName}

+

Văn phòng:${office}

+

Website: ${website}

+

Email: ${emailCompany}

+

Hotline: ${hotline}

+
+
+
+ `; +} + +export const sendResetPasswordEmail = ( + customer, + emailCustomer, + code, + urlVerify, + companyName = COMPANY.name, + office = COMPANY.address, + website = COMPANY.website, + emailCompany = COMPANY.email.support, + hotline = COMPANY.phone.hotline, +) => { + return ` +
+
+
+ Logo +
+
+

Xác thực đặt lại mật khẩu

+

Kính gửi quý khách hàng: ${customer}

+

${companyName} xin chân thành cảm ơn đến Quý khách đã tin tưởng và sử dụng dịch vụ của chúng tôi.

+

Hệ thống đã tiếp nhận yêu cầu đặt lại mật khẩu từ Quý khách.

+ + + + + + + + + + + + + + + + +
THÔNG TIN TÀI KHOẢN
Email đăng nhập:${emailCustomer}
Mã xác thực:${code}
Link xác nhận đặt lại mật khẩu + :Xác nhận đặt lại mật khẩu +
+

+ Chú ý: +
+ Các thông tin + ${companyName} + đã cung cấp rất quan trọng, Quý khách vui lòng bảo mật nghiêm ngặt các thông tin này. +

+

Vui lòng bỏ qua email này nếu Quý khách không yêu cầu đặt lại mật khẩu.

+

+ Trân trọng cảm ơn Quý khách! +

+
+
+

${companyName}

+

Văn phòng:${office}

+

Website: ${website}

+

Email: ${emailCompany}

+

Hotline: ${hotline}

+
+
+
+ `; +}; diff --git a/constants/company.js b/constants/company.js index ae67d1f..3f8091e 100644 --- a/constants/company.js +++ b/constants/company.js @@ -1,5 +1,5 @@ export const COMPANY = { - name: 'BigDataTechCloud', + name: 'BigDataTech Cloud', website: 'https://bigdatatech.cloud', parent: { diff --git a/pages/account/auth.vue b/pages/account/auth.vue index 5628c11..1335739 100644 --- a/pages/account/auth.vue +++ b/pages/account/auth.vue @@ -1,53 +1,68 @@ + + diff --git a/pages/account/recovery.vue b/pages/account/recovery.vue index df588aa..cd0cf45 100644 --- a/pages/account/recovery.vue +++ b/pages/account/recovery.vue @@ -1,96 +1,184 @@ + + diff --git a/pages/signin.vue b/pages/signin.vue index b082bbb..af556b6 100644 --- a/pages/signin.vue +++ b/pages/signin.vue @@ -299,6 +299,7 @@ export default { this.account = data; this.fillData(data); }, + onSuccess(googleUser) { let info = googleUser.getBasicProfile(); @@ -309,6 +310,7 @@ export default { this.type = 'google'; if (!this.$empty(this.email)) this.checkAccount(); }, + async checkAccount() { if (this.$empty(this.email)) return; let found = this.$findapi('user'); @@ -355,6 +357,7 @@ export default { name: 'email', text: `Tài khoản đang chờ xác thực. Gửi lại mã`, }); + this.$router.push({ path: '/account/auth', query: { id: data.id, email: data.email } }); } return this.errors.length > 0 ? true : false; }, @@ -366,10 +369,11 @@ export default { return; } //check permision - if (this.module !== 'website') { - let userapps = await this.$getdata('userapps', { user: data.id, apps__code: this.module }, undefined, true); - if (!userapps) return this.$router.push('/welcome'); - } + // if (this.module !== 'website') { + // let userapps = await this.$getdata('userapps', { user: data.id, apps__code: this.module }, undefined, true); + // if (!userapps) return this.$router.push('/welcome'); + // } + this.login = data; //store login if (this.$store.state.link) { let ele = this.$copy(data); @@ -394,21 +398,21 @@ export default { window.location.href = href; } else this.redirectUrl(); }, - async sendNoti(obj) { - let found = this.$findapi('notiform'); - found.params.filter = { code: 'login-alert' }; - const result = await this.$getapi([found]); - let data = result[0].data.rows[0]; - let content = data.detail; - content = content.replace('[1]', this.email); - content = content.replace('[2]', obj.browser); - content = content.replace('[3]', obj.browser_version); - content = content.replace('[4]', obj.platform); - content = content.replace('[5]', obj.os); - content = content.replace('[6]', this.$dayjs().format('DD/MM/YYYY HH:mm')); - let ele = { title: data.name, content: content, user: [obj.user.toString()], type: 1 }; - await this.$insertapi('notification', ele); - }, + // async sendNoti(obj) { + // let found = this.$findapi('notiform'); + // found.params.filter = { code: 'login-alert' }; + // const result = await this.$getapi([found]); + // let data = result[0].data.rows[0]; + // let content = data.detail; + // content = content.replace('[1]', this.email); + // content = content.replace('[2]', obj.browser); + // content = content.replace('[3]', obj.browser_version); + // content = content.replace('[4]', obj.platform); + // content = content.replace('[5]', obj.os); + // content = content.replace('[6]', this.$dayjs().format('DD/MM/YYYY HH:mm')); + // let ele = { title: data.name, content: content, user: [obj.user.toString()], type: 1 }; + // await this.$insertapi('notification', ele); + // }, async logInWithFacebook() { if (window.FB) { let self = this; diff --git a/pages/signup.vue b/pages/signup.vue index a1f7a05..04501a4 100644 --- a/pages/signup.vue +++ b/pages/signup.vue @@ -26,15 +26,6 @@ {{ errors.find((v) => v.name === 'fullname').text }}

-
- -
- -
-

- {{ errors.find((v) => v.name === 'phone').text }} -

-
@@ -107,7 +98,9 @@

- +
@@ -191,6 +184,7 @@