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

This commit is contained in:
2026-03-11 22:08:41 +03:00
commit f329bfa9d9
585 changed files with 65605 additions and 0 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>