diff --git a/front_vue/index.html b/front_vue/index.html index 66cf375..d597a19 100644 --- a/front_vue/index.html +++ b/front_vue/index.html @@ -2,7 +2,7 @@ - + TaskBoard diff --git a/front_vue/public/config.js b/front_vue/public/config.js index 6820298..4391527 100644 --- a/front_vue/public/config.js +++ b/front_vue/public/config.js @@ -3,6 +3,9 @@ window.APP_CONFIG = { API_BASE: 'http://192.168.1.6', // Интервал автообновления данных (в секундах) - IDLE_REFRESH_SECONDS: 1 + IDLE_REFRESH_SECONDS: 1, + + // Брейкпоинт для мобильной версии (px) + MOBILE_BREAKPOINT: 768 } diff --git a/front_vue/src/App.vue b/front_vue/src/App.vue index 1010a52..b09fed6 100644 --- a/front_vue/src/App.vue +++ b/front_vue/src/App.vue @@ -2,6 +2,21 @@ + + diff --git a/front_vue/src/components/ArchiveCard.vue b/front_vue/src/components/ArchiveCard.vue index a889b23..fe4ae8a 100644 --- a/front_vue/src/components/ArchiveCard.vue +++ b/front_vue/src/components/ArchiveCard.vue @@ -1,75 +1,140 @@ diff --git a/front_vue/src/components/Board.vue b/front_vue/src/components/Board.vue index 61e96b7..8f58093 100644 --- a/front_vue/src/components/Board.vue +++ b/front_vue/src/components/Board.vue @@ -1,6 +1,6 @@ @@ -21,6 +36,35 @@ import { ref, computed, onMounted, onUpdated, watch } from 'vue' import Column from './Column.vue' import { cardsApi } from '../api' +import { useMobile } from '../composables/useMobile' + +const { isMobile } = useMobile() + +// Мобильный свайп +const columnsRef = ref(null) +const currentColumnIndex = ref(0) + +const onColumnsScroll = () => { + if (!columnsRef.value || !isMobile.value) return + const scrollLeft = columnsRef.value.scrollLeft + const columnWidth = columnsRef.value.scrollWidth / filteredColumns.value.length + currentColumnIndex.value = Math.round(scrollLeft / columnWidth) +} + +const scrollToColumn = (index) => { + if (!columnsRef.value) return + const columnWidth = columnsRef.value.scrollWidth / filteredColumns.value.length + columnsRef.value.scrollTo({ + left: index * columnWidth, + behavior: 'smooth' + }) +} + +// Название текущей колонки для мобильного индикатора +const currentColumnTitle = computed(() => { + const col = filteredColumns.value[currentColumnIndex.value] + return col ? col.title : '' +}) const props = defineProps({ activeDepartment: Number, @@ -277,4 +321,76 @@ defineExpose({ saveTask, deleteTask, archiveTask }) align-items: flex-start; } +/* ========== MOBILE: колонки со свайпом ========== */ +.board.mobile { + min-width: auto; + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + overflow: hidden; +} + +.board.mobile .columns { + flex: 1; + display: flex; + gap: 0; + padding: 0; + overflow-x: auto; + overflow-y: hidden; + scroll-snap-type: x mandatory; + scroll-behavior: smooth; + -webkit-overflow-scrolling: touch; + scrollbar-width: none; + -ms-overflow-style: none; + /* Отключаем вертикальный скролл на уровне этого элемента */ + overscroll-behavior: contain; + touch-action: pan-x; +} + +.board.mobile .columns::-webkit-scrollbar { + display: none; +} + +/* Мобильный футер с индикатором колонок */ +.mobile-column-footer { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + padding: 12px 16px; + background: var(--bg-body); + flex-shrink: 0; + min-height: 60px; +} + +.current-column-title { + font-size: 13px; + font-weight: 500; + color: var(--text-secondary); + text-align: center; +} + +.column-indicators { + display: flex; + justify-content: center; + gap: 8px; +} + +.indicator-dot { + width: 10px; + height: 10px; + border-radius: 50%; + background: rgba(255, 255, 255, 0.2); + border: none; + padding: 0; + cursor: pointer; + transition: all 0.3s ease; +} + +.indicator-dot.active { + width: 28px; + border-radius: 5px; + background: var(--dot-color, var(--accent)); +} diff --git a/front_vue/src/components/Card.vue b/front_vue/src/components/Card.vue index f2453e9..8be4bd1 100644 --- a/front_vue/src/components/Card.vue +++ b/front_vue/src/components/Card.vue @@ -22,6 +22,7 @@