product page and linter

This commit is contained in:
2025-07-03 11:13:42 +02:00
parent fbb6c071af
commit 90e1d70f64
72 changed files with 12667 additions and 6578 deletions

View File

@ -1,26 +1,41 @@
<template>
<div class="group flex cursor-pointer items-center justify-start gap-2 whitespace-nowrap">
<button :class="[
'h-[40px] cursor-pointer min-w-40 rounded-[10px] px-[22px] transition-all sm:h-[50px] md:h-[65px] md:rounded-[15px] md:px-[42px]',
type === 'fill'
? 'bg-button text-text-dark group-hover:bg-button-hover'
: type === 'border'
? 'border-button text-button group-hover:border-button-hover group-hover:text-button-hover border'
: 'border-button text-button dark:border-block dark:text-block group-hover:border-button-hover group-hover:text-button-hover border',
full && 'w-full'
]">
<div
class="group flex cursor-pointer items-center justify-start gap-2 whitespace-nowrap"
>
<button
:class="[
'h-[40px] cursor-pointer min-w-40 rounded-[10px] px-[22px] transition-all sm:h-[50px] md:h-[65px] md:rounded-[15px] md:px-[42px]',
type === 'fill'
? 'bg-button text-text-dark group-hover:bg-button-hover'
: type === 'border'
? 'border-button text-button group-hover:border-button-hover group-hover:text-button-hover border'
: 'border-button text-button dark:border-block dark:text-block group-hover:border-button-hover group-hover:text-button-hover border',
full && 'w-full',
]"
>
<slot />
</button>
<div v-if="arrow" :class="[
'flex h-[40px] w-[40px] items-center justify-center rounded-[10px] p-2.5 transition-all sm:h-[50px] sm:w-[50px] md:h-[65px] md:w-[65px] md:rounded-[15px]',
type === 'fill'
? 'bg-button text-text-dark group-hover:bg-button-hover'
: 'border-button text-button dark:border-block dark:text-block group-hover:border-button-hover group-hover:text-button-hover border',
]">
<svg class="" width="26" height="26" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<div
v-if="arrow"
:class="[
'flex h-[40px] w-[40px] items-center justify-center rounded-[10px] p-2.5 transition-all sm:h-[50px] sm:w-[50px] md:h-[65px] md:w-[65px] md:rounded-[15px]',
type === 'fill'
? 'bg-button text-text-dark group-hover:bg-button-hover'
: 'border-button text-button dark:border-block dark:text-block group-hover:border-button-hover group-hover:text-button-hover border',
]"
>
<svg
class=""
width="26"
height="26"
viewBox="0 0 26 26"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M25.1274 1.87258C25.1274 1.3203 24.6797 0.872582 24.1274 0.872584L15.1274 0.872583C14.5751 0.872583 14.1274 1.3203 14.1274 1.87258C14.1274 2.42487 14.5751 2.87258 15.1274 2.87258L23.1274 2.87258L23.1274 10.8726C23.1274 11.4249 23.5751 11.8726 24.1274 11.8726C24.6797 11.8726 25.1274 11.4249 25.1274 10.8726L25.1274 1.87258ZM1.5 24.5L2.20711 25.2071L24.8345 2.57969L24.1274 1.87258L23.4203 1.16548L0.792893 23.7929L1.5 24.5Z"
fill="currentColor" />
fill="currentColor"
/>
</svg>
</div>
</div>
@ -37,5 +52,5 @@ defineProps({
full: {
type: Boolean,
},
});
})
</script>

View File

