Files
tgCrewLanding/src/components/ProblemSection.vue
2025-07-16 22:08:48 +03:00

90 lines
2.6 KiB
Vue

<template>
<slide-template title="problem__title">
<div ref="container" class="w100">
<q-resize-observer @resize="updateWidth" />
<div
v-for="(row, rowIndex) in rows"
:key="rowIndex"
class="row q-py-none"
:class="rowClass(row.length)"
>
<div
v-for="(item, itemIndex) in row"
:key="itemIndex"
class="flex-item"
:style="itemStyle(row.length)"
>
<problem-section-item
:icon="item.icon"
:title="item.title"
:description="item.description"
style="overflow: hidden; min-width: 200px; max-width: 100%"
/>
</div>
</div>
</div>
</slide-template>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import ProblemSectionItem from 'components/ProblemSectionItem.vue'
import SlideTemplate from 'components/SlideTemplate.vue'
const problems = [
{ id: 1, icon: 'mdi-account-group-outline', title: 'problem__address_book', description: 'problem__address_book_description' },
{ id: 2, icon: 'mdi-clipboard-outline', title: 'problem__task_manager', description: 'problem__task_manager_description' },
{ id: 3, icon: 'mdi-calendar-month', title: 'problem__meeting', description: 'problem__meeting_description' },
{ id: 4, icon: 'mdi-folder-open-outline', title: 'problem__files', description: 'problem__files_description' },
{ id: 5, icon: 'mdi-lock-outline', title: 'problem__privacy', description: 'problem__privacy_description' }
]
const baseWidth = 250
const containerWidth = ref(0)
const updateWidth = ({ width }) => {
containerWidth.value = width
}
const maxPerRow = computed(() => {
return Math.max(1, Math.floor(containerWidth.value / baseWidth))
})
const rows = computed(() => {
const total = problems.length
const maxRow = maxPerRow.value
if (maxRow >= total) return [problems]
const rowCount = Math.ceil(total / maxRow)
const baseItems = Math.floor(total / rowCount)
const extra = total % rowCount
const result = []
let start = 0
for (let i = 0; i < rowCount; i++) {
const take = baseItems + (i < extra ? 1 : 0)
result.push(problems.slice(start, start + take))
start += take
}
return result
})
const rowClass = (count) => {
return count === 1 ? 'justify-center' : 'justify-between'
}
const itemStyle = (count) => {
return {
flex: `0 0 ${100 / count}%`,
maxWidth: `${100 / count}%`
}
}
</script>
<style scoped>
</style>