2025-05-28 14:06:19 +00:00
|
|
|
|
<!-- DashboardPage.vue -->
|
2025-05-12 08:24:39 +00:00
|
|
|
|
<template>
|
|
|
|
|
<SidebarMenu />
|
2025-05-27 00:01:58 +00:00
|
|
|
|
|
2025-05-12 08:24:39 +00:00
|
|
|
|
<div class="dashboard-page">
|
|
|
|
|
<div class="content">
|
|
|
|
|
<!-- Top Header -->
|
|
|
|
|
<AppHeader pageTitle="تیم ها" />
|
|
|
|
|
<!-- Description -->
|
|
|
|
|
<div class="section-description">
|
2025-05-27 00:01:58 +00:00
|
|
|
|
<div class="section-title">مدیریت اعضا</div>
|
2025-05-12 08:24:39 +00:00
|
|
|
|
<p>
|
2025-05-27 00:01:58 +00:00
|
|
|
|
در این بخش به شما امکان میدهد تا اتاقها، فایلها و جلسات را با همکاران خود به اشتراک بگذارید. در این بخش میتوانید تیم خود را مدیریت کنید.
|
|
|
|
|
</p>
|
2025-05-12 08:24:39 +00:00
|
|
|
|
</div>
|
2025-05-27 00:01:58 +00:00
|
|
|
|
<!-- Tab Buttons -->
|
|
|
|
|
<div class="tab-buttons">
|
|
|
|
|
<button
|
|
|
|
|
:class="['tab-btn', activeTab === 'users' ? 'active' : '']"
|
|
|
|
|
@click="activeTab = 'users'"
|
|
|
|
|
>
|
|
|
|
|
کاربران
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
:class="['tab-btn', activeTab === 'buy-subscription' ? 'active' : '']"
|
|
|
|
|
@click="activeTab = 'buy-subscription'"
|
|
|
|
|
>
|
|
|
|
|
خرید اشتراک
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
:class="['tab-btn', activeTab === 'membership' ? 'active' : '']"
|
|
|
|
|
@click="activeTab = 'membership'"
|
|
|
|
|
>
|
|
|
|
|
اشتراک ها
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
:class="['tab-btn', activeTab === 'details' ? 'active' : '']"
|
|
|
|
|
@click="activeTab = 'details'"
|
|
|
|
|
>
|
|
|
|
|
جزئیات
|
|
|
|
|
</button>
|
2025-05-18 13:45:35 +00:00
|
|
|
|
</div>
|
2025-05-27 00:01:58 +00:00
|
|
|
|
<!-- Tab Content -->
|
|
|
|
|
<div v-if="activeTab === 'users'">
|
2025-05-28 08:42:55 +00:00
|
|
|
|
<TeamUser
|
2025-05-27 00:01:58 +00:00
|
|
|
|
:userList="userList"
|
2025-05-28 08:42:55 +00:00
|
|
|
|
:teamMemberCapacity="teamMemberCapacity"
|
|
|
|
|
:subscriptionCount="subscriptionCount"
|
2025-05-27 00:01:58 +00:00
|
|
|
|
@add-user="submitNewUser"
|
|
|
|
|
@change-tab="changeTab"
|
|
|
|
|
/>
|
2025-05-18 13:45:35 +00:00
|
|
|
|
</div>
|
2025-05-28 14:06:19 +00:00
|
|
|
|
<div v-if="activeTab === 'membership'">
|
|
|
|
|
<Membership
|
|
|
|
|
:subscriptionCount="subscriptionCount"
|
|
|
|
|
:teamMemberCapacity="teamMemberCapacity"
|
|
|
|
|
:isBillingModalVisible="isBillingModalVisible"
|
|
|
|
|
@change-tab="changeTab"
|
|
|
|
|
@update:isBillingModalVisible="isBillingModalVisible = $event"
|
|
|
|
|
/>
|
2025-05-18 13:45:35 +00:00
|
|
|
|
</div>
|
2025-05-28 14:06:19 +00:00
|
|
|
|
<div v-if="activeTab === 'details'">
|
2025-05-29 23:02:44 +00:00
|
|
|
|
<TeamDetails @update:teamData="handleTeamData" />
|
2025-05-18 13:45:35 +00:00
|
|
|
|
</div>
|
2025-05-28 14:06:19 +00:00
|
|
|
|
<div v-if="activeTab === 'buy-subscription'">
|
|
|
|
|
<BuySubscription
|
|
|
|
|
:memberCount="memberCount"
|
|
|
|
|
:availableMemberOptions="availableMemberOptions"
|
|
|
|
|
:baseUrl="baseUrl"
|
|
|
|
|
@update:memberCount="memberCount = $event"
|
|
|
|
|
@plan-selected="selectedPlan = $event"
|
|
|
|
|
@payment-success="handlePaymentSuccess"
|
|
|
|
|
/>
|
2025-05-18 13:45:35 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-05-12 08:24:39 +00:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
2025-05-27 00:01:58 +00:00
|
|
|
|
import SidebarMenu from '@/components/SidebarMenu.vue';
|
2025-05-12 08:24:39 +00:00
|
|
|
|
import AppHeader from '@/components/Header.vue';
|
2025-05-27 00:01:58 +00:00
|
|
|
|
import TeamUser from '@/components/TeamUser.vue';
|
2025-05-28 14:06:19 +00:00
|
|
|
|
import BuySubscription from '@/components/BuySubscription.vue';
|
|
|
|
|
import Membership from '@/components/Membership.vue';
|
|
|
|
|
import TeamDetails from '@/components/TeamDetails.vue';
|
2025-05-27 00:01:58 +00:00
|
|
|
|
import axios from 'axios';
|
2025-05-12 08:24:39 +00:00
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
name: 'DashboardPage',
|
|
|
|
|
components: {
|
|
|
|
|
SidebarMenu,
|
|
|
|
|
AppHeader,
|
2025-05-27 00:01:58 +00:00
|
|
|
|
TeamUser,
|
2025-05-28 14:06:19 +00:00
|
|
|
|
BuySubscription,
|
|
|
|
|
Membership,
|
|
|
|
|
TeamDetails,
|
2025-05-12 08:24:39 +00:00
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
2025-05-26 15:37:57 +00:00
|
|
|
|
isBillingModalVisible: false,
|
2025-05-18 13:45:35 +00:00
|
|
|
|
memberCount: 5,
|
|
|
|
|
availableMemberOptions: [5, 10, 20, 100],
|
2025-05-27 00:01:58 +00:00
|
|
|
|
selectedPlan: null,
|
2025-05-12 13:14:57 +00:00
|
|
|
|
userList: [
|
2025-05-27 00:01:58 +00:00
|
|
|
|
{
|
|
|
|
|
name: 'دانیال پژوهش کیا',
|
|
|
|
|
email: 'aminimperator@gmail.com',
|
|
|
|
|
role: 'نسخه آزمایشی',
|
|
|
|
|
version: '',
|
|
|
|
|
avatar: 'https://models.readyplayer.me/681f59760bc631a87ad25172.png',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'امین رمضانی',
|
|
|
|
|
email: 'aminimperator@gmail.com',
|
|
|
|
|
role: 'مدیر',
|
|
|
|
|
version: 'نسخه آزمایشی',
|
|
|
|
|
avatar: 'https://models.readyplayer.me/681f59760bc631a87ad25172.png',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'نوید رمضانی',
|
|
|
|
|
email: 'aminimperator@gmail.com',
|
|
|
|
|
role: 'مدیر',
|
|
|
|
|
version: 'نسخه آزمایشی',
|
|
|
|
|
avatar: 'https://models.readyplayer.me/681f59760bc631a87ad25172.png',
|
|
|
|
|
},
|
|
|
|
|
],
|
2025-05-12 13:14:57 +00:00
|
|
|
|
activeTab: 'users',
|
2025-05-12 08:24:39 +00:00
|
|
|
|
previewUrl: '',
|
2025-05-27 00:01:58 +00:00
|
|
|
|
currentPreviewIndex: null,
|
|
|
|
|
currentPreviewType: null,
|
|
|
|
|
videoOptions: {
|
2025-05-12 08:24:39 +00:00
|
|
|
|
autoplay: false,
|
|
|
|
|
controls: true,
|
2025-05-27 00:01:58 +00:00
|
|
|
|
sources: [
|
|
|
|
|
{
|
|
|
|
|
type: 'video/mp4',
|
|
|
|
|
src: '',
|
|
|
|
|
},
|
|
|
|
|
],
|
2025-05-12 08:24:39 +00:00
|
|
|
|
},
|
|
|
|
|
userData: {
|
|
|
|
|
customer: {},
|
|
|
|
|
user: {
|
|
|
|
|
first_name: '',
|
2025-05-27 00:01:58 +00:00
|
|
|
|
last_name: '',
|
2025-05-12 08:24:39 +00:00
|
|
|
|
},
|
|
|
|
|
images: [],
|
|
|
|
|
pdfs: [],
|
|
|
|
|
videos: [],
|
2025-05-27 00:01:58 +00:00
|
|
|
|
glbs: [],
|
2025-05-12 08:24:39 +00:00
|
|
|
|
},
|
|
|
|
|
newFileName: '',
|
|
|
|
|
selectedFile: null,
|
|
|
|
|
uploading: false,
|
|
|
|
|
baseUrl: 'http://194.62.43.230:8000',
|
|
|
|
|
currentUploadType: 'image',
|
|
|
|
|
dialogTitle: 'آپلود فایل جدید',
|
2025-05-27 00:01:58 +00:00
|
|
|
|
fileAccept: '*/*',
|
2025-05-28 08:42:55 +00:00
|
|
|
|
teamMemberCapacity: 0,
|
|
|
|
|
subscriptionCount: 0,
|
2025-05-27 00:01:58 +00:00
|
|
|
|
};
|
2025-05-12 08:24:39 +00:00
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
this.fetchUserData();
|
2025-05-28 08:42:55 +00:00
|
|
|
|
this.fetchTeamMemberInfo();
|
2025-05-12 08:24:39 +00:00
|
|
|
|
},
|
|
|
|
|
methods: {
|
2025-05-27 00:01:58 +00:00
|
|
|
|
changeTab(tabName) {
|
|
|
|
|
this.activeTab = tabName;
|
|
|
|
|
},
|
2025-05-28 14:06:19 +00:00
|
|
|
|
async handlePaymentSuccess() {
|
|
|
|
|
await this.fetchTeamMemberInfo();
|
|
|
|
|
this.activeTab = 'membership';
|
2025-05-27 00:01:58 +00:00
|
|
|
|
},
|
2025-05-28 08:42:55 +00:00
|
|
|
|
async fetchTeamMemberInfo() {
|
|
|
|
|
try {
|
|
|
|
|
const token = localStorage.getItem('token');
|
|
|
|
|
const response = await axios.get(`${this.baseUrl}/get_team_member_info`, {
|
|
|
|
|
headers: {
|
|
|
|
|
Authorization: `Token ${token}`,
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.teamMemberCapacity = response.data.data.team_member_capacity;
|
|
|
|
|
this.subscriptionCount = response.data.data.subscriptionCount;
|
2025-05-28 14:06:19 +00:00
|
|
|
|
console.log('تعداد اشتراکها (subscriptionCount):', this.subscriptionCount);
|
2025-05-28 08:42:55 +00:00
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('خطا در دریافت اطلاعات اشتراک:', error);
|
|
|
|
|
alert('خطا در بارگذاری اطلاعات اشتراک. لطفاً دوباره تلاش کنید.');
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
async submitNewUser(newUser) {
|
2025-05-28 14:06:19 +00:00
|
|
|
|
console.log('اطلاعات کاربر جدید:', newUser);
|
2025-05-28 08:42:55 +00:00
|
|
|
|
|
|
|
|
|
const remainingCapacity = this.subscriptionCount - this.teamMemberCapacity;
|
|
|
|
|
if (remainingCapacity <= 0) {
|
|
|
|
|
alert('ظرفیت تیم پر شده است. لطفاً اشتراک جدیدی خریداری کنید.');
|
|
|
|
|
this.activeTab = 'buy-subscription';
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const token = localStorage.getItem('token');
|
2025-05-28 14:06:19 +00:00
|
|
|
|
|
2025-05-28 08:42:55 +00:00
|
|
|
|
await axios.post(
|
2025-05-28 14:06:19 +00:00
|
|
|
|
'http://my.xroomapp.com:8000/add_teamMember/',
|
2025-05-28 08:42:55 +00:00
|
|
|
|
newUser,
|
|
|
|
|
{
|
|
|
|
|
headers: {
|
|
|
|
|
Authorization: `Token ${token}`,
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
this.userList.push({
|
|
|
|
|
...newUser,
|
|
|
|
|
avatar: 'https://models.readyplayer.me/681f59760bc631a87ad25172.png',
|
|
|
|
|
role: newUser.role || 'کاربر',
|
|
|
|
|
version: newUser.version || 'نسخه آزمایشی',
|
|
|
|
|
});
|
|
|
|
|
|
2025-05-28 14:06:19 +00:00
|
|
|
|
this.teamMemberCapacity++;
|
2025-05-28 08:42:55 +00:00
|
|
|
|
|
|
|
|
|
await this.fetchTeamMemberInfo();
|
|
|
|
|
|
|
|
|
|
alert('کاربر با موفقیت اضافه شد');
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('خطا در اضافه کردن کاربر:', error);
|
|
|
|
|
alert('خطا در اضافه کردن کاربر. لطفاً دوباره تلاش کنید.');
|
|
|
|
|
}
|
2025-05-27 00:01:58 +00:00
|
|
|
|
},
|
2025-05-12 08:24:39 +00:00
|
|
|
|
handleBackdropClick(event) {
|
2025-05-27 00:01:58 +00:00
|
|
|
|
if (event.target === this.$refs.filePreviewDialog) {
|
|
|
|
|
this.closePreviewDialog();
|
|
|
|
|
}
|
|
|
|
|
},
|
2025-05-29 23:02:44 +00:00
|
|
|
|
handleTeamData(data) {
|
|
|
|
|
console.log('اطلاعات دریافتی : ', data);
|
|
|
|
|
},
|
2025-05-12 08:24:39 +00:00
|
|
|
|
openPreviewDialog(type, index, url) {
|
|
|
|
|
if (type === 'video') {
|
|
|
|
|
this.videoOptions.sources[0].src = url;
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
this.$refs.filePreviewDialog?.showModal();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (!this.$refs.filePreviewDialog) {
|
2025-05-27 00:01:58 +00:00
|
|
|
|
console.error('Dialog element not found');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.currentPreviewType = type;
|
|
|
|
|
this.currentPreviewIndex = index;
|
2025-05-12 08:24:39 +00:00
|
|
|
|
this.previewUrl = url;
|
|
|
|
|
|
2025-05-27 00:01:58 +00:00
|
|
|
|
if (type === 'video') {
|
|
|
|
|
this.videoOptions.sources[0].src = url;
|
|
|
|
|
this.videoOptions.poster = this.getVideoThumbnail();
|
|
|
|
|
this.previewUrl = url;
|
|
|
|
|
} else {
|
|
|
|
|
this.previewUrl = url;
|
2025-05-12 08:24:39 +00:00
|
|
|
|
}
|
2025-05-27 00:01:58 +00:00
|
|
|
|
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
this.$refs.filePreviewDialog?.showModal();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (type === 'image') {
|
|
|
|
|
this.previewImageUrl = url;
|
|
|
|
|
this.previewPdfUrl = '';
|
|
|
|
|
} else if (type === 'pdf') {
|
|
|
|
|
this.previewPdfUrl = url;
|
|
|
|
|
this.previewImageUrl = '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.$refs.filePreviewDialog.showModal();
|
|
|
|
|
},
|
|
|
|
|
getVideoThumbnail() {
|
|
|
|
|
return 'https://cdn-icons-png.flaticon.com/512/2839/2839038.png';
|
|
|
|
|
},
|
|
|
|
|
closePreviewDialog() {
|
|
|
|
|
const dialog = this.$refs.filePreviewDialog;
|
|
|
|
|
if (dialog && typeof dialog.close === 'function') {
|
|
|
|
|
dialog.close();
|
|
|
|
|
} else {
|
|
|
|
|
console.warn('Dialog reference not found or close method unavailable');
|
2025-05-12 08:24:39 +00:00
|
|
|
|
}
|
2025-05-27 00:01:58 +00:00
|
|
|
|
this.previewUrl = '';
|
|
|
|
|
this.currentPreviewIndex = null;
|
|
|
|
|
this.currentPreviewType = null;
|
|
|
|
|
},
|
|
|
|
|
async downloadFile() {
|
|
|
|
|
const url =
|
|
|
|
|
this.currentPreviewType === 'image' ? this.previewImageUrl : this.previewPdfUrl;
|
|
|
|
|
if (!url) return;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const response = await fetch(url);
|
|
|
|
|
const blob = await response.blob();
|
|
|
|
|
const downloadUrl = window.URL.createObjectURL(blob);
|
|
|
|
|
const a = document.createElement('a');
|
|
|
|
|
a.href = downloadUrl;
|
|
|
|
|
|
|
|
|
|
if (this.currentPreviewType === 'image') {
|
|
|
|
|
a.download = `image-${new Date().getTime()}.${url.split('.').pop()}`;
|
|
|
|
|
} else if (this.currentPreviewType === 'pdf') {
|
|
|
|
|
a.download = `document-${new Date().getTime()}.pdf`;
|
2025-05-12 08:24:39 +00:00
|
|
|
|
}
|
2025-05-27 00:01:58 +00:00
|
|
|
|
|
|
|
|
|
document.body.appendChild(a);
|
|
|
|
|
a.click();
|
|
|
|
|
window.URL.revokeObjectURL(downloadUrl);
|
|
|
|
|
document.body.removeChild(a);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error downloading file:', error);
|
|
|
|
|
alert('خطا در دانلود فایل');
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
async deleteFile() {
|
|
|
|
|
if (this.currentPreviewIndex === null || !this.currentPreviewType) return;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const token = localStorage.getItem('token');
|
|
|
|
|
let deleteUrl = '';
|
|
|
|
|
let itemId = '';
|
|
|
|
|
let fileArray = [];
|
|
|
|
|
|
|
|
|
|
switch (this.currentPreviewType) {
|
|
|
|
|
case 'image':
|
|
|
|
|
fileArray = this.userData.images;
|
|
|
|
|
itemId = fileArray[this.currentPreviewIndex].id;
|
|
|
|
|
deleteUrl = `${this.baseUrl}/deleteImage/${itemId}/`;
|
|
|
|
|
break;
|
|
|
|
|
case 'pdf':
|
|
|
|
|
fileArray = this.userData.pdfs;
|
|
|
|
|
itemId = fileArray[this.currentPreviewIndex].id;
|
|
|
|
|
deleteUrl = `${this.baseUrl}/deletePdf/${itemId}/`;
|
|
|
|
|
break;
|
|
|
|
|
case 'video':
|
|
|
|
|
fileArray = this.userData.videos;
|
|
|
|
|
itemId = fileArray[this.currentPreviewIndex].id;
|
|
|
|
|
deleteUrl = `${this.baseUrl}/deleteVideo/${itemId}/`;
|
|
|
|
|
break;
|
|
|
|
|
case 'glb':
|
|
|
|
|
fileArray = this.userData.glbs;
|
|
|
|
|
itemId = fileArray[this.currentPreviewIndex].id;
|
|
|
|
|
deleteUrl = `${this.baseUrl}/deleteGlb/${itemId}/`;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await axios.delete(deleteUrl, {
|
|
|
|
|
headers: {
|
|
|
|
|
Authorization: `Token ${token}`,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.closePreviewDialog();
|
|
|
|
|
await this.fetchUserData();
|
|
|
|
|
alert('فایل با موفقیت حذف شد');
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error deleting file:', error);
|
|
|
|
|
alert('خطا در حذف فایل');
|
|
|
|
|
}
|
|
|
|
|
},
|
2025-05-12 08:24:39 +00:00
|
|
|
|
async fetchUserData() {
|
|
|
|
|
try {
|
|
|
|
|
const token = localStorage.getItem('token');
|
|
|
|
|
const response = await axios.get(`${this.baseUrl}/getInfo`, {
|
|
|
|
|
headers: {
|
2025-05-27 00:01:58 +00:00
|
|
|
|
Authorization: `Token ${token}`,
|
|
|
|
|
},
|
2025-05-12 08:24:39 +00:00
|
|
|
|
});
|
|
|
|
|
this.userData = response.data;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error fetching user data:', error);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
getFullImageUrl(relativePath) {
|
|
|
|
|
if (!relativePath) return '';
|
|
|
|
|
return `${this.baseUrl}${relativePath}`;
|
|
|
|
|
},
|
|
|
|
|
formatDate(dateString) {
|
|
|
|
|
if (!dateString) return '';
|
|
|
|
|
const date = new Date(dateString);
|
|
|
|
|
return date.toLocaleDateString('fa-IR');
|
|
|
|
|
},
|
|
|
|
|
openDialog(type) {
|
|
|
|
|
this.currentUploadType = type;
|
2025-05-27 00:01:58 +00:00
|
|
|
|
|
|
|
|
|
switch (type) {
|
2025-05-12 08:24:39 +00:00
|
|
|
|
case 'image':
|
|
|
|
|
this.dialogTitle = 'آپلود تصویر جدید';
|
|
|
|
|
this.fileAccept = 'image/*';
|
|
|
|
|
break;
|
|
|
|
|
case 'pdf':
|
|
|
|
|
this.dialogTitle = 'آپلود فایل PDF';
|
|
|
|
|
this.fileAccept = '.pdf';
|
|
|
|
|
break;
|
|
|
|
|
case 'video':
|
|
|
|
|
this.dialogTitle = 'آپلود ویدیو';
|
|
|
|
|
this.fileAccept = 'video/*';
|
|
|
|
|
break;
|
|
|
|
|
case 'glb':
|
|
|
|
|
this.dialogTitle = 'آپلود مدل 3D';
|
|
|
|
|
this.fileAccept = '.glb';
|
|
|
|
|
break;
|
|
|
|
|
}
|
2025-05-27 00:01:58 +00:00
|
|
|
|
|
2025-05-12 08:24:39 +00:00
|
|
|
|
this.$refs.newFileDialog.showModal();
|
|
|
|
|
},
|
|
|
|
|
closeDialog() {
|
|
|
|
|
this.newFileName = '';
|
|
|
|
|
this.selectedFile = null;
|
|
|
|
|
this.$refs.newFileDialog.close();
|
|
|
|
|
},
|
|
|
|
|
handleFileChange(event) {
|
|
|
|
|
this.selectedFile = event.target.files[0];
|
|
|
|
|
},
|
|
|
|
|
async uploadFile() {
|
|
|
|
|
if (!this.selectedFile) return;
|
2025-05-27 00:01:58 +00:00
|
|
|
|
|
2025-05-12 08:24:39 +00:00
|
|
|
|
this.uploading = true;
|
2025-05-27 00:01:58 +00:00
|
|
|
|
|
2025-05-12 08:24:39 +00:00
|
|
|
|
const formData = new FormData();
|
|
|
|
|
formData.append('name', this.newFileName || this.selectedFile.name);
|
|
|
|
|
|
2025-05-27 00:01:58 +00:00
|
|
|
|
switch (this.currentUploadType) {
|
|
|
|
|
case 'image':
|
|
|
|
|
formData.append('image', this.selectedFile);
|
|
|
|
|
break;
|
|
|
|
|
case 'pdf':
|
|
|
|
|
formData.append('pdf', this.selectedFile);
|
|
|
|
|
break;
|
|
|
|
|
case 'video':
|
|
|
|
|
formData.append('video', this.selectedFile);
|
|
|
|
|
break;
|
|
|
|
|
case 'glb':
|
|
|
|
|
formData.append('glb', this.selectedFile);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2025-05-12 08:24:39 +00:00
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const token = localStorage.getItem('token');
|
|
|
|
|
let uploadUrl = '';
|
2025-05-27 00:01:58 +00:00
|
|
|
|
|
|
|
|
|
switch (this.currentUploadType) {
|
2025-05-12 08:24:39 +00:00
|
|
|
|
case 'image':
|
|
|
|
|
uploadUrl = `${this.baseUrl}/uploadImage/`;
|
|
|
|
|
break;
|
|
|
|
|
case 'pdf':
|
|
|
|
|
uploadUrl = `${this.baseUrl}/uploadPdf/`;
|
|
|
|
|
break;
|
|
|
|
|
case 'video':
|
|
|
|
|
uploadUrl = `${this.baseUrl}/uploadVideo/`;
|
|
|
|
|
break;
|
|
|
|
|
case 'glb':
|
|
|
|
|
uploadUrl = `${this.baseUrl}/uploadGlb/`;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2025-05-27 00:01:58 +00:00
|
|
|
|
|
2025-05-12 08:24:39 +00:00
|
|
|
|
await axios.post(uploadUrl, formData, {
|
|
|
|
|
headers: {
|
2025-05-27 00:01:58 +00:00
|
|
|
|
Authorization: `Token ${token}`,
|
|
|
|
|
'Content-Type': 'multipart/form-data',
|
|
|
|
|
},
|
2025-05-12 08:24:39 +00:00
|
|
|
|
});
|
2025-05-27 00:01:58 +00:00
|
|
|
|
|
2025-05-12 08:24:39 +00:00
|
|
|
|
this.closeDialog();
|
|
|
|
|
await this.fetchUserData();
|
|
|
|
|
alert('فایل با موفقیت آپلود شد');
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error uploading file:', error);
|
|
|
|
|
alert('خطا در آپلود فایل');
|
|
|
|
|
} finally {
|
|
|
|
|
this.uploading = false;
|
|
|
|
|
}
|
2025-05-27 00:01:58 +00:00
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
2025-05-12 08:24:39 +00:00
|
|
|
|
</script>
|
2025-05-28 14:06:19 +00:00
|
|
|
|
|
|
|
|
|
<style scoped>
|
2025-05-12 08:24:39 +00:00
|
|
|
|
|
|
|
|
|
.section-title {
|
2025-05-30 15:41:53 +00:00
|
|
|
|
font-size: 20px;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
color: #2d3748;
|
|
|
|
|
margin-top: 20px;
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.section-description {
|
|
|
|
|
margin-bottom: 3rem;
|
|
|
|
|
margin-top: 1rem;
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
color: #2d3748;
|
|
|
|
|
margin: 1rem 0 3rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.section-description p {
|
|
|
|
|
line-height: 190%;
|
|
|
|
|
color: #4F5A69;
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
margin-top: 1rem;
|
2025-05-12 08:24:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
2025-05-28 14:06:19 +00:00
|
|
|
|
.dashboard-page {
|
|
|
|
|
margin-right: 360px;
|
2025-05-12 08:24:39 +00:00
|
|
|
|
padding: 20px;
|
2025-05-28 14:06:19 +00:00
|
|
|
|
direction: rtl;
|
|
|
|
|
font-family: IRANSansXFaNum, sans-serif;
|
2025-05-12 08:24:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
2025-05-28 14:06:19 +00:00
|
|
|
|
.content {
|
|
|
|
|
background-color: #f8f9fa;
|
|
|
|
|
border-radius: 20px;
|
|
|
|
|
padding: 35px 80px;
|
2025-05-12 08:24:39 +00:00
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-12 13:14:57 +00:00
|
|
|
|
.tab-buttons {
|
|
|
|
|
display: flex;
|
2025-05-28 14:06:19 +00:00
|
|
|
|
gap: 25px;
|
|
|
|
|
margin-top: 2rem;
|
|
|
|
|
margin-bottom: 2rem;
|
2025-05-12 13:14:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tab-btn {
|
|
|
|
|
background: none;
|
|
|
|
|
border: none;
|
|
|
|
|
color: gray;
|
2025-05-27 00:01:58 +00:00
|
|
|
|
font-size: 17px;
|
2025-05-12 13:14:57 +00:00
|
|
|
|
padding: 8px 16px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
border-bottom: 2px solid transparent;
|
|
|
|
|
transition: all 0.2s ease-in-out;
|
2025-05-28 14:06:19 +00:00
|
|
|
|
padding-right: 0;
|
2025-05-12 13:14:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tab-btn.active {
|
|
|
|
|
color: #3a57e8;
|
|
|
|
|
border-bottom: 2px solid #3a57e8;
|
2025-05-27 00:01:58 +00:00
|
|
|
|
font-size: 20px;
|
2025-05-12 13:14:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2025-05-27 00:01:58 +00:00
|
|
|
|
|
2025-05-28 14:06:19 +00:00
|
|
|
|
</style>
|