@ -1,57 +1,81 @@
<template>
<div class="space-y-[15px]">
<p :for="`base-input-${id}`" class="pl-6">
<slot />
</p>
<div class="flex flex-col">
<div class="flex relative">
<input :id="`base-input-${id}`" :value="modelValue" :type="!isPasswordVisible ? type : 'text'"
:placeholder="placeholder" :disabled="disabled"
@input="$emit('update:modelValue', ($event.target as HTMLInputElement).value)"
@focus="$emit('focus')" @blur="$emit('blur')"
class="border border-block placeholder:text-gray dark:placeholder:text-button-disabled rounded-lg px-6 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2" />
<i v-if="disabled"
class="uil uil-lock-alt text-[22px] absolute right-6 top-1/2 -translate-y-1/2 text-gray" />
<div class="space-y-[15px]">
<p :for="`base-input-${id}`"
class="pl-6"
>
<slot />
</p>
<div class="flex flex-col">
<div class="flex relative">
<input
:id="`base-input-${id}`"
:value="modelValue"
:type="!isPasswordVisible ? type : 'text'"
:placeholder="placeholder"
:disabled="disabled"
class="border border-block placeholder:text-gray dark:placeholder:text-button-disabled rounded-lg px-6 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2"
@input="
$emit(
'update:modelValue',
($event.target as HTMLInputElement).value,
)
"
@focus="$emit('focus')"
@blur="$emit('blur')"
>
<i
v-if="disabled"
class="uil uil-lock-alt text-[22px] absolute right-6 top-1/2 -translate-y-1/2 text-gray"
/>
<div v-if="type === 'password'" class="order-2 ml-1.5 cursor-pointer" :title="!isPasswordVisible ? $t('show_password') : $t('hide_password')
" @click="isPasswordVisible = !isPasswordVisible">
<FaceObserver class="ml-4 text-xl leading-6" :isPasswordVisible="isPasswordVisible" />
</div>
<div
v-if="type === 'password'"
class="order-2 ml-1.5 cursor-pointer"
:title="
!isPasswordVisible ? $t('show_password') : $t('hide_password')
"
@click="isPasswordVisible = !isPasswordVisible"
>
<FaceObserver
class="ml-4 text-xl leading-6"
:is-password-visible="isPasswordVisible"
/>
</div>
</div>
</div>
<!-- <p class="mt-2 text-xs text-red-600">{{ validationText }}</p> -->
<!-- <p class="mt-2 text-xs text-red-600">{{ validationText }}</p> -->
<!-- <p v-if="!validation && validation != null" class="mt-2 text-xs text-red-600">
<!-- <p v-if="!validation && validation != null" class="mt-2 text-xs text-red-600">
{{ validationText }}
</p> -->
</div>
</div>
</div>
</template>
<script setup lang="ts">
import FaceObserver from './FaceObserver.vue';
defineEmits(["update:modelValue", "focus", "blur"]);
<script setup lang="ts">
import FaceObserver from './FaceObserver.vue'
defineEmits(['update:modelValue', 'focus', 'blur'])
defineProps<{
modelValue?: string | any;
modelModifiers?: object;
id: number;
type?: string;
disabled?: boolean;
placeholder?: string;
validation?: boolean | null;
validationText?: string;
}>();
const isPasswordVisible = ref(false);
modelValue?: string | undefined
modelModifiers?: object
id: number
type?: string
disabled?: boolean
placeholder?: string
validation?: boolean | null
validationText?: string
}>()
const isPasswordVisible = ref(false)
</script>
<style>
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
transition: background-color 5000s ease-in-out 0s;
transition: background-color 5000s ease-in-out 0s;
}
</style>
</style>

View File

@ -1,8 +1,9 @@
<template>
<UContainer
class="mx-auto w-full max-w-[380px] px-4 sm:max-w-[768px] sm:px-[17px] md:max-w-[1000px] md:px-6 xl:max-w-[1920px] xl:px-20">
<slot />
</UContainer>
<UContainer
class="mx-auto w-full max-w-[380px] px-4 sm:max-w-[768px] sm:px-[17px] md:max-w-[1000px] md:px-6 xl:max-w-[1920px] xl:px-20"
>
<slot />
</UContainer>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup></script>

View File

