add alerts Design in loginsPages , ChangeAvatar , Edit Profile

This commit is contained in:
Diyar Akhgar 2025-06-28 02:26:29 +03:30
parent 2cea1034b1
commit 8684a35c66
9 changed files with 898 additions and 353 deletions

View File

@ -42,3 +42,22 @@ button:focus-visible {
a { a {
text-decoration: none; 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;
}

View File

@ -1,8 +1,11 @@
import { createApp } from 'vue' // src/main.js
import App from './App.vue' import { createApp } from 'vue';
import router from './router' import App from './App.vue';
import '@/assets/main.css' import router from './router';
import Swal from 'sweetalert2';
import '@/assets/main.css';
createApp(App) const app = createApp(App);
.use(router) // Make sure you use the router here app.use(router);
.mount('#app') app.config.globalProperties.$swal = Swal; // Add SweetAlert2 globally
app.mount('#app');

View File

@ -7,10 +7,6 @@
<h3 class="subtitle">ورود به حساب کاربری</h3> <h3 class="subtitle">ورود به حساب کاربری</h3>
<form @submit.prevent="handleSubmit"> <form @submit.prevent="handleSubmit">
<!-- Mobile Number --> <!-- Mobile Number -->
<div class="form-group"> <div class="form-group">
<label for="phone">شماره تماس</label> <label for="phone">شماره تماس</label>
@ -23,7 +19,6 @@
<input v-model="form.password" type="password" id="password" placeholder="گذرواژه" /> <input v-model="form.password" type="password" id="password" placeholder="گذرواژه" />
</div> </div>
<!-- Submit Button --> <!-- Submit Button -->
<button type="submit" class="submit-btn"> <button type="submit" class="submit-btn">
ورود ورود
@ -34,7 +29,7 @@
<div class="login-link"> <div class="login-link">
<router-link to="/signup">ساخت حساب کاربری</router-link> <router-link to="/signup">ساخت حساب کاربری</router-link>
</div> </div>
<!-- Login Link --> <!-- Reset Password Link -->
<div class="login-link"> <div class="login-link">
<router-link to="/resetPassword">فراموشی رمز عبور</router-link> <router-link to="/resetPassword">فراموشی رمز عبور</router-link>
</div> </div>
@ -43,7 +38,7 @@
</template> </template>
<script> <script>
import apiClient from '@/api/axios'; // Adjust the path if needed import apiClient from '@/api/axios';
export default { export default {
data() { data() {
@ -59,32 +54,79 @@ export default {
}, },
methods: { methods: {
async handleSubmit() { 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;
},
});
// Prepare login data
const loginData = { const loginData = {
mobile_number: this.form.mobileNumber, mobile_number: this.form.mobileNumber,
password: this.form.password, password: this.form.password,
}; };
try { try {
// Send login request
const response = await apiClient.post('/login', loginData); const response = await apiClient.post('/login', loginData);
if (response.data.status === 200) { if (response.data.status === 200) {
// Store token and user data in localStorage
const token = response.data.data.token; const token = response.data.data.token;
const user = response.data.data.user; const user = response.data.data.user;
localStorage.setItem('token', token); localStorage.setItem('token', token);
localStorage.setItem('user', JSON.stringify(user)); localStorage.setItem('user', JSON.stringify(user));
// Show success Toast
Toast.fire({
icon: 'success',
title: 'ورود با موفقیت انجام شد',
});
// Redirect to dashboard
this.$router.push('/dashboard'); this.$router.push('/dashboard');
} else { } else {
alert(response.data.message || 'خطا در ورود. لطفا دوباره تلاش کنید.'); // Show error Toast with server message
Toast.fire({
icon: 'error',
title: response.data.message || 'خطا در ورود, لطفا دوباره تلاش کنید',
});
} }
} catch (error) { } catch (error) {
console.error('Login error:', error); // Handle specific error cases
alert('خطا در ورود. لطفا دوباره تلاش کنید.'); 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> </script>

View File

@ -7,7 +7,7 @@
<h3 class="subtitle">فراموشی رمز عبور</h3> <h3 class="subtitle">فراموشی رمز عبور</h3>
<h5 class="descript-xroom"> <h5 class="descript-xroom">
رمز عبور خود را فراموش کرده اید؟ شماره موبایل خود را وارد کنید تا کد تأیید برای شما ارسال شود. رمز عبور خود را فراموش کردهاید؟ شماره موبایل خود را وارد کنید تا کد تأیید برای شما ارسال شود.
</h5> </h5>
<!-- Step 1: Mobile Number Input --> <!-- Step 1: Mobile Number Input -->
@ -63,7 +63,6 @@
</div> </div>
</template> </template>
<script> <script>
import apiClient from '@/api/axios'; // Adjust the path based on your project structure import apiClient from '@/api/axios'; // Adjust the path based on your project structure
@ -80,39 +79,139 @@ export default {
}, },
methods: { methods: {
async requestResetCode() { 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 { try {
// Send request to get reset code
const response = await apiClient.post('/requestResetCode', { const response = await apiClient.post('/requestResetCode', {
mobile_number: this.form.mobileNumber, mobile_number: this.form.mobileNumber,
}); });
if (response.data.success) { if (response.data.success) {
// Update state to show code and password input form
this.codeSent = true; 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) { } 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); console.error('Error requesting reset code:', error);
alert('خطا در ارسال کد تأیید. لطفاً دوباره تلاش کنید.');
} }
}, },
async resetPassword() { 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 { try {
// Send request to verify code and reset password
const response = await apiClient.post('/verifyResetCode', { const response = await apiClient.post('/verifyResetCode', {
mobile_number: this.form.mobileNumber, mobile_number: this.form.mobileNumber,
code: this.form.code, code: this.form.code,
password: this.form.password, password: this.form.password,
}); });
if (response.data.success) { if (response.data.success) {
alert('رمز عبور با موفقیت بازنشانی شد.'); // Show success Toast
Toast.fire({
icon: 'success',
title: '.رمز عبور با موفقیت بازنشانی شد',
});
// Redirect to login page
this.$router.push('/'); this.$router.push('/');
} else {
// Show error Toast with server message
Toast.fire({
icon: 'error',
title: response.data.message || '.خطا در بازنشانی رمز عبور , لطفاً کد یا رمز عبور را بررسی کنید',
});
} }
} catch (error) { } 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); console.error('Error resetting password:', error);
alert('خطا در بازنشانی رمز عبور. لطفاً کد یا رمز عبور را بررسی کنید.');
} }
}, },
}, },
}; };
</script> </script>
<style scoped> <style scoped>
.descript-xroom { .descript-xroom {

View File

@ -19,10 +19,10 @@
<input v-model="form.lastName" type="text" id="lastName" placeholder="نام خانوادگی" /> <input v-model="form.lastName" type="text" id="lastName" placeholder="نام خانوادگی" />
</div> </div>
<!-- Last Name --> <!-- Job Title -->
<div class="form-group"> <div class="form-group">
<label for="lastName">جایگاه شغلی (سمت) </label> <label for="semat">جایگاه شغلی (سمت)</label>
<input v-model="form.semat" type="text" id="semat" placeholder="سمت " /> <input v-model="form.semat" type="text" id="semat" placeholder="سمت" />
</div> </div>
<!-- Mobile Number --> <!-- Mobile Number -->
@ -39,8 +39,8 @@
<!-- Terms and Conditions --> <!-- Terms and Conditions -->
<div class="terms-checkbox"> <div class="terms-checkbox">
<input type="checkbox" id="terms" v-model="form.terms" /> <input type="checkbox" id="terms" v-model="form.terms" required />
<label for="terms">کلیه قوانین داده شده و شرایط حریم خصوصی را مطالعه کرده و تایید میکنم.</label> <label for="terms">کلیه قوانین داده شده و شرایط حریم خصوصی را مطالعه کرده و تأیید میکنم.</label>
</div> </div>
<!-- Submit Button --> <!-- Submit Button -->
@ -75,6 +75,28 @@ export default {
}, },
methods: { methods: {
async handleSubmit() { 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 // Prepare the data to match API format
const signupData = { const signupData = {
first_name: this.form.firstName, first_name: this.form.firstName,
@ -85,18 +107,52 @@ export default {
}; };
try { try {
// Send signup request
const response = await axios.post('http://194.62.43.230:8000/signup', signupData); const response = await axios.post('http://194.62.43.230:8000/signup', signupData);
console.log('Signup success:', response.data);
const token = response.data.token;
// Check if signup was successful
if (response.data.token) {
// Store token in localStorage
localStorage.setItem('token', response.data.token);
localStorage.setItem('token', token); // Show success Toast
Toast.fire({
icon: 'success',
title: '.حساب کاربری با موفقیت ساخته شد',
});
// Redirect to login page upon successful signup // Redirect to login page
this.$router.push('/'); this.$router.push('/');
} else {
// Show error Toast with server message
Toast.fire({
icon: 'error',
title: response.data.message || 'خطا در ثبت‌نام, لطفاً دوباره تلاش کنید',
});
}
} catch (error) { } 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); console.error('Signup error:', error);
// Handle error, show alert or error message
} }
}, },
}, },
@ -177,6 +233,7 @@ export default {
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 20px; margin-bottom: 20px;
gap: 5px;
} }
.terms-checkbox input { .terms-checkbox input {

View File

@ -4,10 +4,10 @@
<h2 class="title"> <h2 class="title">
<img :src="require('@/assets/img/Logins-logo.png')" alt="Logo" style="max-width: 150px;" /> <img :src="require('@/assets/img/Logins-logo.png')" alt="Logo" style="max-width: 150px;" />
</h2> </h2>
<h3 class="subtitle"> تایید شماره موبایل </h3> <h3 class="subtitle">تأیید شماره موبایل</h3>
<h5 class="descript-xroom"> <h5 class="descript-xroom">
پیامکی شامل کد تایید به موبایل شما ارسال شده است. پیامکی شامل کد تأیید به موبایل شما ارسال شده است.
</h5> </h5>
<button <button
@ -25,23 +25,7 @@
</span> </span>
</button> </button>
<!-- Code Input -->
<!-- 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"> <form @submit.prevent="submitSmsVerification">
<div class="form-group"> <div class="form-group">
<label for="code">کد تأیید</label> <label for="code">کد تأیید</label>
@ -54,25 +38,21 @@
/> />
</div> </div>
<button type="submit" class="submit-btn"> <button type="submit" class="submit-btn">
تایید کد تأیید کد
</button> </button>
</form> </form>
<!-- Links --> <!-- Links -->
<div class="login-link"> <div class="login-link">
<router-link to="/signup">ساخت حساب کاربری</router-link> <router-link to="/signup">ساخت حساب کاربری</router-link>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
// import apiClient from '@/api/axios'; // Adjust the path based on your project structure import axios from '@/axios'; // Adjust the path based on your project structure
import axios from '@/axios';
export default { export default {
data() { data() {
@ -83,14 +63,13 @@ export default {
password: '', password: '',
}, },
codeSent: false, // Tracks if the code has been sent codeSent: false, // Tracks if the code has been sent
isButtonDisabled: false, // Tracks if resend button is disabled
countdown: 120, // Countdown timer in seconds (2 minutes)
isButtonDisabled: false, countdownInterval: null, // Interval for countdown
countdown: 120, // in seconds (2 minutes)
countdownInterval: null,
}; };
}, },
mounted() { mounted() {
// Check for token and trigger SMS sending on mount
const token = localStorage.getItem('token'); const token = localStorage.getItem('token');
if (!token) { if (!token) {
window.location.reload(); window.location.reload();
@ -100,29 +79,79 @@ export default {
}, },
methods: { methods: {
async sendSms() { async sendSms() {
// 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 { try {
// Get token from localStorage
const token = localStorage.getItem('token'); const token = localStorage.getItem('token');
// Send request to get verification SMS
const response = await axios.get('/sendSmsVerification', { const response = await axios.get('/sendSmsVerification', {
headers: { headers: {
'Authorization': `Token ${token}`, Authorization: `Token ${token}`,
'Content-Type': 'multipart/form-data', 'Content-Type': 'multipart/form-data',
}, },
}); });
if (response.status == 200) { if (response.status === 200) {
// Update state to indicate code was sent
this.codeSent = true; this.codeSent = true;
alert('کد تأیید به شماره موبایل شما ارسال شد.');
this.startCountdown(); // Start countdown when code is sent // Show success Toast
Toast.fire({
icon: 'success',
title: '.کد تأیید به شماره موبایل شما ارسال شد',
});
// Start countdown for resend button
this.startCountdown();
} else {
// Show error Toast with server message
Toast.fire({
icon: 'error',
title: response.data.message || 'خطا در ارسال کد تأیید, لطفاً دوباره تلاش کنید',
});
} }
} catch (error) { } catch (error) {
console.error('Error requesting reset code:', error); // Handle specific error cases
alert('خطا در ارسال کد تأیید. لطفاً دوباره تلاش کنید.'); 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() { startCountdown() {
// Disable resend button and start countdown
this.isButtonDisabled = true; this.isButtonDisabled = true;
this.countdown = 120; // Reset to 2 minutes this.countdown = 120; // Reset to 2 minutes
@ -130,6 +159,7 @@ export default {
clearInterval(this.countdownInterval); clearInterval(this.countdownInterval);
} }
// Update countdown every second
this.countdownInterval = setInterval(() => { this.countdownInterval = setInterval(() => {
if (this.countdown > 0) { if (this.countdown > 0) {
this.countdown--; this.countdown--;
@ -139,61 +169,98 @@ export default {
} }
}, 1000); }, 1000);
}, },
async submitSmsVerification() { 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 { try {
// Get token from localStorage
const token = localStorage.getItem('token'); const token = localStorage.getItem('token');
// Send request to verify SMS code
const response = await axios.post(
'/submitSmsVerification',
const response = await axios.post('/submitSmsVerification',
{ {
verification_sms_code: this.form.code, verification_sms_code: this.form.code,
},
}, {headers: { {
headers: {
'Authorization': `Token ${token}`, Authorization: `Token ${token}`,
'Content-Type': 'multipart/form-data' 'Content-Type': 'multipart/form-data',
},
}
} }
); );
// const response = await apiClient.post('/submitSmsVerification', { if (response.status === 200) {
// Show success Toast
Toast.fire({
icon: 'success',
title: '.کد تأیید صحیح است',
});
// Redirect to dashboard
// verification_sms_code: this.form.code,
// });
if (response.status == 200) {
alert('کد صحیح است');
this.$router.push('/dashboard'); this.$router.push('/dashboard');
} else {
// Show error Toast with server message
Toast.fire({
icon: 'error',
title: response.data.message || '.کد تأیید نامعتبر است',
});
} }
} catch (error) { } catch (error) {
console.error('Error resetting password:', error); // Handle specific error cases
alert('کد خطا دارد'); 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> </script>
<style scoped> <style scoped>
.descript-xroom { .descript-xroom {
font-family: IRANSansXFaNum; font-family: IRANSansXFaNum;
font-weight: 500; font-weight: 500;
font-size: 13px; font-size: 13px;
line-height: 210%; line-height: 210%;
letter-spacing: 0%; letter-spacing: 0%;
text-align: justify; text-align: justify;
vertical-align: middle; vertical-align: middle;
margin-bottom: 30px; margin-bottom: 30px;
} }
/* Basic reset */ /* Basic reset */
* { * {

View File

@ -59,62 +59,53 @@ import { ref } from 'vue';
export default { export default {
name: 'ChangeAvatar', name: 'ChangeAvatar',
components: {
},
data() { data() {
return { return {
selectedProfileImage: null, selectedProfileImage: null,
userData: { userData: {
user: { first_name: '', last_name: '', email: '' } user: { first_name: '', last_name: '', email: '' }
}, },
editForm: { first_name: '', last_name: '', email: '' }, editForm: { first_name: '', last_name: '', email: '' },
passwordForm: { current_password: '', new_password: '', confirm_password: '' }, passwordForm: { current_password: '', new_password: '', confirm_password: '' },
saving: false, saving: false,
// userProfilePicUrl: 'https://i.imgur.com/QbXfV6C.png',
userAvatarUrl: 'https://i.imgur.com/QbXfV6C.png', userAvatarUrl: 'https://i.imgur.com/QbXfV6C.png',
baseUrl: 'http://194.62.43.230:8000' baseUrl: 'http://194.62.43.230:8000'
} };
}, },
setup() { setup() {
// Define male avatars
const maleAvatars = ref([ 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: 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: 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: 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'}, { 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' },
// Add more male avatars as needed
]); ]);
// Define female avatars
const femaleAvatars = ref([ 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: 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/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: 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: 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: 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: 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: 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: 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' }, { 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 selectedAvatar = ref(null);
// const selectAvatar = (avatar) => { const selectedAvatar = ref(null);
// selectedAvatar.value = avatar;
// // You can add API call here to save the selected avatar
// console.log('Selected avatar:', avatar);
// };
return { return {
maleAvatars, maleAvatars,
femaleAvatars, femaleAvatars,
selectedAvatar, selectedAvatar,
// selectAvatar,
}; };
}, },
created() { created() {
// Fetch user data on component creation
this.fetchUserData(); this.fetchUserData();
}, },
computed: { computed: {
userProfilePicUrl() { userProfilePicUrl() {
// Get customer data from localStorage
const customer = JSON.parse(localStorage.getItem('customer') || {}); const customer = JSON.parse(localStorage.getItem('customer') || {});
if (!customer.profile_img) return this.defaultProfileImage; if (!customer.profile_img) return this.defaultProfileImage;
return `http://194.62.43.230:8000/media/${customer.profile_img}`; return `http://194.62.43.230:8000/media/${customer.profile_img}`;
@ -122,12 +113,27 @@ export default {
}, },
methods: { methods: {
async selectAvatar(avatar) { 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.saving = true;
this.selectedAvatar = avatar.id; this.selectedAvatar = avatar.id;
// try { try {
// Send request to update profile with selected avatar
await axios.post(`${this.baseUrl}/editProfile/`, { await axios.post(`${this.baseUrl}/editProfile/`, {
profile_glb_url: avatar.src , profile_glb_url: avatar.src,
profile_img: avatar.profile_img profile_img: avatar.profile_img
}, { }, {
headers: { headers: {
@ -135,67 +141,109 @@ export default {
} }
}); });
// print(response) // Show success Toast
// Update local storage if needed Toast.fire({
// const customer = JSON.parse(localStorage.getItem('customer') || '{}'); icon: 'success',
// customer.profile_glb = avatar.src; title: '.آواتار با موفقیت انتخاب شد',
// localStorage.setItem('customer', JSON.stringify(customer)); });
// Show success message // Delay redirect to allow Toast to be visible
// this.$toast.success('آواتار با موفقیت انتخاب شد'); setTimeout(() => {
alert('تغییرات با موفقیت ذخیره شد'); window.location.assign('/dashboard');
}, 2000); // 3-second delay to match Toast duration
// Optionally refresh user data } catch (error) {
// await this.fetchUserData(); // 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 = 'مشکل در ارتباط با سرور. لطفاً دوباره تلاش کنید';
}
// } catch (error) { // Show error Toast
// console.error('Error selecting avatar:', error); Toast.fire({
// const errorMessage = error.response?.data?.detail || icon: 'error',
// error.response?.data?.message || title: errorMessage,
// 'خطا در انتخاب آواتار'; });
// this.$toast.error(errorMessage);
// } finally { // Log error for debugging
// this.saving = false; console.error('Error selecting avatar:', error);
// this.selectedAvatar = null; } finally {
// } // Reset saving state and selected avatar
this.saving = false;
this.selectedAvatar = null;
}
}, },
async fetchUserData() { 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 { try {
// Fetch user data
const response = await axios.get('/getInfo'); const response = await axios.get('/getInfo');
this.userData = response.data; this.userData = response.data;
} catch (error) { } 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); 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() { async saveProfile() {
// 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
this.saving = true; this.saving = true;
try { try {
// Prepare form data for profile update
const formData = new FormData(); const formData = new FormData();
formData.append('first_name', this.editForm.first_name); formData.append('first_name', this.editForm.first_name);
formData.append('last_name', this.editForm.last_name); formData.append('last_name', this.editForm.last_name);
@ -204,6 +252,7 @@ export default {
formData.append('profile_img', this.selectedProfileImage); formData.append('profile_img', this.selectedProfileImage);
} }
// Send request to update profile
await axios.post(`${this.baseUrl}/editProfile/`, formData, { await axios.post(`${this.baseUrl}/editProfile/`, formData, {
headers: { headers: {
'Content-Type': 'multipart/form-data' 'Content-Type': 'multipart/form-data'
@ -213,30 +262,101 @@ export default {
// Handle password change if filled // Handle password change if filled
if (this.passwordForm.new_password && this.passwordForm.current_password) { if (this.passwordForm.new_password && this.passwordForm.current_password) {
if (this.passwordForm.new_password !== this.passwordForm.confirm_password) { if (this.passwordForm.new_password !== this.passwordForm.confirm_password) {
// Show error Toast for password mismatch
Toast.fire({
icon: 'error',
title: 'رمز عبور جدید و تکرار آن مطابقت ندارند',
});
throw new Error('رمز عبور جدید و تکرار آن مطابقت ندارند'); throw new Error('رمز عبور جدید و تکرار آن مطابقت ندارند');
} }
// Send request to reset password
await axios.post(`${this.baseUrl}/resetPassword/`, { await axios.post(`${this.baseUrl}/resetPassword/`, {
old_password: this.passwordForm.current_password, old_password: this.passwordForm.current_password,
new_password: this.passwordForm.new_password new_password: this.passwordForm.new_password
}); });
} }
// Fetch updated user data
await this.fetchUserData(); await this.fetchUserData();
alert('تغییرات با موفقیت ذخیره شد');
// Show success Toast
Toast.fire({
icon: 'success',
title: 'تغییرات با موفقیت ذخیره شد',
});
} catch (error) { } catch (error) {
alert(error.response?.data?.detail || error.message || 'خطا در ذخیره تغییرات'); // 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 { } finally {
// Reset saving state
this.saving = false; this.saving = false;
} }
}, },
changeAvatar() { 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() { 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) { uploadProfileImage(event) {
// Handle profile image upload
const file = event.target.files[0]; const file = event.target.files[0];
if (file) { if (file) {
this.selectedProfileImage = file; this.selectedProfileImage = file;
@ -244,7 +364,7 @@ export default {
} }
} }
} }
} };
</script> </script>
<style scoped> <style scoped>

View File

@ -1,13 +1,7 @@
<template> <template>
<div> <div>
<!-- Two-Column Form Layout -->
<div class="profile-edit-container"> <div class="profile-edit-container">
<!-- Left Column -->
<div class="column"> <div class="column">
<!-- VR Avatar Section -->
<div class="form-section"> <div class="form-section">
<h3>آواتار واقعیت مجازی شما</h3> <h3>آواتار واقعیت مجازی شما</h3>
<p class="section-description"> <p class="section-description">
@ -40,8 +34,6 @@
</div> </div>
</div> </div>
</div> </div>
<!-- Password Change Section -->
<div class="form-section"> <div class="form-section">
<h3>تغییر رمز عبور</h3> <h3>تغییر رمز عبور</h3>
<div class="form-group"> <div class="form-group">
@ -60,19 +52,13 @@
{{ saving ? 'در حال ذخیره...' : 'ذخیره' }} {{ saving ? 'در حال ذخیره...' : 'ذخیره' }}
</button> </button>
</div> </div>
</div> </div>
<!-- Right Column -->
<div class="column"> <div class="column">
<!-- Profile Picture Section -->
<div class="form-section"> <div class="form-section">
<h3>تصویر پروفایل</h3> <h3>تصویر پروفایل</h3>
<p class="section-description"> <p class="section-description">
این نماد در کنار نام شما و برای دیگران در واقعیت مجازی و در پلتفرم وب قابل مشاهده خواهد بود. این نماد در کنار نام شما و برای دیگران در واقعیت مجازی و در پلتفرم وب قابل مشاهده خواهد بود.
</p> </p>
<div style="display: flex; align-items: center;"> <div style="display: flex; align-items: center;">
<img :src="userProfilePicUrl" class="profile-image" /> <img :src="userProfilePicUrl" class="profile-image" />
<label class="profile-upload" for="profile-upload"> <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;" /> <input type="file" @change="uploadProfileImage" id="profile-upload" class="upload-input" style="display: none;" />
</div> </div>
</div> </div>
<!-- User Info Section -->
<div class="form-section"> <div class="form-section">
<h3>اطلاعات کاربر</h3> <h3>اطلاعات کاربر</h3>
<div class="form-group"> <div class="form-group">
@ -123,8 +105,12 @@
<input type="email" id="email" v-model="editForm.email" disabled /> <input type="email" id="email" v-model="editForm.email" disabled />
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="fullName">نام کامل</label> <label for="firstName">نام</label>
<input type="text" id="fullName" v-model="editForm.full_name" placeholder="نام و نام خانوادگی" /> <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>
<div class="form-group"> <div class="form-group">
<label for="position">جایگاه</label> <label for="position">جایگاه</label>
@ -134,11 +120,8 @@
{{ saving ? 'در حال ذخیره...' : 'ذخیره' }} {{ saving ? 'در حال ذخیره...' : 'ذخیره' }}
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
@ -152,85 +135,239 @@ export default {
return { return {
selectedProfileImage: null, selectedProfileImage: null,
userData: { 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: '' }, passwordForm: { current_password: '', new_password: '', confirm_password: '' },
initialFormState: { first_name: '', last_name: '', semat: '' },
saving: false, saving: false,
userAvatarUrl: 'https://i.imgur.com/QbXfV6C.png', userAvatarUrl: 'https://i.imgur.com/QbXfV6C.png',
baseUrl: 'http://194.62.43.230:8000' baseUrl: 'http://194.62.43.230:8000',
} };
}, },
created() { created() {
this.fetchUserData(); this.fetchUserData();
}, },
computed: { computed: {
userProfilePicUrl() { userProfilePicUrl() {
const customer = JSON.parse(localStorage.getItem('customer') || {}); // Prioritize userData from API if available
if (!customer.profile_img) return this.defaultProfileImage; if (this.userData.customer && this.userData.customer.profile_img) {
return `${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: { methods: {
async fetchUserData() { 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 { try {
const response = await axios.get('/getInfo'); 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 = { this.editForm = {
full_name: `${response.data.user.first_name} ${response.data.user.last_name}`.trim(), // ترکیب نام و نام خانوادگی first_name: userData.user.first_name || '',
email: response.data.user.email, last_name: userData.user.last_name || '',
semat: response.data.user.semat, email: userData.user.email || '',
userAvatarUrl: response.data.customer.profile_img 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) { } catch (error) {
Toast.fire({
icon: 'error',
title: 'خطا در بارگذاری اطلاعات کاربر. لطفاً دوباره تلاش کنید',
});
console.error('Error fetching user data:', error); 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() { 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; this.saving = true;
let isProfileChanged = false;
let isPasswordChanged = false;
let onlyNameChanged = false;
try { try {
const formData = new FormData(); const formData = new FormData();
// تجزیه full_name به first_name و last_name (اگر API نیاز دارد)
const [first_name = '', last_name = ''] = this.editForm.full_name.split(' ').filter(Boolean); if (this.editForm.first_name !== this.initialFormState.first_name || this.editForm.last_name !== this.initialFormState.last_name) {
formData.append('first_name', first_name); formData.append('first_name', this.editForm.first_name);
formData.append('last_name', last_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); formData.append('semat', this.editForm.semat);
isProfileChanged = true;
onlyNameChanged = false;
}
if (this.selectedProfileImage) { if (this.selectedProfileImage) {
formData.append('profile_img', this.selectedProfileImage); formData.append('profile_img', this.selectedProfileImage);
isProfileChanged = true;
onlyNameChanged = false;
} }
if (isProfileChanged) {
await axios.post(`${this.baseUrl}/editProfile/`, formData, { await axios.post(`${this.baseUrl}/editProfile/`, formData, {
headers: { headers: {
'Content-Type': 'multipart/form-data' 'Content-Type': 'multipart/form-data',
} },
}); });
}
// Handle password change if filled if (this.passwordForm.current_password && this.passwordForm.new_password) {
if (this.passwordForm.new_password && this.passwordForm.current_password) {
if (this.passwordForm.new_password !== this.passwordForm.confirm_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/`, { await axios.post(`${this.baseUrl}/resetPassword/`, {
old_password: this.passwordForm.current_password, 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(); 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) { } 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 { } finally {
this.saving = false; this.saving = false;
} }
}, },
changeAvatar() { 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() { 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) { uploadProfileImage(event) {
const file = event.target.files[0]; const file = event.target.files[0];
@ -238,11 +375,12 @@ export default {
this.selectedProfileImage = file; this.selectedProfileImage = file;
this.userProfilePicUrl = URL.createObjectURL(file); this.userProfilePicUrl = URL.createObjectURL(file);
} }
} },
} },
} };
</script> </script>
<style scoped> <style scoped>
.page-title { .page-title {

View File

@ -135,7 +135,7 @@ router.beforeEach(async (to, from, next) => {
if (!customer.is_sms_verified && to.name !== 'SmsVerification') { if (!customer.is_sms_verified && to.name !== 'SmsVerification') {
return next('/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'); return next('/dashboard/ChangeAvatar');
} }