userAcount page Responsive

This commit is contained in:
Diyar Akhgar 2025-06-12 23:20:40 +03:30
parent 449cd33d26
commit ce9d9e6fbe
3 changed files with 391 additions and 97 deletions

View File

@ -182,6 +182,7 @@ export default {
align-items: center;
gap: 8px;
position: relative;
cursor: pointer;
}
.user-icon {

View File

@ -251,7 +251,7 @@ export default {
.profile-container {
display: flex;
align-items: center;
gap: 1.5rem;
gap: 0.5rem;
}
.group {
@ -346,7 +346,7 @@ export default {
@media (max-width: 520px) {
.sidebar {
width: 250px;
padding: 1rem 1rem 1rem 0.5rem;
padding: 1rem 0.5rem;
transition: transform 0.3s ease-in-out;
transform: translateX(100%);
}
@ -361,9 +361,18 @@ export default {
}
.group {
width: 100%;
}
.profile-link {
margin-right: -30px;
}
.frame {
padding-right: 0.5rem;
}
.clip-path-group-wrapper {
width: 150px;
height: 40px;
@ -379,7 +388,7 @@ export default {
@media (min-width: 520px) and (max-width: 780px) {
.sidebar {
width: 22rem;
padding: 1rem 1rem 1rem 0.5rem;
padding: 1rem 0.5rem 1rem 0.5rem;
transform: translateX(100%);
}
@ -395,6 +404,14 @@ export default {
.group {
width: 100%;
}
.profile-link {
margin-right: -30px;
}
.frame {
padding-right: 0.5rem;
}
.clip-path-group-wrapper {
width: 150px;
@ -478,24 +495,41 @@ export default {
.group {
width: 228px;
margin-bottom: 75px;
margin-bottom: 30px;
}
.profile {
margin-left: 20px;
width: 120px;
height: 120px;
margin-left: 0;
}
.profile-container {
padding: 10px 0;
position: relative;
gap: 0;
}
.text-wrapper-2 {
font-size: 16px;
}
.logo-xroom {
margin-top: 2.5rem;
}
.text-wrapper-3 {
font-size: 19px;
}
.clip-path-group{
width: 150px;
height: 40px;
}
.clip-path-group-wrapper {
width: 150px;
height: 40px;
}
}
</style>

View File

@ -13,11 +13,31 @@
<p class="section-description">
میتوانید با آپلود یک تصویر، به شخصیسازی آواتار خود، ظاهر خود را در محیط واقعیت مجازی ویرایش کنید.
</p>
<img :src="userAvatarUrl" class="avatar-image" />
<div class="avatar-actions">
<router-link to="/dashboard/readyPlayer">تغییر آواتار </router-link>
<img :src="userProfilePicUrl" class="avatar-image" />
<div style="display: flex;align-items: center;gap: 2.5rem;">
<span style="display: flex;align-items: center;">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
<g clip-path="url(#clip0_312_6762)">
<path d="M14.1147 4.54126C14.4671 4.18888 14.6652 3.71091 14.6652 3.2125C14.6653 2.71409 14.4674 2.23607 14.115 1.8836C13.7626 1.53112 13.2846 1.33307 12.7862 1.33301C12.2878 1.33295 11.8098 1.53088 11.4573 1.88326L2.55999 10.7826C2.4052 10.9369 2.29073 11.127 2.22665 11.3359L1.34599 14.2373C1.32876 14.2949 1.32746 14.3562 1.34222 14.4145C1.35699 14.4728 1.38727 14.5261 1.42985 14.5686C1.47244 14.6111 1.52573 14.6413 1.58409 14.656C1.64245 14.6707 1.70369 14.6693 1.76132 14.6519L4.66332 13.7719C4.8721 13.7084 5.0621 13.5947 5.21665 13.4406L14.1147 4.54126Z" stroke="#3A57E8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10 3.33325L12.6667 5.99992" stroke="#3A57E8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_312_6762">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>
<router-link to="/dashboard/readyPlayer">تغییر آواتار </router-link>
</span>
<span style="display: flex;align-items: center;">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M2 8C2 9.18669 2.35189 10.3467 3.01118 11.3334C3.67047 12.3201 4.60754 13.0892 5.7039 13.5433C6.80026 13.9974 8.00666 14.1162 9.17054 13.8847C10.3344 13.6532 11.4035 13.0818 12.2426 12.2426C13.0818 11.4035 13.6532 10.3344 13.8847 9.17054C14.1162 8.00666 13.9974 6.80026 13.5433 5.7039C13.0892 4.60754 12.3201 3.67047 11.3334 3.01118C10.3467 2.35189 9.18669 2 8 2C6.32263 2.00631 4.71265 2.66082 3.50667 3.82667L2 5.33333" stroke="#3A57E8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M2 2V5.33333H5.33333" stroke="#3A57E8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<router-link to="/dashboard/readyPlayer">ساخت آواتار جدید </router-link>
</span>
</div>
</div>
</div>
@ -53,12 +73,44 @@
این نماد در کنار نام شما و برای دیگران در واقعیت مجازی و در پلتفرم وب قابل مشاهده خواهد بود.
</p>
<img :src="userProfilePicUrl" class="profile-image" />
<input type="file" @change="uploadProfileImage" class="upload-input" />
<div style="display: flex; align-items: center;">
<img :src="userProfilePicUrl" class="profile-image" />
<label class="profile-upload" for="profile-upload">
<span>
<svg
xmlns="http://www.w3.org/2000/svg"
width="19"
height="19"
viewBox="0 0 16 16"
fill="none"
>
<path
d="M2.66602 11.3333V12.6666C2.66602 13.0202 2.80649 13.3593 3.05654 13.6094C3.30659 13.8594 3.64573 13.9999 3.99935 13.9999H11.9993C12.353 13.9999 12.6921 13.8594 12.9422 13.6094C13.1922 13.3593 13.3327 13.0202 13.3327 12.6666V11.3333"
stroke="white"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M4.66602 6.00008L7.99935 2.66675L11.3327 6.00008"
stroke="white"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M8 2.66675V10.6667"
stroke="white"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</span>
<span>آپلود</span>
</label>
<input type="file" @change="uploadProfileImage" id="profile-upload" class="upload-input" style="display: none;" />
</div>
</div>
@ -71,13 +123,12 @@
<input type="email" id="email" v-model="editForm.email" disabled />
</div>
<div class="form-group">
<label for="firstName">نام و نام خانوادگی</label>
<input type="text" id="firstName" v-model="editForm.first_name" />
<input type="text" id="lastName" v-model="editForm.last_name" />
<label for="fullName">نام کامل</label>
<input type="text" id="fullName" v-model="editForm.full_name" placeholder="نام و نام خانوادگی" />
</div>
<div class="form-group">
<label for="position">جایگاه</label>
<input v-model="editForm.semat" type="text" id="position" placeholder="جایگاه شغلی (اختیاری)" />
<input v-model="editForm.semat" type="text" id="position" placeholder="جایگاه شغلی (اختیاری)" />
</div>
<button class="save-btn" @click="saveProfile" :disabled="saving">
{{ saving ? 'در حال ذخیره...' : 'ذخیره' }}
@ -96,20 +147,16 @@ import axios from '@/axios';
export default {
name: 'EditProfile',
components: {
},
components: {},
data() {
return {
selectedProfileImage: null,
userData: {
user: { first_name: '', last_name: '', email: '', semat: '' }
},
editForm: { first_name: '', last_name: '', email: '' },
editForm: { full_name: '', email: '', semat: '' }, // جایگزینی first_name و last_name با full_name
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'
}
@ -130,88 +177,74 @@ export default {
const response = await axios.get('/getInfo');
this.userData = response.data;
this.editForm = {
first_name: response.data.user.first_name,
last_name: response.data.user.last_name,
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
userAvatarUrl: response.data.customer.profile_img
};
} catch (error) {
console.error('Error fetching user data:', error);
}
}
},
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);
formData.append('semat', this.editForm.semat);
this.saving = true;
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.selectedProfileImage) {
formData.append('profile_img', this.selectedProfileImage);
}
if (this.selectedProfileImage) {
formData.append('profile_img', this.selectedProfileImage);
}
await axios.post(`${this.baseUrl}/editProfile/`, formData, {
headers: {
'Content-Type': 'multipart/form-data'
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
});
}
await this.fetchUserData();
alert('تغییرات با موفقیت ذخیره شد');
} catch (error) {
alert(error.response?.data?.detail || error.message || 'خطا در ذخیره تغییرات');
} finally {
this.saving = false;
}
});
// 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
});
}
await this.fetchUserData();
alert('تغییرات با موفقیت ذخیره شد');
} catch (error) {
alert(error.response?.data?.detail || error.message || 'خطا در ذخیره تغییرات');
} finally {
this.saving = false;
}
},
},
changeAvatar() {
alert('تغییر آواتار کلیک شد');
},
regenerateAvatar() {
alert('ساخت مجدد آواتار کلیک شد');
},
uploadProfileImage(event) {
const file = event.target.files[0];
if (file) {
this.selectedProfileImage = file;
this.userProfilePicUrl = URL.createObjectURL(file);
uploadProfileImage(event) {
const file = event.target.files[0];
if (file) {
this.selectedProfileImage = file;
this.userProfilePicUrl = URL.createObjectURL(file);
}
}
}
}
}
</script>
<style scoped>
/* .dashboard-page {
margin-right: 360px;
padding: 20px;
direction: rtl;
font-family: IRANSansXFaNum, sans-serif;
}
.content {
background-color: #f8f9fa;
border-radius: 20px;
padding: 35px 80px;
display: flex;
flex-direction: column;
gap: 32px;
} */
.page-title {
font-size: 22px;
font-weight: bold;
@ -230,27 +263,43 @@ export default {
}
.form-section {
background: #fff;
border-radius: 12px;
padding: 24px;
margin-bottom: 24px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
.form-section h3 {
margin-bottom: 8px;
color: #222;
font-size: 18px;
margin-bottom: 1.5rem;
color: #101010;
font-weight: 600;
font-size: 21px;
}
.section-description {
color: #777;
font-size: 14px;
color: #667387;
font-size: 16px;
margin-bottom: 12px;
line-height: 190%;
}
.form-group {
margin-bottom: 16px;
display: flex;
justify-content: space-between;
align-items: center;
}
.profile-upload {
display: flex;
align-items: center;
gap: 0.5rem;
background-color: #6dc993;
padding: 10px 26px;
border-radius: 10px;
border: none;
font-size: 18px;
color: #fff;
cursor: pointer;
}
.form-group label {
@ -263,7 +312,7 @@ export default {
input[type="text"],
input[type="email"],
input[type="password"] {
width: 100%;
width: 70%;
padding: 10px 14px;
font-size: 14px;
border: 1px solid #ddd;
@ -271,22 +320,34 @@ input[type="password"] {
direction: rtl;
}
input[type="text"]:focus,
input[type="email"]:focus,
input[type="password"]:focus {
outline: none;
}
input:disabled {
background: #f5f5f5;
color: #777;
width: 70%;
}
.avatar-image,
.profile-image {
width: 80px;
height: 80px;
width: 120px;
height: 120px;
border-radius: 12px;
margin-bottom: 12px;
}
.avatar-actions {
display: flex;
align-items: center;
}
.avatar-actions a {
color: #3a57e8;
font-size: 14px;
font-size: 15px;
cursor: pointer;
margin: 0 4px;
}
@ -300,6 +361,9 @@ input:disabled {
font-weight: 500;
cursor: pointer;
margin-top: 8px;
width: 70%;
display: block;
margin-right: auto;
}
.save-btn:disabled {
@ -312,4 +376,199 @@ input:disabled {
}
</style>
/* سایز موبایل (max-width: 600px) */
@media screen and (max-width: 600px) {
.profile-edit-container {
flex-direction: column;
gap: 16px;
}
.column {
width: 100%;
}
.form-section {
padding: 16px;
margin-bottom: 16px;
}
.form-section h3 {
font-size: 18px;
}
.section-description {
font-size: 14px;
line-height: 170%;
}
.form-group {
flex-direction: column;
align-items: flex-start;
}
input[type="text"],
input[type="email"],
input[type="password"],
input:disabled {
width: 100%;
font-size: 13px;
padding: 8px 12px;
}
.save-btn {
width: 100%;
padding: 8px;
font-size: 14px;
}
.avatar-image,
.profile-image {
width: 80px;
height: 80px;
}
.avatar-actions {
flex-direction: column;
gap: 12px;
align-items: flex-start;
}
.profile-upload {
padding: 8px 20px;
font-size: 16px;
}
.avatar-actions a {
font-size: 14px;
}
}
/* سایز تبلت کوچک (min-width: 600px - max-width: 1024px) */
@media screen and (min-width: 600px) and (max-width: 1024px) {
.profile-edit-container {
flex-direction: column;
gap: 24px;
}
.column {
width: 100%;
}
.form-section {
padding: 20px;
margin-bottom: 20px;
}
.form-section h3 {
font-size: 20px;
}
.section-description {
font-size: 15px;
}
.form-group {
flex-direction: row;
}
input[type="text"],
input[type="email"],
input[type="password"],
input:disabled {
width: 65%;
font-size: 14px;
}
.save-btn {
width: 65%;
padding: 10px;
}
.avatar-image,
.profile-image {
width: 100px;
height: 100px;
}
.avatar-actions {
flex-direction: row;
gap: 16px;
}
.profile-upload {
padding: 10px 24px;
font-size: 17px;
}
}
/* سایز تبلت بزرگ و لپ‌تاپ کوچک (min-width: 1024px - max-width: 1280px) */
@media screen and (min-width: 1024px) and (max-width: 1280px) {
.profile-edit-container {
flex-direction: column;
gap: 24px;
}
.column {
width: 100%;
}
.form-section {
padding: 20px;
margin-bottom: 20px;
}
.form-section h3 {
font-size: 20px;
}
.section-description {
font-size: 15px;
}
.form-group {
flex-direction: row;
}
input[type="text"],
input[type="email"],
input[type="password"],
input:disabled {
width: 65%;
font-size: 14px;
}
.save-btn {
width: 65%;
padding: 10px;
}
.avatar-image,
.profile-image {
width: 100px;
height: 100px;
}
.avatar-actions {
flex-direction: row;
gap: 16px;
}
.profile-upload {
padding: 10px 24px;
font-size: 17px;
}
}
/* سایز دسکتاپ (min-width: 1280px) */
@media screen and (min-width: 1280px) {
/* استایل‌های اصلی دسکتاپ که در بالا تعریف شده‌اند اعمال می‌شوند */
/* تغییرات اضافی در صورت نیاز می‌توانید اینجا اضافه کنید */
.profile-edit-container {
gap: 32px;
}
.form-section {
padding: 24px;
}
}
</style>