XRoomDashboardFront/xroom-dashboard/src/pages/dashboard/Spaces.vue
2025-06-08 19:20:16 +03:30

413 lines
8.8 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<!-- Top Header -->
<AppHeader pageTitle="فضاها" />
<!-- Description -->
<div class="section-description">
<div class="section-title">مدیریت فضای مجازی</div>
<p class="title-description">
با همکاران خود در یک فضای مجازی ملاقات کنید. در این صفحه میتوانید فضای اطراف خود را مشاهده و مدیریت کنید.
</p>
</div>
<!-- Add Space Button -->
<button class="add-space" @click="openCreateSpaceModal">
+ <span style="margin-right: 0.5rem;">اضافه کردن فضای اختصاصی</span>
</button>
<!-- Spaces -->
<div v-if="filteredSpaces.length > 0 " style="z-index: 0;">
<swiper
:slidesPerView="1.7"
:spaceBetween="20"
:freeMode="true"
:pagination="{ clickable: false }"
:modules="modules"
:breakpoints="{
768: { slidesPerView: 3.3, spaceBetween: 15 },
1024: { slidesPerView: 2.8, spaceBetween: 15 },
1280: { slidesPerView: 4.1, spaceBetween: 25 },
}"
class="mySwiper"
>
<swiper-slide v-for="(space, index) in filteredSpaces" :key="index" class="card">
<img :src="'http://my.xroomapp.com:8000' + space.img" alt="تصویر فضا" />
<div class="card-texts">
<h2>{{ space.name }}</h2>
<p class="space-capacity">
حداکثر: {{ space.capacity }} کاربر
</p>
<p class="space-type">
{{ space.type }}
</p>
</div>
</swiper-slide>
</swiper>
</div>
<div v-else class="no-spaces-message">
<p>هیچ فضایی با فیلترهای انتخابشده یافت نشد.</p>
</div>
</div>
<!-- Create Space Modal -->
<CreateSpaceModal
:isVisible="isCreateSpaceModalVisible"
@close="closeCreateSpaceModal"
:spaces="spaces"
@submit="handleCreateSpaceSubmit"
/>
</template>
<script>
import CreateSpaceModal from '@/components/CreateSpaceModal.vue';
import { Swiper, SwiperSlide } from 'swiper/vue';
import 'swiper/css';
import { FreeMode, Pagination } from 'swiper/modules';
import axios from 'axios';
export default {
name: 'DashboardPage',
components: {
CreateSpaceModal,
Swiper,
SwiperSlide,
},
data() {
return {
modules: [FreeMode, Pagination],
isCreateSpaceModalVisible: false,
sharingFilters: [
{ label: 'همه', value: 'all' },
{ label: 'تیم', value: 'team' },
{ label: 'حریم خصوصی', value: 'private' },
],
spaceTypeFilters: [
{ label: 'فضاها', value: 'spaces' },
{ label: 'قالب‌ها', value: 'templates' },
{ label: 'همه', value: 'all' },
],
activeSharingFilter: 'all',
activeSpaceTypeFilter: 'spaces',
spaces: [], // Initialize the spaces array
selectedSpace: null, // Store the selected space
};
},
computed: {
filteredSpaces() {
return this.spaces.filter((space) => {
const matchesSharing =
this.activeSharingFilter === 'all' || space.sharing === this.activeSharingFilter;
const matchesSpaceType =
this.activeSpaceTypeFilter === 'all' || space.spaceType === this.activeSpaceTypeFilter;
return matchesSharing && matchesSpaceType;
});
},
},
methods: {
setActiveSharingFilter(value) {
this.activeSharingFilter = value;
},
setActiveSpaceTypeFilter(value) {
this.activeSpaceTypeFilter = value;
},
openCreateSpaceModal() {
this.isCreateSpaceModalVisible = true;
},
closeCreateSpaceModal() {
this.isCreateSpaceModalVisible = false;
},
async fetchSpaces() {
try {
const token = localStorage.getItem('token'); // Retrieve the token from localStorage
if (!token) {
console.error('No token found!');
return;
}
const response = await axios.get(
'http://my.xroomapp.com:8000/get_spaces', // API endpoint
{
headers: {
Authorization: `Token ${token}`,
'Content-Type': 'application/json',
},
}
);
// Store the spaces data in the spaces array
this.spaces = response.data.spaces.map(space => ({
name: space.name,
img: space.assetBundleRoomId.img, // Assuming 'img' exists in the API response
capacity: space.capacity,
type: space.Private ? 'Private' : 'Public', // Adjust if you have a different field
sharing: space.Private ? 'private' : 'team',
spaceType: 'spaces',
description: space.description, // Store description from response
}));
} catch (error) {
console.error('Error fetching spaces:', error);
}
},
handleCreateSpaceSubmit(space) {
// Handle form submission here, space will contain the selected space and the additional fields
console.log('Form submitted with:', space);
this.closeCreateSpaceModal(); // Close the modal after submission
},
},
mounted() {
this.fetchSpaces(); // Fetch spaces when the component is mounted
},
};
</script>
<style>
/* Base styles applied across all screen sizes */
.section-title {
font-weight: 700;
color: #101010;
font-size: 19px;
line-height: 26.6px;
}
.section-description {
margin: 1rem 0 3rem;
font-size: 20px;
font-weight: 600;
color: #2d3748;
}
.section-description p {
line-height: 190%;
color: #4f5a69;
font-size: 15px;
margin-top: 1rem;
font-weight: 500;
text-align: justify;
}
.filter-section {
display: flex;
align-items: center;
margin-bottom: 2.5rem;
padding: 24px 16px;
border-radius: 10px;
background-color: #FFFFFF;
}
.sharing-filters {
max-width: 79%;
width: 100%;
margin-left: 1.5rem;
}
.space-type-filter {
max-width: 21%;
width: 100%;
}
.active-filter {
background-color: #3A57E8;
color: #FFFFFF;
font-size: 15px;
font-weight: 500;
border-radius: 8px;
border: none;
padding: 7px 12px;
cursor: pointer;
margin-left: 1rem;
}
.disable-filter {
color: #3A57E8;
background-color: #FFFFFF;
font-size: 15px;
font-weight: 500;
border-radius: 8px;
border: none;
padding: 7px 10px;
cursor: pointer;
margin-left: 1rem;
}
.filter-buttons {
margin-top: 1rem;
}
.add-space {
display: block;
background-color: #3A57E8;
color: #FFFFFF;
border-radius: 8px;
border: none;
cursor: pointer;
width: max-content;
margin: auto;
font-weight: 500;
}
.mySwiper {
margin: 2.5rem 0;
}
.card {
height: auto;
border: 1px solid #B8C0CB;
border-radius: 16px;
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
padding: 4px;
}
.card img {
width: 100%;
height: 10rem;
border-radius: 14px;
border: none;
object-fit: cover;
}
.card-texts {
width: 100%;
margin-top: 1rem;
padding-right: 1rem;
display: grid;
gap: 1rem;
}
.card-texts h2 {
text-overflow: ellipsis;
white-space: nowrap;
overflow-x: clip;
width: 170px;
font-weight: 600;
color: #101010;
}
.space-capacity {
display: flex;
align-items: center;
font-size: 14px;
font-weight: 500;
color: #718096;
}
.space-type {
display: flex;
align-items: center;
font-size: 14px;
font-weight: 500;
color: #3A57E8;
text-overflow: ellipsis;
overflow-x: clip;
white-space: nowrap;
width: 170px;
}
.no-spaces-message {
font-size: 18px;
font-weight: 500;
color: #101010;
margin-top: 4rem;
margin-bottom: 12rem;
text-align: center;
}
/* Media Queries for responsive adjustments */
@media (max-width: 600px) {
.card {
max-width: 250px;
height: 17.5rem;
}
.card-texts h2 {
font-size: 16px;
}
.add-space {
padding : 8px 18px ;
}
}
@media (min-width: 600px) and (max-width: 1024px) {
.card-texts h2 {
font-size: 17px;
font-weight: 500;
}
.card {
height: 17.5rem;
}
.add-space {
padding : 8px 18px ;
}
}
@media (min-width: 1024px) and (max-width: 1280px) {
.section-title {
font-size: 20px;
font-weight: 600;
color: #101010;
margin: 20px 0 10px;
}
.add-space {
padding: 10px 20px;
font-size: 15px;
}
.card-texts h2 {
font-size: 18px;
}
.card {
height: 17.5rem;
}
}
@media (min-width: 1280px) {
.section-title {
font-size: 21px;
}
.section-description p {
font-size: 17.5px;
}
.add-space {
padding: 12px 24px;
font-size: 16px;
}
.card {
max-width: 250px;
height: 20rem;
}
.card img {
width: 100%;
height: 12rem;
}
.card-texts h2 {
font-size: 21px;
}
.space-capacity,
.space-type {
font-size: 16px;
}
}
</style>