This commit is contained in:
alsaze 2025-11-18 17:14:40 +03:00
parent 5198cf0e0b
commit ddd8b7df71
10 changed files with 134 additions and 208 deletions

View File

@ -1,5 +1,3 @@
@use 'utils' as *;
//скроллбар //скроллбар
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 8px; width: 8px;
@ -30,33 +28,3 @@
body { body {
-ms-overflow-style: -ms-autohiding-scrollbar; -ms-overflow-style: -ms-autohiding-scrollbar;
} }
//swiper
.swiper {
width: 100%;
height: calc(100dvh - 54px);
}
.swiper-slide {
text-align: center;
font-size: 18px;
background: #444;
/* Center slide text vertically */
display: flex;
justify-content: center;
align-items: center;
}
.swiper-slide img {
display: block;
width: 100%;
height: calc(100dvh - 54px);
object-fit: cover;
}
.swiper-pagination {
position: absolute;
bottom: 200px !important;
--swiper-pagination-bullet-size: 4px
}

5
assets/scss/mixins.scss Normal file
View File

@ -0,0 +1,5 @@
@mixin mobile {
@media (max-width: 768px) {
@content;
}
}

View File

@ -1,148 +0,0 @@
@use 'sass:color';
@mixin mobile {
@media (max-width: 768px) {
@content;
}
}
$indents: 0 2 4 5 6 8 10 12 15 16 18 20 24 25 28 30 32 36 40 48 50 52 60 64;
@each $i in $indents {
.m#{$i} {
margin: #{$i}px;
}
.mx#{$i} {
margin-left: #{$i}px;
margin-right: #{$i}px;
}
.my#{$i} {
margin-top: #{$i}px;
margin-bottom: #{$i}px;
}
.mt#{$i} {
margin-top: #{$i}px;
}
.mb#{$i} {
margin-bottom: #{$i}px;
}
.ml#{$i} {
margin-left: #{$i}px;
}
.mr#{$i} {
margin-right: #{$i}px;
}
.p#{$i} {
padding: #{$i}px;
}
.px#{$i} {
padding-left: #{$i}px;
padding-right: #{$i}px;
}
.py#{$i} {
padding-top: #{$i}px;
padding-bottom: #{$i}px;
}
.pt#{$i} {
padding-top: #{$i}px;
}
.pb#{$i} {
padding-bottom: #{$i}px;
}
.pl#{$i} {
padding-left: #{$i}px;
}
.pr#{$i} {
padding-right: #{$i}px;
}
}
.mla {
margin-left: auto;
}
.mra {
margin-left: auto;
}
.mx-auto {
margin-left: auto;
margin-right: auto;
}
@each $align in ('left', 'right', 'center') {
.text-align-#{$align} {
text-align: #{$align};
}
}
.w-25 { width: 25% !important; }
.w-50 { width: 50% !important; }
.w-75 { width: 75% !important; }
.w-100 { width: 100% !important; }
.d-none { display: none !important; }
.d-inline { display: inline !important; }
.d-inline-block { display: inline-block !important; }
.d-block { display: block !important; }
.d-table { display: table !important; }
.d-table-row { display: table-row !important; }
.d-table-cell { display: table-cell !important; }
.d-flex { display: flex !important; }
.d-inline-flex { display: inline-flex !important; }
.flex-row { flex-direction: row !important; }
.flex-column { flex-direction: column !important; }
.flex-row-reverse { flex-direction: row-reverse !important; }
.flex-column-reverse { flex-direction: column-reverse !important; }
.flex-wrap { flex-wrap: wrap !important; }
.flex-nowrap { flex-wrap: nowrap !important; }
.flex-wrap-reverse { flex-wrap: wrap-reverse !important; }
.justify-content-start { justify-content: flex-start !important; }
.justify-content-end { justify-content: flex-end !important; }
.justify-content-center { justify-content: center !important; }
.justify-content-between { justify-content: space-between !important; }
.justify-content-around { justify-content: space-around !important; }
.align-items-start { align-items: flex-start !important; }
.align-items-end { align-items: flex-end !important; }
.align-items-center { align-items: center !important; }
.align-items-baseline { align-items: baseline !important; }
.align-items-stretch { align-items: stretch !important; }
.align-content-start { align-content: flex-start !important; }
.align-content-end { align-content: flex-end !important; }
.align-content-center { align-content: center !important; }
.align-content-between { align-content: space-between !important; }
.align-content-around { align-content: space-around !important; }
.align-content-stretch { align-content: stretch !important; }
.align-self-auto { align-self: auto !important; }
.align-self-start { align-self: flex-start !important; }
.align-self-end { align-self: flex-end !important; }
.align-self-center { align-self: center !important; }
.align-self-baseline { align-self: baseline !important; }
.align-self-stretch { align-self: stretch !important; }
.text-align-center { text-align: center !important; }
.text-align-left { text-align: left !important; }
.text-align-right { text-align: right !important; }
.cursor-pointer { cursor: pointer !important; }
.cursor-not-allowed { cursor: not-allowed !important; }
.cursor-progress { cursor: progress !important; }

