Squashed commit message
Some checks failed
Telegram Mini App Shop Builder / Compute version metadata (push) Has been cancelled
Telegram Mini App Shop Builder / Run Frontend tests (push) Has been cancelled
Telegram Mini App Shop Builder / Run Backend tests (push) Has been cancelled
Telegram Mini App Shop Builder / Run PHP_CodeSniffer (push) Has been cancelled
Telegram Mini App Shop Builder / Build module. (push) Has been cancelled
Telegram Mini App Shop Builder / release (push) Has been cancelled
Some checks failed
Telegram Mini App Shop Builder / Compute version metadata (push) Has been cancelled
Telegram Mini App Shop Builder / Run Frontend tests (push) Has been cancelled
Telegram Mini App Shop Builder / Run Backend tests (push) Has been cancelled
Telegram Mini App Shop Builder / Run PHP_CodeSniffer (push) Has been cancelled
Telegram Mini App Shop Builder / Build module. (push) Has been cancelled
Telegram Mini App Shop Builder / release (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<p>
|
||||
<span class="text-xs font-medium">
|
||||
{{ option.name }}: {{ option.value }} <span v-if="option.price"> ({{ option.price_prefix }}<Price :value="option.price"/>)</span>
|
||||
</span>
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Price from "@/components/Price.vue";
|
||||
|
||||
const props = defineProps({
|
||||
option: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<p>
|
||||
<span class="text-xs font-medium">
|
||||
{{ option.name }}: {{ option.value }} <span v-if="option.price"> ({{ option.price_prefix }}<Price :value="option.price"/>)</span>
|
||||
</span>
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Price from "@/components/Price.vue";
|
||||
|
||||
const props = defineProps({
|
||||
option: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<p>
|
||||
<span class="text-xs font-medium">
|
||||
{{ option.name }}: {{ option.value }} <span v-if="option.price"> ({{ option.price_prefix }}<Price :value="option.price"/>)</span>
|
||||
</span>
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Price from "@/components/Price.vue";
|
||||
|
||||
const props = defineProps({
|
||||
option: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,31 @@
|
||||
<template>
|
||||
<div v-for="option in options" :key="option.product_option_id" class="mt-3">
|
||||
<component
|
||||
v-if="SUPPORTED_OPTION_TYPES.includes(option.type) && componentMap[option.type]"
|
||||
:is="componentMap[option.type]"
|
||||
:modelValue="option"
|
||||
/>
|
||||
<div v-else class="text-sm text-error">
|
||||
Тип опции "{{ option.type }}" не поддерживается.
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import OptionRadio from "./Types/OptionRadio.vue";
|
||||
import OptionCheckbox from "./Types/OptionCheckbox.vue";
|
||||
import OptionText from "./Types/OptionText.vue";
|
||||
import OptionTextarea from "./Types/OptionTextarea.vue";
|
||||
import OptionSelect from "./Types/OptionSelect.vue";
|
||||
import {SUPPORTED_OPTION_TYPES} from "@/constants/options.js";
|
||||
|
||||
const componentMap = {
|
||||
radio: OptionRadio,
|
||||
checkbox: OptionCheckbox,
|
||||
text: OptionText,
|
||||
textarea: OptionTextarea,
|
||||
select: OptionSelect,
|
||||
};
|
||||
|
||||
const options = defineModel();
|
||||
</script>
|
||||
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<div>
|
||||
<OptionTemplate :name="model.name" :required="model.required">
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<label
|
||||
v-for="value in model.product_option_value"
|
||||
class="group relative flex items-center justify-center btn btn-soft btn-secondary btn-sm"
|
||||
:class="value.selected ? 'btn-active' : ''"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
:value="value.product_option_value_id"
|
||||
:checked="value.selected"
|
||||
@change="select(value)"
|
||||
class="absolute inset-0 appearance-none focus:outline-none disabled:cursor-not-allowed"
|
||||
/>
|
||||
|
||||
<span class="text-xs font-medium group-has-checked:text-white">
|
||||
{{ value.name }}<span v-if="value.price"> ({{ value.price_prefix }}{{ value.price }})</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</OptionTemplate>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import OptionTemplate from "./OptionTemplate.vue";
|
||||
|
||||
const model = defineModel();
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
function select(toggledValue) {
|
||||
model.value.product_option_value.forEach(value => {
|
||||
if (value === toggledValue) {
|
||||
value.selected = !value.selected;
|
||||
}
|
||||
});
|
||||
|
||||
model.value.value = model.value.product_option_value.filter(item => item.selected === true);
|
||||
|
||||
emit('update:modelValue', model.value);
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<OptionTemplate :name="model.name" :required="model.required">
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<label
|
||||
v-for="value in model.product_option_value"
|
||||
class="group relative flex items-center justify-center btn btn-soft btn-secondary btn-sm"
|
||||
:class="value.selected ? 'btn-active' : ''"
|
||||
>
|
||||
|
||||
<input
|
||||
type="radio"
|
||||
:name="`option-${model.product_option_id}`"
|
||||
:value="value.product_option_value_id"
|
||||
:checked="value.selected"
|
||||
@change="select(value)"
|
||||
class="absolute inset-0 appearance-none focus:outline-none disabled:cursor-not-allowed"
|
||||
/>
|
||||
|
||||
<span class="text-xs font-medium">
|
||||
{{ value.name }}<span v-if="value.price"> ({{ value.price_prefix }}{{ value.price }})</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</OptionTemplate>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import OptionTemplate from "./OptionTemplate.vue";
|
||||
|
||||
const model = defineModel();
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
function select(selectedValue) {
|
||||
model.value.product_option_value.forEach(value => {
|
||||
value.selected = (value === selectedValue);
|
||||
});
|
||||
|
||||
model.value.value = selectedValue;
|
||||
|
||||
emit('update:modelValue', model);
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<OptionTemplate :name="model.name" :required="model.required">
|
||||
<select
|
||||
:name="`option-${model.product_option_id}`"
|
||||
class="select"
|
||||
@change="onChange"
|
||||
>
|
||||
<option value="" disabled selected>Выберите значение</option>
|
||||
<option
|
||||
v-for="value in model.product_option_value"
|
||||
:key="value.product_option_value_id"
|
||||
:value="value.product_option_value_id"
|
||||
:selected="value.selected"
|
||||
>
|
||||
{{ value.name }}<span v-if="value.price"> ({{ value.price_prefix }}{{ value.price }})</span>
|
||||
</option>
|
||||
</select>
|
||||
</OptionTemplate>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import OptionTemplate from "./OptionTemplate.vue";
|
||||
|
||||
const model = defineModel();
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
function onChange(event) {
|
||||
const selectedId = Number(event.target.value);
|
||||
|
||||
model.value.product_option_value.forEach(value => {
|
||||
value.selected = (value.product_option_value_id === selectedId);
|
||||
});
|
||||
|
||||
model.value.value = model.value.product_option_value.find(value => value.product_option_value_id === selectedId);
|
||||
|
||||
emit('update:modelValue', model.value);
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="text-sm mb-2">
|
||||
{{ name }} <span v-if="required" class="text-error">*</span>
|
||||
</h3>
|
||||
|
||||
<fieldset>
|
||||
<slot></slot>
|
||||
</fieldset>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<OptionTemplate :name="model.name" :required="model.required">
|
||||
<input
|
||||
type="text"
|
||||
class="input"
|
||||
:placeholder="model.name"
|
||||
:value="model.value"
|
||||
@input="input(model, $event.target.value)"
|
||||
/>
|
||||
</OptionTemplate>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import OptionTemplate from "./OptionTemplate.vue";
|
||||
|
||||
const model = defineModel();
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
function input(model, newValue) {
|
||||
model.value = newValue;
|
||||
emit('update:modelValue', model);
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<OptionTemplate :name="model.name" :required="model.required">
|
||||
<textarea
|
||||
type="text"
|
||||
class="textarea"
|
||||
:placeholder="model.name"
|
||||
v-text="model.value"
|
||||
@input="input(model, $event.target.value)"
|
||||
/>
|
||||
</OptionTemplate>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import OptionTemplate from "./OptionTemplate.vue";
|
||||
|
||||
const model = defineModel();
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
function input(model, newValue) {
|
||||
model.value = newValue;
|
||||
emit('update:modelValue', model);
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user