Fixes: 1) Refactor `useProducts` and `useCategorybySlug` composables for improved error handling and lazy loading; 2) Correct import path in `product-page.vue` for `useProductBySlug`; 3) Update `useLanguages` composable to set current locale from local storage; 4) Remove unused `auth.js`, `base-header.vue`, and deprecated GraphQL fragments; Extra: Minor styling adjustments and removal of redundant console logs; Updated `package-lock.json` dependencies for version consistency.
148 lines
No EOL
3 KiB
Vue
148 lines
No EOL
3 KiB
Vue
<template>
|
|
<div class="block">
|
|
<div class="block__inner">
|
|
<input
|
|
:placeholder="placeholder"
|
|
:type="isPasswordVisible"
|
|
:value="modelValue"
|
|
@input="onInput"
|
|
@keydown="numberOnly ? onlyNumbersKeydown($event) : null"
|
|
class="block__input"
|
|
>
|
|
<button
|
|
@click.prevent="setPasswordVisible"
|
|
class="block__eyes"
|
|
v-if="type === 'password' && modelValue"
|
|
>
|
|
<i v-if="isPasswordVisible === 'password'" class="pi pi-eye-slash"></i>
|
|
<i v-else class="pi pi-eye"></i>
|
|
</button>
|
|
</div>
|
|
<p v-if="!validate" class="block__error">{{ errorMessage }}</p>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import {ref} from "vue";
|
|
|
|
const $emit = defineEmits()
|
|
const props = defineProps({
|
|
type: String,
|
|
placeholder: String,
|
|
isError: Boolean,
|
|
error: String,
|
|
modelValue: [String, Number],
|
|
rules: Array,
|
|
numberOnly: Boolean
|
|
})
|
|
|
|
const isPasswordVisible = ref(props.type)
|
|
const setPasswordVisible = () => {
|
|
if (isPasswordVisible.value === 'password') {
|
|
isPasswordVisible.value = 'text'
|
|
return
|
|
}
|
|
isPasswordVisible.value = 'password'
|
|
}
|
|
|
|
const onlyNumbersKeydown = (event) => {
|
|
if (!/^\d$/.test(event.key) &&
|
|
!['ArrowLeft', 'ArrowRight', 'Backspace', 'Delete', 'Tab', 'Home', 'End'].includes(event.key)) {
|
|
event.preventDefault();
|
|
}
|
|
}
|
|
|
|
const validate = ref(true)
|
|
const errorMessage = ref('')
|
|
const onInput = (e) => {
|
|
let value = e.target.value;
|
|
|
|
if (props.numberOnly) {
|
|
const newValue = value.replace(/\D/g, '');
|
|
if (newValue !== value) {
|
|
e.target.value = newValue;
|
|
value = newValue;
|
|
}
|
|
}
|
|
|
|
let result = true
|
|
|
|
props.rules?.forEach((rule) => {
|
|
result = rule((e.target).value)
|
|
|
|
if (result !== true) {
|
|
errorMessage.value = String(result)
|
|
result = false
|
|
}
|
|
})
|
|
|
|
validate.value = result
|
|
|
|
return $emit('update:modelValue', (e.target).value)
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.block {
|
|
width: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
gap: 10px;
|
|
position: relative;
|
|
|
|
&__inner {
|
|
width: 100%;
|
|
position: relative;
|
|
}
|
|
|
|
&__input {
|
|
width: 100%;
|
|
padding: 6px 12px;
|
|
border: 1px solid #e0e0e0;
|
|
//border: 1px solid #b2b2b2;
|
|
border-radius: $default_border_radius;
|
|
background-color: $white;
|
|
|
|
color: #1f1f1f;
|
|
font-size: 12px;
|
|
font-weight: 400;
|
|
line-height: 20px;
|
|
|
|
&::placeholder {
|
|
color: #2B2B2B;
|
|
}
|
|
}
|
|
|
|
&__eyes {
|
|
cursor: pointer;
|
|
position: absolute;
|
|
right: 20px;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
background-color: transparent;
|
|
display: grid;
|
|
place-items: center;
|
|
font-size: 18px;
|
|
color: #838383;
|
|
}
|
|
|
|
&__error {
|
|
color: $error;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
animation: fadeInUp 0.3s ease;
|
|
|
|
@keyframes fadeInUp {
|
|
0% {
|
|
opacity: 0;
|
|
transform: translateY(-50%);
|
|
}
|
|
100% {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style> |