fix edits

This commit is contained in:
Diyar Akhgar 2025-06-04 02:57:19 +03:30
parent f851bd5794
commit d8a0da9986
13 changed files with 313 additions and 140 deletions

View File

@ -111,19 +111,20 @@ router-view {
/* Responsive Styles */ /* Responsive Styles */
@media (max-width: 520px) { @media (max-width: 520px) {
.dashboard-page { .dashboard-page {
padding: 15px 5px; padding: 0;
direction: rtl; direction: rtl;
} }
.content { .content {
padding: 5px 15px !important; padding: 5px 15px !important;
gap: 0; gap: 0;
border-radius: 0;
} }
} }
@media (min-width: 521px) and (max-width: 780px) { @media (min-width: 521px) and (max-width: 780px) {
.dashboard-page { .dashboard-page {
padding: 15px; padding: 0;
direction: rtl; direction: rtl;
} }
@ -131,6 +132,7 @@ router-view {
padding: 0px 15px !important; padding: 0px 15px !important;
padding-bottom: 45px !important; padding-bottom: 45px !important;
gap: 0; gap: 0;
border-radius: 0;
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -118,7 +118,7 @@
d="M15 12.5L10 7.5L5 12.5" d="M15 12.5L10 7.5L5 12.5"
stroke="#3A57E8" stroke="#3A57E8"
stroke-width="2" stroke-width="2"
stroke-linecap prištede="round" stroke-linecap="round"
stroke-linejoin="round" stroke-linejoin="round"
/> />
</svg> </svg>
@ -292,7 +292,7 @@
</div> </div>
<div class="participants-objects"> <div class="participants-objects">
<h2>شرکت کنندگان</h2> <h2>شرکت کنندگان</h2>
<p><span style="color: #101010;font-weight: 600;">کاربران</span> یا <span style="color: #101010;font-weight: 600;">مهمانان تیم</span> را با پر کردن آدرس ایمیل آنها دعوت کنید.</p> <p><span style="color: #101010;font-weight: 600;">کاربران</span> یا <span style="color: #101010;font-weight: 600;">مهمانان تیم</span> را با پر کردن شماره تلفن آنها دعوت کنید.</p>
<span class="participants-guide"> <span class="participants-guide">
میتوانید به مجری اجازه بدهید تا ابزارهایی برای مدیریت این جلسه و همچنین ابزارهایی برای مدیریت مجوزها در طول جلسه به او بدهد. میتوانید به مجری اجازه بدهید تا ابزارهایی برای مدیریت این جلسه و همچنین ابزارهایی برای مدیریت مجوزها در طول جلسه به او بدهد.
</span> </span>
@ -304,23 +304,23 @@
</div> </div>
<div class="user-info"> <div class="user-info">
<p class="user-name">{{ fullName }}</p> <p class="user-name">{{ fullName }}</p>
<span>{{ userEmail || 'ایمیل موجود نیست' }}</span> <span>{{ userPhone || 'شماره تلفن موجود نیست' }}</span>
</div> </div>
</div> </div>
<p class="presenter-role">{{ userRole }}</p> <p class="presenter-role">{{ userRole }}</p>
</div> </div>
<div class="presenter" v-for="participant in participants" :key="participant.email"> <div class="presenter" v-for="participant in participants" :key="participant.phone">
<div style="display: flex;align-items: center;height: 100%;"> <div style="display: flex;align-items: center;height: 100%;">
<div class="avatar-wrapper"> <div class="avatar-wrapper">
<img class="user-avatar" :src="participant.profile_img || defaultProfileIcon" /> <img class="user-avatar" :src="participant.profile_img || defaultProfileIcon" />
</div> </div>
<div class="user-info"> <div class="user-info">
<p class="user-name">{{ participant.name || 'کاربر مهمان' }}</p> <p class="user-name">{{ participant.name || 'کاربر مهمان' }}</p>
<span>{{ participant.email }}</span> <span>{{ participant.phone }}</span>
</div> </div>
</div> </div>
<p class="presenter-role">{{ participant.role }}</p> <p class="presenter-role">{{ participant.role }}</p>
<button @click="removeParticipant(participant.email)"> <button @click="removeParticipant(participant.phone)">
<svg xmlns="http://www.w3.org/2000/svg" width="35" height="35" viewBox="0 0 32 32" fill="none"> <svg xmlns="http://www.w3.org/2000/svg" width="35" height="35" viewBox="0 0 32 32" fill="none">
<rect x="0.5" y="0.5" width="31" height="31" rx="7.5" fill="white"/> <rect x="0.5" y="0.5" width="31" height="31" rx="7.5" fill="white"/>
<rect x="0.5" y="0.5" width="31" height="31" rx="7.5" stroke="#E2DEE9"/> <rect x="0.5" y="0.5" width="31" height="31" rx="7.5" stroke="#E2DEE9"/>
@ -330,13 +330,13 @@
</button> </button>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="participantEmail">اضافه کردن شرکت کننده</label> <label for="participantPhone">اضافه کردن شرکت کننده</label>
<div class="participant-input"> <div class="participant-input">
<input <input
type="email" type="tel"
id="participantEmail" id="participantPhone"
v-model="newParticipantEmail" v-model="newParticipantPhone"
placeholder="لطفا ایمیل شرکت کننده را وارد کنید ..." placeholder="لطفا شماره تلفن شرکت کننده را وارد کنید"
@keyup.enter="addParticipant" @keyup.enter="addParticipant"
/> />
<button type="button" @click="addParticipant"> <button type="button" @click="addParticipant">
@ -349,7 +349,7 @@
</div> </div>
</form> </form>
<span class="last-span"> <span class="last-span">
شرکت کنندگان را اضافه کنید برای شرکت کنندگانی که به این جلسه اضافه شده اند ایمیلی حاوی کد جلسه، عنوان، توضیحات و زمان ارسال می شود. شرکت کنندگان را اضافه کنید برای شرکت کنندگانی که به این جلسه اضافه شده اند پیامکی حاوی کد جلسه، عنوان، توضیحات و زمان ارسال میشود.
</span> </span>
</div> </div>
<div class="form-actions"> <div class="form-actions">
@ -358,11 +358,11 @@
</div> </div>
</div> </div>
</div> </div>
<RoomSelectionModal <RoomSelectionModal
:is-open="isRoomSelectionOpen" :is-open="isRoomSelectionOpen"
@close="isRoomSelectionOpen = false" @close="isRoomSelectionOpen = false"
@submit-rooms="handleRoomSelection" @submit-rooms="handleRoomSelection"
/> />
</template> </template>
<script> <script>
@ -395,7 +395,7 @@ export default {
selectedRooms: [], selectedRooms: [],
}, },
participants: [], participants: [],
newParticipantEmail: '', newParticipantPhone: '',
defaultProfileIcon: 'https://c.animaapp.com/m9nvumalUMfQbN/img/frame.svg', defaultProfileIcon: 'https://c.animaapp.com/m9nvumalUMfQbN/img/frame.svg',
error: null, error: null,
isRoomSelectionOpen: false, isRoomSelectionOpen: false,
@ -408,8 +408,8 @@ export default {
? `${user.first_name} ${user.last_name}` ? `${user.first_name} ${user.last_name}`
: 'کاربر مهمان'; : 'کاربر مهمان';
}, },
userEmail() { userPhone() {
return 'diyar.akhgar@gmail.com'; return '09123456789'; // شماره تلفن کاربر اصلی (میتوانید از localStorage یا منبع دیگری بگیرید)
}, },
userRole() { userRole() {
return 'مجری'; return 'مجری';
@ -419,8 +419,7 @@ export default {
return customer.profile_img || this.defaultProfileIcon; return customer.profile_img || this.defaultProfileIcon;
}, },
}, },
watch: { watch: {
// نظارت بر باز و بسته شدن پاپآپ اصلی
isOpen(newVal) { isOpen(newVal) {
if (newVal) { if (newVal) {
document.body.style.overflow = 'hidden'; document.body.style.overflow = 'hidden';
@ -428,7 +427,6 @@ export default {
document.body.style.overflow = ''; document.body.style.overflow = '';
} }
}, },
// نظارت بر باز و بسته شدن پاپآپ انتخاب اتاق
isRoomSelectionOpen(newVal) { isRoomSelectionOpen(newVal) {
if (newVal) { if (newVal) {
document.body.style.overflow = 'hidden'; document.body.style.overflow = 'hidden';
@ -438,10 +436,9 @@ export default {
}, },
}, },
methods: { methods: {
beforeDestroy() { beforeDestroy() {
// اطمینان از فعال شدن اسکرول هنگام حذف کامپوننت document.body.style.overflow = '';
document.body.style.overflow = ''; },
},
openRoomSelection() { openRoomSelection() {
this.isRoomSelectionOpen = true; this.isRoomSelectionOpen = true;
}, },
@ -450,31 +447,32 @@ export default {
this.isRoomSelectionOpen = false; this.isRoomSelectionOpen = false;
}, },
addParticipant() { addParticipant() {
if (!this.newParticipantEmail || !this.validateEmail(this.newParticipantEmail)) { if (!this.newParticipantPhone || !this.validatePhone(this.newParticipantPhone)) {
this.error = 'لطفاً ایمیل معتبر وارد کنید'; this.error = 'لطفاً شماره تلفن معتبر وارد کنید (مثال: 09123456789)';
return; return;
} }
if ( if (
this.participants.some((p) => p.email === this.newParticipantEmail) || this.participants.some((p) => p.phone === this.newParticipantPhone) ||
this.newParticipantEmail === this.userEmail this.newParticipantPhone === this.userPhone
) { ) {
this.error = 'این ایمیل قبلاً اضافه شده است'; this.error = 'این شماره تلفن قبلاً اضافه شده است';
return; return;
} }
this.participants.push({ this.participants.push({
email: this.newParticipantEmail, phone: this.newParticipantPhone,
name: 'کاربر مهمان', name: 'کاربر مهمان',
role: 'شرکت‌کننده', role: 'شرکت‌کننده',
profile_img: this.defaultProfileIcon, profile_img: this.defaultProfileIcon,
}); });
this.newParticipantEmail = ''; this.newParticipantPhone = '';
this.error = null; this.error = null;
}, },
removeParticipant(email) { removeParticipant(phone) {
this.participants = this.participants.filter((p) => p.email !== email); this.participants = this.participants.filter((p) => p.phone !== phone);
}, },
validateEmail(email) { validatePhone(phone) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); // اعتبارسنجی شماره تلفن (مثال: فرمت شماره تلفن ایرانی)
return /^09[0-9]{9}$/.test(phone); // فرمت: 09XXXXXXXXX (11 رقم، شروع با 09)
}, },
closeModal() { closeModal() {
this.$emit('close'); this.$emit('close');
@ -492,7 +490,7 @@ export default {
selectedRooms: [], selectedRooms: [],
}; };
this.participants = []; this.participants = [];
this.newParticipantEmail = ''; this.newParticipantPhone = '';
this.error = null; this.error = null;
this.isRoomSelectionOpen = false; this.isRoomSelectionOpen = false;
}, },
@ -557,9 +555,9 @@ export default {
endDateTime, endDateTime,
rooms: this.form.selectedRooms, rooms: this.form.selectedRooms,
participants: [ participants: [
...(this.userEmail ? [{ email: this.userEmail, role: this.userRole }] : []), ...(this.userPhone ? [{ phone: this.userPhone, role: this.userRole }] : []),
...this.participants.map((p) => ({ ...this.participants.map((p) => ({
email: p.email, phone: p.phone,
role: p.role, role: p.role,
})), })),
], ],
@ -904,12 +902,17 @@ export default {
.participant-input button { .participant-input button {
position: absolute; position: absolute;
left: 0; right: 0;
top: 11px; top: 11px;
background-color: transparent; background-color: transparent;
border: none; border: none;
} }
#participantPhone::placeholder {
text-align: right;
padding-right: 1.5rem;
}
</style> </style>
<style> <style>

View File

@ -42,9 +42,9 @@
</svg> </svg>
</span> </span>
</button> </button>
<button class="green-button"> <button class="green-button" @click="goToBuySubscription">
<img :src="require('@/assets/img/shopIcon.png')" alt="Icon" class="button-icon" /> <img :src="require('@/assets/img/shopIcon.png')" alt="Icon" class="button-icon" />
<span>خرید اشتراک </span> <span>خرید اشتراک</span>
</button> </button>
</div> </div>
</template> </template>
@ -95,6 +95,9 @@ export default {
}, },
toggleSidebar() { toggleSidebar() {
this.$emit('toggle-sidebar'); this.$emit('toggle-sidebar');
},
goToBuySubscription() {
this.$router.push({ path: '/dashboard/teams', query: { tab: 'buy-subscription' } });
} }
}, },
mounted() { mounted() {

View File

@ -350,6 +350,17 @@ export default {
.group { .group {
width: 100%; width: 100%;
} }
.clip-path-group-wrapper {
width: 150px;
height: 40px;
}
.clip-path-group {
width: 150px;
height: 40px;
object-fit: contain;
}
} }
@media (min-width: 520px) and (max-width: 780px) { @media (min-width: 520px) and (max-width: 780px) {
@ -368,6 +379,17 @@ export default {
.group { .group {
width: 100%; width: 100%;
} }
.clip-path-group-wrapper {
width: 150px;
height: 40px;
}
.clip-path-group {
width: 150px;
height: 40px;
object-fit: contain;
}
} }
@media (min-width: 780px) and (max-width: 1280px) { @media (min-width: 780px) and (max-width: 1280px) {

View File

@ -2,7 +2,7 @@
<div class="signup-page"> <div class="signup-page">
<div class="signup-form"> <div class="signup-form">
<h2 class="title"> <h2 class="title">
<img :src="require('@/assets/img/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>

View File

@ -2,7 +2,7 @@
<div class="signup-page"> <div class="signup-page">
<div class="signup-form"> <div class="signup-form">
<h2 class="title"> <h2 class="title">
<img :src="require('@/assets/img/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>

View File

@ -2,7 +2,7 @@
<div class="signup-page"> <div class="signup-page">
<div class="signup-form"> <div class="signup-form">
<h2 class="title"> <h2 class="title">
<img :src="require('@/assets/img/logo.png')" alt="Logo" /> <img :src="require('@/assets/img/Logins-logo.png')" alt="Logo" />
</h2> </h2>
<h3 class="subtitle">ساخت حساب کاربری</h3> <h3 class="subtitle">ساخت حساب کاربری</h3>

View File

@ -2,7 +2,7 @@
<div class="signup-page"> <div class="signup-page">
<div class="signup-form"> <div class="signup-form">
<h2 class="title"> <h2 class="title">
<img :src="require('@/assets/img/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>

View File

@ -249,39 +249,39 @@ export default {
}, },
computed: { computed: {
filteredFileSections() { filteredFileSections() {
let sections = this.fileSections; let sections = this.fileSections;
if (this.activeFilter === 'all-files' || this.activeFilter === 'recent-files') { if (this.activeFilter === 'all-files' || this.activeFilter === 'recent-files') {
sections = this.fileSections.filter(section => { sections = this.fileSections.filter(section => {
const files = this.filteredFiles(section.type); const files = this.filteredFiles(section.type);
return files.length > 0; return files.length > 0;
}); });
} else { } else {
const filterTypeMap = { const filterTypeMap = {
images: 'image', images: 'image',
pdfs: 'pdf', pdfs: 'pdf',
videos: 'video', videos: 'video',
glbs: 'glb', glbs: 'glb',
others: 'other', others: 'other',
}; };
const filterType = filterTypeMap[this.activeFilter]; const filterType = filterTypeMap[this.activeFilter];
sections = filterType sections = filterType
? this.fileSections.filter(section => { ? this.fileSections.filter(section => {
const files = this.filteredFiles(section.type); const files = this.filteredFiles(section.type);
return section.type === filterType && files.length > 0; return section.type === filterType && files.length > 0;
}) })
: []; : [];
} }
return sections; return sections;
}, },
hasRecentFiles() { hasRecentFiles() {
const sevenDaysAgo = new Date(); const oneDayAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7); oneDayAgo.setHours(oneDayAgo.getHours() - 24);
return ['images', 'pdfs', 'videos', 'glbs', 'others'].some(type => return ['images', 'pdfs', 'videos', 'glbs', 'others'].some(type =>
this.userData[type].some(file => new Date(file.created_at) >= sevenDaysAgo) this.userData[type].some(file => new Date(file.created_at) >= oneDayAgo)
); );
}, },
}, },
created() { created() {
this.fetchUserData(); this.fetchUserData();
@ -305,13 +305,13 @@ export default {
if (!files) return []; if (!files) return [];
if (this.activeFilter === 'recent-files') { if (this.activeFilter === 'recent-files') {
const sevenDaysAgo = new Date(); const oneDayAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7); oneDayAgo.setHours(oneDayAgo.getHours() - 24);
return files.filter(file => new Date(file.created_at) >= sevenDaysAgo); return files.filter(file => new Date(file.created_at) >= oneDayAgo);
} }
const filterTypeMap = { const filterTypeMap = {
images: 'image', images: 'image',
pdfs: 'pdf', pdfs: 'pdf',
videos: 'video', videos: 'video',
glbs: 'glb', glbs: 'glb',
@ -332,7 +332,7 @@ export default {
case 'video': case 'video':
return 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTfQ1L9b8tFaGXBQxOdCCaq-AcYkmawPtRVZA&s'; return 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTfQ1L9b8tFaGXBQxOdCCaq-AcYkmawPtRVZA&s';
case 'glb': case 'glb':
return require('@/assets/img/3d icon.jpg'); return require('@/assets/img/3d-icon.jpg');
case 'other': case 'other':
return 'https://cdn-icons-png.flaticon.com/512/186/186159.png'; return 'https://cdn-icons-png.flaticon.com/512/186/186159.png';
default: default:
@ -395,6 +395,7 @@ export default {
}; };
</script> </script>
<style scoped> <style scoped>
/* General Styles */ /* General Styles */
.file-manager { .file-manager {

View File

@ -56,13 +56,15 @@
/> />
<img <img
src="https://c.animaapp.com/m9nvumalUMfQbN/img/frame-19.svg" src="https://c.animaapp.com/m9nvumalUMfQbN/img/frame-19.svg"
alt="Tutorial" alt="Downloads"
class="tutorial-item" class="tutorial-item"
@click="goToDownloads"
/> />
<img <img
src="https://c.animaapp.com/m9nvumalUMfQbN/img/frame-21.svg" src="https://c.animaapp.com/m9nvumalUMfQbN/img/frame-21.svg"
alt="Tutorial" alt="Teams"
class="tutorial-item" class="tutorial-item"
@click="goToTeams"
/> />
</div> </div>
</div> </div>
@ -104,25 +106,35 @@
:breakpoints="{ :breakpoints="{
768: { slidesPerView: 3.4, spaceBetween: 15 }, 768: { slidesPerView: 3.4, spaceBetween: 15 },
1024: { slidesPerView: 2.8, spaceBetween: 25 }, 1024: { slidesPerView: 2.8, spaceBetween: 25 },
1280: { slidesPerView: 3.8, spaceBetween: 30 }, 1280: { slidesPerView: 4.4, spaceBetween: 30 },
}" }"
:modules="modules" :modules="modules"
class="last-files-swiper" class="last-files-swiper"
> >
<swiper-slide v-for="(meeting, index) in meetings" :key="index" class="meeting-card"> <swiper-slide v-for="(file, index) in recentFiles" :key="index" class="meeting-card">
<div <div
class="card-image" class="card-image"
:style="{ backgroundImage: `url(${meeting.image})` }" :class="[
{
'file-image': file.type === 'image',
'file-pdf': file.type === 'pdf',
'file-video': file.type === 'video',
'file-glb': file.type === 'glb',
'file-other': file.type === 'other',
}
]"
:style="{ backgroundImage: `url(${getFilePreviewImage(file.type, file)})` }"
@click="openPreviewDialog(file.type, index, getFullFileUrl(file[file.type]), file.id)"
></div> ></div>
<div class="card-content"> <div class="card-content">
<h3>{{ meeting.title }}</h3> <h3>{{ file.name }}</h3>
<div class="meeting-date"> <div class="meeting-date">
<img <img
src="https://c.animaapp.com/m9nvumalUMfQbN/img/frame-1.svg" src="https://c.animaapp.com/m9nvumalUMfQbN/img/frame-1.svg"
alt="Calendar Icon" alt="Calendar Icon"
class="date-icon" class="date-icon"
/> />
<span>{{ meeting.date }}</span> <span>{{ formatDate(file.created_at) }}</span>
</div> </div>
</div> </div>
</swiper-slide> </swiper-slide>
@ -147,6 +159,16 @@
@close="closeDialog" @close="closeDialog"
@upload-success="fetchUserData" @upload-success="fetchUserData"
/> />
<FilePreviewDialog
:is-open="isPreviewDialogOpen"
:preview-url="previewUrl"
:preview-type="currentPreviewType"
:preview-index="currentPreviewIndex"
:base-url="baseUrl"
:video-options="videoOptions"
@close="closePreviewDialog"
@delete-success="fetchUserData"
/>
</div> </div>
</template> </template>
@ -154,9 +176,11 @@
import CreateMeetingModal from '@/components/CreateMeetingModal.vue'; import CreateMeetingModal from '@/components/CreateMeetingModal.vue';
import TutorialShowModal from '@/components/TutorialShowModal.vue'; import TutorialShowModal from '@/components/TutorialShowModal.vue';
import NewFileDialog from '@/components/NewFileDialog.vue'; import NewFileDialog from '@/components/NewFileDialog.vue';
import FilePreviewDialog from '@/components/FilePreviewDialog.vue';
import { Swiper, SwiperSlide } from 'swiper/vue'; import { Swiper, SwiperSlide } from 'swiper/vue';
import 'swiper/css'; import 'swiper/css';
import { Pagination } from 'swiper/modules'; import { Pagination } from 'swiper/modules';
import axios from 'axios';
export default { export default {
name: 'DashboardPage', name: 'DashboardPage',
@ -164,6 +188,7 @@ export default {
CreateMeetingModal, CreateMeetingModal,
TutorialShowModal, TutorialShowModal,
NewFileDialog, NewFileDialog,
FilePreviewDialog,
Swiper, Swiper,
SwiperSlide, SwiperSlide,
}, },
@ -173,48 +198,85 @@ export default {
showModal: false, showModal: false,
tutorialShowModal: false, tutorialShowModal: false,
isNewFileDialogOpen: false, isNewFileDialogOpen: false,
isPreviewDialogOpen: false,
currentUploadType: 'image', currentUploadType: 'image',
currentPreviewType: null,
currentPreviewIndex: null,
previewUrl: '',
baseUrl: 'http://194.62.43.230:8000', baseUrl: 'http://194.62.43.230:8000',
meetings: [ videoOptions: {
{ autoplay: false,
title: 'Pico Control', controls: true,
date: '24 تیر 1403', sources: [{ type: 'video/mp4', src: '' }],
image: 'https://c.animaapp.com/m9nvumalUMfQbN/img/frame-23-1.png', },
}, userData: {
{ images: [],
title: 'Flash Back', pdfs: [],
date: '24 تیر 1403', videos: [],
image: 'https://c.animaapp.com/m9nvumalUMfQbN/img/frame-23-4.png', glbs: [],
}, others: [],
{ },
title: 'Fakor Sanat Tehran', recentFiles: [],
date: '24 تیر 1403',
image: 'https://c.animaapp.com/m9nvumalUMfQbN/img/frame-23-2.png',
},
{
title: 'Design Artist',
date: '24 تیر 1403',
image: 'https://c.animaapp.com/m9nvumalUMfQbN/img/frame-23-3.png',
},
{
title: 'Fakor Sanat Tehran',
date: '24 تیر 1403',
image: 'https://c.animaapp.com/m9nvumalUMfQbN/img/frame-23-2.png',
},
{
title: 'Design Artist',
date: '24 تیر 1403',
image: 'https://c.animaapp.com/m9nvumalUMfQbN/img/frame-23-3.png',
},
{
title: 'Flash Back',
date: '24 تیر 1403',
image: 'https://c.animaapp.com/m9nvumalUMfQbN/img/frame-23-4.png',
},
],
}; };
}, },
created() {
this.fetchUserData();
},
methods: { methods: {
async fetchUserData() {
try {
const token = localStorage.getItem('token');
const response = await axios.get(`${this.baseUrl}/getInfo`, {
headers: {
Authorization: `Token ${token}`,
},
});
this.userData = {
...response.data.data,
others: response.data.data.others || [],
};
// فیلتر فایلهای اخیر (24 ساعت گذشته)
const oneDayAgo = new Date();
oneDayAgo.setHours(oneDayAgo.getHours() - 24);
this.recentFiles = [
...this.userData.images.map(file => ({ ...file, type: 'image' })),
...this.userData.pdfs.map(file => ({ ...file, type: 'pdf' })),
...this.userData.videos.map(file => ({ ...file, type: 'video' })),
...this.userData.glbs.map(file => ({ ...file, type: 'glb' })),
...this.userData.others.map(file => ({ ...file, type: 'other' })),
].filter(file => new Date(file.created_at) >= oneDayAgo);
} catch (error) {
console.error('Error fetching user data:', error);
this.recentFiles = [];
}
},
getFilePreviewImage(type, file) {
switch (type) {
case 'image':
return this.getFullFileUrl(file.image);
case 'pdf':
return 'https://cdn-icons-png.flaticon.com/512/337/337946.png';
case 'video':
return 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTfQ1L9b8tFaGXBQxOdCCaq-AcYkmawPtRVZA&s';
case 'glb':
return 'https://images.freeimages.com/clg/istock/previews/1024/102424081-icon-3d-modeling.jpg'; // URL ثابت برای مدل سهبعدی
case 'other':
return 'https://cdn-icons-png.flaticon.com/512/186/186159.png';
default:
return '';
}
},
getFullFileUrl(relativePath) {
if (!relativePath) return '';
return `${this.baseUrl}${relativePath}`;
},
formatDate(dateString) {
if (!dateString) return '';
const date = new Date(dateString);
return date.toLocaleDateString('fa-IR');
},
createNewMeeting(meetingData) { createNewMeeting(meetingData) {
this.meetings.push({ this.meetings.push({
title: meetingData.title, title: meetingData.title,
@ -232,8 +294,28 @@ export default {
closeDialog() { closeDialog() {
this.isNewFileDialogOpen = false; this.isNewFileDialogOpen = false;
}, },
fetchUserData() { openPreviewDialog(type, index, url, id) {
console.log('Fetching user data'); this.currentPreviewType = type;
this.currentPreviewIndex = id;
this.previewUrl = url;
if (type === 'video') {
this.videoOptions.sources[0].src = url;
}
this.isPreviewDialogOpen = true;
},
closePreviewDialog() {
this.isPreviewDialogOpen = false;
this.previewUrl = '';
this.currentPreviewIndex = null;
this.currentPreviewType = null;
},
goToDownloads() {
this.$router.push('/dashboard/download');
},
goToTeams() {
this.$router.push('/dashboard/teams');
}, },
}, },
}; };
@ -348,12 +430,22 @@ export default {
.card-image { .card-image {
width: 100%; width: 100%;
height: 120px; height: 172px;
background-size: cover; background-size: cover;
background-position: center; background-position: center;
border-radius: 14px 14px 0 0; border-radius: 14px 14px 0 0;
} }
.file-pdf,.file-video,.file-glb {
background-size: contain !important;
background-repeat: no-repeat;
margin-top: 0.8rem;
height: 160px;
width: 8rem !important;
margin-right: auto;
margin-left: auto;
}
.card-content { .card-content {
padding: 12px 10px 8px; padding: 12px 10px 8px;
} }
@ -499,6 +591,16 @@ export default {
height: 172px; height: 172px;
} }
.file-pdf,.file-video,.file-glb {
background-size: contain !important;
background-repeat: no-repeat;
margin-top: 0.8rem;
height: 160px;
width: 8rem !important;
margin-right: auto;
margin-left: auto;
}
.card-content { .card-content {
padding: 8px 16px 16px; padding: 8px 16px 16px;
} }
@ -564,17 +666,32 @@ export default {
height: 172px; height: 172px;
} }
.file-pdf,.file-video,.file-glb {
background-size: contain !important;
background-repeat: no-repeat;
margin-top: 0.8rem;
height: 160px;
width: 8rem !important;
margin-right: auto;
margin-left: auto;
}
.card-content { .card-content {
padding: 8px 16px 16px; padding: 8px 16px 16px;
} }
.card-content h3 { .card-content h3 {
font-size: 15px; font-size: 20px;
line-height: 190%;
} }
.date-icon { .date-icon {
width: 20px; width: 22px;
height: 20px; height: 22px;
}
.meeting-date span {
font-size: 16px;
} }
.file-buttons { .file-buttons {
@ -630,17 +747,32 @@ export default {
height: 172px; height: 172px;
} }
.file-pdf,.file-video,.file-glb {
background-size: contain !important;
background-repeat: no-repeat;
margin-top: 0.8rem;
height: 160px;
width: 8rem !important;
margin-right: auto;
margin-left: auto;
}
.card-content { .card-content {
padding: 8px 16px 16px; padding: 8px 16px 16px;
} }
.card-content h3 { .card-content h3 {
font-size: 15px; font-size: 20px;
line-height: 190%;
} }
.date-icon { .date-icon {
width: 20px; width: 22px;
height: 20px; height: 22px;
}
.meeting-date span {
font-size: 16px;
} }
.file-buttons { .file-buttons {

View File

@ -1,4 +1,3 @@
<!-- DashboardPage.vue -->
<template> <template>
<div> <div>
<!-- Description --> <!-- Description -->
@ -153,6 +152,10 @@ export default {
created() { created() {
this.fetchUserData(); this.fetchUserData();
this.fetchTeamMemberInfo(); this.fetchTeamMemberInfo();
const tab = this.$route.query.tab;
if (tab) {
this.activeTab = tab;
}
}, },
methods: { methods: {
changeTab(tabName) { changeTab(tabName) {
@ -468,6 +471,13 @@ export default {
} }
}, },
}, },
watch: {
'$route.query.tab'(newTab) {
if (newTab) {
this.activeTab = newTab;
}
}
}
}; };
</script> </script>