@ -1,15 +1,37 @@
<template>
<svg v-if="isPasswordVisible" xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 -960 960 960" width="16px" fill="#000000"><path d="m644-428-58-58q9-47-27-88t-93-32l-58-58q17-8 34.5-12t37.5-4q75 0 127.5 52.5T660-500q0 20-4 37.5T644-428Zm128 126-58-56q38-29 67.5-63.5T832-500q-50-101-143.5-160.5T480-720q-29 0-57 4t-55 12l-62-62q41-17 84-25.5t90-8.5q151 0 269 83.5T920-500q-23 59-60.5 109.5T772-302Zm20 246L624-222q-35 11-70.5 16.5T480-200q-151 0-269-83.5T40-500q21-53 53-98.5t73-81.5L56-792l56-56 736 736-56 56ZM222-624q-29 26-53 57t-41 67q50 101 143.5 160.5T480-280q20 0 39-2.5t39-5.5l-36-38q-11 3-21 4.5t-21 1.5q-75 0-127.5-52.5T300-500q0-11 1.5-21t4.5-21l-84-82Zm319 93Zm-151 75Z"/></svg>
<svg v-else xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 -960 960 960" width="16px" fill="#000000"><path d="M480-320q75 0 127.5-52.5T660-500q0-75-52.5-127.5T480-680q-75 0-127.5 52.5T300-500q0 75 52.5 127.5T480-320Zm0-72q-45 0-76.5-31.5T372-500q0-45 31.5-76.5T480-608q45 0 76.5 31.5T588-500q0 45-31.5 76.5T480-392Zm0 192q-146 0-266-81.5T40-500q54-137 174-218.5T480-800q146 0 266 81.5T920-500q-54 137-174 218.5T480-200Zm0-300Zm0 220q113 0 207.5-59.5T832-500q-50-101-144.5-160.5T480-720q-113 0-207.5 59.5T128-500q50 101 144.5 160.5T480-280Z"/></svg>
</template>
<script>
export default {
props: {
isPasswordVisible: {
type: Boolean,
required: true
}
}
};
</script>
<svg
v-if="isPasswordVisible"
xmlns="http://www.w3.org/2000/svg"
height="16px"
viewBox="0 -960 960 960"
width="16px"
fill="#000000"
>
<path
d="m644-428-58-58q9-47-27-88t-93-32l-58-58q17-8 34.5-12t37.5-4q75 0 127.5 52.5T660-500q0 20-4 37.5T644-428Zm128 126-58-56q38-29 67.5-63.5T832-500q-50-101-143.5-160.5T480-720q-29 0-57 4t-55 12l-62-62q41-17 84-25.5t90-8.5q151 0 269 83.5T920-500q-23 59-60.5 109.5T772-302Zm20 246L624-222q-35 11-70.5 16.5T480-200q-151 0-269-83.5T40-500q21-53 53-98.5t73-81.5L56-792l56-56 736 736-56 56ZM222-624q-29 26-53 57t-41 67q50 101 143.5 160.5T480-280q20 0 39-2.5t39-5.5l-36-38q-11 3-21 4.5t-21 1.5q-75 0-127.5-52.5T300-500q0-11 1.5-21t4.5-21l-84-82Zm319 93Zm-151 75Z"
/>
</svg>
<svg
v-else
xmlns="http://www.w3.org/2000/svg"
height="16px"
viewBox="0 -960 960 960"
width="16px"
fill="#000000"
>
<path
d="M480-320q75 0 127.5-52.5T660-500q0-75-52.5-127.5T480-680q-75 0-127.5 52.5T300-500q0 75 52.5 127.5T480-320Zm0-72q-45 0-76.5-31.5T372-500q0-45 31.5-76.5T480-608q45 0 76.5 31.5T588-500q0 45-31.5 76.5T480-392Zm0 192q-146 0-266-81.5T40-500q54-137 174-218.5T480-800q146 0 266 81.5T920-500q-54 137-174 218.5T480-200Zm0-300Zm0 220q113 0 207.5-59.5T832-500q-50-101-144.5-160.5T480-720q-113 0-207.5 59.5T128-500q50 101 144.5 160.5T480-280Z"
/>
</svg>
</template>
<script>
export default {
props: {
isPasswordVisible: {
type: Boolean,
required: true,
},
},
}
</script>

View File

@ -1,29 +1,51 @@
<template>
<div class="hidden md:block">
<svg width="100%" height="100%" viewBox="0 0 870 350" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="customClip">
<path
d="M20 0.5H847.666C858.366 0.5 867.067 9.12193 867.165 19.8213L869.315 254.821C869.415 265.66 860.656 274.5 849.816 274.5H653C641.678 274.5 632.5 283.678 632.5 295V330C632.5 340.77 623.77 349.5 613 349.5H20C9.23045 349.5 0.5 340.77 0.5 330V20C0.5 9.23045 9.23045 0.5 20 0.5Z" />
</clipPath>
</defs>
<div class="hidden md:block">
<svg
width="100%"
height="100%"
viewBox="0 0 870 350"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<clipPath id="customClip">
<path
d="M20 0.5H847.666C858.366 0.5 867.067 9.12193 867.165 19.8213L869.315 254.821C869.415 265.66 860.656 274.5 849.816 274.5H653C641.678 274.5 632.5 283.678 632.5 295V330C632.5 340.77 623.77 349.5 613 349.5H20C9.23045 349.5 0.5 340.77 0.5 330V20C0.5 9.23045 9.23045 0.5 20 0.5Z"
/>
</clipPath>
</defs>
<image :href="src" clip-path="url(#customClip)" preserveAspectRatio="xMidYMid slice" width="100%"
height="100%" />
<image
:href="src"
clip-path="url(#customClip)"
preserveAspectRatio="xMidYMid slice"
width="100%"
height="100%"
/>
<foreignObject x="640" y="285" width="calc(100% - 640px - 1px)" height="calc(100% - 285px)">
<slot name="button" />
</foreignObject>
</svg>
</div>
<div class="block md:hidden">
<img :src="src" width="100%" height="100%" class="object-contain rounded-2xl my-4" />
<div class="flex justify-center">
<slot name="button" />
</div>
<foreignObject
x="640"
y="285"
width="calc(100% - 640px - 1px)"
height="calc(100% - 285px)"
>
<slot name="button" />
</foreignObject>
</svg>
</div>
<div class="block md:hidden">
<img
:src="src"
width="100%"
height="100%"
class="object-contain rounded-2xl my-4"
>
<div class="flex justify-center">
<slot name="button" />
</div>
</div>
</template>
<script lang="ts" setup>
defineProps<{ src: string }>()
</script>
</script>