10
components/Table.vue Normal file
View File

@ -0,0 +1,10 @@
<template>
</template>
<script setup lang="ts">
</script>
<style scoped lang="scss">
</style>

View File

@ -16,12 +16,7 @@
</div> </div>
</template> </template>
<script setup lang="ts">
</script>
<style lang="scss" scoped> <style lang="scss" scoped>
@use '~/assets/scss/utils' as *;
.layout { .layout {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@ -1,4 +1,8 @@
// https://nuxt.com/docs/api/configuration/nuxt-config // https://nuxt.com/docs/api/configuration/nuxt-config
import { createResolver } from '@nuxt/kit'
const { resolve } = createResolver(import.meta.url)
export default defineNuxtConfig({ export default defineNuxtConfig({
ssr: false, ssr: false,
compatibilityDate: '2025-05-15', compatibilityDate: '2025-05-15',
@ -36,4 +40,13 @@ export default defineNuxtConfig({
], ],
}, },
}, },
vite: {
css: {
preprocessorOptions: {
scss: {
additionalData: `@use "${resolve('./assets/scss/mixins')}" as *;`,
},
},
},
},
}) })

View File

@ -16,7 +16,6 @@
class="table-wrapper" class="table-wrapper"
> >
<div :style="{ height: `${totalSize}px` }"> <div :style="{ height: `${totalSize}px` }">
<!-- Even though we're still using sematic table tags, we must use CSS grid and flexbox for dynamic row heights -->
<table> <table>
<thead> <thead>
<tr <tr
@ -49,9 +48,9 @@
<tbody :style="{ height: `${totalSize}px` }"> <tbody :style="{ height: `${totalSize}px` }">
<tr <tr
v-for="vRow in virtualRows" v-for="vRow in virtualRows"
:ref="measureElement /*measure dynamic row height*/" :ref="measureElement"
:key="rows[vRow?.index]?.id" :key="rows[vRow?.index]?.id"
:data-index=" vRow?.index /* needed for dynamic row height measurement*/ " :data-index=" vRow?.index"
:style="{ transform: `translateY(${vRow?.start}px)` }" :style="{ transform: `translateY(${vRow?.start}px)` }"
> >
<td <td
@ -188,14 +187,13 @@ const table = useVueTable({
getSortedRowModel: getSortedRowModel(), getSortedRowModel: getSortedRowModel(),
}) })
// The virtualizer needs to know the scrollable container element
const rows = computed(() => table?.getRowModel()?.rows) const rows = computed(() => table?.getRowModel()?.rows)
const tableContainerRef = ref<HTMLDivElement | null>(null) const tableContainerRef = ref<HTMLDivElement | null>(null)
const rowVirtualizerOptions = computed(() => { const rowVirtualizerOptions = computed(() => {
return { return {
count: rows.value.length, count: rows.value.length,
estimateSize: () => 50, // estimate row height for accurate scrollbar dragging estimateSize: () => 50,
getScrollElement: () => tableContainerRef.value, getScrollElement: () => tableContainerRef.value,
overscan: 5, overscan: 5,
} }
@ -215,7 +213,6 @@ function measureElement(el?: Element) {
return undefined return undefined
} }
// virtualizer end
function openPost(post: Post) { function openPost(post: Post) {
selectedUser.value = users?.value?.find(user => user?.id === post?.userId) selectedUser.value = users?.value?.find(user => user?.id === post?.userId)
@ -228,8 +225,6 @@ function truncate(text: string, max = 15) {
</script> </script>
<style lang="scss"> <style lang="scss">
@use '~/assets/scss/utils' as *;
.index-page { .index-page {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@ -1,5 +0,0 @@
import { vMaska } from 'maska/vue'
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.directive('maska', vMaska)
})

View File

@ -5,12 +5,33 @@ export default defineEventHandler(async (event) => {
const { search } = getQuery(event) const { search } = getQuery(event)
const apiUrl = process.env.VITE_MY_API_BASE_URL! const apiUrl = process.env.VITE_MY_API_BASE_URL!
return await $fetch(`${apiUrl}/posts?title_like=${search}`, { return [
headers: { {
'Content-Type': 'application/json', userId: 1,
'Accept-Language': 'ru-RU', id: 1,
title: 'pizda',
body: 'jopa',
}, },
}) {
userId: 1,
id: 1,
title: 'pizda',
body: 'jopa',
},
{
userId: 1,
id: 1,
title: 'pizda',
body: 'jopa',
},
]
// return await $fetch<Posts>(`${apiUrl}/posts?title_like=${search}`, {
// headers: {
// 'Content-Type': 'application/json',
// 'Accept-Language': 'ru-RU',
// },
// })
} }
catch (error) { catch (error) {
return sendError(event, createError({ return sendError(event, createError({

View File

@ -4,12 +4,84 @@ export default defineEventHandler(async (event) => {
try { try {
const apiUrl = process.env.VITE_MY_API_BASE_URL! const apiUrl = process.env.VITE_MY_API_BASE_URL!
return await $fetch<Users>(`${apiUrl}/users`, { return [
headers: { {
'Content-Type': 'application/json', id: 1,
'Accept-Language': 'ru-RU', name: 'pizda',
username: 'jopa',
email: 'pizdajopa@nail.com',
address: {
street: 'pushkina',
suite: 'xuyushkina',
city: 'Omsk',
zipcode: 'xuicode',
geo: {
lat: '-9123',
lng: '32112',
}, },
}) },
phone: '89219123321',
website: 'koptilnya.xyz',
company: {
name: 'alfabot',
catchPhrase: 'xuibot',
bs: 'bs xueta kakayota',
},
},
{
id: 1,
name: 'pizda',
username: 'jopa',
email: 'pizdajopa@nail.com',
address: {
street: 'pushkina',
suite: 'xuyushkina',
city: 'Omsk',
zipcode: 'xuicode',
geo: {
lat: '-9123',
lng: '32112',
},
},
phone: '89219123321',
website: 'koptilnya.xyz',
company: {
name: 'alfabot',
catchPhrase: 'xuibot',
bs: 'bs xueta kakayota',
},
},
{
id: 1,
name: 'pizda',
username: 'jopa',
email: 'pizdajopa@nail.com',
address: {
street: 'pushkina',
suite: 'xuyushkina',
city: 'Omsk',
zipcode: 'xuicode',
geo: {
lat: '-9123',
lng: '32112',
},
},
phone: '89219123321',
website: 'koptilnya.xyz',
company: {
name: 'alfabot',
catchPhrase: 'xuibot',
bs: 'bs xueta kakayota',
},
},
]
// return await $fetch<Users>(`${apiUrl}/users`, {
// headers: {
// 'Content-Type': 'application/json',
// 'Accept-Language': 'ru-RU',
// },
// })
} }
catch (error) { catch (error) {
return sendError(event, createError({ return sendError(event, createError({