1
0
Files
TaskBoard/front_vue/src/components/ProjectSelector.vue
Falknat 5018a2d123 Мобильная версия
1. Адаптация и разработка мобильного варианта.
2026-01-15 09:33:16 +07:00

152 lines
3.3 KiB
Vue

<template>
<div class="project-select" :class="{ mobile: isMobile }" v-if="store.currentProject" @click.stop>
<button class="project-btn" @click="dropdownOpen = !dropdownOpen">
<i data-lucide="folder" class="folder-icon"></i>
{{ store.currentProject?.name || 'Выберите проект' }}
<i data-lucide="chevron-down" class="chevron" :class="{ open: dropdownOpen }"></i>
</button>
<div class="project-dropdown" v-if="dropdownOpen">
<button
v-for="project in store.projects"
:key="project.id"
class="project-option"
:class="{ active: store.currentProjectId === project.id }"
@click="handleSelect(project.id)"
>
{{ project.name }}
</button>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import { useProjectsStore } from '../stores/projects'
import { useMobile } from '../composables/useMobile'
const store = useProjectsStore()
const { isMobile } = useMobile()
const dropdownOpen = ref(false)
const emit = defineEmits(['change'])
const handleSelect = async (projectId) => {
dropdownOpen.value = false
await store.selectProject(projectId)
emit('change', projectId)
}
// Закрытие дропдауна при клике вне
const closeDropdown = (e) => {
if (!e.target.closest('.project-select')) {
dropdownOpen.value = false
}
}
onMounted(() => {
document.addEventListener('click', closeDropdown)
if (window.lucide) window.lucide.createIcons()
})
onUnmounted(() => {
document.removeEventListener('click', closeDropdown)
})
</script>
<style scoped>
.project-select {
position: relative;
}
.project-btn {
display: flex;
align-items: center;
gap: 6px;
padding: 5px 11px;
background: var(--accent-soft);
border: 1px solid var(--accent);
border-radius: 6px;
color: var(--accent);
font-family: inherit;
font-size: 12px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.3px;
cursor: pointer;
transition: all 0.15s;
}
.project-btn:hover {
background: var(--accent);
color: #000;
}
.project-btn .folder-icon {
width: 12px;
height: 12px;
margin-right: 2px;
}
.project-btn .chevron {
width: 10px;
height: 10px;
margin-left: 4px;
opacity: 0.7;
transition: transform 0.2s;
}
.project-btn .chevron.open {
transform: rotate(180deg);
}
.project-dropdown {
position: absolute;
top: calc(100% + 6px);
left: 0;
min-width: 200px;
background: var(--bg-secondary);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 10px;
padding: 6px;
z-index: 100;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
}
.project-option {
display: block;
width: 100%;
padding: 10px 12px;
background: transparent;
border: none;
border-radius: 6px;
color: var(--text-secondary);
font-family: inherit;
font-size: 13px;
text-align: left;
cursor: pointer;
transition: all 0.15s;
}
.project-option:hover {
background: rgba(255, 255, 255, 0.06);
color: var(--text-primary);
}
.project-option.active {
background: var(--accent-soft);
color: var(--accent);
}
/* ========== MOBILE ========== */
.project-select.mobile .project-dropdown {
position: fixed;
top: auto;
left: 16px;
right: 16px;
bottom: 80px;
min-width: auto;
max-height: 60vh;
overflow-y: auto;
}
</style>