Tighten catalog product detail layout
This commit is contained in:
@@ -484,28 +484,28 @@ function fieldHelperText(group: ProductGroup, field: ParamFieldKey) {
|
|||||||
const setting = groupCatalogSetting(group);
|
const setting = groupCatalogSetting(group);
|
||||||
|
|
||||||
if (field === 'widthMm') {
|
if (field === 'widthMm') {
|
||||||
return 'Ширина рулона.';
|
return 'Ширина рулона в миллиметрах.';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field === 'lengthM') {
|
if (field === 'lengthM') {
|
||||||
const customRange = formatLengthRange(setting);
|
const customRange = formatLengthRange(setting);
|
||||||
if (setting.allowCustomLength && customRange) {
|
if (setting.allowCustomLength && customRange) {
|
||||||
return `Стандартная длина или своя: ${customRange}.`;
|
return `Можно выбрать стандартный метраж или заказать свой: ${customRange}.`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'Длина рулона в метрах.';
|
return 'Стандартный метраж рулона.';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field === 'thicknessMicron') {
|
if (field === 'thicknessMicron') {
|
||||||
return 'Толщина материала.';
|
return 'Толщина материала в микронах.';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field === 'sleeveBrand') {
|
if (field === 'sleeveBrand') {
|
||||||
if (setting.allowCustomSleeveBrand) {
|
if (setting.allowCustomSleeveBrand) {
|
||||||
return 'Можно выбрать стандартную втулку или сделать с логотипом.';
|
return 'Можно выбрать стандартную втулку или сделать свою с логотипом.';
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'Тип втулки внутри рулона.';
|
return 'Стандартный вариант втулки.';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field === 'colorTag') {
|
if (field === 'colorTag') {
|
||||||
@@ -543,19 +543,6 @@ function customizationDetails(group: ProductGroup) {
|
|||||||
return details;
|
return details;
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectedSummary(group: ProductGroup) {
|
|
||||||
return visibleFields(group)
|
|
||||||
.map((field) => {
|
|
||||||
const value = getGroupState(group)[field.key];
|
|
||||||
if (value === null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `${field.label}: ${formatOptionLabel(field.key, value)}`;
|
|
||||||
})
|
|
||||||
.filter((item): item is string => Boolean(item));
|
|
||||||
}
|
|
||||||
|
|
||||||
function productBadges(product: ParsedProduct) {
|
function productBadges(product: ParsedProduct) {
|
||||||
const badges: string[] = [];
|
const badges: string[] = [];
|
||||||
|
|
||||||
@@ -631,7 +618,7 @@ function productDetailPath(group: ProductGroup) {
|
|||||||
<NuxtLink
|
<NuxtLink
|
||||||
v-if="previousGroup"
|
v-if="previousGroup"
|
||||||
:to="productDetailPath(previousGroup)"
|
:to="productDetailPath(previousGroup)"
|
||||||
class="absolute left-0 top-28 z-10 hidden w-44 -translate-x-[72%] rounded-[28px] border border-[#e6efe9] bg-white p-3 shadow-[0_20px_40px_rgba(18,56,36,0.08)] transition hover:-translate-x-[76%] hover:shadow-[0_28px_48px_rgba(18,56,36,0.12)] 2xl:block"
|
class="absolute left-0 top-28 z-10 hidden w-44 -translate-x-[92%] rounded-[28px] border border-[#e6efe9] bg-white p-3 shadow-[0_20px_40px_rgba(18,56,36,0.08)] transition hover:-translate-x-[98%] hover:shadow-[0_28px_48px_rgba(18,56,36,0.12)] 2xl:block"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="createProductCover(previousGroup.typeLabel, previousGroup.key)"
|
:src="createProductCover(previousGroup.typeLabel, previousGroup.key)"
|
||||||
@@ -645,7 +632,7 @@ function productDetailPath(group: ProductGroup) {
|
|||||||
<NuxtLink
|
<NuxtLink
|
||||||
v-if="nextGroup"
|
v-if="nextGroup"
|
||||||
:to="productDetailPath(nextGroup)"
|
:to="productDetailPath(nextGroup)"
|
||||||
class="absolute right-0 top-28 z-10 hidden w-44 translate-x-[72%] rounded-[28px] border border-[#e6efe9] bg-white p-3 shadow-[0_20px_40px_rgba(18,56,36,0.08)] transition hover:translate-x-[76%] hover:shadow-[0_28px_48px_rgba(18,56,36,0.12)] 2xl:block"
|
class="absolute right-0 top-28 z-10 hidden w-44 translate-x-[92%] rounded-[28px] border border-[#e6efe9] bg-white p-3 shadow-[0_20px_40px_rgba(18,56,36,0.08)] transition hover:translate-x-[98%] hover:shadow-[0_28px_48px_rgba(18,56,36,0.12)] 2xl:block"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="createProductCover(nextGroup.typeLabel, nextGroup.key)"
|
:src="createProductCover(nextGroup.typeLabel, nextGroup.key)"
|
||||||
@@ -701,7 +688,7 @@ function productDetailPath(group: ProductGroup) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid gap-5 px-3 sm:px-6 xl:grid-cols-[minmax(0,0.92fr)_minmax(0,1.15fr)_320px] xl:px-8">
|
<div class="grid gap-5 px-3 sm:px-6 xl:grid-cols-[minmax(0,0.92fr)_minmax(0,1.15fr)_320px] xl:px-8">
|
||||||
<div class="space-y-4">
|
<div class="space-y-3">
|
||||||
<div class="overflow-hidden rounded-[32px] border border-[#e6efe9] bg-white p-4 shadow-[0_20px_40px_rgba(18,56,36,0.06)]">
|
<div class="overflow-hidden rounded-[32px] border border-[#e6efe9] bg-white p-4 shadow-[0_20px_40px_rgba(18,56,36,0.06)]">
|
||||||
<img
|
<img
|
||||||
:src="createProductCover(selectedGroup.typeLabel, articleLabel(selectedGroup))"
|
:src="createProductCover(selectedGroup.typeLabel, articleLabel(selectedGroup))"
|
||||||
@@ -711,21 +698,6 @@ function productDetailPath(group: ProductGroup) {
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
|
||||||
v-if="selectedSummary(selectedGroup).length"
|
|
||||||
class="rounded-[28px] border border-[#e6efe9] bg-white p-4 shadow-[0_18px_36px_rgba(18,56,36,0.05)]"
|
|
||||||
>
|
|
||||||
<div class="flex flex-wrap gap-2">
|
|
||||||
<span
|
|
||||||
v-for="item in selectedSummary(selectedGroup)"
|
|
||||||
:key="`${selectedGroup.key}-${item}`"
|
|
||||||
class="rounded-full border border-[#dce9e1] bg-[#f8fbf9] px-3 py-1.5 text-sm font-medium text-[#355947]"
|
|
||||||
>
|
|
||||||
{{ item }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="customizationDetails(selectedGroup).length"
|
v-if="customizationDetails(selectedGroup).length"
|
||||||
class="rounded-[28px] border border-[#dce9e1] bg-[#f7fbf8] p-4"
|
class="rounded-[28px] border border-[#dce9e1] bg-[#f7fbf8] p-4"
|
||||||
@@ -746,11 +718,9 @@ function productDetailPath(group: ProductGroup) {
|
|||||||
<article
|
<article
|
||||||
v-for="field in visibleFields(selectedGroup)"
|
v-for="field in visibleFields(selectedGroup)"
|
||||||
:key="`${selectedGroup.key}-${field.key}`"
|
:key="`${selectedGroup.key}-${field.key}`"
|
||||||
class="rounded-[28px] border border-[#e6efe9] bg-white p-5 shadow-[0_18px_36px_rgba(18,56,36,0.05)]"
|
class="rounded-[28px] border border-[#e6efe9] bg-white p-4 shadow-[0_18px_36px_rgba(18,56,36,0.05)]"
|
||||||
>
|
>
|
||||||
<p class="text-base font-semibold text-[#163624]">{{ field.label }}</p>
|
<div class="flex flex-wrap gap-2">
|
||||||
|
|
||||||
<div class="mt-3 flex flex-wrap gap-2">
|
|
||||||
<label
|
<label
|
||||||
v-for="option in getAllFieldOptions(selectedGroup, field.key)"
|
v-for="option in getAllFieldOptions(selectedGroup, field.key)"
|
||||||
:key="`${selectedGroup.key}-${field.key}-${option}`"
|
:key="`${selectedGroup.key}-${field.key}-${option}`"
|
||||||
@@ -774,33 +744,17 @@ function productDetailPath(group: ProductGroup) {
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="mt-3 text-sm leading-6 text-[#607569]">{{ fieldHelperText(selectedGroup, field.key) }}</p>
|
<p class="mt-2 text-sm leading-6 text-[#607569]">{{ fieldHelperText(selectedGroup, field.key) }}</p>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<aside class="self-start xl:sticky xl:top-24">
|
<aside class="self-start xl:sticky xl:top-24">
|
||||||
<div class="rounded-[30px] border border-[#e6efe9] bg-white p-5 shadow-[0_24px_48px_rgba(18,56,36,0.08)]">
|
<div class="rounded-[30px] border border-[#e6efe9] bg-white p-5 shadow-[0_24px_48px_rgba(18,56,36,0.08)]">
|
||||||
<p class="text-xs font-semibold uppercase tracking-[0.18em] text-[#789182]">Артикул</p>
|
|
||||||
<p class="mt-2 text-2xl font-bold leading-tight text-[#163624]">{{ articleLabel(selectedGroup) }}</p>
|
<p class="mt-2 text-2xl font-bold leading-tight text-[#163624]">{{ articleLabel(selectedGroup) }}</p>
|
||||||
|
|
||||||
<div
|
|
||||||
v-if="selectedSummary(selectedGroup).length"
|
|
||||||
class="mt-5 rounded-[24px] border border-[#edf4ef] bg-[#f8fbf9] p-4"
|
|
||||||
>
|
|
||||||
<div class="flex flex-wrap gap-2">
|
|
||||||
<span
|
|
||||||
v-for="item in selectedSummary(selectedGroup)"
|
|
||||||
:key="`${selectedGroup.key}-summary-${item}`"
|
|
||||||
class="rounded-full bg-white px-3 py-1.5 text-xs font-semibold text-[#355947]"
|
|
||||||
>
|
|
||||||
{{ item }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button
|
<button
|
||||||
v-if="selectedQty(selectedGroup) === 0"
|
v-if="selectedQty(selectedGroup) === 0"
|
||||||
class="btn mt-5 h-12 w-full rounded-full border-0 bg-[#139957] px-6 text-base font-semibold text-white hover:bg-[#0d854a]"
|
class="btn mt-4 h-12 w-full rounded-full border-0 bg-[#139957] px-6 text-base font-semibold text-white hover:bg-[#0d854a]"
|
||||||
:disabled="!selectedProduct(selectedGroup)"
|
:disabled="!selectedProduct(selectedGroup)"
|
||||||
@click="incrementSelected(selectedGroup)"
|
@click="incrementSelected(selectedGroup)"
|
||||||
>
|
>
|
||||||
@@ -809,7 +763,7 @@ function productDetailPath(group: ProductGroup) {
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
class="mt-5 flex items-center justify-between rounded-[24px] border border-[#dce9e1] bg-[#f8fbf9] px-2 py-2"
|
class="mt-4 flex items-center justify-between rounded-[24px] border border-[#dce9e1] bg-[#f8fbf9] px-2 py-2"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="btn btn-square border-0 bg-white text-[#163624] shadow-none hover:bg-white"
|
class="btn btn-square border-0 bg-white text-[#163624] shadow-none hover:bg-white"
|
||||||
|
|||||||
Reference in New Issue
Block a user