mirror of
https://github.com/Dadechin/XRoomDashboardFront.git
synced 2025-07-02 00:04:35 +00:00
add alerts Design in loginsPages , ChangeAvatar , Edit Profile
This commit is contained in:
parent
2cea1034b1
commit
8684a35c66
|
@ -41,4 +41,23 @@ button:focus-visible {
|
|||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* sweet alert */
|
||||
|
||||
.swal2-popup {
|
||||
right: 1rem !important;
|
||||
top: 1rem !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: right !important;
|
||||
width: 95% !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
|
||||
.swal2-title {
|
||||
padding-right: 12px !important;
|
||||
margin-right: 0 !important;
|
||||
color: #101010 !important;
|
||||
text-align: right !important;
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import '@/assets/main.css'
|
||||
// src/main.js
|
||||
import { createApp } from 'vue';
|
||||
import App from './App.vue';
|
||||
import router from './router';
|
||||
import Swal from 'sweetalert2';
|
||||
import '@/assets/main.css';
|
||||
|
||||
createApp(App)
|
||||
.use(router) // Make sure you use the router here
|
||||
.mount('#app')
|
||||
const app = createApp(App);
|
||||
app.use(router);
|
||||
app.config.globalProperties.$swal = Swal; // Add SweetAlert2 globally
|
||||
app.mount('#app');
|
|
@ -7,10 +7,6 @@
|
|||
<h3 class="subtitle">ورود به حساب کاربری</h3>
|
||||
|
||||
<form @submit.prevent="handleSubmit">
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Mobile Number -->
|
||||
<div class="form-group">
|
||||
<label for="phone">شماره تماس</label>
|
||||
|
@ -23,10 +19,9 @@
|
|||
<input v-model="form.password" type="password" id="password" placeholder="گذرواژه" />
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Submit Button -->
|
||||
<button type="submit" class="submit-btn">
|
||||
ورود
|
||||
<button type="submit" class="submit-btn">
|
||||
ورود
|
||||
</button>
|
||||
</form>
|
||||
|
||||
|
@ -34,7 +29,7 @@
|
|||
<div class="login-link">
|
||||
<router-link to="/signup">ساخت حساب کاربری</router-link>
|
||||
</div>
|
||||
<!-- Login Link -->
|
||||
<!-- Reset Password Link -->
|
||||
<div class="login-link">
|
||||
<router-link to="/resetPassword">فراموشی رمز عبور</router-link>
|
||||
</div>
|
||||
|
@ -42,8 +37,8 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import apiClient from '@/api/axios'; // Adjust the path if needed
|
||||
<script>
|
||||
import apiClient from '@/api/axios';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
|
@ -59,32 +54,79 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
async handleSubmit() {
|
||||
const loginData = {
|
||||
mobile_number: this.form.mobileNumber,
|
||||
password: this.form.password,
|
||||
};
|
||||
// Define Toast configuration with SweetAlert2
|
||||
const Toast = this.$swal.mixin({
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 3000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.onmouseenter = this.$swal.stopTimer;
|
||||
toast.onmouseleave = this.$swal.resumeTimer;
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
const response = await apiClient.post('/login', loginData);
|
||||
|
||||
if (response.data.status === 200) {
|
||||
const token = response.data.data.token;
|
||||
const user = response.data.data.user;
|
||||
// Prepare login data
|
||||
const loginData = {
|
||||
mobile_number: this.form.mobileNumber,
|
||||
password: this.form.password,
|
||||
};
|
||||
|
||||
localStorage.setItem('token', token);
|
||||
localStorage.setItem('user', JSON.stringify(user));
|
||||
try {
|
||||
// Send login request
|
||||
const response = await apiClient.post('/login', loginData);
|
||||
|
||||
this.$router.push('/dashboard');
|
||||
} else {
|
||||
alert(response.data.message || 'خطا در ورود. لطفا دوباره تلاش کنید.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Login error:', error);
|
||||
alert('خطا در ورود. لطفا دوباره تلاش کنید.');
|
||||
}
|
||||
}
|
||||
if (response.data.status === 200) {
|
||||
// Store token and user data in localStorage
|
||||
const token = response.data.data.token;
|
||||
const user = response.data.data.user;
|
||||
|
||||
localStorage.setItem('token', token);
|
||||
localStorage.setItem('user', JSON.stringify(user));
|
||||
|
||||
// Show success Toast
|
||||
Toast.fire({
|
||||
icon: 'success',
|
||||
title: 'ورود با موفقیت انجام شد',
|
||||
});
|
||||
|
||||
// Redirect to dashboard
|
||||
this.$router.push('/dashboard');
|
||||
} else {
|
||||
// Show error Toast with server message
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: response.data.message || 'خطا در ورود, لطفا دوباره تلاش کنید',
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
// Handle specific error cases
|
||||
let errorMessage = 'خطا در ورود, لطفا دوباره تلاش کنید';
|
||||
if (error.response) {
|
||||
// Handle server errors (e.g., 400, 401, 500)
|
||||
if (error.response.status === 401) {
|
||||
errorMessage = '.شماره تماس یا رمز عبور اشتباه است';
|
||||
} else if (error.response.status === 400) {
|
||||
errorMessage = '.اطلاعات ورودی نامعتبر است';
|
||||
} else {
|
||||
errorMessage = error.response.data.message || errorMessage;
|
||||
}
|
||||
} else if (error.request) {
|
||||
// Handle network errors (no response from server)
|
||||
errorMessage = 'مشکل در ارتباط با سرور, لطفا دوباره تلاش کنید';
|
||||
}
|
||||
|
||||
// Show error Toast
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: errorMessage,
|
||||
});
|
||||
|
||||
// Log error for debugging
|
||||
console.error('Login error:', error);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<h3 class="subtitle">فراموشی رمز عبور</h3>
|
||||
|
||||
<h5 class="descript-xroom">
|
||||
رمز عبور خود را فراموش کرده اید؟ شماره موبایل خود را وارد کنید تا کد تأیید برای شما ارسال شود.
|
||||
رمز عبور خود را فراموش کردهاید؟ شماره موبایل خود را وارد کنید تا کد تأیید برای شما ارسال شود.
|
||||
</h5>
|
||||
|
||||
<!-- Step 1: Mobile Number Input -->
|
||||
|
@ -63,7 +63,6 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import apiClient from '@/api/axios'; // Adjust the path based on your project structure
|
||||
|
||||
|
@ -80,39 +79,139 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
async requestResetCode() {
|
||||
// Define Toast configuration with SweetAlert2
|
||||
const Toast = this.$swal.mixin({
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 3000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.onmouseenter = this.$swal.stopTimer;
|
||||
toast.onmouseleave = this.$swal.resumeTimer;
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
// Send request to get reset code
|
||||
const response = await apiClient.post('/requestResetCode', {
|
||||
mobile_number: this.form.mobileNumber,
|
||||
});
|
||||
|
||||
if (response.data.success) {
|
||||
// Update state to show code and password input form
|
||||
this.codeSent = true;
|
||||
alert('کد تأیید به شماره موبایل شما ارسال شد.');
|
||||
|
||||
// Show success Toast
|
||||
Toast.fire({
|
||||
icon: 'success',
|
||||
title: '.کد تأیید به شماره موبایل شما ارسال شد',
|
||||
});
|
||||
} else {
|
||||
// Show error Toast with server message
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: response.data.message || 'خطا در ارسال کد تأیید, لطفاً دوباره تلاش کنید',
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
// Handle specific error cases
|
||||
let errorMessage = 'خطا در ارسال کد تأیید, لطفاً دوباره تلاش کنید';
|
||||
if (error.response) {
|
||||
// Handle server errors (e.g., 400, 401, 500)
|
||||
if (error.response.status === 400) {
|
||||
errorMessage = '.شماره تماس نامعتبر است';
|
||||
} else if (error.response.status === 404) {
|
||||
errorMessage = '.شماره تماس ثبتنشده است';
|
||||
} else {
|
||||
errorMessage = error.response.data.message || errorMessage;
|
||||
}
|
||||
} else if (error.request) {
|
||||
// Handle network errors (no response from server)
|
||||
errorMessage = 'مشکل در ارتباط با سرور, لطفاً دوباره تلاش کنید';
|
||||
}
|
||||
|
||||
// Show error Toast
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: errorMessage,
|
||||
});
|
||||
|
||||
// Log error for debugging
|
||||
console.error('Error requesting reset code:', error);
|
||||
alert('خطا در ارسال کد تأیید. لطفاً دوباره تلاش کنید.');
|
||||
}
|
||||
},
|
||||
async resetPassword() {
|
||||
// Define Toast configuration with SweetAlert2
|
||||
const Toast = this.$swal.mixin({
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 3000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.onmouseenter = this.$swal.stopTimer;
|
||||
toast.onmouseleave = this.$swal.resumeTimer;
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
// Send request to verify code and reset password
|
||||
const response = await apiClient.post('/verifyResetCode', {
|
||||
mobile_number: this.form.mobileNumber,
|
||||
code: this.form.code,
|
||||
password: this.form.password,
|
||||
});
|
||||
|
||||
if (response.data.success) {
|
||||
alert('رمز عبور با موفقیت بازنشانی شد.');
|
||||
// Show success Toast
|
||||
Toast.fire({
|
||||
icon: 'success',
|
||||
title: '.رمز عبور با موفقیت بازنشانی شد',
|
||||
});
|
||||
|
||||
// Redirect to login page
|
||||
this.$router.push('/');
|
||||
} else {
|
||||
// Show error Toast with server message
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: response.data.message || '.خطا در بازنشانی رمز عبور , لطفاً کد یا رمز عبور را بررسی کنید',
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
// Handle specific error cases
|
||||
let errorMessage = '.خطا در بازنشانی رمز عبور , لطفاً کد یا رمز عبور را بررسی کنید';
|
||||
if (error.response) {
|
||||
// Handle server errors (e.g., 400, 401, 500)
|
||||
if (error.response.status === 400) {
|
||||
errorMessage = '.کد تأیید یا رمز عبور نامعتبر است';
|
||||
} else if (error.response.status === 401) {
|
||||
errorMessage = '.کد تأیید اشتباه است';
|
||||
} else {
|
||||
errorMessage = error.response.data.message || errorMessage;
|
||||
}
|
||||
} else if (error.request) {
|
||||
// Handle network errors (no response from server)
|
||||
errorMessage = '.مشکل در ارتباط با سرور , لطفاً دوباره تلاش کنید';
|
||||
}
|
||||
|
||||
// Show error Toast
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: errorMessage,
|
||||
});
|
||||
|
||||
// Log error for debugging
|
||||
console.error('Error resetting password:', error);
|
||||
alert('خطا در بازنشانی رمز عبور. لطفاً کد یا رمز عبور را بررسی کنید.');
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<style scoped>
|
||||
|
||||
.descript-xroom {
|
||||
|
|
|
@ -19,10 +19,10 @@
|
|||
<input v-model="form.lastName" type="text" id="lastName" placeholder="نام خانوادگی" />
|
||||
</div>
|
||||
|
||||
<!-- Last Name -->
|
||||
<!-- Job Title -->
|
||||
<div class="form-group">
|
||||
<label for="lastName">جایگاه شغلی (سمت) </label>
|
||||
<input v-model="form.semat" type="text" id="semat" placeholder="سمت " />
|
||||
<label for="semat">جایگاه شغلی (سمت)</label>
|
||||
<input v-model="form.semat" type="text" id="semat" placeholder="سمت" />
|
||||
</div>
|
||||
|
||||
<!-- Mobile Number -->
|
||||
|
@ -39,8 +39,8 @@
|
|||
|
||||
<!-- Terms and Conditions -->
|
||||
<div class="terms-checkbox">
|
||||
<input type="checkbox" id="terms" v-model="form.terms" />
|
||||
<label for="terms">کلیه قوانین داده شده و شرایط حریم خصوصی را مطالعه کرده و تایید میکنم.</label>
|
||||
<input type="checkbox" id="terms" v-model="form.terms" required />
|
||||
<label for="terms">کلیه قوانین داده شده و شرایط حریم خصوصی را مطالعه کرده و تأیید میکنم.</label>
|
||||
</div>
|
||||
|
||||
<!-- Submit Button -->
|
||||
|
@ -75,6 +75,28 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
async handleSubmit() {
|
||||
// Define Toast configuration with SweetAlert2
|
||||
const Toast = this.$swal.mixin({
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 3000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.onmouseenter = this.$swal.stopTimer;
|
||||
toast.onmouseleave = this.$swal.resumeTimer;
|
||||
},
|
||||
});
|
||||
|
||||
// Validate form inputs
|
||||
if (!this.form.firstName || !this.form.lastName || !this.form.semat || !this.form.mobileNumber || !this.form.password) {
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: '.لطفاً تمام فیلدها را پر کنید',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare the data to match API format
|
||||
const signupData = {
|
||||
first_name: this.form.firstName,
|
||||
|
@ -85,18 +107,52 @@ export default {
|
|||
};
|
||||
|
||||
try {
|
||||
// Send signup request
|
||||
const response = await axios.post('http://194.62.43.230:8000/signup', signupData);
|
||||
console.log('Signup success:', response.data);
|
||||
const token = response.data.token;
|
||||
|
||||
|
||||
localStorage.setItem('token', token);
|
||||
|
||||
// Redirect to login page upon successful signup
|
||||
this.$router.push('/');
|
||||
// Check if signup was successful
|
||||
if (response.data.token) {
|
||||
// Store token in localStorage
|
||||
localStorage.setItem('token', response.data.token);
|
||||
|
||||
// Show success Toast
|
||||
Toast.fire({
|
||||
icon: 'success',
|
||||
title: '.حساب کاربری با موفقیت ساخته شد',
|
||||
});
|
||||
|
||||
// Redirect to login page
|
||||
this.$router.push('/');
|
||||
} else {
|
||||
// Show error Toast with server message
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: response.data.message || 'خطا در ثبتنام, لطفاً دوباره تلاش کنید',
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
// Handle specific error cases
|
||||
let errorMessage = 'خطا در ثبتنام, لطفاً دوباره تلاش کنید';
|
||||
if (error.response) {
|
||||
// Handle server errors (e.g., 400)
|
||||
if (error.response.status === 400) {
|
||||
errorMessage = '.شماره تلفن قبلاً ثبت شده است';
|
||||
} else {
|
||||
errorMessage = error.response.data.message || errorMessage;
|
||||
}
|
||||
} else if (error.request) {
|
||||
// Handle network errors (no response from server)
|
||||
errorMessage = 'مشکل در ارتباط با سرور, لطفاً دوباره تلاش کنید';
|
||||
}
|
||||
|
||||
// Show error Toast
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: errorMessage,
|
||||
});
|
||||
|
||||
// Log error for debugging
|
||||
console.error('Signup error:', error);
|
||||
// Handle error, show alert or error message
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -177,6 +233,7 @@ export default {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.terms-checkbox input {
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
<h2 class="title">
|
||||
<img :src="require('@/assets/img/Logins-logo.png')" alt="Logo" style="max-width: 150px;" />
|
||||
</h2>
|
||||
<h3 class="subtitle"> تایید شماره موبایل </h3>
|
||||
<h3 class="subtitle">تأیید شماره موبایل</h3>
|
||||
|
||||
<h5 class="descript-xroom">
|
||||
پیامکی شامل کد تایید به موبایل شما ارسال شده است.
|
||||
پیامکی شامل کد تأیید به موبایل شما ارسال شده است.
|
||||
</h5>
|
||||
|
||||
<button
|
||||
|
@ -25,24 +25,8 @@
|
|||
</span>
|
||||
</button>
|
||||
|
||||
|
||||
<!-- Step 1: Mobile Number Input -->
|
||||
<!-- <form v-if="!codeSent" @submit.prevent="requestResetCode">
|
||||
<div class="form-group">
|
||||
<label for="phone">شماره تماس</label>
|
||||
<input
|
||||
v-model="form.mobileNumber"
|
||||
type="text"
|
||||
id="phone"
|
||||
placeholder="شماره تماس"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
</form> -->
|
||||
|
||||
<!-- Step 2: Code and New Password Input -->
|
||||
<form @submit.prevent="submitSmsVerification">
|
||||
<!-- Code Input -->
|
||||
<form @submit.prevent="submitSmsVerification">
|
||||
<div class="form-group">
|
||||
<label for="code">کد تأیید</label>
|
||||
<input
|
||||
|
@ -53,26 +37,22 @@
|
|||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<button type="submit" class="submit-btn">
|
||||
تایید کد
|
||||
تأیید کد
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!-- Links -->
|
||||
<div class="login-link">
|
||||
<router-link to="/signup">ساخت حساب کاربری</router-link>
|
||||
|
||||
<router-link to="/signup">ساخت حساب کاربری</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
// import apiClient from '@/api/axios'; // Adjust the path based on your project structure
|
||||
import axios from '@/axios';
|
||||
import axios from '@/axios'; // Adjust the path based on your project structure
|
||||
|
||||
export default {
|
||||
data() {
|
||||
|
@ -83,117 +63,204 @@ export default {
|
|||
password: '',
|
||||
},
|
||||
codeSent: false, // Tracks if the code has been sent
|
||||
|
||||
|
||||
isButtonDisabled: false,
|
||||
countdown: 120, // in seconds (2 minutes)
|
||||
countdownInterval: null,
|
||||
isButtonDisabled: false, // Tracks if resend button is disabled
|
||||
countdown: 120, // Countdown timer in seconds (2 minutes)
|
||||
countdownInterval: null, // Interval for countdown
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
const token = localStorage.getItem('token');
|
||||
if (!token) {
|
||||
window.location.reload();
|
||||
} else {
|
||||
this.sendSms(); // Automatically call sendSms on mount
|
||||
}
|
||||
// Check for token and trigger SMS sending on mount
|
||||
const token = localStorage.getItem('token');
|
||||
if (!token) {
|
||||
window.location.reload();
|
||||
} else {
|
||||
this.sendSms(); // Automatically call sendSms on mount
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async sendSms() {
|
||||
try {
|
||||
const token = localStorage.getItem('token');
|
||||
// Define Toast configuration with SweetAlert2
|
||||
const Toast = this.$swal.mixin({
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 3000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.onmouseenter = this.$swal.stopTimer;
|
||||
toast.onmouseleave = this.$swal.resumeTimer;
|
||||
},
|
||||
});
|
||||
|
||||
const response = await axios.get('/sendSmsVerification', {
|
||||
headers: {
|
||||
'Authorization': `Token ${token}`,
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
});
|
||||
|
||||
if (response.status == 200) {
|
||||
this.codeSent = true;
|
||||
alert('کد تأیید به شماره موبایل شما ارسال شد.');
|
||||
this.startCountdown(); // Start countdown when code is sent
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error requesting reset code:', error);
|
||||
alert('خطا در ارسال کد تأیید. لطفاً دوباره تلاش کنید.');
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
startCountdown() {
|
||||
this.isButtonDisabled = true;
|
||||
this.countdown = 120; // Reset to 2 minutes
|
||||
|
||||
if (this.countdownInterval) {
|
||||
clearInterval(this.countdownInterval);
|
||||
}
|
||||
|
||||
this.countdownInterval = setInterval(() => {
|
||||
if (this.countdown > 0) {
|
||||
this.countdown--;
|
||||
} else {
|
||||
this.isButtonDisabled = false;
|
||||
clearInterval(this.countdownInterval);
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
async submitSmsVerification() {
|
||||
try {
|
||||
const token = localStorage.getItem('token');
|
||||
// Get token from localStorage
|
||||
const token = localStorage.getItem('token');
|
||||
|
||||
// Send request to get verification SMS
|
||||
const response = await axios.get('/sendSmsVerification', {
|
||||
headers: {
|
||||
Authorization: `Token ${token}`,
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
});
|
||||
|
||||
if (response.status === 200) {
|
||||
// Update state to indicate code was sent
|
||||
this.codeSent = true;
|
||||
|
||||
|
||||
|
||||
// Show success Toast
|
||||
Toast.fire({
|
||||
icon: 'success',
|
||||
title: '.کد تأیید به شماره موبایل شما ارسال شد',
|
||||
});
|
||||
|
||||
|
||||
const response = await axios.post('/submitSmsVerification',
|
||||
{
|
||||
verification_sms_code: this.form.code,
|
||||
|
||||
}, {headers: {
|
||||
|
||||
'Authorization': `Token ${token}`,
|
||||
'Content-Type': 'multipart/form-data'
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// const response = await apiClient.post('/submitSmsVerification', {
|
||||
|
||||
|
||||
// verification_sms_code: this.form.code,
|
||||
|
||||
// });
|
||||
if (response.status == 200) {
|
||||
alert('کد صحیح است');
|
||||
this.$router.push('/dashboard');
|
||||
// Start countdown for resend button
|
||||
this.startCountdown();
|
||||
} else {
|
||||
// Show error Toast with server message
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: response.data.message || 'خطا در ارسال کد تأیید, لطفاً دوباره تلاش کنید',
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error resetting password:', error);
|
||||
alert('کد خطا دارد');
|
||||
// Handle specific error cases
|
||||
let errorMessage = 'خطا در ارسال کد تأیید, لطفاً دوباره تلاش کنید';
|
||||
if (error.response) {
|
||||
// Handle server errors (e.g., 400, 401)
|
||||
if (error.response.status === 400) {
|
||||
errorMessage = '.درخواست نامعتبر است';
|
||||
} else if (error.response.status === 401) {
|
||||
errorMessage = 'توکن نامعتبر است, لطفاً دوباره وارد شوید';
|
||||
} else {
|
||||
errorMessage = error.response.data.message || errorMessage;
|
||||
}
|
||||
} else if (error.request) {
|
||||
// Handle network errors (no response from server)
|
||||
errorMessage = 'مشکل در ارتباط با سرور, لطفاً دوباره تلاش کنید';
|
||||
}
|
||||
|
||||
// Show error Toast
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: errorMessage,
|
||||
});
|
||||
|
||||
// Log error for debugging
|
||||
console.error('Error requesting SMS code:', error);
|
||||
}
|
||||
},
|
||||
startCountdown() {
|
||||
// Disable resend button and start countdown
|
||||
this.isButtonDisabled = true;
|
||||
this.countdown = 120; // Reset to 2 minutes
|
||||
|
||||
if (this.countdownInterval) {
|
||||
clearInterval(this.countdownInterval);
|
||||
}
|
||||
|
||||
// Update countdown every second
|
||||
this.countdownInterval = setInterval(() => {
|
||||
if (this.countdown > 0) {
|
||||
this.countdown--;
|
||||
} else {
|
||||
this.isButtonDisabled = false;
|
||||
clearInterval(this.countdownInterval);
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
async submitSmsVerification() {
|
||||
// Define Toast configuration with SweetAlert2
|
||||
const Toast = this.$swal.mixin({
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 3000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.onmouseenter = this.$swal.stopTimer;
|
||||
toast.onmouseleave = this.$swal.resumeTimer;
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
// Get token from localStorage
|
||||
const token = localStorage.getItem('token');
|
||||
|
||||
// Send request to verify SMS code
|
||||
const response = await axios.post(
|
||||
'/submitSmsVerification',
|
||||
{
|
||||
verification_sms_code: this.form.code,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Token ${token}`,
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (response.status === 200) {
|
||||
// Show success Toast
|
||||
Toast.fire({
|
||||
icon: 'success',
|
||||
title: '.کد تأیید صحیح است',
|
||||
});
|
||||
|
||||
// Redirect to dashboard
|
||||
this.$router.push('/dashboard');
|
||||
} else {
|
||||
// Show error Toast with server message
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: response.data.message || '.کد تأیید نامعتبر است',
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
// Handle specific error cases
|
||||
let errorMessage = '.کد تأیید نامعتبر است';
|
||||
if (error.response) {
|
||||
// Handle server errors (e.g., 400, 401)
|
||||
if (error.response.status === 400) {
|
||||
errorMessage = '.کد تأیید نامعتبر است';
|
||||
} else if (error.response.status === 401) {
|
||||
errorMessage = 'توکن نامعتبر است, لطفاً دوباره وارد شوید';
|
||||
} else {
|
||||
errorMessage = error.response.data.message || errorMessage;
|
||||
}
|
||||
} else if (error.request) {
|
||||
// Handle network errors (no response from server)
|
||||
errorMessage = 'مشکل در ارتباط با سرور, لطفاً دوباره تلاش کنید';
|
||||
}
|
||||
|
||||
// Show error Toast
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: errorMessage,
|
||||
});
|
||||
|
||||
// Log error for debugging
|
||||
console.error('Error verifying SMS code:', error);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<style scoped>
|
||||
|
||||
.descript-xroom {
|
||||
font-family: IRANSansXFaNum;
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
line-height: 210%;
|
||||
letter-spacing: 0%;
|
||||
text-align: justify;
|
||||
vertical-align: middle;
|
||||
margin-bottom: 30px;
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
line-height: 210%;
|
||||
letter-spacing: 0%;
|
||||
text-align: justify;
|
||||
vertical-align: middle;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
/* Basic reset */
|
||||
* {
|
||||
|
|
|
@ -59,62 +59,53 @@ import { ref } from 'vue';
|
|||
|
||||
export default {
|
||||
name: 'ChangeAvatar',
|
||||
components: {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedProfileImage: null,
|
||||
|
||||
userData: {
|
||||
user: { first_name: '', last_name: '', email: '' }
|
||||
},
|
||||
editForm: { first_name: '', last_name: '', email: '' },
|
||||
passwordForm: { current_password: '', new_password: '', confirm_password: '' },
|
||||
saving: false,
|
||||
// userProfilePicUrl: 'https://i.imgur.com/QbXfV6C.png',
|
||||
userAvatarUrl: 'https://i.imgur.com/QbXfV6C.png',
|
||||
baseUrl: 'http://194.62.43.230:8000'
|
||||
}
|
||||
};
|
||||
},
|
||||
setup() {
|
||||
// Define male avatars
|
||||
const maleAvatars = ref([
|
||||
{ id: 1, name: 'مرد ۱', src: 'http://my.xroomapp.com:8000/media/user_glbs/men1.glb', profile_img:'http://my.xroomapp.com:8000/media/user_images/men1.png' },
|
||||
{ id: 2, name: 'مرد ۲', src: 'http://my.xroomapp.com:8000/media/user_glbs/men2.glb' , profile_img:'http://my.xroomapp.com:8000/media/user_images/men2.png'},
|
||||
{ id: 7, name: 'مرد ۳', src: 'http://my.xroomapp.com:8000/media/user_glbs/men3.glb' , profile_img:'http://my.xroomapp.com:8000/media/user_images/men3.png'},
|
||||
{ id: 17, name: 'مرد 4', src: 'http://my.xroomapp.com:8000/media/user_glbs/men4.glb' , profile_img:'http://my.xroomapp.com:8000/media/user_images/men4.png'},
|
||||
// Add more male avatars as needed
|
||||
{ id: 1, name: 'مرد ۱', src: 'http://my.xroomapp.com:8000/media/user_glbs/men1.glb', profile_img: 'http://my.xroomapp.com:8000/media/user_images/men1.png' },
|
||||
{ id: 2, name: 'مرد ۲', src: 'http://my.xroomapp.com:8000/media/user_glbs/men2.glb', profile_img: 'http://my.xroomapp.com:8000/media/user_images/men2.png' },
|
||||
{ id: 7, name: 'مرد ۳', src: 'http://my.xroomapp.com:8000/media/user_glbs/men3.glb', profile_img: 'http://my.xroomapp.com:8000/media/user_images/men3.png' },
|
||||
{ id: 17, name: 'مرد ۴', src: 'http://my.xroomapp.com:8000/media/user_glbs/men4.glb', profile_img: 'http://my.xroomapp.com:8000/media/user_images/men4.png' },
|
||||
]);
|
||||
|
||||
|
||||
|
||||
// Define female avatars
|
||||
const femaleAvatars = ref([
|
||||
{ id: 4, name: 'زن ۱', src: 'http://my.xroomapp.com:8000/media/user_glbs/women1.glb', profile_img: 'http://my.xroomapp.com:8000/media/user_images/women1.png' },
|
||||
{ id: 10, name: 'زن ۳', src: 'http://my.xroomapp.com:8000/media/user_glbs/women2.glb', profile_img: 'http://my.xroomapp.com:8000/media/user_images/women2.png' },
|
||||
{ id: 10, name: 'زن ۳', src: 'http://my.xroomapp.com:8000/media/user_glbs/women3.glb', profile_img: 'http://my.xroomapp.com:8000/media/user_images/women3.png' },
|
||||
{ id: 10, name: 'زن ۳', src: 'http://my.xroomapp.com:8000/media/user_glbs/women4.glb', profile_img: 'http://my.xroomapp.com:8000/media/user_images/women4.png' },
|
||||
{ id: 10, name: 'زن ۳', src: 'http://my.xroomapp.com:8000/media/user_glbs/women6.glb', profile_img: 'http://my.xroomapp.com:8000/media/user_images/women6.png' },
|
||||
{ id: 10, name: 'زن ۳', src: 'http://my.xroomapp.com:8000/media/user_glbs/women7.glb', profile_img: 'http://my.xroomapp.com:8000/media/user_images/women7.png' },
|
||||
]);
|
||||
const selectedAvatar = ref(null);
|
||||
{ id: 4, name: 'زن ۱', src: 'http://my.xroomapp.com:8000/media/user_glbs/women1.glb', profile_img: 'http://my.xroomapp.com:8000/media/user_images/women1.png' },
|
||||
{ id: 10, name: 'زن ۲', src: 'http://my.xroomapp.com:8000/media/user_glbs/women2.glb', profile_img: 'http://my.xroomapp.com:8000/media/user_images/women2.png' },
|
||||
{ id: 11, name: 'زن ۳', src: 'http://my.xroomapp.com:8000/media/user_glbs/women3.glb', profile_img: 'http://my.xroomapp.com:8000/media/user_images/women3.png' },
|
||||
{ id: 12, name: 'زن ۴', src: 'http://my.xroomapp.com:8000/media/user_glbs/women4.glb', profile_img: 'http://my.xroomapp.com:8000/media/user_images/women4.png' },
|
||||
{ id: 13, name: 'زن ۵', src: 'http://my.xroomapp.com:8000/media/user_glbs/women6.glb', profile_img: 'http://my.xroomapp.com:8000/media/user_images/women6.png' },
|
||||
{ id: 14, name: 'زن ۶', src: 'http://my.xroomapp.com:8000/media/user_glbs/women7.glb', profile_img: 'http://my.xroomapp.com:8000/media/user_images/women7.png' },
|
||||
]);
|
||||
|
||||
// const selectAvatar = (avatar) => {
|
||||
// selectedAvatar.value = avatar;
|
||||
// // You can add API call here to save the selected avatar
|
||||
// console.log('Selected avatar:', avatar);
|
||||
// };
|
||||
const selectedAvatar = ref(null);
|
||||
|
||||
return {
|
||||
maleAvatars,
|
||||
femaleAvatars,
|
||||
selectedAvatar,
|
||||
// selectAvatar,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
// Fetch user data on component creation
|
||||
this.fetchUserData();
|
||||
},
|
||||
computed: {
|
||||
userProfilePicUrl() {
|
||||
// Get customer data from localStorage
|
||||
const customer = JSON.parse(localStorage.getItem('customer') || {});
|
||||
if (!customer.profile_img) return this.defaultProfileImage;
|
||||
return `http://194.62.43.230:8000/media/${customer.profile_img}`;
|
||||
|
@ -122,12 +113,27 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
async selectAvatar(avatar) {
|
||||
// Define Toast configuration with SweetAlert2
|
||||
const Toast = this.$swal.mixin({
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 2000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.onmouseenter = this.$swal.stopTimer;
|
||||
toast.onmouseleave = this.$swal.resumeTimer;
|
||||
},
|
||||
});
|
||||
|
||||
// Set saving state and selected avatar
|
||||
this.saving = true;
|
||||
this.selectedAvatar = avatar.id;
|
||||
|
||||
// try {
|
||||
await axios.post(`${this.baseUrl}/editProfile/`, {
|
||||
profile_glb_url: avatar.src ,
|
||||
|
||||
try {
|
||||
// Send request to update profile with selected avatar
|
||||
await axios.post(`${this.baseUrl}/editProfile/`, {
|
||||
profile_glb_url: avatar.src,
|
||||
profile_img: avatar.profile_img
|
||||
}, {
|
||||
headers: {
|
||||
|
@ -135,116 +141,230 @@ export default {
|
|||
}
|
||||
});
|
||||
|
||||
// print(response)
|
||||
// Update local storage if needed
|
||||
// const customer = JSON.parse(localStorage.getItem('customer') || '{}');
|
||||
// customer.profile_glb = avatar.src;
|
||||
// localStorage.setItem('customer', JSON.stringify(customer));
|
||||
// Show success Toast
|
||||
Toast.fire({
|
||||
icon: 'success',
|
||||
title: '.آواتار با موفقیت انتخاب شد',
|
||||
});
|
||||
|
||||
// Show success message
|
||||
// this.$toast.success('آواتار با موفقیت انتخاب شد');
|
||||
alert('تغییرات با موفقیت ذخیره شد');
|
||||
// Delay redirect to allow Toast to be visible
|
||||
setTimeout(() => {
|
||||
window.location.assign('/dashboard');
|
||||
}, 2000); // 3-second delay to match Toast duration
|
||||
|
||||
// Optionally refresh user data
|
||||
// await this.fetchUserData();
|
||||
|
||||
// } catch (error) {
|
||||
// console.error('Error selecting avatar:', error);
|
||||
// const errorMessage = error.response?.data?.detail ||
|
||||
// error.response?.data?.message ||
|
||||
// 'خطا در انتخاب آواتار';
|
||||
// this.$toast.error(errorMessage);
|
||||
// } finally {
|
||||
// this.saving = false;
|
||||
// this.selectedAvatar = null;
|
||||
// }
|
||||
} catch (error) {
|
||||
// Handle specific error cases
|
||||
let errorMessage = 'خطا در انتخاب آواتار. لطفاً دوباره تلاش کنید';
|
||||
if (error.response) {
|
||||
// Handle server errors (e.g., 400, 401)
|
||||
if (error.response.status === 400) {
|
||||
errorMessage = 'درخواست نامعتبر است.';
|
||||
} else if (error.response.status === 401) {
|
||||
errorMessage = 'توکن نامعتبر است. لطفاً دوباره وارد شوید';
|
||||
} else {
|
||||
errorMessage = error.response.data.detail || error.response.data.message || errorMessage;
|
||||
}
|
||||
} else if (error.request) {
|
||||
// Handle network errors (no response from server)
|
||||
errorMessage = 'مشکل در ارتباط با سرور. لطفاً دوباره تلاش کنید';
|
||||
}
|
||||
|
||||
// Show error Toast
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: errorMessage,
|
||||
});
|
||||
|
||||
// Log error for debugging
|
||||
console.error('Error selecting avatar:', error);
|
||||
} finally {
|
||||
// Reset saving state and selected avatar
|
||||
this.saving = false;
|
||||
this.selectedAvatar = null;
|
||||
}
|
||||
},
|
||||
|
||||
async fetchUserData() {
|
||||
// Define Toast configuration with SweetAlert2
|
||||
const Toast = this.$swal.mixin({
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 2000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.onmouseenter = this.$swal.stopTimer;
|
||||
toast.onmouseleave = this.$swal.resumeTimer;
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
// Fetch user data
|
||||
const response = await axios.get('/getInfo');
|
||||
this.userData = response.data;
|
||||
} catch (error) {
|
||||
// Handle specific error cases
|
||||
let errorMessage = 'خطا در دریافت اطلاعات کاربر';
|
||||
if (error.response) {
|
||||
// Handle server errors (e.g., 400, 401)
|
||||
if (error.response.status === 401) {
|
||||
errorMessage = 'توکن نامعتبر است. لطفاً دوباره وارد شوید';
|
||||
} else {
|
||||
errorMessage = error.response.data.detail || error.response.data.message || errorMessage;
|
||||
}
|
||||
} else if (error.request) {
|
||||
// Handle network errors (no response from server)
|
||||
errorMessage = 'مشکل در ارتباط با سرور. لطفاً دوباره تلاش کنید';
|
||||
}
|
||||
|
||||
// Show error Toast
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: errorMessage,
|
||||
});
|
||||
|
||||
// Log error for debugging
|
||||
console.error('Error fetching user data:', error);
|
||||
}
|
||||
},
|
||||
// async selectAvatar(avatar) {
|
||||
// try {
|
||||
// const response = await axios.post(
|
||||
// 'http://194.62.43.230:8000/editProfile',
|
||||
// {
|
||||
// profile_glb: avatar.src // Send the GLB URL in the specified field
|
||||
// },
|
||||
// {
|
||||
// headers: {
|
||||
// 'Content-Type': 'application/json',
|
||||
// 'Authorization': `Bearer ${yourAuthToken}` // Add if you use authentication
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
|
||||
// // Show success message
|
||||
// alert('آواتار با موفقیت انتخاب شد!');
|
||||
// console.log('Avatar selected:', response.data);
|
||||
|
||||
// } catch (error) {
|
||||
// console.error('Error selecting avatar:', error);
|
||||
// alert('خطا در انتخاب آواتار!');
|
||||
// }
|
||||
// },
|
||||
|
||||
async saveProfile() {
|
||||
this.saving = true;
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append('first_name', this.editForm.first_name);
|
||||
formData.append('last_name', this.editForm.last_name);
|
||||
|
||||
if (this.selectedProfileImage) {
|
||||
formData.append('profile_img', this.selectedProfileImage);
|
||||
}
|
||||
|
||||
await axios.post(`${this.baseUrl}/editProfile/`, formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
});
|
||||
|
||||
// Handle password change if filled
|
||||
if (this.passwordForm.new_password && this.passwordForm.current_password) {
|
||||
if (this.passwordForm.new_password !== this.passwordForm.confirm_password) {
|
||||
throw new Error('رمز عبور جدید و تکرار آن مطابقت ندارند');
|
||||
}
|
||||
|
||||
await axios.post(`${this.baseUrl}/resetPassword/`, {
|
||||
old_password: this.passwordForm.current_password,
|
||||
new_password: this.passwordForm.new_password
|
||||
// Define Toast configuration with SweetAlert2
|
||||
const Toast = this.$swal.mixin({
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 2000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.onmouseenter = this.$swal.stopTimer;
|
||||
toast.onmouseleave = this.$swal.resumeTimer;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
await this.fetchUserData();
|
||||
alert('تغییرات با موفقیت ذخیره شد');
|
||||
} catch (error) {
|
||||
alert(error.response?.data?.detail || error.message || 'خطا در ذخیره تغییرات');
|
||||
} finally {
|
||||
this.saving = false;
|
||||
}
|
||||
},
|
||||
// Set saving state
|
||||
this.saving = true;
|
||||
try {
|
||||
// Prepare form data for profile update
|
||||
const formData = new FormData();
|
||||
formData.append('first_name', this.editForm.first_name);
|
||||
formData.append('last_name', this.editForm.last_name);
|
||||
|
||||
if (this.selectedProfileImage) {
|
||||
formData.append('profile_img', this.selectedProfileImage);
|
||||
}
|
||||
|
||||
// Send request to update profile
|
||||
await axios.post(`${this.baseUrl}/editProfile/`, formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
});
|
||||
|
||||
// Handle password change if filled
|
||||
if (this.passwordForm.new_password && this.passwordForm.current_password) {
|
||||
if (this.passwordForm.new_password !== this.passwordForm.confirm_password) {
|
||||
// Show error Toast for password mismatch
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: 'رمز عبور جدید و تکرار آن مطابقت ندارند',
|
||||
});
|
||||
throw new Error('رمز عبور جدید و تکرار آن مطابقت ندارند');
|
||||
}
|
||||
|
||||
// Send request to reset password
|
||||
await axios.post(`${this.baseUrl}/resetPassword/`, {
|
||||
old_password: this.passwordForm.current_password,
|
||||
new_password: this.passwordForm.new_password
|
||||
});
|
||||
}
|
||||
|
||||
// Fetch updated user data
|
||||
await this.fetchUserData();
|
||||
|
||||
// Show success Toast
|
||||
Toast.fire({
|
||||
icon: 'success',
|
||||
title: 'تغییرات با موفقیت ذخیره شد',
|
||||
});
|
||||
} catch (error) {
|
||||
// Handle specific error cases
|
||||
let errorMessage = 'خطا در ذخیره تغییرات. لطفاً دوباره تلاش کنید';
|
||||
if (error.response) {
|
||||
// Handle server errors (e.g., 400, 401)
|
||||
if (error.response.status === 400) {
|
||||
errorMessage = '.درخواست نامعتبر است';
|
||||
} else if (error.response.status === 401) {
|
||||
errorMessage = 'توکن نامعتبر است. لطفاً دوباره وارد شوید';
|
||||
} else {
|
||||
errorMessage = error.response.data.detail || error.response.data.message || errorMessage;
|
||||
}
|
||||
} else if (error.request) {
|
||||
// Handle network errors (no response from server)
|
||||
errorMessage = 'مشکل در ارتباط با سرور. لطفاً دوباره تلاش کنید';
|
||||
}
|
||||
|
||||
// Show error Toast
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: errorMessage,
|
||||
});
|
||||
|
||||
// Log error for debugging
|
||||
console.error('Error saving profile:', error);
|
||||
} finally {
|
||||
// Reset saving state
|
||||
this.saving = false;
|
||||
}
|
||||
},
|
||||
changeAvatar() {
|
||||
alert('تغییر آواتار کلیک شد');
|
||||
// Define Toast configuration with SweetAlert2
|
||||
const Toast = this.$swal.mixin({
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 2000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.onmouseenter = this.$swal.stopTimer;
|
||||
toast.onmouseleave = this.$swal.resumeTimer;
|
||||
},
|
||||
});
|
||||
|
||||
// Show Toast for change avatar click
|
||||
Toast.fire({
|
||||
icon: 'info',
|
||||
title: 'تغییر آواتار کلیک شد',
|
||||
});
|
||||
},
|
||||
regenerateAvatar() {
|
||||
alert('ساخت مجدد آواتار کلیک شد');
|
||||
// Define Toast configuration with SweetAlert2
|
||||
const Toast = this.$swal.mixin({
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 2000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.onmouseenter = this.$swal.stopTimer;
|
||||
toast.onmouseleave = this.$swal.resumeTimer;
|
||||
},
|
||||
});
|
||||
|
||||
// Show Toast for regenerate avatar click
|
||||
Toast.fire({
|
||||
icon: 'info',
|
||||
title: 'ساخت مجدد آواتار کلیک شد.',
|
||||
});
|
||||
},
|
||||
uploadProfileImage(event) {
|
||||
const file = event.target.files[0];
|
||||
if (file) {
|
||||
this.selectedProfileImage = file;
|
||||
this.userProfilePicUrl = URL.createObjectURL(file);
|
||||
uploadProfileImage(event) {
|
||||
// Handle profile image upload
|
||||
const file = event.target.files[0];
|
||||
if (file) {
|
||||
this.selectedProfileImage = file;
|
||||
this.userProfilePicUrl = URL.createObjectURL(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
@ -459,4 +579,4 @@ body, html {
|
|||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
|
@ -1,13 +1,7 @@
|
|||
<template>
|
||||
<div>
|
||||
|
||||
<!-- Two-Column Form Layout -->
|
||||
<div class="profile-edit-container">
|
||||
|
||||
<!-- Left Column -->
|
||||
<div class="column">
|
||||
|
||||
<!-- VR Avatar Section -->
|
||||
<div class="form-section">
|
||||
<h3>آواتار واقعیت مجازی شما</h3>
|
||||
<p class="section-description">
|
||||
|
@ -40,8 +34,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Password Change Section -->
|
||||
<div class="form-section">
|
||||
<h3>تغییر رمز عبور</h3>
|
||||
<div class="form-group">
|
||||
|
@ -60,19 +52,13 @@
|
|||
{{ saving ? 'در حال ذخیره...' : 'ذخیره' }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Right Column -->
|
||||
<div class="column">
|
||||
|
||||
<!-- Profile Picture Section -->
|
||||
<div class="form-section">
|
||||
<h3>تصویر پروفایل</h3>
|
||||
<p class="section-description">
|
||||
این نماد در کنار نام شما و برای دیگران در واقعیت مجازی و در پلتفرم وب قابل مشاهده خواهد بود.
|
||||
</p>
|
||||
|
||||
<div style="display: flex; align-items: center;">
|
||||
<img :src="userProfilePicUrl" class="profile-image" />
|
||||
<label class="profile-upload" for="profile-upload">
|
||||
|
@ -112,10 +98,6 @@
|
|||
<input type="file" @change="uploadProfileImage" id="profile-upload" class="upload-input" style="display: none;" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- User Info Section -->
|
||||
<div class="form-section">
|
||||
<h3>اطلاعات کاربر</h3>
|
||||
<div class="form-group">
|
||||
|
@ -123,8 +105,12 @@
|
|||
<input type="email" id="email" v-model="editForm.email" disabled />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="fullName">نام کامل</label>
|
||||
<input type="text" id="fullName" v-model="editForm.full_name" placeholder="نام و نام خانوادگی" />
|
||||
<label for="firstName">نام</label>
|
||||
<input type="text" id="firstName" v-model="editForm.first_name" placeholder="نام" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="lastName">نام خانوادگی</label>
|
||||
<input type="text" id="lastName" v-model="editForm.last_name" placeholder="نام خانوادگی" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="position">جایگاه</label>
|
||||
|
@ -134,11 +120,8 @@
|
|||
{{ saving ? 'در حال ذخیره...' : 'ذخیره' }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -152,85 +135,239 @@ export default {
|
|||
return {
|
||||
selectedProfileImage: null,
|
||||
userData: {
|
||||
user: { first_name: '', last_name: '', email: '', semat: '' }
|
||||
customer: { semat: '', profile_img: '' },
|
||||
user: { first_name: '', last_name: '' },
|
||||
},
|
||||
editForm: { full_name: '', email: '', semat: '' }, // جایگزینی first_name و last_name با full_name
|
||||
editForm: { first_name: '', last_name: '', email: '', semat: '' },
|
||||
passwordForm: { current_password: '', new_password: '', confirm_password: '' },
|
||||
initialFormState: { first_name: '', last_name: '', semat: '' },
|
||||
saving: false,
|
||||
userAvatarUrl: 'https://i.imgur.com/QbXfV6C.png',
|
||||
baseUrl: 'http://194.62.43.230:8000'
|
||||
}
|
||||
baseUrl: 'http://194.62.43.230:8000',
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.fetchUserData();
|
||||
},
|
||||
computed: {
|
||||
userProfilePicUrl() {
|
||||
const customer = JSON.parse(localStorage.getItem('customer') || {});
|
||||
if (!customer.profile_img) return this.defaultProfileImage;
|
||||
return `${customer.profile_img}`;
|
||||
}
|
||||
// Prioritize userData from API if available
|
||||
if (this.userData.customer && this.userData.customer.profile_img) {
|
||||
return this.userData.customer.profile_img;
|
||||
}
|
||||
// Fallback to localStorage
|
||||
const customer = JSON.parse(localStorage.getItem('customer') || '{}');
|
||||
return customer.profile_img || this.userAvatarUrl;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async fetchUserData() {
|
||||
const Toast = this.$swal.mixin({
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 3000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.onmouseenter = this.$swal.stopTimer;
|
||||
toast.onmouseleave = this.$swal.resumeTimer;
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
const response = await axios.get('/getInfo');
|
||||
this.userData = response.data;
|
||||
|
||||
// Check if response.data and required fields exist
|
||||
if (!response.data || !response.data.data) {
|
||||
throw new Error('دادههای پاسخ از سرور معتبر نیست');
|
||||
}
|
||||
|
||||
const userData = response.data.data; // Adjust to match the nested 'data' structure
|
||||
if (!userData.user || !userData.customer) {
|
||||
throw new Error('دادههای کاربر یا مشتری در پاسخ سرور وجود ندارد');
|
||||
}
|
||||
|
||||
this.userData = userData;
|
||||
this.editForm = {
|
||||
full_name: `${response.data.user.first_name} ${response.data.user.last_name}`.trim(), // ترکیب نام و نام خانوادگی
|
||||
email: response.data.user.email,
|
||||
semat: response.data.user.semat,
|
||||
userAvatarUrl: response.data.customer.profile_img
|
||||
first_name: userData.user.first_name || '',
|
||||
last_name: userData.user.last_name || '',
|
||||
email: userData.user.email || '',
|
||||
semat: userData.customer.semat || '',
|
||||
};
|
||||
this.initialFormState = {
|
||||
first_name: this.editForm.first_name,
|
||||
last_name: this.editForm.last_name,
|
||||
semat: this.editForm.semat,
|
||||
};
|
||||
|
||||
// Update localStorage to keep it in sync with the API response
|
||||
localStorage.setItem('customer', JSON.stringify(userData.customer));
|
||||
} catch (error) {
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: 'خطا در بارگذاری اطلاعات کاربر. لطفاً دوباره تلاش کنید',
|
||||
});
|
||||
console.error('Error fetching user data:', error);
|
||||
}
|
||||
// Initialize with default values to prevent breaking the UI
|
||||
this.editForm = {
|
||||
first_name: '',
|
||||
last_name: '',
|
||||
email: '',
|
||||
semat: '',
|
||||
};
|
||||
this.initialFormState = {
|
||||
first_name: '',
|
||||
last_name: '',
|
||||
semat: '',
|
||||
};
|
||||
}
|
||||
},
|
||||
async saveProfile() {
|
||||
const Toast = this.$swal.mixin({
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 3000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.onmouseenter = this.$swal.stopTimer;
|
||||
toast.onmouseleave = this.$swal.resumeTimer;
|
||||
},
|
||||
});
|
||||
|
||||
this.saving = true;
|
||||
let isProfileChanged = false;
|
||||
let isPasswordChanged = false;
|
||||
let onlyNameChanged = false;
|
||||
|
||||
try {
|
||||
const formData = new FormData();
|
||||
// تجزیه full_name به first_name و last_name (اگر API نیاز دارد)
|
||||
const [first_name = '', last_name = ''] = this.editForm.full_name.split(' ').filter(Boolean);
|
||||
formData.append('first_name', first_name);
|
||||
formData.append('last_name', last_name);
|
||||
formData.append('semat', this.editForm.semat);
|
||||
|
||||
if (this.editForm.first_name !== this.initialFormState.first_name || this.editForm.last_name !== this.initialFormState.last_name) {
|
||||
formData.append('first_name', this.editForm.first_name);
|
||||
formData.append('last_name', this.editForm.last_name);
|
||||
isProfileChanged = true;
|
||||
onlyNameChanged = true;
|
||||
}
|
||||
|
||||
if (this.editForm.semat !== this.initialFormState.semat) {
|
||||
formData.append('semat', this.editForm.semat);
|
||||
isProfileChanged = true;
|
||||
onlyNameChanged = false;
|
||||
}
|
||||
|
||||
if (this.selectedProfileImage) {
|
||||
formData.append('profile_img', this.selectedProfileImage);
|
||||
isProfileChanged = true;
|
||||
onlyNameChanged = false;
|
||||
}
|
||||
|
||||
await axios.post(`${this.baseUrl}/editProfile/`, formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
});
|
||||
if (isProfileChanged) {
|
||||
await axios.post(`${this.baseUrl}/editProfile/`, formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Handle password change if filled
|
||||
if (this.passwordForm.new_password && this.passwordForm.current_password) {
|
||||
if (this.passwordForm.current_password && this.passwordForm.new_password) {
|
||||
if (this.passwordForm.new_password !== this.passwordForm.confirm_password) {
|
||||
throw new Error('رمز عبور جدید و تکرار آن مطابقت ندارند');
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: 'رمز عبور جدید و تکرار آن مطابقت ندارند',
|
||||
});
|
||||
this.saving = false;
|
||||
return;
|
||||
}
|
||||
|
||||
await axios.post(`${this.baseUrl}/resetPassword/`, {
|
||||
old_password: this.passwordForm.current_password,
|
||||
new_password: this.passwordForm.new_password
|
||||
new_password: this.passwordForm.new_password,
|
||||
});
|
||||
isPasswordChanged = true;
|
||||
onlyNameChanged = false;
|
||||
}
|
||||
|
||||
if (!isProfileChanged && !isPasswordChanged) {
|
||||
Toast.fire({
|
||||
icon: 'info',
|
||||
title: 'هیچ تغییری اعمال نشده است',
|
||||
});
|
||||
this.saving = false;
|
||||
return;
|
||||
}
|
||||
|
||||
await this.fetchUserData();
|
||||
alert('تغییرات با موفقیت ذخیره شد');
|
||||
this.passwordForm = { current_password: '', new_password: '', confirm_password: '' };
|
||||
this.editForm.first_name = '';
|
||||
this.editForm.last_name = '';
|
||||
this.editForm.semat = '';
|
||||
this.selectedProfileImage = null;
|
||||
|
||||
Toast.fire({
|
||||
icon: 'success',
|
||||
title: 'تغییرات با موفقیت ذخیره شد',
|
||||
});
|
||||
|
||||
if (onlyNameChanged) {
|
||||
window.location.reload();
|
||||
}
|
||||
} catch (error) {
|
||||
alert(error.response?.data?.detail || error.message || 'خطا در ذخیره تغییرات');
|
||||
let errorMessage = 'خطا در ذخیره تغییرات';
|
||||
if (error.response) {
|
||||
if (error.response.status === 400) {
|
||||
errorMessage = 'اطلاعات ورودی نامعتبر است';
|
||||
} else if (error.response.status === 401) {
|
||||
errorMessage = 'رمز عبور فعلی اشتباه است';
|
||||
} else {
|
||||
errorMessage = error.response.data.detail || errorMessage;
|
||||
}
|
||||
} else if (error.request) {
|
||||
errorMessage = 'مشکل در ارتباط با سرور، لطفاً دوباره تلاش کنید';
|
||||
}
|
||||
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: errorMessage,
|
||||
});
|
||||
console.error('Error saving profile:', error);
|
||||
} finally {
|
||||
this.saving = false;
|
||||
}
|
||||
},
|
||||
changeAvatar() {
|
||||
alert('تغییر آواتار کلیک شد');
|
||||
const Toast = this.$swal.mixin({
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 3000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.onmouseenter = this.$swal.stopTimer;
|
||||
toast.onmouseleave = this.$swal.resumeTimer;
|
||||
},
|
||||
});
|
||||
Toast.fire({
|
||||
icon: 'info',
|
||||
title: 'تغییر آواتار کلیک شد',
|
||||
});
|
||||
},
|
||||
regenerateAvatar() {
|
||||
alert('ساخت مجدد آواتار کلیک شد');
|
||||
const Toast = this.$swal.mixin({
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 3000,
|
||||
timerProgressBar: true,
|
||||
didOpen: (toast) => {
|
||||
toast.onmouseenter = this.$swal.stopTimer;
|
||||
toast.onmouseleave = this.$swal.resumeTimer;
|
||||
},
|
||||
});
|
||||
Toast.fire({
|
||||
icon: 'info',
|
||||
title: 'ساخت مجدد آواتار کلیک شد',
|
||||
});
|
||||
},
|
||||
uploadProfileImage(event) {
|
||||
const file = event.target.files[0];
|
||||
|
@ -238,11 +375,12 @@ export default {
|
|||
this.selectedProfileImage = file;
|
||||
this.userProfilePicUrl = URL.createObjectURL(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
|
||||
.page-title {
|
||||
|
|
|
@ -135,7 +135,7 @@ router.beforeEach(async (to, from, next) => {
|
|||
if (!customer.is_sms_verified && to.name !== 'SmsVerification') {
|
||||
return next('/SmsVerification');
|
||||
}
|
||||
else if (!customer.profile_glb && (to.name !== 'ReadyPlayer' ||to.name !== 'ChangeAvatar' )) {
|
||||
else if (!customer.profile_glb && (to.name !== 'ReadyPlayer' && to.name !== 'ChangeAvatar' )) {
|
||||
return next('/dashboard/ChangeAvatar');
|
||||
}
|
||||
|
||||
|
@ -152,4 +152,4 @@ router.beforeEach(async (to, from, next) => {
|
|||
|
||||
next();
|
||||
});
|
||||
export default router
|
||||
export default router
|
||||
|
|
Loading…
Reference in New Issue
Block a user