Fixes: 1) Replace `ElNotification` calls with `useNotification` utility across all authentication and user-related composables; 2) Add missing semicolons in multiple index exports and styled components; 3) Resolve issues with reactivity in `useStore` composable by renaming and restructuring product variables; Extra: 1) Refactor localized strings and translations for better readability and maintenance; 2) Tweak styles including scoped styles, z-index adjustments, and SCSS mixins; 3) Remove unused components and imports to streamline storefront layout.
93 lines
No EOL
1.7 KiB
Vue
93 lines
No EOL
1.7 KiB
Vue
<template>
|
|
<div class="block">
|
|
<textarea
|
|
:placeholder="placeholder"
|
|
:value="modelValue"
|
|
@input="onInput"
|
|
class="block__textarea"
|
|
/>
|
|
<p v-if="!isValid" class="block__error">{{ errorMessage }}</p>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
type Rule = (value: string) => boolean | string;
|
|
|
|
const emit = defineEmits<{
|
|
(e: 'update:modelValue', value: string | number): void;
|
|
}>();
|
|
const props = defineProps<{
|
|
placeholder: string,
|
|
modelValue?: string,
|
|
rules?: Rule[]
|
|
}>();
|
|
|
|
const isValid = ref(true);
|
|
const errorMessage = ref('');
|
|
|
|
const onInput = (e: Event) => {
|
|
const target = e.target as HTMLTextAreaElement;
|
|
const value = target.value;
|
|
|
|
isValid.value = true;
|
|
errorMessage.value = '';
|
|
|
|
props.rules?.forEach(rule => {
|
|
const result = rule(value);
|
|
if (result !== true) {
|
|
isValid.value = false;
|
|
errorMessage.value = String(result);
|
|
}
|
|
});
|
|
|
|
emit('update:modelValue', value);
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.block {
|
|
width: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
gap: 10px;
|
|
position: relative;
|
|
|
|
&__textarea {
|
|
width: 100%;
|
|
height: 150px;
|
|
resize: none;
|
|
padding: 6px 12px;
|
|
border: 1px solid #e0e0e0;
|
|
border-radius: $default_border_radius;
|
|
background-color: $white;
|
|
|
|
color: #1f1f1f;
|
|
font-size: 12px;
|
|
font-weight: 400;
|
|
line-height: 20px;
|
|
|
|
&::placeholder {
|
|
color: #2B2B2B;
|
|
}
|
|
}
|
|
|
|
&__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> |