Wygląd sklepu

Standardowe szablony Comarch

Instrukcja: Jak dostosować samodzielnie szablon do szybkich zwrotów w e-Commerce?

Wskazówka
Wskazówka: W tym artykule trzeba będzie wprowadzać zmiany w plikach js oraz scss. Z tego artykułu dowiesz się jak je kompilować i minifikować.
W szablonach Rubin, Szafir oraz Topaz / One Page Shop wprowadziliśmy funkcję szybkich zwrotów. Umożliwia ona klientom składanie wniosku o zwrot produktu zarówno z poziomu profilu klienta (zalogowani), jak i z dedykowanej strony zwrotów po podaniu numeru zamówienia oraz adresu e-mail (niezalogowani). Wraz z funkcjonalnością pojawił się m.in. rozbudowany ekran potwierdzenia zwrotu zawierający kolejne kroki i adres do wysyłki, banery informacyjne dotyczące terminu zwrotu oraz przyciski akcji w tabeli produktów wyświetlane bezpośrednio (zamiast w rozwijanym menu). Aby Twój szablon poprawnie obsługiwał te zmiany, wprowadź modyfikacje opisane poniżej w sekcji dotyczącej Twojego szablonu. Po zakończeniu edycji pamiętaj o kompilacji i minifikacji plików js oraz scss.
Wskazówka
Potrzebujesz pomocy lub masz pytania? Skontaktuj się z nami poprzez portal asysta.comarch.pl.
Wskazówka
Obecnie w Polsce trwają prace nad ostatecznym kształtem przepisów oraz nowelizacją Ustawy o prawach konsumenta, która wdroży unijną dyrektywę UE 2023/2673 i wprowadzi nowe wymagania techniczne dla platform e-commerce (m.in. ułatwienia w procedurze zwrotów). W momencie publikacji ostatecznej wersji polskich przepisów, wdrożone funkcjonalności mogą wymagać dostosowania do ostatecznych wytycznych ustawodawcy. Prezentowane informacje mają charakter poglądowy a instrukcja dotyczy zmian, jakie wprowadziliśmy w szablonach Comarch – w przypadku pytań dotyczących indywidualnej sytuacji prawnej Twojego sklepu, zalecamy konsultację z radcą prawnym lub adwokatem.

Szablon Rubin

1. Tłumaczenia

W panelu administracyjnym sklepu zaktualizuj dwa istniejące tłumaczenia oraz dodaj nowe klucze wymagane przez funkcjonalność szybkich zwrotów. Zaktualizuj poniższe istniejące tłumaczenia: ReturnSuccessTitle - PL: Gotowe! Przyjęliśmy Twoje zgłoszenie - EN: Done! We have received your request - DE: Fertig! Wir haben Ihre Anfrage erhalten - FR: C'est fait ! Nous avons reçu votre demande ReturnSuccessInfo - PL: Przygotuj paczkę i odeślij ją do nas – wszystkie szczegóły znajdziesz poniżej. - EN: Prepare the package and send it back to us – all the details are below. - DE: Bereiten Sie das Paket vor und senden Sie es an uns zurück – alle Details finden Sie unten. - FR: Préparez le colis et renvoyez-le nous – tous les détails sont ci-dessous. Dodaj nowe tłumaczenia: OrderReturnDeadlineInfo - PL: Zamówienie można zwrócić w ciągu {0} dni od daty dostawy. - EN: You can return the order within {0} days from the delivery date. - DE: Sie können die Bestellung innerhalb von {0} Tagen ab Lieferdatum zurückgeben. - FR: Vous pouvez retourner la commande dans les {0} jours suivant la date de livraison. RestrictedOrderViewInfo - PL: Wybrane dane zamówienia zostały ukryte ze względów bezpieczeństwa. Możesz zwrócić produkty bez logowania. - EN: Some order details are hidden for security reasons. You can return products without signing in. - DE: Einige Bestelldetails wurden aus Sicherheitsgründen ausgeblendet. Sie können Produkte ohne Anmeldung zurücksenden. - FR: Certaines informations de la commande ont été masquées pour des raisons de sécurité. Vous pouvez retourner des produits sans vous connecter. Com_RefundMethod - PL: Sposób zwrotu środków - EN: Refund method - DE: Rückerstattungsmethode - FR: Mode de remboursement Com_RefundAsPaid - PL: Tak jak zapłacono - EN: Same as paid - DE: Wie bezahlt - FR: Comme payé Com_RefundToBankAccount - PL: Na konto bankowe - EN: To bank account - DE: Auf Bankkonto - FR: Sur le compte bancaire Com_BankAccountNumber - PL: Nr konta bankowego - EN: Bank account number - DE: Bankkontonummer - FR: Numéro de compte bancaire Com_ConfirmationSentTo - PL: Potwierdzenie zwrotu zostało wysłane na adres: - EN: Return confirmation has been sent to: - DE: Bestätigung wurde gesendet an: - FR: La confirmation de retour a été envoyée à: Com_NextSteps - PL: Następne kroki - EN: Next Steps - DE: Nächste Schritte - FR: Prochaines étapes Com_PackProducts - PL: Bezpiecznie zapakuj swoje produkty - EN: Safely pack your products - DE: Verpacken Sie Ihre Produkte sicher - FR: Emballez vos produits en toute sécurité Com_SendPackageTo - PL: Wyślij paczkę na adres: - EN: Send the package to the address: - DE: Senden Sie das Paket an die Adresse: - FR: Envoyez le colis à l'adresse: Com_RefundAfterReceive - PL: Pieniądze zwrócimy niezwłocznie po otrzymaniu i sprawdzeniu Twojej paczki - EN: We will refund the money promptly upon receipt and inspection of your package - DE: Wir erstatten das Geld umgehend nach Erhalt und Überprüfung Ihres Pakets zurück - FR: Nous rembourserons l'argent rapidement après réception et inspection de votre colis ReturnInThreeSteps - PL: Zwróć towar w 3 krokach - EN: Return the product in 3 steps - DE: Geben Sie die Ware in 3 Schritten zurück - FR: Retournez la marchandise en 3 étapes ReturnWithoutReasonInfo - PL: Przysługuje Ci możliwość zwrotu bez podania przyczyny. - EN: You have the right to return the product without giving a reason. - DE: Sie haben das Recht, die Ware ohne Angabe von Gründen zurückzugeben. - FR: Vous avez le droit de retourner la marchandise sans donner de motif. OrEnterOrderNumber - PL: lub podaj numer zamówienia - EN: or enter the order number - DE: oder geben Sie die Bestellnummer ein - FR: ou saisissez le numéro de commande FillForm - PL: Wypełnij formularz - EN: Fill out the form - DE: Füllen Sie das Formular aus - FR: Remplissez le formulaire ReturnOnline - PL: zwrotu online - EN: online return - DE: Online-Rückgabe - FR: retour en ligne SendParcel - PL: Wyślij paczkę - EN: Send the parcel - DE: Paket senden - FR: Envoyer le colis SendParcelToOurAddress - PL: nadaj przesyłkę na nasz adres - EN: send the parcel to our address - DE: senden Sie das Paket an unsere Adresse - FR: envoyez le colis à notre adresse FastSimpleSecure - PL: Szybko, prosto i bezpiecznie. - EN: Fast, simple and secure. - DE: Schnell, einfach und sicher. - FR: Rapide, simple et sécurisé. ReadyForReturn - PL: Gotowy do zwrotu? - EN: Ready for return? - DE: Bereit zur Rückgabe? - FR: Prêt pour le retour ? ReadyForReturnInfo - PL: Kliknij poniżej, aby rozpocząć proces zwrotu. Przeprowadzimy Cię przez wszystkie kroki. - EN: Click below to start the return process. We will guide you through all the steps. - DE: Klicken Sie unten, um den Rückgabeprozess zu starten. Wir führen Sie durch alle Schritte. - FR: Cliquez ci-dessous pour lancer le processus de retour. Nous vous guiderons à travers toutes les étapes. StartReturn - PL: Rozpocznij zwrot - EN: Start return - DE: Rückgabe starten - FR: Commencer le retour ProductReturn - PL: Zwrot produktu - EN: Product return - DE: Produktrückgabe - FR: Retour du produit ProductReturnFormInfo - PL: Wprowadź dane zamówienia, aby zlokalizować zakup i rozpocząć proces zwrotu. Numer zamówienia znajdziesz w e-mailu z potwierdzeniem. - EN: Enter the order details to locate the purchase and start the return process. You will find the order number in the confirmation e-mail. - DE: Geben Sie die Bestelldaten ein, um den Kauf zu lokalisieren und den Rückgabeprozess zu starten. Die Bestellnummer finden Sie in der Bestätigungs-E-Mail. - FR: Saisissez les données de la commande pour localiser l'achat et démarrer le processus de retour. Vous trouverez le numéro de commande dans l'e-mail de confirmation. InvalidOrderNumber - PL: Błędny numer zamówienia. Spróbuj ponownie. - EN: Invalid order number. Please try again. - DE: Ungültige Bestellnummer. Bitte versuchen Sie es erneut. - FR: Numéro de commande incorrect. Veuillez réessayer. FindOrder - PL: Znajdź zamówienie - EN: Find order - DE: Bestellung finden - FR: Trouver la commande LoginToSeeOrdersAndReturn - PL: aby zobaczyć swoje zamówienia i dokonać zwrotu. - EN: to see your orders and make a return. - DE: um Ihre Bestellungen einzusehen und eine Rückgabe vorzunehmen. - FR: pour voir vos commandes et effectuer un retour. RefundLookupError - PL: Wystąpił błąd podczas wyszukiwania zamówienia. Spróbuj ponownie później. - EN: An error occurred while searching for the order. Please try again later. - DE: Bei der Suche nach der Bestellung ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut. - FR: Une erreur s'est produite lors de la recherche de la commande. Veuillez réessayer plus tard.

2. Nowa strona Szybkie zwroty

Funkcjonalność szybkich zwrotów wymaga utworzenia dodatkowej strony statycznej refunds. Wykonaj poniższe kroki.

Plik refunds.html w katalogu głównym szablonu

W katalogu głównym szablonu utwórz nowy plik refunds.html z następującą zawartością:
{% extends '_layout.html' -%}

{% block pageContent -%}
{% include 'static-elements/refunds/refunds.html' -%}
{% endblock -%}

Plik static-elements/refunds/refunds.html

W folderze static-elements utwórz nowy katalog refunds, a w nim plik refunds.html:
<div class="page-padding">
    <h1 class="refunds-page-title refunds-initial-view-js">{{ translations.Returns }}</h1>
    <section class="refunds-container refunds-initial-view-js">
        <div class="refunds-info">
            <h2 class="refunds-info__title">{{ translations.ReturnInThreeSteps }}</h2>
            <p class="refunds-info__intro">{{ translations.ReturnWithoutReasonInfo }}</p>
            <ol class="refunds-steps">
                <li class="refunds-steps__item">
                    <span class="refunds-steps__number">1</span>
                    <p class="refunds-steps__text"><strong>{{ translations.LogIn }}</strong> {{ translations.OrEnterOrderNumber }}</p>
                </li>
                <li class="refunds-steps__item">
                    <span class="refunds-steps__number">2</span>
                    <p class="refunds-steps__text"><strong>{{ translations.FillForm }}</strong> {{ translations.ReturnOnline }}</p>
                </li>
                <li class="refunds-steps__item">
                    <span class="refunds-steps__number">3</span>
                    <p class="refunds-steps__text"><strong>{{ translations.SendParcel }}</strong> - {{ translations.SendParcelToOurAddress }}</p>
                </li>
            </ol>
            <p class="refunds-info__hint">{{ translations.FastSimpleSecure }}</p>
        </div>
        <div class="refunds-cta">
            <div class="refunds-cta__header">
                <h3 class="refunds-cta__title">{{ translations.ReadyForReturn }}</h3>
                <p class="refunds-cta__description">{{ translations.ReadyForReturnInfo }}</p>
            </div>
            {% if usr.Authenticated -%}
            <a class="primary-action-button refunds-cta__button" href="{{ config.DefinedPages.CustomerProfile.Url }}?tab=orders" rel="nofollow" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </a>
            {% else -%}
            <button class="primary-action-button refunds-cta__button start-refund-js" type="button" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </button>
            {% endif -%}
        </div>
    </section>
    {% unless usr.Authenticated -%}
    <section class="refund-form-section refund-form-view-js hidden-js">
        <div class="refund-form">
            <div class="refund-form__header">
                <h2 class="refund-form__title">{{ translations.ProductReturn }}</h2>
                <p class="refund-form__description">{{ translations.ProductReturnFormInfo }}</p>
            </div>
            <form class="refund-form__body refund-form-js" novalidate="" data-error="{{ translations.RefundLookupError }}">
                <div class="form__input-wrapper">
                    <label class="form__input-info input-info-js" for="refundOrderNumber">{{ translations.NumberOfOrder }}</label>
                    <input id="refundOrderNumber" class="form__input-value input-value-js" maxlength="50" name="orderNumber" required="" type="text" />
                    <div class="form__invalid-input validation-info-js validation-required-js hidden-js">{{ translations.FieldRequired }}</div>
                </div>
                <div class="form__input-wrapper">
                    <label class="form__input-info input-info-js" for="refundEmail" data-type="email">{{ translations.EmailAddress }}</label>
                    <input id="refundEmail" class="form__input-value input-value-js" autocomplete="email" maxlength="192" name="email" required="" type="email" />
                    <div class="form__invalid-input validation-info-js validation-required-js hidden-js">{{ translations.FieldRequired }}</div>
                    <div class="form__invalid-input validation-info-js email-valid-js hidden-js">{{ translations.FillProperEmail }}</div>
                </div>
                <button class="primary-action-button refund-form__submit refund-form-submit-js" type="button">
                    {{ translations.FindOrder }}
                </button>
                <p class="refund-form__login-info">{{ translations.HaveAccount }} <a class="refund-form__login-link show-login-popup-js" tabindex="0" role="button" rel="nofollow">{{ translations.LogIn }},</a> {{ translations.LoginToSeeOrdersAndReturn }}</p>
            </form>
        </div>
    </section>
    {% endunless -%}
</div>

Plik js/layout1.js – kod obsługi formularza zwrotu

Na końcu pliku js/layout1.js dodaj poniższy kod odpowiedzialny za walidację i wysłanie formularza wyszukiwania zamówienia (dla niezalogowanego klienta):
$(document).ready(function() {
    refunds.init();
})

const refunds = {
    init: function() {
        this.events();
    },

    findRefundOrder: function(orderNumber, email) {
        return $.post('', {
            __action: 'Order/QuickReturnLookup',
            orderId: orderNumber,
            email: email,
            __csrf: __CSRF
        });
    },

    showForm: function() {
        $('.refunds-initial-view-js').addClass('hidden-js');
        $('.refund-form-view-js').removeClass('hidden-js');
        $('.refund-form-js input[name="orderNumber"]').trigger('focus');
    },

    clearFieldError: function(input) {
        const $input = $(input);
        $input.removeClass('validation-error-js');
        $input.closest('.form__input-wrapper').find('.form__invalid-input').addClass('hidden-js');
    },

    submitForm: async function(button) {
        const $submit = $(button);
        const $form = $submit.closest('.refund-form-js');
        const $orderInput = $form.find('input[name="orderNumber"]');
        const $emailInput = $form.find('input[name="email"]');
        const orderValue = $orderInput.val().trim();
        const emailValue = $emailInput.val().trim();
        const emailRegex = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w{2,}$/;
        let hasError = false;

        $form.find('.form__invalid-input').addClass('hidden-js');
        $form.find('.form__input-value').removeClass('validation-error-js');

        if (orderValue.length === 0) {
            $orderInput.addClass('validation-error-js');
            $orderInput.closest('.form__input-wrapper').find('.validation-required-js').removeClass('hidden-js');
            hasError = true;
        }

        if (emailValue.length === 0) {
            $emailInput.addClass('validation-error-js');
            $emailInput.closest('.form__input-wrapper').find('.validation-required-js').removeClass('hidden-js');
            hasError = true;
        } else if (!emailRegex.test(emailValue)) {
            $emailInput.addClass('validation-error-js');
            $emailInput.closest('.form__input-wrapper').find('.email-valid-js').removeClass('hidden-js');
            hasError = true;
        }

        if (hasError) {
            return;
        }

        $submit.prop('disabled', true);

        try {
            const result = await refunds.findRefundOrder(orderValue, emailValue);
            const action = result.action;
            if (action.Redirect302) {
                globalThis.location.href = action.Redirect302;
                return;
            }
            app.temporaryPopupMessage(undefined, action.Message, action.Type);
        } catch (error) {
            console.error('Refund order lookup failed.', error);
            app.temporaryPopupMessage(undefined, $form.data('error'), 'err');
        } finally {
            $submit.prop('disabled', false);
        }
    },

    events: function() {
        $('body').on('click', '.start-refund-js', function() {
            refunds.showForm();
        });

        $('body').on('input', '.refund-form-js .form__input-value', function() {
            refunds.clearFieldError(this);
        });

        $('body').on('click', '.refund-form-submit-js', function(e) {
            e.preventDefault();
            refunds.submitForm(this);
        });

        $('body').on('keydown', '.refund-form-js input', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
                $(this).closest('.refund-form-js').find('.refund-form-submit-js').trigger('click');
            }
        });
    }
};

Pliki SCSS strony Szybkie zwroty

W folderze scss/static-elements utwórz nowy katalog refunds i umieść w nim trzy pliki: refunds-g.scss, refunds-m.scss i refunds-t.scss. scss/static-elements/refunds/refunds-g.scss:
.refunds-page-title {
    margin: 0 0 24px;
    font-size: 24px;
    font-weight: 500;
    line-height: 32px;
    color: $primaryColorFont;
}

.refunds-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 32px;
    margin-bottom: 32px;
    color: $primaryColorFont;
}

.refunds-info {
    align-self: flex-start;
    display: flex;
    flex-direction: column;
    gap: 16px;
    width: 100%;
    max-width: 800px;

    &__title {
        margin: 0;
        font-size: 20px;
        font-weight: 600;
        line-height: 28px;
        color: $primaryColorFont;
    }

    &__intro {
        margin: 0;
        font-size: 16px;
        font-weight: 500;
        line-height: 24px;
        color: $primaryColorFont;
    }

    &__hint {
        margin: 4px 0 0;
        font-size: 12px;
        font-weight: 400;
        line-height: 20px;
        color: $breadcrumbs;
    }
}

.refunds-steps {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;

    &__item {
        display: flex;
        align-items: center;
        gap: 12px;
    }

    &__number {
        flex-shrink: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        border-radius: 50%;
        background-color: #f3f3f3;
        color: $primaryColor;
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
    }

    &__text {
        margin: 0;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        color: $primaryColorFont;

        strong {
            font-weight: 600;
        }
    }
}

.refunds-cta {
    box-sizing: border-box;
    width: 100%;
    max-width: 578px;
    padding: 40px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 24px;
    background-color: $bgColor;
    border: 1px solid $lightBorderColor;
    border-radius: 8px;

    &__header {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 12px;
        width: 100%;
    }

    &__title {
        margin: 0;
        font-size: 24px;
        font-weight: 600;
        line-height: 32px;
        text-align: center;
        color: $primaryColorFont;
    }

    &__description {
        margin: 0;
        font-size: 16px;
        font-weight: 400;
        line-height: 24px;
        text-align: center;
        color: $breadcrumbs;
    }

    &__button {
        width: 100%;
        text-decoration: none;
    }
}

.refund-form-section {
    display: flex;
    justify-content: center;
    width: 100%;
    margin-bottom: 32px;
}

.refund-form {
    box-sizing: border-box;
    width: 100%;
    max-width: 578px;
    padding: 40px;
    background-color: $bgColor;
    border: 1px solid $lightBorderColor;
    border-radius: 8px;

    &__header {
        display: flex;
        flex-direction: column;
        gap: 12px;
        margin-bottom: 32px;
    }

    &__title {
        margin: 0;
        font-size: 24px;
        font-weight: 600;
        line-height: 32px;
        color: $primaryColorFont;
    }

    &__description {
        margin: 0;
        font-size: 14px;
        font-weight: 400;
        line-height: 20px;
        color: $breadcrumbs;
    }

    &__body {
        display: flex;
        flex-direction: column;
    }

    .form__input-wrapper {
        .form__input-value {
            &.validation-error-js {
                border-color: $dangerColor;
                color: $dangerColor;
            }
        }

        .form__invalid-input {
            position: static;
            display: block;
            margin: 4px 0 0;
            padding-left: 16px;
            text-align: left;
            color: $dangerColor;
            font-size: 12px;
            font-weight: 400;
            line-height: 16px;
        }
    }

    &__submit {
        width: 100%;
        margin-top: 4px;
    }

    &__login-info {
        margin: 16px 0 0;
        text-align: center;
        font-size: 14px;
        font-weight: 400;
        line-height: 20px;
        color: $primaryColorFont;
    }

    &__login-link {
        color: $primaryColor;
        font-weight: 600;
        cursor: pointer;
        text-decoration: none;

        &:hover {
            text-decoration: underline;
        }
    }
}
scss/static-elements/refunds/refunds-m.scss:
@media screen and (max-width: 767px) {
    .refunds-page-title {
        font-size: 20px;
        line-height: 28px;
        margin-bottom: 16px;
    }

    .refunds-container {
        gap: 24px;
        margin-bottom: 24px;
    }

    .refunds-info {
        max-width: 100%;
        gap: 12px;

        &__title {
            font-size: 18px;
            line-height: 24px;
        }

        &__intro {
            font-size: 14px;
            line-height: 22px;
        }
    }

    .refunds-steps {
        &__item {
            align-items: flex-start;
            gap: 10px;
        }

        &__number {
            width: 28px;
            height: 28px;
            font-size: 13px;
        }

        &__text {
            font-size: 13px;
            line-height: 20px;
            padding-top: 3px;
        }
    }

    .refunds-cta {
        padding: 24px;

        &__title {
            font-size: 20px;
            line-height: 28px;
        }

        &__description {
            font-size: 14px;
            line-height: 22px;
        }
    }

    .refund-form {
        padding: 24px;

        &__header {
            margin-bottom: 24px;
        }

        &__title {
            font-size: 20px;
            line-height: 28px;
        }

        &__description {
            font-size: 13px;
            line-height: 18px;
        }

        &__login-info {
            font-size: 13px;
        }
    }
}
scss/static-elements/refunds/refunds-t.scss:
@media screen and (min-width: 768px) and (max-width: 1439px) {
    .refunds-info {
        max-width: 100%;
    }
}

3. Modyfikacje istniejących plików HTML

partials/cart/thx.html

W pliku partials/cart/thx.html znajdź fragment generujący etykietę zgody w sekcji zgód marketingowych:
<label class="cart__tos-label tos-js" tabindex="0" role="checkbox" for="{{ consent.FieldValue }}" aria-checked="false"></label>
Usuń z niego atrybut for="{{ consent.FieldValue }}". Po zmianie linia powinna wyglądać tak:
<label class="cart__tos-label tos-js" tabindex="0" role="checkbox" aria-checked="false"></label>

partials/common/login.html

1. W pliku partials/common/login.html w kontenerze opakowującym formularz dodaj klasę login-container-popup. Zamień linię:
<div class="{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id -%} login-popup-js{% else -%} login-container {% endif -%}">
na:
<div class="{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id -%} login-popup-js login-container-popup{% else -%} login-container {% endif -%}">
2. W warunku otaczającym przycisk zamykający popup logowania usuń warunek and settings.signIn == "popup". Zamień linię:
{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id and settings.signIn == "popup" -%}
na:
{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id -%}

partials/product/amount-stepper.html

W pliku partials/product/amount-stepper.html znajdź blok ustawiający zmienne dla typów complaint i return:
{% if type == 'complaint' or type == 'return' -%}
{% assign reloadClass = '' -%}
{% assign complaintOrReturn = true -%}
{% endif -%}
i dodaj w jego wnętrzu nową linię ustawiającą maksymalną ilość produktu:
{% if type == 'complaint' or type == 'return' -%}
{% assign reloadClass = '' -%}
{% assign complaintOrReturn = true -%}
{% assign max = product.Quantity | Normalize -%}
{% endif -%}

partials/order/products-partials/product-table-header.html

Na samym początku pliku partials/order/products-partials/product-table-header.html dodaj blok przypisujący flagę complaintsOrReturnsEnabled:
{% if config.Complaints.ComplaintsEnabled or config.Complaints.ReturnsEnabled -%}
{% assign complaintsOrReturnsEnabled = true -%}
{% endif -%}

partials/product/products-table.html

Przyciski reklamacji i zwrotu są wyświetlane bezpośrednio w tabeli, zamiast w rozwijanym menu. W pliku partials/product/products-table.html znajdź komórkę z opcjami:
{% if order.Status == 3 and complaintsOrReturnsEnabled and product.CanComplain == true -%}
<button class="pure-button open-dropdown-js" aria-label="{{translations.Options}}">
    <!-- TODO: ikona SVG przycisku opcji – bez zmian, jak w istniejącym pliku -->
</button>
<div class="dropdown dropdown-js hidden-js" style="bottom: auto !important;">
    {% if config.Complaints.ComplaintsEnabled == true and product.CanComplain == true -%}
    <button class="pure-button open-complaint-form-js" data-type="complaint" data-product="{{ product.Url }}">
        {{ translations.Complain }}
    </button>
    {% endif -%}
    {% if config.Complaints.ReturnsEnabled == true and product.CanReturn == true and product.IsSetElement == false -%}
    <button class="pure-button open-complaint-form-js" data-type="return" data-product="{{ product.Url }}">
        {{ translations.Return }}
    </button>
    {% endif -%}
</div>
{% endif -%}
i zastąp ją następującym fragmentem:
{% if order.Status == 3 and complaintsOrReturnsEnabled -%}
{% if config.Complaints.ComplaintsEnabled == true and product.CanComplain == true -%}
<button class="pure-button open-complaint-form-js complaint-action-btn" data-type="complaint" data-product="{{ product.Url }}">
    {{ translations.Complain }}
</button>
{% endif -%}
{% if config.Complaints.ReturnsEnabled == true and product.CanReturn == true and product.IsSetElement == false -%}
<button class="pure-button open-complaint-form-js complaint-action-btn" data-type="return" data-product="{{ product.Url }}">
    {{ translations.Return }}
</button>
{% endif -%}
{% endif -%}
Następnie w tym samym pliku znajdź zewnętrzny warunek otaczający kontenery formularzy reklamacji i zwrotu i poluzuj go (usuń warunek product.CanComplain == true). Zamień:
{% if order.Status == 3 and complaintsOrReturnsEnabled and product.CanComplain == true -%}
na:
{% if order.Status == 3 and complaintsOrReturnsEnabled -%}

partials/customer-profile/orders/order-details.html

W pliku partials/customer-profile/orders/order-details.html wykonaj poniższe zmiany. a) Bloki Opcje (zawierające klasę options submenu z przyciskami akcji zamówienia) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}, aby ukryć je dla niezalogowanych klientów dokonujących szybkiego zwrotu. Wstaw {% unless order.Restricted -%} bezpośrednio przed otwierającym <div class="options submenu">, a {% endunless -%} po jego zamykającym </div>:
{% unless order.Restricted -%}
<div class="options submenu">
    ...
</div>
{% endunless -%}
b) W kontenerze messages-container-js na początku (przed istniejącymi komunikatami typu OrderEditable) dodaj baner informujący o ukrytych danych zamówienia oraz, na końcu kontenera, baner informujący o terminie zwrotu:
{% if order.Restricted -%}
<div class="return-info-banner">
    <!-- TODO: ikona SVG informacyjna (z klasą icon) -->
    {{ translations.RestrictedOrderViewInfo }}
</div>
{% endif -%}
{% if order.Status == 3 and config.Complaints.ReturnsEnabled -%}
<div class="return-info-banner">
    <!-- TODO: ikona SVG informacyjna (z klasą icon) -->
    {{ translations.OrderReturnDeadlineInfo | Format: config.Complaints.DaysToReturn }}
</div>
{% endif -%}
c) We wszystkich miejscach wyświetlających numer telefonu klienta zamień warunki sprawdzające jedynie pusty ciąg na warunki sprawdzające również wartość null. Zamień każde wystąpienie:
{% if order.Customer.DeliveryAddress.PhoneNo != '' -%}
na:
{% if order.Customer.DeliveryAddress.PhoneNo != null and order.Customer.DeliveryAddress.PhoneNo != '' -%}
d) Analogicznie zaktualizuj warunek wyświetlania NIP-u/TIN-u w sekcji danych do faktury. Zamień:
{% elseif order.Customer.TIN != '' -%}
na:
{% elseif order.Customer.TIN != null and order.Customer.TIN != '' -%}
e) W sekcji adresu dostawy zamień otwierający warunek alternatywny {% else -%} (bezpośrednio przed kontenerem z translations.DelivAddress) na bardziej restrykcyjny:
{% elseif order.Customer.DeliveryAddress != null -%}
f) Sekcję wybranego dokumentu (ChoosenDocument) opakuj warunkiem ukrywającym ją dla zamówień typu restricted. Wstaw {% unless order.Restricted -%} przed kontenerem order-details-item z tytułem translations.ChoosenDocument oraz {% endunless -%} za jego zamykającym </div>. g) W sekcji dokumentów zamówienia dodaj do warunku sprawdzenie order.Restricted == false. Zamień:
{% if orderDocumentsSize > 0 -%}
na:
{% if orderDocumentsSize > 0 and order.Restricted == false -%}
h) W sekcji załączników zamówienia dodaj analogiczne sprawdzenie. Zamień:
{% if config.Orders.AttachmentsEnabled and orderAttachmentsSize > 0 -%}
na:
{% if config.Orders.AttachmentsEnabled and orderAttachmentsSize > 0 and order.Restricted == false -%}
i) W sekcji zamówień powiązanych zamień:
{% if order.RelatedOrders[0] -%}
na:
{% if order.RelatedOrders[0] and order.Restricted == false -%}

partials/customer-profile/complaints/complaint-form.html

W pliku partials/customer-profile/complaints/complaint-form.html wprowadź poniższe zmiany. a) W kontenerze amount-stepper-container (wewnątrz warunku {% if type != 'set-return' -%}) na samym początku dodaj nową etykietę:
<span class="amount-stepper-container__label">{{ translations.Quantity }}:</span>
b) Pod sekcją z komentarzem reklamacji/zwrotu (po zamykającym {% endif -%} z sekcji complaint-message-textarea) wewnątrz warunku {% if type != 'set-return' -%} dodaj sekcję wyboru sposobu zwrotu środków:
<div class="refund-method-wrapper">
    <div class="refund-method-wrapper__title">{{ translations.Com_RefundMethod }} <span class="required">*</span></div>
    <label class="refund-method-option">
        <input class="refund-method-option__radio refund-method-radio-js" checked="checked" name="refundMethod" type="radio" value="asPaid" />
        <span class="refund-method-option__box"></span>
        <span class="refund-method-option__label">
            {{ translations.Com_RefundAsPaid }} {% if order.Payment.Name and order.Payment.Name != '' -%} ({{ order.Payment.Name }}){% endif -%}
        </span>
    </label>
    <label class="refund-method-option">
        <input class="refund-method-option__radio refund-method-radio-js" name="refundMethod" type="radio" value="bankAccount" />
        <span class="refund-method-option__box"></span>
        <span class="refund-method-option__label">{{ translations.Com_RefundToBankAccount }}</span>
    </label>
</div>
<div class="form__input-wrapper account-number-wrapper-js hidden-js">
    <label class="form__input-info input-info-js" for="accountNumber">{{ translations.Com_BankAccountNumber }} <span class="required">*</span></label>
    <input id="accountNumber" class="form__input-value input-value-js" disabled="disabled" maxlength="50" name="accountNumber" type="text" />
    <div class="form__invalid-input validation-info-js validation-required-js hidden-js">{{ translations.FieldRequired }}</div>
</div>
c) W sekcji załączników plików zamień prosty licznik file-{{forloop.index}} na prefiks zawierający identyfikator zamówienia, numer produktu i typ formularza. Tuż przed pętlą {% for i in (1..config.Complaints.AttachmentsMaxCount) -%} dodaj nową linię:
{% capture filePrefix -%}file-{{ order.Id }}-{{ product.No }}-{{ type }}{% endcapture -%}
Następnie wewnątrz pętli zamień:
<label class="file" for="file-{{forloop.index}}">
<input id="file-{{forloop.index}}" class="add-attachement-in-complaint-js hidden-js" type="file" /></label>
na:
<label class="file" for="{{ filePrefix }}-{{ forloop.index }}">
<input id="{{ filePrefix }}-{{ forloop.index }}" class="add-attachement-in-complaint-js hidden-js" type="file" /></label>
d) Komunikat sukcesu wyświetlany po wysłaniu formularza ma być inny dla reklamacji, a inny dla zwrotu. Znajdź kontener <div class="success-message-js hidden-js"> i jego dotychczasową zawartość:
<div class="success-message-js hidden-js">
    {{ successInfo }}
</div>
zastąp:
<div class="success-message-js hidden-js">
    {% if complaint -%}
    {{ successInfo }}
    {% else -%}
    <div class="data-form__header return-success__header">
        <button class="close-button hide-container-js closing-modal-js" aria-label="{{ translations.Close }}">
            <!-- TODO: ikona SVG zamknięcia – jak w pozostałych popupach szablonu -->
        </button>
    </div>
    <div class="return-success__icon">
        <!-- TODO: ikona SVG potwierdzenia (zielony "check") -->
    </div>
    <div class="return-success__title">{{ successTitle }}</div>
    <div class="return-success__subtitle">{{ successInfo }}</div>
    {% if order.Customer.Email and order.Customer.Email != '' -%}
    <div class="return-success__email-box">
        <!-- TODO: ikona SVG informacyjna -->
        <div>
            <div>{{ translations.Com_ConfirmationSentTo }}</div>
            <strong>{{ order.Customer.Email }}</strong>
        </div>
    </div>
    {% endif -%}
    <div class="return-success__steps-title">{{ translations.Com_NextSteps }}</div>
    <ol class="return-success__steps">
        <li>{{ translations.Com_PackProducts }}</li>
        <li>{{ translations.Com_SendPackageTo }}
            {% if config.Shop.Address.Street != '' -%} {{ config.Shop.Address.Street }}{% endif -%}
            {% if config.Shop.Address.StreetNo != '' -%} {{ config.Shop.Address.StreetNo }}{% endif -%}
            {% if config.Shop.Address.UnitNo != '' -%}/{{ config.Shop.Address.UnitNo }}{% endif -%}
            {% if config.Shop.Address.ZipCode != '' or config.Shop.Address.City != '' -%}, {{ config.Shop.Address.ZipCode }} {{ config.Shop.Address.City }}{% endif -%}</li>
        <li>{{ translations.Com_RefundAfterReceive }}</li>
    </ol>
    <div class="buttons-container short">
        <button class="primary-action-button hide-container-js closing-modal-js">
            {{ translations.Close }}
        </button>
    </div>
    {% endif -%}
</div>

4. Modyfikacje pliku js/layout-customerprofile0.js

Poniższe zmiany dotyczą pliku js/layout-customerprofile0.js (jego nieskompresowanej wersji, którą po edycji należy ponownie zminifikować do layout-customerprofile0.min.js). a) W funkcji openComplaintForm wewnątrz warunku if (hiddenContainer) – tuż po linii hiddenContainer.querySelector('.success-message-js').classList.add('hidden-js'); – dodaj kod ujawniający nagłówek formularza oraz resetujący wybór sposobu zwrotu do opcji domyślnej:
const mainHeader = hiddenContainer.querySelector(':scope > .data-form__header');
if (mainHeader) {
    mainHeader.classList.remove('hidden-js');
}
hiddenContainer.classList.remove('hidden-js');

const asPaidRadio = hiddenContainer.querySelector('.refund-method-radio-js[value="asPaid"]');
if (asPaidRadio) {
    asPaidRadio.checked = true;
    $(asPaidRadio).trigger('change');
}
(Linia hiddenContainer.classList.remove('hidden-js'); już istnieje – pokazana jest dla kontekstu. Nowe są bloki const mainHeader i const asPaidRadio.) b) W funkcji sendComplaint, w bloku przygotowującym dane formularza – po pętli for (const item of dataFromHTML) dokładającej pola do fd – dodaj fragment dołączający parametr qrHash z adresu URL przy wysyłaniu zwrotu:
if (form.find('input[name="__action"]').val() === 'Order/ReturnAdd') {
    const qrHash = new URLSearchParams(globalThis.location.search).get('qrHash');
    if (qrHash) {
        fd.append('qrHash', qrHash);
    }
}
c) W tej samej funkcji sendComplaint, w callbacku success po pomyślnym wysłaniu, zamień fragment:
form.parents('.add-complaint-form-js').find('.success-message-js').removeClass('hidden-js');
na:
const container = form.parents('.add-complaint-form-js');
container.find('.success-message-js').removeClass('hidden-js');
container.children('.data-form__header').addClass('hidden-js');
d) Na samym końcu pliku js/layout-customerprofile0.js dodaj nowy handler obsługujący przełączanie sposobu zwrotu środków. Pokazuje on / ukrywa pole na numer konta bankowego:
$('body').on('change', '.refund-method-radio-js', function(e) {
    const radio = $(e.currentTarget);
    const form = radio.closest('.form-js');
    const wrapper = form.find('.account-number-wrapper-js');
    const input = wrapper.find('input[name="accountNumber"]');
    if (radio.val() === 'bankAccount' && radio.prop('checked')) {
        wrapper.removeClass('hidden-js');
        input.prop('disabled', false);
        input.prop('required', true);
    } else {
        wrapper.addClass('hidden-js');
        wrapper.find('.validation-required-js').addClass('hidden-js');
        wrapper.find('.form__input-info').removeClass('validation-error');
        input.removeClass('validation-error-js');
        input.prop('required', false);
        input.prop('disabled', true);
        input.val('');
    }
});

5. Modyfikacje plików SCSS profilu klienta

Poniższe style należy dodać do plików scss/static-elements/customer-profile/customer-profile-g.scss (wersja desktop) oraz scss/static-elements/customer-profile/customer-profile-m.scss (wersja mobile). Po zmianach pamiętaj o kompilacji – nie edytuj ręcznie wynikowych plików CSS.

Plik scss/static-elements/customer-profile/customer-profile-g.scss

a) Dla "przyklejonej" kolumny z akcjami reklamacji/zwrotu w tabeli produktów dodaj reguły wewnątrz selektora otaczającego tabelę zamówienia (tam, gdzie znajdują się style dla thead tr th):
thead tr th.open-complaint-form-container-js {
    position: sticky;
    right: 0;
    background: transparent;
    z-index: 5;

    &::before {
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        right: 0;
        width: 200px;
        background: linear-gradient(to right, rgba(255, 255, 255, 0), #fff 50%);
        pointer-events: none;
    }
}

td.complaint-actions-inline {
    white-space: nowrap;
    text-align: right;
    padding-left: 16px;
    padding-right: 8px;
    position: sticky;
    right: 0;
    background: #fff;
    z-index: 2;

    &::before {
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        left: -32px;
        width: 32px;
        background: linear-gradient(to right, rgba(255, 255, 255, 0), #fff 100%);
        pointer-events: none;
    }

    .pure-button.complaint-action-btn {
        display: inline-flex;
        background: transparent;
        border: 0;
        border-radius: 4px;
        color: $primaryColor;
        padding: 4px 8px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
        transition: background-color 150ms ease;

        &:hover,
        &:focus-visible {
            color: $primaryColor;
            background: rgba(0, 0, 0, 0.06);
        }

        & + .complaint-action-btn {
            margin-left: 8px;
        }
    }
}
b) Style hovera dla wiersza tabeli z akcjami reklamacji/zwrotu (umieść w głównym zakresie pliku):
.row {
    &:hover,
    &:focus-within,
    &.hovered-js {
        td.complaint-actions-inline {
            background: #F1DDDE;

            &::before {
                background: linear-gradient(to right, rgba(241, 221, 222, 0), #F1DDDE 100%);
            }
        }
    }

    &.set td.complaint-actions-inline {
        background: #ececec;

        &::before {
            background: linear-gradient(to right, rgba(236, 236, 236, 0), #ececec 100%);
        }
    }
}
c) Style banera informacyjnego (termin zwrotu / ukryte dane zamówienia):
.return-info-banner {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    margin: 0 0 24px 0;
    background: #E8F1F8;
    border: 1px solid #C7DCEE;
    border-radius: 5px;
    font-size: 14px;
    line-height: 20px;
    color: #2C3E50;

    .icon {
        flex-shrink: 0;
        fill: #4A90BC;
    }

    strong {
        font-weight: 600;
    }
}
d) Style sekcji wyboru sposobu zwrotu środków oraz radio-buttonów:
.refund-method-wrapper {
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin-bottom: 24px;

    &__title {
        color: $primaryColorFont;
        font-size: 14px;
        font-weight: 500;
        line-height: 20px;
    }
}

.refund-method-option {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;

    &__radio {
        display: none;

        &:checked ~ .refund-method-option__box {
            border-color: $primaryColor;

            &::after {
                content: "";
                display: block;
                width: 8px;
                height: 8px;
                border-radius: 50%;
                background: $primaryColor;
            }
        }
    }

    &__box {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 16px;
        height: 16px;
        border: 1px solid #767676;
        border-radius: 50%;
        flex-shrink: 0;
    }

    &__label {
        font-size: 14px;
        line-height: 20px;
    }
}
e) Style ekranu sukcesu po wysłaniu zwrotu (m.in. ikona, tytuł, lista kolejnych kroków):
.add-complaint-form-js .characters-length {
    margin-top: 0;
    bottom: 23px;
}

.add-complaint-form-js {
    .quantity__plus.disabled-js,
    .quantity__minus.disabled-js {
        opacity: 0.4;
    }
}

.add-complaint-form-js .data-form__header.return-success__header {
    margin-bottom: 8px;
}

.return-success {
    &__icon {
        display: flex;
        justify-content: center;
        margin-bottom: 16px;

        svg {
            fill: #2E7D32;
        }
    }

    &__title {
        text-align: center;
        font-size: 20px;
        font-weight: 600;
        line-height: 28px;
        color: $primaryColorFont;
        margin-bottom: 8px;
    }

    &__subtitle {
        text-align: center;
        font-size: 14px;
        line-height: 20px;
        color: $labelsColor;
        padding-bottom: 24px;
        border-bottom: 1px solid #E7E7E7;
        margin-bottom: 24px;
    }

    &__email-box {
        display: flex;
        align-items: flex-start;
        gap: 12px;
        padding: 12px 16px;
        background: #F0F6FC;
        border: 1px solid #D6E4F0;
        border-radius: 6px;
        margin-bottom: 24px;
        font-size: 14px;
        line-height: 20px;
        color: $primaryColorFont;

        svg {
            fill: #1976D2;
            flex-shrink: 0;
            margin-top: 2px;
        }
    }

    &__steps-title {
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
        color: $primaryColorFont;
        margin-bottom: 12px;
    }

    &__steps {
        margin: 0 0 24px;
        padding-left: 20px;
        font-size: 14px;
        line-height: 20px;
        color: $primaryColorFont;

        li {
            margin-bottom: 8px;

            &:last-child {
                margin-bottom: 0;
            }
        }
    }
}
f) Uzupełnij wnętrze selektora .file-attachements-wrapper o style dla kontenera pojedynczego załącznika:
.file-container {
    .file {
        align-items: center;
        font-weight: 400;
        color: $primaryColorFont;
        justify-content: flex-start;
    }

    .icon-js svg {
        fill: $primaryColorFont;
    }

    .clear-file-input-js {
        flex-shrink: 0;
        display: flex;
        align-items: center;

        svg {
            width: 14px;
            height: 14px;
            fill: $primaryColor;
        }
    }
}

Plik scss/static-elements/customer-profile/customer-profile-m.scss

Na końcu pliku customer-profile-m.scss dodaj reguły dopasowujące przyciski reklamacji/zwrotu do widoku mobilnego (układają się one wówczas jeden pod drugim):
.eshop__table-container {
    thead tr th.open-complaint-form-container-js::before {
        width: 100px;
    }

    td.complaint-actions-inline {
        .pure-button.complaint-action-btn {
            display: block;
            width: max-content;
            margin-left: auto;
            text-align: right;

            & + .complaint-action-btn {
                margin-left: auto;
                margin-top: 4px;
            }
        }
    }
}
Po wprowadzeniu wszystkich powyższych zmian w szablonie Rubin pamiętaj o kompilacji oraz minifikacji plików js i scss, zgodnie z artykułem dostępnym pod linkiem https://pomoc.comarchesklep.pl/artykul/kompilacja-i-minifikacja-plikow/.

Szablon Szafir

1. Tłumaczenia

W panelu administracyjnym sklepu dodaj nowe klucze tłumaczeń wymagane przez funkcjonalność szybkich zwrotów w szablonie Szafir. OrderReturnDeadlineInfo - PL: Zamówienie można zwrócić w ciągu {0} dni od daty dostawy. - EN: You can return the order within {0} days from the delivery date. - DE: Sie können die Bestellung innerhalb von {0} Tagen ab Lieferdatum zurückgeben. - FR: Vous pouvez retourner la commande dans les {0} jours suivant la date de livraison. RestrictedOrderViewInfo - PL: Wybrane dane zamówienia zostały ukryte ze względów bezpieczeństwa. Możesz zwrócić produkty bez logowania. - EN: Some order details are hidden for security reasons. You can return products without signing in. - DE: Einige Bestelldetails wurden aus Sicherheitsgründen ausgeblendet. Sie können Produkte ohne Anmeldung zurücksenden. - FR: Certaines informations de la commande ont été masquées pour des raisons de sécurité. Vous pouvez retourner des produits sans vous connecter. RefundMethod - PL: Sposób zwrotu środków - EN: Refund method - DE: Rückerstattungsmethode - FR: Méthode de remboursement RefundAsPaid - PL: Tak jak zapłacono - EN: As paid - DE: Wie bezahlt - FR: Comme payé RefundToBankAccount - PL: Na konto bankowe - EN: To bank account - DE: Auf Bankkonto - FR: Sur le compte bancaire BankAccountNumber - PL: Nr konta bankowego - EN: Bank account number - DE: Bankkontonummer - FR: Numéro de compte bancaire ReturnConfirmationTitle - PL: Gotowe! Przyjęliśmy Twoje zgłoszenie - EN: Done! We have received your request - DE: Fertig! Wir haben Ihre Anfrage erhalten - FR: Terminé! Nous avons reçu votre demande ReturnConfirmationInfo - PL: Przygotuj paczkę i odeślij ją do nas – wszystkie szczegóły znajdziesz poniżej. - EN: Prepare the package and send it back to us – all details can be found below. - DE: Bereiten Sie das Paket vor und senden Sie es an uns zurück – alle Details finden Sie unten. - FR: Préparez le colis et renvoyez-le nous – tous les détails se trouvent ci-dessous. ReturnConfirmationEmailSent - PL: Potwierdzenie zwrotu zostało wysłane na adres: - EN: Return confirmation has been sent to: - DE: Die Rücksendebestätigung wurde gesendet an: - FR: La confirmation de retour a été envoyée à: NextSteps - PL: Następne kroki - EN: Next steps - DE: Nächste Schritte - FR: Prochaines étapes ReturnStep1 - PL: Bezpiecznie zapakuj swoje produkty - EN: Safely pack your products - DE: Verpacken Sie Ihre Produkte sicher - FR: Emballez vos produits en toute sécurité ReturnStep2Address - PL: Wyślij paczkę na adres - EN: Send the package to - DE: Senden Sie das Paket an - FR: Envoyez le colis à ReturnStep3 - PL: Pieniądze zwrócimy niezwłocznie po otrzymaniu i sprawdzeniu Twojej paczki. - EN: We will refund the money promptly after receiving and checking your package. - DE: Wir erstatten das Geld umgehend nach Erhalt und Überprüfung Ihres Pakets. - FR: Nous rembourserons l'argent rapidement après réception et vérification de votre colis. ReturnInThreeSteps - PL: Zwróć towar w 3 krokach - EN: Return the product in 3 steps - DE: Geben Sie die Ware in 3 Schritten zurück - FR: Retournez la marchandise en 3 étapes ReturnWithoutReasonInfo - PL: Przysługuje Ci możliwość zwrotu bez podania przyczyny. - EN: You have the right to return the product without giving a reason. - DE: Sie haben das Recht, die Ware ohne Angabe von Gründen zurückzugeben. - FR: Vous avez le droit de retourner la marchandise sans donner de motif. OrEnterOrderNumber - PL: lub podaj numer zamówienia - EN: or enter the order number - DE: oder geben Sie die Bestellnummer ein - FR: ou saisissez le numéro de commande FillForm - PL: Wypełnij formularz - EN: Fill out the form - DE: Füllen Sie das Formular aus - FR: Remplissez le formulaire ReturnOnline - PL: zwrotu online - EN: online return - DE: Online-Rückgabe - FR: retour en ligne SendParcel - PL: Wyślij paczkę - EN: Send the parcel - DE: Paket senden - FR: Envoyer le colis SendParcelToOurAddress - PL: nadaj przesyłkę na nasz adres - EN: send the parcel to our address - DE: senden Sie das Paket an unsere Adresse - FR: envoyez le colis à notre adresse FastSimpleSecure - PL: Szybko, prosto i bezpiecznie. - EN: Fast, simple and secure. - DE: Schnell, einfach und sicher. - FR: Rapide, simple et sécurisé. ReadyForReturn - PL: Gotowy do zwrotu? - EN: Ready for return? - DE: Bereit zur Rückgabe? - FR: Prêt pour le retour ? ReadyForReturnInfo - PL: Kliknij poniżej, aby rozpocząć proces zwrotu. Przeprowadzimy Cię przez wszystkie kroki. - EN: Click below to start the return process. We will guide you through all the steps. - DE: Klicken Sie unten, um den Rückgabeprozess zu starten. Wir führen Sie durch alle Schritte. - FR: Cliquez ci-dessous pour lancer le processus de retour. Nous vous guiderons à travers toutes les étapes. StartReturn - PL: Rozpocznij zwrot - EN: Start return - DE: Rückgabe starten - FR: Commencer le retour ProductReturn - PL: Zwrot produktu - EN: Product return - DE: Produktrückgabe - FR: Retour du produit ProductReturnFormInfo - PL: Wprowadź dane zamówienia, aby zlokalizować zakup i rozpocząć proces zwrotu. Numer zamówienia znajdziesz w e-mailu z potwierdzeniem. - EN: Enter the order details to locate the purchase and start the return process. You will find the order number in the confirmation e-mail. - DE: Geben Sie die Bestelldaten ein, um den Kauf zu lokalisieren und den Rückgabeprozess zu starten. Die Bestellnummer finden Sie in der Bestätigungs-E-Mail. - FR: Saisissez les données de la commande pour localiser l'achat et démarrer le processus de retour. Vous trouverez le numéro de commande dans l'e-mail de confirmation. InvalidOrderNumber - PL: Błędny numer zamówienia. Spróbuj ponownie. - EN: Invalid order number. Please try again. - DE: Ungültige Bestellnummer. Bitte versuchen Sie es erneut. - FR: Numéro de commande incorrect. Veuillez réessayer. FindOrder - PL: Znajdź zamówienie - EN: Find order - DE: Bestellung finden - FR: Trouver la commande LoginToSeeOrdersAndReturn - PL: aby zobaczyć swoje zamówienia i dokonać zwrotu. - EN: to see your orders and make a return. - DE: um Ihre Bestellungen einzusehen und eine Rückgabe vorzunehmen. - FR: pour voir vos commandes et effectuer un retour. RefundLookupError - PL: Wystąpił błąd podczas wyszukiwania zamówienia. Spróbuj ponownie później. - EN: An error occurred while searching for the order. Please try again later. - DE: Bei der Suche nach der Bestellung ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut. - FR: Une erreur s'est produite lors de la recherche de la commande. Veuillez réessayer plus tard.

2. Nowa strona Szybkie zwroty

Funkcjonalność szybkich zwrotów wymaga utworzenia dodatkowej strony statycznej refunds. Wykonaj poniższe kroki.

Plik refunds.html w katalogu głównym szablonu

W katalogu głównym szablonu utwórz nowy plik refunds.html z następującą zawartością:
{% extends '_layout.html' %}

{% block content %}
{% include 'static-elements/refunds/refunds.html' %}
{% endblock %}

Plik static-elements/refunds/refunds.html

W folderze static-elements utwórz nowy katalog refunds, a w nim plik refunds.html:
<section class="refunds refunds-js form-js">
    <p class="refunds-header refunds-initial-view-js">{{ translations.Returns }}</p>
    <div class="refunds-intro refunds-initial-view-js">
        <div class="refunds-info">
            <p class="refunds-info-title">{{ translations.ReturnInThreeSteps }}</p>
            <p class="refunds-info-desc">{{ translations.ReturnWithoutReasonInfo }}</p>
            <ol class="refunds-steps">
                <li class="refunds-steps-item">
                    <span class="refunds-steps-number">1</span>
                    <p class="refunds-steps-text"><strong>{{ translations.SignIn }}</strong> {{ translations.OrEnterOrderNumber }}</p>
                </li>
                <li class="refunds-steps-item">
                    <span class="refunds-steps-number">2</span>
                    <p class="refunds-steps-text"><strong>{{ translations.FillForm }}</strong> {{ translations.ReturnOnline }}</p>
                </li>
                <li class="refunds-steps-item">
                    <span class="refunds-steps-number">3</span>
                    <p class="refunds-steps-text"><strong>{{ translations.SendParcel }}</strong> - {{ translations.SendParcelToOurAddress }}</p>
                </li>
            </ol>
            <p class="refunds-info-hint">{{ translations.FastSimpleSecure }}</p>
        </div>
        <div class="refunds-cta">
            <p class="refunds-cta-title">{{ translations.ReadyForReturn }}</p>
            <p class="refunds-cta-desc">{{ translations.ReadyForReturnInfo }}</p>
            {% if usr.Authenticated -%}
            <a class="refunds-cta-button" href="{{ config.DefinedPages.CustomerProfile.Url }}?tab=orders" rel="nofollow" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </a>
            {% else -%}
            <button class="refunds-cta-button start-refund-js" type="button" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </button>
            {% endif -%}
        </div>
    </div>
    {% unless usr.Authenticated -%}
    <div class="refunds-form-section refund-form-view-js hidden-js">
        <div class="refunds-form">
            <p class="refunds-form-title">{{ translations.ProductReturn }}</p>
            <p class="refunds-form-desc">{{ translations.ProductReturnFormInfo }}</p>
            <div class="refund-form-js" data-cp-url="{{ config.DefinedPages.CustomerProfile.Url }}">
                <div class="message-bar-ui warning-bar-ui refund-lookup-error-js hidden-js">{{ translations.RefundLookupError }}</div>
                <div class="form__input-wrapper">
                    <label class="form__input-info form__input-info-js" for="refundOrderNumber" data-type="text">{{ translations.OrderNumber }} <span class="required-ui">*</span></label>
                    <input id="refundOrderNumber" class="form__input-value form__input-value-js" maxlength="50" name="orderNumber" required="" type="text" aria-label="{{ translations.OrderNumber }}" />
                    <span class="error-ui validation-info-js validation-required-js hidden-js">{{ translations.RequiredField }}</span>
                </div>
                <div class="form__input-wrapper">
                    <label class="form__input-info form__input-info-js" for="refundEmail" data-type="email">{{ translations.EmailAddress }} <span class="required-ui">*</span></label>
                    <input id="refundEmail" class="form__input-value form__input-value-js" autocomplete="email" maxlength="192" name="email" required="" type="email" aria-label="{{ translations.EmailAddress }}" />
                    <span class="error-ui validation-info-js validation-required-js hidden-js">{{ translations.RequiredField }}</span>
                    <span class="error-ui validation-info-js email-valid-js hidden-js">{{ translations.FillProperEmail }}</span>
                </div>
                <div class="required-fields-info-ui form__required-fields-info"><span class="required-ui">* </span>{{ translations.RequiredFields }}</div>
                <button class="refunds-form-submit refund-form-submit-js" type="button" aria-label="{{ translations.FindOrder }}">
                    {{ translations.FindOrder }}
                </button>
                <p class="refunds-form-login-info">{{ translations.HaveAccount }} <a class="refunds-form-login-link" href="{{ config.DefinedPages.Login.Url }}" rel="nofollow">{{ translations.SignIn }}</a>, {{ translations.LoginToSeeOrdersAndReturn }}</p>
            </div>
        </div>
    </div>
    {% endunless -%}
</section>

Plik js/layout0.js – kod obsługi formularza zwrotu

Na końcu pliku js/layout0.js dodaj poniższy kod odpowiedzialny za walidację i wysłanie formularza wyszukiwania zamówienia (dla niezalogowanego klienta). Po zapisaniu pliku pamiętaj o zminifikowaniu go do layout0.min.js.
const refunds = {
    findRefundOrder(orderNumber, email) {
        return $.post('', {
            __action: 'Order/QuickReturnLookup',
            orderId: orderNumber,
            email: email,
            __csrf: __CSRF
        });
    },

    showForm() {
        document.querySelectorAll('.refunds-initial-view-js').forEach((el) => el.classList.add('hidden-js'));
        document.querySelectorAll('.refund-form-view-js').forEach((el) => el.classList.remove('hidden-js'));
        document.querySelector('.refund-form-js input[name="orderNumber"]')?.focus();
    },

    clearFieldError(input) {
        input.classList.remove('validation-error-ui', 'validation-error-lq');
        input.closest('.form__input-wrapper')
            ?.querySelectorAll('.error-ui')
            .forEach((el) => el.classList.add('hidden-js'));
    },

    markFieldError(input, errorSelector) {
        input.classList.add('validation-error-ui', 'validation-error-lq');
        input.closest('.form__input-wrapper')?.querySelector(errorSelector)?.classList.remove('hidden-js');
    },

    validateForm({ orderInput, emailInput }) {
        const orderValue = orderInput.value.trim();
        const emailValue = emailInput.value.trim();
        const emailRegex = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w{2,}$/;
        let hasError = false;

        if (orderValue.length === 0) {
            refunds.markFieldError(orderInput, '.validation-required-js');
            hasError = true;
        }

        if (emailValue.length === 0) {
            refunds.markFieldError(emailInput, '.validation-required-js');
            hasError = true;
        } else if (!emailRegex.test(emailValue)) {
            refunds.markFieldError(emailInput, '.email-valid-js');
            hasError = true;
        }

        return { hasError, orderValue };
    },

    async submitForm(button) {
        const form = button.closest('.refund-form-js');
        if (!form) {
            return;
        }
        const orderInput = form.querySelector('input[name="orderNumber"]');
        const emailInput = form.querySelector('input[name="email"]');

        form.querySelectorAll('.error-ui').forEach((el) => el.classList.add('hidden-js'));
        form.querySelector('.refund-lookup-error-js')?.classList.add('hidden-js');
        form.querySelectorAll('.form__input-value').forEach((el) => {
            el.classList.remove('validation-error-ui', 'validation-error-lq');
        });

        const { hasError, orderValue } = refunds.validateForm({ orderInput, emailInput });
        if (hasError) {
            return;
        }

        button.disabled = true;
        const errorBar = form.querySelector('.refund-lookup-error-js');
        try {
            const result = await refunds.findRefundOrder(orderValue, emailInput.value.trim());
            const action = result.action;
            if (action.Redirect302) {
                globalThis.location.href = action.Redirect302;
                return;
            }
            if (errorBar) {
                errorBar.textContent = action.Message;
                errorBar.classList.remove('hidden-js');
            }
        } catch (error) {
            console.error('Refund order lookup failed.', error);
            errorBar?.classList.remove('hidden-js');
        } finally {
            button.disabled = false;
        }
    }
};

js.delegate(document.body, 'click', '.start-refund-js', () => refunds.showForm());

js.delegate(document.body, 'input', '.refund-form-js .form__input-value', function () {
    refunds.clearFieldError(this);
});

js.delegate(document.body, 'click', '.refund-form-submit-js', function (event) {
    event.preventDefault();
    refunds.submitForm(this);
});

js.delegate(document.body, 'keydown', '.refund-form-js input', function (event) {
    if (event.key !== 'Enter') {
        return;
    }
    event.preventDefault();
    this.closest('.refund-form-js')?.querySelector('.refund-form-submit-js')?.click();
});

Pliki SCSS strony Szybkie zwroty

W folderze scss/static-elements utwórz nowy katalog refunds i umieść w nim dwa pliki: refunds-g.scss (style desktop) oraz refunds-m.scss (style mobilne). scss/static-elements/refunds/refunds-g.scss:
.refunds {
    padding: 40px 110px;
    background-color: $bgColor;
    color: $primaryColorFont;

    .refunds-header {
        display: block;
        width: 100%;
        margin: 0 0 24px;
        color: $primaryColorFont;
        text-align: left;
        font-size: 32px;
        font-weight: 500;
        line-height: 42px;
        letter-spacing: 0.8px;
    }

    .refunds-intro {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 32px;
        margin-bottom: 40px;
    }

    .refunds-info {
        align-self: flex-start;
        width: 100%;
        max-width: 800px;
        display: flex;
        flex-direction: column;
        gap: 16px;
        color: $primaryColorFont;

        @media screen and (min-width: 769px) and (max-width: 1279px) {
            max-width: 100%;
        }
    }

    .refunds-info-title {
        margin: 0;
        font-size: 20px;
        font-weight: 500;
        line-height: 28px;
        letter-spacing: 0.4px;
    }

    .refunds-info-desc {
        margin: 0;
        font-size: 16px;
        font-weight: 400;
        line-height: 24px;
        letter-spacing: 0.3px;
    }

    .refunds-info-hint {
        margin: 4px 0 0;
        color: $secondaryColorFont;
        font-size: 12px;
        font-weight: 400;
        line-height: 20px;
        letter-spacing: 0.2px;
    }

    .refunds-steps {
        list-style: none;
        margin: 0;
        padding: 0;
        display: flex;
        flex-direction: column;
        gap: 12px;
    }

    .refunds-steps-item {
        display: flex;
        align-items: center;
        gap: 12px;
    }

    .refunds-steps-number {
        flex-shrink: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        border-radius: 50%;
        background-color: $formsBgColor;
        color: $primaryColor;
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
    }

    .refunds-steps-text {
        margin: 0;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        letter-spacing: 0.3px;

        strong {
            font-weight: 600;
        }
    }

    .refunds-cta {
        box-sizing: border-box;
        width: 100%;
        max-width: 578px;
        padding: 32px 40px;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 12px;
        background-color: $bgColor;
        border: 1px solid $lightBorderColor;
    }

    .refunds-cta-title {
        margin: 0;
        text-align: center;
        font-size: 22px;
        font-weight: 500;
        line-height: 30px;
        letter-spacing: 0.5px;
        color: $primaryColorFont;
    }

    .refunds-cta-desc {
        margin: 0;
        text-align: center;
        color: $secondaryColorFont;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        letter-spacing: 0.3px;
    }

    .refunds-cta-button,
    .refunds-form-submit {
        display: inline-block;
        width: 100%;
        margin-top: 8px;
        padding: 12px 16px;
        background: $btnSolidBgColor;
        color: $btnSolidTextColor;
        border: 1px solid $btnSolidBgColor;
        font-size: 14px;
        font-weight: 500;
        line-height: 20px;
        text-align: center;
        text-decoration: none;
        cursor: pointer;
        transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;

        &:hover,
        &:focus {
            background: $btnSolidHoverBgColor;
            color: $btnSolidHoverTextColor;
            border-color: $btnSolidHoverBgColor;
        }

        &[disabled],
        &[disabled]:hover {
            background: $btnDisabledBg;
            border-color: $btnDisabledFont;
            color: $btnDisabledFont;
            cursor: default;
        }
    }

    .refunds-form-section {
        display: flex;
        justify-content: center;
        width: 100%;
        margin-top: 32px;
        margin-bottom: 40px;
    }

    .refunds-form {
        box-sizing: border-box;
        width: 100%;
        max-width: 578px;
        padding: 32px 40px;
        background-color: $bgColor;
        border: 1px solid $lightBorderColor;
    }

    .refunds-form-title {
        margin: 0 0 8px;
        font-size: 22px;
        font-weight: 500;
        line-height: 30px;
        letter-spacing: 0.5px;
        color: $primaryColorFont;
    }

    .refunds-form-desc {
        margin: 0 0 20px;
        color: $secondaryColorFont;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        letter-spacing: 0.3px;
    }

    .refund-form-js {
        display: flex;
        flex-direction: column;

        .form__input-wrapper {
            position: relative;
            margin-bottom: 16px;

            .form__input-info {
                display: block;
                margin: 0 0 4px;
                color: $primaryColorFont;
                font-size: 13px;
                font-weight: 400;
                line-height: 18px;
            }

            input {
                width: 100%;
                height: 36px;
                margin: 0;
                padding: 0 10px;
                box-sizing: border-box;
                border: 1px solid $lightBorderColor;
                font-size: 14px;

                &::placeholder {
                    font-size: 14px;
                }

                &.validation-error-ui,
                &.validation-error-lq {
                    border-color: $dangerColor;
                    color: $dangerColor;
                }
            }

            .error-ui {
                position: static;
                display: block;
                margin: 4px 0 0;
                padding: 0;
                text-align: left;
                color: $dangerColor;
                font-size: 12px;
                font-weight: 400;
                line-height: 16px;
            }
        }

        .form__required-fields-info {
            margin: 4px 0 16px;
            color: $primaryColorFont;
            font-size: 12px;
            font-weight: 300;
            line-height: 18px;
        }
    }

    .refunds-form-login-info {
        margin: 12px 0 0;
        text-align: center;
        color: $primaryColorFont;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
    }

    .refunds-form-login-link {
        color: $primaryColor;
        font-weight: 600;
        cursor: pointer;
        text-decoration: none;

        &:hover {
            text-decoration: underline;
        }
    }
}
scss/static-elements/refunds/refunds-m.scss:
@media screen and (max-width: 768px) {
    .refunds {
        padding: 20px 16px;

        .refunds-header {
            font-size: 24px;
            line-height: 32px;
            margin-bottom: 16px;
        }

        .refunds-intro {
            gap: 24px;
            margin-bottom: 24px;
        }

        .refunds-info {
            max-width: 100%;
            gap: 12px;
        }

        .refunds-info-title {
            font-size: 18px;
            line-height: 24px;
        }

        .refunds-info-desc {
            font-size: 14px;
            line-height: 22px;
        }

        .refunds-steps-item {
            align-items: flex-start;
            gap: 10px;
        }

        .refunds-steps-number {
            width: 28px;
            height: 28px;
            font-size: 13px;
        }

        .refunds-steps-text {
            font-size: 13px;
            line-height: 20px;
            padding-top: 3px;
        }

        .refunds-cta {
            padding: 24px;
        }

        .refunds-cta-title {
            font-size: 20px;
            line-height: 28px;
        }

        .refunds-form-section {
            margin-top: 20px;
            margin-bottom: 24px;
        }

        .refunds-form {
            padding: 24px;
            border: none;
        }

        .refunds-form-title {
            font-size: 20px;
            line-height: 28px;
        }

        .refunds-form-desc {
            margin-bottom: 16px;
        }

        .refunds-form-login-info {
            font-size: 13px;
        }
    }
}

3. Modyfikacje istniejących plików HTML

partials/customer-profile/orders/order-details.html

W pliku partials/customer-profile/orders/order-details.html wykonaj poniższe zmiany. a) Blok z przyciskami akcji nawigacji zamówienia (zawierający {% if order.EditingAllowed -%}, opcje anulowania, edycji, ponowienia, druku itp.) opakuj warunkiem ukrywającym go dla zamówień typu restricted. Bezpośrednio po linii z elementem <li class="active-ui only-text-ui ...">...</li> wstaw:
{% unless order.Restricted -%}
a tuż przed zamykającym znacznikiem </ul> tej samej nawigacji dodaj:
{% endunless -%}
b) Na początku kontenera messages-container-lq messages-container-ui (zaraz po jego otwarciu) dodaj baner informujący o ukrytych danych zamówienia:
{% if order.Restricted -%}
<div class="message-bar-ui no-margin-ui">
    <i class="not-clickable-ui ti-info-alt"></i>
    {{ translations.RestrictedOrderViewInfo }}
</div>
{% endif -%}
c) Na końcu tego samego kontenera (przed zamykającym </div>) dodaj baner informujący o terminie zwrotu wraz z przypisaniem flagi complaintsOrReturnsEnabled:
{% if config.Complaints.ComplaintsEnabled or config.Complaints.ReturnsEnabled -%}
{% assign complaintsOrReturnsEnabled = true -%}
{% endif -%}

{% if order.Status == 3 and complaintsOrReturnsEnabled -%}
<div class="message-bar-ui no-margin-ui">
    <i class="not-clickable-ui ti-info-alt"></i>
    {{translations.OrderReturnDeadlineInfo | Format: config.Complaints.DaysToReturn}}
</div>
{% endif -%}
d) Blok z przyciskami akcji wewnątrz info-container-js (zawierający przyciski order.CanCancel, edycji, ponowienia zakupu itd.) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}. Wstaw {% unless order.Restricted -%} bezpośrednio przed pierwszym {% if order.CanCancel -%}, a {% endunless -%} po zamykającym warunku odpowiedzialnym za popup potwierdzenia ({% include 'partials/common/confirmation-popup.html' with 0 -%}). e) W sekcji wyświetlającej dokumenty zamówienia zamień:
{% if order.Documents %}
na:
{% if order.Documents and order.Restricted == false %}
f) We wszystkich miejscach wyświetlających numer telefonu klienta zamień warunki sprawdzające jedynie pusty ciąg na warunki sprawdzające również wartość null. Zamień każde wystąpienie:
{% if order.Customer.DeliveryAddress.PhoneNo != '' -%}
na:
{% if order.Customer.DeliveryAddress.PhoneNo != null and order.Customer.DeliveryAddress.PhoneNo != '' -%}
g) Każdą sekcję z tytułem translations.ChoosenDocument opakuj warunkiem ukrywającym ją dla zamówień restricted. Wstaw {% unless order.Restricted -%} bezpośrednio przed <div class="name-ui mt20-ui">{{ translations.ChoosenDocument }}</div> oraz {% endunless -%} po jej zamykającym </div>. h) W sekcji wyświetlającej alternatywny adres dostawy zamień warunek {% else -%} (bezpośrednio przed order-info-item-ui z translations.DelivAddress) na bardziej restrykcyjny:
{% elseif order.Customer.DeliveryAddress != null -%}
i) W sekcji danych do faktury zamień warunek wyświetlania NIP-u/TIN-u. Zamień:
{% elseif order.Customer.TIN != '' -%}
na:
{% elseif order.Customer.TIN != null and order.Customer.TIN != '' -%}
j) W sekcji załączników zamówienia (kontener attachements-ui remarks-ui) zamień warunek otaczający. Zamień:
{% if config.Orders.AttachmentsEnabled -%}
na:
{% if config.Orders.AttachmentsEnabled and order.Restricted == false -%}
k) W sekcji zamówień powiązanych (kontener remarks-ui eshop-order-ui) zamień:
{% if order.RelatedOrders -%}
na:
{% if order.RelatedOrders and order.Restricted == false -%}

partials/customer-profile/complaints/complaint-form.html

W pliku partials/customer-profile/complaints/complaint-form.html wprowadź poniższe zmiany. a) W kontenerze amount-stepper-container-ui amount-stepper-container-lq (wewnątrz warunku {% if type != 'set-return' -%}) na samym początku dodaj etykietę widoczną tylko dla zwrotów:
{% unless complaint -%}
<span class="amount-stepper-label-ui">{{ translations.Quantity }}:</span>
{% endunless -%}
b) Bezpośrednio po zamknięciu kontenera amount-stepper-container-ui (po jego </div> i odpowiadającym {% endif -%}) dodaj sekcję wyboru sposobu zwrotu środków – widoczną tylko w formularzu zwrotu:
{% unless complaint -%}
<div class="refund-method-container-ui refund-method-container-js">
    <label class="label-ui" for="refundMethod">{{ translations.RefundMethod }} <span class="required-ui">*</span></label>
    <div>
        <span class="select-background-ui">
            <select id="refundMethod" class="refund-method-select-js" name="refundMethod" aria-label="{{ translations.RefundMethod }}">
                <option selected="selected" value="original">{{ translations.RefundAsPaid }} {% if order.Payment.Name and order.Payment.Name != "" -%} ({{ order.Payment.Name }}){% endif -%}</option>
                <option value="bank">{{ translations.RefundToBankAccount }}</option>
            </select>
        </span>
        <i class="ti-angle-down select-arrow-ui"></i>
    </div>
    <div class="bank-account-container-ui bank-account-container-js hidden-js">
        <label class="label-ui" for="bankAccountNumber">{{ translations.BankAccountNumber }} <span class="required-ui">*</span></label>
        <div>
            <input id="bankAccountNumber" disabled="disabled" name="bankAccountNumber" type="text" placeholder="{{ translations.BankAccountNumber }}" aria-label="{{ translations.BankAccountNumber }}" />
            <span class="error-ui validation-info-js validation-required-js hidden-js">{{ translations.RequiredField }}</span>
        </div>
    </div>
</div>
{% endunless -%}
c) Komunikat sukcesu wyświetlany po wysłaniu formularza ma być inny dla reklamacji, a inny dla zwrotu. Znajdź kontener <div class="success-message-js hidden-js"> wraz z jego dotychczasową zawartością (komunikat ComplaintAdded + successInfo):
<div class="success-message-js hidden-js">
    <div class="complaint-added-ui">
        <i class="va-mid-ui ti-check"></i>
        <span class="va-mid-ui line-height-1-ui">
            {{ translations.ComplaintAdded }}
        </span>
    </div>
    <div class="info-ui">{{ successInfo }}</div>
</div>
i zastąp go nową, rozszerzoną wersją z dwoma wariantami (reklamacja / zwrot):
<div class="success-message-js hidden-js">
    {% if complaint -%}
    <div class="complaint-added-ui">
        <i class="va-mid-ui ti-check"></i>
        <span class="va-mid-ui line-height-1-ui">
            {{ translations.ComplaintAdded }}
        </span>
    </div>
    <div class="info-ui">{{ successInfo }}</div>
    {% else -%}
    <div class="return-success-popup-ui">
        <div class="return-success-icon-ui">
            <i class="ti-check"></i>
        </div>
        <div class="return-success-title-ui">{{ translations.ReturnConfirmationTitle }}</div>
        <div class="return-success-desc-ui">{{ translations.ReturnConfirmationInfo }}</div>
        {% if order.Customer.Email and order.Customer.Email != "" -%}
        <div class="return-success-email-info-ui">
            <i class="ti-info-alt"></i>
            {{ translations.ReturnConfirmationEmailSent }} <strong>{{ order.Customer.Email }}</strong>
        </div>
        {% endif -%}
        <div class="return-success-steps-title-ui">{{ translations.NextSteps }}</div>
        <ol class="return-success-steps-ui">
            <li>{{ translations.ReturnStep1 }}</li>
            <li>{{ translations.ReturnStep2Address }}: {{ config.Shop.Address.Street }} {{ config.Shop.Address.StreetNo }}{% if config.Shop.Address.UnitNo and config.Shop.Address.UnitNo != "" -%}/{{ config.Shop.Address.UnitNo }}{% endif -%}, {{ config.Shop.Address.ZipCode }} {{ config.Shop.Address.City }}</li>
            <li>{{ translations.ReturnStep3 }}</li>
        </ol>
        <div class="return-success-actions-ui">
            <button class="btn-ui return-success-close-ui hide-container-js closing-modal-js" aria-label="{{ translations.Close }}">
                {{ translations.Close }}
            </button>
        </div>
    </div>
    {% endif -%}
</div>

4. Modyfikacje pliku js/init-ui2.js

Poniższe zmiany dotyczą pliku js/init-ui2.js (po edycji pamiętaj o zminifikowaniu go do init-ui2.min.js). a) Tuż po linii rejestrującej handler openComplaintForm:
js.delegate(document.body, 'click', '.open-complaint-form-js', openComplaintForm);
dodaj poniższy handler obsługujący przełączanie sposobu zwrotu środków – pokazuje on / ukrywa pole na numer konta bankowego:
js.delegate(document.body, 'change', '.refund-method-select-js', function() {
    const container = js.parents(this, 'refund-method-container-js');
    if(!container) return;
    const bankWrapper = container.getElementsByClassName('bank-account-container-js')[0];
    if(!bankWrapper) return;
    const bankInput = bankWrapper.querySelector('input[name="bankAccountNumber"]');
    const validationMsg = bankWrapper.getElementsByClassName('validation-required-js')[0];
    if(this.value === 'bank') {
        bankWrapper.classList.remove('hidden-js');
        if(bankInput) {
            bankInput.disabled = false;
            bankInput.required = true;
        }
    } else {
        bankWrapper.classList.add('hidden-js');
        if(bankInput) {
            bankInput.disabled = true;
            bankInput.required = false;
            bankInput.value = '';
            bankInput.classList.remove('validation-error-lq', 'validation-error-ui');
        }
        if(validationMsg) validationMsg.classList.add('hidden-js');
    }
});
b) W funkcji sendComplaint, bezpośrednio po pętli for (var i=0; i<dataFromHTML.length; i++) dokładającej pola do fd, dodaj fragment dołączający parametr qrHash z adresu URL przy wysyłaniu zwrotu:
if (form.find('input[name="__action"]').val() === 'Order/ReturnAdd') {
    var qrHash = new URLSearchParams(globalThis.location.search).get('qrHash');
    if (qrHash) {
        fd.append('qrHash', qrHash);
    }
}

5. Modyfikacje pliku scss/globals/_globals2.scss

W pliku scss/globals/_globals2.scss wewnątrz selektora opakowującego (tego, który zawiera m.in. .note-ui) dodaj poniższe reguły. Po zmianach pamiętaj o kompilacji SCSS – nie edytuj ręcznie wynikowych plików CSS. a) Style etykiety ilości oraz kontenera wyboru sposobu zwrotu środków (wstaw w sąsiedztwie istniejących reguł sekcji formularza reklamacji/zwrotu):
.amount-stepper-label-ui {
    margin-right: 10px;
    vertical-align: middle;
}

.refund-method-container-ui {
    margin-bottom: 20px;

    .bank-account-container-ui {
        margin-top: 10px;

        input {
            width: 100%;
        }
    }
}
b) Style ekranu sukcesu po wysłaniu zwrotu (ikona, tytuł, lista kolejnych kroków, sekcja z e-mailem i przyciskiem zamknięcia):
.return-success-popup-ui {
    padding: 30px 20px 20px;

    .return-success-icon-ui {
        width: 60px;
        height: 60px;
        border-radius: 50%;
        border: 2px solid #68a204;
        margin: 0 auto 20px;
        display: flex;
        align-items: center;
        justify-content: center;

        i {
            color: #68a204;
            font-size: 26px;
        }
    }

    .return-success-title-ui {
        font-size: 18px;
        font-weight: 500;
        text-align: center;
        margin-bottom: 10px;
    }

    .return-success-desc-ui {
        font-size: 14px;
        color: $primaryColorFont;
        text-align: center;
        margin-bottom: 20px;
    }

    .return-success-email-info-ui {
        background-color: $bgColor;
        border: 1px solid $lightBorderColor;
        padding: 12px;
        border-radius: 4px;
        font-size: 14px;
        margin-bottom: 20px;
        display: flex;
        align-items: flex-start;

        i {
            margin-right: 10px;
            color: $primaryColorFont;
            font-size: 16px;
            line-height: 1.4;
        }

        strong {
            display: block;
        }
    }

    .return-success-steps-title-ui {
        font-weight: 500;
        margin-bottom: 10px;
    }

    .return-success-steps-ui {
        padding-left: 20px;
        margin: 0 0 20px;
        font-size: 14px;

        li {
            margin-bottom: 8px;
            padding-left: 5px;
        }
    }

    .return-success-actions-ui {
        border-top: 1px solid $lightBorderColor;
        padding-top: 15px;
        text-align: right;

        .return-success-close-ui {
            padding: 10px 30px;
        }
    }
}
Po wprowadzeniu wszystkich powyższych zmian w szablonie Szafir pamiętaj o kompilacji oraz minifikacji plików js i scss, zgodnie z artykułem dostępnym pod linkiem https://pomoc.comarchesklep.pl/artykul/kompilacja-i-minifikacja-plikow/.

Szablon Topaz / One Page Shop

Zmiany opisane poniżej dotyczą szablonu Topaz. Szablon One Page Shop ma praktycznie identyczną strukturę – wszystkie modyfikacje dotyczą tych samych plików i mają tę samą zawartość. Wystarczy zastosować poniższą instrukcję w plikach szablonu OPS pod tymi samymi ścieżkami.

1. Tłumaczenia

W panelu administracyjnym sklepu dodaj nowe klucze tłumaczeń wymagane przez funkcjonalność szybkich zwrotów w szablonie Topaz / OPS. RestrictedOrderViewInfo - PL: Wybrane dane zamówienia zostały ukryte ze względów bezpieczeństwa. Możesz zwrócić produkty bez logowania. - EN: Some order details are hidden for security reasons. You can return products without signing in. - DE: Einige Bestelldetails wurden aus Sicherheitsgründen ausgeblendet. Sie können Produkte ohne Anmeldung zurücksenden. - FR: Certaines informations de la commande ont été masquées pour des raisons de sécurité. Vous pouvez retourner des produits sans vous connecter. Prf_ReturnPeriodInfo - PL: Zamówienie można zwrócić w ciągu {0} dni od daty dostawy. - EN: The order can be returned within {0} days from the delivery date. - DE: Die Bestellung kann innerhalb von {0} Tagen ab dem Lieferdatum zurückgegeben werden. - FR: La commande peut être retournée dans un délai de {0} jours à compter de la date de livraison. ComplaintSuccessTitle - PL: Gotowe! Przyjęliśmy Twoje zgłoszenie - EN: Done! We have received your request - DE: Fertig! Wir haben Ihre Meldung erhalten - FR: C'est fait ! Nous avons reçu votre demande ComplaintSuccessDescription - PL: Przygotuj paczkę i odeślij ją do nas – wszystkie szczegóły znajdziesz poniżej. - EN: Prepare the parcel and send it back to us – you will find all the details below. - DE: Bereiten Sie das Paket vor und senden Sie es an uns zurück – alle Details finden Sie unten. - FR: Préparez le colis et renvoyez-le-nous – vous trouverez tous les détails ci-dessous. ComplaintSuccessConfirmationSent - PL: Potwierdzenie zwrotu zostało wysłane na adres: - EN: The return confirmation has been sent to: - DE: Die Rückgabebestätigung wurde an folgende Adresse gesendet: - FR: La confirmation de retour a été envoyée à : ComplaintSuccessStepsTitle - PL: Następne kroki - EN: Next steps - DE: Nächste Schritte - FR: Étapes suivantes ComplaintSuccessStep1 - PL: Bezpiecznie zapakuj swoje produkty - EN: Pack your products securely - DE: Verpacken Sie Ihre Produkte sicher - FR: Emballez vos produits en toute sécurité ComplaintSuccessStep2 - PL: Wyślij paczkę na adres: - EN: Send the parcel to: - DE: Senden Sie das Paket an folgende Adresse: - FR: Envoyez le colis à l'adresse : ComplaintSuccessStep3 - PL: Pieniądze zwrócimy niezwłocznie po otrzymaniu i sprawdzeniu Twojej paczki. - EN: We will refund the money immediately after receiving and inspecting your parcel. - DE: Wir erstatten den Betrag unverzüglich nach Erhalt und Prüfung Ihres Pakets. - FR: Nous rembourserons l'argent immédiatement après réception et vérification de votre colis. ReturnInThreeSteps - PL: Zwróć towar w 3 krokach - EN: Return the product in 3 steps - DE: Geben Sie die Ware in 3 Schritten zurück - FR: Retournez la marchandise en 3 étapes ReturnWithoutReasonInfo - PL: Przysługuje Ci możliwość zwrotu bez podania przyczyny. - EN: You have the right to return the product without giving a reason. - DE: Sie haben das Recht, die Ware ohne Angabe von Gründen zurückzugeben. - FR: Vous avez le droit de retourner la marchandise sans donner de motif. OrEnterOrderNumber - PL: lub podaj numer zamówienia - EN: or enter the order number - DE: oder geben Sie die Bestellnummer ein - FR: ou entrez le numéro de commande FillForm - PL: Wypełnij formularz - EN: Fill out the form - DE: Füllen Sie das Formular aus - FR: Remplissez le formulaire ReturnOnline - PL: zwrotu online - EN: online return - DE: Online-Rückgabe - FR: retour en ligne SendParcel - PL: Wyślij paczkę - EN: Send the parcel - DE: Senden Sie das Paket - FR: Envoyez le colis SendParcelToOurAddress - PL: nadaj przesyłkę na nasz adres - EN: send the parcel to our address - DE: senden Sie das Paket an unsere Adresse - FR: envoyez le colis à notre adresse FastSimpleSecure - PL: Szybko, prosto i bezpiecznie. - EN: Fast, simple and secure. - DE: Schnell, einfach und sicher. - FR: Rapide, simple et sûr. ReadyForReturn - PL: Gotowy do zwrotu? - EN: Ready for return? - DE: Bereit zur Rückgabe? - FR: Prêt pour le retour ? ReadyForReturnInfo - PL: Kliknij poniżej, aby rozpocząć proces zwrotu. Przeprowadzimy Cię przez wszystkie kroki. - EN: Click below to start the return process. We will guide you through all the steps. - DE: Klicken Sie unten, um den Rückgabeprozess zu starten. Wir führen Sie durch alle Schritte. - FR: Cliquez ci-dessous pour commencer le processus de retour. Nous vous guiderons à chaque étape. StartReturn - PL: Rozpocznij zwrot - EN: Start return - DE: Rückgabe starten - FR: Commencer le retour ProductReturn - PL: Zwrot produktu - EN: Product return - DE: Produktrückgabe - FR: Retour du produit ProductReturnFormInfo - PL: Wprowadź dane zamówienia, aby zlokalizować zakup i rozpocząć proces zwrotu. Numer zamówienia znajdziesz w e-mailu z potwierdzeniem. - EN: Enter the order details to locate the purchase and start the return process. You will find the order number in the confirmation e-mail. - DE: Geben Sie die Bestelldaten ein, um den Kauf zu lokalisieren und den Rückgabeprozess zu starten. Die Bestellnummer finden Sie in der Bestätigungs-E-Mail. - FR: Saisissez les données de la commande pour localiser l'achat et démarrer le processus de retour. Vous trouverez le numéro de commande dans l'e-mail de confirmation. FindOrder - PL: Znajdź zamówienie - EN: Find order - DE: Bestellung finden - FR: Trouver la commande RefundLookupError - PL: Wystąpił błąd podczas wyszukiwania zamówienia. Spróbuj ponownie później. - EN: An error occurred while searching for the order. Please try again later. - DE: Fehler beim Suchen nach der Bestellung. Versuchen Sie es später erneut. - FR: Une erreur s'est produite lors de la recherche de la commande. Veuillez réessayer plus tard. LoginToSeeOrdersAndReturn - PL: aby zobaczyć swoje zamówienia i dokonać zwrotu. - EN: to see your orders and make a return. - DE: um Ihre Bestellungen zu sehen und eine Rückgabe zu machen. - FR: pour voir vos commandes et faire un retour. InvalidEmail - PL: Nieprawidłowy adres e-mail - EN: Invalid e-mail address - DE: Ungültige E-Mail-Adresse - FR: L'adresse e-mail est incorrecte. RefundMethod - PL: Sposób zwrotu środków - EN: Refund method - DE: Rückerstattungsmethode - FR: Mode de remboursement RefundAsPaid - PL: Zwrot na sposób płatności - EN: Refund to the original payment method - DE: Rückerstattung auf die ursprüngliche Zahlungsmethode - FR: Remboursement sur le mode de paiement initial RefundToBankAccount - PL: Zwrot na konto bankowe - EN: Refund to bank account - DE: Rückerstattung auf das Bankkonto - FR: Remboursement sur un compte bancaire

2. Nowa strona Szybkie zwroty

Funkcja szybkich zwrotów wymaga utworzenia dodatkowej strony statycznej refunds. Wykonaj poniższe kroki.

Plik refunds.html w katalogu głównym szablonu

W katalogu głównym szablonu utwórz nowy plik refunds.html z następującą zawartością:
{% extends '_layout.html' -%}
{% block pageContent -%}
{% include 'static-elements/refunds/refunds.html' -%}
{% endblock -%}

Plik static-elements/refunds/refunds.html

W folderze static-elements utwórz nowy katalog refunds, a w nim plik refunds.html:
{% include 'partials/common/breadcrumbs.html' -%}

<div class="container my-5 refunds-page-wrapper">

    <!-- Nagłówek główny -->
    <div class="text-center mb-5">
        <h1 class="mb-3">{{ translations.ReturnInThreeSteps }}</h1>
        <p class="lead text-muted">{{ translations.ReturnWithoutReasonInfo }}</p>
    </div>

    <!-- Sekcja 3 kroków (Siatka 3-kolumnowa) -->
    <div class="row text-center mb-5">
        <div class="col-md-4 mb-4">
            <div class="p-4 border rounded bg-light h-100">
                <h3 class="h5">1. {{ translations.Log_Login }}</h3>
                <p class="mb-0">{{ translations.OrEnterOrderNumber }}</p>
            </div>
        </div>
        <div class="col-md-4 mb-4">
            <div class="p-4 border rounded bg-light h-100">
                <h3 class="h5">2. {{ translations.FillForm }}</h3>
                <p class="mb-0">{{ translations.ReturnOnline }}</p>
            </div>
        </div>
        <div class="col-md-4 mb-4">
            <div class="p-4 border rounded bg-light h-100">
                <h3 class="h5">3. {{ translations.SendParcel }}</h3>
                <p class="mb-0">{{ translations.SendParcelToOurAddress }}</p>
            </div>
        </div>
    </div>

    <!-- Wyróżniony tekst -->
    <div class="text-center mb-5">
        <h2 class="text-success h3">{{ translations.FastSimpleSecure }}</h2>
    </div>

    <!-- Sekcja gotowości do zwrotu (Call to Action) -->
    <div class="text-center p-5 border rounded mb-5">
        <h2 class="h3">{{ translations.ReadyForReturn }}</h2>
        <p>{{ translations.ReadyForReturnInfo }}</p>

        <div class="mt-4">
            {% if customer.Authenticated -%}
                <a href="/Return/List" class="btn btn-primary btn-lg">{{ translations.StartReturn }}</a>
            {% else -%}
                <a href="/Return/List" class="btn btn-primary btn-lg">{{ translations.StartReturn }}</a>
            {% endif -%}
        </div>
    </div>

    <!-- Wyszukiwanie zamówienia dla niezalogowanych -->
    <div class="row justify-content-center mb-5">
        <div class="col-md-6 col-lg-5">
            <div class="text-center mb-4">
                <h3 class="h4">{{ translations.ProductReturn }}</h3>
                <p class="text-muted">{{ translations.ProductReturnFormInfo }}</p>
            </div>

            <form action="/Return/FindOrder" method="POST" class="border p-4 rounded bg-white">
                <div class="form-group mb-3">
                    <label class="font-weight-bold">{{ translations.Com_OrderNumber }}</label>
                    <input type="text" class="form-control" name="OrderNumber" required>
                </div>
                <div class="form-group mb-4">
                    <label class="font-weight-bold">{{ translations.EmailAddress }}</label>
                    <input type="email" class="form-control" name="Email" required>
                </div>
                <button type="submit" class="btn btn-dark w-100 btn-lg">{{ translations.FindOrder }}</button>
            </form>
        </div>
    </div>

    <!-- Zachęta do logowania dla niezalogowanych (Gości) -->
    {% if customer.Authenticated == false -%}
        <div class="text-center py-4 mt-4 border-top">
            <h4 class="h5">{{ translations.Reg_HaveAcc }}</h4>
            <p>{{ translations.LoginToSeeOrdersAndReturn }}</p>
            <!-- W Topaz przycisk logowania często otwiera popup ze zdefiniowaną klasą js-login-popup-trigger -->
            <button class="btn btn-outline-primary js-login-popup-trigger">{{ translations.Log_Login }}</button>
        </div>
        {% include 'partials/common/login-register-popup.html' -%}
    {% endif -%}

</div>

<!-- Globalny komponent Newslettera -->
{% if settings.newsletterOnFunctionalPages == 'yes' -%}
    {% include 'partials/newsletter-global.html' -%}
{% endif -%}

Pliki SCSS strony Szybkie zwroty

W folderze scss/static-elements utwórz nowy katalog refunds, a w nim trzy pliki: refunds-g.scss (style ogólne), refunds-d.scss (desktop) oraz refunds-m.scss (mobile). scss/static-elements/refunds/refunds-g.scss:
.refunds-container {
    box-sizing: border-box;
    margin: 0 auto;
    color: $primaryFontColor;
    background-color: $primaryPageBg;

    .refunds-view {
        display: flex;
        flex-direction: column;
        align-items: center;

        &.hidden-js {
            display: none;
        }
    }

    .refunds-intro {
        width: 100%;
        align-self: stretch;

        &__heading {
            margin: 0 0 16px;
            font-size: $mediumFontSize;
            font-weight: 600;
            line-height: 1.4;
            color: $primaryFontColor;
        }

        &__lead {
            margin: 0 0 16px;
            font-size: 16px;
            font-weight: 500;
            line-height: 1.5;
            color: $primaryFontColor;
        }

        &__hint {
            margin: 16px 0 0;
            font-size: $extraSmallFontSize;
            color: $secondaryFontColor;
        }
    }

    .refunds-steps {
        list-style: none;
        counter-reset: refund-step;
        margin: 0;
        padding: 0;
        display: flex;
        flex-direction: column;
        gap: 8px;

        &__item {
            counter-increment: refund-step;
            display: flex;
            align-items: center;
            gap: 12px;

            &::before {
                content: counter(refund-step);
                flex: 0 0 auto;
                width: 32px;
                height: 32px;
                border-radius: 50%;
                background-color: $primaryBtnBg;
                color: $primaryBtnFontColor;
                font-weight: 600;
                font-size: $smallFontSize;
                line-height: 1;
                display: inline-flex;
                align-items: center;
                justify-content: center;
            }
        }

        &__text {
            font-size: $smallFontSize;
            line-height: 1.5;
            color: $primaryFontColor;

            strong {
                font-weight: 600;
            }
        }
    }

    .refunds-card,
    .refunds-lookup {
        box-sizing: border-box;
        width: 100%;
        background-color: $primaryPageBg;
        border: 1px solid $borderColor;
        border-radius: 8px;
        display: flex;
        flex-direction: column;
        margin-left: auto;
        margin-right: auto;
    }

    .refunds-card {
        align-items: center;
        text-align: center;
        gap: 12px;

        &__heading {
            margin: 0;
            font-size: $bigFontSize;
            font-weight: 600;
            line-height: 1.3;
            color: $primaryFontColor;
        }

        &__text {
            margin: 0;
            font-size: 16px;
            line-height: 1.5;
            color: $secondaryFontColor;
        }

        &__btn {
            width: 100%;
            margin-top: 12px;
        }
    }

    .refund-form-js {
        .form__invalid-input {
            margin: 4px 0 0;
            font-size: $extraSmallFontSize;
            line-height: 16px;
            color: $messageErrorColor;
        }
    }

    .refunds-lookup {
        gap: 16px;

        &__heading {
            margin: 0;
            font-size: $bigFontSize;
            font-weight: 600;
            line-height: 1.3;
            color: $primaryFontColor;
        }

        &__lead {
            margin: 0;
            font-size: $smallFontSize;
            line-height: 1.5;
            color: $secondaryFontColor;
        }

        &__loginPrompt {
            margin: 8px 0 0;
            font-size: $smallFontSize;
            color: $primaryFontColor;
        }

        &__loginLink {
            color: $linkFontColor;
            font-weight: 600;
            text-decoration: underline;

            &:hover,
            &:focus {
                text-decoration: none;
            }
        }

        &__error {
            margin: 0;
            font-size: $smallFontSize;
            color: $messageErrorColor;
        }
    }
}

.loginRegister--login-only {
    .loginRegisterTabsContainer {
        display: none;
    }

    .registrationForm-js {
        display: none;
    }
}
scss/static-elements/refunds/refunds-d.scss:
@media screen and (min-width: 769px) {
    .refunds-container {
        max-width: 1400px;
        padding-top: 32px;
        padding-bottom: 64px;

        .refunds-view {
            gap: 32px;
        }

        .refunds-intro {
            &__heading {
                font-size: 20px;
            }

            &__lead {
                margin-bottom: 24px;
            }
        }

        .refunds-card,
        .refunds-lookup {
            max-width: 578px;
        }

        .refunds-card {
            padding: 40px;
        }

        .refunds-lookup {
            padding: 32px;
        }
    }
}
scss/static-elements/refunds/refunds-m.scss:
@media screen and (max-width: 768px) {
    .refunds-container {
        padding: 16px 3% 40px;

        .refunds-view {
            gap: 24px;
        }

        .refunds-intro {
            &__heading {
                font-size: 18px;
            }

            &__lead {
                font-size: $smallFontSize;
                margin-bottom: 16px;
            }
        }

        .refunds-steps {
            &__item {
                &::before {
                    width: 28px;
                    height: 28px;
                }
            }
        }

        .refunds-card {
            padding: 24px 16px;

            &__heading {
                font-size: $mediumFontSize;
            }

            &__text {
                font-size: $smallFontSize;
            }
        }

        .refunds-lookup {
            padding: 20px 16px;

            &__heading {
                font-size: $mediumFontSize;
            }
        }
    }
}

3. Modyfikacje istniejących plików HTML

partials/customer/order-content.html

W pliku partials/customer/order-content.html wykonaj poniższe zmiany. a) Bezpośrednio po otwarciu kontenera <div class="orderContent order-content-js"> dodaj dwa nowe bannery informacyjne (jeden o ukrytych danych zamówienia, drugi o terminie zwrotu, wraz z wyliczaniem flagi hasReturnableProduct):
{% if order.Restricted -%}
<div class="orderContent__returnInfo" role="note">
    <!-- TODO: ikona SVG informacyjna z klasą orderContent__returnInfo__icon -->
    {{ translations.RestrictedOrderViewInfo }}
</div>
{% endif -%}
{% assign hasReturnableProduct = false -%}
{% if config.Complaints.ReturnsEnabled -%}
{% for product in order.Products -%}
{% if product.CanReturn -%}
{% assign hasReturnableProduct = true -%}
{% break -%}
{% endif -%}
{% endfor -%}
{% endif -%}
{% if hasReturnableProduct -%}
<div class="orderContent__returnInfo" role="note">
    <!-- TODO: ikona SVG informacyjna z klasą orderContent__returnInfo__icon -->
    {{ translations.Prf_ReturnPeriodInfo | Format: config.Complaints.DaysToReturn }}
</div>
{% endif -%}
b) Kontener <div class="orderContent__docsToPrint">...</div> (z dokumentami do druku) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}, aby ukrywać go dla zamówień typu restricted. c) Cały dotychczasowy blok przycisków reklamacji/zwrotu (oparty na konstrukcji {% if ComplaintsEnabled and ReturnsEnabled %} ... {% elseif ComplaintsEnabled %} ... {% elseif ReturnsEnabled %} ... {% endif %} z jednym wspólnym przyciskiem) zamień na dwa niezależne warunki, dzięki czemu dla produktu uprawnionego zarówno do reklamacji, jak i do zwrotu, oba przyciski wyświetlają się obok siebie. Strukturę wewnątrz warunku {% if product.CanComplain or product.CanReturn -%} zastąp poniższym kodem:
{% if config.Complaints.ComplaintsEnabled == true and product.CanComplain -%}
<button class="orderContent__complainBtn orderContent__complainBtn--complaint showPopupBtn-js addDataToComplaintForm-js" data-popup-class="popupDialog" data-form-type="complaint" data-product-id="{{product.No}}" data-image-id="{{product.ImageId}}" data-imageext="{{product.Image.ExternalUrl}}" data-product-name="{{product.NameNoHtml | H}}" data-product-complain="{{product.CanComplain}}" data-product-count="{{ newProductQuantity }} {{ product.Unit }}" data-product-unit="{{ product.Unit }}" data-product-description="{{ productAttributes | Join: ' / ' | H }}" data-product-return="false" data-product-quantity="{{newProductQuantity}}" data-order-id="{{order.Id}}" data-order-date="{{order.Date | Date: 'yyyy-MM-dd'}}">
    <svg width="16" height="16">
        <use href="#comment-alt-regular"></use>
    </svg>
    {{translations.Prf_SendComplaint }}
</button>
{% endif -%}
{% if config.Complaints.ReturnsEnabled == true and product.CanReturn -%}
<button class="orderContent__complainBtn orderContent__complainBtn--return showPopupBtn-js addDataToComplaintForm-js" data-popup-class="popupDialog" data-form-type="return" data-product-id="{{product.No}}" data-image-id="{{product.ImageId}}" data-imageext="{{product.Image.ExternalUrl}}" data-product-name="{{product.NameNoHtml | H}}" data-product-complain="false" data-product-count="{{ newProductQuantity }} {{ product.Unit }}" data-product-unit="{{ product.Unit }}" data-product-description="{{ productAttributes | Join: ' / ' | H }}" data-product-return="{{product.CanReturn}}" data-product-quantity="{{newProductQuantity}}" data-order-id="{{order.Id}}" data-order-date="{{order.Date | Date: 'yyyy-MM-dd'}}">
    <svg width="16" height="16">
        <use href="#sync-regular"></use>
    </svg>
    {{ translations.Prf_OrderReturn }}
</button>
{% endif -%}
Kluczowe różnice w stosunku do poprzedniej wersji: każdy przycisk renderowany jest niezależnie (oba mogą wystąpić równocześnie), przyciski mają modyfikatory orderContent__complainBtn--complaint i orderContent__complainBtn--return, atrybut data-form-type (odczytywany w JS), w przycisku reklamacji wymuszone data-product-return="false", w przycisku zwrotu wymuszone data-product-complain="false", ikony 16x16 (#comment-alt-regular dla reklamacji, #sync-regular dla zwrotu), a etykieta przycisku zawiera już tylko jedno tłumaczenie. d) W pozostałych miejscach z przyciskami reklamacji/zwrotu (sekcje, w których nie zmieniają się klasy i ikony) dodaj jedynie dwa nowe atrybuty:
data-product-unit="{{ product.Unit }}"
data-product-description="{{ productAttributes | Join: ' / ' | H }}"
e) W sekcji załączników zamówienia zamień:
{% if order.Attachments[0] -%}
na:
{% if order.Attachments[0] and order.Restricted == false -%}
f) W kontenerze <div class="orderContent__recipient orderContent__infoBox"> zamień wyświetlanie adresu dostawy:
<span class="orderContent__lightText">{{ order.Customer.DeliveryAddress.Street }} {{ order.Customer.DeliveryAddress.StreetNo }} / {{ order.Customer.DeliveryAddress.UnitNo }}</span>
na:
<span class="orderContent__lightText">{{ order.Customer.DeliveryAddress.Street }} {{ order.Customer.DeliveryAddress.StreetNo }}{% if order.Customer.DeliveryAddress.UnitNo != null and order.Customer.DeliveryAddress.UnitNo != '' -%} / {{ order.Customer.DeliveryAddress.UnitNo }}{% endif -%}</span>
g) Sekcję z przyciskami akcji zamówienia (orderCancel-js, ponowienie płatności itd.) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}. Wstaw {% unless order.Restricted -%} bezpośrednio przed warunkiem {% if order.CanRestorePayment -%}, a {% endunless -%} po zamykającym {% endif -%} bloku z przyciskiem anulowania zamówienia.

partials/common/complaint-popup.html

Plik partials/common/complaint-popup.html wymaga gruntownej przebudowy. Usuwamy z niego radiowe przyciski wyboru "reklamacja/zwrot", a typ formularza jest teraz przekazywany z zewnątrz przez parametr __include. Sterowanie ilością zostało przeniesione do kafelka z produktem (z etykietą i obsługą wariantu statycznego, gdy zostaje tylko 1 sztuka). W formularzu zwrotu zamiast samego pola numeru konta pojawia się sekcja wyboru sposobu zwrotu środków (refundMethod-js) – z opcją „zwrot na sposób płatności" (domyślna) lub „zwrot na konto bankowe". Pole numeru konta jest domyślnie ukryte i disabled; pokazuje się dopiero po wybraniu opcji „konto bankowe" (obsługa w JS w metodzie changeRefundMethod). Tytuł, kafelek produktu i formularz oznaczone są dodatkową klasą complain-form-view-js, dzięki czemu po pomyślnym wysłaniu formularza można je ukryć i wyświetlić ekran sukcesu (complain-success-view-js). Zastąp całą zawartość pliku poniższym kodem:
{% if hideContent -%}
{% else -%}
{% assign formType = include -%}
{% assign isReturn = false -%}
{% if formType == 'return' -%}
{% assign isReturn = true -%}
{% endif -%}
<div class="popupDialog popupDialog__complain popupDialog-js">
    {% assign order = customer-profile.Order -%}
    <div class="popupDialog__wrapper">
        <button class="popupDialog__closeBtn closePopupBtn-js">
            <!-- TODO: ikona SVG zamknięcia – jak w pozostałych popupach szablonu -->
        </button>
        <span class="popupDialog__title complain-form-view-js">
            {% if isReturn -%}
            {{ translations.Prf_OrderReturn }}
            {% else -%}
            {{ translations.Prf_SendComplaint }}
            {% endif -%}
        </span>
        <div class="complain__product complain-form-view-js">
            <figure><img class="productImage-js" alt="product_image" /></figure>
            <div class="complain__productInfo">
                <!-- TODO: zweryfikuj z szablonem elementy z klasami productName-js i productDescription-js (nazwa i opis produktu) -->
                <span class="productName-js"></span>
                <span class="productDescription-js"></span>
                <div class="complain__quantity">
                    <label class="complain__quantityLabel" for="complaint-quantity">{{translations.Com_Quantity}}:</label>
                    <div class="complain__quantityControl min-js quantityControl-js">
                        <button class="button-minus-add-product" type="button" aria-label="{{translations.ButtonMinusAddProduct}}" data-field="quantity">
                            <!-- TODO: ikona SVG minus -->
                        </button>
                        <input id="complaint-quantity" class="quantity-field quantity__field-js" max="" min="1" name="quantity" type="number" value="1" data-decimal="false" />
                        <button class="button-plus-add-product" type="button" aria-label="{{ translations.ButtonPlusAddProduct }}" data-field="quantity">
                            <!-- TODO: ikona SVG plus -->
                        </button>
                    </div>
                    <span class="quantityStatic-js hidden"></span>
                    <span class="productUnit-js"></span>
                </div>
            </div>
        </div>
        <div class="form complain__form inputs-container-js complain-form-view-js" data-success-info="{{ translations.ReportSuccessInfo }}">
            <input name="__action" type="hidden" value="{% if isReturn -%}Order/ReturnAdd{% else -%}Order/ComplaintAdd{% endif -%}" />
            <strong>{{ translations.ReportDetails }}</strong>
            {% unless isReturn -%}
            <div class="form__input-wrapper">
                {% if config.Complaints.Defects <> null -%}
                {% assign defectsSize = config.Complaints.Defects | Size -%}
                <label class="hidden" for="defectId">{{ translations.ChooseComplaintCause }}</label>
                <select class="form__input-value form__input-value-js {% if settings.themeName == 'Dark' -%} darkTheme {% endif -%}" name="defectId" required="">
                    {% if defectsSize > 1 -%}
                    <option value="-1">* {{translations.ChooseComplaintCause}}</option>
                    {% endif -%}
                    {% for def in config.Complaints.Defects -%}
                    <option value="{{def.Id}}">{{def.Name}}</option>
                    {% endfor -%}
                </select>
                {% endif -%}
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            <div class="form__input-wrapper">
                <span class="form__icons">
                    <!-- TODO: ikona SVG kalendarza -->
                </span>
                <input id="defectDate" class="form__input-value form__icon_padding form__input-value-js orderDate-js" max="{{config.Now | Date: 'yyyy-MM-dd'}}" min="{{order.Date | Date: 'yyyy-MM-dd'}}" name="defectDate" type="date" value="{{config.Now | Date: 'yyyy-MM-dd'}}" placeholder="yyyy-MM-dd" />
                <label class="form__input-info" for="defectDate">* {{translations.Prf_DefectDate}}</label>
            </div>
            <div class="form__input-wrapper">
                {% if config.Complaints.Requests <> null -%}
                {% assign requestsSize = config.Complaints.Requests | Size -%}
                <label class="hidden" for="requestId">{{ translations.Prf_ComplainRequest }}</label>
                <select class="form__input-value form__input-value-js {% if settings.themeName == 'Dark' -%} darkTheme {% endif -%}" name="requestId" required="">
                    {% if requestsSize > 1 -%}
                    <option value="-1">* {{translations.Prf_ComplainRequest}}</option>
                    {% endif -%}
                    {% for req in config.Complaints.Requests -%}
                    <option value="{{req.Id}}">{{req.Name}}</option>
                    {% endfor -%}
                </select>
                {% endif -%}
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            {% else -%}
            {% assign returnTypes = config.Complaints.Returns | Size -%}
            {% if returnTypes > 1 -%}
            <div class="form__input-wrapper">
                <label class="hidden" for="returnId">{{ translations.ChooseReturn }}</label>
                <select class="form__input-value form__input-value-js {% if settings.themeName == 'Dark' -%} darkTheme {% endif -%}" name="returnId" required="">
                    <option value="-1">* {{translations.ChooseReturn}}</option>
                    {% for return in config.Complaints.Returns -%}
                    <option value="{{return.Id}}">{{return.Name}}</option>
                    {% endfor -%}
                </select>
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            {% endif %}
            {% endunless -%}
            <div class="form__input-wrapper returnInputWrapper-js refundMethodWrapper-js">
                <label class="complain__sectionLabel" for="refundMethod">{{ translations.RefundMethod }}</label>
                <select id="refundMethod" class="form__input-value form__input-value-js refundMethod-js {% if settings.themeName == 'Dark' -%}darkTheme{% endif -%}" name="refundMethod">
                    <option value="payment">{{ translations.RefundAsPaid }}{% if order.Payment.Name != null and order.Payment.Name != '' %} ({{ order.Payment.Name }}){% endif %}</option>
                    <option value="account">{{ translations.RefundToBankAccount }}</option>
                </select>
            </div>
            <div class="form__input-wrapper accountNumberWrapper-js" style="display: none;">
                <input id="accountNumber" class="form__input-value form__input-value-js" disabled="disabled" maxlength="50" name="accountNumber" type="text" />
                <label class="form__input-info form__input-info-js" for="accountNumber">{{translations.Crt_BankAccountNumber}}</label>
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            <div class="form__input-wrapper">
                {{translations.Prf_AdditionalInfo}}
                <textarea class="form__input-value" name="message" aria-label="{{ translations.Prf_AdditionalInfo }}"></textarea>
            </div>
            <div class="form__input-wrapper">
                <span class="form__requiredFields--info">* {{ translations.Com_RequiredFields }}</span>
            </div>
            {% if config.Complaints.AttachmentsEnabled -%}
            <div class="form__input-wrapper attachementsInputWrapper" data-not-added-info="{{translations.AttachementsNotAdded}}">
                <button class="form__attachementsLabel form__attachementsLabel--btn form__attachementsLabel-js" data-page="complaints">
                    <!-- TODO: ikona SVG dodawania załącznika -->
                    {{ translations.AddAttachment }}
                </button>
                {% capture maxSize -%}{{config.Complaints.AttachmentMaxSize | DividedBy: 1024}}KB{% endcapture -%}
                {% for i in (1..config.Complaints.AttachmentsMaxCount) -%}
                <div class="form__attachement-input-container form__attachement-input-container-attachments form__attachement-input-container--hidden">
                    <!-- TODO: ikona SVG oraz element z nazwą pliku (form__attachement-input-container-attachments__text) -->
                    <input class="addAttachementInComplaint-js" accept="{{ config.Complaints.AttachmentExtensions }}" name="file" type="file" aria-label="{{ translations.AddAttachment }}" data-file-size="{{ config.Complaints.AttachmentMaxSize }}" data-size-exceeded="{{ translations.Com_FileSizeExceeded | Format: maxSize }}" data-invalid-file="{{ translations.Com_InvalidFile | Format: config.Complaints.AttachmentExtensions }}" />
                    <button class="form__clear-attachement-input clearFileInput-js" style="display: none;">
                        <!-- TODO: ikona SVG usuwania załącznika -->
                    </button>
                </div>
                {% endfor -%}
            </div>
            {% endif -%}
            <input class="productId-js" name="no" type="hidden" value="" />
            <input class="orderId-js" name="orderId" type="hidden" value="{{order.Id}}" />
            <button class="primary-action-button orderComplaintOrReturnAdd-js" type="button" data-id="{{order.Id}}">{{translations.Report}}</button>
        </div>
        <div class="complain__successView complain-success-view-js hidden">
            <div class="complain__successIcon">
                <!-- TODO: ikona SVG potwierdzenia (zielony "check", klasa svgIcon) -->
            </div>
            <h2 class="complain__successTitle">{{ translations.ComplaintSuccessTitle }}</h2>
            <p class="complain__successDescription">{{ translations.ComplaintSuccessDescription }}</p>
            <div class="complain__successInfoBox">
                <!-- TODO: ikona SVG informacyjna (klasa svgIcon) -->
                <span>{{ translations.ComplaintSuccessConfirmationSent }}
                    <strong>{{ order.Customer.Email }}</strong>
                </span>
            </div>
            <h3 class="complain__successStepsTitle">{{ translations.ComplaintSuccessStepsTitle }}</h3>
            <ol class="complain__successSteps">
                <li>{{ translations.ComplaintSuccessStep1 }}</li>
                <li>{{ translations.ComplaintSuccessStep2 }} {{ config.Shop.Address.Street }} {{ config.Shop.Address.StreetNo }}{% if config.Shop.Address.UnitNo != '' %}/{{ config.Shop.Address.UnitNo }}{% endif %}, {{ config.Shop.Address.ZipCode }} {{ config.Shop.Address.City }}</li>
                <li>{{ translations.ComplaintSuccessStep3 }}</li>
            </ol>
            <div class="complain__successActions">
                <button class="primary-action-button closePopupBtn-js" type="button">{{ translations.BtnClose }}</button>
            </div>
        </div>
    </div>
</div>
{% endif -%}

4. Modyfikacje pliku js/layout1.js

Poniższe zmiany dotyczą pliku js/layout1.js. Po edycji pamiętaj o zminifikowaniu pliku do layout1.min.js. a) W obiekcie customerProfile usuń całą metodę setComplainReturnRadioButtons (radiowy przełącznik reklamacja/zwrot nie jest już potrzebny – typ formularza jest teraz przekazywany przy otwieraniu popupu). b) W tym samym obiekcie zastąp całą metodę addDataToComplaintForm nową implementacją, która odczytuje typ formularza z atrybutu data-form-type przycisku i przekazuje go do szablonu jako parametr __include:
addDataToComplaintForm: function (e) {
    const template = 'partials/common/complaint-popup.html';
    const data = e.currentTarget;
    const formType = data.dataset.formType === 'return' ? 'return' : 'complaint';

    $.get('', {__template: template, __include: "'" + formType + "'"}, function(result) {
        $('.customer__content-js').append(result.template);
        $('.popupDialog__complain').show();
        $('body').addClass('customerProfileNoScroll');

        const image = $('.productImage-js');
        const productName = $('.productName-js');
        const inputId = $('.productId-js');
        const productQuantity = $('.quantity__field-js');
        const quantityControl = $('.quantityControl-js');
        const quantityStatic = $('.quantityStatic-js');
        const productUnit = $('.productUnit-js');
        const productDescription = $('.productDescription-js');

        const orderId = $('.orderId-js');
        const buttonOrderId = $('.orderComplaintOrReturnAdd-js');
        const orderDate = $('.orderDate-js');

        productName.text(data.dataset.productName);
        productUnit.text(data.dataset.productUnit || '');
        productDescription.text(data.dataset.productDescription || '');
        inputId.val(data.dataset.productId);
        productQuantity.attr('max', data.dataset.productQuantity);

        if (parseInt(data.dataset.productQuantity, 10) <= 1) {
            quantityControl.addClass('hidden');
            quantityStatic.text(data.dataset.productQuantity).removeClass('hidden');
        } else {
            quantityControl.removeClass('hidden');
            quantityStatic.addClass('hidden');
        }

        orderId.val(data.dataset.orderId);
        buttonOrderId.attr('data-id', data.dataset.orderId);
        orderDate.attr('min', data.dataset.orderDate);

        if (data.dataset.imageext != null && data.dataset.imageext != "") {
            image.attr('src', data.dataset.imageext);
        } else if (data.dataset.imageId != null && data.dataset.imageId != "") {
            image.attr('src', '/Image/?id=' + data.dataset.imageId);
        }

        if (image.attr('src') === '' || image.attr('src') == null) {
            image.closest('figure').addClass('noImage-js');
        }

        setTimeout(function() {
            app.activateFocusTrap('.popupDialog__complain', e.target);
        }, 200);
    });
},
c) Zastąp metodę changeReturnComplaintForm nową wersją (obsługuje również pole numeru konta i wywołuje changeRefundMethod po przełączeniu na zwrot):
changeReturnComplaintForm: function (e) {
    const form = $(e.currentTarget).closest('.inputs-container-js');
    const complaintInputs = form.find('.complaintInputWrapper-js');
    const returnInputs = form.find('.returnInputWrapper-js');
    const accountWrapper = form.find('.accountNumberWrapper-js');
    const accountInput = accountWrapper.find('input[name="accountNumber"]');

    if ($(e.currentTarget).is(':checked') && e.currentTarget.dataset.name === 'complaint' ) {
        $.each(complaintInputs, function (index, value) {
            $(value).find('input, select').first().removeAttr('disabled');
            $(value).show(300);
        });
        returnInputs.each(function () {
            $(this).find('input, select').first().attr('disabled', 'true');
        });
        returnInputs.hide(300);
        accountInput.removeAttr('disabled').removeAttr('required').removeClass('form__validation-error-js');
        accountWrapper.find('.form__validation-required-js').hide();
        accountWrapper.show(300);
    }

    if ($(e.currentTarget).is(':checked') && e.currentTarget.dataset.name === 'return' ) {
        $.each(complaintInputs, function (index, value) {
            $(value).find('input, select').first().attr('disabled', 'true');
            $(value).hide(300);
        });
        returnInputs.each(function () {
            $(this).find('input, select').first().removeAttr('disabled');
        });
        returnInputs.show(300);
        customerProfile.changeRefundMethod(form);
    }
},
d) Tuż za metodą changeReturnComplaintForm dodaj nową metodę changeRefundMethod (pokazuje / ukrywa pole numeru konta bankowego na podstawie wybranego sposobu zwrotu):
changeRefundMethod: function (formOrEvent) {
    const form = formOrEvent && formOrEvent.currentTarget
        ? $(formOrEvent.currentTarget).closest('.inputs-container-js')
        : $(formOrEvent);
    const select = form.find('.refundMethod-js');
    const accountWrapper = form.find('.accountNumberWrapper-js');
    const accountInput = accountWrapper.find('input[name="accountNumber"]');

    if (select.val() === 'account') {
        accountInput.removeAttr('disabled').attr('required', 'required');
        accountWrapper.show(300);
    } else {
        accountInput.attr('disabled', 'true').removeAttr('required').removeClass('form__validation-error-js');
        accountWrapper.find('.form__validation-required-js').hide();
        accountWrapper.hide(300);
    }
},
e) W metodzie wysyłającej formularz reklamacji/zwrotu (gdzie znajduje się pętla for (let i=0; i<dataFromHTML.length; i++)) zaraz po pętli dodaj fragment dołączający parametr qrHash z URL-a przy wysyłaniu zwrotu:
if (form.find('input[name="__action"]').val() === 'Order/ReturnAdd') {
    const qrHash = new URLSearchParams(globalThis.location.search).get('qrHash');
    if (qrHash) {
        fd.append('qrHash', qrHash);
    }
}
f) W tej samej metodzie, w callbacku success po pomyślnym wysłaniu, zamień fragment:
if (data.action.Result) {
    const message = form.data('success-info');
    app.showTemporaryPopup(message, 'success', '', 8000);
    $('.clearFileInput-js').hide();
    app.hidePopup(e);
    sessionStorage.removeItem('complains');
    sessionStorage.removeItem('order' + (e.currentTarget).dataset.id);
    $('.order' + (e.currentTarget).dataset.id).remove();
    $('.popupDialog__complain').remove();
    $('body').removeClass('customerProfileNoScroll');
    customerProfile.showOrderDetails(e);
}
na:
if (data.action.Result) {
    $('.clearFileInput-js').hide();
    sessionStorage.removeItem('complains');
    sessionStorage.removeItem('order' + (e.currentTarget).dataset.id);
    const popup = $(e.currentTarget).closest('.popupDialog__complain');
    popup.find('.complain-form-view-js').addClass('hidden');
    popup.find('.complain-success-view-js').removeClass('hidden');
    popup.find('.popupDialog__wrapper').scrollTop(0);
}
g) W sekcji rejestracji zdarzeń profilu klienta (tam, gdzie znajdują się m.in. mainSection.on('change', '.radioComplaint-js, .radioReturn-js', ...)) tuż za istniejącym handlerem zmiany typu formularza dopisz nowy handler:
mainSection.on('change', '.refundMethod-js', function (e) {
    customerProfile.changeRefundMethod(e);
});
h) Znajdź globalny handler obsługujący keydown z selektorem zaczynającym się od .radioReturn-js label, .radioComplaint-js label, ... i usuń z niego dwa pierwsze selektory (po zmianie zaczyna się od .showHideSection-js):
// PRZED
$('body').on('keydown', '.radioReturn-js label, .radioComplaint-js label, .showHideSection-js, .checkBoxes__container label, .customerPagination__form-js, .discountsDetails-js, .customer-focus, .customer__menuActivate-js', function(e) { ... });

// PO
$('body').on('keydown', '.showHideSection-js, .checkBoxes__container label, .customerPagination__form-js, .discountsDetails-js, .customer-focus, .customer__menuActivate-js', function(e) { ... });
i) W obiekcie app w pliku js/layout1.js obsłuż przekierowanie po zalogowaniu z parametrem #login-redirect= (używanym przez stronę szybkich zwrotów). W bloku rejestracji/logowania, w miejscu gdzie obsługiwany jest hash #back-to-cart, tuż po nim dodaj:
if (globalThis.location.hash.startsWith('#login-redirect=')) {
    url = globalThis.location.hash.slice('#login-redirect='.length);
}
Następnie w handlerze sukcesu logowania, gdzie znajduje się sprawdzenie window.location.hash.includes('#back-to-cart') wraz z przekierowaniem, tuż za nim dodaj analogiczny blok przekierowujący w przypadku #login-redirect=:
if (globalThis.location.hash.startsWith('#login-redirect=')) {
    globalThis.location.assign(globalThis.location.hash.slice('#login-redirect='.length));
    return;
}

5. Modyfikacje plików SCSS profilu klienta

Poniższe style należy dodać do plików scss/static-elements/customer-profile/customer-profile-g.scss (style ogólne), customer-profile-d.scss (desktop) i customer-profile-m.scss (mobile). Po zmianach pamiętaj o kompilacji SCSS – nie edytuj ręcznie wynikowych plików CSS.

Plik customer-profile-g.scss

a) Wewnątrz selektora opakowującego (tam, gdzie znajdują się istniejące reguły .orderContent__complainBtn) dodaj nowe reguły dla banera informacyjnego oraz kontenera grupującego przyciski reklamacji/zwrotu:
.orderContent__returnInfo {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 16px 0 24px;
    padding: 12px 16px;
    background-color: color-mix(in srgb, #{$linkFontColor} 4%, transparent);
    border: 1px solid color-mix(in srgb, #{$linkFontColor} 20%, transparent);
    border-radius: 4px;
    font-size: 13px;
    line-height: 1.4;
    color: $primaryFontColor;

    &__icon {
        flex-shrink: 0;
        fill: $linkFontColor;
    }
}

.orderContent__complainBtns {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin: 16px 0 4px;
}
b) Następnie zastąp istniejące style .orderContent__complainBtn nowym wyglądem przycisku (z tłem, obramowaniem i hoverem):
.orderContent__complainBtn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 16px 0 4px;
    padding: 6px 12px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 4px;
    color: $linkFontColor;
    fill: $linkFontColor;
    font-size: 13px;
    font-weight: 500;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 180ms, border-color 180ms;

    .orderContent__complainBtns & {
        margin: 0;
    }

    svg {
        margin: 0;
        flex-shrink: 0;
    }

    &:hover,
    &:focus-visible {
        background-color: color-mix(in srgb, #{$linkFontColor} 6%, transparent);
        border-color: color-mix(in srgb, #{$linkFontColor} 25%, transparent);
        outline: none;
    }
}
c) Dodaj style etykiety sekcji oraz kontenera sposobu zwrotu w popupie reklamacji:
.complain__sectionLabel {
    display: block;
    margin-bottom: 8px;
    font-size: 14px;
    font-weight: 500;
    color: $primaryFontColor;
}

.refundMethodWrapper-js {
    margin-bottom: 18px;
}
d) Dodaj kompletne style ekranu sukcesu zwrotu (m.in. ikona, tytuł, lista kolejnych kroków, sekcja z e-mailem i przyciskiem zamknięcia):
.complain__successView {
    text-align: center;
    padding: 16px 0 0;
}

.complain__successIcon {
    display: flex;
    justify-content: center;
    margin: 8px 0 20px;

    .svgIcon {
        width: 64px;
        height: 64px;
        fill: #2d8c4a;
    }
}

.complain__successTitle {
    font-size: 20px;
    font-weight: 600;
    line-height: 1.3;
    margin: 0 0 12px;
    color: $primaryFontColor;
}

.complain__successDescription {
    font-size: 14px;
    line-height: 1.5;
    color: $primaryFontColor;
    margin: 0 0 20px;
}

.complain__successInfoBox {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 14px;
    margin: 0 0 24px;
    border: 1px solid #cfdcef;
    background-color: #f0f5fc;
    border-radius: 6px;
    text-align: left;

    .svgIcon {
        flex-shrink: 0;
        margin-top: 2px;
        fill: #3a6ea5;
    }

    span {
        font-size: 13px;
        line-height: 1.5;
        color: $primaryFontColor;
    }

    strong {
        display: block;
        font-weight: 600;
        margin-top: 2px;
        word-break: break-all;
    }
}

.complain__successStepsTitle {
    font-size: 15px;
    font-weight: 600;
    margin: 0 0 12px;
    text-align: left;
    color: $primaryFontColor;
}

.complain__successSteps {
    margin: 0 0 24px;
    padding-left: 22px;
    text-align: left;

    li {
        font-size: 14px;
        line-height: 1.6;
        margin-bottom: 6px;
        color: $primaryFontColor;
    }
}

.complain__successActions {
    display: flex;
    justify-content: flex-end;
    padding-top: 16px;
    padding-bottom: 30px;
    margin-top: 8px;
    border-top: 1px solid $borderColor;

    .primary-action-button {
        min-width: 140px;
        margin: 0;
    }

    @media screen and (max-width: 599px) {
        .primary-action-button {
            width: 100%;
            min-width: 0;
        }
    }
}
e) Zaktualizuj style załączników – znajdź istniejące reguły .form__clear-attachement-input oraz reguły z position: absolute; top: 11px; i zastąp je nowymi (które ustawiają załączniki w układzie statycznym z poprawnym overflowem i przyciskiem usuwania):
.form__attachement-input-container-attachments__text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.form__attachement-input-container--hidden,
.form__attachement-input-container-attachments.form__attachement-input-container--hidden {
    display: none;
}

.form__clear-attachement-input {
    position: static;
    background: transparent;
    border: none;
    padding: 2px 4px;
    margin: 0 0 0 4px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;

    svg {
        fill: $linkFontColor;
        transition: opacity 200ms;
    }

    &:hover svg {
        opacity: 0.7;
    }
}

Plik customer-profile-d.scss

Wewnątrz wrappera @media screen and (min-width: 769px) zamień istniejące style przycisku reklamacji:
.customer .orderContent__complainBtn {
    position: absolute;
    bottom: 8px;
}
na poniższy fragment (dodaje pozycjonowanie kontenera grupującego przyciski oraz osobny selektor dla pojedynczych przycisków w wierszu produktu):
.customer .orderContent__complainBtns {
    position: absolute;
    bottom: 8px;
    right: 0;
    margin: 0;
}

.customer .orderContent__productDetails > .orderContent__complainBtn {
    position: absolute;
    bottom: 8px;
    right: 0;
    margin: 0;
}

Plik customer-profile-m.scss

W obrębie selektora .customer zamień istniejący media-query @media screen and (max-width: 359px) wraz z jego wnętrzem na rozszerzoną wersję (układająca przyciski reklamacji/zwrotu pionowo na szerokościach do 450px):
@media screen and (max-width: 450px) {
    .customer__orderContent .orderContent__productsRow {
        max-height: none;
    }

    .customer__orderContent .orderContent__productDetails {
        display: flex;
        flex-direction: column;
        align-items: stretch;
    }

    .customer__orderContent .orderContent__complainBtns {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 8px;
        width: 100%;
        margin: 12px 0 4px;
        padding-top: 12px;
        border-top: 1px solid $borderColor;
    }

    .customer__orderContent .orderContent__complainBtn {
        display: flex;
        width: 100%;
        justify-content: center;
        padding: 10px 12px;
        margin: 12px 0 4px;
        border-color: color-mix(in srgb, #{$linkFontColor} 25%, transparent);
    }

    .customer__orderContent .orderContent__complainBtns .orderContent__complainBtn {
        margin: 0;
    }
}

6. Szablon One Page Shop

Szablon One Page Shop ma praktycznie identyczną strukturę plików jak Topaz. Wszystkie powyższe modyfikacje (tłumaczenia, nowa strona zwrotów, edycje plików partials/common/complaint-popup.html oraz partials/customer/order-content.html, zmiany w js/layout1.js oraz w plikach SCSS profilu klienta i strony zwrotów) wykonaj 1:1 w plikach szablonu OPS pod tymi samymi ścieżkami. Treść kodu jest taka sama, ścieżki plików są takie same – instrukcja dla Topaza w pełni stosuje się również do One Page Shopa. Po wprowadzeniu wszystkich powyższych zmian w szablonie Topaz (oraz One Page Shop) pamiętaj o kompilacji oraz minifikacji plików js i scss, zgodnie z artykułem dostępnym pod linkiem https://pomoc.comarchesklep.pl/artykul/kompilacja-i-minifikacja-plikow/.
Wskazówka
Potrzebujesz pomocy lub masz pytania? Skontaktuj się z nami poprzez portal asysta.comarch.pl.

Graficzna prezentacja atrybutów na karcie produktu oraz na liście towarów w szablonie Rubin

Wstęp

Funkcja umożliwia prezentację atrybutów w formie kolorów, miniatur oraz kafelków z tekstem. Dotyczy ona towarów z wariantami. Chcesz, aby w Twoim e-sklepie atrybuty były prezentowane graficznie? Pokażemy Ci, jak w prosty sposób zmienić ustawienia, aby to umożliwić.

Konfiguracja atrybutów graficznych

Aby skonfigurować atrybuty graficzne, przejdź w Panelu administracyjnym do opcji Wygląd sklepu > Ustawienia, a następnie do sekcji Lista towarów > Strona główna. W tym miejscu możesz wybrać sposób prezentacji atrybutów: jako kolory, miniatury zdjęć lub warianty towarów.
Wskazówka
Pamiętaj, aby wprowadzone zmiany były widoczne w e-Sklepie należy je Zapisać i Opublikować.
Domyślnie parametr dotyczący graficznej prezentacji wariantów towarów jest ustawiony na „Nie”. W takiej sytuacji produkty w szablonie Rubin wyświetlane są w formie tabelarycznej.

Wariant - Kolory

Po wybraniu wariantu Kolory, w panelu administracyjnym automatycznie pojawi się nowe okno z nazwami kolorów oraz ich graficznymi odpowiednikami w notacji heksadecymalnej. Jest to część konfiguracji tej funkcji, która umożliwia mapowanie kolorów. Funkcja ta działa na podstawie atrybutów przypisanych do towarów w systemie ERP.

Domyślnie kolory takie jak niebieski, żółty czy fioletowy są mapowane automatycznie, więc uzupełnianie tego okna nie jest konieczne. Jednak jeśli atrybut zawiera niestandardowe nazwy kolorów, np. „miętowy”, należy ręcznie przypisać odpowiedni kolor w poniższym polu.

Przykładowa konfiguracja wariantu - Kolory

W systemie ERP stwórz atrybut o nazwie Kolor w formacie lista, a następnie udostępnij go do Comarch e-Sklep. Wypełnij pozycje listy, wpisując nazwy kolorów, np. żółty, fioletowy, pomarańczowy itd. Następnie przypisz utworzony atrybut do odpowiedniego towaru, który zostanie przesłany do e-Sklepu. Podczas przypisywania tego atrybutu do towaru pozostaw pole „Wartość” puste, aby umożliwić wybór wariantów kolorystycznych. Po zakończeniu powyższych kroków przeprowadź synchronizację z e-Sklepem.

Prezentacja wariantu Kolory na stronie e-Sklepu

Na liście towarów: Na szczegółach towarów - dla wszystkich wariantów

Wariant - Miniatury (tylko dla towarów zgrupowanych - "fantomów")

Wybór wariantu miniatury umożliwia graficzną prezentację wariantów towarów za pomocą pierwszego zdjęcia każdego towaru zgrupowanego (fantoma). Ze względu na specyfikę działania (każdy towar musi posiadać własne zdjęcie), funkcja ta jest dostępna wyłącznie dla towarów zgrupowanych.

Przykładowa konfiguracja wariantu - Miniatury

W systemie Comarch ERP stwórz towar zgrupowany zgodnie z dokumentacją Comarch e-Sklep. Poniższy wariant opiera się na konfiguracji atrybutu przedstawionej w sekcji dotyczącej graficznej prezentacji kolorów.

Prezentacja wariantu Miniatury na stronie e-Sklepu

Na liście towarów: Na szczegółach towarów:

Wariant - Tekst

W ramach konfiguracji wariantów z tekstem wystarczy zaznaczyć wskazane ustawienie: Po zapisaniu i opublikowaniu zmian kafelki z tekstem zostaną wyświetlone w odpowiednich miejscach w ramach e-Sklepu.

Przykładowa konfiguracja wariantu z tekstem

W systemie Comarch ERP stwórz towar zgrupowany zgodnie z dokumentacją Comarch e-Sklep. Poniższy wariant wykorzystuje konfigurację atrybutu zaprezentowaną w sekcji poświęconej graficznej prezentacji kolorów.

Prezentacja wariantu z tekstem na stronie e-Sklepu

Na liście towarów:   Na szczegółach towarów:  

Kreator wyglądu szablonu Rubin

Wstęp

Jednym z kluczowych elementów wpływających na sukces w branży e-commerce jest odpowiednia oprawa wizualna sklepu internetowego. To ona w dużej mierze kształtuje wrażenia użytkowników oraz wpływa na przebieg ich procesu zakupowego. Dzięki narzędziu Kreator Szablonu Rubin (B2B) właściciele sklepów mają możliwość stworzenia unikalnego, dopasowanego szablonu, który będzie obsługiwał zarówno klientów detalicznych, jak i firmy, łącząc modele B2B oraz B2C.

Zastosowanie

Kreator Szablonu Rubin to intuicyjne narzędzie do projektowania wyglądu sklepu. Wszystko odbywa się na poziomie strony internetowej, gdzie przy pomocy metody "przeciągnij i upuść" możesz stworzyć szablon idealnie pasujący do Twojego sklepu.

Kreator pozwala na zaprojektowanie wszystkich kluczowych obszarów sklepu, w tym:

  • Strony głównej.
  • Listy towarów.
  • Koszyka.

Kto może używać tej opcji?

Aby móc używać tego narzędzia należy posiadać:

  • Comarch e-Sklep w wersji Enterprise lub B2B,
  • szerokość ekranu powyżej 1280 px, a zalecana to 1920 px,
  • oraz jedną z przeglądarek internetowych w aktualnej wersji.

Wskazówka
Kreator szablonu Rubin dostępny jedynie w wersji przeglądarkowej.

Zaczynamy!

Jak zaprojektować układ szablonu?

Aby rozpocząć projektowanie szablonu, należy udać się na stronę Kreatora Wyglądu, gdzie pojawi się powitalny komunikat. Na początku trzeba wybrać, dla jakiego typu sprzedaży ma być stworzony szablon – detalicznej lub hurtowej. Sprzedaż hurtowa jest dedykowana tym, którzy chcą oferować swoje produkty także klientom biznesowym w większych ilościach. Po dokonaniu wyboru modelu sprzedaży, wystarczy kliknąć przycisk „Rozpocznij pracę”. Następnie, użytkownik będzie miał możliwość stworzenia nowego szablonu lub edytowania jednego z dostępnych, gotowych szablonów.

  W sytuacji gdy wcześniej tworzony był już projekt, widoczny będzie przycisk umożliwiający dokończenie szablonu lub rozpoczęcie nowego projektu. Opcja Nowy szablon umożliwia zbudowanie od początku nowego szablonu Rubin według Twojego indywidualnego pomysłu.   W ramach szablonów B2B do wyboru zostały udostępnione szablon Rubin oraz szablon Szafir w trzech wersjach kolorystycznych. Są to gotowe wersje szablonów z możliwością ich edycji. Dzięki temu nie musisz zaczynać pracy od zera – wystarczy, że wybierzesz jeden z dostępnych szablonów, a następnie łatwo dopasujesz go do swoich wymagań. Podwójne kliknięcie na wybrany kafelek pozwala przejść do kolejnego etapu. W trzech prostych krokach zapoznasz się z podstawowymi funkcjami kreatora. Po ich przejściu, możesz rozpocząć dalsze dostosowywanie szablonu lub od razu wygenerować przygotowaną wersję szablonu Rubin.

Od czego zacząć?

Wybierz preferowaną wersję językową Kreatora i rozpocznij tworzenie swojego szablonu. Dostępne opcje to: język polski, angielski, niemiecki oraz francuski. Aby zmienić język, kliknij strzałkę obok flagi i nazwy języka w lewym dolnym rogu. Po wybraniu języka, przy podglądzie na pełnym ekranie, szablon będzie wyświetlany w wybranej wersji językowej.

Po ustawieniu wersji językowej dla Kreatora, warto nadać nazwę swojemu szablonowi. Można to zrobić klikając „Zmień” w lewym górnym rogu, a następnie wpisując nową nazwę, która zastąpi domyślną nazwę „Rubin”. Ta nazwa będzie widoczna po zaimportowaniu szablonu do panelu administracyjnego oraz po wyeksportowaniu go do pliku XML, wraz z datą i godziną wygenerowania szablonu.

Krok 1 - Strona główna

W tej sekcji należy zaprojektować wygląd strony głównej naszego Comarch e-Sklepu dla szablonu Rubin. Strona główna może składać się z następujących elementów:

  • Nagłówek,
  • Baner,
  • Widget,
  • Banner pop-up,
  • Proponowane,
  • Newsletter,
  • Slider producentów,
  • Slider marek,
  • Aktualności,
  • Banner infografika,
  • Element tekstowy,
  • Stopka.

Po kliknięciu w strzałkę, sekcje rozwiną się i pokażą dostępne elementy:

Metodą "Przeciągnij i upuść" przenosimy wybrane elementy na obszar po prawej stronie:

Postępuj analogicznie z pozostałymi elementami.

Nagłówek

Sekcja „Nagłówek” prezentuje jeden widok. Nagłówek dodatkowo można konfigurować w zakresie funkcji związanych ze składaniem Zapytań o wycenę.

Bannery

Sekcja "Bannery" pozwala dodać slider. Informacje dotyczące rekomendowanych rozmiarów obrazków w bannerach opisaliśmy w tym artykule.

Widget

Sekcja "Widget" pozwala dodać jeden element, który pozwoli zaprezentować następujące funkcj:
  • dodanie zdjęcia,
  • dodanie tekstu tekstu nagłówka (tekst pionowy),
  • dodanie linku do przycisku,
  • dodanie tekstu.

Banner pop-up

Sekcja „Banner pop-up” pozwala na dodanie bannera w formie popupu. Banner ten jest możliwy do wyświetlenia jedynie na stronie głównej e-Sklepu.

Proponowane

Sekcja „Proponowane” oferuje dodatkowe opcje do konfiguracji. Z menu rozwijanego, dostępnego po kliknięciu przycisku „Zmień typ”, możesz wybrać kategorię produktów, które mają być wyświetlane w tej sekcji (np. nowości, najczęściej oglądane, wyprzedaż, sugerowane). Po dokonaniu zmiany typu, sekcja zostanie odpowiednio nazwana po załadowaniu szablonu do sklepu.

Dodatkowo po najechaniu kursorem na tę sekcję, wybierając Opcje, możemy ustawić liczbę towarów, która będzie się wyświetlać (maksymalnie 50).

Podczas tworzenia szablonu w Kreatorze wyglądu Rubin po dodaniu sekcji towary polecane można określić typ wyświetlanych produktów. Nazwa sekcji jest zależna oraz adekwatna do określonego typu. Daną nazwę można modyfikować w tłumaczeniach szablonu. Dodatkowo każdy wybrany typ jest podlinkowany do wszystkich produktów wskazanego rodzaju. W zależności od wybranego typu, edycji parametrów wyświetlania dokonasz w panelu administracyjnym e-Sklepu. Z kolei informację o typie towaru ustawisz w systemie ERP. Typy towarów edytowane z poziomu panelu administracyjnego Comarch e-Sklep:
  • Promocja,
  • Nowość,
  • Wyprzedaż,
  • Super jakość,
  • Super cena,
  • Rekomendacja sprzedawcy,
  • Zapowiedź,
  • Sugerowane,
  • Towar polecany,
  • Najczęściej oglądane / najczęściej kupowane,
  • Cross-selling - oferowanie produktów uzupełniających wcześniejsze zakupy,
Aby zdecydować o parametrach wyświetlania tych informacji należy przejść w panelu administracyjnym Comarch e-Sklep do zakładki Ustawienia > Ustawienia sklepu > Towary:

Producent, marka, ręcznie wybrane produkty, kategoria oraz ostatnio oglądane są obsługiwane w ramach lokalnego obiektu "Siatka towarów". Aby wprowadzić zmiany w ustawieniach dla jednego z tych typów, należy przejść do panelu administracyjnego do opcji Wygląd sklepu > Ustawienia >Ustawienia zaawansowane, a następnie do zakładki Obiekty. W szczegółach wybranego obiektu (Siatka towarów) można określić, które produkty będą wyświetlane w sekcji "Proponowane". W przypadku wyboru "Producenta" lub "Marki" konieczne jest ręczne wskazanie odpowiedniego producenta lub marki.

Dodawanie informacji o typie produktu w systemie ERP dotyczy:
  • Nowości,
  • Produktu z gazetki,
  • Produktu polecanego,
  • Wyprzedaży,
  • Promocja,
  • Nowość,
  • Super jakości,
  • Super ceny,
  • Najlepszej oceny,
  • Rekomendacji sprzedawcy.
Informacja tego typu ustawiana jest bezpośrednio na karcie towaru w systemie ERP poprzez zaznaczenie odpowiedniej flagi w systemie ERP XL (zakładka aplikacje) lub atrybutu czasowego w ERP Optima (zakładka e-Sklep, sekcja atrybuty czasowe). Po wybraniu konkretnej opcji w systemie ERP na karcie danego produktu w Comarch e-Sklep zostanie dodana odpowiednia informacja.

Newsletter

Dla newslettera możliwe jest ustawienie stałej sekcji na stornie głównej lub newslettera w postaci popupu:

Slider marek

Sekcja "Slider marek" pozwala na dodanie do szablonu widoku slidera z logo marek. W sliderze wyświetlane są logotypy marek, które zostały zaimportowane z systemu ERP. Po kliknięciu na wybrane logo, użytkownik zobaczy listę produktów przypisanych do danej marki. Sekcje te mogą być umieszczone w dowolnym miejscu na stronie głównej szablonu.

Slider producentów

Sekcja "Slider producentów" pozwala na dodanie do szablonu widoku slidera z logo producentów. W sliderze wyświetlane są logotypy producentów zaimportowane z systemu ERP. Po kliknięciu na wybrane logo, użytkownik zobaczy listę produktów przypisanych do danego producenta. Sekcje te mogą być umieszczone w dowolnym miejscu na stronie głównej szablonu.

Aktualności

Sekcja umożliwia zamieszczenie aktualności na stronie głównej w formie listy artykułów z bloga. Tekst wprowadza się w panelu administracyjnym przechodząc do zakładki  Marketing > Blog.

Banner infografika

Sekcja "Banner infografika" pozwala na zaprezentowanie korzyści z zakupów w Twoim sklepie. Dotyczą one obszarów: informacji o dostawie, płatnościach czy obowiązujących rabatach rabatach. Banner możesz dodać tylko do strony głównej. Obrazki są możliwe do edycji w ramach elementu homepage-small w panelu administracyjnym e-Sklepu w obszarze: Wygląd sklepu > Ustawienia > Bannery.

Stopka

Sekcja "Stopka" zawiera jeden widok do wyboru. W widoku Stopki widnieją strony statyczne, którymi można zarządzać w sekcji Wygląd Sklepu/ Ustawienia/ Stopka. Dla każdej z sekcji wyświetla się jej utworzona w panelu nazwa. W stopce znajduje się komunikat @Comarch SA 2025. All rights reserved Powered by Comarch e-Sklep. Dodatkowo istnieje możliwość umieszczenia w stopce odnośników do mediów społecznościowych oraz ich ikony. Możemy dodać ikony naszych dostawców oraz form płatności wykorzystywanych w sklepie w ramach ustawień Wygląd Sklepu > Ustawienia > Bannery w sekcjach LogisticsPartners oraz PaymentOperators.

Po wybraniu wszystkich niezbędnych sekcji nasza strona główna powinna być gotowa. Efekt naszej pracy możemy podejrzeć klikając Podgląd w prawym górnym rogu.

Dzięki tej opcji możesz zobaczyć, jak będzie prezentował się Twój szablon zarówno w wersji dekstop, jak i mobile.

Strona główna wymaga dwóch podstawowych elementów: nagłówka oraz stopki. Pozostałe elementy nie są obowiązkowe.

Krok 2 - Lista towarów

Kolejnym krokiem jest utworzenie listy towarów. Aby to zrobić, należy rozwinąć listę zgodnie z poniższym rysunkiem, a następnie przejść do wskazanej zakładki:

Banner

Sekcja "Banner" daje możliwość dodania do listy slideru, dzięki czemu masz możliwość wzbogacenia kategorii towarowych o obrazki.  

Panel filtra

Sekcja "Panel filtra" umożliwia wybór liczby wyświetlanych wartości filtrów a także o tym czy filtrowanie powinno odbywać się po klinićiu przycisku "Zastosuj". Z tego poziomu możemy także wybrać elementy prezentowane w panelu filtrów.

Opis kategorii

W sekcji możesz zdecydować, czy opis ma być domyślnie zwinięty lub rozwinięty.

Lista towarów

Podobnie, jak w przypadku strony głównej konfigurujemy wygląd listy towarów. Dodatkowo możemy wskazać liczbę wyświetlanych towarów, domyślny widok listy towarów, prezentację atrybutów, a także zdecydować czy pozwolisz na zakup towarów wielowariantowych z listy towarów.

W Kreatorze Szablonu Rubin dostępny jest jeden widok listy towarów:  

Krok 3 - Koszyk

Po utworzeniu szczegółów towaru przechodzimy do ustawień koszyka dostępnego w e-Sklepie. Dodatkowo na stronie koszyka możesz wskazać sposób prezentacji przeliczników jednostek miary:

Następnie możemy przejść do modyfikacji wyglądu naszego szablonu. W tym celu należy przejść do zakładki Style.

Style

Jak zmienić kolory, czcionki oraz ikony?

Po dodaniu elementów strony możemy dodatkowo podejrzeć, jak będzie wyglądał nasz przyszły szablon. W tym celu należy przejść do zakładki Style.

Motyw kolorystyczny

W tym momencie dla szablonu Rubin został przygotowany jeden motyw kolorystyczny:

Motyw możemy zmieniać według indywidualnych preferencji. Możemy zmodyfikować kolor poszczególnych elementów (m.in.: tło strony, tło nagłówka, nazwę towaru). Zmiany należy zapisać klikając Zapisz. Jeśli wykonane zmiany nie są zadowalające, możemy przywrócić ustawienia domyśle dla danego motywu kolorystycznego, klikając przycisk Przywróć.

Możliwe jest również wprowadzenie szesnastkowego zapisu kolorów. Heksadecymalny zapis kolorów dla poszczególnych sekcji w szablonie dostępny jest podczas edycji wybranego motywu kolorystycznego.

Czcionki

W tym momencie w ramach szablu Rubin została udostępniona jedna czcionka:

Ikony

Ostatnim elementem, który możemy modyfikować z poziomu zakładki Style jest wygląd ikon. Mamy do wyboru 3 różne warianty wyglądu ikon. Dodatkowo istnieje możliwość wyboru w jakiej postaci wyświetla się ikona koszyka (torba, wózek lub koszyk) oraz loader.

 

Funkcja cofania zmian

Funkcja odpowiadająca za cofanie oraz powtórzenie wprowadzonych zmian oznaczona jest symbolem strzałek, zapamiętuje ona do 30 ostatnich modyfikacji szablonu. Nieaktywna strzałka oznacza, że aktualnie nie ma dostępnych kroków. Mamy możliwość przywracania zmian: dodawania/ usuwania elementów oraz edycji ich położenia, a także stylu w szablonie.
Wskazówka
Funkcję cofania obejmuje zmiany motywu kolorystycznego, natomiast edycja poszczególnych kolorów w motywie nie jest zapisywana.

Generowanie i wgrywanie szablonu

Po zaprojektowaniu wyglądu szablonu możemy go wygenerować i pobrać na dysk korzystając z przycisku Generuj widocznego w prawym górnym rogu:

Obok przycisku Generuj dostępna jest również opcja Importuj szablon, umożliwiająca wgranie wcześniej zapisanego szablonu z dysku i ponowną jego edycję.

W przypadku prawidłowego wygenerowania szablonu wyświetlony zostanie komunikat informujący o tym fakcie i pobrany plik.

Pobrany szablon należy zaimportować w Comarch e-Sklep w zakładce Wygląd sklepu/ Zaimportuj szablon z Kreatora Wyglądu.

W przypadku braku obowiązkowych elementów szablonu nie będzie możliwe jego wygenerowanie. przycisk Generuj będzie wyszarzały, a w prawym dolnym rogu pojawi się komunikat „Uzupełnij elementy wymagane w szablonie”. Sekcje, gdzie element nie został wybrany, będą się wyświetlać z odpowiednią ikoną.

 

Aktualizacja szablonu

W Kreatorze szablonu Rubin znajduje się opcja aktualizacji poprzednich wersji szablonu. W celu zaktualizowania całego szablonu należy wgrać plik z poprzednim szablonem do Kreatora szablonu Rubin według tej instrukcji:
  • po uruchomieniu strony kreatora wybierz opcję: Stwórz nowy projekt,
  • wybierz Nowy szablon,
  • w prawym górnym rogu wybierz opcję Importuj szablon,
  • następnie zaimportuj plik z szablonem, który ma być zaktualizowany. Po poprawnym zaimportowaniu szablonu otrzymasz informację zwrotną:
  • po wgraniu szablonu do aktualizacji użyj opcji Generuj. 
Dzięki temu w prosty sposób można starsze szablony Rubin podnieść do wersji aktualnej.

Więcej informacji

Więcej informacji można znaleźć w artykułach o wyglądzie sklepu oraz o dostosowaniu wyglądu.

Gotowe szablony Comarch

Comarch e-Sklep umożliwia tworzenie oraz edycję szablonów graficznych opartych na silniku DotLiquid wykonanych w technice Responsive Web Design (RWD). Dzięki tej technologii strona sklepu dostosowuje się automatycznie do rozdzielczości urządzenia, na którym jest wyświetlana i nie ma potrzeby tworzenia osobnych szablonów dla wersji mobilnej. Dodatkowo wszystkie standardowe szablony są dostosowane do wyświetlania w rozdzielczości 4K.

Domyślnie użytkownicy Comarch e-Sklep mają dostęp do pięciu darmowych szablonów: Topaz, Dla gastronomii i One Page Shop (generowane przez Kreator wyglądu) oraz Szafir i Rubin(dostępny dla wersji B2B w Kreatorze B2B).

Więcej o darmowych szablonach przeczytasz w artykułach Szablon Rubin, Szablon Dla gastronomii, Szablon Szafir, Szablon Topaz i Szablon One Page Shop. Szablony te można poddać edycji w celu spersonalizowania wyglądu swojego sklepu dzięki prostym ustawieniom w panelu administracyjnym, gdzie można zmienić takie parametry jak:

  • Motyw kolorystyczny – możliwość skorzystania z kliku predefiniowanych motywów i ich edycji,
  • Ustawienia wstążek – zmiana kolorystyki flag promocyjnych na towarach,
  • Kolory komunikatów – możliwość zmiany kolorystyki komunikatów pojawiających się w e-Sklepie,
  • Bannery – możliwość tworzenia własnych bannerów (zdjęcia, opis, linki), zmiana animacji bannera,
  • Logo i Favicon – możliwość wgrania własnego logo i Favicon (ikony widocznej na zakładce przeglądarki),
  • Obiekty – konfigurowalne obiekty pozwalające np. na zmianę rodzaju towarów wyświetlanych na stronie głównej,

Dla bardziej zaawansowanych użytkowników znających technologie takie jak HTML, CSS, JS, DotLiquid udostępniony jest obszar z plikami szablonu, gdzie można dokonywać zmian na poziomie kodu szablonu, co daje praktycznie nieograniczone możliwości edycji i personalizacji wyglądu sklepu.

Wymagania:

Wspierane przeglądarki (minimalna wersja)
  •   Mozilla Firefox – aktualna wersja przeglądarki, nie starsza niż trzy miesiące,
  •   Google Chrome – aktualna wersja przeglądarki, nie starsza niż trzy miesiące,
  •   Microsoft Edge – aktualna wersja przeglądarki, nie starsza niż trzy miesiące.
W obszarze Wygląd sklepu/ Gotowe szablony Comarch znajdziesz listę wszystkich darmowych szablonów Comarch. Poprzez link Zobacz demo Możesz obejrzeć sklepy demonstracyjne przygotowane dla każdego z szablonów oraz pobrać i zainstalować wybrany przez siebie szablon. Szczegóły dotyczące edycji szablonów znajdziesz w kategorii Dostosowanie wyglądu.

Wybór szablonu startowego

Wstęp

W przypadku pierwszej konfiguracji, na stronie sklepu nie ma zaimportowanego żadnego z szablonów. Rozpoczynając pracę z Comarch e-Sklep, przy pierwszym wejściu na adres Twojego sklepu, otworzy się strona z wyborem szablonu graficznego.

First run

Po wejściu na sklep pokaże się widok „First Run”. Umożliwia on pierwsze dostosowanie wyglądu strony. W widoku "First run" będziesz mógł stworzyć swój własny szablon w Kreatorze wyglądu lub wybrać spośród darmowych wzorów przygotowanych przez Comarch:
Dla każdego z nich zostały przygotowane dokładne opisy w czterech wersjach językowych: polskim, angielskim, niemieckim i francuskim oraz specjalne sklepy demonstracyjne. Dzięki temu można zapoznać się z różnymi projektami wyglądu dla różnych branż w tym branży kosmetycznej, odzieżowej czy spożywczej. Dokładne przedstawienie każdego z szablonów może służyć, jako inspiracja przy wyborze właściwego wyglądu dla nowego sklepu. First Run oferuje prostą instalację szablonu. Wystarczy przejść do szczegółów wybranego widoku, a następnie wybrać „Zainstaluj”. Dany szablon zostanie zaimportowany na pierwszy z czterech dostępnych slotów udostępnionych w ramach ustawień wyglądu sklepu.

Kreator wyglądu

Aby stworzyć nowy szablon w panelu administracyjnym e-Sklep w zakładkę Wygląd sklepu/ Kreator wyglądu, zostaniesz przekierowany na stronę kreatora, następnie wybierz, czy chcesz stworzyć szablon dla sklepu B2B czy B2C. W kolejnym korku będziesz mógł wybrać, czy opcję Dokończ poprzedni szablon bądź Stwórz nowy projekt Następnie w przypadku tworzenia nowego projektu w oknie wyboru będziesz mógł wskazać właściwy szablon, który będziesz mógł dostosować do własnych preferencji względem dostępnych opcji.
Wskazówka
Więcej informacji na temat edycji szablonów znajdziesz w centrum pomocy dotyczącej  kreatora wyglądu.
Zapisanie i pobranie na dysk utworzonego wzorca możesz wykonać klikając przycisk Generuj. Natomiast pobrany szablon możesz ponownie edytować po wgraniu go do kreatora za pomocą opcji Importuj szablon. Gotowy szablon zaimportujesz w panelu Comarch e-Sklep w zakładce Wygląd sklepu/ Zaimportuj szablon z Kreatora wyglądu.   Następnie należy wgrać pobrany szablon klikając w Wybierz plik XML. Po wgraniu szablonu  kliknij Importuj Szablon.

Gotowe szablony Comarch

Gotowe szablony Comarch przy pierwszym uruchomieniu sklepu można wgrać na dwa sposoby:
1. Przy pierwszym wejściu na adres Twojego sklepu
Pojawi się strona z gotowymi szablonami:
Wskazówka
Szablon Szafir, dostępny jest dla sklepów w wersji B2B oraz Enterprise
Po kliknięciu w jeden z gotowych szablonów Comarch możesz potwierdzić jego wybór lub podejrzeć jak prezentuje się na naszym sklepie demo.  

2. Wybór szablonu z panelu administracyjnego Comarch e-Sklep

Standardowe szablony dostępne są w panelu Comarch e-Sklep w zakładce Wygląd sklepu/ Gotowe szablony Comarch. Po kliknięciu w Chcę pobrać i zainstalować szablon, szablon zostanie zapisany. Pojawi się komunikat o pomyślnym przeprowadzeniu zmian.   Wybrany szablon można w każdej chwili zmienić w panelu administracyjnym e-Sklepu. Podstawowe informacje o naszych darmowych szablonach znajdziesz w artykule Gotowe szablony Comarch. Instalacja szablonów z poziomu panelu administracyjnego opisana w artykule Szablony w sklepie.

3. Wgranie własnego szablonu do Comarch e-Sklep

W e-Sklepie możesz także wgrać własny szablon. Jeśli został on już przez Ciebie utworzony i wygenerowany w Kreatorze Wyglądu, to wystarczy wgrać go do Twojego e-Sklepu, aby móc cieszyć się jego unikalnym wyglądem. Można to zrobić za pomocą opcji Wygląd sklepu/ Zaimportuj szablon z Kreatora wyglądu.

 

Jak zaktualizować szablon do najnowszej wersji?

Jak zaktualizować szablon do najnowszej wersji?

Wskazówka
Od 1 czerwca 2025 roku zakończyliśmy aktualizację oraz wydawanie nowych wersji szablonów Bursztyn, Agat i Opal, a tym samym ich wsparcie, aby skupić się na nowoczesnych rozwiązaniach, które jeszcze lepiej odpowiadają na potrzeby dynamicznie rozwijającego się rynku e-commerce. Zachęcamy Was do przejścia na nasze nowe, udoskonalone szablony. Dla sklepów B2C polecamy szablony Topaz, One Page Shop oraz Dla Gastronomii, natomiast dla platform B2B idealnym wyborem będą Rubin i Szafir.

Wstęp

W e-Sklepie możesz dowolnie zmieniać szablony. Możesz je także modyfikować oraz aktualizować. Wiąże się to z wgraniem zupełnie nowego szablonu na miejsce starego. Aktualizacja wyglądu powoduje zmianę dotychczasowych ustawień. Przed każdą aktualizacją polecamy utworzyć odpowiednią dla siebie instrukcję, która będzie zawierała Twoje ustawienia kolorów czy modyfikacje w kodzie szablonu. Możesz także wyeksportować dotychczasowy szablon, aby stanowił on kopię bezpieczeństwa.

Jak zaktualizować szablon?

Instrukcja aktualizacji szablonów: Rubin, Szafir, Topaz i One Page Shop (dostępnych w Kreatorze Wyglądu)

Aby zaktualizować szablon Rubin, Szafir, Topaz lub One Page Shop należy skorzystać z aktualnej wersji Kreatora Wyglądu, do którego odnośnik znajduje się w panelu administracyjnym e-Sklepu w sekcji Wygląd sklepu/ Kreator wyglądu. Istnieją dwie możliwości aktualizacji tych szablonów:

  • wygenerowanie nowego szablonu w Kreatorze Wyglądu oraz wgranie go do e-Sklepu,
  • import posiadanego szablonu do Kreatora Wyglądu oraz ponowne wygenerowanie go w najnowszej wersji.

Wyeksportowany z Kreatora Wyglądu szablon należy wgrać do e-Sklepu. W panelu administracyjnym e-Sklepu, w sekcji Wygląd sklepu znajduje się bezpośredni odnośnik do importu szablonu z Kreatora wyglądu. Szczegółowa instrukcja dostępna jest w artykule Jak wyeksportować i zaimportować swój szablon w e-Sklepie?

Podczas dokonywania modyfikacji w szablonach zachęcamy do skorzystania z naszego Centrum Pomocy.

Wskazówka
Pamiętaj o zapisaniu szablonu oraz opublikowaniu go w e-Sklepie. Zmiany wprowadzone w ustawieniach zostaną zsynchronizowane do sklepu po 10 minutach.

Instrukcja aktualizacji szablonów: Bursztyn, Agat i Opal.

Aby zaktualizować szablon Bursztyn, Agat lub Opal należy w panelu administracyjnym e-Sklepu przejść do sekcji Wygląd Sklepu/ Gotowe szablony Comarch, w której znajdują się najnowsze wersje szablonów dostępne do zainstalowania. Z wyświetlonej listy należy wybrać szablon, który ma zostać wgrany do e-Sklepu. W tym celu wybierz przycisk Chcę pobrać i zainstalować szablon:

Następnie wyświetli się nowe okno, w którym należy:

  • wybrać tzw. slot, który zostanie nadpisany nowym (aktualnym) szablonem. W każdym e-Sklepie dostępne są 4 miejsca na wgranie szablonu, spośród których jeden szablon oznacza się jako aktywny i domyślny,
  • określić, czy wgrywany szablon ma podmienić istniejące bannery. Gdy parametr zostanie zaznaczony, wówczas wszystkie bannery zapisane na danym slocie zostaną usunięte i zastąpione bannerami z importowanego szablonu. Jeżeli w nadpisywanym szablonie znajdują się bannery oraz lookbooki, które mają nadal wyświetlać się w e-Sklepie, należy wskazany parametr zostawić odznaczony. Gdy parametr nie zostanie zaznaczony, wówczas dotychczasowe bannery i lookbooki nie zostaną usunięte.
  • Zaimportować szablon do e-Sklepu.
    Wskazówka
    Import szablonu jest operacją nieodwracalną i spowoduje nadpisanie dotychczasowego szablonu. W przypadku, gdy szablon był modyfikowany (dokonywano zmian w kodzie HTML) jego aktualizacja spowoduje, iż zmiany nie zostaną przeniesione. Warto wykonać eksport posiadanego szablonu do pliku w celu zapisania oraz posiadania wglądu to wprowadzanych modyfikacji. Jeżeli istnieje taka konieczność należy ponownie dokonać samodzielnej edycji szablonu.

Aby nowy szablon pojawił się w e-Sklepie należy upewnić się, czy jest on aktywny oraz ustawiony jako domyślny. W sekcji Wygląd sklepu/Ustawienia/Edytuj ustawienia zaawansowane w zakładce Szablon znajdują się odpowiedzialne za to parametry, które powinny być zaznaczone.

Wszelkie zmiany należy zapisać, a następnie opublikować.

Uwaga
Jeżeli szablon nie zostanie opublikowany, wówczas nie pojawi się on w e-Sklepie.

Instrukcja aktualizacji innych szablonów (niż szablonów Comarch) oraz aktualizacji szablonów z własnymi modyfikacjami

Jeżeli w swoim Comarch e-Sklepie korzystasz z własnego szablonu, czyli innego niż gotowe szablony Comarch, to powinieneś jego aktualizację przeprowadzić we własnym zakresie lub zlecić ją firmie/ osobie, która dla Ciebie przygotowała ten szablon. W przypadku, gdy korzystasz z gotowego szablonu Comarch, ale wprowadziłeś do niego indywidualne zmiany (poza Kreatorem Wyglądu), to również we własnym zakresie (lub ze wsparciem autora zmian) musisz zadbać o aktualizację swojej wersji szablonu.

Polecane produkty, kategorie oraz bannery w wyszukiwarce

Wstęp

Parametry wyszukiwania stanowią istotny element w funkcjonowaniu sklepu internetowego. Wygodne oraz efektywne przeszukiwanie asortymentu zachęca klientów do kontynuacji zakupów. Aktualnie, po kliknięciu w pole wyszukiwania, klienci natychmiast uzyskują dostęp do polecanych produktów, kategorii i wybranych marek. Nowa funkcja nie tylko ułatwia skuteczne przeglądanie oferty, ale również pełni rolę skutecznego narzędzia do promowania asortymentu. Dzięki łatwemu dostępowi do rekomendacji, zwiększasz atrakcyjność swojego e-Sklepu, umożliwiając klientom bardziej intuicyjne odkrywanie interesujących produktów. Wyżej opisaną funkcjonalność możesz włączyć w dwóch miejscach:
  • Na ustawieniach nagłówka w Kreatorze wyglądu:
  • W panelu administracyjnym w zakładce Wygląd sklepu/ Ustawienia/ Ustawienia sklepu/ Dodatkowe. W tym miejscu wybierz w Widoku wyszukiwania towarów w nagłówku opcję ’Z rekomendacjami”.
Pojawiający się popup z rekomendacjami składa się z trzech osobnych elementów, jakimi są:
  • Polecane produkty
  • Polecane kategorie
  • Polecane marki
Produkty polecane skonfiguruj przechodząc do panelu administracyjnego do zakładki  Wygląd sklepu/ Ustawienia/ Więcej(trzy kropki)/ Edytuj ustawienia zaawansowane/ Obiekty. Odnajdź obiekt header-recomm-products, po czym wybierz jeden typ z listy. Do wyboru masz:
  • Ostatnio oglądane,
  • Ręczny,
  • Grupa towarowa,
  • Producent,
  • Marka.
Wskazówka
W popupie z rekomendacjami wyświetlonych zostanie maksymalnie 6 polecanych towarów
Kategorie polecane skonfiguruj przechodząc do panelu administracyjnego do zakładki Wygląd sklepu/ Ustawienia/ Więcej(trzy kropki)/ Edytuj ustawienia zaawansowane/ Obiekty. Odnajdź na obiekt header-recomm-categories, po czym wybierz jeden typ z listy:
  • Grupy najwyższego poziomu,
  • Podgrupy począwszy od,
  • Wybrane,
  • Zawężaj menu do wybranej grupy.
Przyklad
Jeśli kategoria ma więcej niż trzy podkategorie, to widoczna będzie jedynie ta, która jest ostatnia
Polecane marki skonfiguruj przechodząc do panelu administracyjnego do zakładki  Wygląd sklepu/ Ustawienia/ Bannery w obiekcie headerRecommLogos. Dodaj odpowiednie zdjęcia. Możesz także dodać link. Dzięki temu po kliknięciu w banner ostaną przekierowany na podany adres URL.
Wskazówka
Jeśli obiekt header-recomm-categories,  header-recomm-products lub banner headerRecommLogos zostanie usunięty, to popup z rekomendacjami nie będzie widoczny na stronie

Obsługa Tłumacza Google w szablonach

Wskazówka
Od 1 czerwca 2025 roku zakończyliśmy aktualizację oraz wydawanie nowych wersji szablonów Bursztyn, Agat i Opal, a tym samym ich wsparcie, aby skupić się na nowoczesnych rozwiązaniach, które jeszcze lepiej odpowiadają na potrzeby dynamicznie rozwijającego się rynku e-commerce. Zachęcamy Was do przejścia na nasze nowe, udoskonalone szablony. Dla sklepów B2C polecamy szablony Topaz, One Page Shop oraz Dla Gastronomii, natomiast dla platform B2B idealnym wyborem będą Rubin i Szafir.

Obsługa Tłumacza Google w szablonach

W Comarch e-Sklep możesz ułatwić zakupy swoim Klientom udostępniając możliwość tłumaczenia stron z pomocą Tłumacza Google. Opcja dotyczy wszystkich szablonów Comarch.

Jak włączyć Tłumacz Google w szablonie?

Szablon Szafir, Bursztyn, Agat, Opal

W panelu administracyjnym przejdź do Wygląd sklepu/ Ustawienia, a następnie w sekcji Ustawienia Dodatkowe oznacz parametr „Zezwól na tłumaczenie strony przez Tłumacz Google”: Wprowadzone zmiany zapisz i opublikuj.

Szablon Topaz, Szafir, One Page Shop

W panelu administracyjnym przejdź do Wygląd sklepu/ Ustawienia/ Dodatkowe i oznacz parametr Zezwól na tłumaczenie strony przez Tłumacz Google: Wprowadzone zmiany zapisz i opublikuj. Po zapisaniu i publikacji wprowadzonych zmian, na stronie Twojego sklepu u góry wyświetli się Tłumacz Google pozwalający na wybór języka.

Jak wykonać kopię bezpieczeństwa mojego szablonu?

Jak wykonać kopię bezpieczeństwa mojego szablonu?

Oprawa wizualna sklepu jest bardzo ważnym elementem podczas prowadzenia sprzedaży w sieci. Narzędzie Kreator Wyglądu Comarch e-Sklep umożliwia stworzenie własnych, niepowtarzalnych szablonów wedle preferencji i potrzeb użytkowników. W intuicyjnym narzędziu jakim jest Kreator, będziesz w stanie zaprojektować wszelkie niezbędne funkcje, takie jak stronę główną, listę towarów, szczegóły towaru oraz koszyk. Jeśli Twój projekt szablonu został zaimportowany do e-Sklepu oraz skonfigurowany wedle Twoich preferencji (dodanie grafik do bannerów, modyfikacje kolorystyczne) masz możliwość jego zapisania, co będzie stanowić kopię bezpieczeństwa. Kopia bezpieczeństwa to dane, które w każdej chwili można odtworzyć w przypadku ich utracenia (np. poprzez przypadkowe usunięcie) lub częstego wprowadzania zmian. Dane, jakie może zawierać kopia bezpieczeństwa to szablon, który wcześniej został przez nas wygenerowany wraz z bannerami. Zaleca się wykonywanie kopii zapasowych oraz zabezpieczenie ich hasłem. Każda wykonana kopia zapasowa powinna zostać zapisana w bezpiecznym i dogodnym dla Użytkownika miejscu.

Jak wykonać kopię bezpieczeństwa?

W Panelu Administracyjnym przejdź do sekcji Wygląd sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane, a następnie przejdź do zakładki Eksport szablonu. W pustych polach znajdujących się w zakładce Eksport szablonu, opcjonalnie przed eksportem możesz uzupełnić powyższe dane, tj. Autora szablonu, e-mail, telefon i stronę WWW sklepu. Aby wyeksportować szablon, kliknij Eksportuj szablon. Wyeksportowany plik jest w formacie XML, a jego nazwa zawiera szablon oraz wersję, co znacznie ułatwia zarządzanie kopiami bezpieczeństwa w przypadku wykonywania ich regularnie.

Jak wyeksportować bannery?

Bannery, które znajdują się w Twoim sklepie możesz również wyeksportować tworząc kopię bezpieczeństwa. W tym celu także musisz przejść do Wygląd sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane, a następnie do zakładki Eksport szablonu. Obok przycisku Eksportuj szablon, znajduje się przycisk Eksportuj bannery, który musisz kliknąć aby bannery, które posiadasz w e-Sklepie zostały weksportowane. Kopia bezpieczeństwa jest również zapisywana w formacie XML, a nazwa pliku wskazuje na szablon, wersję i zawartość bannerów.

Jak zabezpieczyć hasłem swój szablon?

Jeśli chcesz, aby Twój szablon został zabezpieczony hasłem, a znajomość hasła była niezbędna podczas zaimportowania tego szablonu do e-Sklepu, musisz w tym celu przejść w Panelu Administracyjnym do sekcji Wygląd sklepu/ Ustawienia/ Ustawienia zaawansowane, następnie do zakładki Szablon. W tym miejscu nadasz hasło dla swojego szablonu. Zgodnie z Polityką bezpieczeństwa haseł, hasło powinno:
  • Składać się z minimum 8 znaków,
  • Zawierać dużą literę,
  • Zawierać małą literę,
  • Zawierać cyfrę 0-9,
  • Zawierać znak specjalny – ‘!.+?;^]=-(&_)#=
Gotowe! Teraz Twój szablon został zabezpieczony hasłem. Jeśli wyeksportujesz szablon, który zabezpieczyłeś hasłem – podczas importu tego szablonu, będziesz musiał podać nadane wcześniej hasło. Jego brak uniemożliwi import szablonu, a podanie błędnego hasła spowoduje nieprawidłowe działanie szablonu po imporcie. Więcej informacji znajdziesz:

Polityka bezpieczeństwa haseł

Z powodów bezpieczeństwa we wszystkich standardowych szablonach została wprowadzona zmiana odnośnie wymagań dotyczących hasła dla Klientów w Comarch e-Sklep. Nowe hasło powinno:
  • składać się z minimum 8 znaków
  • zawierać dużą literę
  • zawierać małą literę
  • cyfry 0-9
  • znaki specjalne:  ‘ ! @ # $ ^ & * ( ) + = , – : [  ] ; { } . _
Wskazówka
System weryfikuje wpisywanie hasła na bieżąco(w momencie pisania) w formie graficznej, zgodnie z powyższymi wymogami bezpieczeństwa. Opcja widoczna jest w szablonach Topaz od wersji 2022 oraz Szafir od wersji 2021.
Nowe hasło spełnić łącznie wszystkie powyższe 5 warunków. Zmiana dotyczy wszystkich klientów: zarejestrowanych wcześniej przed zmianą oraz nowych, którzy będą się rejestrować po raz pierwszy.

Jak wyeksportować i zaimportować swój szablon w e-Sklepie?

Comarch e-Sklep daje możliwość dostosowania wyglądu do preferencji sprzedawcy oraz potrzeb Klientów. Jeśli utworzyłeś już swój autorski projekt, to masz możliwość jego zapisania. Plik będzie potrzebny przy chęci modyfikacji wyglądu. Zapisana wersja szablonu może również stanowić kopię bezpieczeństwa. Warto jest więc wyeksportować szablon do pliku.

Jak wyeksportować swój szablon z Comarch e-Sklep?

Krok 1. W panelu administracyjnym przejdź do sekcji Wygląd Sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane/ zakładka Eksport szablonu.

Krok 2. W tym miejscu możesz opcjonalnie (przed eksportem) określić autora szablonu, podać adres e-mail, telefon oraz adres WWW swojego e-Sklepu.

Krok 3. Jeżeli chcesz wyeksportować szablon do pliku użyj przycisku Eksportuj szablon.

Gotowe! Szablon został wyeksportowany do pliku na Twoim urządzeniu.

Wskazówka
Z tego miejsca możesz także wyeksportować posiadane w e-Sklepie bannery, korzystając z przycisku Eksportuj bannery.

Jak wgrać własny szablon do Comarch e-Sklep?

Własny szablon. Jak go wgrać?

Po skomponowaniu swojego własnego szablonu możesz wgrać go do e-Sklepu. Postępuj zgodnie z poniższymi krokami.

Krok 1. W panelu administracyjnym przejdź do sekcji Wygląd Sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane/ zakładka Import szablonu.

Krok 2. Określ, czy wgrywany szablon ma podmienić istniejące bannery. Gdy parametr zostanie zaznaczony, wówczas wszystkie bannery zapisane na danym slocie zostaną usunięte i zastąpione bannerami z importowanego szablonu.

Krok 3. Wybierz plik XML swojego szablonu i naciśnij Importuj szablon.

Uwaga
Import szablonu jest operacją nieodwracalną i spowoduje nadpisanie dotychczasowego szablonu. W przypadku, gdy szablon był modyfikowany (dokonywano zmian w kodzie HTML) jego aktualizacja spowoduje, iż zmiany nie zostaną przeniesione. Warto wykonać eksport posiadanego szablonu do pliku w celu zapisania oraz posiadania wglądu to wprowadzanych modyfikacji. Jeżeli istnieje taka konieczność należy ponownie dokonać samodzielnej edycji szablonu

Wskazówka
W zakładce Szablony możesz określić, czy wgrywany szablon ma być domyślny i aktywny w e-Sklepie.

Krok 4. Teraz możesz podejrzeć zmiany, jakie zaszły w wyglądzie Twojego e-Sklepu. W tym celu możesz podejrzeć zmiany w czasie rzeczywistym lub przejść w tryb incognito. Pamiętaj, że wszelkie zmiany zostaną opublikowane po pełnej synchronizacji, która wciągu 10 minut zgodnie z wyświetlanym komunikatem.

Gotowe! Twój szablon został zaimportowany do e-Sklepu.

Szablon Rubin ( dedykowany dla B2B)

Instrukcja: Jak dostosować samodzielnie szablon do szybkich zwrotów w e-Commerce?

Wskazówka
Wskazówka: W tym artykule trzeba będzie wprowadzać zmiany w plikach js oraz scss. Z tego artykułu dowiesz się jak je kompilować i minifikować.
W szablonach Rubin, Szafir oraz Topaz / One Page Shop wprowadziliśmy funkcję szybkich zwrotów. Umożliwia ona klientom składanie wniosku o zwrot produktu zarówno z poziomu profilu klienta (zalogowani), jak i z dedykowanej strony zwrotów po podaniu numeru zamówienia oraz adresu e-mail (niezalogowani). Wraz z funkcjonalnością pojawił się m.in. rozbudowany ekran potwierdzenia zwrotu zawierający kolejne kroki i adres do wysyłki, banery informacyjne dotyczące terminu zwrotu oraz przyciski akcji w tabeli produktów wyświetlane bezpośrednio (zamiast w rozwijanym menu). Aby Twój szablon poprawnie obsługiwał te zmiany, wprowadź modyfikacje opisane poniżej w sekcji dotyczącej Twojego szablonu. Po zakończeniu edycji pamiętaj o kompilacji i minifikacji plików js oraz scss.
Wskazówka
Potrzebujesz pomocy lub masz pytania? Skontaktuj się z nami poprzez portal asysta.comarch.pl.
Wskazówka
Obecnie w Polsce trwają prace nad ostatecznym kształtem przepisów oraz nowelizacją Ustawy o prawach konsumenta, która wdroży unijną dyrektywę UE 2023/2673 i wprowadzi nowe wymagania techniczne dla platform e-commerce (m.in. ułatwienia w procedurze zwrotów). W momencie publikacji ostatecznej wersji polskich przepisów, wdrożone funkcjonalności mogą wymagać dostosowania do ostatecznych wytycznych ustawodawcy. Prezentowane informacje mają charakter poglądowy a instrukcja dotyczy zmian, jakie wprowadziliśmy w szablonach Comarch – w przypadku pytań dotyczących indywidualnej sytuacji prawnej Twojego sklepu, zalecamy konsultację z radcą prawnym lub adwokatem.

Szablon Rubin

1. Tłumaczenia

W panelu administracyjnym sklepu zaktualizuj dwa istniejące tłumaczenia oraz dodaj nowe klucze wymagane przez funkcjonalność szybkich zwrotów. Zaktualizuj poniższe istniejące tłumaczenia: ReturnSuccessTitle - PL: Gotowe! Przyjęliśmy Twoje zgłoszenie - EN: Done! We have received your request - DE: Fertig! Wir haben Ihre Anfrage erhalten - FR: C'est fait ! Nous avons reçu votre demande ReturnSuccessInfo - PL: Przygotuj paczkę i odeślij ją do nas – wszystkie szczegóły znajdziesz poniżej. - EN: Prepare the package and send it back to us – all the details are below. - DE: Bereiten Sie das Paket vor und senden Sie es an uns zurück – alle Details finden Sie unten. - FR: Préparez le colis et renvoyez-le nous – tous les détails sont ci-dessous. Dodaj nowe tłumaczenia: OrderReturnDeadlineInfo - PL: Zamówienie można zwrócić w ciągu {0} dni od daty dostawy. - EN: You can return the order within {0} days from the delivery date. - DE: Sie können die Bestellung innerhalb von {0} Tagen ab Lieferdatum zurückgeben. - FR: Vous pouvez retourner la commande dans les {0} jours suivant la date de livraison. RestrictedOrderViewInfo - PL: Wybrane dane zamówienia zostały ukryte ze względów bezpieczeństwa. Możesz zwrócić produkty bez logowania. - EN: Some order details are hidden for security reasons. You can return products without signing in. - DE: Einige Bestelldetails wurden aus Sicherheitsgründen ausgeblendet. Sie können Produkte ohne Anmeldung zurücksenden. - FR: Certaines informations de la commande ont été masquées pour des raisons de sécurité. Vous pouvez retourner des produits sans vous connecter. Com_RefundMethod - PL: Sposób zwrotu środków - EN: Refund method - DE: Rückerstattungsmethode - FR: Mode de remboursement Com_RefundAsPaid - PL: Tak jak zapłacono - EN: Same as paid - DE: Wie bezahlt - FR: Comme payé Com_RefundToBankAccount - PL: Na konto bankowe - EN: To bank account - DE: Auf Bankkonto - FR: Sur le compte bancaire Com_BankAccountNumber - PL: Nr konta bankowego - EN: Bank account number - DE: Bankkontonummer - FR: Numéro de compte bancaire Com_ConfirmationSentTo - PL: Potwierdzenie zwrotu zostało wysłane na adres: - EN: Return confirmation has been sent to: - DE: Bestätigung wurde gesendet an: - FR: La confirmation de retour a été envoyée à: Com_NextSteps - PL: Następne kroki - EN: Next Steps - DE: Nächste Schritte - FR: Prochaines étapes Com_PackProducts - PL: Bezpiecznie zapakuj swoje produkty - EN: Safely pack your products - DE: Verpacken Sie Ihre Produkte sicher - FR: Emballez vos produits en toute sécurité Com_SendPackageTo - PL: Wyślij paczkę na adres: - EN: Send the package to the address: - DE: Senden Sie das Paket an die Adresse: - FR: Envoyez le colis à l'adresse: Com_RefundAfterReceive - PL: Pieniądze zwrócimy niezwłocznie po otrzymaniu i sprawdzeniu Twojej paczki - EN: We will refund the money promptly upon receipt and inspection of your package - DE: Wir erstatten das Geld umgehend nach Erhalt und Überprüfung Ihres Pakets zurück - FR: Nous rembourserons l'argent rapidement après réception et inspection de votre colis ReturnInThreeSteps - PL: Zwróć towar w 3 krokach - EN: Return the product in 3 steps - DE: Geben Sie die Ware in 3 Schritten zurück - FR: Retournez la marchandise en 3 étapes ReturnWithoutReasonInfo - PL: Przysługuje Ci możliwość zwrotu bez podania przyczyny. - EN: You have the right to return the product without giving a reason. - DE: Sie haben das Recht, die Ware ohne Angabe von Gründen zurückzugeben. - FR: Vous avez le droit de retourner la marchandise sans donner de motif. OrEnterOrderNumber - PL: lub podaj numer zamówienia - EN: or enter the order number - DE: oder geben Sie die Bestellnummer ein - FR: ou saisissez le numéro de commande FillForm - PL: Wypełnij formularz - EN: Fill out the form - DE: Füllen Sie das Formular aus - FR: Remplissez le formulaire ReturnOnline - PL: zwrotu online - EN: online return - DE: Online-Rückgabe - FR: retour en ligne SendParcel - PL: Wyślij paczkę - EN: Send the parcel - DE: Paket senden - FR: Envoyer le colis SendParcelToOurAddress - PL: nadaj przesyłkę na nasz adres - EN: send the parcel to our address - DE: senden Sie das Paket an unsere Adresse - FR: envoyez le colis à notre adresse FastSimpleSecure - PL: Szybko, prosto i bezpiecznie. - EN: Fast, simple and secure. - DE: Schnell, einfach und sicher. - FR: Rapide, simple et sécurisé. ReadyForReturn - PL: Gotowy do zwrotu? - EN: Ready for return? - DE: Bereit zur Rückgabe? - FR: Prêt pour le retour ? ReadyForReturnInfo - PL: Kliknij poniżej, aby rozpocząć proces zwrotu. Przeprowadzimy Cię przez wszystkie kroki. - EN: Click below to start the return process. We will guide you through all the steps. - DE: Klicken Sie unten, um den Rückgabeprozess zu starten. Wir führen Sie durch alle Schritte. - FR: Cliquez ci-dessous pour lancer le processus de retour. Nous vous guiderons à travers toutes les étapes. StartReturn - PL: Rozpocznij zwrot - EN: Start return - DE: Rückgabe starten - FR: Commencer le retour ProductReturn - PL: Zwrot produktu - EN: Product return - DE: Produktrückgabe - FR: Retour du produit ProductReturnFormInfo - PL: Wprowadź dane zamówienia, aby zlokalizować zakup i rozpocząć proces zwrotu. Numer zamówienia znajdziesz w e-mailu z potwierdzeniem. - EN: Enter the order details to locate the purchase and start the return process. You will find the order number in the confirmation e-mail. - DE: Geben Sie die Bestelldaten ein, um den Kauf zu lokalisieren und den Rückgabeprozess zu starten. Die Bestellnummer finden Sie in der Bestätigungs-E-Mail. - FR: Saisissez les données de la commande pour localiser l'achat et démarrer le processus de retour. Vous trouverez le numéro de commande dans l'e-mail de confirmation. InvalidOrderNumber - PL: Błędny numer zamówienia. Spróbuj ponownie. - EN: Invalid order number. Please try again. - DE: Ungültige Bestellnummer. Bitte versuchen Sie es erneut. - FR: Numéro de commande incorrect. Veuillez réessayer. FindOrder - PL: Znajdź zamówienie - EN: Find order - DE: Bestellung finden - FR: Trouver la commande LoginToSeeOrdersAndReturn - PL: aby zobaczyć swoje zamówienia i dokonać zwrotu. - EN: to see your orders and make a return. - DE: um Ihre Bestellungen einzusehen und eine Rückgabe vorzunehmen. - FR: pour voir vos commandes et effectuer un retour. RefundLookupError - PL: Wystąpił błąd podczas wyszukiwania zamówienia. Spróbuj ponownie później. - EN: An error occurred while searching for the order. Please try again later. - DE: Bei der Suche nach der Bestellung ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut. - FR: Une erreur s'est produite lors de la recherche de la commande. Veuillez réessayer plus tard.

2. Nowa strona Szybkie zwroty

Funkcjonalność szybkich zwrotów wymaga utworzenia dodatkowej strony statycznej refunds. Wykonaj poniższe kroki.

Plik refunds.html w katalogu głównym szablonu

W katalogu głównym szablonu utwórz nowy plik refunds.html z następującą zawartością:
{% extends '_layout.html' -%}

{% block pageContent -%}
{% include 'static-elements/refunds/refunds.html' -%}
{% endblock -%}

Plik static-elements/refunds/refunds.html

W folderze static-elements utwórz nowy katalog refunds, a w nim plik refunds.html:
<div class="page-padding">
    <h1 class="refunds-page-title refunds-initial-view-js">{{ translations.Returns }}</h1>
    <section class="refunds-container refunds-initial-view-js">
        <div class="refunds-info">
            <h2 class="refunds-info__title">{{ translations.ReturnInThreeSteps }}</h2>
            <p class="refunds-info__intro">{{ translations.ReturnWithoutReasonInfo }}</p>
            <ol class="refunds-steps">
                <li class="refunds-steps__item">
                    <span class="refunds-steps__number">1</span>
                    <p class="refunds-steps__text"><strong>{{ translations.LogIn }}</strong> {{ translations.OrEnterOrderNumber }}</p>
                </li>
                <li class="refunds-steps__item">
                    <span class="refunds-steps__number">2</span>
                    <p class="refunds-steps__text"><strong>{{ translations.FillForm }}</strong> {{ translations.ReturnOnline }}</p>
                </li>
                <li class="refunds-steps__item">
                    <span class="refunds-steps__number">3</span>
                    <p class="refunds-steps__text"><strong>{{ translations.SendParcel }}</strong> - {{ translations.SendParcelToOurAddress }}</p>
                </li>
            </ol>
            <p class="refunds-info__hint">{{ translations.FastSimpleSecure }}</p>
        </div>
        <div class="refunds-cta">
            <div class="refunds-cta__header">
                <h3 class="refunds-cta__title">{{ translations.ReadyForReturn }}</h3>
                <p class="refunds-cta__description">{{ translations.ReadyForReturnInfo }}</p>
            </div>
            {% if usr.Authenticated -%}
            <a class="primary-action-button refunds-cta__button" href="{{ config.DefinedPages.CustomerProfile.Url }}?tab=orders" rel="nofollow" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </a>
            {% else -%}
            <button class="primary-action-button refunds-cta__button start-refund-js" type="button" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </button>
            {% endif -%}
        </div>
    </section>
    {% unless usr.Authenticated -%}
    <section class="refund-form-section refund-form-view-js hidden-js">
        <div class="refund-form">
            <div class="refund-form__header">
                <h2 class="refund-form__title">{{ translations.ProductReturn }}</h2>
                <p class="refund-form__description">{{ translations.ProductReturnFormInfo }}</p>
            </div>
            <form class="refund-form__body refund-form-js" novalidate="" data-error="{{ translations.RefundLookupError }}">
                <div class="form__input-wrapper">
                    <label class="form__input-info input-info-js" for="refundOrderNumber">{{ translations.NumberOfOrder }}</label>
                    <input id="refundOrderNumber" class="form__input-value input-value-js" maxlength="50" name="orderNumber" required="" type="text" />
                    <div class="form__invalid-input validation-info-js validation-required-js hidden-js">{{ translations.FieldRequired }}</div>
                </div>
                <div class="form__input-wrapper">
                    <label class="form__input-info input-info-js" for="refundEmail" data-type="email">{{ translations.EmailAddress }}</label>
                    <input id="refundEmail" class="form__input-value input-value-js" autocomplete="email" maxlength="192" name="email" required="" type="email" />
                    <div class="form__invalid-input validation-info-js validation-required-js hidden-js">{{ translations.FieldRequired }}</div>
                    <div class="form__invalid-input validation-info-js email-valid-js hidden-js">{{ translations.FillProperEmail }}</div>
                </div>
                <button class="primary-action-button refund-form__submit refund-form-submit-js" type="button">
                    {{ translations.FindOrder }}
                </button>
                <p class="refund-form__login-info">{{ translations.HaveAccount }} <a class="refund-form__login-link show-login-popup-js" tabindex="0" role="button" rel="nofollow">{{ translations.LogIn }},</a> {{ translations.LoginToSeeOrdersAndReturn }}</p>
            </form>
        </div>
    </section>
    {% endunless -%}
</div>

Plik js/layout1.js – kod obsługi formularza zwrotu

Na końcu pliku js/layout1.js dodaj poniższy kod odpowiedzialny za walidację i wysłanie formularza wyszukiwania zamówienia (dla niezalogowanego klienta):
$(document).ready(function() {
    refunds.init();
})

const refunds = {
    init: function() {
        this.events();
    },

    findRefundOrder: function(orderNumber, email) {
        return $.post('', {
            __action: 'Order/QuickReturnLookup',
            orderId: orderNumber,
            email: email,
            __csrf: __CSRF
        });
    },

    showForm: function() {
        $('.refunds-initial-view-js').addClass('hidden-js');
        $('.refund-form-view-js').removeClass('hidden-js');
        $('.refund-form-js input[name="orderNumber"]').trigger('focus');
    },

    clearFieldError: function(input) {
        const $input = $(input);
        $input.removeClass('validation-error-js');
        $input.closest('.form__input-wrapper').find('.form__invalid-input').addClass('hidden-js');
    },

    submitForm: async function(button) {
        const $submit = $(button);
        const $form = $submit.closest('.refund-form-js');
        const $orderInput = $form.find('input[name="orderNumber"]');
        const $emailInput = $form.find('input[name="email"]');
        const orderValue = $orderInput.val().trim();
        const emailValue = $emailInput.val().trim();
        const emailRegex = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w{2,}$/;
        let hasError = false;

        $form.find('.form__invalid-input').addClass('hidden-js');
        $form.find('.form__input-value').removeClass('validation-error-js');

        if (orderValue.length === 0) {
            $orderInput.addClass('validation-error-js');
            $orderInput.closest('.form__input-wrapper').find('.validation-required-js').removeClass('hidden-js');
            hasError = true;
        }

        if (emailValue.length === 0) {
            $emailInput.addClass('validation-error-js');
            $emailInput.closest('.form__input-wrapper').find('.validation-required-js').removeClass('hidden-js');
            hasError = true;
        } else if (!emailRegex.test(emailValue)) {
            $emailInput.addClass('validation-error-js');
            $emailInput.closest('.form__input-wrapper').find('.email-valid-js').removeClass('hidden-js');
            hasError = true;
        }

        if (hasError) {
            return;
        }

        $submit.prop('disabled', true);

        try {
            const result = await refunds.findRefundOrder(orderValue, emailValue);
            const action = result.action;
            if (action.Redirect302) {
                globalThis.location.href = action.Redirect302;
                return;
            }
            app.temporaryPopupMessage(undefined, action.Message, action.Type);
        } catch (error) {
            console.error('Refund order lookup failed.', error);
            app.temporaryPopupMessage(undefined, $form.data('error'), 'err');
        } finally {
            $submit.prop('disabled', false);
        }
    },

    events: function() {
        $('body').on('click', '.start-refund-js', function() {
            refunds.showForm();
        });

        $('body').on('input', '.refund-form-js .form__input-value', function() {
            refunds.clearFieldError(this);
        });

        $('body').on('click', '.refund-form-submit-js', function(e) {
            e.preventDefault();
            refunds.submitForm(this);
        });

        $('body').on('keydown', '.refund-form-js input', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
                $(this).closest('.refund-form-js').find('.refund-form-submit-js').trigger('click');
            }
        });
    }
};

Pliki SCSS strony Szybkie zwroty

W folderze scss/static-elements utwórz nowy katalog refunds i umieść w nim trzy pliki: refunds-g.scss, refunds-m.scss i refunds-t.scss. scss/static-elements/refunds/refunds-g.scss:
.refunds-page-title {
    margin: 0 0 24px;
    font-size: 24px;
    font-weight: 500;
    line-height: 32px;
    color: $primaryColorFont;
}

.refunds-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 32px;
    margin-bottom: 32px;
    color: $primaryColorFont;
}

.refunds-info {
    align-self: flex-start;
    display: flex;
    flex-direction: column;
    gap: 16px;
    width: 100%;
    max-width: 800px;

    &__title {
        margin: 0;
        font-size: 20px;
        font-weight: 600;
        line-height: 28px;
        color: $primaryColorFont;
    }

    &__intro {
        margin: 0;
        font-size: 16px;
        font-weight: 500;
        line-height: 24px;
        color: $primaryColorFont;
    }

    &__hint {
        margin: 4px 0 0;
        font-size: 12px;
        font-weight: 400;
        line-height: 20px;
        color: $breadcrumbs;
    }
}

.refunds-steps {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;

    &__item {
        display: flex;
        align-items: center;
        gap: 12px;
    }

    &__number {
        flex-shrink: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        border-radius: 50%;
        background-color: #f3f3f3;
        color: $primaryColor;
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
    }

    &__text {
        margin: 0;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        color: $primaryColorFont;

        strong {
            font-weight: 600;
        }
    }
}

.refunds-cta {
    box-sizing: border-box;
    width: 100%;
    max-width: 578px;
    padding: 40px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 24px;
    background-color: $bgColor;
    border: 1px solid $lightBorderColor;
    border-radius: 8px;

    &__header {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 12px;
        width: 100%;
    }

    &__title {
        margin: 0;
        font-size: 24px;
        font-weight: 600;
        line-height: 32px;
        text-align: center;
        color: $primaryColorFont;
    }

    &__description {
        margin: 0;
        font-size: 16px;
        font-weight: 400;
        line-height: 24px;
        text-align: center;
        color: $breadcrumbs;
    }

    &__button {
        width: 100%;
        text-decoration: none;
    }
}

.refund-form-section {
    display: flex;
    justify-content: center;
    width: 100%;
    margin-bottom: 32px;
}

.refund-form {
    box-sizing: border-box;
    width: 100%;
    max-width: 578px;
    padding: 40px;
    background-color: $bgColor;
    border: 1px solid $lightBorderColor;
    border-radius: 8px;

    &__header {
        display: flex;
        flex-direction: column;
        gap: 12px;
        margin-bottom: 32px;
    }

    &__title {
        margin: 0;
        font-size: 24px;
        font-weight: 600;
        line-height: 32px;
        color: $primaryColorFont;
    }

    &__description {
        margin: 0;
        font-size: 14px;
        font-weight: 400;
        line-height: 20px;
        color: $breadcrumbs;
    }

    &__body {
        display: flex;
        flex-direction: column;
    }

    .form__input-wrapper {
        .form__input-value {
            &.validation-error-js {
                border-color: $dangerColor;
                color: $dangerColor;
            }
        }

        .form__invalid-input {
            position: static;
            display: block;
            margin: 4px 0 0;
            padding-left: 16px;
            text-align: left;
            color: $dangerColor;
            font-size: 12px;
            font-weight: 400;
            line-height: 16px;
        }
    }

    &__submit {
        width: 100%;
        margin-top: 4px;
    }

    &__login-info {
        margin: 16px 0 0;
        text-align: center;
        font-size: 14px;
        font-weight: 400;
        line-height: 20px;
        color: $primaryColorFont;
    }

    &__login-link {
        color: $primaryColor;
        font-weight: 600;
        cursor: pointer;
        text-decoration: none;

        &:hover {
            text-decoration: underline;
        }
    }
}
scss/static-elements/refunds/refunds-m.scss:
@media screen and (max-width: 767px) {
    .refunds-page-title {
        font-size: 20px;
        line-height: 28px;
        margin-bottom: 16px;
    }

    .refunds-container {
        gap: 24px;
        margin-bottom: 24px;
    }

    .refunds-info {
        max-width: 100%;
        gap: 12px;

        &__title {
            font-size: 18px;
            line-height: 24px;
        }

        &__intro {
            font-size: 14px;
            line-height: 22px;
        }
    }

    .refunds-steps {
        &__item {
            align-items: flex-start;
            gap: 10px;
        }

        &__number {
            width: 28px;
            height: 28px;
            font-size: 13px;
        }

        &__text {
            font-size: 13px;
            line-height: 20px;
            padding-top: 3px;
        }
    }

    .refunds-cta {
        padding: 24px;

        &__title {
            font-size: 20px;
            line-height: 28px;
        }

        &__description {
            font-size: 14px;
            line-height: 22px;
        }
    }

    .refund-form {
        padding: 24px;

        &__header {
            margin-bottom: 24px;
        }

        &__title {
            font-size: 20px;
            line-height: 28px;
        }

        &__description {
            font-size: 13px;
            line-height: 18px;
        }

        &__login-info {
            font-size: 13px;
        }
    }
}
scss/static-elements/refunds/refunds-t.scss:
@media screen and (min-width: 768px) and (max-width: 1439px) {
    .refunds-info {
        max-width: 100%;
    }
}

3. Modyfikacje istniejących plików HTML

partials/cart/thx.html

W pliku partials/cart/thx.html znajdź fragment generujący etykietę zgody w sekcji zgód marketingowych:
<label class="cart__tos-label tos-js" tabindex="0" role="checkbox" for="{{ consent.FieldValue }}" aria-checked="false"></label>
Usuń z niego atrybut for="{{ consent.FieldValue }}". Po zmianie linia powinna wyglądać tak:
<label class="cart__tos-label tos-js" tabindex="0" role="checkbox" aria-checked="false"></label>

partials/common/login.html

1. W pliku partials/common/login.html w kontenerze opakowującym formularz dodaj klasę login-container-popup. Zamień linię:
<div class="{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id -%} login-popup-js{% else -%} login-container {% endif -%}">
na:
<div class="{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id -%} login-popup-js login-container-popup{% else -%} login-container {% endif -%}">
2. W warunku otaczającym przycisk zamykający popup logowania usuń warunek and settings.signIn == "popup". Zamień linię:
{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id and settings.signIn == "popup" -%}
na:
{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id -%}

partials/product/amount-stepper.html

W pliku partials/product/amount-stepper.html znajdź blok ustawiający zmienne dla typów complaint i return:
{% if type == 'complaint' or type == 'return' -%}
{% assign reloadClass = '' -%}
{% assign complaintOrReturn = true -%}
{% endif -%}
i dodaj w jego wnętrzu nową linię ustawiającą maksymalną ilość produktu:
{% if type == 'complaint' or type == 'return' -%}
{% assign reloadClass = '' -%}
{% assign complaintOrReturn = true -%}
{% assign max = product.Quantity | Normalize -%}
{% endif -%}

partials/order/products-partials/product-table-header.html

Na samym początku pliku partials/order/products-partials/product-table-header.html dodaj blok przypisujący flagę complaintsOrReturnsEnabled:
{% if config.Complaints.ComplaintsEnabled or config.Complaints.ReturnsEnabled -%}
{% assign complaintsOrReturnsEnabled = true -%}
{% endif -%}

partials/product/products-table.html

Przyciski reklamacji i zwrotu są wyświetlane bezpośrednio w tabeli, zamiast w rozwijanym menu. W pliku partials/product/products-table.html znajdź komórkę z opcjami:
{% if order.Status == 3 and complaintsOrReturnsEnabled and product.CanComplain == true -%}
<button class="pure-button open-dropdown-js" aria-label="{{translations.Options}}">
    <!-- TODO: ikona SVG przycisku opcji – bez zmian, jak w istniejącym pliku -->
</button>
<div class="dropdown dropdown-js hidden-js" style="bottom: auto !important;">
    {% if config.Complaints.ComplaintsEnabled == true and product.CanComplain == true -%}
    <button class="pure-button open-complaint-form-js" data-type="complaint" data-product="{{ product.Url }}">
        {{ translations.Complain }}
    </button>
    {% endif -%}
    {% if config.Complaints.ReturnsEnabled == true and product.CanReturn == true and product.IsSetElement == false -%}
    <button class="pure-button open-complaint-form-js" data-type="return" data-product="{{ product.Url }}">
        {{ translations.Return }}
    </button>
    {% endif -%}
</div>
{% endif -%}
i zastąp ją następującym fragmentem:
{% if order.Status == 3 and complaintsOrReturnsEnabled -%}
{% if config.Complaints.ComplaintsEnabled == true and product.CanComplain == true -%}
<button class="pure-button open-complaint-form-js complaint-action-btn" data-type="complaint" data-product="{{ product.Url }}">
    {{ translations.Complain }}
</button>
{% endif -%}
{% if config.Complaints.ReturnsEnabled == true and product.CanReturn == true and product.IsSetElement == false -%}
<button class="pure-button open-complaint-form-js complaint-action-btn" data-type="return" data-product="{{ product.Url }}">
    {{ translations.Return }}
</button>
{% endif -%}
{% endif -%}
Następnie w tym samym pliku znajdź zewnętrzny warunek otaczający kontenery formularzy reklamacji i zwrotu i poluzuj go (usuń warunek product.CanComplain == true). Zamień:
{% if order.Status == 3 and complaintsOrReturnsEnabled and product.CanComplain == true -%}
na:
{% if order.Status == 3 and complaintsOrReturnsEnabled -%}

partials/customer-profile/orders/order-details.html

W pliku partials/customer-profile/orders/order-details.html wykonaj poniższe zmiany. a) Bloki Opcje (zawierające klasę options submenu z przyciskami akcji zamówienia) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}, aby ukryć je dla niezalogowanych klientów dokonujących szybkiego zwrotu. Wstaw {% unless order.Restricted -%} bezpośrednio przed otwierającym <div class="options submenu">, a {% endunless -%} po jego zamykającym </div>:
{% unless order.Restricted -%}
<div class="options submenu">
    ...
</div>
{% endunless -%}
b) W kontenerze messages-container-js na początku (przed istniejącymi komunikatami typu OrderEditable) dodaj baner informujący o ukrytych danych zamówienia oraz, na końcu kontenera, baner informujący o terminie zwrotu:
{% if order.Restricted -%}
<div class="return-info-banner">
    <!-- TODO: ikona SVG informacyjna (z klasą icon) -->
    {{ translations.RestrictedOrderViewInfo }}
</div>
{% endif -%}
{% if order.Status == 3 and config.Complaints.ReturnsEnabled -%}
<div class="return-info-banner">
    <!-- TODO: ikona SVG informacyjna (z klasą icon) -->
    {{ translations.OrderReturnDeadlineInfo | Format: config.Complaints.DaysToReturn }}
</div>
{% endif -%}
c) We wszystkich miejscach wyświetlających numer telefonu klienta zamień warunki sprawdzające jedynie pusty ciąg na warunki sprawdzające również wartość null. Zamień każde wystąpienie:
{% if order.Customer.DeliveryAddress.PhoneNo != '' -%}
na:
{% if order.Customer.DeliveryAddress.PhoneNo != null and order.Customer.DeliveryAddress.PhoneNo != '' -%}
d) Analogicznie zaktualizuj warunek wyświetlania NIP-u/TIN-u w sekcji danych do faktury. Zamień:
{% elseif order.Customer.TIN != '' -%}
na:
{% elseif order.Customer.TIN != null and order.Customer.TIN != '' -%}
e) W sekcji adresu dostawy zamień otwierający warunek alternatywny {% else -%} (bezpośrednio przed kontenerem z translations.DelivAddress) na bardziej restrykcyjny:
{% elseif order.Customer.DeliveryAddress != null -%}
f) Sekcję wybranego dokumentu (ChoosenDocument) opakuj warunkiem ukrywającym ją dla zamówień typu restricted. Wstaw {% unless order.Restricted -%} przed kontenerem order-details-item z tytułem translations.ChoosenDocument oraz {% endunless -%} za jego zamykającym </div>. g) W sekcji dokumentów zamówienia dodaj do warunku sprawdzenie order.Restricted == false. Zamień:
{% if orderDocumentsSize > 0 -%}
na:
{% if orderDocumentsSize > 0 and order.Restricted == false -%}
h) W sekcji załączników zamówienia dodaj analogiczne sprawdzenie. Zamień:
{% if config.Orders.AttachmentsEnabled and orderAttachmentsSize > 0 -%}
na:
{% if config.Orders.AttachmentsEnabled and orderAttachmentsSize > 0 and order.Restricted == false -%}
i) W sekcji zamówień powiązanych zamień:
{% if order.RelatedOrders[0] -%}
na:
{% if order.RelatedOrders[0] and order.Restricted == false -%}

partials/customer-profile/complaints/complaint-form.html

W pliku partials/customer-profile/complaints/complaint-form.html wprowadź poniższe zmiany. a) W kontenerze amount-stepper-container (wewnątrz warunku {% if type != 'set-return' -%}) na samym początku dodaj nową etykietę:
<span class="amount-stepper-container__label">{{ translations.Quantity }}:</span>
b) Pod sekcją z komentarzem reklamacji/zwrotu (po zamykającym {% endif -%} z sekcji complaint-message-textarea) wewnątrz warunku {% if type != 'set-return' -%} dodaj sekcję wyboru sposobu zwrotu środków:
<div class="refund-method-wrapper">
    <div class="refund-method-wrapper__title">{{ translations.Com_RefundMethod }} <span class="required">*</span></div>
    <label class="refund-method-option">
        <input class="refund-method-option__radio refund-method-radio-js" checked="checked" name="refundMethod" type="radio" value="asPaid" />
        <span class="refund-method-option__box"></span>
        <span class="refund-method-option__label">
            {{ translations.Com_RefundAsPaid }} {% if order.Payment.Name and order.Payment.Name != '' -%} ({{ order.Payment.Name }}){% endif -%}
        </span>
    </label>
    <label class="refund-method-option">
        <input class="refund-method-option__radio refund-method-radio-js" name="refundMethod" type="radio" value="bankAccount" />
        <span class="refund-method-option__box"></span>
        <span class="refund-method-option__label">{{ translations.Com_RefundToBankAccount }}</span>
    </label>
</div>
<div class="form__input-wrapper account-number-wrapper-js hidden-js">
    <label class="form__input-info input-info-js" for="accountNumber">{{ translations.Com_BankAccountNumber }} <span class="required">*</span></label>
    <input id="accountNumber" class="form__input-value input-value-js" disabled="disabled" maxlength="50" name="accountNumber" type="text" />
    <div class="form__invalid-input validation-info-js validation-required-js hidden-js">{{ translations.FieldRequired }}</div>
</div>
c) W sekcji załączników plików zamień prosty licznik file-{{forloop.index}} na prefiks zawierający identyfikator zamówienia, numer produktu i typ formularza. Tuż przed pętlą {% for i in (1..config.Complaints.AttachmentsMaxCount) -%} dodaj nową linię:
{% capture filePrefix -%}file-{{ order.Id }}-{{ product.No }}-{{ type }}{% endcapture -%}
Następnie wewnątrz pętli zamień:
<label class="file" for="file-{{forloop.index}}">
<input id="file-{{forloop.index}}" class="add-attachement-in-complaint-js hidden-js" type="file" /></label>
na:
<label class="file" for="{{ filePrefix }}-{{ forloop.index }}">
<input id="{{ filePrefix }}-{{ forloop.index }}" class="add-attachement-in-complaint-js hidden-js" type="file" /></label>
d) Komunikat sukcesu wyświetlany po wysłaniu formularza ma być inny dla reklamacji, a inny dla zwrotu. Znajdź kontener <div class="success-message-js hidden-js"> i jego dotychczasową zawartość:
<div class="success-message-js hidden-js">
    {{ successInfo }}
</div>
zastąp:
<div class="success-message-js hidden-js">
    {% if complaint -%}
    {{ successInfo }}
    {% else -%}
    <div class="data-form__header return-success__header">
        <button class="close-button hide-container-js closing-modal-js" aria-label="{{ translations.Close }}">
            <!-- TODO: ikona SVG zamknięcia – jak w pozostałych popupach szablonu -->
        </button>
    </div>
    <div class="return-success__icon">
        <!-- TODO: ikona SVG potwierdzenia (zielony "check") -->
    </div>
    <div class="return-success__title">{{ successTitle }}</div>
    <div class="return-success__subtitle">{{ successInfo }}</div>
    {% if order.Customer.Email and order.Customer.Email != '' -%}
    <div class="return-success__email-box">
        <!-- TODO: ikona SVG informacyjna -->
        <div>
            <div>{{ translations.Com_ConfirmationSentTo }}</div>
            <strong>{{ order.Customer.Email }}</strong>
        </div>
    </div>
    {% endif -%}
    <div class="return-success__steps-title">{{ translations.Com_NextSteps }}</div>
    <ol class="return-success__steps">
        <li>{{ translations.Com_PackProducts }}</li>
        <li>{{ translations.Com_SendPackageTo }}
            {% if config.Shop.Address.Street != '' -%} {{ config.Shop.Address.Street }}{% endif -%}
            {% if config.Shop.Address.StreetNo != '' -%} {{ config.Shop.Address.StreetNo }}{% endif -%}
            {% if config.Shop.Address.UnitNo != '' -%}/{{ config.Shop.Address.UnitNo }}{% endif -%}
            {% if config.Shop.Address.ZipCode != '' or config.Shop.Address.City != '' -%}, {{ config.Shop.Address.ZipCode }} {{ config.Shop.Address.City }}{% endif -%}</li>
        <li>{{ translations.Com_RefundAfterReceive }}</li>
    </ol>
    <div class="buttons-container short">
        <button class="primary-action-button hide-container-js closing-modal-js">
            {{ translations.Close }}
        </button>
    </div>
    {% endif -%}
</div>

4. Modyfikacje pliku js/layout-customerprofile0.js

Poniższe zmiany dotyczą pliku js/layout-customerprofile0.js (jego nieskompresowanej wersji, którą po edycji należy ponownie zminifikować do layout-customerprofile0.min.js). a) W funkcji openComplaintForm wewnątrz warunku if (hiddenContainer) – tuż po linii hiddenContainer.querySelector('.success-message-js').classList.add('hidden-js'); – dodaj kod ujawniający nagłówek formularza oraz resetujący wybór sposobu zwrotu do opcji domyślnej:
const mainHeader = hiddenContainer.querySelector(':scope > .data-form__header');
if (mainHeader) {
    mainHeader.classList.remove('hidden-js');
}
hiddenContainer.classList.remove('hidden-js');

const asPaidRadio = hiddenContainer.querySelector('.refund-method-radio-js[value="asPaid"]');
if (asPaidRadio) {
    asPaidRadio.checked = true;
    $(asPaidRadio).trigger('change');
}
(Linia hiddenContainer.classList.remove('hidden-js'); już istnieje – pokazana jest dla kontekstu. Nowe są bloki const mainHeader i const asPaidRadio.) b) W funkcji sendComplaint, w bloku przygotowującym dane formularza – po pętli for (const item of dataFromHTML) dokładającej pola do fd – dodaj fragment dołączający parametr qrHash z adresu URL przy wysyłaniu zwrotu:
if (form.find('input[name="__action"]').val() === 'Order/ReturnAdd') {
    const qrHash = new URLSearchParams(globalThis.location.search).get('qrHash');
    if (qrHash) {
        fd.append('qrHash', qrHash);
    }
}
c) W tej samej funkcji sendComplaint, w callbacku success po pomyślnym wysłaniu, zamień fragment:
form.parents('.add-complaint-form-js').find('.success-message-js').removeClass('hidden-js');
na:
const container = form.parents('.add-complaint-form-js');
container.find('.success-message-js').removeClass('hidden-js');
container.children('.data-form__header').addClass('hidden-js');
d) Na samym końcu pliku js/layout-customerprofile0.js dodaj nowy handler obsługujący przełączanie sposobu zwrotu środków. Pokazuje on / ukrywa pole na numer konta bankowego:
$('body').on('change', '.refund-method-radio-js', function(e) {
    const radio = $(e.currentTarget);
    const form = radio.closest('.form-js');
    const wrapper = form.find('.account-number-wrapper-js');
    const input = wrapper.find('input[name="accountNumber"]');
    if (radio.val() === 'bankAccount' && radio.prop('checked')) {
        wrapper.removeClass('hidden-js');
        input.prop('disabled', false);
        input.prop('required', true);
    } else {
        wrapper.addClass('hidden-js');
        wrapper.find('.validation-required-js').addClass('hidden-js');
        wrapper.find('.form__input-info').removeClass('validation-error');
        input.removeClass('validation-error-js');
        input.prop('required', false);
        input.prop('disabled', true);
        input.val('');
    }
});

5. Modyfikacje plików SCSS profilu klienta

Poniższe style należy dodać do plików scss/static-elements/customer-profile/customer-profile-g.scss (wersja desktop) oraz scss/static-elements/customer-profile/customer-profile-m.scss (wersja mobile). Po zmianach pamiętaj o kompilacji – nie edytuj ręcznie wynikowych plików CSS.

Plik scss/static-elements/customer-profile/customer-profile-g.scss

a) Dla "przyklejonej" kolumny z akcjami reklamacji/zwrotu w tabeli produktów dodaj reguły wewnątrz selektora otaczającego tabelę zamówienia (tam, gdzie znajdują się style dla thead tr th):
thead tr th.open-complaint-form-container-js {
    position: sticky;
    right: 0;
    background: transparent;
    z-index: 5;

    &::before {
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        right: 0;
        width: 200px;
        background: linear-gradient(to right, rgba(255, 255, 255, 0), #fff 50%);
        pointer-events: none;
    }
}

td.complaint-actions-inline {
    white-space: nowrap;
    text-align: right;
    padding-left: 16px;
    padding-right: 8px;
    position: sticky;
    right: 0;
    background: #fff;
    z-index: 2;

    &::before {
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        left: -32px;
        width: 32px;
        background: linear-gradient(to right, rgba(255, 255, 255, 0), #fff 100%);
        pointer-events: none;
    }

    .pure-button.complaint-action-btn {
        display: inline-flex;
        background: transparent;
        border: 0;
        border-radius: 4px;
        color: $primaryColor;
        padding: 4px 8px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
        transition: background-color 150ms ease;

        &:hover,
        &:focus-visible {
            color: $primaryColor;
            background: rgba(0, 0, 0, 0.06);
        }

        & + .complaint-action-btn {
            margin-left: 8px;
        }
    }
}
b) Style hovera dla wiersza tabeli z akcjami reklamacji/zwrotu (umieść w głównym zakresie pliku):
.row {
    &:hover,
    &:focus-within,
    &.hovered-js {
        td.complaint-actions-inline {
            background: #F1DDDE;

            &::before {
                background: linear-gradient(to right, rgba(241, 221, 222, 0), #F1DDDE 100%);
            }
        }
    }

    &.set td.complaint-actions-inline {
        background: #ececec;

        &::before {
            background: linear-gradient(to right, rgba(236, 236, 236, 0), #ececec 100%);
        }
    }
}
c) Style banera informacyjnego (termin zwrotu / ukryte dane zamówienia):
.return-info-banner {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    margin: 0 0 24px 0;
    background: #E8F1F8;
    border: 1px solid #C7DCEE;
    border-radius: 5px;
    font-size: 14px;
    line-height: 20px;
    color: #2C3E50;

    .icon {
        flex-shrink: 0;
        fill: #4A90BC;
    }

    strong {
        font-weight: 600;
    }
}
d) Style sekcji wyboru sposobu zwrotu środków oraz radio-buttonów:
.refund-method-wrapper {
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin-bottom: 24px;

    &__title {
        color: $primaryColorFont;
        font-size: 14px;
        font-weight: 500;
        line-height: 20px;
    }
}

.refund-method-option {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;

    &__radio {
        display: none;

        &:checked ~ .refund-method-option__box {
            border-color: $primaryColor;

            &::after {
                content: "";
                display: block;
                width: 8px;
                height: 8px;
                border-radius: 50%;
                background: $primaryColor;
            }
        }
    }

    &__box {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 16px;
        height: 16px;
        border: 1px solid #767676;
        border-radius: 50%;
        flex-shrink: 0;
    }

    &__label {
        font-size: 14px;
        line-height: 20px;
    }
}
e) Style ekranu sukcesu po wysłaniu zwrotu (m.in. ikona, tytuł, lista kolejnych kroków):
.add-complaint-form-js .characters-length {
    margin-top: 0;
    bottom: 23px;
}

.add-complaint-form-js {
    .quantity__plus.disabled-js,
    .quantity__minus.disabled-js {
        opacity: 0.4;
    }
}

.add-complaint-form-js .data-form__header.return-success__header {
    margin-bottom: 8px;
}

.return-success {
    &__icon {
        display: flex;
        justify-content: center;
        margin-bottom: 16px;

        svg {
            fill: #2E7D32;
        }
    }

    &__title {
        text-align: center;
        font-size: 20px;
        font-weight: 600;
        line-height: 28px;
        color: $primaryColorFont;
        margin-bottom: 8px;
    }

    &__subtitle {
        text-align: center;
        font-size: 14px;
        line-height: 20px;
        color: $labelsColor;
        padding-bottom: 24px;
        border-bottom: 1px solid #E7E7E7;
        margin-bottom: 24px;
    }

    &__email-box {
        display: flex;
        align-items: flex-start;
        gap: 12px;
        padding: 12px 16px;
        background: #F0F6FC;
        border: 1px solid #D6E4F0;
        border-radius: 6px;
        margin-bottom: 24px;
        font-size: 14px;
        line-height: 20px;
        color: $primaryColorFont;

        svg {
            fill: #1976D2;
            flex-shrink: 0;
            margin-top: 2px;
        }
    }

    &__steps-title {
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
        color: $primaryColorFont;
        margin-bottom: 12px;
    }

    &__steps {
        margin: 0 0 24px;
        padding-left: 20px;
        font-size: 14px;
        line-height: 20px;
        color: $primaryColorFont;

        li {
            margin-bottom: 8px;

            &:last-child {
                margin-bottom: 0;
            }
        }
    }
}
f) Uzupełnij wnętrze selektora .file-attachements-wrapper o style dla kontenera pojedynczego załącznika:
.file-container {
    .file {
        align-items: center;
        font-weight: 400;
        color: $primaryColorFont;
        justify-content: flex-start;
    }

    .icon-js svg {
        fill: $primaryColorFont;
    }

    .clear-file-input-js {
        flex-shrink: 0;
        display: flex;
        align-items: center;

        svg {
            width: 14px;
            height: 14px;
            fill: $primaryColor;
        }
    }
}

Plik scss/static-elements/customer-profile/customer-profile-m.scss

Na końcu pliku customer-profile-m.scss dodaj reguły dopasowujące przyciski reklamacji/zwrotu do widoku mobilnego (układają się one wówczas jeden pod drugim):
.eshop__table-container {
    thead tr th.open-complaint-form-container-js::before {
        width: 100px;
    }

    td.complaint-actions-inline {
        .pure-button.complaint-action-btn {
            display: block;
            width: max-content;
            margin-left: auto;
            text-align: right;

            & + .complaint-action-btn {
                margin-left: auto;
                margin-top: 4px;
            }
        }
    }
}
Po wprowadzeniu wszystkich powyższych zmian w szablonie Rubin pamiętaj o kompilacji oraz minifikacji plików js i scss, zgodnie z artykułem dostępnym pod linkiem https://pomoc.comarchesklep.pl/artykul/kompilacja-i-minifikacja-plikow/.

Szablon Szafir

1. Tłumaczenia

W panelu administracyjnym sklepu dodaj nowe klucze tłumaczeń wymagane przez funkcjonalność szybkich zwrotów w szablonie Szafir. OrderReturnDeadlineInfo - PL: Zamówienie można zwrócić w ciągu {0} dni od daty dostawy. - EN: You can return the order within {0} days from the delivery date. - DE: Sie können die Bestellung innerhalb von {0} Tagen ab Lieferdatum zurückgeben. - FR: Vous pouvez retourner la commande dans les {0} jours suivant la date de livraison. RestrictedOrderViewInfo - PL: Wybrane dane zamówienia zostały ukryte ze względów bezpieczeństwa. Możesz zwrócić produkty bez logowania. - EN: Some order details are hidden for security reasons. You can return products without signing in. - DE: Einige Bestelldetails wurden aus Sicherheitsgründen ausgeblendet. Sie können Produkte ohne Anmeldung zurücksenden. - FR: Certaines informations de la commande ont été masquées pour des raisons de sécurité. Vous pouvez retourner des produits sans vous connecter. RefundMethod - PL: Sposób zwrotu środków - EN: Refund method - DE: Rückerstattungsmethode - FR: Méthode de remboursement RefundAsPaid - PL: Tak jak zapłacono - EN: As paid - DE: Wie bezahlt - FR: Comme payé RefundToBankAccount - PL: Na konto bankowe - EN: To bank account - DE: Auf Bankkonto - FR: Sur le compte bancaire BankAccountNumber - PL: Nr konta bankowego - EN: Bank account number - DE: Bankkontonummer - FR: Numéro de compte bancaire ReturnConfirmationTitle - PL: Gotowe! Przyjęliśmy Twoje zgłoszenie - EN: Done! We have received your request - DE: Fertig! Wir haben Ihre Anfrage erhalten - FR: Terminé! Nous avons reçu votre demande ReturnConfirmationInfo - PL: Przygotuj paczkę i odeślij ją do nas – wszystkie szczegóły znajdziesz poniżej. - EN: Prepare the package and send it back to us – all details can be found below. - DE: Bereiten Sie das Paket vor und senden Sie es an uns zurück – alle Details finden Sie unten. - FR: Préparez le colis et renvoyez-le nous – tous les détails se trouvent ci-dessous. ReturnConfirmationEmailSent - PL: Potwierdzenie zwrotu zostało wysłane na adres: - EN: Return confirmation has been sent to: - DE: Die Rücksendebestätigung wurde gesendet an: - FR: La confirmation de retour a été envoyée à: NextSteps - PL: Następne kroki - EN: Next steps - DE: Nächste Schritte - FR: Prochaines étapes ReturnStep1 - PL: Bezpiecznie zapakuj swoje produkty - EN: Safely pack your products - DE: Verpacken Sie Ihre Produkte sicher - FR: Emballez vos produits en toute sécurité ReturnStep2Address - PL: Wyślij paczkę na adres - EN: Send the package to - DE: Senden Sie das Paket an - FR: Envoyez le colis à ReturnStep3 - PL: Pieniądze zwrócimy niezwłocznie po otrzymaniu i sprawdzeniu Twojej paczki. - EN: We will refund the money promptly after receiving and checking your package. - DE: Wir erstatten das Geld umgehend nach Erhalt und Überprüfung Ihres Pakets. - FR: Nous rembourserons l'argent rapidement après réception et vérification de votre colis. ReturnInThreeSteps - PL: Zwróć towar w 3 krokach - EN: Return the product in 3 steps - DE: Geben Sie die Ware in 3 Schritten zurück - FR: Retournez la marchandise en 3 étapes ReturnWithoutReasonInfo - PL: Przysługuje Ci możliwość zwrotu bez podania przyczyny. - EN: You have the right to return the product without giving a reason. - DE: Sie haben das Recht, die Ware ohne Angabe von Gründen zurückzugeben. - FR: Vous avez le droit de retourner la marchandise sans donner de motif. OrEnterOrderNumber - PL: lub podaj numer zamówienia - EN: or enter the order number - DE: oder geben Sie die Bestellnummer ein - FR: ou saisissez le numéro de commande FillForm - PL: Wypełnij formularz - EN: Fill out the form - DE: Füllen Sie das Formular aus - FR: Remplissez le formulaire ReturnOnline - PL: zwrotu online - EN: online return - DE: Online-Rückgabe - FR: retour en ligne SendParcel - PL: Wyślij paczkę - EN: Send the parcel - DE: Paket senden - FR: Envoyer le colis SendParcelToOurAddress - PL: nadaj przesyłkę na nasz adres - EN: send the parcel to our address - DE: senden Sie das Paket an unsere Adresse - FR: envoyez le colis à notre adresse FastSimpleSecure - PL: Szybko, prosto i bezpiecznie. - EN: Fast, simple and secure. - DE: Schnell, einfach und sicher. - FR: Rapide, simple et sécurisé. ReadyForReturn - PL: Gotowy do zwrotu? - EN: Ready for return? - DE: Bereit zur Rückgabe? - FR: Prêt pour le retour ? ReadyForReturnInfo - PL: Kliknij poniżej, aby rozpocząć proces zwrotu. Przeprowadzimy Cię przez wszystkie kroki. - EN: Click below to start the return process. We will guide you through all the steps. - DE: Klicken Sie unten, um den Rückgabeprozess zu starten. Wir führen Sie durch alle Schritte. - FR: Cliquez ci-dessous pour lancer le processus de retour. Nous vous guiderons à travers toutes les étapes. StartReturn - PL: Rozpocznij zwrot - EN: Start return - DE: Rückgabe starten - FR: Commencer le retour ProductReturn - PL: Zwrot produktu - EN: Product return - DE: Produktrückgabe - FR: Retour du produit ProductReturnFormInfo - PL: Wprowadź dane zamówienia, aby zlokalizować zakup i rozpocząć proces zwrotu. Numer zamówienia znajdziesz w e-mailu z potwierdzeniem. - EN: Enter the order details to locate the purchase and start the return process. You will find the order number in the confirmation e-mail. - DE: Geben Sie die Bestelldaten ein, um den Kauf zu lokalisieren und den Rückgabeprozess zu starten. Die Bestellnummer finden Sie in der Bestätigungs-E-Mail. - FR: Saisissez les données de la commande pour localiser l'achat et démarrer le processus de retour. Vous trouverez le numéro de commande dans l'e-mail de confirmation. InvalidOrderNumber - PL: Błędny numer zamówienia. Spróbuj ponownie. - EN: Invalid order number. Please try again. - DE: Ungültige Bestellnummer. Bitte versuchen Sie es erneut. - FR: Numéro de commande incorrect. Veuillez réessayer. FindOrder - PL: Znajdź zamówienie - EN: Find order - DE: Bestellung finden - FR: Trouver la commande LoginToSeeOrdersAndReturn - PL: aby zobaczyć swoje zamówienia i dokonać zwrotu. - EN: to see your orders and make a return. - DE: um Ihre Bestellungen einzusehen und eine Rückgabe vorzunehmen. - FR: pour voir vos commandes et effectuer un retour. RefundLookupError - PL: Wystąpił błąd podczas wyszukiwania zamówienia. Spróbuj ponownie później. - EN: An error occurred while searching for the order. Please try again later. - DE: Bei der Suche nach der Bestellung ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut. - FR: Une erreur s'est produite lors de la recherche de la commande. Veuillez réessayer plus tard.

2. Nowa strona Szybkie zwroty

Funkcjonalność szybkich zwrotów wymaga utworzenia dodatkowej strony statycznej refunds. Wykonaj poniższe kroki.

Plik refunds.html w katalogu głównym szablonu

W katalogu głównym szablonu utwórz nowy plik refunds.html z następującą zawartością:
{% extends '_layout.html' %}

{% block content %}
{% include 'static-elements/refunds/refunds.html' %}
{% endblock %}

Plik static-elements/refunds/refunds.html

W folderze static-elements utwórz nowy katalog refunds, a w nim plik refunds.html:
<section class="refunds refunds-js form-js">
    <p class="refunds-header refunds-initial-view-js">{{ translations.Returns }}</p>
    <div class="refunds-intro refunds-initial-view-js">
        <div class="refunds-info">
            <p class="refunds-info-title">{{ translations.ReturnInThreeSteps }}</p>
            <p class="refunds-info-desc">{{ translations.ReturnWithoutReasonInfo }}</p>
            <ol class="refunds-steps">
                <li class="refunds-steps-item">
                    <span class="refunds-steps-number">1</span>
                    <p class="refunds-steps-text"><strong>{{ translations.SignIn }}</strong> {{ translations.OrEnterOrderNumber }}</p>
                </li>
                <li class="refunds-steps-item">
                    <span class="refunds-steps-number">2</span>
                    <p class="refunds-steps-text"><strong>{{ translations.FillForm }}</strong> {{ translations.ReturnOnline }}</p>
                </li>
                <li class="refunds-steps-item">
                    <span class="refunds-steps-number">3</span>
                    <p class="refunds-steps-text"><strong>{{ translations.SendParcel }}</strong> - {{ translations.SendParcelToOurAddress }}</p>
                </li>
            </ol>
            <p class="refunds-info-hint">{{ translations.FastSimpleSecure }}</p>
        </div>
        <div class="refunds-cta">
            <p class="refunds-cta-title">{{ translations.ReadyForReturn }}</p>
            <p class="refunds-cta-desc">{{ translations.ReadyForReturnInfo }}</p>
            {% if usr.Authenticated -%}
            <a class="refunds-cta-button" href="{{ config.DefinedPages.CustomerProfile.Url }}?tab=orders" rel="nofollow" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </a>
            {% else -%}
            <button class="refunds-cta-button start-refund-js" type="button" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </button>
            {% endif -%}
        </div>
    </div>
    {% unless usr.Authenticated -%}
    <div class="refunds-form-section refund-form-view-js hidden-js">
        <div class="refunds-form">
            <p class="refunds-form-title">{{ translations.ProductReturn }}</p>
            <p class="refunds-form-desc">{{ translations.ProductReturnFormInfo }}</p>
            <div class="refund-form-js" data-cp-url="{{ config.DefinedPages.CustomerProfile.Url }}">
                <div class="message-bar-ui warning-bar-ui refund-lookup-error-js hidden-js">{{ translations.RefundLookupError }}</div>
                <div class="form__input-wrapper">
                    <label class="form__input-info form__input-info-js" for="refundOrderNumber" data-type="text">{{ translations.OrderNumber }} <span class="required-ui">*</span></label>
                    <input id="refundOrderNumber" class="form__input-value form__input-value-js" maxlength="50" name="orderNumber" required="" type="text" aria-label="{{ translations.OrderNumber }}" />
                    <span class="error-ui validation-info-js validation-required-js hidden-js">{{ translations.RequiredField }}</span>
                </div>
                <div class="form__input-wrapper">
                    <label class="form__input-info form__input-info-js" for="refundEmail" data-type="email">{{ translations.EmailAddress }} <span class="required-ui">*</span></label>
                    <input id="refundEmail" class="form__input-value form__input-value-js" autocomplete="email" maxlength="192" name="email" required="" type="email" aria-label="{{ translations.EmailAddress }}" />
                    <span class="error-ui validation-info-js validation-required-js hidden-js">{{ translations.RequiredField }}</span>
                    <span class="error-ui validation-info-js email-valid-js hidden-js">{{ translations.FillProperEmail }}</span>
                </div>
                <div class="required-fields-info-ui form__required-fields-info"><span class="required-ui">* </span>{{ translations.RequiredFields }}</div>
                <button class="refunds-form-submit refund-form-submit-js" type="button" aria-label="{{ translations.FindOrder }}">
                    {{ translations.FindOrder }}
                </button>
                <p class="refunds-form-login-info">{{ translations.HaveAccount }} <a class="refunds-form-login-link" href="{{ config.DefinedPages.Login.Url }}" rel="nofollow">{{ translations.SignIn }}</a>, {{ translations.LoginToSeeOrdersAndReturn }}</p>
            </div>
        </div>
    </div>
    {% endunless -%}
</section>

Plik js/layout0.js – kod obsługi formularza zwrotu

Na końcu pliku js/layout0.js dodaj poniższy kod odpowiedzialny za walidację i wysłanie formularza wyszukiwania zamówienia (dla niezalogowanego klienta). Po zapisaniu pliku pamiętaj o zminifikowaniu go do layout0.min.js.
const refunds = {
    findRefundOrder(orderNumber, email) {
        return $.post('', {
            __action: 'Order/QuickReturnLookup',
            orderId: orderNumber,
            email: email,
            __csrf: __CSRF
        });
    },

    showForm() {
        document.querySelectorAll('.refunds-initial-view-js').forEach((el) => el.classList.add('hidden-js'));
        document.querySelectorAll('.refund-form-view-js').forEach((el) => el.classList.remove('hidden-js'));
        document.querySelector('.refund-form-js input[name="orderNumber"]')?.focus();
    },

    clearFieldError(input) {
        input.classList.remove('validation-error-ui', 'validation-error-lq');
        input.closest('.form__input-wrapper')
            ?.querySelectorAll('.error-ui')
            .forEach((el) => el.classList.add('hidden-js'));
    },

    markFieldError(input, errorSelector) {
        input.classList.add('validation-error-ui', 'validation-error-lq');
        input.closest('.form__input-wrapper')?.querySelector(errorSelector)?.classList.remove('hidden-js');
    },

    validateForm({ orderInput, emailInput }) {
        const orderValue = orderInput.value.trim();
        const emailValue = emailInput.value.trim();
        const emailRegex = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w{2,}$/;
        let hasError = false;

        if (orderValue.length === 0) {
            refunds.markFieldError(orderInput, '.validation-required-js');
            hasError = true;
        }

        if (emailValue.length === 0) {
            refunds.markFieldError(emailInput, '.validation-required-js');
            hasError = true;
        } else if (!emailRegex.test(emailValue)) {
            refunds.markFieldError(emailInput, '.email-valid-js');
            hasError = true;
        }

        return { hasError, orderValue };
    },

    async submitForm(button) {
        const form = button.closest('.refund-form-js');
        if (!form) {
            return;
        }
        const orderInput = form.querySelector('input[name="orderNumber"]');
        const emailInput = form.querySelector('input[name="email"]');

        form.querySelectorAll('.error-ui').forEach((el) => el.classList.add('hidden-js'));
        form.querySelector('.refund-lookup-error-js')?.classList.add('hidden-js');
        form.querySelectorAll('.form__input-value').forEach((el) => {
            el.classList.remove('validation-error-ui', 'validation-error-lq');
        });

        const { hasError, orderValue } = refunds.validateForm({ orderInput, emailInput });
        if (hasError) {
            return;
        }

        button.disabled = true;
        const errorBar = form.querySelector('.refund-lookup-error-js');
        try {
            const result = await refunds.findRefundOrder(orderValue, emailInput.value.trim());
            const action = result.action;
            if (action.Redirect302) {
                globalThis.location.href = action.Redirect302;
                return;
            }
            if (errorBar) {
                errorBar.textContent = action.Message;
                errorBar.classList.remove('hidden-js');
            }
        } catch (error) {
            console.error('Refund order lookup failed.', error);
            errorBar?.classList.remove('hidden-js');
        } finally {
            button.disabled = false;
        }
    }
};

js.delegate(document.body, 'click', '.start-refund-js', () => refunds.showForm());

js.delegate(document.body, 'input', '.refund-form-js .form__input-value', function () {
    refunds.clearFieldError(this);
});

js.delegate(document.body, 'click', '.refund-form-submit-js', function (event) {
    event.preventDefault();
    refunds.submitForm(this);
});

js.delegate(document.body, 'keydown', '.refund-form-js input', function (event) {
    if (event.key !== 'Enter') {
        return;
    }
    event.preventDefault();
    this.closest('.refund-form-js')?.querySelector('.refund-form-submit-js')?.click();
});

Pliki SCSS strony Szybkie zwroty

W folderze scss/static-elements utwórz nowy katalog refunds i umieść w nim dwa pliki: refunds-g.scss (style desktop) oraz refunds-m.scss (style mobilne). scss/static-elements/refunds/refunds-g.scss:
.refunds {
    padding: 40px 110px;
    background-color: $bgColor;
    color: $primaryColorFont;

    .refunds-header {
        display: block;
        width: 100%;
        margin: 0 0 24px;
        color: $primaryColorFont;
        text-align: left;
        font-size: 32px;
        font-weight: 500;
        line-height: 42px;
        letter-spacing: 0.8px;
    }

    .refunds-intro {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 32px;
        margin-bottom: 40px;
    }

    .refunds-info {
        align-self: flex-start;
        width: 100%;
        max-width: 800px;
        display: flex;
        flex-direction: column;
        gap: 16px;
        color: $primaryColorFont;

        @media screen and (min-width: 769px) and (max-width: 1279px) {
            max-width: 100%;
        }
    }

    .refunds-info-title {
        margin: 0;
        font-size: 20px;
        font-weight: 500;
        line-height: 28px;
        letter-spacing: 0.4px;
    }

    .refunds-info-desc {
        margin: 0;
        font-size: 16px;
        font-weight: 400;
        line-height: 24px;
        letter-spacing: 0.3px;
    }

    .refunds-info-hint {
        margin: 4px 0 0;
        color: $secondaryColorFont;
        font-size: 12px;
        font-weight: 400;
        line-height: 20px;
        letter-spacing: 0.2px;
    }

    .refunds-steps {
        list-style: none;
        margin: 0;
        padding: 0;
        display: flex;
        flex-direction: column;
        gap: 12px;
    }

    .refunds-steps-item {
        display: flex;
        align-items: center;
        gap: 12px;
    }

    .refunds-steps-number {
        flex-shrink: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        border-radius: 50%;
        background-color: $formsBgColor;
        color: $primaryColor;
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
    }

    .refunds-steps-text {
        margin: 0;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        letter-spacing: 0.3px;

        strong {
            font-weight: 600;
        }
    }

    .refunds-cta {
        box-sizing: border-box;
        width: 100%;
        max-width: 578px;
        padding: 32px 40px;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 12px;
        background-color: $bgColor;
        border: 1px solid $lightBorderColor;
    }

    .refunds-cta-title {
        margin: 0;
        text-align: center;
        font-size: 22px;
        font-weight: 500;
        line-height: 30px;
        letter-spacing: 0.5px;
        color: $primaryColorFont;
    }

    .refunds-cta-desc {
        margin: 0;
        text-align: center;
        color: $secondaryColorFont;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        letter-spacing: 0.3px;
    }

    .refunds-cta-button,
    .refunds-form-submit {
        display: inline-block;
        width: 100%;
        margin-top: 8px;
        padding: 12px 16px;
        background: $btnSolidBgColor;
        color: $btnSolidTextColor;
        border: 1px solid $btnSolidBgColor;
        font-size: 14px;
        font-weight: 500;
        line-height: 20px;
        text-align: center;
        text-decoration: none;
        cursor: pointer;
        transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;

        &:hover,
        &:focus {
            background: $btnSolidHoverBgColor;
            color: $btnSolidHoverTextColor;
            border-color: $btnSolidHoverBgColor;
        }

        &[disabled],
        &[disabled]:hover {
            background: $btnDisabledBg;
            border-color: $btnDisabledFont;
            color: $btnDisabledFont;
            cursor: default;
        }
    }

    .refunds-form-section {
        display: flex;
        justify-content: center;
        width: 100%;
        margin-top: 32px;
        margin-bottom: 40px;
    }

    .refunds-form {
        box-sizing: border-box;
        width: 100%;
        max-width: 578px;
        padding: 32px 40px;
        background-color: $bgColor;
        border: 1px solid $lightBorderColor;
    }

    .refunds-form-title {
        margin: 0 0 8px;
        font-size: 22px;
        font-weight: 500;
        line-height: 30px;
        letter-spacing: 0.5px;
        color: $primaryColorFont;
    }

    .refunds-form-desc {
        margin: 0 0 20px;
        color: $secondaryColorFont;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        letter-spacing: 0.3px;
    }

    .refund-form-js {
        display: flex;
        flex-direction: column;

        .form__input-wrapper {
            position: relative;
            margin-bottom: 16px;

            .form__input-info {
                display: block;
                margin: 0 0 4px;
                color: $primaryColorFont;
                font-size: 13px;
                font-weight: 400;
                line-height: 18px;
            }

            input {
                width: 100%;
                height: 36px;
                margin: 0;
                padding: 0 10px;
                box-sizing: border-box;
                border: 1px solid $lightBorderColor;
                font-size: 14px;

                &::placeholder {
                    font-size: 14px;
                }

                &.validation-error-ui,
                &.validation-error-lq {
                    border-color: $dangerColor;
                    color: $dangerColor;
                }
            }

            .error-ui {
                position: static;
                display: block;
                margin: 4px 0 0;
                padding: 0;
                text-align: left;
                color: $dangerColor;
                font-size: 12px;
                font-weight: 400;
                line-height: 16px;
            }
        }

        .form__required-fields-info {
            margin: 4px 0 16px;
            color: $primaryColorFont;
            font-size: 12px;
            font-weight: 300;
            line-height: 18px;
        }
    }

    .refunds-form-login-info {
        margin: 12px 0 0;
        text-align: center;
        color: $primaryColorFont;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
    }

    .refunds-form-login-link {
        color: $primaryColor;
        font-weight: 600;
        cursor: pointer;
        text-decoration: none;

        &:hover {
            text-decoration: underline;
        }
    }
}
scss/static-elements/refunds/refunds-m.scss:
@media screen and (max-width: 768px) {
    .refunds {
        padding: 20px 16px;

        .refunds-header {
            font-size: 24px;
            line-height: 32px;
            margin-bottom: 16px;
        }

        .refunds-intro {
            gap: 24px;
            margin-bottom: 24px;
        }

        .refunds-info {
            max-width: 100%;
            gap: 12px;
        }

        .refunds-info-title {
            font-size: 18px;
            line-height: 24px;
        }

        .refunds-info-desc {
            font-size: 14px;
            line-height: 22px;
        }

        .refunds-steps-item {
            align-items: flex-start;
            gap: 10px;
        }

        .refunds-steps-number {
            width: 28px;
            height: 28px;
            font-size: 13px;
        }

        .refunds-steps-text {
            font-size: 13px;
            line-height: 20px;
            padding-top: 3px;
        }

        .refunds-cta {
            padding: 24px;
        }

        .refunds-cta-title {
            font-size: 20px;
            line-height: 28px;
        }

        .refunds-form-section {
            margin-top: 20px;
            margin-bottom: 24px;
        }

        .refunds-form {
            padding: 24px;
            border: none;
        }

        .refunds-form-title {
            font-size: 20px;
            line-height: 28px;
        }

        .refunds-form-desc {
            margin-bottom: 16px;
        }

        .refunds-form-login-info {
            font-size: 13px;
        }
    }
}

3. Modyfikacje istniejących plików HTML

partials/customer-profile/orders/order-details.html

W pliku partials/customer-profile/orders/order-details.html wykonaj poniższe zmiany. a) Blok z przyciskami akcji nawigacji zamówienia (zawierający {% if order.EditingAllowed -%}, opcje anulowania, edycji, ponowienia, druku itp.) opakuj warunkiem ukrywającym go dla zamówień typu restricted. Bezpośrednio po linii z elementem <li class="active-ui only-text-ui ...">...</li> wstaw:
{% unless order.Restricted -%}
a tuż przed zamykającym znacznikiem </ul> tej samej nawigacji dodaj:
{% endunless -%}
b) Na początku kontenera messages-container-lq messages-container-ui (zaraz po jego otwarciu) dodaj baner informujący o ukrytych danych zamówienia:
{% if order.Restricted -%}
<div class="message-bar-ui no-margin-ui">
    <i class="not-clickable-ui ti-info-alt"></i>
    {{ translations.RestrictedOrderViewInfo }}
</div>
{% endif -%}
c) Na końcu tego samego kontenera (przed zamykającym </div>) dodaj baner informujący o terminie zwrotu wraz z przypisaniem flagi complaintsOrReturnsEnabled:
{% if config.Complaints.ComplaintsEnabled or config.Complaints.ReturnsEnabled -%}
{% assign complaintsOrReturnsEnabled = true -%}
{% endif -%}

{% if order.Status == 3 and complaintsOrReturnsEnabled -%}
<div class="message-bar-ui no-margin-ui">
    <i class="not-clickable-ui ti-info-alt"></i>
    {{translations.OrderReturnDeadlineInfo | Format: config.Complaints.DaysToReturn}}
</div>
{% endif -%}
d) Blok z przyciskami akcji wewnątrz info-container-js (zawierający przyciski order.CanCancel, edycji, ponowienia zakupu itd.) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}. Wstaw {% unless order.Restricted -%} bezpośrednio przed pierwszym {% if order.CanCancel -%}, a {% endunless -%} po zamykającym warunku odpowiedzialnym za popup potwierdzenia ({% include 'partials/common/confirmation-popup.html' with 0 -%}). e) W sekcji wyświetlającej dokumenty zamówienia zamień:
{% if order.Documents %}
na:
{% if order.Documents and order.Restricted == false %}
f) We wszystkich miejscach wyświetlających numer telefonu klienta zamień warunki sprawdzające jedynie pusty ciąg na warunki sprawdzające również wartość null. Zamień każde wystąpienie:
{% if order.Customer.DeliveryAddress.PhoneNo != '' -%}
na:
{% if order.Customer.DeliveryAddress.PhoneNo != null and order.Customer.DeliveryAddress.PhoneNo != '' -%}
g) Każdą sekcję z tytułem translations.ChoosenDocument opakuj warunkiem ukrywającym ją dla zamówień restricted. Wstaw {% unless order.Restricted -%} bezpośrednio przed <div class="name-ui mt20-ui">{{ translations.ChoosenDocument }}</div> oraz {% endunless -%} po jej zamykającym </div>. h) W sekcji wyświetlającej alternatywny adres dostawy zamień warunek {% else -%} (bezpośrednio przed order-info-item-ui z translations.DelivAddress) na bardziej restrykcyjny:
{% elseif order.Customer.DeliveryAddress != null -%}
i) W sekcji danych do faktury zamień warunek wyświetlania NIP-u/TIN-u. Zamień:
{% elseif order.Customer.TIN != '' -%}
na:
{% elseif order.Customer.TIN != null and order.Customer.TIN != '' -%}
j) W sekcji załączników zamówienia (kontener attachements-ui remarks-ui) zamień warunek otaczający. Zamień:
{% if config.Orders.AttachmentsEnabled -%}
na:
{% if config.Orders.AttachmentsEnabled and order.Restricted == false -%}
k) W sekcji zamówień powiązanych (kontener remarks-ui eshop-order-ui) zamień:
{% if order.RelatedOrders -%}
na:
{% if order.RelatedOrders and order.Restricted == false -%}

partials/customer-profile/complaints/complaint-form.html

W pliku partials/customer-profile/complaints/complaint-form.html wprowadź poniższe zmiany. a) W kontenerze amount-stepper-container-ui amount-stepper-container-lq (wewnątrz warunku {% if type != 'set-return' -%}) na samym początku dodaj etykietę widoczną tylko dla zwrotów:
{% unless complaint -%}
<span class="amount-stepper-label-ui">{{ translations.Quantity }}:</span>
{% endunless -%}
b) Bezpośrednio po zamknięciu kontenera amount-stepper-container-ui (po jego </div> i odpowiadającym {% endif -%}) dodaj sekcję wyboru sposobu zwrotu środków – widoczną tylko w formularzu zwrotu:
{% unless complaint -%}
<div class="refund-method-container-ui refund-method-container-js">
    <label class="label-ui" for="refundMethod">{{ translations.RefundMethod }} <span class="required-ui">*</span></label>
    <div>
        <span class="select-background-ui">
            <select id="refundMethod" class="refund-method-select-js" name="refundMethod" aria-label="{{ translations.RefundMethod }}">
                <option selected="selected" value="original">{{ translations.RefundAsPaid }} {% if order.Payment.Name and order.Payment.Name != "" -%} ({{ order.Payment.Name }}){% endif -%}</option>
                <option value="bank">{{ translations.RefundToBankAccount }}</option>
            </select>
        </span>
        <i class="ti-angle-down select-arrow-ui"></i>
    </div>
    <div class="bank-account-container-ui bank-account-container-js hidden-js">
        <label class="label-ui" for="bankAccountNumber">{{ translations.BankAccountNumber }} <span class="required-ui">*</span></label>
        <div>
            <input id="bankAccountNumber" disabled="disabled" name="bankAccountNumber" type="text" placeholder="{{ translations.BankAccountNumber }}" aria-label="{{ translations.BankAccountNumber }}" />
            <span class="error-ui validation-info-js validation-required-js hidden-js">{{ translations.RequiredField }}</span>
        </div>
    </div>
</div>
{% endunless -%}
c) Komunikat sukcesu wyświetlany po wysłaniu formularza ma być inny dla reklamacji, a inny dla zwrotu. Znajdź kontener <div class="success-message-js hidden-js"> wraz z jego dotychczasową zawartością (komunikat ComplaintAdded + successInfo):
<div class="success-message-js hidden-js">
    <div class="complaint-added-ui">
        <i class="va-mid-ui ti-check"></i>
        <span class="va-mid-ui line-height-1-ui">
            {{ translations.ComplaintAdded }}
        </span>
    </div>
    <div class="info-ui">{{ successInfo }}</div>
</div>
i zastąp go nową, rozszerzoną wersją z dwoma wariantami (reklamacja / zwrot):
<div class="success-message-js hidden-js">
    {% if complaint -%}
    <div class="complaint-added-ui">
        <i class="va-mid-ui ti-check"></i>
        <span class="va-mid-ui line-height-1-ui">
            {{ translations.ComplaintAdded }}
        </span>
    </div>
    <div class="info-ui">{{ successInfo }}</div>
    {% else -%}
    <div class="return-success-popup-ui">
        <div class="return-success-icon-ui">
            <i class="ti-check"></i>
        </div>
        <div class="return-success-title-ui">{{ translations.ReturnConfirmationTitle }}</div>
        <div class="return-success-desc-ui">{{ translations.ReturnConfirmationInfo }}</div>
        {% if order.Customer.Email and order.Customer.Email != "" -%}
        <div class="return-success-email-info-ui">
            <i class="ti-info-alt"></i>
            {{ translations.ReturnConfirmationEmailSent }} <strong>{{ order.Customer.Email }}</strong>
        </div>
        {% endif -%}
        <div class="return-success-steps-title-ui">{{ translations.NextSteps }}</div>
        <ol class="return-success-steps-ui">
            <li>{{ translations.ReturnStep1 }}</li>
            <li>{{ translations.ReturnStep2Address }}: {{ config.Shop.Address.Street }} {{ config.Shop.Address.StreetNo }}{% if config.Shop.Address.UnitNo and config.Shop.Address.UnitNo != "" -%}/{{ config.Shop.Address.UnitNo }}{% endif -%}, {{ config.Shop.Address.ZipCode }} {{ config.Shop.Address.City }}</li>
            <li>{{ translations.ReturnStep3 }}</li>
        </ol>
        <div class="return-success-actions-ui">
            <button class="btn-ui return-success-close-ui hide-container-js closing-modal-js" aria-label="{{ translations.Close }}">
                {{ translations.Close }}
            </button>
        </div>
    </div>
    {% endif -%}
</div>

4. Modyfikacje pliku js/init-ui2.js

Poniższe zmiany dotyczą pliku js/init-ui2.js (po edycji pamiętaj o zminifikowaniu go do init-ui2.min.js). a) Tuż po linii rejestrującej handler openComplaintForm:
js.delegate(document.body, 'click', '.open-complaint-form-js', openComplaintForm);
dodaj poniższy handler obsługujący przełączanie sposobu zwrotu środków – pokazuje on / ukrywa pole na numer konta bankowego:
js.delegate(document.body, 'change', '.refund-method-select-js', function() {
    const container = js.parents(this, 'refund-method-container-js');
    if(!container) return;
    const bankWrapper = container.getElementsByClassName('bank-account-container-js')[0];
    if(!bankWrapper) return;
    const bankInput = bankWrapper.querySelector('input[name="bankAccountNumber"]');
    const validationMsg = bankWrapper.getElementsByClassName('validation-required-js')[0];
    if(this.value === 'bank') {
        bankWrapper.classList.remove('hidden-js');
        if(bankInput) {
            bankInput.disabled = false;
            bankInput.required = true;
        }
    } else {
        bankWrapper.classList.add('hidden-js');
        if(bankInput) {
            bankInput.disabled = true;
            bankInput.required = false;
            bankInput.value = '';
            bankInput.classList.remove('validation-error-lq', 'validation-error-ui');
        }
        if(validationMsg) validationMsg.classList.add('hidden-js');
    }
});
b) W funkcji sendComplaint, bezpośrednio po pętli for (var i=0; i<dataFromHTML.length; i++) dokładającej pola do fd, dodaj fragment dołączający parametr qrHash z adresu URL przy wysyłaniu zwrotu:
if (form.find('input[name="__action"]').val() === 'Order/ReturnAdd') {
    var qrHash = new URLSearchParams(globalThis.location.search).get('qrHash');
    if (qrHash) {
        fd.append('qrHash', qrHash);
    }
}

5. Modyfikacje pliku scss/globals/_globals2.scss

W pliku scss/globals/_globals2.scss wewnątrz selektora opakowującego (tego, który zawiera m.in. .note-ui) dodaj poniższe reguły. Po zmianach pamiętaj o kompilacji SCSS – nie edytuj ręcznie wynikowych plików CSS. a) Style etykiety ilości oraz kontenera wyboru sposobu zwrotu środków (wstaw w sąsiedztwie istniejących reguł sekcji formularza reklamacji/zwrotu):
.amount-stepper-label-ui {
    margin-right: 10px;
    vertical-align: middle;
}

.refund-method-container-ui {
    margin-bottom: 20px;

    .bank-account-container-ui {
        margin-top: 10px;

        input {
            width: 100%;
        }
    }
}
b) Style ekranu sukcesu po wysłaniu zwrotu (ikona, tytuł, lista kolejnych kroków, sekcja z e-mailem i przyciskiem zamknięcia):
.return-success-popup-ui {
    padding: 30px 20px 20px;

    .return-success-icon-ui {
        width: 60px;
        height: 60px;
        border-radius: 50%;
        border: 2px solid #68a204;
        margin: 0 auto 20px;
        display: flex;
        align-items: center;
        justify-content: center;

        i {
            color: #68a204;
            font-size: 26px;
        }
    }

    .return-success-title-ui {
        font-size: 18px;
        font-weight: 500;
        text-align: center;
        margin-bottom: 10px;
    }

    .return-success-desc-ui {
        font-size: 14px;
        color: $primaryColorFont;
        text-align: center;
        margin-bottom: 20px;
    }

    .return-success-email-info-ui {
        background-color: $bgColor;
        border: 1px solid $lightBorderColor;
        padding: 12px;
        border-radius: 4px;
        font-size: 14px;
        margin-bottom: 20px;
        display: flex;
        align-items: flex-start;

        i {
            margin-right: 10px;
            color: $primaryColorFont;
            font-size: 16px;
            line-height: 1.4;
        }

        strong {
            display: block;
        }
    }

    .return-success-steps-title-ui {
        font-weight: 500;
        margin-bottom: 10px;
    }

    .return-success-steps-ui {
        padding-left: 20px;
        margin: 0 0 20px;
        font-size: 14px;

        li {
            margin-bottom: 8px;
            padding-left: 5px;
        }
    }

    .return-success-actions-ui {
        border-top: 1px solid $lightBorderColor;
        padding-top: 15px;
        text-align: right;

        .return-success-close-ui {
            padding: 10px 30px;
        }
    }
}
Po wprowadzeniu wszystkich powyższych zmian w szablonie Szafir pamiętaj o kompilacji oraz minifikacji plików js i scss, zgodnie z artykułem dostępnym pod linkiem https://pomoc.comarchesklep.pl/artykul/kompilacja-i-minifikacja-plikow/.

Szablon Topaz / One Page Shop

Zmiany opisane poniżej dotyczą szablonu Topaz. Szablon One Page Shop ma praktycznie identyczną strukturę – wszystkie modyfikacje dotyczą tych samych plików i mają tę samą zawartość. Wystarczy zastosować poniższą instrukcję w plikach szablonu OPS pod tymi samymi ścieżkami.

1. Tłumaczenia

W panelu administracyjnym sklepu dodaj nowe klucze tłumaczeń wymagane przez funkcjonalność szybkich zwrotów w szablonie Topaz / OPS. RestrictedOrderViewInfo - PL: Wybrane dane zamówienia zostały ukryte ze względów bezpieczeństwa. Możesz zwrócić produkty bez logowania. - EN: Some order details are hidden for security reasons. You can return products without signing in. - DE: Einige Bestelldetails wurden aus Sicherheitsgründen ausgeblendet. Sie können Produkte ohne Anmeldung zurücksenden. - FR: Certaines informations de la commande ont été masquées pour des raisons de sécurité. Vous pouvez retourner des produits sans vous connecter. Prf_ReturnPeriodInfo - PL: Zamówienie można zwrócić w ciągu {0} dni od daty dostawy. - EN: The order can be returned within {0} days from the delivery date. - DE: Die Bestellung kann innerhalb von {0} Tagen ab dem Lieferdatum zurückgegeben werden. - FR: La commande peut être retournée dans un délai de {0} jours à compter de la date de livraison. ComplaintSuccessTitle - PL: Gotowe! Przyjęliśmy Twoje zgłoszenie - EN: Done! We have received your request - DE: Fertig! Wir haben Ihre Meldung erhalten - FR: C'est fait ! Nous avons reçu votre demande ComplaintSuccessDescription - PL: Przygotuj paczkę i odeślij ją do nas – wszystkie szczegóły znajdziesz poniżej. - EN: Prepare the parcel and send it back to us – you will find all the details below. - DE: Bereiten Sie das Paket vor und senden Sie es an uns zurück – alle Details finden Sie unten. - FR: Préparez le colis et renvoyez-le-nous – vous trouverez tous les détails ci-dessous. ComplaintSuccessConfirmationSent - PL: Potwierdzenie zwrotu zostało wysłane na adres: - EN: The return confirmation has been sent to: - DE: Die Rückgabebestätigung wurde an folgende Adresse gesendet: - FR: La confirmation de retour a été envoyée à : ComplaintSuccessStepsTitle - PL: Następne kroki - EN: Next steps - DE: Nächste Schritte - FR: Étapes suivantes ComplaintSuccessStep1 - PL: Bezpiecznie zapakuj swoje produkty - EN: Pack your products securely - DE: Verpacken Sie Ihre Produkte sicher - FR: Emballez vos produits en toute sécurité ComplaintSuccessStep2 - PL: Wyślij paczkę na adres: - EN: Send the parcel to: - DE: Senden Sie das Paket an folgende Adresse: - FR: Envoyez le colis à l'adresse : ComplaintSuccessStep3 - PL: Pieniądze zwrócimy niezwłocznie po otrzymaniu i sprawdzeniu Twojej paczki. - EN: We will refund the money immediately after receiving and inspecting your parcel. - DE: Wir erstatten den Betrag unverzüglich nach Erhalt und Prüfung Ihres Pakets. - FR: Nous rembourserons l'argent immédiatement après réception et vérification de votre colis. ReturnInThreeSteps - PL: Zwróć towar w 3 krokach - EN: Return the product in 3 steps - DE: Geben Sie die Ware in 3 Schritten zurück - FR: Retournez la marchandise en 3 étapes ReturnWithoutReasonInfo - PL: Przysługuje Ci możliwość zwrotu bez podania przyczyny. - EN: You have the right to return the product without giving a reason. - DE: Sie haben das Recht, die Ware ohne Angabe von Gründen zurückzugeben. - FR: Vous avez le droit de retourner la marchandise sans donner de motif. OrEnterOrderNumber - PL: lub podaj numer zamówienia - EN: or enter the order number - DE: oder geben Sie die Bestellnummer ein - FR: ou entrez le numéro de commande FillForm - PL: Wypełnij formularz - EN: Fill out the form - DE: Füllen Sie das Formular aus - FR: Remplissez le formulaire ReturnOnline - PL: zwrotu online - EN: online return - DE: Online-Rückgabe - FR: retour en ligne SendParcel - PL: Wyślij paczkę - EN: Send the parcel - DE: Senden Sie das Paket - FR: Envoyez le colis SendParcelToOurAddress - PL: nadaj przesyłkę na nasz adres - EN: send the parcel to our address - DE: senden Sie das Paket an unsere Adresse - FR: envoyez le colis à notre adresse FastSimpleSecure - PL: Szybko, prosto i bezpiecznie. - EN: Fast, simple and secure. - DE: Schnell, einfach und sicher. - FR: Rapide, simple et sûr. ReadyForReturn - PL: Gotowy do zwrotu? - EN: Ready for return? - DE: Bereit zur Rückgabe? - FR: Prêt pour le retour ? ReadyForReturnInfo - PL: Kliknij poniżej, aby rozpocząć proces zwrotu. Przeprowadzimy Cię przez wszystkie kroki. - EN: Click below to start the return process. We will guide you through all the steps. - DE: Klicken Sie unten, um den Rückgabeprozess zu starten. Wir führen Sie durch alle Schritte. - FR: Cliquez ci-dessous pour commencer le processus de retour. Nous vous guiderons à chaque étape. StartReturn - PL: Rozpocznij zwrot - EN: Start return - DE: Rückgabe starten - FR: Commencer le retour ProductReturn - PL: Zwrot produktu - EN: Product return - DE: Produktrückgabe - FR: Retour du produit ProductReturnFormInfo - PL: Wprowadź dane zamówienia, aby zlokalizować zakup i rozpocząć proces zwrotu. Numer zamówienia znajdziesz w e-mailu z potwierdzeniem. - EN: Enter the order details to locate the purchase and start the return process. You will find the order number in the confirmation e-mail. - DE: Geben Sie die Bestelldaten ein, um den Kauf zu lokalisieren und den Rückgabeprozess zu starten. Die Bestellnummer finden Sie in der Bestätigungs-E-Mail. - FR: Saisissez les données de la commande pour localiser l'achat et démarrer le processus de retour. Vous trouverez le numéro de commande dans l'e-mail de confirmation. FindOrder - PL: Znajdź zamówienie - EN: Find order - DE: Bestellung finden - FR: Trouver la commande RefundLookupError - PL: Wystąpił błąd podczas wyszukiwania zamówienia. Spróbuj ponownie później. - EN: An error occurred while searching for the order. Please try again later. - DE: Fehler beim Suchen nach der Bestellung. Versuchen Sie es später erneut. - FR: Une erreur s'est produite lors de la recherche de la commande. Veuillez réessayer plus tard. LoginToSeeOrdersAndReturn - PL: aby zobaczyć swoje zamówienia i dokonać zwrotu. - EN: to see your orders and make a return. - DE: um Ihre Bestellungen zu sehen und eine Rückgabe zu machen. - FR: pour voir vos commandes et faire un retour. InvalidEmail - PL: Nieprawidłowy adres e-mail - EN: Invalid e-mail address - DE: Ungültige E-Mail-Adresse - FR: L'adresse e-mail est incorrecte. RefundMethod - PL: Sposób zwrotu środków - EN: Refund method - DE: Rückerstattungsmethode - FR: Mode de remboursement RefundAsPaid - PL: Zwrot na sposób płatności - EN: Refund to the original payment method - DE: Rückerstattung auf die ursprüngliche Zahlungsmethode - FR: Remboursement sur le mode de paiement initial RefundToBankAccount - PL: Zwrot na konto bankowe - EN: Refund to bank account - DE: Rückerstattung auf das Bankkonto - FR: Remboursement sur un compte bancaire

2. Nowa strona Szybkie zwroty

Funkcja szybkich zwrotów wymaga utworzenia dodatkowej strony statycznej refunds. Wykonaj poniższe kroki.

Plik refunds.html w katalogu głównym szablonu

W katalogu głównym szablonu utwórz nowy plik refunds.html z następującą zawartością:
{% extends '_layout.html' -%}
{% block pageContent -%}
{% include 'static-elements/refunds/refunds.html' -%}
{% endblock -%}

Plik static-elements/refunds/refunds.html

W folderze static-elements utwórz nowy katalog refunds, a w nim plik refunds.html:
{% include 'partials/common/breadcrumbs.html' -%}

<div class="container my-5 refunds-page-wrapper">

    <!-- Nagłówek główny -->
    <div class="text-center mb-5">
        <h1 class="mb-3">{{ translations.ReturnInThreeSteps }}</h1>
        <p class="lead text-muted">{{ translations.ReturnWithoutReasonInfo }}</p>
    </div>

    <!-- Sekcja 3 kroków (Siatka 3-kolumnowa) -->
    <div class="row text-center mb-5">
        <div class="col-md-4 mb-4">
            <div class="p-4 border rounded bg-light h-100">
                <h3 class="h5">1. {{ translations.Log_Login }}</h3>
                <p class="mb-0">{{ translations.OrEnterOrderNumber }}</p>
            </div>
        </div>
        <div class="col-md-4 mb-4">
            <div class="p-4 border rounded bg-light h-100">
                <h3 class="h5">2. {{ translations.FillForm }}</h3>
                <p class="mb-0">{{ translations.ReturnOnline }}</p>
            </div>
        </div>
        <div class="col-md-4 mb-4">
            <div class="p-4 border rounded bg-light h-100">
                <h3 class="h5">3. {{ translations.SendParcel }}</h3>
                <p class="mb-0">{{ translations.SendParcelToOurAddress }}</p>
            </div>
        </div>
    </div>

    <!-- Wyróżniony tekst -->
    <div class="text-center mb-5">
        <h2 class="text-success h3">{{ translations.FastSimpleSecure }}</h2>
    </div>

    <!-- Sekcja gotowości do zwrotu (Call to Action) -->
    <div class="text-center p-5 border rounded mb-5">
        <h2 class="h3">{{ translations.ReadyForReturn }}</h2>
        <p>{{ translations.ReadyForReturnInfo }}</p>

        <div class="mt-4">
            {% if customer.Authenticated -%}
                <a href="/Return/List" class="btn btn-primary btn-lg">{{ translations.StartReturn }}</a>
            {% else -%}
                <a href="/Return/List" class="btn btn-primary btn-lg">{{ translations.StartReturn }}</a>
            {% endif -%}
        </div>
    </div>

    <!-- Wyszukiwanie zamówienia dla niezalogowanych -->
    <div class="row justify-content-center mb-5">
        <div class="col-md-6 col-lg-5">
            <div class="text-center mb-4">
                <h3 class="h4">{{ translations.ProductReturn }}</h3>
                <p class="text-muted">{{ translations.ProductReturnFormInfo }}</p>
            </div>

            <form action="/Return/FindOrder" method="POST" class="border p-4 rounded bg-white">
                <div class="form-group mb-3">
                    <label class="font-weight-bold">{{ translations.Com_OrderNumber }}</label>
                    <input type="text" class="form-control" name="OrderNumber" required>
                </div>
                <div class="form-group mb-4">
                    <label class="font-weight-bold">{{ translations.EmailAddress }}</label>
                    <input type="email" class="form-control" name="Email" required>
                </div>
                <button type="submit" class="btn btn-dark w-100 btn-lg">{{ translations.FindOrder }}</button>
            </form>
        </div>
    </div>

    <!-- Zachęta do logowania dla niezalogowanych (Gości) -->
    {% if customer.Authenticated == false -%}
        <div class="text-center py-4 mt-4 border-top">
            <h4 class="h5">{{ translations.Reg_HaveAcc }}</h4>
            <p>{{ translations.LoginToSeeOrdersAndReturn }}</p>
            <!-- W Topaz przycisk logowania często otwiera popup ze zdefiniowaną klasą js-login-popup-trigger -->
            <button class="btn btn-outline-primary js-login-popup-trigger">{{ translations.Log_Login }}</button>
        </div>
        {% include 'partials/common/login-register-popup.html' -%}
    {% endif -%}

</div>

<!-- Globalny komponent Newslettera -->
{% if settings.newsletterOnFunctionalPages == 'yes' -%}
    {% include 'partials/newsletter-global.html' -%}
{% endif -%}

Pliki SCSS strony Szybkie zwroty

W folderze scss/static-elements utwórz nowy katalog refunds, a w nim trzy pliki: refunds-g.scss (style ogólne), refunds-d.scss (desktop) oraz refunds-m.scss (mobile). scss/static-elements/refunds/refunds-g.scss:
.refunds-container {
    box-sizing: border-box;
    margin: 0 auto;
    color: $primaryFontColor;
    background-color: $primaryPageBg;

    .refunds-view {
        display: flex;
        flex-direction: column;
        align-items: center;

        &.hidden-js {
            display: none;
        }
    }

    .refunds-intro {
        width: 100%;
        align-self: stretch;

        &__heading {
            margin: 0 0 16px;
            font-size: $mediumFontSize;
            font-weight: 600;
            line-height: 1.4;
            color: $primaryFontColor;
        }

        &__lead {
            margin: 0 0 16px;
            font-size: 16px;
            font-weight: 500;
            line-height: 1.5;
            color: $primaryFontColor;
        }

        &__hint {
            margin: 16px 0 0;
            font-size: $extraSmallFontSize;
            color: $secondaryFontColor;
        }
    }

    .refunds-steps {
        list-style: none;
        counter-reset: refund-step;
        margin: 0;
        padding: 0;
        display: flex;
        flex-direction: column;
        gap: 8px;

        &__item {
            counter-increment: refund-step;
            display: flex;
            align-items: center;
            gap: 12px;

            &::before {
                content: counter(refund-step);
                flex: 0 0 auto;
                width: 32px;
                height: 32px;
                border-radius: 50%;
                background-color: $primaryBtnBg;
                color: $primaryBtnFontColor;
                font-weight: 600;
                font-size: $smallFontSize;
                line-height: 1;
                display: inline-flex;
                align-items: center;
                justify-content: center;
            }
        }

        &__text {
            font-size: $smallFontSize;
            line-height: 1.5;
            color: $primaryFontColor;

            strong {
                font-weight: 600;
            }
        }
    }

    .refunds-card,
    .refunds-lookup {
        box-sizing: border-box;
        width: 100%;
        background-color: $primaryPageBg;
        border: 1px solid $borderColor;
        border-radius: 8px;
        display: flex;
        flex-direction: column;
        margin-left: auto;
        margin-right: auto;
    }

    .refunds-card {
        align-items: center;
        text-align: center;
        gap: 12px;

        &__heading {
            margin: 0;
            font-size: $bigFontSize;
            font-weight: 600;
            line-height: 1.3;
            color: $primaryFontColor;
        }

        &__text {
            margin: 0;
            font-size: 16px;
            line-height: 1.5;
            color: $secondaryFontColor;
        }

        &__btn {
            width: 100%;
            margin-top: 12px;
        }
    }

    .refund-form-js {
        .form__invalid-input {
            margin: 4px 0 0;
            font-size: $extraSmallFontSize;
            line-height: 16px;
            color: $messageErrorColor;
        }
    }

    .refunds-lookup {
        gap: 16px;

        &__heading {
            margin: 0;
            font-size: $bigFontSize;
            font-weight: 600;
            line-height: 1.3;
            color: $primaryFontColor;
        }

        &__lead {
            margin: 0;
            font-size: $smallFontSize;
            line-height: 1.5;
            color: $secondaryFontColor;
        }

        &__loginPrompt {
            margin: 8px 0 0;
            font-size: $smallFontSize;
            color: $primaryFontColor;
        }

        &__loginLink {
            color: $linkFontColor;
            font-weight: 600;
            text-decoration: underline;

            &:hover,
            &:focus {
                text-decoration: none;
            }
        }

        &__error {
            margin: 0;
            font-size: $smallFontSize;
            color: $messageErrorColor;
        }
    }
}

.loginRegister--login-only {
    .loginRegisterTabsContainer {
        display: none;
    }

    .registrationForm-js {
        display: none;
    }
}
scss/static-elements/refunds/refunds-d.scss:
@media screen and (min-width: 769px) {
    .refunds-container {
        max-width: 1400px;
        padding-top: 32px;
        padding-bottom: 64px;

        .refunds-view {
            gap: 32px;
        }

        .refunds-intro {
            &__heading {
                font-size: 20px;
            }

            &__lead {
                margin-bottom: 24px;
            }
        }

        .refunds-card,
        .refunds-lookup {
            max-width: 578px;
        }

        .refunds-card {
            padding: 40px;
        }

        .refunds-lookup {
            padding: 32px;
        }
    }
}
scss/static-elements/refunds/refunds-m.scss:
@media screen and (max-width: 768px) {
    .refunds-container {
        padding: 16px 3% 40px;

        .refunds-view {
            gap: 24px;
        }

        .refunds-intro {
            &__heading {
                font-size: 18px;
            }

            &__lead {
                font-size: $smallFontSize;
                margin-bottom: 16px;
            }
        }

        .refunds-steps {
            &__item {
                &::before {
                    width: 28px;
                    height: 28px;
                }
            }
        }

        .refunds-card {
            padding: 24px 16px;

            &__heading {
                font-size: $mediumFontSize;
            }

            &__text {
                font-size: $smallFontSize;
            }
        }

        .refunds-lookup {
            padding: 20px 16px;

            &__heading {
                font-size: $mediumFontSize;
            }
        }
    }
}

3. Modyfikacje istniejących plików HTML

partials/customer/order-content.html

W pliku partials/customer/order-content.html wykonaj poniższe zmiany. a) Bezpośrednio po otwarciu kontenera <div class="orderContent order-content-js"> dodaj dwa nowe bannery informacyjne (jeden o ukrytych danych zamówienia, drugi o terminie zwrotu, wraz z wyliczaniem flagi hasReturnableProduct):
{% if order.Restricted -%}
<div class="orderContent__returnInfo" role="note">
    <!-- TODO: ikona SVG informacyjna z klasą orderContent__returnInfo__icon -->
    {{ translations.RestrictedOrderViewInfo }}
</div>
{% endif -%}
{% assign hasReturnableProduct = false -%}
{% if config.Complaints.ReturnsEnabled -%}
{% for product in order.Products -%}
{% if product.CanReturn -%}
{% assign hasReturnableProduct = true -%}
{% break -%}
{% endif -%}
{% endfor -%}
{% endif -%}
{% if hasReturnableProduct -%}
<div class="orderContent__returnInfo" role="note">
    <!-- TODO: ikona SVG informacyjna z klasą orderContent__returnInfo__icon -->
    {{ translations.Prf_ReturnPeriodInfo | Format: config.Complaints.DaysToReturn }}
</div>
{% endif -%}
b) Kontener <div class="orderContent__docsToPrint">...</div> (z dokumentami do druku) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}, aby ukrywać go dla zamówień typu restricted. c) Cały dotychczasowy blok przycisków reklamacji/zwrotu (oparty na konstrukcji {% if ComplaintsEnabled and ReturnsEnabled %} ... {% elseif ComplaintsEnabled %} ... {% elseif ReturnsEnabled %} ... {% endif %} z jednym wspólnym przyciskiem) zamień na dwa niezależne warunki, dzięki czemu dla produktu uprawnionego zarówno do reklamacji, jak i do zwrotu, oba przyciski wyświetlają się obok siebie. Strukturę wewnątrz warunku {% if product.CanComplain or product.CanReturn -%} zastąp poniższym kodem:
{% if config.Complaints.ComplaintsEnabled == true and product.CanComplain -%}
<button class="orderContent__complainBtn orderContent__complainBtn--complaint showPopupBtn-js addDataToComplaintForm-js" data-popup-class="popupDialog" data-form-type="complaint" data-product-id="{{product.No}}" data-image-id="{{product.ImageId}}" data-imageext="{{product.Image.ExternalUrl}}" data-product-name="{{product.NameNoHtml | H}}" data-product-complain="{{product.CanComplain}}" data-product-count="{{ newProductQuantity }} {{ product.Unit }}" data-product-unit="{{ product.Unit }}" data-product-description="{{ productAttributes | Join: ' / ' | H }}" data-product-return="false" data-product-quantity="{{newProductQuantity}}" data-order-id="{{order.Id}}" data-order-date="{{order.Date | Date: 'yyyy-MM-dd'}}">
    <svg width="16" height="16">
        <use href="#comment-alt-regular"></use>
    </svg>
    {{translations.Prf_SendComplaint }}
</button>
{% endif -%}
{% if config.Complaints.ReturnsEnabled == true and product.CanReturn -%}
<button class="orderContent__complainBtn orderContent__complainBtn--return showPopupBtn-js addDataToComplaintForm-js" data-popup-class="popupDialog" data-form-type="return" data-product-id="{{product.No}}" data-image-id="{{product.ImageId}}" data-imageext="{{product.Image.ExternalUrl}}" data-product-name="{{product.NameNoHtml | H}}" data-product-complain="false" data-product-count="{{ newProductQuantity }} {{ product.Unit }}" data-product-unit="{{ product.Unit }}" data-product-description="{{ productAttributes | Join: ' / ' | H }}" data-product-return="{{product.CanReturn}}" data-product-quantity="{{newProductQuantity}}" data-order-id="{{order.Id}}" data-order-date="{{order.Date | Date: 'yyyy-MM-dd'}}">
    <svg width="16" height="16">
        <use href="#sync-regular"></use>
    </svg>
    {{ translations.Prf_OrderReturn }}
</button>
{% endif -%}
Kluczowe różnice w stosunku do poprzedniej wersji: każdy przycisk renderowany jest niezależnie (oba mogą wystąpić równocześnie), przyciski mają modyfikatory orderContent__complainBtn--complaint i orderContent__complainBtn--return, atrybut data-form-type (odczytywany w JS), w przycisku reklamacji wymuszone data-product-return="false", w przycisku zwrotu wymuszone data-product-complain="false", ikony 16x16 (#comment-alt-regular dla reklamacji, #sync-regular dla zwrotu), a etykieta przycisku zawiera już tylko jedno tłumaczenie. d) W pozostałych miejscach z przyciskami reklamacji/zwrotu (sekcje, w których nie zmieniają się klasy i ikony) dodaj jedynie dwa nowe atrybuty:
data-product-unit="{{ product.Unit }}"
data-product-description="{{ productAttributes | Join: ' / ' | H }}"
e) W sekcji załączników zamówienia zamień:
{% if order.Attachments[0] -%}
na:
{% if order.Attachments[0] and order.Restricted == false -%}
f) W kontenerze <div class="orderContent__recipient orderContent__infoBox"> zamień wyświetlanie adresu dostawy:
<span class="orderContent__lightText">{{ order.Customer.DeliveryAddress.Street }} {{ order.Customer.DeliveryAddress.StreetNo }} / {{ order.Customer.DeliveryAddress.UnitNo }}</span>
na:
<span class="orderContent__lightText">{{ order.Customer.DeliveryAddress.Street }} {{ order.Customer.DeliveryAddress.StreetNo }}{% if order.Customer.DeliveryAddress.UnitNo != null and order.Customer.DeliveryAddress.UnitNo != '' -%} / {{ order.Customer.DeliveryAddress.UnitNo }}{% endif -%}</span>
g) Sekcję z przyciskami akcji zamówienia (orderCancel-js, ponowienie płatności itd.) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}. Wstaw {% unless order.Restricted -%} bezpośrednio przed warunkiem {% if order.CanRestorePayment -%}, a {% endunless -%} po zamykającym {% endif -%} bloku z przyciskiem anulowania zamówienia.

partials/common/complaint-popup.html

Plik partials/common/complaint-popup.html wymaga gruntownej przebudowy. Usuwamy z niego radiowe przyciski wyboru "reklamacja/zwrot", a typ formularza jest teraz przekazywany z zewnątrz przez parametr __include. Sterowanie ilością zostało przeniesione do kafelka z produktem (z etykietą i obsługą wariantu statycznego, gdy zostaje tylko 1 sztuka). W formularzu zwrotu zamiast samego pola numeru konta pojawia się sekcja wyboru sposobu zwrotu środków (refundMethod-js) – z opcją „zwrot na sposób płatności" (domyślna) lub „zwrot na konto bankowe". Pole numeru konta jest domyślnie ukryte i disabled; pokazuje się dopiero po wybraniu opcji „konto bankowe" (obsługa w JS w metodzie changeRefundMethod). Tytuł, kafelek produktu i formularz oznaczone są dodatkową klasą complain-form-view-js, dzięki czemu po pomyślnym wysłaniu formularza można je ukryć i wyświetlić ekran sukcesu (complain-success-view-js). Zastąp całą zawartość pliku poniższym kodem:
{% if hideContent -%}
{% else -%}
{% assign formType = include -%}
{% assign isReturn = false -%}
{% if formType == 'return' -%}
{% assign isReturn = true -%}
{% endif -%}
<div class="popupDialog popupDialog__complain popupDialog-js">
    {% assign order = customer-profile.Order -%}
    <div class="popupDialog__wrapper">
        <button class="popupDialog__closeBtn closePopupBtn-js">
            <!-- TODO: ikona SVG zamknięcia – jak w pozostałych popupach szablonu -->
        </button>
        <span class="popupDialog__title complain-form-view-js">
            {% if isReturn -%}
            {{ translations.Prf_OrderReturn }}
            {% else -%}
            {{ translations.Prf_SendComplaint }}
            {% endif -%}
        </span>
        <div class="complain__product complain-form-view-js">
            <figure><img class="productImage-js" alt="product_image" /></figure>
            <div class="complain__productInfo">
                <!-- TODO: zweryfikuj z szablonem elementy z klasami productName-js i productDescription-js (nazwa i opis produktu) -->
                <span class="productName-js"></span>
                <span class="productDescription-js"></span>
                <div class="complain__quantity">
                    <label class="complain__quantityLabel" for="complaint-quantity">{{translations.Com_Quantity}}:</label>
                    <div class="complain__quantityControl min-js quantityControl-js">
                        <button class="button-minus-add-product" type="button" aria-label="{{translations.ButtonMinusAddProduct}}" data-field="quantity">
                            <!-- TODO: ikona SVG minus -->
                        </button>
                        <input id="complaint-quantity" class="quantity-field quantity__field-js" max="" min="1" name="quantity" type="number" value="1" data-decimal="false" />
                        <button class="button-plus-add-product" type="button" aria-label="{{ translations.ButtonPlusAddProduct }}" data-field="quantity">
                            <!-- TODO: ikona SVG plus -->
                        </button>
                    </div>
                    <span class="quantityStatic-js hidden"></span>
                    <span class="productUnit-js"></span>
                </div>
            </div>
        </div>
        <div class="form complain__form inputs-container-js complain-form-view-js" data-success-info="{{ translations.ReportSuccessInfo }}">
            <input name="__action" type="hidden" value="{% if isReturn -%}Order/ReturnAdd{% else -%}Order/ComplaintAdd{% endif -%}" />
            <strong>{{ translations.ReportDetails }}</strong>
            {% unless isReturn -%}
            <div class="form__input-wrapper">
                {% if config.Complaints.Defects <> null -%}
                {% assign defectsSize = config.Complaints.Defects | Size -%}
                <label class="hidden" for="defectId">{{ translations.ChooseComplaintCause }}</label>
                <select class="form__input-value form__input-value-js {% if settings.themeName == 'Dark' -%} darkTheme {% endif -%}" name="defectId" required="">
                    {% if defectsSize > 1 -%}
                    <option value="-1">* {{translations.ChooseComplaintCause}}</option>
                    {% endif -%}
                    {% for def in config.Complaints.Defects -%}
                    <option value="{{def.Id}}">{{def.Name}}</option>
                    {% endfor -%}
                </select>
                {% endif -%}
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            <div class="form__input-wrapper">
                <span class="form__icons">
                    <!-- TODO: ikona SVG kalendarza -->
                </span>
                <input id="defectDate" class="form__input-value form__icon_padding form__input-value-js orderDate-js" max="{{config.Now | Date: 'yyyy-MM-dd'}}" min="{{order.Date | Date: 'yyyy-MM-dd'}}" name="defectDate" type="date" value="{{config.Now | Date: 'yyyy-MM-dd'}}" placeholder="yyyy-MM-dd" />
                <label class="form__input-info" for="defectDate">* {{translations.Prf_DefectDate}}</label>
            </div>
            <div class="form__input-wrapper">
                {% if config.Complaints.Requests <> null -%}
                {% assign requestsSize = config.Complaints.Requests | Size -%}
                <label class="hidden" for="requestId">{{ translations.Prf_ComplainRequest }}</label>
                <select class="form__input-value form__input-value-js {% if settings.themeName == 'Dark' -%} darkTheme {% endif -%}" name="requestId" required="">
                    {% if requestsSize > 1 -%}
                    <option value="-1">* {{translations.Prf_ComplainRequest}}</option>
                    {% endif -%}
                    {% for req in config.Complaints.Requests -%}
                    <option value="{{req.Id}}">{{req.Name}}</option>
                    {% endfor -%}
                </select>
                {% endif -%}
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            {% else -%}
            {% assign returnTypes = config.Complaints.Returns | Size -%}
            {% if returnTypes > 1 -%}
            <div class="form__input-wrapper">
                <label class="hidden" for="returnId">{{ translations.ChooseReturn }}</label>
                <select class="form__input-value form__input-value-js {% if settings.themeName == 'Dark' -%} darkTheme {% endif -%}" name="returnId" required="">
                    <option value="-1">* {{translations.ChooseReturn}}</option>
                    {% for return in config.Complaints.Returns -%}
                    <option value="{{return.Id}}">{{return.Name}}</option>
                    {% endfor -%}
                </select>
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            {% endif %}
            {% endunless -%}
            <div class="form__input-wrapper returnInputWrapper-js refundMethodWrapper-js">
                <label class="complain__sectionLabel" for="refundMethod">{{ translations.RefundMethod }}</label>
                <select id="refundMethod" class="form__input-value form__input-value-js refundMethod-js {% if settings.themeName == 'Dark' -%}darkTheme{% endif -%}" name="refundMethod">
                    <option value="payment">{{ translations.RefundAsPaid }}{% if order.Payment.Name != null and order.Payment.Name != '' %} ({{ order.Payment.Name }}){% endif %}</option>
                    <option value="account">{{ translations.RefundToBankAccount }}</option>
                </select>
            </div>
            <div class="form__input-wrapper accountNumberWrapper-js" style="display: none;">
                <input id="accountNumber" class="form__input-value form__input-value-js" disabled="disabled" maxlength="50" name="accountNumber" type="text" />
                <label class="form__input-info form__input-info-js" for="accountNumber">{{translations.Crt_BankAccountNumber}}</label>
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            <div class="form__input-wrapper">
                {{translations.Prf_AdditionalInfo}}
                <textarea class="form__input-value" name="message" aria-label="{{ translations.Prf_AdditionalInfo }}"></textarea>
            </div>
            <div class="form__input-wrapper">
                <span class="form__requiredFields--info">* {{ translations.Com_RequiredFields }}</span>
            </div>
            {% if config.Complaints.AttachmentsEnabled -%}
            <div class="form__input-wrapper attachementsInputWrapper" data-not-added-info="{{translations.AttachementsNotAdded}}">
                <button class="form__attachementsLabel form__attachementsLabel--btn form__attachementsLabel-js" data-page="complaints">
                    <!-- TODO: ikona SVG dodawania załącznika -->
                    {{ translations.AddAttachment }}
                </button>
                {% capture maxSize -%}{{config.Complaints.AttachmentMaxSize | DividedBy: 1024}}KB{% endcapture -%}
                {% for i in (1..config.Complaints.AttachmentsMaxCount) -%}
                <div class="form__attachement-input-container form__attachement-input-container-attachments form__attachement-input-container--hidden">
                    <!-- TODO: ikona SVG oraz element z nazwą pliku (form__attachement-input-container-attachments__text) -->
                    <input class="addAttachementInComplaint-js" accept="{{ config.Complaints.AttachmentExtensions }}" name="file" type="file" aria-label="{{ translations.AddAttachment }}" data-file-size="{{ config.Complaints.AttachmentMaxSize }}" data-size-exceeded="{{ translations.Com_FileSizeExceeded | Format: maxSize }}" data-invalid-file="{{ translations.Com_InvalidFile | Format: config.Complaints.AttachmentExtensions }}" />
                    <button class="form__clear-attachement-input clearFileInput-js" style="display: none;">
                        <!-- TODO: ikona SVG usuwania załącznika -->
                    </button>
                </div>
                {% endfor -%}
            </div>
            {% endif -%}
            <input class="productId-js" name="no" type="hidden" value="" />
            <input class="orderId-js" name="orderId" type="hidden" value="{{order.Id}}" />
            <button class="primary-action-button orderComplaintOrReturnAdd-js" type="button" data-id="{{order.Id}}">{{translations.Report}}</button>
        </div>
        <div class="complain__successView complain-success-view-js hidden">
            <div class="complain__successIcon">
                <!-- TODO: ikona SVG potwierdzenia (zielony "check", klasa svgIcon) -->
            </div>
            <h2 class="complain__successTitle">{{ translations.ComplaintSuccessTitle }}</h2>
            <p class="complain__successDescription">{{ translations.ComplaintSuccessDescription }}</p>
            <div class="complain__successInfoBox">
                <!-- TODO: ikona SVG informacyjna (klasa svgIcon) -->
                <span>{{ translations.ComplaintSuccessConfirmationSent }}
                    <strong>{{ order.Customer.Email }}</strong>
                </span>
            </div>
            <h3 class="complain__successStepsTitle">{{ translations.ComplaintSuccessStepsTitle }}</h3>
            <ol class="complain__successSteps">
                <li>{{ translations.ComplaintSuccessStep1 }}</li>
                <li>{{ translations.ComplaintSuccessStep2 }} {{ config.Shop.Address.Street }} {{ config.Shop.Address.StreetNo }}{% if config.Shop.Address.UnitNo != '' %}/{{ config.Shop.Address.UnitNo }}{% endif %}, {{ config.Shop.Address.ZipCode }} {{ config.Shop.Address.City }}</li>
                <li>{{ translations.ComplaintSuccessStep3 }}</li>
            </ol>
            <div class="complain__successActions">
                <button class="primary-action-button closePopupBtn-js" type="button">{{ translations.BtnClose }}</button>
            </div>
        </div>
    </div>
</div>
{% endif -%}

4. Modyfikacje pliku js/layout1.js

Poniższe zmiany dotyczą pliku js/layout1.js. Po edycji pamiętaj o zminifikowaniu pliku do layout1.min.js. a) W obiekcie customerProfile usuń całą metodę setComplainReturnRadioButtons (radiowy przełącznik reklamacja/zwrot nie jest już potrzebny – typ formularza jest teraz przekazywany przy otwieraniu popupu). b) W tym samym obiekcie zastąp całą metodę addDataToComplaintForm nową implementacją, która odczytuje typ formularza z atrybutu data-form-type przycisku i przekazuje go do szablonu jako parametr __include:
addDataToComplaintForm: function (e) {
    const template = 'partials/common/complaint-popup.html';
    const data = e.currentTarget;
    const formType = data.dataset.formType === 'return' ? 'return' : 'complaint';

    $.get('', {__template: template, __include: "'" + formType + "'"}, function(result) {
        $('.customer__content-js').append(result.template);
        $('.popupDialog__complain').show();
        $('body').addClass('customerProfileNoScroll');

        const image = $('.productImage-js');
        const productName = $('.productName-js');
        const inputId = $('.productId-js');
        const productQuantity = $('.quantity__field-js');
        const quantityControl = $('.quantityControl-js');
        const quantityStatic = $('.quantityStatic-js');
        const productUnit = $('.productUnit-js');
        const productDescription = $('.productDescription-js');

        const orderId = $('.orderId-js');
        const buttonOrderId = $('.orderComplaintOrReturnAdd-js');
        const orderDate = $('.orderDate-js');

        productName.text(data.dataset.productName);
        productUnit.text(data.dataset.productUnit || '');
        productDescription.text(data.dataset.productDescription || '');
        inputId.val(data.dataset.productId);
        productQuantity.attr('max', data.dataset.productQuantity);

        if (parseInt(data.dataset.productQuantity, 10) <= 1) {
            quantityControl.addClass('hidden');
            quantityStatic.text(data.dataset.productQuantity).removeClass('hidden');
        } else {
            quantityControl.removeClass('hidden');
            quantityStatic.addClass('hidden');
        }

        orderId.val(data.dataset.orderId);
        buttonOrderId.attr('data-id', data.dataset.orderId);
        orderDate.attr('min', data.dataset.orderDate);

        if (data.dataset.imageext != null && data.dataset.imageext != "") {
            image.attr('src', data.dataset.imageext);
        } else if (data.dataset.imageId != null && data.dataset.imageId != "") {
            image.attr('src', '/Image/?id=' + data.dataset.imageId);
        }

        if (image.attr('src') === '' || image.attr('src') == null) {
            image.closest('figure').addClass('noImage-js');
        }

        setTimeout(function() {
            app.activateFocusTrap('.popupDialog__complain', e.target);
        }, 200);
    });
},
c) Zastąp metodę changeReturnComplaintForm nową wersją (obsługuje również pole numeru konta i wywołuje changeRefundMethod po przełączeniu na zwrot):
changeReturnComplaintForm: function (e) {
    const form = $(e.currentTarget).closest('.inputs-container-js');
    const complaintInputs = form.find('.complaintInputWrapper-js');
    const returnInputs = form.find('.returnInputWrapper-js');
    const accountWrapper = form.find('.accountNumberWrapper-js');
    const accountInput = accountWrapper.find('input[name="accountNumber"]');

    if ($(e.currentTarget).is(':checked') && e.currentTarget.dataset.name === 'complaint' ) {
        $.each(complaintInputs, function (index, value) {
            $(value).find('input, select').first().removeAttr('disabled');
            $(value).show(300);
        });
        returnInputs.each(function () {
            $(this).find('input, select').first().attr('disabled', 'true');
        });
        returnInputs.hide(300);
        accountInput.removeAttr('disabled').removeAttr('required').removeClass('form__validation-error-js');
        accountWrapper.find('.form__validation-required-js').hide();
        accountWrapper.show(300);
    }

    if ($(e.currentTarget).is(':checked') && e.currentTarget.dataset.name === 'return' ) {
        $.each(complaintInputs, function (index, value) {
            $(value).find('input, select').first().attr('disabled', 'true');
            $(value).hide(300);
        });
        returnInputs.each(function () {
            $(this).find('input, select').first().removeAttr('disabled');
        });
        returnInputs.show(300);
        customerProfile.changeRefundMethod(form);
    }
},
d) Tuż za metodą changeReturnComplaintForm dodaj nową metodę changeRefundMethod (pokazuje / ukrywa pole numeru konta bankowego na podstawie wybranego sposobu zwrotu):
changeRefundMethod: function (formOrEvent) {
    const form = formOrEvent && formOrEvent.currentTarget
        ? $(formOrEvent.currentTarget).closest('.inputs-container-js')
        : $(formOrEvent);
    const select = form.find('.refundMethod-js');
    const accountWrapper = form.find('.accountNumberWrapper-js');
    const accountInput = accountWrapper.find('input[name="accountNumber"]');

    if (select.val() === 'account') {
        accountInput.removeAttr('disabled').attr('required', 'required');
        accountWrapper.show(300);
    } else {
        accountInput.attr('disabled', 'true').removeAttr('required').removeClass('form__validation-error-js');
        accountWrapper.find('.form__validation-required-js').hide();
        accountWrapper.hide(300);
    }
},
e) W metodzie wysyłającej formularz reklamacji/zwrotu (gdzie znajduje się pętla for (let i=0; i<dataFromHTML.length; i++)) zaraz po pętli dodaj fragment dołączający parametr qrHash z URL-a przy wysyłaniu zwrotu:
if (form.find('input[name="__action"]').val() === 'Order/ReturnAdd') {
    const qrHash = new URLSearchParams(globalThis.location.search).get('qrHash');
    if (qrHash) {
        fd.append('qrHash', qrHash);
    }
}
f) W tej samej metodzie, w callbacku success po pomyślnym wysłaniu, zamień fragment:
if (data.action.Result) {
    const message = form.data('success-info');
    app.showTemporaryPopup(message, 'success', '', 8000);
    $('.clearFileInput-js').hide();
    app.hidePopup(e);
    sessionStorage.removeItem('complains');
    sessionStorage.removeItem('order' + (e.currentTarget).dataset.id);
    $('.order' + (e.currentTarget).dataset.id).remove();
    $('.popupDialog__complain').remove();
    $('body').removeClass('customerProfileNoScroll');
    customerProfile.showOrderDetails(e);
}
na:
if (data.action.Result) {
    $('.clearFileInput-js').hide();
    sessionStorage.removeItem('complains');
    sessionStorage.removeItem('order' + (e.currentTarget).dataset.id);
    const popup = $(e.currentTarget).closest('.popupDialog__complain');
    popup.find('.complain-form-view-js').addClass('hidden');
    popup.find('.complain-success-view-js').removeClass('hidden');
    popup.find('.popupDialog__wrapper').scrollTop(0);
}
g) W sekcji rejestracji zdarzeń profilu klienta (tam, gdzie znajdują się m.in. mainSection.on('change', '.radioComplaint-js, .radioReturn-js', ...)) tuż za istniejącym handlerem zmiany typu formularza dopisz nowy handler:
mainSection.on('change', '.refundMethod-js', function (e) {
    customerProfile.changeRefundMethod(e);
});
h) Znajdź globalny handler obsługujący keydown z selektorem zaczynającym się od .radioReturn-js label, .radioComplaint-js label, ... i usuń z niego dwa pierwsze selektory (po zmianie zaczyna się od .showHideSection-js):
// PRZED
$('body').on('keydown', '.radioReturn-js label, .radioComplaint-js label, .showHideSection-js, .checkBoxes__container label, .customerPagination__form-js, .discountsDetails-js, .customer-focus, .customer__menuActivate-js', function(e) { ... });

// PO
$('body').on('keydown', '.showHideSection-js, .checkBoxes__container label, .customerPagination__form-js, .discountsDetails-js, .customer-focus, .customer__menuActivate-js', function(e) { ... });
i) W obiekcie app w pliku js/layout1.js obsłuż przekierowanie po zalogowaniu z parametrem #login-redirect= (używanym przez stronę szybkich zwrotów). W bloku rejestracji/logowania, w miejscu gdzie obsługiwany jest hash #back-to-cart, tuż po nim dodaj:
if (globalThis.location.hash.startsWith('#login-redirect=')) {
    url = globalThis.location.hash.slice('#login-redirect='.length);
}
Następnie w handlerze sukcesu logowania, gdzie znajduje się sprawdzenie window.location.hash.includes('#back-to-cart') wraz z przekierowaniem, tuż za nim dodaj analogiczny blok przekierowujący w przypadku #login-redirect=:
if (globalThis.location.hash.startsWith('#login-redirect=')) {
    globalThis.location.assign(globalThis.location.hash.slice('#login-redirect='.length));
    return;
}

5. Modyfikacje plików SCSS profilu klienta

Poniższe style należy dodać do plików scss/static-elements/customer-profile/customer-profile-g.scss (style ogólne), customer-profile-d.scss (desktop) i customer-profile-m.scss (mobile). Po zmianach pamiętaj o kompilacji SCSS – nie edytuj ręcznie wynikowych plików CSS.

Plik customer-profile-g.scss

a) Wewnątrz selektora opakowującego (tam, gdzie znajdują się istniejące reguły .orderContent__complainBtn) dodaj nowe reguły dla banera informacyjnego oraz kontenera grupującego przyciski reklamacji/zwrotu:
.orderContent__returnInfo {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 16px 0 24px;
    padding: 12px 16px;
    background-color: color-mix(in srgb, #{$linkFontColor} 4%, transparent);
    border: 1px solid color-mix(in srgb, #{$linkFontColor} 20%, transparent);
    border-radius: 4px;
    font-size: 13px;
    line-height: 1.4;
    color: $primaryFontColor;

    &__icon {
        flex-shrink: 0;
        fill: $linkFontColor;
    }
}

.orderContent__complainBtns {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin: 16px 0 4px;
}
b) Następnie zastąp istniejące style .orderContent__complainBtn nowym wyglądem przycisku (z tłem, obramowaniem i hoverem):
.orderContent__complainBtn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 16px 0 4px;
    padding: 6px 12px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 4px;
    color: $linkFontColor;
    fill: $linkFontColor;
    font-size: 13px;
    font-weight: 500;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 180ms, border-color 180ms;

    .orderContent__complainBtns & {
        margin: 0;
    }

    svg {
        margin: 0;
        flex-shrink: 0;
    }

    &:hover,
    &:focus-visible {
        background-color: color-mix(in srgb, #{$linkFontColor} 6%, transparent);
        border-color: color-mix(in srgb, #{$linkFontColor} 25%, transparent);
        outline: none;
    }
}
c) Dodaj style etykiety sekcji oraz kontenera sposobu zwrotu w popupie reklamacji:
.complain__sectionLabel {
    display: block;
    margin-bottom: 8px;
    font-size: 14px;
    font-weight: 500;
    color: $primaryFontColor;
}

.refundMethodWrapper-js {
    margin-bottom: 18px;
}
d) Dodaj kompletne style ekranu sukcesu zwrotu (m.in. ikona, tytuł, lista kolejnych kroków, sekcja z e-mailem i przyciskiem zamknięcia):
.complain__successView {
    text-align: center;
    padding: 16px 0 0;
}

.complain__successIcon {
    display: flex;
    justify-content: center;
    margin: 8px 0 20px;

    .svgIcon {
        width: 64px;
        height: 64px;
        fill: #2d8c4a;
    }
}

.complain__successTitle {
    font-size: 20px;
    font-weight: 600;
    line-height: 1.3;
    margin: 0 0 12px;
    color: $primaryFontColor;
}

.complain__successDescription {
    font-size: 14px;
    line-height: 1.5;
    color: $primaryFontColor;
    margin: 0 0 20px;
}

.complain__successInfoBox {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 14px;
    margin: 0 0 24px;
    border: 1px solid #cfdcef;
    background-color: #f0f5fc;
    border-radius: 6px;
    text-align: left;

    .svgIcon {
        flex-shrink: 0;
        margin-top: 2px;
        fill: #3a6ea5;
    }

    span {
        font-size: 13px;
        line-height: 1.5;
        color: $primaryFontColor;
    }

    strong {
        display: block;
        font-weight: 600;
        margin-top: 2px;
        word-break: break-all;
    }
}

.complain__successStepsTitle {
    font-size: 15px;
    font-weight: 600;
    margin: 0 0 12px;
    text-align: left;
    color: $primaryFontColor;
}

.complain__successSteps {
    margin: 0 0 24px;
    padding-left: 22px;
    text-align: left;

    li {
        font-size: 14px;
        line-height: 1.6;
        margin-bottom: 6px;
        color: $primaryFontColor;
    }
}

.complain__successActions {
    display: flex;
    justify-content: flex-end;
    padding-top: 16px;
    padding-bottom: 30px;
    margin-top: 8px;
    border-top: 1px solid $borderColor;

    .primary-action-button {
        min-width: 140px;
        margin: 0;
    }

    @media screen and (max-width: 599px) {
        .primary-action-button {
            width: 100%;
            min-width: 0;
        }
    }
}
e) Zaktualizuj style załączników – znajdź istniejące reguły .form__clear-attachement-input oraz reguły z position: absolute; top: 11px; i zastąp je nowymi (które ustawiają załączniki w układzie statycznym z poprawnym overflowem i przyciskiem usuwania):
.form__attachement-input-container-attachments__text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.form__attachement-input-container--hidden,
.form__attachement-input-container-attachments.form__attachement-input-container--hidden {
    display: none;
}

.form__clear-attachement-input {
    position: static;
    background: transparent;
    border: none;
    padding: 2px 4px;
    margin: 0 0 0 4px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;

    svg {
        fill: $linkFontColor;
        transition: opacity 200ms;
    }

    &:hover svg {
        opacity: 0.7;
    }
}

Plik customer-profile-d.scss

Wewnątrz wrappera @media screen and (min-width: 769px) zamień istniejące style przycisku reklamacji:
.customer .orderContent__complainBtn {
    position: absolute;
    bottom: 8px;
}
na poniższy fragment (dodaje pozycjonowanie kontenera grupującego przyciski oraz osobny selektor dla pojedynczych przycisków w wierszu produktu):
.customer .orderContent__complainBtns {
    position: absolute;
    bottom: 8px;
    right: 0;
    margin: 0;
}

.customer .orderContent__productDetails > .orderContent__complainBtn {
    position: absolute;
    bottom: 8px;
    right: 0;
    margin: 0;
}

Plik customer-profile-m.scss

W obrębie selektora .customer zamień istniejący media-query @media screen and (max-width: 359px) wraz z jego wnętrzem na rozszerzoną wersję (układająca przyciski reklamacji/zwrotu pionowo na szerokościach do 450px):
@media screen and (max-width: 450px) {
    .customer__orderContent .orderContent__productsRow {
        max-height: none;
    }

    .customer__orderContent .orderContent__productDetails {
        display: flex;
        flex-direction: column;
        align-items: stretch;
    }

    .customer__orderContent .orderContent__complainBtns {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 8px;
        width: 100%;
        margin: 12px 0 4px;
        padding-top: 12px;
        border-top: 1px solid $borderColor;
    }

    .customer__orderContent .orderContent__complainBtn {
        display: flex;
        width: 100%;
        justify-content: center;
        padding: 10px 12px;
        margin: 12px 0 4px;
        border-color: color-mix(in srgb, #{$linkFontColor} 25%, transparent);
    }

    .customer__orderContent .orderContent__complainBtns .orderContent__complainBtn {
        margin: 0;
    }
}

6. Szablon One Page Shop

Szablon One Page Shop ma praktycznie identyczną strukturę plików jak Topaz. Wszystkie powyższe modyfikacje (tłumaczenia, nowa strona zwrotów, edycje plików partials/common/complaint-popup.html oraz partials/customer/order-content.html, zmiany w js/layout1.js oraz w plikach SCSS profilu klienta i strony zwrotów) wykonaj 1:1 w plikach szablonu OPS pod tymi samymi ścieżkami. Treść kodu jest taka sama, ścieżki plików są takie same – instrukcja dla Topaza w pełni stosuje się również do One Page Shopa. Po wprowadzeniu wszystkich powyższych zmian w szablonie Topaz (oraz One Page Shop) pamiętaj o kompilacji oraz minifikacji plików js i scss, zgodnie z artykułem dostępnym pod linkiem https://pomoc.comarchesklep.pl/artykul/kompilacja-i-minifikacja-plikow/.
Wskazówka
Potrzebujesz pomocy lub masz pytania? Skontaktuj się z nami poprzez portal asysta.comarch.pl.

Graficzna prezentacja atrybutów na karcie produktu oraz na liście towarów w szablonie Rubin

Wstęp

Funkcja umożliwia prezentację atrybutów w formie kolorów, miniatur oraz kafelków z tekstem. Dotyczy ona towarów z wariantami. Chcesz, aby w Twoim e-sklepie atrybuty były prezentowane graficznie? Pokażemy Ci, jak w prosty sposób zmienić ustawienia, aby to umożliwić.

Konfiguracja atrybutów graficznych

Aby skonfigurować atrybuty graficzne, przejdź w Panelu administracyjnym do opcji Wygląd sklepu > Ustawienia, a następnie do sekcji Lista towarów > Strona główna. W tym miejscu możesz wybrać sposób prezentacji atrybutów: jako kolory, miniatury zdjęć lub warianty towarów.
Wskazówka
Pamiętaj, aby wprowadzone zmiany były widoczne w e-Sklepie należy je Zapisać i Opublikować.
Domyślnie parametr dotyczący graficznej prezentacji wariantów towarów jest ustawiony na „Nie”. W takiej sytuacji produkty w szablonie Rubin wyświetlane są w formie tabelarycznej.

Wariant - Kolory

Po wybraniu wariantu Kolory, w panelu administracyjnym automatycznie pojawi się nowe okno z nazwami kolorów oraz ich graficznymi odpowiednikami w notacji heksadecymalnej. Jest to część konfiguracji tej funkcji, która umożliwia mapowanie kolorów. Funkcja ta działa na podstawie atrybutów przypisanych do towarów w systemie ERP.

Domyślnie kolory takie jak niebieski, żółty czy fioletowy są mapowane automatycznie, więc uzupełnianie tego okna nie jest konieczne. Jednak jeśli atrybut zawiera niestandardowe nazwy kolorów, np. „miętowy”, należy ręcznie przypisać odpowiedni kolor w poniższym polu.

Przykładowa konfiguracja wariantu - Kolory

W systemie ERP stwórz atrybut o nazwie Kolor w formacie lista, a następnie udostępnij go do Comarch e-Sklep. Wypełnij pozycje listy, wpisując nazwy kolorów, np. żółty, fioletowy, pomarańczowy itd. Następnie przypisz utworzony atrybut do odpowiedniego towaru, który zostanie przesłany do e-Sklepu. Podczas przypisywania tego atrybutu do towaru pozostaw pole „Wartość” puste, aby umożliwić wybór wariantów kolorystycznych. Po zakończeniu powyższych kroków przeprowadź synchronizację z e-Sklepem.

Prezentacja wariantu Kolory na stronie e-Sklepu

Na liście towarów: Na szczegółach towarów - dla wszystkich wariantów

Wariant - Miniatury (tylko dla towarów zgrupowanych - "fantomów")

Wybór wariantu miniatury umożliwia graficzną prezentację wariantów towarów za pomocą pierwszego zdjęcia każdego towaru zgrupowanego (fantoma). Ze względu na specyfikę działania (każdy towar musi posiadać własne zdjęcie), funkcja ta jest dostępna wyłącznie dla towarów zgrupowanych.

Przykładowa konfiguracja wariantu - Miniatury

W systemie Comarch ERP stwórz towar zgrupowany zgodnie z dokumentacją Comarch e-Sklep. Poniższy wariant opiera się na konfiguracji atrybutu przedstawionej w sekcji dotyczącej graficznej prezentacji kolorów.

Prezentacja wariantu Miniatury na stronie e-Sklepu

Na liście towarów: Na szczegółach towarów:

Wariant - Tekst

W ramach konfiguracji wariantów z tekstem wystarczy zaznaczyć wskazane ustawienie: Po zapisaniu i opublikowaniu zmian kafelki z tekstem zostaną wyświetlone w odpowiednich miejscach w ramach e-Sklepu.

Przykładowa konfiguracja wariantu z tekstem

W systemie Comarch ERP stwórz towar zgrupowany zgodnie z dokumentacją Comarch e-Sklep. Poniższy wariant wykorzystuje konfigurację atrybutu zaprezentowaną w sekcji poświęconej graficznej prezentacji kolorów.

Prezentacja wariantu z tekstem na stronie e-Sklepu

Na liście towarów:   Na szczegółach towarów:  

Szablon Rubin - podstawowe informacje

Wstęp

Szablon Rubin jest dedykowany dla sklepów w wersji B2B. Wyróżnia się nowoczesnym wyglądem zgodnym z najnowszymi trendami oraz intuicyjną nawigacją, co pozwala na szybkie i komfortowe zakupy. Oferuje funkcje dedykowane dla modelu B2B, w tym umożliwia wykorzystanie Comarch e-Sklep Sync do wyświetlania zamówień, faktur i wydań zewnętrznych z systemu ERP. Przy pomocy Kreatora wyglądu, można dostosować układ elementów szablonu względem indywidualnych oczekiwań. Elastyczność konfiguracji szablonu sprawia, że jest on idealnym rozwiązaniem dla zróżnicowanych potrzeb biznesowych. Główne wyróżniki szablonu:
  • obsługa sprzedaży dla klientów biznesowych oraz indywidualnych,
  • intuicyjna nawigacja boczna pozwalająca na szybki przegląd towarów dodanych do koszyka bądź zapytania o wycenę,
  • trzy widoki listy towarów, w tym lista pozwalająca na jednoczesne dodawanie wielu towarów zarówno do koszyka, jak i do list zakupów,
  • szczegóły towaru z paskiem nawigacji przyklejonym do nagłówka, który podczas przeglądania szczegółów oferty umożliwia natychmiastowy dostęp do najważniejszych sekcji i funkcji – w tym możliwość szybkiego dodania towaru do koszyka,
  • koszyk z rekomendacjami produktów oraz jednostronną finalizacją, ułatwiającą zakup,
  • profil klienta pozwalający na łatwą identyfikację statusów zamówień oraz dostęp do faktur i wydań zewnętrznych z systemu ERP,
  • obsługa wielu list zakupów,
  • możliwość składania zapytań o wycenę produków.
Przejdź do naszego sklepu demonstracyjnego i zobacz, jak wygląda Szablon Rubin w Comarch e-Sklep! W tym artykule zawarliśmy podstawowe informacje na temat funkcji dostępnych w szablonie. Dzięki możliwości konfiguracji elementów szablonu możesz łatwo spersonalizować swój e-Sklep.

Obsługa sprzedaży dla klientów biznesowych

Jako że szablon Rubin został zaprojektowany, aby umożliwić sprzedaż dla klientów biznesowych, obsługuje on funkcje dostosowane do modelu B2B. W ramach przykładowych udogodnień oferowanych przez szablon należy wymienić możliwości, takie jak:
  • obsługa klientów detalicznych oraz typu firma – połączenie modeli B2B oraz B2C,
  • możliwość włączenia tylko cen netto,
  • obsługa wielu koszyków (z możliwością edycji nazwy koszyka i usuwania całego koszyka jednym przyciskiem),
  • obsługa wielu list zakupowych, ułatwiająca powtórne zakupy tych samych towarów.
  • wyświetlanie zamówień, faktur i wydań zewnętrznych z systemu ERP w profilu klienta dzięki wykorzystaniu Comarch e-sklep Sync,
  • możliwość włączenia limitów kredytowych,
  • opcja dostępu do sklepu tylko dla zalogowanych użytkowników,
  • możliwość dodawania pracowników w profilu klienta,
  • opiekun handlowy dla kontrahenta.

Konfiguracja szablonu Rubin w panelu administracyjnym

Z poziomu panelu administracyjnego możesz dokonywać konfiguracji opcji wyglądu szablonu. Po przejściu do sekcji Wygląd sklepu > Ustawienia dostępne są ustawienia dla czterech zakładek:
  • W zakładce Ogólne możesz dokonać zmian w motywie kolorystycznym Twojego e-Sklepu. Z tego poziomu również możliwe do konfiguracji są takie opcje jak: ustawienia ceny netto, prezentacja promocji, rabatów progowych czy jednostek pomocniczych.
  • W zakładce Strona główna znajdują się ustawienia, dzięki którym możesz ustalić kolejność poszczególnych elementów na stronie głównej. Dodatkowo możesz zarządzać animacjami na poszczególnych bannerach i sliderach.
  • W zakładce Lista towarów znajdują się ustawienia dotyczące filtrów czy wyświetlania opisu danej kategorii towarowej. Z tego miejsca można zarządzać prezentacją informacji na kaflach w ramach listy.
  • W zakładce Zarzadzanie strefą klienta znajdziesz ustawienia elementów, które mają być widoczne po zalogowaniu do strefy klienta.

Strona główna

Strona główna w sklepie internetowym pełni rolę wprowadzenia do oferty sklepu. Jej głównym celem jest przyciągnięcie uwagi odwiedzających, zaprezentowanie najważniejszych produktów czy aktualnych promocji. Z tego względu na stronie głównej do skonfigurowania możliwe są takie elementy jak:

  • Banner w formie slidera – ustawienia dla banneru można znaleźć w sekcji Wygląd sklepu > Ustawienia > Bannery po przejściu do sekcji mainBanner. Domyślny rozmiar dla obrazka we wskazanym bannerze wynosi: 1574px x 425px. Więcej o ustawieniach można przeczytać w artykule dotyczącym konfiguracji bannerów.
  • Banner z infografikami – pozwala na zaprezentowanie korzyści z zakupów w Twoim sklepie. Domyślny rozmiar obrazków wynosi: 48px x 48px. Edycja banneru jest możliwa z poziomu opcji Wygląd sklepu > Ustawienia > Bannery po przejściu do sekcji homepage-small.
  • Banner popup – pozwala na poinformowanie klientów o bieżącej ofercie czy rabatach. Domyślny rozmiar grafiki w bannerze wynosi: 330px x 418px. Edycja banneru jest możliwa z poziomu opcji Wygląd sklepu > Ustawienia > Bannery po przejściu do sekcji banner_popup1.
 
  • Zapis do newslettera – newsletter to jeden z kluczowych elementów każdej strony internetowej, który pozwala na utrzymywanie kontaktu z użytkownikami i budowanie bazy subskrybentów. W przypadku szablonu Rubin, sekcja z zapisem do newslettera jest możliwa do ustawienia w formie stałej sekcji na stronie głównej.
Możliwe jest także zaprezentowania zapisu do newslettera w formie banneru.
  • Towary polecane – slider z wybranymi towarami. Mogą to być na przykład towary z wybraną flagą, najczęściej kupowane na sklepie lub ustawione ręcznie z poziomu Panelu Administracyjnego. Elementy te możliwe są do edycji w zakładce Wygląd Sklepu > Ustawienia > Edytuj ustawienia zaawansowane > Obiekty po przejściu do obiektu new-product-mp-x. Więcej informacji można znaleźć w ramach artykułu dotyczącego wyświetlania towarów polecanych w szablonach.
  • Tekst SEO – wskazany element charakteryzuje się możliwością wprowadzenia statycznego opisu na stronie głównej w e-Sklepie. Aby ustawić treść, przejdź do zakładki Wygląd Sklepu > Ustawienia > Edytuj ustawienia zaawansowane > Obiekty. W tym miejscu należy odszukać obiekt text-element-1-mp-1 i edytować element tekstowy.
  • Aktualności – w tej sekcji znajdziesz najnowsze artykuły z bloga w formie slidera. Każdy wpis zawiera obrazek, tytuł, krótki fragment treści, a także tagi tematyczne oraz datę ostatniej aktualizacji.
  • Slider marek oraz slider producentów – w ramach wskazanych sliderów będą pokazywały się loga marek i producentów, uzupełnionych po stronie systemów Comarch ERP.

Lista towarów

1. Widoki list towarów

Lista towarów zawiera trzy różne widoki. W zakładce Wygląd sklepu > Ustawienia > Lista towarów jest możliwość wybrania domyślnego widoku: Każdy z nich ma inne zastosowanie i cechy charakterystyczne:
  • W ramach widoku kafli użytkownicy mają możliwość szybkiego dodania pojedynczej sztuki towaru:
  • W przypadku listy z rozbudowanym kaflem, możesz zaprezentować opis towaru lub jego atrybutów zgodnie z ustawieniem:

Z poziomu kafli dostępne są również dodatkowe akcje, takie jak dodanie do zapytania o wycenę, list zakupów czy do porównania. Co więcej, dla wskazanej listy, została dodana możliwość kopiowania kodu towaru.

  • Szybka lista charakteryzuje się możliwością dodania wielu towarów jednocześnie. Na wskazanej liście jest możliwość dodawania równocześnie kilku towarów zarówno do listy zakupów, jak i do koszyka:
W przypadku ustawień dla widoków szybkiej listy i rozbudowanych kafli, istnieje możliwość ustalenia ilości wyświetlanych atrybutów:

2. Graficzna prezentacja wariantów

W ramach kafli możesz ustawić graficzną prezentację wariantów – po najechaniu na kafel zostaną zaprezentowane atrybuty w postaci:
  • miniatur zdjęć,
  • wariantów kolorystycznych,
  • wartości tekstowej.
Wskazaną prezentację można włączyć po przejściu do opcji Wygląd sklepu > Ustawienia > Lista towarów. W tym miejscu można wybrać sposób prezentacji wariantów:

3. Opis kategorii

Na liście towarów możesz wyświetlić także opis danej kategorii dodany po stronie systemu Comarch ERP. Jest on zaprezentowany w szablonie w następującej formie: Jeżeli został on wypełniony, możesz zdecydować czy ma być on domyślnie zwinięty czy rozwinięty:

4. Panel filtra

W ramach ustawień listy towarów do dostosowania możliwe są też filtry. Z tego poziomu dostępne do skonfigurowania są następujące opcje:
  • Liczba wyświetlanych wartości, która wskazuje ile domyślnie będzie pokazanych elementów danego filtra przed przyciskiem „Pokaż więcej”:

W przypadku takiego ustawienia przed wskazanym przyciskiem będzie prezentowane pięć wartości filtra – reszta zostanie zaprezentowana po rozwinięciu:

  • Filtruj po użyciu przycisku „Zastosuj”:

Zgodnie z ustawieniem filtry będą działać dopiero po kliknięciu wskazanego przycisku. Jeżeli parametr jest ustawiony na „Nie”, lista będzie filtrować się dynamicznie po wybraniu filtra.

  • Domyślne ustawienie filtrów jako zwiniętych bądź rozwiniętych:
Wskazane ustawienie wpływa na to, czy po wejściu na listę towarów będą wskazane wartości filtrów czy zostaną one zaprezentowane dopiero po rozwinięciu:
  • Wskazanie elementów, które mają być prezentowane w panelu filtrów:
  • Graficzna prezentacja filtra typu kolor, którą należy skonfigurować zarówno w Panelu administracyjnym, jak i systemie Comarch ERP według instrukcji. Po wykonaniu odpowiednich kroków, kolory będą prezentować się następująco:

Szczegóły towaru

1. Sekcja z towarem

W ramach szczegółów towaru możemy wyróżnić sekcje z towarem. W jej ramach prezentowane są zdjęcia towarów oraz informacje towarze, takie jak: 
  • Ceny, w tym prezentację:
  • Jednostki miary oraz przeliczniki do jednostki podstawowej lub domyślnej.
  • Stan magazynowy.
  • Dostępność produktu.
  • Cechy towaru.
  • Informacja o wartości dostawy danego towaru.
  • Możliwość udostępnienia towaru w social mediach lub za pomocą linku.
  • Opcję „Zapytaj o towar” bądź „Zapytaj opiekuna” w zależności od konfiguracji.
W tym miejscu klienci mają także dostęp do dodatkowych opcji takich jak:
  • Tabela rozmiarów – możliwa do ustawienia z poziomu ustawień Wygląd sklepu > Ustawienia > Ogólne. Tabela rozmiarów jest możliwa do skonfigurowania w formie strony, pliku pdf lub popupu.
  • Sprawdź dostępność w salonie – dzięki wskazanemu elementowi, potencjalni klienci będą mieli okazję sprawdzić, czy dany towar znajduje się w sklepie stacjonarnym (salonie). Funkcja jest dostępna po spełnieniu odpowiednich wymagań konfiguracyjnych opisanych w artykule: Sprawdź dostępność towaru w salonie.
  • Historia zakupów – dla sklepów w wersji B2B, powiązanych z systemem Comarch ERP XL oraz aktywną usługą e-Sklep Sync, możliwe jest włączenie wskazanego ustawienia w opcjach Wygląd sklepu > Ustawienia > Ogólne:

Dzięki temu możliwe będzie wskazanie historii zakupów z ostatnich 6 miesięcy

  • Harmonogram dostaw – funkcja służy do sprawdzania, czy towar został zamówiony u dostawcy, jak również udostępnia informacje o zamówionej ilości oraz planowanej dostawie. Więcej informacji na jej temat można przeczytać w artykule udostępnionym w Centrum Pomocy.
Poniżej wskazanych informacji o towarze znajdują się dodatkowe sekcje. Podczas przewijania strony widoczna jest nawigacja przyklejona do nagłówka, która ułatwia szybkie dodanie towaru do koszyka.

2. Opis i specyfikacja

W pierwszej kolejności wskazane są opis i specyfikacja danego towaru. Wskazane elementy takie jak opis czy atrybuty towaru są możliwe do dodania po stronie systemów Comarch ERP.

3. Podmiot odpowiedzialny

Zgodnie z rozporządzeniem GPSR w szablonie możliwe jest zaprezentowanie podmiotów odpowiedzialnych. Konfiguracja w ramach wyświetlenia wskazanych informacji w szablonie została opisana w artykule: Jak dostosować e-Sklep do wymogów Rozporządzenia GPSR?

4. Opinie o towarze

Na szczegółach towaru możliwe do wyświetlenia są opinie o towarze. Sekcja jest wzbogacona o paski informujące o ilości poszczególnych ocen. Obsłużone zostało również zgłaszanie opinii zgodnie z Aktem o usługach cyfrowych DSA.

5. Pliki do pobrania

Sekcja z plikami do pobrania zwiera pliki załączone na karcie towaru po stronie systemu Comarch ERP:

6. Zestawy

W przypadku korzystania z systemu Comarch ERP Optima, do zaprezentowania na stronie szczegółów towaru możliwe są zestawy: Dzięki wskazanej prezentacji, klient może dowiedzieć się o promocyjnej ofercie zakupu kilku towarów jednocześnie w tańszej cenie.

7. Towary podobne i akcesoria

Dla towarów skonfigurowanych w systemie Comarch ERP XL istnieje możliwość zdefiniowania Towarów podobnych lub Akcesoriów. Aby wskazana sekcja była dostępna w e-Sklepie, należy ją skonfigurować po stronie Comarch ERP XL zgodnie z fragmentem instrukcji, w którym opisano obsługę towarów podobnych lub akcesoriów dla towaru. W przypadku zamienników, możliwe jest także ich skonfigurowanie w Comarch ERP Optima.

Koszyk

Po przejściu na stronę koszyka wyświetla się podsumowanie dodanych do niego towarów. Wskazana sekcja ma na celu prezentację towarów w ramach rekomendacji zakupowych, aby zachęcić klienta do dalszych zakupów. W szablonie Rubin składanie zamówienia zostało zaprojektowane tak, aby użytkownik mógł w jednym kroku wypełnić niezbędne dane: 
  • Formularz z danymi zamawiającego oraz danymi do faktury.
  • Sposób dostawy.
  • Sposób płatności.
Po uzupełnieniu powyższych informacji i zakupie towaru można przejść do podsumowania, w którym prezentowane są m.in. wcześniej wprowadzone dane klienta. W ramach koszyka istnieje możliwość włączenia prezentacji wartości rabatów dla danego zamówienia, zgodnie z ustawieniem:

Dzięki temu promocja zostanie zaprezentowana w koszyku w następujący sposób:   Dodatkowo, w przypadku dostaw, możliwe jest także włączenie edycji daty dostawy:

Wskazane ustawienie prezentuje się następująco:

Zapytanie o wycenę

W modelu sprzedaży B2B często spotyka się spersonalizowane wyceny dla różnych kontrahentów. Na wysokość cen wpływają takie czynniki jak zmieniające się ceny towarów, ilość zamówionych produktów, sytuacja rynkowa oraz szczególne warunki ustalone w umowach między sprzedawcą a klientem. Z tego względu w szablonie Rubin istnieje możliwość dodawania towarów do zapytania o wycenę zgodnie z ustawieniem: Do zapytania o wycenę możesz przejść z poziomu nagłówka, klikając ikonę "Zapytanie o wycenę". Po kliknięciu w szablonie prezentowany jest panel boczny z towarami dodanymi do zapytania: Po przejściu do szczegółów, dostępny jest formularz: Obsługa zapytań jest w dalszej kolejności procesowana po stronie panelu administracyjnego. W dalszej kolejności zarówno zapytanie o wycenę, jak i utworzona z niego oferta sprzedaży jest dostępna dla klienta z poziomu Profilu klienta.

Profil klienta

1. Ustawienia profilu klienta

W przypadku ustawień profilu klienta w ramach: Wygląd sklepu > Ustawienia >  Zarządzanie strefą klienta widoczna jest lista elementów zamieszczonych w e-Sklepie. Lista składa się z następujących ustawień:
  • Dostępne – ustawienie wyświetlania danego elementu na stronie. Jeżeli parametr jest zaznaczony (podświetla się na szaro) wówczas element będzie widoczny na stronie.
  • Kolejność – w tym polu za pomocą strzałek możemy zmienić kolejność przycisków.
  • Ikona – w tym miejscu należy wprowadzić nazwę ikony, która powinna się wyświetlać na dodanym elemencie.
  • Etykieta PL – nazwa elementu, która będzie się wyświetlała w polskiej wersji strony.
  • Id tłumaczenia – id z którego będą pobierane tłumaczenia elementu wyświetlane w obcojęzycznej wersji strony. Tłumaczenia dodawane są w panelu administracyjnym: Wygląd sklepu > Ustawienia > Tłumaczenia.

2. Dokumenty dostępne w profilu klienta

W ramach profilu klienta dostępne są dokumenty związane z procesem zamówienia w e-Sklepie. Z tego poziomu klient ma dostęp do zakładek prezentujących:
  • zamówienia,
  • faktury,
  • wydania zewnętrzne,
  • wydania magazynowe.
Aby móc obsługiwać dokumenty pochodzące z systemu Comarch ERP, należy skonfigurować usługę Comarch e-Sklep Sync. Dzięki temu dla klientów widoczne staną się dokumenty udostępniane przez to narzędzie. Dokumenty, dla których wymagana jest wskazana usługa zostały opisane w artykule Dokumenty udostępniane przez Comarch e-Sklep Sync. Dzięki odpowiednim oznaczeniom kolorystycznym klient ma możliwość w prosty sposób zapoznać się ze statusami wskazanych dokumentów:

3. Zapytania o wycenę i oferty sprzedaży

Z tego poziomu klient ma dostęp również do listy z wykonanymi zapytaniami o wycenę. Po stworzeniu wyceny na dane zapytanie, w zakładce Oferta sprzedaży pojawi się oferta do zaakceptowania przez klienta: Więcej informacji na temat zapytań i ofert sprzedaży można znaleźć w artykułach: Zapytaj o cenę oraz Jak stworzyć ofertę sprzedaży i zapytanie ofertowe?

4. Reklamacje/zwroty

Klient ma możliwość zareklamowania towaru po przejściu na szczegóły zamówienia. Z tego poziomu jest możliwość wybrania opcji reklamacji dla towaru: Informacje o reklamacjach znajdą się w zakładce Reklamacje/ Zwroty:

5. Moje dane

W zakładce Moje dane klient ma możliwość weryfikacji wprowadzonych danych jako firma bądź osoba fizyczna. W tym miejscu wyświetlone są także uzupełnione adresy dostawy – wskazany jest także adres domyślny.

6. Pracownicy

We wskazanej zakładce istnieje możliwość dodania pracownika, jak również jego zablokowania. Dodatkowo jeżeli pracownik jest przypisany do kilku firm istnieje możliwość zmiany firmy z poziomu nagłówka sklepu: Więcej na temat pracowników w e-Sklepie możesz dowiedzieć się w artykule: Wielu pracowników kontrahenta.

7. Twoje konto

We wskazanej zakładce znajdują się dane kontaktowe klienta, jak i dane do logowania – e-mail i hasło. Z tego poziomu dostępna jest również historia konta

8. Zgody

W tym miejscu klientowi prezentowana jest lista zaakceptowanych zgód:

9. Do pobrania

Poprzez dodanie załączników do karty kontrahenta w systemie Comarch ERP XL  w szablonie Rubin jest możliwe wyświetlanie listy plików do pobrania dla zalogowanych użytkowników. Są one widoczne i dostępne do pobrania w Profilu Klienta we wskazanej zakładce. Sposób konfiguracji wskazanych plików został opisany w artykule: Lista plików Klienta – Do pobrania

10. Promocje

Dzięki wskazanej zakładce klienci mogą sprawdzić, jakie rabaty aktualnie posiadają. Widoczne w tej zakładce rabaty są przesyłane z systemu ERP oraz ustalane w Panelu Administracyjnym Comarch e-Sklep. Obsługiwane rabaty:
  • rabaty dla nowego klienta
  • rabaty od wartości zamówienia
  • rabat dla stałego klienta
  • rabaty z Comarch ERP
  • stała cena z Comarch ERP
Aby wskazane promocje wyświetlały się w profilu klienta należy włączyć ustawienie w Wygląd sklepu > Ustawienia > Ogólne: Informacje o konfiguracji rabatów można znaleźć w ramach artykułu: Rabaty – rodzaje i zasady wyliczania.

Listy zakupów

W szablonie Rubin dla wersji sklepu B2B możliwe jest posiadanie wielu list zakupów. Funkcja dostępna jest tylko dla zalogowanych klientów. Umożliwia ona zaplanowanie zakupów z wyprzedzeniem w uporządkowany sposób poprzez tworzenie list na różne okazje i ustawianie dla nich daty przypomnienia: Po przejściu do list istnieje możliwość utworzenia nowej listy: W ramach listy jest możliwa do ustawienia data przypomnienia: Dodatkowo z tego poziomu klient ma możliwość nadania liście nazwy, przeniesienia jej do zapytania o wycenę, jak również dodania towarów z listy do koszyka.

Lookbook

Lookbook oferuje możliwość przedstawienia towarów bezpośrednio na zdjęciu w formie zaznaczonych pinezek. W szablonie Rubin możliwe jest stworzenie wielu lookbooków. Będą one w takim wypadku prezentowane w formie listy: Szczegóły lookbooka charakteryzują się precyzyjnym oznaczeniem towarów na zdjęciu. Dzięki znacznikom umieszczonym na grafice Twoi klienci będą mogli podejrzeć towar i dodać go bezpośrednio do koszyka lub listy zakupów. Po kliknięciu na przycisk z plusem wyświetli się popup ze szczegółami towaru oraz opcją zakupu.
Wskazówka
Rekomendowany rozmiar grafik do lookbooka to 578 x 578 px.
Aby poprawnie skonfigurować lookbook, skorzystaj z naszej instrukcji zawartej w artykule: Jak skonfigurować Lookbook w Comarch e-Sklep?

Blog

Blog jest ważnym elementem w strategii każdego sklepu internetowego. Umożliwia sprzedawcy dzielenie się wiedzą i doświadczeniami dotyczącymi oferowanych produktów. Poprzez bloga, sklep może podpowiedzieć klientom, jak najlepiej wykorzystać dostępne artykuły. Dodatkowo, regularne publikowanie wartościowych treści ma korzystny wpływ na pozycjonowanie strony, dzięki unikalnym materiałom. To sprawia, że Twój sklep może być częściej widoczny w wynikach wyszukiwania.

W sekcji z blogiem prezentowane są aktualnie dodane artykuły, które są możliwe do konfiguracji w Panelu administracyjnym. Dla każdego wpisu przedstawione są: zdjęcie, treść, tagi oraz przewidywany czas czytania. Szczegółowe informacje na temat konfiguracji bloga w e-Sklepie znajdują się w artykule: Jak skonfigurować blog?

Kreator wyglądu szablonu Rubin

Wstęp

Jednym z kluczowych elementów wpływających na sukces w branży e-commerce jest odpowiednia oprawa wizualna sklepu internetowego. To ona w dużej mierze kształtuje wrażenia użytkowników oraz wpływa na przebieg ich procesu zakupowego. Dzięki narzędziu Kreator Szablonu Rubin (B2B) właściciele sklepów mają możliwość stworzenia unikalnego, dopasowanego szablonu, który będzie obsługiwał zarówno klientów detalicznych, jak i firmy, łącząc modele B2B oraz B2C.

Zastosowanie

Kreator Szablonu Rubin to intuicyjne narzędzie do projektowania wyglądu sklepu. Wszystko odbywa się na poziomie strony internetowej, gdzie przy pomocy metody "przeciągnij i upuść" możesz stworzyć szablon idealnie pasujący do Twojego sklepu.

Kreator pozwala na zaprojektowanie wszystkich kluczowych obszarów sklepu, w tym:

  • Strony głównej.
  • Listy towarów.
  • Koszyka.

Kto może używać tej opcji?

Aby móc używać tego narzędzia należy posiadać:

  • Comarch e-Sklep w wersji Enterprise lub B2B,
  • szerokość ekranu powyżej 1280 px, a zalecana to 1920 px,
  • oraz jedną z przeglądarek internetowych w aktualnej wersji.

Wskazówka
Kreator szablonu Rubin dostępny jedynie w wersji przeglądarkowej.

Zaczynamy!

Jak zaprojektować układ szablonu?

Aby rozpocząć projektowanie szablonu, należy udać się na stronę Kreatora Wyglądu, gdzie pojawi się powitalny komunikat. Na początku trzeba wybrać, dla jakiego typu sprzedaży ma być stworzony szablon – detalicznej lub hurtowej. Sprzedaż hurtowa jest dedykowana tym, którzy chcą oferować swoje produkty także klientom biznesowym w większych ilościach. Po dokonaniu wyboru modelu sprzedaży, wystarczy kliknąć przycisk „Rozpocznij pracę”. Następnie, użytkownik będzie miał możliwość stworzenia nowego szablonu lub edytowania jednego z dostępnych, gotowych szablonów.

  W sytuacji gdy wcześniej tworzony był już projekt, widoczny będzie przycisk umożliwiający dokończenie szablonu lub rozpoczęcie nowego projektu. Opcja Nowy szablon umożliwia zbudowanie od początku nowego szablonu Rubin według Twojego indywidualnego pomysłu.   W ramach szablonów B2B do wyboru zostały udostępnione szablon Rubin oraz szablon Szafir w trzech wersjach kolorystycznych. Są to gotowe wersje szablonów z możliwością ich edycji. Dzięki temu nie musisz zaczynać pracy od zera – wystarczy, że wybierzesz jeden z dostępnych szablonów, a następnie łatwo dopasujesz go do swoich wymagań. Podwójne kliknięcie na wybrany kafelek pozwala przejść do kolejnego etapu. W trzech prostych krokach zapoznasz się z podstawowymi funkcjami kreatora. Po ich przejściu, możesz rozpocząć dalsze dostosowywanie szablonu lub od razu wygenerować przygotowaną wersję szablonu Rubin.

Od czego zacząć?

Wybierz preferowaną wersję językową Kreatora i rozpocznij tworzenie swojego szablonu. Dostępne opcje to: język polski, angielski, niemiecki oraz francuski. Aby zmienić język, kliknij strzałkę obok flagi i nazwy języka w lewym dolnym rogu. Po wybraniu języka, przy podglądzie na pełnym ekranie, szablon będzie wyświetlany w wybranej wersji językowej.

Po ustawieniu wersji językowej dla Kreatora, warto nadać nazwę swojemu szablonowi. Można to zrobić klikając „Zmień” w lewym górnym rogu, a następnie wpisując nową nazwę, która zastąpi domyślną nazwę „Rubin”. Ta nazwa będzie widoczna po zaimportowaniu szablonu do panelu administracyjnego oraz po wyeksportowaniu go do pliku XML, wraz z datą i godziną wygenerowania szablonu.

Krok 1 - Strona główna

W tej sekcji należy zaprojektować wygląd strony głównej naszego Comarch e-Sklepu dla szablonu Rubin. Strona główna może składać się z następujących elementów:

  • Nagłówek,
  • Baner,
  • Widget,
  • Banner pop-up,
  • Proponowane,
  • Newsletter,
  • Slider producentów,
  • Slider marek,
  • Aktualności,
  • Banner infografika,
  • Element tekstowy,
  • Stopka.

Po kliknięciu w strzałkę, sekcje rozwiną się i pokażą dostępne elementy:

Metodą "Przeciągnij i upuść" przenosimy wybrane elementy na obszar po prawej stronie:

Postępuj analogicznie z pozostałymi elementami.

Nagłówek

Sekcja „Nagłówek” prezentuje jeden widok. Nagłówek dodatkowo można konfigurować w zakresie funkcji związanych ze składaniem Zapytań o wycenę.

Bannery

Sekcja "Bannery" pozwala dodać slider. Informacje dotyczące rekomendowanych rozmiarów obrazków w bannerach opisaliśmy w tym artykule.

Widget

Sekcja "Widget" pozwala dodać jeden element, który pozwoli zaprezentować następujące funkcj:
  • dodanie zdjęcia,
  • dodanie tekstu tekstu nagłówka (tekst pionowy),
  • dodanie linku do przycisku,
  • dodanie tekstu.

Banner pop-up

Sekcja „Banner pop-up” pozwala na dodanie bannera w formie popupu. Banner ten jest możliwy do wyświetlenia jedynie na stronie głównej e-Sklepu.

Proponowane

Sekcja „Proponowane” oferuje dodatkowe opcje do konfiguracji. Z menu rozwijanego, dostępnego po kliknięciu przycisku „Zmień typ”, możesz wybrać kategorię produktów, które mają być wyświetlane w tej sekcji (np. nowości, najczęściej oglądane, wyprzedaż, sugerowane). Po dokonaniu zmiany typu, sekcja zostanie odpowiednio nazwana po załadowaniu szablonu do sklepu.

Dodatkowo po najechaniu kursorem na tę sekcję, wybierając Opcje, możemy ustawić liczbę towarów, która będzie się wyświetlać (maksymalnie 50).

Podczas tworzenia szablonu w Kreatorze wyglądu Rubin po dodaniu sekcji towary polecane można określić typ wyświetlanych produktów. Nazwa sekcji jest zależna oraz adekwatna do określonego typu. Daną nazwę można modyfikować w tłumaczeniach szablonu. Dodatkowo każdy wybrany typ jest podlinkowany do wszystkich produktów wskazanego rodzaju. W zależności od wybranego typu, edycji parametrów wyświetlania dokonasz w panelu administracyjnym e-Sklepu. Z kolei informację o typie towaru ustawisz w systemie ERP. Typy towarów edytowane z poziomu panelu administracyjnego Comarch e-Sklep:
  • Promocja,
  • Nowość,
  • Wyprzedaż,
  • Super jakość,
  • Super cena,
  • Rekomendacja sprzedawcy,
  • Zapowiedź,
  • Sugerowane,
  • Towar polecany,
  • Najczęściej oglądane / najczęściej kupowane,
  • Cross-selling - oferowanie produktów uzupełniających wcześniejsze zakupy,
Aby zdecydować o parametrach wyświetlania tych informacji należy przejść w panelu administracyjnym Comarch e-Sklep do zakładki Ustawienia > Ustawienia sklepu > Towary:

Producent, marka, ręcznie wybrane produkty, kategoria oraz ostatnio oglądane są obsługiwane w ramach lokalnego obiektu "Siatka towarów". Aby wprowadzić zmiany w ustawieniach dla jednego z tych typów, należy przejść do panelu administracyjnego do opcji Wygląd sklepu > Ustawienia >Ustawienia zaawansowane, a następnie do zakładki Obiekty. W szczegółach wybranego obiektu (Siatka towarów) można określić, które produkty będą wyświetlane w sekcji "Proponowane". W przypadku wyboru "Producenta" lub "Marki" konieczne jest ręczne wskazanie odpowiedniego producenta lub marki.

Dodawanie informacji o typie produktu w systemie ERP dotyczy:
  • Nowości,
  • Produktu z gazetki,
  • Produktu polecanego,
  • Wyprzedaży,
  • Promocja,
  • Nowość,
  • Super jakości,
  • Super ceny,
  • Najlepszej oceny,
  • Rekomendacji sprzedawcy.
Informacja tego typu ustawiana jest bezpośrednio na karcie towaru w systemie ERP poprzez zaznaczenie odpowiedniej flagi w systemie ERP XL (zakładka aplikacje) lub atrybutu czasowego w ERP Optima (zakładka e-Sklep, sekcja atrybuty czasowe). Po wybraniu konkretnej opcji w systemie ERP na karcie danego produktu w Comarch e-Sklep zostanie dodana odpowiednia informacja.

Newsletter

Dla newslettera możliwe jest ustawienie stałej sekcji na stornie głównej lub newslettera w postaci popupu:

Slider marek

Sekcja "Slider marek" pozwala na dodanie do szablonu widoku slidera z logo marek. W sliderze wyświetlane są logotypy marek, które zostały zaimportowane z systemu ERP. Po kliknięciu na wybrane logo, użytkownik zobaczy listę produktów przypisanych do danej marki. Sekcje te mogą być umieszczone w dowolnym miejscu na stronie głównej szablonu.

Slider producentów

Sekcja "Slider producentów" pozwala na dodanie do szablonu widoku slidera z logo producentów. W sliderze wyświetlane są logotypy producentów zaimportowane z systemu ERP. Po kliknięciu na wybrane logo, użytkownik zobaczy listę produktów przypisanych do danego producenta. Sekcje te mogą być umieszczone w dowolnym miejscu na stronie głównej szablonu.

Aktualności

Sekcja umożliwia zamieszczenie aktualności na stronie głównej w formie listy artykułów z bloga. Tekst wprowadza się w panelu administracyjnym przechodząc do zakładki  Marketing > Blog.

Banner infografika

Sekcja "Banner infografika" pozwala na zaprezentowanie korzyści z zakupów w Twoim sklepie. Dotyczą one obszarów: informacji o dostawie, płatnościach czy obowiązujących rabatach rabatach. Banner możesz dodać tylko do strony głównej. Obrazki są możliwe do edycji w ramach elementu homepage-small w panelu administracyjnym e-Sklepu w obszarze: Wygląd sklepu > Ustawienia > Bannery.

Stopka

Sekcja "Stopka" zawiera jeden widok do wyboru. W widoku Stopki widnieją strony statyczne, którymi można zarządzać w sekcji Wygląd Sklepu/ Ustawienia/ Stopka. Dla każdej z sekcji wyświetla się jej utworzona w panelu nazwa. W stopce znajduje się komunikat @Comarch SA 2025. All rights reserved Powered by Comarch e-Sklep. Dodatkowo istnieje możliwość umieszczenia w stopce odnośników do mediów społecznościowych oraz ich ikony. Możemy dodać ikony naszych dostawców oraz form płatności wykorzystywanych w sklepie w ramach ustawień Wygląd Sklepu > Ustawienia > Bannery w sekcjach LogisticsPartners oraz PaymentOperators.

Po wybraniu wszystkich niezbędnych sekcji nasza strona główna powinna być gotowa. Efekt naszej pracy możemy podejrzeć klikając Podgląd w prawym górnym rogu.

Dzięki tej opcji możesz zobaczyć, jak będzie prezentował się Twój szablon zarówno w wersji dekstop, jak i mobile.

Strona główna wymaga dwóch podstawowych elementów: nagłówka oraz stopki. Pozostałe elementy nie są obowiązkowe.

Krok 2 - Lista towarów

Kolejnym krokiem jest utworzenie listy towarów. Aby to zrobić, należy rozwinąć listę zgodnie z poniższym rysunkiem, a następnie przejść do wskazanej zakładki:

Banner

Sekcja "Banner" daje możliwość dodania do listy slideru, dzięki czemu masz możliwość wzbogacenia kategorii towarowych o obrazki.  

Panel filtra

Sekcja "Panel filtra" umożliwia wybór liczby wyświetlanych wartości filtrów a także o tym czy filtrowanie powinno odbywać się po klinićiu przycisku "Zastosuj". Z tego poziomu możemy także wybrać elementy prezentowane w panelu filtrów.

Opis kategorii

W sekcji możesz zdecydować, czy opis ma być domyślnie zwinięty lub rozwinięty.

Lista towarów

Podobnie, jak w przypadku strony głównej konfigurujemy wygląd listy towarów. Dodatkowo możemy wskazać liczbę wyświetlanych towarów, domyślny widok listy towarów, prezentację atrybutów, a także zdecydować czy pozwolisz na zakup towarów wielowariantowych z listy towarów.

W Kreatorze Szablonu Rubin dostępny jest jeden widok listy towarów:  

Krok 3 - Koszyk

Po utworzeniu szczegółów towaru przechodzimy do ustawień koszyka dostępnego w e-Sklepie. Dodatkowo na stronie koszyka możesz wskazać sposób prezentacji przeliczników jednostek miary:

Następnie możemy przejść do modyfikacji wyglądu naszego szablonu. W tym celu należy przejść do zakładki Style.

Style

Jak zmienić kolory, czcionki oraz ikony?

Po dodaniu elementów strony możemy dodatkowo podejrzeć, jak będzie wyglądał nasz przyszły szablon. W tym celu należy przejść do zakładki Style.

Motyw kolorystyczny

W tym momencie dla szablonu Rubin został przygotowany jeden motyw kolorystyczny:

Motyw możemy zmieniać według indywidualnych preferencji. Możemy zmodyfikować kolor poszczególnych elementów (m.in.: tło strony, tło nagłówka, nazwę towaru). Zmiany należy zapisać klikając Zapisz. Jeśli wykonane zmiany nie są zadowalające, możemy przywrócić ustawienia domyśle dla danego motywu kolorystycznego, klikając przycisk Przywróć.

Możliwe jest również wprowadzenie szesnastkowego zapisu kolorów. Heksadecymalny zapis kolorów dla poszczególnych sekcji w szablonie dostępny jest podczas edycji wybranego motywu kolorystycznego.

Czcionki

W tym momencie w ramach szablu Rubin została udostępniona jedna czcionka:

Ikony

Ostatnim elementem, który możemy modyfikować z poziomu zakładki Style jest wygląd ikon. Mamy do wyboru 3 różne warianty wyglądu ikon. Dodatkowo istnieje możliwość wyboru w jakiej postaci wyświetla się ikona koszyka (torba, wózek lub koszyk) oraz loader.

 

Funkcja cofania zmian

Funkcja odpowiadająca za cofanie oraz powtórzenie wprowadzonych zmian oznaczona jest symbolem strzałek, zapamiętuje ona do 30 ostatnich modyfikacji szablonu. Nieaktywna strzałka oznacza, że aktualnie nie ma dostępnych kroków. Mamy możliwość przywracania zmian: dodawania/ usuwania elementów oraz edycji ich położenia, a także stylu w szablonie.
Wskazówka
Funkcję cofania obejmuje zmiany motywu kolorystycznego, natomiast edycja poszczególnych kolorów w motywie nie jest zapisywana.

Generowanie i wgrywanie szablonu

Po zaprojektowaniu wyglądu szablonu możemy go wygenerować i pobrać na dysk korzystając z przycisku Generuj widocznego w prawym górnym rogu:

Obok przycisku Generuj dostępna jest również opcja Importuj szablon, umożliwiająca wgranie wcześniej zapisanego szablonu z dysku i ponowną jego edycję.

W przypadku prawidłowego wygenerowania szablonu wyświetlony zostanie komunikat informujący o tym fakcie i pobrany plik.

Pobrany szablon należy zaimportować w Comarch e-Sklep w zakładce Wygląd sklepu/ Zaimportuj szablon z Kreatora Wyglądu.

W przypadku braku obowiązkowych elementów szablonu nie będzie możliwe jego wygenerowanie. przycisk Generuj będzie wyszarzały, a w prawym dolnym rogu pojawi się komunikat „Uzupełnij elementy wymagane w szablonie”. Sekcje, gdzie element nie został wybrany, będą się wyświetlać z odpowiednią ikoną.

 

Aktualizacja szablonu

W Kreatorze szablonu Rubin znajduje się opcja aktualizacji poprzednich wersji szablonu. W celu zaktualizowania całego szablonu należy wgrać plik z poprzednim szablonem do Kreatora szablonu Rubin według tej instrukcji:
  • po uruchomieniu strony kreatora wybierz opcję: Stwórz nowy projekt,
  • wybierz Nowy szablon,
  • w prawym górnym rogu wybierz opcję Importuj szablon,
  • następnie zaimportuj plik z szablonem, który ma być zaktualizowany. Po poprawnym zaimportowaniu szablonu otrzymasz informację zwrotną:
  • po wgraniu szablonu do aktualizacji użyj opcji Generuj. 
Dzięki temu w prosty sposób można starsze szablony Rubin podnieść do wersji aktualnej.

Więcej informacji

Więcej informacji można znaleźć w artykułach o wyglądzie sklepu oraz o dostosowaniu wyglądu.

Szablon Szafir (dedykowany dla B2B)

Instrukcja: Jak dostosować samodzielnie szablon do szybkich zwrotów w e-Commerce?

Wskazówka
Wskazówka: W tym artykule trzeba będzie wprowadzać zmiany w plikach js oraz scss. Z tego artykułu dowiesz się jak je kompilować i minifikować.
W szablonach Rubin, Szafir oraz Topaz / One Page Shop wprowadziliśmy funkcję szybkich zwrotów. Umożliwia ona klientom składanie wniosku o zwrot produktu zarówno z poziomu profilu klienta (zalogowani), jak i z dedykowanej strony zwrotów po podaniu numeru zamówienia oraz adresu e-mail (niezalogowani). Wraz z funkcjonalnością pojawił się m.in. rozbudowany ekran potwierdzenia zwrotu zawierający kolejne kroki i adres do wysyłki, banery informacyjne dotyczące terminu zwrotu oraz przyciski akcji w tabeli produktów wyświetlane bezpośrednio (zamiast w rozwijanym menu). Aby Twój szablon poprawnie obsługiwał te zmiany, wprowadź modyfikacje opisane poniżej w sekcji dotyczącej Twojego szablonu. Po zakończeniu edycji pamiętaj o kompilacji i minifikacji plików js oraz scss.
Wskazówka
Potrzebujesz pomocy lub masz pytania? Skontaktuj się z nami poprzez portal asysta.comarch.pl.
Wskazówka
Obecnie w Polsce trwają prace nad ostatecznym kształtem przepisów oraz nowelizacją Ustawy o prawach konsumenta, która wdroży unijną dyrektywę UE 2023/2673 i wprowadzi nowe wymagania techniczne dla platform e-commerce (m.in. ułatwienia w procedurze zwrotów). W momencie publikacji ostatecznej wersji polskich przepisów, wdrożone funkcjonalności mogą wymagać dostosowania do ostatecznych wytycznych ustawodawcy. Prezentowane informacje mają charakter poglądowy a instrukcja dotyczy zmian, jakie wprowadziliśmy w szablonach Comarch – w przypadku pytań dotyczących indywidualnej sytuacji prawnej Twojego sklepu, zalecamy konsultację z radcą prawnym lub adwokatem.

Szablon Rubin

1. Tłumaczenia

W panelu administracyjnym sklepu zaktualizuj dwa istniejące tłumaczenia oraz dodaj nowe klucze wymagane przez funkcjonalność szybkich zwrotów. Zaktualizuj poniższe istniejące tłumaczenia: ReturnSuccessTitle - PL: Gotowe! Przyjęliśmy Twoje zgłoszenie - EN: Done! We have received your request - DE: Fertig! Wir haben Ihre Anfrage erhalten - FR: C'est fait ! Nous avons reçu votre demande ReturnSuccessInfo - PL: Przygotuj paczkę i odeślij ją do nas – wszystkie szczegóły znajdziesz poniżej. - EN: Prepare the package and send it back to us – all the details are below. - DE: Bereiten Sie das Paket vor und senden Sie es an uns zurück – alle Details finden Sie unten. - FR: Préparez le colis et renvoyez-le nous – tous les détails sont ci-dessous. Dodaj nowe tłumaczenia: OrderReturnDeadlineInfo - PL: Zamówienie można zwrócić w ciągu {0} dni od daty dostawy. - EN: You can return the order within {0} days from the delivery date. - DE: Sie können die Bestellung innerhalb von {0} Tagen ab Lieferdatum zurückgeben. - FR: Vous pouvez retourner la commande dans les {0} jours suivant la date de livraison. RestrictedOrderViewInfo - PL: Wybrane dane zamówienia zostały ukryte ze względów bezpieczeństwa. Możesz zwrócić produkty bez logowania. - EN: Some order details are hidden for security reasons. You can return products without signing in. - DE: Einige Bestelldetails wurden aus Sicherheitsgründen ausgeblendet. Sie können Produkte ohne Anmeldung zurücksenden. - FR: Certaines informations de la commande ont été masquées pour des raisons de sécurité. Vous pouvez retourner des produits sans vous connecter. Com_RefundMethod - PL: Sposób zwrotu środków - EN: Refund method - DE: Rückerstattungsmethode - FR: Mode de remboursement Com_RefundAsPaid - PL: Tak jak zapłacono - EN: Same as paid - DE: Wie bezahlt - FR: Comme payé Com_RefundToBankAccount - PL: Na konto bankowe - EN: To bank account - DE: Auf Bankkonto - FR: Sur le compte bancaire Com_BankAccountNumber - PL: Nr konta bankowego - EN: Bank account number - DE: Bankkontonummer - FR: Numéro de compte bancaire Com_ConfirmationSentTo - PL: Potwierdzenie zwrotu zostało wysłane na adres: - EN: Return confirmation has been sent to: - DE: Bestätigung wurde gesendet an: - FR: La confirmation de retour a été envoyée à: Com_NextSteps - PL: Następne kroki - EN: Next Steps - DE: Nächste Schritte - FR: Prochaines étapes Com_PackProducts - PL: Bezpiecznie zapakuj swoje produkty - EN: Safely pack your products - DE: Verpacken Sie Ihre Produkte sicher - FR: Emballez vos produits en toute sécurité Com_SendPackageTo - PL: Wyślij paczkę na adres: - EN: Send the package to the address: - DE: Senden Sie das Paket an die Adresse: - FR: Envoyez le colis à l'adresse: Com_RefundAfterReceive - PL: Pieniądze zwrócimy niezwłocznie po otrzymaniu i sprawdzeniu Twojej paczki - EN: We will refund the money promptly upon receipt and inspection of your package - DE: Wir erstatten das Geld umgehend nach Erhalt und Überprüfung Ihres Pakets zurück - FR: Nous rembourserons l'argent rapidement après réception et inspection de votre colis ReturnInThreeSteps - PL: Zwróć towar w 3 krokach - EN: Return the product in 3 steps - DE: Geben Sie die Ware in 3 Schritten zurück - FR: Retournez la marchandise en 3 étapes ReturnWithoutReasonInfo - PL: Przysługuje Ci możliwość zwrotu bez podania przyczyny. - EN: You have the right to return the product without giving a reason. - DE: Sie haben das Recht, die Ware ohne Angabe von Gründen zurückzugeben. - FR: Vous avez le droit de retourner la marchandise sans donner de motif. OrEnterOrderNumber - PL: lub podaj numer zamówienia - EN: or enter the order number - DE: oder geben Sie die Bestellnummer ein - FR: ou saisissez le numéro de commande FillForm - PL: Wypełnij formularz - EN: Fill out the form - DE: Füllen Sie das Formular aus - FR: Remplissez le formulaire ReturnOnline - PL: zwrotu online - EN: online return - DE: Online-Rückgabe - FR: retour en ligne SendParcel - PL: Wyślij paczkę - EN: Send the parcel - DE: Paket senden - FR: Envoyer le colis SendParcelToOurAddress - PL: nadaj przesyłkę na nasz adres - EN: send the parcel to our address - DE: senden Sie das Paket an unsere Adresse - FR: envoyez le colis à notre adresse FastSimpleSecure - PL: Szybko, prosto i bezpiecznie. - EN: Fast, simple and secure. - DE: Schnell, einfach und sicher. - FR: Rapide, simple et sécurisé. ReadyForReturn - PL: Gotowy do zwrotu? - EN: Ready for return? - DE: Bereit zur Rückgabe? - FR: Prêt pour le retour ? ReadyForReturnInfo - PL: Kliknij poniżej, aby rozpocząć proces zwrotu. Przeprowadzimy Cię przez wszystkie kroki. - EN: Click below to start the return process. We will guide you through all the steps. - DE: Klicken Sie unten, um den Rückgabeprozess zu starten. Wir führen Sie durch alle Schritte. - FR: Cliquez ci-dessous pour lancer le processus de retour. Nous vous guiderons à travers toutes les étapes. StartReturn - PL: Rozpocznij zwrot - EN: Start return - DE: Rückgabe starten - FR: Commencer le retour ProductReturn - PL: Zwrot produktu - EN: Product return - DE: Produktrückgabe - FR: Retour du produit ProductReturnFormInfo - PL: Wprowadź dane zamówienia, aby zlokalizować zakup i rozpocząć proces zwrotu. Numer zamówienia znajdziesz w e-mailu z potwierdzeniem. - EN: Enter the order details to locate the purchase and start the return process. You will find the order number in the confirmation e-mail. - DE: Geben Sie die Bestelldaten ein, um den Kauf zu lokalisieren und den Rückgabeprozess zu starten. Die Bestellnummer finden Sie in der Bestätigungs-E-Mail. - FR: Saisissez les données de la commande pour localiser l'achat et démarrer le processus de retour. Vous trouverez le numéro de commande dans l'e-mail de confirmation. InvalidOrderNumber - PL: Błędny numer zamówienia. Spróbuj ponownie. - EN: Invalid order number. Please try again. - DE: Ungültige Bestellnummer. Bitte versuchen Sie es erneut. - FR: Numéro de commande incorrect. Veuillez réessayer. FindOrder - PL: Znajdź zamówienie - EN: Find order - DE: Bestellung finden - FR: Trouver la commande LoginToSeeOrdersAndReturn - PL: aby zobaczyć swoje zamówienia i dokonać zwrotu. - EN: to see your orders and make a return. - DE: um Ihre Bestellungen einzusehen und eine Rückgabe vorzunehmen. - FR: pour voir vos commandes et effectuer un retour. RefundLookupError - PL: Wystąpił błąd podczas wyszukiwania zamówienia. Spróbuj ponownie później. - EN: An error occurred while searching for the order. Please try again later. - DE: Bei der Suche nach der Bestellung ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut. - FR: Une erreur s'est produite lors de la recherche de la commande. Veuillez réessayer plus tard.

2. Nowa strona Szybkie zwroty

Funkcjonalność szybkich zwrotów wymaga utworzenia dodatkowej strony statycznej refunds. Wykonaj poniższe kroki.

Plik refunds.html w katalogu głównym szablonu

W katalogu głównym szablonu utwórz nowy plik refunds.html z następującą zawartością:
{% extends '_layout.html' -%}

{% block pageContent -%}
{% include 'static-elements/refunds/refunds.html' -%}
{% endblock -%}

Plik static-elements/refunds/refunds.html

W folderze static-elements utwórz nowy katalog refunds, a w nim plik refunds.html:
<div class="page-padding">
    <h1 class="refunds-page-title refunds-initial-view-js">{{ translations.Returns }}</h1>
    <section class="refunds-container refunds-initial-view-js">
        <div class="refunds-info">
            <h2 class="refunds-info__title">{{ translations.ReturnInThreeSteps }}</h2>
            <p class="refunds-info__intro">{{ translations.ReturnWithoutReasonInfo }}</p>
            <ol class="refunds-steps">
                <li class="refunds-steps__item">
                    <span class="refunds-steps__number">1</span>
                    <p class="refunds-steps__text"><strong>{{ translations.LogIn }}</strong> {{ translations.OrEnterOrderNumber }}</p>
                </li>
                <li class="refunds-steps__item">
                    <span class="refunds-steps__number">2</span>
                    <p class="refunds-steps__text"><strong>{{ translations.FillForm }}</strong> {{ translations.ReturnOnline }}</p>
                </li>
                <li class="refunds-steps__item">
                    <span class="refunds-steps__number">3</span>
                    <p class="refunds-steps__text"><strong>{{ translations.SendParcel }}</strong> - {{ translations.SendParcelToOurAddress }}</p>
                </li>
            </ol>
            <p class="refunds-info__hint">{{ translations.FastSimpleSecure }}</p>
        </div>
        <div class="refunds-cta">
            <div class="refunds-cta__header">
                <h3 class="refunds-cta__title">{{ translations.ReadyForReturn }}</h3>
                <p class="refunds-cta__description">{{ translations.ReadyForReturnInfo }}</p>
            </div>
            {% if usr.Authenticated -%}
            <a class="primary-action-button refunds-cta__button" href="{{ config.DefinedPages.CustomerProfile.Url }}?tab=orders" rel="nofollow" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </a>
            {% else -%}
            <button class="primary-action-button refunds-cta__button start-refund-js" type="button" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </button>
            {% endif -%}
        </div>
    </section>
    {% unless usr.Authenticated -%}
    <section class="refund-form-section refund-form-view-js hidden-js">
        <div class="refund-form">
            <div class="refund-form__header">
                <h2 class="refund-form__title">{{ translations.ProductReturn }}</h2>
                <p class="refund-form__description">{{ translations.ProductReturnFormInfo }}</p>
            </div>
            <form class="refund-form__body refund-form-js" novalidate="" data-error="{{ translations.RefundLookupError }}">
                <div class="form__input-wrapper">
                    <label class="form__input-info input-info-js" for="refundOrderNumber">{{ translations.NumberOfOrder }}</label>
                    <input id="refundOrderNumber" class="form__input-value input-value-js" maxlength="50" name="orderNumber" required="" type="text" />
                    <div class="form__invalid-input validation-info-js validation-required-js hidden-js">{{ translations.FieldRequired }}</div>
                </div>
                <div class="form__input-wrapper">
                    <label class="form__input-info input-info-js" for="refundEmail" data-type="email">{{ translations.EmailAddress }}</label>
                    <input id="refundEmail" class="form__input-value input-value-js" autocomplete="email" maxlength="192" name="email" required="" type="email" />
                    <div class="form__invalid-input validation-info-js validation-required-js hidden-js">{{ translations.FieldRequired }}</div>
                    <div class="form__invalid-input validation-info-js email-valid-js hidden-js">{{ translations.FillProperEmail }}</div>
                </div>
                <button class="primary-action-button refund-form__submit refund-form-submit-js" type="button">
                    {{ translations.FindOrder }}
                </button>
                <p class="refund-form__login-info">{{ translations.HaveAccount }} <a class="refund-form__login-link show-login-popup-js" tabindex="0" role="button" rel="nofollow">{{ translations.LogIn }},</a> {{ translations.LoginToSeeOrdersAndReturn }}</p>
            </form>
        </div>
    </section>
    {% endunless -%}
</div>

Plik js/layout1.js – kod obsługi formularza zwrotu

Na końcu pliku js/layout1.js dodaj poniższy kod odpowiedzialny za walidację i wysłanie formularza wyszukiwania zamówienia (dla niezalogowanego klienta):
$(document).ready(function() {
    refunds.init();
})

const refunds = {
    init: function() {
        this.events();
    },

    findRefundOrder: function(orderNumber, email) {
        return $.post('', {
            __action: 'Order/QuickReturnLookup',
            orderId: orderNumber,
            email: email,
            __csrf: __CSRF
        });
    },

    showForm: function() {
        $('.refunds-initial-view-js').addClass('hidden-js');
        $('.refund-form-view-js').removeClass('hidden-js');
        $('.refund-form-js input[name="orderNumber"]').trigger('focus');
    },

    clearFieldError: function(input) {
        const $input = $(input);
        $input.removeClass('validation-error-js');
        $input.closest('.form__input-wrapper').find('.form__invalid-input').addClass('hidden-js');
    },

    submitForm: async function(button) {
        const $submit = $(button);
        const $form = $submit.closest('.refund-form-js');
        const $orderInput = $form.find('input[name="orderNumber"]');
        const $emailInput = $form.find('input[name="email"]');
        const orderValue = $orderInput.val().trim();
        const emailValue = $emailInput.val().trim();
        const emailRegex = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w{2,}$/;
        let hasError = false;

        $form.find('.form__invalid-input').addClass('hidden-js');
        $form.find('.form__input-value').removeClass('validation-error-js');

        if (orderValue.length === 0) {
            $orderInput.addClass('validation-error-js');
            $orderInput.closest('.form__input-wrapper').find('.validation-required-js').removeClass('hidden-js');
            hasError = true;
        }

        if (emailValue.length === 0) {
            $emailInput.addClass('validation-error-js');
            $emailInput.closest('.form__input-wrapper').find('.validation-required-js').removeClass('hidden-js');
            hasError = true;
        } else if (!emailRegex.test(emailValue)) {
            $emailInput.addClass('validation-error-js');
            $emailInput.closest('.form__input-wrapper').find('.email-valid-js').removeClass('hidden-js');
            hasError = true;
        }

        if (hasError) {
            return;
        }

        $submit.prop('disabled', true);

        try {
            const result = await refunds.findRefundOrder(orderValue, emailValue);
            const action = result.action;
            if (action.Redirect302) {
                globalThis.location.href = action.Redirect302;
                return;
            }
            app.temporaryPopupMessage(undefined, action.Message, action.Type);
        } catch (error) {
            console.error('Refund order lookup failed.', error);
            app.temporaryPopupMessage(undefined, $form.data('error'), 'err');
        } finally {
            $submit.prop('disabled', false);
        }
    },

    events: function() {
        $('body').on('click', '.start-refund-js', function() {
            refunds.showForm();
        });

        $('body').on('input', '.refund-form-js .form__input-value', function() {
            refunds.clearFieldError(this);
        });

        $('body').on('click', '.refund-form-submit-js', function(e) {
            e.preventDefault();
            refunds.submitForm(this);
        });

        $('body').on('keydown', '.refund-form-js input', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
                $(this).closest('.refund-form-js').find('.refund-form-submit-js').trigger('click');
            }
        });
    }
};

Pliki SCSS strony Szybkie zwroty

W folderze scss/static-elements utwórz nowy katalog refunds i umieść w nim trzy pliki: refunds-g.scss, refunds-m.scss i refunds-t.scss. scss/static-elements/refunds/refunds-g.scss:
.refunds-page-title {
    margin: 0 0 24px;
    font-size: 24px;
    font-weight: 500;
    line-height: 32px;
    color: $primaryColorFont;
}

.refunds-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 32px;
    margin-bottom: 32px;
    color: $primaryColorFont;
}

.refunds-info {
    align-self: flex-start;
    display: flex;
    flex-direction: column;
    gap: 16px;
    width: 100%;
    max-width: 800px;

    &__title {
        margin: 0;
        font-size: 20px;
        font-weight: 600;
        line-height: 28px;
        color: $primaryColorFont;
    }

    &__intro {
        margin: 0;
        font-size: 16px;
        font-weight: 500;
        line-height: 24px;
        color: $primaryColorFont;
    }

    &__hint {
        margin: 4px 0 0;
        font-size: 12px;
        font-weight: 400;
        line-height: 20px;
        color: $breadcrumbs;
    }
}

.refunds-steps {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;

    &__item {
        display: flex;
        align-items: center;
        gap: 12px;
    }

    &__number {
        flex-shrink: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        border-radius: 50%;
        background-color: #f3f3f3;
        color: $primaryColor;
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
    }

    &__text {
        margin: 0;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        color: $primaryColorFont;

        strong {
            font-weight: 600;
        }
    }
}

.refunds-cta {
    box-sizing: border-box;
    width: 100%;
    max-width: 578px;
    padding: 40px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 24px;
    background-color: $bgColor;
    border: 1px solid $lightBorderColor;
    border-radius: 8px;

    &__header {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 12px;
        width: 100%;
    }

    &__title {
        margin: 0;
        font-size: 24px;
        font-weight: 600;
        line-height: 32px;
        text-align: center;
        color: $primaryColorFont;
    }

    &__description {
        margin: 0;
        font-size: 16px;
        font-weight: 400;
        line-height: 24px;
        text-align: center;
        color: $breadcrumbs;
    }

    &__button {
        width: 100%;
        text-decoration: none;
    }
}

.refund-form-section {
    display: flex;
    justify-content: center;
    width: 100%;
    margin-bottom: 32px;
}

.refund-form {
    box-sizing: border-box;
    width: 100%;
    max-width: 578px;
    padding: 40px;
    background-color: $bgColor;
    border: 1px solid $lightBorderColor;
    border-radius: 8px;

    &__header {
        display: flex;
        flex-direction: column;
        gap: 12px;
        margin-bottom: 32px;
    }

    &__title {
        margin: 0;
        font-size: 24px;
        font-weight: 600;
        line-height: 32px;
        color: $primaryColorFont;
    }

    &__description {
        margin: 0;
        font-size: 14px;
        font-weight: 400;
        line-height: 20px;
        color: $breadcrumbs;
    }

    &__body {
        display: flex;
        flex-direction: column;
    }

    .form__input-wrapper {
        .form__input-value {
            &.validation-error-js {
                border-color: $dangerColor;
                color: $dangerColor;
            }
        }

        .form__invalid-input {
            position: static;
            display: block;
            margin: 4px 0 0;
            padding-left: 16px;
            text-align: left;
            color: $dangerColor;
            font-size: 12px;
            font-weight: 400;
            line-height: 16px;
        }
    }

    &__submit {
        width: 100%;
        margin-top: 4px;
    }

    &__login-info {
        margin: 16px 0 0;
        text-align: center;
        font-size: 14px;
        font-weight: 400;
        line-height: 20px;
        color: $primaryColorFont;
    }

    &__login-link {
        color: $primaryColor;
        font-weight: 600;
        cursor: pointer;
        text-decoration: none;

        &:hover {
            text-decoration: underline;
        }
    }
}
scss/static-elements/refunds/refunds-m.scss:
@media screen and (max-width: 767px) {
    .refunds-page-title {
        font-size: 20px;
        line-height: 28px;
        margin-bottom: 16px;
    }

    .refunds-container {
        gap: 24px;
        margin-bottom: 24px;
    }

    .refunds-info {
        max-width: 100%;
        gap: 12px;

        &__title {
            font-size: 18px;
            line-height: 24px;
        }

        &__intro {
            font-size: 14px;
            line-height: 22px;
        }
    }

    .refunds-steps {
        &__item {
            align-items: flex-start;
            gap: 10px;
        }

        &__number {
            width: 28px;
            height: 28px;
            font-size: 13px;
        }

        &__text {
            font-size: 13px;
            line-height: 20px;
            padding-top: 3px;
        }
    }

    .refunds-cta {
        padding: 24px;

        &__title {
            font-size: 20px;
            line-height: 28px;
        }

        &__description {
            font-size: 14px;
            line-height: 22px;
        }
    }

    .refund-form {
        padding: 24px;

        &__header {
            margin-bottom: 24px;
        }

        &__title {
            font-size: 20px;
            line-height: 28px;
        }

        &__description {
            font-size: 13px;
            line-height: 18px;
        }

        &__login-info {
            font-size: 13px;
        }
    }
}
scss/static-elements/refunds/refunds-t.scss:
@media screen and (min-width: 768px) and (max-width: 1439px) {
    .refunds-info {
        max-width: 100%;
    }
}

3. Modyfikacje istniejących plików HTML

partials/cart/thx.html

W pliku partials/cart/thx.html znajdź fragment generujący etykietę zgody w sekcji zgód marketingowych:
<label class="cart__tos-label tos-js" tabindex="0" role="checkbox" for="{{ consent.FieldValue }}" aria-checked="false"></label>
Usuń z niego atrybut for="{{ consent.FieldValue }}". Po zmianie linia powinna wyglądać tak:
<label class="cart__tos-label tos-js" tabindex="0" role="checkbox" aria-checked="false"></label>

partials/common/login.html

1. W pliku partials/common/login.html w kontenerze opakowującym formularz dodaj klasę login-container-popup. Zamień linię:
<div class="{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id -%} login-popup-js{% else -%} login-container {% endif -%}">
na:
<div class="{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id -%} login-popup-js login-container-popup{% else -%} login-container {% endif -%}">
2. W warunku otaczającym przycisk zamykający popup logowania usuń warunek and settings.signIn == "popup". Zamień linię:
{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id and settings.signIn == "popup" -%}
na:
{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id -%}

partials/product/amount-stepper.html

W pliku partials/product/amount-stepper.html znajdź blok ustawiający zmienne dla typów complaint i return:
{% if type == 'complaint' or type == 'return' -%}
{% assign reloadClass = '' -%}
{% assign complaintOrReturn = true -%}
{% endif -%}
i dodaj w jego wnętrzu nową linię ustawiającą maksymalną ilość produktu:
{% if type == 'complaint' or type == 'return' -%}
{% assign reloadClass = '' -%}
{% assign complaintOrReturn = true -%}
{% assign max = product.Quantity | Normalize -%}
{% endif -%}

partials/order/products-partials/product-table-header.html

Na samym początku pliku partials/order/products-partials/product-table-header.html dodaj blok przypisujący flagę complaintsOrReturnsEnabled:
{% if config.Complaints.ComplaintsEnabled or config.Complaints.ReturnsEnabled -%}
{% assign complaintsOrReturnsEnabled = true -%}
{% endif -%}

partials/product/products-table.html

Przyciski reklamacji i zwrotu są wyświetlane bezpośrednio w tabeli, zamiast w rozwijanym menu. W pliku partials/product/products-table.html znajdź komórkę z opcjami:
{% if order.Status == 3 and complaintsOrReturnsEnabled and product.CanComplain == true -%}
<button class="pure-button open-dropdown-js" aria-label="{{translations.Options}}">
    <!-- TODO: ikona SVG przycisku opcji – bez zmian, jak w istniejącym pliku -->
</button>
<div class="dropdown dropdown-js hidden-js" style="bottom: auto !important;">
    {% if config.Complaints.ComplaintsEnabled == true and product.CanComplain == true -%}
    <button class="pure-button open-complaint-form-js" data-type="complaint" data-product="{{ product.Url }}">
        {{ translations.Complain }}
    </button>
    {% endif -%}
    {% if config.Complaints.ReturnsEnabled == true and product.CanReturn == true and product.IsSetElement == false -%}
    <button class="pure-button open-complaint-form-js" data-type="return" data-product="{{ product.Url }}">
        {{ translations.Return }}
    </button>
    {% endif -%}
</div>
{% endif -%}
i zastąp ją następującym fragmentem:
{% if order.Status == 3 and complaintsOrReturnsEnabled -%}
{% if config.Complaints.ComplaintsEnabled == true and product.CanComplain == true -%}
<button class="pure-button open-complaint-form-js complaint-action-btn" data-type="complaint" data-product="{{ product.Url }}">
    {{ translations.Complain }}
</button>
{% endif -%}
{% if config.Complaints.ReturnsEnabled == true and product.CanReturn == true and product.IsSetElement == false -%}
<button class="pure-button open-complaint-form-js complaint-action-btn" data-type="return" data-product="{{ product.Url }}">
    {{ translations.Return }}
</button>
{% endif -%}
{% endif -%}
Następnie w tym samym pliku znajdź zewnętrzny warunek otaczający kontenery formularzy reklamacji i zwrotu i poluzuj go (usuń warunek product.CanComplain == true). Zamień:
{% if order.Status == 3 and complaintsOrReturnsEnabled and product.CanComplain == true -%}
na:
{% if order.Status == 3 and complaintsOrReturnsEnabled -%}

partials/customer-profile/orders/order-details.html

W pliku partials/customer-profile/orders/order-details.html wykonaj poniższe zmiany. a) Bloki Opcje (zawierające klasę options submenu z przyciskami akcji zamówienia) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}, aby ukryć je dla niezalogowanych klientów dokonujących szybkiego zwrotu. Wstaw {% unless order.Restricted -%} bezpośrednio przed otwierającym <div class="options submenu">, a {% endunless -%} po jego zamykającym </div>:
{% unless order.Restricted -%}
<div class="options submenu">
    ...
</div>
{% endunless -%}
b) W kontenerze messages-container-js na początku (przed istniejącymi komunikatami typu OrderEditable) dodaj baner informujący o ukrytych danych zamówienia oraz, na końcu kontenera, baner informujący o terminie zwrotu:
{% if order.Restricted -%}
<div class="return-info-banner">
    <!-- TODO: ikona SVG informacyjna (z klasą icon) -->
    {{ translations.RestrictedOrderViewInfo }}
</div>
{% endif -%}
{% if order.Status == 3 and config.Complaints.ReturnsEnabled -%}
<div class="return-info-banner">
    <!-- TODO: ikona SVG informacyjna (z klasą icon) -->
    {{ translations.OrderReturnDeadlineInfo | Format: config.Complaints.DaysToReturn }}
</div>
{% endif -%}
c) We wszystkich miejscach wyświetlających numer telefonu klienta zamień warunki sprawdzające jedynie pusty ciąg na warunki sprawdzające również wartość null. Zamień każde wystąpienie:
{% if order.Customer.DeliveryAddress.PhoneNo != '' -%}
na:
{% if order.Customer.DeliveryAddress.PhoneNo != null and order.Customer.DeliveryAddress.PhoneNo != '' -%}
d) Analogicznie zaktualizuj warunek wyświetlania NIP-u/TIN-u w sekcji danych do faktury. Zamień:
{% elseif order.Customer.TIN != '' -%}
na:
{% elseif order.Customer.TIN != null and order.Customer.TIN != '' -%}
e) W sekcji adresu dostawy zamień otwierający warunek alternatywny {% else -%} (bezpośrednio przed kontenerem z translations.DelivAddress) na bardziej restrykcyjny:
{% elseif order.Customer.DeliveryAddress != null -%}
f) Sekcję wybranego dokumentu (ChoosenDocument) opakuj warunkiem ukrywającym ją dla zamówień typu restricted. Wstaw {% unless order.Restricted -%} przed kontenerem order-details-item z tytułem translations.ChoosenDocument oraz {% endunless -%} za jego zamykającym </div>. g) W sekcji dokumentów zamówienia dodaj do warunku sprawdzenie order.Restricted == false. Zamień:
{% if orderDocumentsSize > 0 -%}
na:
{% if orderDocumentsSize > 0 and order.Restricted == false -%}
h) W sekcji załączników zamówienia dodaj analogiczne sprawdzenie. Zamień:
{% if config.Orders.AttachmentsEnabled and orderAttachmentsSize > 0 -%}
na:
{% if config.Orders.AttachmentsEnabled and orderAttachmentsSize > 0 and order.Restricted == false -%}
i) W sekcji zamówień powiązanych zamień:
{% if order.RelatedOrders[0] -%}
na:
{% if order.RelatedOrders[0] and order.Restricted == false -%}

partials/customer-profile/complaints/complaint-form.html

W pliku partials/customer-profile/complaints/complaint-form.html wprowadź poniższe zmiany. a) W kontenerze amount-stepper-container (wewnątrz warunku {% if type != 'set-return' -%}) na samym początku dodaj nową etykietę:
<span class="amount-stepper-container__label">{{ translations.Quantity }}:</span>
b) Pod sekcją z komentarzem reklamacji/zwrotu (po zamykającym {% endif -%} z sekcji complaint-message-textarea) wewnątrz warunku {% if type != 'set-return' -%} dodaj sekcję wyboru sposobu zwrotu środków:
<div class="refund-method-wrapper">
    <div class="refund-method-wrapper__title">{{ translations.Com_RefundMethod }} <span class="required">*</span></div>
    <label class="refund-method-option">
        <input class="refund-method-option__radio refund-method-radio-js" checked="checked" name="refundMethod" type="radio" value="asPaid" />
        <span class="refund-method-option__box"></span>
        <span class="refund-method-option__label">
            {{ translations.Com_RefundAsPaid }} {% if order.Payment.Name and order.Payment.Name != '' -%} ({{ order.Payment.Name }}){% endif -%}
        </span>
    </label>
    <label class="refund-method-option">
        <input class="refund-method-option__radio refund-method-radio-js" name="refundMethod" type="radio" value="bankAccount" />
        <span class="refund-method-option__box"></span>
        <span class="refund-method-option__label">{{ translations.Com_RefundToBankAccount }}</span>
    </label>
</div>
<div class="form__input-wrapper account-number-wrapper-js hidden-js">
    <label class="form__input-info input-info-js" for="accountNumber">{{ translations.Com_BankAccountNumber }} <span class="required">*</span></label>
    <input id="accountNumber" class="form__input-value input-value-js" disabled="disabled" maxlength="50" name="accountNumber" type="text" />
    <div class="form__invalid-input validation-info-js validation-required-js hidden-js">{{ translations.FieldRequired }}</div>
</div>
c) W sekcji załączników plików zamień prosty licznik file-{{forloop.index}} na prefiks zawierający identyfikator zamówienia, numer produktu i typ formularza. Tuż przed pętlą {% for i in (1..config.Complaints.AttachmentsMaxCount) -%} dodaj nową linię:
{% capture filePrefix -%}file-{{ order.Id }}-{{ product.No }}-{{ type }}{% endcapture -%}
Następnie wewnątrz pętli zamień:
<label class="file" for="file-{{forloop.index}}">
<input id="file-{{forloop.index}}" class="add-attachement-in-complaint-js hidden-js" type="file" /></label>
na:
<label class="file" for="{{ filePrefix }}-{{ forloop.index }}">
<input id="{{ filePrefix }}-{{ forloop.index }}" class="add-attachement-in-complaint-js hidden-js" type="file" /></label>
d) Komunikat sukcesu wyświetlany po wysłaniu formularza ma być inny dla reklamacji, a inny dla zwrotu. Znajdź kontener <div class="success-message-js hidden-js"> i jego dotychczasową zawartość:
<div class="success-message-js hidden-js">
    {{ successInfo }}
</div>
zastąp:
<div class="success-message-js hidden-js">
    {% if complaint -%}
    {{ successInfo }}
    {% else -%}
    <div class="data-form__header return-success__header">
        <button class="close-button hide-container-js closing-modal-js" aria-label="{{ translations.Close }}">
            <!-- TODO: ikona SVG zamknięcia – jak w pozostałych popupach szablonu -->
        </button>
    </div>
    <div class="return-success__icon">
        <!-- TODO: ikona SVG potwierdzenia (zielony "check") -->
    </div>
    <div class="return-success__title">{{ successTitle }}</div>
    <div class="return-success__subtitle">{{ successInfo }}</div>
    {% if order.Customer.Email and order.Customer.Email != '' -%}
    <div class="return-success__email-box">
        <!-- TODO: ikona SVG informacyjna -->
        <div>
            <div>{{ translations.Com_ConfirmationSentTo }}</div>
            <strong>{{ order.Customer.Email }}</strong>
        </div>
    </div>
    {% endif -%}
    <div class="return-success__steps-title">{{ translations.Com_NextSteps }}</div>
    <ol class="return-success__steps">
        <li>{{ translations.Com_PackProducts }}</li>
        <li>{{ translations.Com_SendPackageTo }}
            {% if config.Shop.Address.Street != '' -%} {{ config.Shop.Address.Street }}{% endif -%}
            {% if config.Shop.Address.StreetNo != '' -%} {{ config.Shop.Address.StreetNo }}{% endif -%}
            {% if config.Shop.Address.UnitNo != '' -%}/{{ config.Shop.Address.UnitNo }}{% endif -%}
            {% if config.Shop.Address.ZipCode != '' or config.Shop.Address.City != '' -%}, {{ config.Shop.Address.ZipCode }} {{ config.Shop.Address.City }}{% endif -%}</li>
        <li>{{ translations.Com_RefundAfterReceive }}</li>
    </ol>
    <div class="buttons-container short">
        <button class="primary-action-button hide-container-js closing-modal-js">
            {{ translations.Close }}
        </button>
    </div>
    {% endif -%}
</div>

4. Modyfikacje pliku js/layout-customerprofile0.js

Poniższe zmiany dotyczą pliku js/layout-customerprofile0.js (jego nieskompresowanej wersji, którą po edycji należy ponownie zminifikować do layout-customerprofile0.min.js). a) W funkcji openComplaintForm wewnątrz warunku if (hiddenContainer) – tuż po linii hiddenContainer.querySelector('.success-message-js').classList.add('hidden-js'); – dodaj kod ujawniający nagłówek formularza oraz resetujący wybór sposobu zwrotu do opcji domyślnej:
const mainHeader = hiddenContainer.querySelector(':scope > .data-form__header');
if (mainHeader) {
    mainHeader.classList.remove('hidden-js');
}
hiddenContainer.classList.remove('hidden-js');

const asPaidRadio = hiddenContainer.querySelector('.refund-method-radio-js[value="asPaid"]');
if (asPaidRadio) {
    asPaidRadio.checked = true;
    $(asPaidRadio).trigger('change');
}
(Linia hiddenContainer.classList.remove('hidden-js'); już istnieje – pokazana jest dla kontekstu. Nowe są bloki const mainHeader i const asPaidRadio.) b) W funkcji sendComplaint, w bloku przygotowującym dane formularza – po pętli for (const item of dataFromHTML) dokładającej pola do fd – dodaj fragment dołączający parametr qrHash z adresu URL przy wysyłaniu zwrotu:
if (form.find('input[name="__action"]').val() === 'Order/ReturnAdd') {
    const qrHash = new URLSearchParams(globalThis.location.search).get('qrHash');
    if (qrHash) {
        fd.append('qrHash', qrHash);
    }
}
c) W tej samej funkcji sendComplaint, w callbacku success po pomyślnym wysłaniu, zamień fragment:
form.parents('.add-complaint-form-js').find('.success-message-js').removeClass('hidden-js');
na:
const container = form.parents('.add-complaint-form-js');
container.find('.success-message-js').removeClass('hidden-js');
container.children('.data-form__header').addClass('hidden-js');
d) Na samym końcu pliku js/layout-customerprofile0.js dodaj nowy handler obsługujący przełączanie sposobu zwrotu środków. Pokazuje on / ukrywa pole na numer konta bankowego:
$('body').on('change', '.refund-method-radio-js', function(e) {
    const radio = $(e.currentTarget);
    const form = radio.closest('.form-js');
    const wrapper = form.find('.account-number-wrapper-js');
    const input = wrapper.find('input[name="accountNumber"]');
    if (radio.val() === 'bankAccount' && radio.prop('checked')) {
        wrapper.removeClass('hidden-js');
        input.prop('disabled', false);
        input.prop('required', true);
    } else {
        wrapper.addClass('hidden-js');
        wrapper.find('.validation-required-js').addClass('hidden-js');
        wrapper.find('.form__input-info').removeClass('validation-error');
        input.removeClass('validation-error-js');
        input.prop('required', false);
        input.prop('disabled', true);
        input.val('');
    }
});

5. Modyfikacje plików SCSS profilu klienta

Poniższe style należy dodać do plików scss/static-elements/customer-profile/customer-profile-g.scss (wersja desktop) oraz scss/static-elements/customer-profile/customer-profile-m.scss (wersja mobile). Po zmianach pamiętaj o kompilacji – nie edytuj ręcznie wynikowych plików CSS.

Plik scss/static-elements/customer-profile/customer-profile-g.scss

a) Dla "przyklejonej" kolumny z akcjami reklamacji/zwrotu w tabeli produktów dodaj reguły wewnątrz selektora otaczającego tabelę zamówienia (tam, gdzie znajdują się style dla thead tr th):
thead tr th.open-complaint-form-container-js {
    position: sticky;
    right: 0;
    background: transparent;
    z-index: 5;

    &::before {
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        right: 0;
        width: 200px;
        background: linear-gradient(to right, rgba(255, 255, 255, 0), #fff 50%);
        pointer-events: none;
    }
}

td.complaint-actions-inline {
    white-space: nowrap;
    text-align: right;
    padding-left: 16px;
    padding-right: 8px;
    position: sticky;
    right: 0;
    background: #fff;
    z-index: 2;

    &::before {
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        left: -32px;
        width: 32px;
        background: linear-gradient(to right, rgba(255, 255, 255, 0), #fff 100%);
        pointer-events: none;
    }

    .pure-button.complaint-action-btn {
        display: inline-flex;
        background: transparent;
        border: 0;
        border-radius: 4px;
        color: $primaryColor;
        padding: 4px 8px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
        transition: background-color 150ms ease;

        &:hover,
        &:focus-visible {
            color: $primaryColor;
            background: rgba(0, 0, 0, 0.06);
        }

        & + .complaint-action-btn {
            margin-left: 8px;
        }
    }
}
b) Style hovera dla wiersza tabeli z akcjami reklamacji/zwrotu (umieść w głównym zakresie pliku):
.row {
    &:hover,
    &:focus-within,
    &.hovered-js {
        td.complaint-actions-inline {
            background: #F1DDDE;

            &::before {
                background: linear-gradient(to right, rgba(241, 221, 222, 0), #F1DDDE 100%);
            }
        }
    }

    &.set td.complaint-actions-inline {
        background: #ececec;

        &::before {
            background: linear-gradient(to right, rgba(236, 236, 236, 0), #ececec 100%);
        }
    }
}
c) Style banera informacyjnego (termin zwrotu / ukryte dane zamówienia):
.return-info-banner {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    margin: 0 0 24px 0;
    background: #E8F1F8;
    border: 1px solid #C7DCEE;
    border-radius: 5px;
    font-size: 14px;
    line-height: 20px;
    color: #2C3E50;

    .icon {
        flex-shrink: 0;
        fill: #4A90BC;
    }

    strong {
        font-weight: 600;
    }
}
d) Style sekcji wyboru sposobu zwrotu środków oraz radio-buttonów:
.refund-method-wrapper {
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin-bottom: 24px;

    &__title {
        color: $primaryColorFont;
        font-size: 14px;
        font-weight: 500;
        line-height: 20px;
    }
}

.refund-method-option {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;

    &__radio {
        display: none;

        &:checked ~ .refund-method-option__box {
            border-color: $primaryColor;

            &::after {
                content: "";
                display: block;
                width: 8px;
                height: 8px;
                border-radius: 50%;
                background: $primaryColor;
            }
        }
    }

    &__box {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 16px;
        height: 16px;
        border: 1px solid #767676;
        border-radius: 50%;
        flex-shrink: 0;
    }

    &__label {
        font-size: 14px;
        line-height: 20px;
    }
}
e) Style ekranu sukcesu po wysłaniu zwrotu (m.in. ikona, tytuł, lista kolejnych kroków):
.add-complaint-form-js .characters-length {
    margin-top: 0;
    bottom: 23px;
}

.add-complaint-form-js {
    .quantity__plus.disabled-js,
    .quantity__minus.disabled-js {
        opacity: 0.4;
    }
}

.add-complaint-form-js .data-form__header.return-success__header {
    margin-bottom: 8px;
}

.return-success {
    &__icon {
        display: flex;
        justify-content: center;
        margin-bottom: 16px;

        svg {
            fill: #2E7D32;
        }
    }

    &__title {
        text-align: center;
        font-size: 20px;
        font-weight: 600;
        line-height: 28px;
        color: $primaryColorFont;
        margin-bottom: 8px;
    }

    &__subtitle {
        text-align: center;
        font-size: 14px;
        line-height: 20px;
        color: $labelsColor;
        padding-bottom: 24px;
        border-bottom: 1px solid #E7E7E7;
        margin-bottom: 24px;
    }

    &__email-box {
        display: flex;
        align-items: flex-start;
        gap: 12px;
        padding: 12px 16px;
        background: #F0F6FC;
        border: 1px solid #D6E4F0;
        border-radius: 6px;
        margin-bottom: 24px;
        font-size: 14px;
        line-height: 20px;
        color: $primaryColorFont;

        svg {
            fill: #1976D2;
            flex-shrink: 0;
            margin-top: 2px;
        }
    }

    &__steps-title {
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
        color: $primaryColorFont;
        margin-bottom: 12px;
    }

    &__steps {
        margin: 0 0 24px;
        padding-left: 20px;
        font-size: 14px;
        line-height: 20px;
        color: $primaryColorFont;

        li {
            margin-bottom: 8px;

            &:last-child {
                margin-bottom: 0;
            }
        }
    }
}
f) Uzupełnij wnętrze selektora .file-attachements-wrapper o style dla kontenera pojedynczego załącznika:
.file-container {
    .file {
        align-items: center;
        font-weight: 400;
        color: $primaryColorFont;
        justify-content: flex-start;
    }

    .icon-js svg {
        fill: $primaryColorFont;
    }

    .clear-file-input-js {
        flex-shrink: 0;
        display: flex;
        align-items: center;

        svg {
            width: 14px;
            height: 14px;
            fill: $primaryColor;
        }
    }
}

Plik scss/static-elements/customer-profile/customer-profile-m.scss

Na końcu pliku customer-profile-m.scss dodaj reguły dopasowujące przyciski reklamacji/zwrotu do widoku mobilnego (układają się one wówczas jeden pod drugim):
.eshop__table-container {
    thead tr th.open-complaint-form-container-js::before {
        width: 100px;
    }

    td.complaint-actions-inline {
        .pure-button.complaint-action-btn {
            display: block;
            width: max-content;
            margin-left: auto;
            text-align: right;

            & + .complaint-action-btn {
                margin-left: auto;
                margin-top: 4px;
            }
        }
    }
}
Po wprowadzeniu wszystkich powyższych zmian w szablonie Rubin pamiętaj o kompilacji oraz minifikacji plików js i scss, zgodnie z artykułem dostępnym pod linkiem https://pomoc.comarchesklep.pl/artykul/kompilacja-i-minifikacja-plikow/.

Szablon Szafir

1. Tłumaczenia

W panelu administracyjnym sklepu dodaj nowe klucze tłumaczeń wymagane przez funkcjonalność szybkich zwrotów w szablonie Szafir. OrderReturnDeadlineInfo - PL: Zamówienie można zwrócić w ciągu {0} dni od daty dostawy. - EN: You can return the order within {0} days from the delivery date. - DE: Sie können die Bestellung innerhalb von {0} Tagen ab Lieferdatum zurückgeben. - FR: Vous pouvez retourner la commande dans les {0} jours suivant la date de livraison. RestrictedOrderViewInfo - PL: Wybrane dane zamówienia zostały ukryte ze względów bezpieczeństwa. Możesz zwrócić produkty bez logowania. - EN: Some order details are hidden for security reasons. You can return products without signing in. - DE: Einige Bestelldetails wurden aus Sicherheitsgründen ausgeblendet. Sie können Produkte ohne Anmeldung zurücksenden. - FR: Certaines informations de la commande ont été masquées pour des raisons de sécurité. Vous pouvez retourner des produits sans vous connecter. RefundMethod - PL: Sposób zwrotu środków - EN: Refund method - DE: Rückerstattungsmethode - FR: Méthode de remboursement RefundAsPaid - PL: Tak jak zapłacono - EN: As paid - DE: Wie bezahlt - FR: Comme payé RefundToBankAccount - PL: Na konto bankowe - EN: To bank account - DE: Auf Bankkonto - FR: Sur le compte bancaire BankAccountNumber - PL: Nr konta bankowego - EN: Bank account number - DE: Bankkontonummer - FR: Numéro de compte bancaire ReturnConfirmationTitle - PL: Gotowe! Przyjęliśmy Twoje zgłoszenie - EN: Done! We have received your request - DE: Fertig! Wir haben Ihre Anfrage erhalten - FR: Terminé! Nous avons reçu votre demande ReturnConfirmationInfo - PL: Przygotuj paczkę i odeślij ją do nas – wszystkie szczegóły znajdziesz poniżej. - EN: Prepare the package and send it back to us – all details can be found below. - DE: Bereiten Sie das Paket vor und senden Sie es an uns zurück – alle Details finden Sie unten. - FR: Préparez le colis et renvoyez-le nous – tous les détails se trouvent ci-dessous. ReturnConfirmationEmailSent - PL: Potwierdzenie zwrotu zostało wysłane na adres: - EN: Return confirmation has been sent to: - DE: Die Rücksendebestätigung wurde gesendet an: - FR: La confirmation de retour a été envoyée à: NextSteps - PL: Następne kroki - EN: Next steps - DE: Nächste Schritte - FR: Prochaines étapes ReturnStep1 - PL: Bezpiecznie zapakuj swoje produkty - EN: Safely pack your products - DE: Verpacken Sie Ihre Produkte sicher - FR: Emballez vos produits en toute sécurité ReturnStep2Address - PL: Wyślij paczkę na adres - EN: Send the package to - DE: Senden Sie das Paket an - FR: Envoyez le colis à ReturnStep3 - PL: Pieniądze zwrócimy niezwłocznie po otrzymaniu i sprawdzeniu Twojej paczki. - EN: We will refund the money promptly after receiving and checking your package. - DE: Wir erstatten das Geld umgehend nach Erhalt und Überprüfung Ihres Pakets. - FR: Nous rembourserons l'argent rapidement après réception et vérification de votre colis. ReturnInThreeSteps - PL: Zwróć towar w 3 krokach - EN: Return the product in 3 steps - DE: Geben Sie die Ware in 3 Schritten zurück - FR: Retournez la marchandise en 3 étapes ReturnWithoutReasonInfo - PL: Przysługuje Ci możliwość zwrotu bez podania przyczyny. - EN: You have the right to return the product without giving a reason. - DE: Sie haben das Recht, die Ware ohne Angabe von Gründen zurückzugeben. - FR: Vous avez le droit de retourner la marchandise sans donner de motif. OrEnterOrderNumber - PL: lub podaj numer zamówienia - EN: or enter the order number - DE: oder geben Sie die Bestellnummer ein - FR: ou saisissez le numéro de commande FillForm - PL: Wypełnij formularz - EN: Fill out the form - DE: Füllen Sie das Formular aus - FR: Remplissez le formulaire ReturnOnline - PL: zwrotu online - EN: online return - DE: Online-Rückgabe - FR: retour en ligne SendParcel - PL: Wyślij paczkę - EN: Send the parcel - DE: Paket senden - FR: Envoyer le colis SendParcelToOurAddress - PL: nadaj przesyłkę na nasz adres - EN: send the parcel to our address - DE: senden Sie das Paket an unsere Adresse - FR: envoyez le colis à notre adresse FastSimpleSecure - PL: Szybko, prosto i bezpiecznie. - EN: Fast, simple and secure. - DE: Schnell, einfach und sicher. - FR: Rapide, simple et sécurisé. ReadyForReturn - PL: Gotowy do zwrotu? - EN: Ready for return? - DE: Bereit zur Rückgabe? - FR: Prêt pour le retour ? ReadyForReturnInfo - PL: Kliknij poniżej, aby rozpocząć proces zwrotu. Przeprowadzimy Cię przez wszystkie kroki. - EN: Click below to start the return process. We will guide you through all the steps. - DE: Klicken Sie unten, um den Rückgabeprozess zu starten. Wir führen Sie durch alle Schritte. - FR: Cliquez ci-dessous pour lancer le processus de retour. Nous vous guiderons à travers toutes les étapes. StartReturn - PL: Rozpocznij zwrot - EN: Start return - DE: Rückgabe starten - FR: Commencer le retour ProductReturn - PL: Zwrot produktu - EN: Product return - DE: Produktrückgabe - FR: Retour du produit ProductReturnFormInfo - PL: Wprowadź dane zamówienia, aby zlokalizować zakup i rozpocząć proces zwrotu. Numer zamówienia znajdziesz w e-mailu z potwierdzeniem. - EN: Enter the order details to locate the purchase and start the return process. You will find the order number in the confirmation e-mail. - DE: Geben Sie die Bestelldaten ein, um den Kauf zu lokalisieren und den Rückgabeprozess zu starten. Die Bestellnummer finden Sie in der Bestätigungs-E-Mail. - FR: Saisissez les données de la commande pour localiser l'achat et démarrer le processus de retour. Vous trouverez le numéro de commande dans l'e-mail de confirmation. InvalidOrderNumber - PL: Błędny numer zamówienia. Spróbuj ponownie. - EN: Invalid order number. Please try again. - DE: Ungültige Bestellnummer. Bitte versuchen Sie es erneut. - FR: Numéro de commande incorrect. Veuillez réessayer. FindOrder - PL: Znajdź zamówienie - EN: Find order - DE: Bestellung finden - FR: Trouver la commande LoginToSeeOrdersAndReturn - PL: aby zobaczyć swoje zamówienia i dokonać zwrotu. - EN: to see your orders and make a return. - DE: um Ihre Bestellungen einzusehen und eine Rückgabe vorzunehmen. - FR: pour voir vos commandes et effectuer un retour. RefundLookupError - PL: Wystąpił błąd podczas wyszukiwania zamówienia. Spróbuj ponownie później. - EN: An error occurred while searching for the order. Please try again later. - DE: Bei der Suche nach der Bestellung ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut. - FR: Une erreur s'est produite lors de la recherche de la commande. Veuillez réessayer plus tard.

2. Nowa strona Szybkie zwroty

Funkcjonalność szybkich zwrotów wymaga utworzenia dodatkowej strony statycznej refunds. Wykonaj poniższe kroki.

Plik refunds.html w katalogu głównym szablonu

W katalogu głównym szablonu utwórz nowy plik refunds.html z następującą zawartością:
{% extends '_layout.html' %}

{% block content %}
{% include 'static-elements/refunds/refunds.html' %}
{% endblock %}

Plik static-elements/refunds/refunds.html

W folderze static-elements utwórz nowy katalog refunds, a w nim plik refunds.html:
<section class="refunds refunds-js form-js">
    <p class="refunds-header refunds-initial-view-js">{{ translations.Returns }}</p>
    <div class="refunds-intro refunds-initial-view-js">
        <div class="refunds-info">
            <p class="refunds-info-title">{{ translations.ReturnInThreeSteps }}</p>
            <p class="refunds-info-desc">{{ translations.ReturnWithoutReasonInfo }}</p>
            <ol class="refunds-steps">
                <li class="refunds-steps-item">
                    <span class="refunds-steps-number">1</span>
                    <p class="refunds-steps-text"><strong>{{ translations.SignIn }}</strong> {{ translations.OrEnterOrderNumber }}</p>
                </li>
                <li class="refunds-steps-item">
                    <span class="refunds-steps-number">2</span>
                    <p class="refunds-steps-text"><strong>{{ translations.FillForm }}</strong> {{ translations.ReturnOnline }}</p>
                </li>
                <li class="refunds-steps-item">
                    <span class="refunds-steps-number">3</span>
                    <p class="refunds-steps-text"><strong>{{ translations.SendParcel }}</strong> - {{ translations.SendParcelToOurAddress }}</p>
                </li>
            </ol>
            <p class="refunds-info-hint">{{ translations.FastSimpleSecure }}</p>
        </div>
        <div class="refunds-cta">
            <p class="refunds-cta-title">{{ translations.ReadyForReturn }}</p>
            <p class="refunds-cta-desc">{{ translations.ReadyForReturnInfo }}</p>
            {% if usr.Authenticated -%}
            <a class="refunds-cta-button" href="{{ config.DefinedPages.CustomerProfile.Url }}?tab=orders" rel="nofollow" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </a>
            {% else -%}
            <button class="refunds-cta-button start-refund-js" type="button" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </button>
            {% endif -%}
        </div>
    </div>
    {% unless usr.Authenticated -%}
    <div class="refunds-form-section refund-form-view-js hidden-js">
        <div class="refunds-form">
            <p class="refunds-form-title">{{ translations.ProductReturn }}</p>
            <p class="refunds-form-desc">{{ translations.ProductReturnFormInfo }}</p>
            <div class="refund-form-js" data-cp-url="{{ config.DefinedPages.CustomerProfile.Url }}">
                <div class="message-bar-ui warning-bar-ui refund-lookup-error-js hidden-js">{{ translations.RefundLookupError }}</div>
                <div class="form__input-wrapper">
                    <label class="form__input-info form__input-info-js" for="refundOrderNumber" data-type="text">{{ translations.OrderNumber }} <span class="required-ui">*</span></label>
                    <input id="refundOrderNumber" class="form__input-value form__input-value-js" maxlength="50" name="orderNumber" required="" type="text" aria-label="{{ translations.OrderNumber }}" />
                    <span class="error-ui validation-info-js validation-required-js hidden-js">{{ translations.RequiredField }}</span>
                </div>
                <div class="form__input-wrapper">
                    <label class="form__input-info form__input-info-js" for="refundEmail" data-type="email">{{ translations.EmailAddress }} <span class="required-ui">*</span></label>
                    <input id="refundEmail" class="form__input-value form__input-value-js" autocomplete="email" maxlength="192" name="email" required="" type="email" aria-label="{{ translations.EmailAddress }}" />
                    <span class="error-ui validation-info-js validation-required-js hidden-js">{{ translations.RequiredField }}</span>
                    <span class="error-ui validation-info-js email-valid-js hidden-js">{{ translations.FillProperEmail }}</span>
                </div>
                <div class="required-fields-info-ui form__required-fields-info"><span class="required-ui">* </span>{{ translations.RequiredFields }}</div>
                <button class="refunds-form-submit refund-form-submit-js" type="button" aria-label="{{ translations.FindOrder }}">
                    {{ translations.FindOrder }}
                </button>
                <p class="refunds-form-login-info">{{ translations.HaveAccount }} <a class="refunds-form-login-link" href="{{ config.DefinedPages.Login.Url }}" rel="nofollow">{{ translations.SignIn }}</a>, {{ translations.LoginToSeeOrdersAndReturn }}</p>
            </div>
        </div>
    </div>
    {% endunless -%}
</section>

Plik js/layout0.js – kod obsługi formularza zwrotu

Na końcu pliku js/layout0.js dodaj poniższy kod odpowiedzialny za walidację i wysłanie formularza wyszukiwania zamówienia (dla niezalogowanego klienta). Po zapisaniu pliku pamiętaj o zminifikowaniu go do layout0.min.js.
const refunds = {
    findRefundOrder(orderNumber, email) {
        return $.post('', {
            __action: 'Order/QuickReturnLookup',
            orderId: orderNumber,
            email: email,
            __csrf: __CSRF
        });
    },

    showForm() {
        document.querySelectorAll('.refunds-initial-view-js').forEach((el) => el.classList.add('hidden-js'));
        document.querySelectorAll('.refund-form-view-js').forEach((el) => el.classList.remove('hidden-js'));
        document.querySelector('.refund-form-js input[name="orderNumber"]')?.focus();
    },

    clearFieldError(input) {
        input.classList.remove('validation-error-ui', 'validation-error-lq');
        input.closest('.form__input-wrapper')
            ?.querySelectorAll('.error-ui')
            .forEach((el) => el.classList.add('hidden-js'));
    },

    markFieldError(input, errorSelector) {
        input.classList.add('validation-error-ui', 'validation-error-lq');
        input.closest('.form__input-wrapper')?.querySelector(errorSelector)?.classList.remove('hidden-js');
    },

    validateForm({ orderInput, emailInput }) {
        const orderValue = orderInput.value.trim();
        const emailValue = emailInput.value.trim();
        const emailRegex = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w{2,}$/;
        let hasError = false;

        if (orderValue.length === 0) {
            refunds.markFieldError(orderInput, '.validation-required-js');
            hasError = true;
        }

        if (emailValue.length === 0) {
            refunds.markFieldError(emailInput, '.validation-required-js');
            hasError = true;
        } else if (!emailRegex.test(emailValue)) {
            refunds.markFieldError(emailInput, '.email-valid-js');
            hasError = true;
        }

        return { hasError, orderValue };
    },

    async submitForm(button) {
        const form = button.closest('.refund-form-js');
        if (!form) {
            return;
        }
        const orderInput = form.querySelector('input[name="orderNumber"]');
        const emailInput = form.querySelector('input[name="email"]');

        form.querySelectorAll('.error-ui').forEach((el) => el.classList.add('hidden-js'));
        form.querySelector('.refund-lookup-error-js')?.classList.add('hidden-js');
        form.querySelectorAll('.form__input-value').forEach((el) => {
            el.classList.remove('validation-error-ui', 'validation-error-lq');
        });

        const { hasError, orderValue } = refunds.validateForm({ orderInput, emailInput });
        if (hasError) {
            return;
        }

        button.disabled = true;
        const errorBar = form.querySelector('.refund-lookup-error-js');
        try {
            const result = await refunds.findRefundOrder(orderValue, emailInput.value.trim());
            const action = result.action;
            if (action.Redirect302) {
                globalThis.location.href = action.Redirect302;
                return;
            }
            if (errorBar) {
                errorBar.textContent = action.Message;
                errorBar.classList.remove('hidden-js');
            }
        } catch (error) {
            console.error('Refund order lookup failed.', error);
            errorBar?.classList.remove('hidden-js');
        } finally {
            button.disabled = false;
        }
    }
};

js.delegate(document.body, 'click', '.start-refund-js', () => refunds.showForm());

js.delegate(document.body, 'input', '.refund-form-js .form__input-value', function () {
    refunds.clearFieldError(this);
});

js.delegate(document.body, 'click', '.refund-form-submit-js', function (event) {
    event.preventDefault();
    refunds.submitForm(this);
});

js.delegate(document.body, 'keydown', '.refund-form-js input', function (event) {
    if (event.key !== 'Enter') {
        return;
    }
    event.preventDefault();
    this.closest('.refund-form-js')?.querySelector('.refund-form-submit-js')?.click();
});

Pliki SCSS strony Szybkie zwroty

W folderze scss/static-elements utwórz nowy katalog refunds i umieść w nim dwa pliki: refunds-g.scss (style desktop) oraz refunds-m.scss (style mobilne). scss/static-elements/refunds/refunds-g.scss:
.refunds {
    padding: 40px 110px;
    background-color: $bgColor;
    color: $primaryColorFont;

    .refunds-header {
        display: block;
        width: 100%;
        margin: 0 0 24px;
        color: $primaryColorFont;
        text-align: left;
        font-size: 32px;
        font-weight: 500;
        line-height: 42px;
        letter-spacing: 0.8px;
    }

    .refunds-intro {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 32px;
        margin-bottom: 40px;
    }

    .refunds-info {
        align-self: flex-start;
        width: 100%;
        max-width: 800px;
        display: flex;
        flex-direction: column;
        gap: 16px;
        color: $primaryColorFont;

        @media screen and (min-width: 769px) and (max-width: 1279px) {
            max-width: 100%;
        }
    }

    .refunds-info-title {
        margin: 0;
        font-size: 20px;
        font-weight: 500;
        line-height: 28px;
        letter-spacing: 0.4px;
    }

    .refunds-info-desc {
        margin: 0;
        font-size: 16px;
        font-weight: 400;
        line-height: 24px;
        letter-spacing: 0.3px;
    }

    .refunds-info-hint {
        margin: 4px 0 0;
        color: $secondaryColorFont;
        font-size: 12px;
        font-weight: 400;
        line-height: 20px;
        letter-spacing: 0.2px;
    }

    .refunds-steps {
        list-style: none;
        margin: 0;
        padding: 0;
        display: flex;
        flex-direction: column;
        gap: 12px;
    }

    .refunds-steps-item {
        display: flex;
        align-items: center;
        gap: 12px;
    }

    .refunds-steps-number {
        flex-shrink: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        border-radius: 50%;
        background-color: $formsBgColor;
        color: $primaryColor;
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
    }

    .refunds-steps-text {
        margin: 0;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        letter-spacing: 0.3px;

        strong {
            font-weight: 600;
        }
    }

    .refunds-cta {
        box-sizing: border-box;
        width: 100%;
        max-width: 578px;
        padding: 32px 40px;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 12px;
        background-color: $bgColor;
        border: 1px solid $lightBorderColor;
    }

    .refunds-cta-title {
        margin: 0;
        text-align: center;
        font-size: 22px;
        font-weight: 500;
        line-height: 30px;
        letter-spacing: 0.5px;
        color: $primaryColorFont;
    }

    .refunds-cta-desc {
        margin: 0;
        text-align: center;
        color: $secondaryColorFont;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        letter-spacing: 0.3px;
    }

    .refunds-cta-button,
    .refunds-form-submit {
        display: inline-block;
        width: 100%;
        margin-top: 8px;
        padding: 12px 16px;
        background: $btnSolidBgColor;
        color: $btnSolidTextColor;
        border: 1px solid $btnSolidBgColor;
        font-size: 14px;
        font-weight: 500;
        line-height: 20px;
        text-align: center;
        text-decoration: none;
        cursor: pointer;
        transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;

        &:hover,
        &:focus {
            background: $btnSolidHoverBgColor;
            color: $btnSolidHoverTextColor;
            border-color: $btnSolidHoverBgColor;
        }

        &[disabled],
        &[disabled]:hover {
            background: $btnDisabledBg;
            border-color: $btnDisabledFont;
            color: $btnDisabledFont;
            cursor: default;
        }
    }

    .refunds-form-section {
        display: flex;
        justify-content: center;
        width: 100%;
        margin-top: 32px;
        margin-bottom: 40px;
    }

    .refunds-form {
        box-sizing: border-box;
        width: 100%;
        max-width: 578px;
        padding: 32px 40px;
        background-color: $bgColor;
        border: 1px solid $lightBorderColor;
    }

    .refunds-form-title {
        margin: 0 0 8px;
        font-size: 22px;
        font-weight: 500;
        line-height: 30px;
        letter-spacing: 0.5px;
        color: $primaryColorFont;
    }

    .refunds-form-desc {
        margin: 0 0 20px;
        color: $secondaryColorFont;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        letter-spacing: 0.3px;
    }

    .refund-form-js {
        display: flex;
        flex-direction: column;

        .form__input-wrapper {
            position: relative;
            margin-bottom: 16px;

            .form__input-info {
                display: block;
                margin: 0 0 4px;
                color: $primaryColorFont;
                font-size: 13px;
                font-weight: 400;
                line-height: 18px;
            }

            input {
                width: 100%;
                height: 36px;
                margin: 0;
                padding: 0 10px;
                box-sizing: border-box;
                border: 1px solid $lightBorderColor;
                font-size: 14px;

                &::placeholder {
                    font-size: 14px;
                }

                &.validation-error-ui,
                &.validation-error-lq {
                    border-color: $dangerColor;
                    color: $dangerColor;
                }
            }

            .error-ui {
                position: static;
                display: block;
                margin: 4px 0 0;
                padding: 0;
                text-align: left;
                color: $dangerColor;
                font-size: 12px;
                font-weight: 400;
                line-height: 16px;
            }
        }

        .form__required-fields-info {
            margin: 4px 0 16px;
            color: $primaryColorFont;
            font-size: 12px;
            font-weight: 300;
            line-height: 18px;
        }
    }

    .refunds-form-login-info {
        margin: 12px 0 0;
        text-align: center;
        color: $primaryColorFont;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
    }

    .refunds-form-login-link {
        color: $primaryColor;
        font-weight: 600;
        cursor: pointer;
        text-decoration: none;

        &:hover {
            text-decoration: underline;
        }
    }
}
scss/static-elements/refunds/refunds-m.scss:
@media screen and (max-width: 768px) {
    .refunds {
        padding: 20px 16px;

        .refunds-header {
            font-size: 24px;
            line-height: 32px;
            margin-bottom: 16px;
        }

        .refunds-intro {
            gap: 24px;
            margin-bottom: 24px;
        }

        .refunds-info {
            max-width: 100%;
            gap: 12px;
        }

        .refunds-info-title {
            font-size: 18px;
            line-height: 24px;
        }

        .refunds-info-desc {
            font-size: 14px;
            line-height: 22px;
        }

        .refunds-steps-item {
            align-items: flex-start;
            gap: 10px;
        }

        .refunds-steps-number {
            width: 28px;
            height: 28px;
            font-size: 13px;
        }

        .refunds-steps-text {
            font-size: 13px;
            line-height: 20px;
            padding-top: 3px;
        }

        .refunds-cta {
            padding: 24px;
        }

        .refunds-cta-title {
            font-size: 20px;
            line-height: 28px;
        }

        .refunds-form-section {
            margin-top: 20px;
            margin-bottom: 24px;
        }

        .refunds-form {
            padding: 24px;
            border: none;
        }

        .refunds-form-title {
            font-size: 20px;
            line-height: 28px;
        }

        .refunds-form-desc {
            margin-bottom: 16px;
        }

        .refunds-form-login-info {
            font-size: 13px;
        }
    }
}

3. Modyfikacje istniejących plików HTML

partials/customer-profile/orders/order-details.html

W pliku partials/customer-profile/orders/order-details.html wykonaj poniższe zmiany. a) Blok z przyciskami akcji nawigacji zamówienia (zawierający {% if order.EditingAllowed -%}, opcje anulowania, edycji, ponowienia, druku itp.) opakuj warunkiem ukrywającym go dla zamówień typu restricted. Bezpośrednio po linii z elementem <li class="active-ui only-text-ui ...">...</li> wstaw:
{% unless order.Restricted -%}
a tuż przed zamykającym znacznikiem </ul> tej samej nawigacji dodaj:
{% endunless -%}
b) Na początku kontenera messages-container-lq messages-container-ui (zaraz po jego otwarciu) dodaj baner informujący o ukrytych danych zamówienia:
{% if order.Restricted -%}
<div class="message-bar-ui no-margin-ui">
    <i class="not-clickable-ui ti-info-alt"></i>
    {{ translations.RestrictedOrderViewInfo }}
</div>
{% endif -%}
c) Na końcu tego samego kontenera (przed zamykającym </div>) dodaj baner informujący o terminie zwrotu wraz z przypisaniem flagi complaintsOrReturnsEnabled:
{% if config.Complaints.ComplaintsEnabled or config.Complaints.ReturnsEnabled -%}
{% assign complaintsOrReturnsEnabled = true -%}
{% endif -%}

{% if order.Status == 3 and complaintsOrReturnsEnabled -%}
<div class="message-bar-ui no-margin-ui">
    <i class="not-clickable-ui ti-info-alt"></i>
    {{translations.OrderReturnDeadlineInfo | Format: config.Complaints.DaysToReturn}}
</div>
{% endif -%}
d) Blok z przyciskami akcji wewnątrz info-container-js (zawierający przyciski order.CanCancel, edycji, ponowienia zakupu itd.) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}. Wstaw {% unless order.Restricted -%} bezpośrednio przed pierwszym {% if order.CanCancel -%}, a {% endunless -%} po zamykającym warunku odpowiedzialnym za popup potwierdzenia ({% include 'partials/common/confirmation-popup.html' with 0 -%}). e) W sekcji wyświetlającej dokumenty zamówienia zamień:
{% if order.Documents %}
na:
{% if order.Documents and order.Restricted == false %}
f) We wszystkich miejscach wyświetlających numer telefonu klienta zamień warunki sprawdzające jedynie pusty ciąg na warunki sprawdzające również wartość null. Zamień każde wystąpienie:
{% if order.Customer.DeliveryAddress.PhoneNo != '' -%}
na:
{% if order.Customer.DeliveryAddress.PhoneNo != null and order.Customer.DeliveryAddress.PhoneNo != '' -%}
g) Każdą sekcję z tytułem translations.ChoosenDocument opakuj warunkiem ukrywającym ją dla zamówień restricted. Wstaw {% unless order.Restricted -%} bezpośrednio przed <div class="name-ui mt20-ui">{{ translations.ChoosenDocument }}</div> oraz {% endunless -%} po jej zamykającym </div>. h) W sekcji wyświetlającej alternatywny adres dostawy zamień warunek {% else -%} (bezpośrednio przed order-info-item-ui z translations.DelivAddress) na bardziej restrykcyjny:
{% elseif order.Customer.DeliveryAddress != null -%}
i) W sekcji danych do faktury zamień warunek wyświetlania NIP-u/TIN-u. Zamień:
{% elseif order.Customer.TIN != '' -%}
na:
{% elseif order.Customer.TIN != null and order.Customer.TIN != '' -%}
j) W sekcji załączników zamówienia (kontener attachements-ui remarks-ui) zamień warunek otaczający. Zamień:
{% if config.Orders.AttachmentsEnabled -%}
na:
{% if config.Orders.AttachmentsEnabled and order.Restricted == false -%}
k) W sekcji zamówień powiązanych (kontener remarks-ui eshop-order-ui) zamień:
{% if order.RelatedOrders -%}
na:
{% if order.RelatedOrders and order.Restricted == false -%}

partials/customer-profile/complaints/complaint-form.html

W pliku partials/customer-profile/complaints/complaint-form.html wprowadź poniższe zmiany. a) W kontenerze amount-stepper-container-ui amount-stepper-container-lq (wewnątrz warunku {% if type != 'set-return' -%}) na samym początku dodaj etykietę widoczną tylko dla zwrotów:
{% unless complaint -%}
<span class="amount-stepper-label-ui">{{ translations.Quantity }}:</span>
{% endunless -%}
b) Bezpośrednio po zamknięciu kontenera amount-stepper-container-ui (po jego </div> i odpowiadającym {% endif -%}) dodaj sekcję wyboru sposobu zwrotu środków – widoczną tylko w formularzu zwrotu:
{% unless complaint -%}
<div class="refund-method-container-ui refund-method-container-js">
    <label class="label-ui" for="refundMethod">{{ translations.RefundMethod }} <span class="required-ui">*</span></label>
    <div>
        <span class="select-background-ui">
            <select id="refundMethod" class="refund-method-select-js" name="refundMethod" aria-label="{{ translations.RefundMethod }}">
                <option selected="selected" value="original">{{ translations.RefundAsPaid }} {% if order.Payment.Name and order.Payment.Name != "" -%} ({{ order.Payment.Name }}){% endif -%}</option>
                <option value="bank">{{ translations.RefundToBankAccount }}</option>
            </select>
        </span>
        <i class="ti-angle-down select-arrow-ui"></i>
    </div>
    <div class="bank-account-container-ui bank-account-container-js hidden-js">
        <label class="label-ui" for="bankAccountNumber">{{ translations.BankAccountNumber }} <span class="required-ui">*</span></label>
        <div>
            <input id="bankAccountNumber" disabled="disabled" name="bankAccountNumber" type="text" placeholder="{{ translations.BankAccountNumber }}" aria-label="{{ translations.BankAccountNumber }}" />
            <span class="error-ui validation-info-js validation-required-js hidden-js">{{ translations.RequiredField }}</span>
        </div>
    </div>
</div>
{% endunless -%}
c) Komunikat sukcesu wyświetlany po wysłaniu formularza ma być inny dla reklamacji, a inny dla zwrotu. Znajdź kontener <div class="success-message-js hidden-js"> wraz z jego dotychczasową zawartością (komunikat ComplaintAdded + successInfo):
<div class="success-message-js hidden-js">
    <div class="complaint-added-ui">
        <i class="va-mid-ui ti-check"></i>
        <span class="va-mid-ui line-height-1-ui">
            {{ translations.ComplaintAdded }}
        </span>
    </div>
    <div class="info-ui">{{ successInfo }}</div>
</div>
i zastąp go nową, rozszerzoną wersją z dwoma wariantami (reklamacja / zwrot):
<div class="success-message-js hidden-js">
    {% if complaint -%}
    <div class="complaint-added-ui">
        <i class="va-mid-ui ti-check"></i>
        <span class="va-mid-ui line-height-1-ui">
            {{ translations.ComplaintAdded }}
        </span>
    </div>
    <div class="info-ui">{{ successInfo }}</div>
    {% else -%}
    <div class="return-success-popup-ui">
        <div class="return-success-icon-ui">
            <i class="ti-check"></i>
        </div>
        <div class="return-success-title-ui">{{ translations.ReturnConfirmationTitle }}</div>
        <div class="return-success-desc-ui">{{ translations.ReturnConfirmationInfo }}</div>
        {% if order.Customer.Email and order.Customer.Email != "" -%}
        <div class="return-success-email-info-ui">
            <i class="ti-info-alt"></i>
            {{ translations.ReturnConfirmationEmailSent }} <strong>{{ order.Customer.Email }}</strong>
        </div>
        {% endif -%}
        <div class="return-success-steps-title-ui">{{ translations.NextSteps }}</div>
        <ol class="return-success-steps-ui">
            <li>{{ translations.ReturnStep1 }}</li>
            <li>{{ translations.ReturnStep2Address }}: {{ config.Shop.Address.Street }} {{ config.Shop.Address.StreetNo }}{% if config.Shop.Address.UnitNo and config.Shop.Address.UnitNo != "" -%}/{{ config.Shop.Address.UnitNo }}{% endif -%}, {{ config.Shop.Address.ZipCode }} {{ config.Shop.Address.City }}</li>
            <li>{{ translations.ReturnStep3 }}</li>
        </ol>
        <div class="return-success-actions-ui">
            <button class="btn-ui return-success-close-ui hide-container-js closing-modal-js" aria-label="{{ translations.Close }}">
                {{ translations.Close }}
            </button>
        </div>
    </div>
    {% endif -%}
</div>

4. Modyfikacje pliku js/init-ui2.js

Poniższe zmiany dotyczą pliku js/init-ui2.js (po edycji pamiętaj o zminifikowaniu go do init-ui2.min.js). a) Tuż po linii rejestrującej handler openComplaintForm:
js.delegate(document.body, 'click', '.open-complaint-form-js', openComplaintForm);
dodaj poniższy handler obsługujący przełączanie sposobu zwrotu środków – pokazuje on / ukrywa pole na numer konta bankowego:
js.delegate(document.body, 'change', '.refund-method-select-js', function() {
    const container = js.parents(this, 'refund-method-container-js');
    if(!container) return;
    const bankWrapper = container.getElementsByClassName('bank-account-container-js')[0];
    if(!bankWrapper) return;
    const bankInput = bankWrapper.querySelector('input[name="bankAccountNumber"]');
    const validationMsg = bankWrapper.getElementsByClassName('validation-required-js')[0];
    if(this.value === 'bank') {
        bankWrapper.classList.remove('hidden-js');
        if(bankInput) {
            bankInput.disabled = false;
            bankInput.required = true;
        }
    } else {
        bankWrapper.classList.add('hidden-js');
        if(bankInput) {
            bankInput.disabled = true;
            bankInput.required = false;
            bankInput.value = '';
            bankInput.classList.remove('validation-error-lq', 'validation-error-ui');
        }
        if(validationMsg) validationMsg.classList.add('hidden-js');
    }
});
b) W funkcji sendComplaint, bezpośrednio po pętli for (var i=0; i<dataFromHTML.length; i++) dokładającej pola do fd, dodaj fragment dołączający parametr qrHash z adresu URL przy wysyłaniu zwrotu:
if (form.find('input[name="__action"]').val() === 'Order/ReturnAdd') {
    var qrHash = new URLSearchParams(globalThis.location.search).get('qrHash');
    if (qrHash) {
        fd.append('qrHash', qrHash);
    }
}

5. Modyfikacje pliku scss/globals/_globals2.scss

W pliku scss/globals/_globals2.scss wewnątrz selektora opakowującego (tego, który zawiera m.in. .note-ui) dodaj poniższe reguły. Po zmianach pamiętaj o kompilacji SCSS – nie edytuj ręcznie wynikowych plików CSS. a) Style etykiety ilości oraz kontenera wyboru sposobu zwrotu środków (wstaw w sąsiedztwie istniejących reguł sekcji formularza reklamacji/zwrotu):
.amount-stepper-label-ui {
    margin-right: 10px;
    vertical-align: middle;
}

.refund-method-container-ui {
    margin-bottom: 20px;

    .bank-account-container-ui {
        margin-top: 10px;

        input {
            width: 100%;
        }
    }
}
b) Style ekranu sukcesu po wysłaniu zwrotu (ikona, tytuł, lista kolejnych kroków, sekcja z e-mailem i przyciskiem zamknięcia):
.return-success-popup-ui {
    padding: 30px 20px 20px;

    .return-success-icon-ui {
        width: 60px;
        height: 60px;
        border-radius: 50%;
        border: 2px solid #68a204;
        margin: 0 auto 20px;
        display: flex;
        align-items: center;
        justify-content: center;

        i {
            color: #68a204;
            font-size: 26px;
        }
    }

    .return-success-title-ui {
        font-size: 18px;
        font-weight: 500;
        text-align: center;
        margin-bottom: 10px;
    }

    .return-success-desc-ui {
        font-size: 14px;
        color: $primaryColorFont;
        text-align: center;
        margin-bottom: 20px;
    }

    .return-success-email-info-ui {
        background-color: $bgColor;
        border: 1px solid $lightBorderColor;
        padding: 12px;
        border-radius: 4px;
        font-size: 14px;
        margin-bottom: 20px;
        display: flex;
        align-items: flex-start;

        i {
            margin-right: 10px;
            color: $primaryColorFont;
            font-size: 16px;
            line-height: 1.4;
        }

        strong {
            display: block;
        }
    }

    .return-success-steps-title-ui {
        font-weight: 500;
        margin-bottom: 10px;
    }

    .return-success-steps-ui {
        padding-left: 20px;
        margin: 0 0 20px;
        font-size: 14px;

        li {
            margin-bottom: 8px;
            padding-left: 5px;
        }
    }

    .return-success-actions-ui {
        border-top: 1px solid $lightBorderColor;
        padding-top: 15px;
        text-align: right;

        .return-success-close-ui {
            padding: 10px 30px;
        }
    }
}
Po wprowadzeniu wszystkich powyższych zmian w szablonie Szafir pamiętaj o kompilacji oraz minifikacji plików js i scss, zgodnie z artykułem dostępnym pod linkiem https://pomoc.comarchesklep.pl/artykul/kompilacja-i-minifikacja-plikow/.

Szablon Topaz / One Page Shop

Zmiany opisane poniżej dotyczą szablonu Topaz. Szablon One Page Shop ma praktycznie identyczną strukturę – wszystkie modyfikacje dotyczą tych samych plików i mają tę samą zawartość. Wystarczy zastosować poniższą instrukcję w plikach szablonu OPS pod tymi samymi ścieżkami.

1. Tłumaczenia

W panelu administracyjnym sklepu dodaj nowe klucze tłumaczeń wymagane przez funkcjonalność szybkich zwrotów w szablonie Topaz / OPS. RestrictedOrderViewInfo - PL: Wybrane dane zamówienia zostały ukryte ze względów bezpieczeństwa. Możesz zwrócić produkty bez logowania. - EN: Some order details are hidden for security reasons. You can return products without signing in. - DE: Einige Bestelldetails wurden aus Sicherheitsgründen ausgeblendet. Sie können Produkte ohne Anmeldung zurücksenden. - FR: Certaines informations de la commande ont été masquées pour des raisons de sécurité. Vous pouvez retourner des produits sans vous connecter. Prf_ReturnPeriodInfo - PL: Zamówienie można zwrócić w ciągu {0} dni od daty dostawy. - EN: The order can be returned within {0} days from the delivery date. - DE: Die Bestellung kann innerhalb von {0} Tagen ab dem Lieferdatum zurückgegeben werden. - FR: La commande peut être retournée dans un délai de {0} jours à compter de la date de livraison. ComplaintSuccessTitle - PL: Gotowe! Przyjęliśmy Twoje zgłoszenie - EN: Done! We have received your request - DE: Fertig! Wir haben Ihre Meldung erhalten - FR: C'est fait ! Nous avons reçu votre demande ComplaintSuccessDescription - PL: Przygotuj paczkę i odeślij ją do nas – wszystkie szczegóły znajdziesz poniżej. - EN: Prepare the parcel and send it back to us – you will find all the details below. - DE: Bereiten Sie das Paket vor und senden Sie es an uns zurück – alle Details finden Sie unten. - FR: Préparez le colis et renvoyez-le-nous – vous trouverez tous les détails ci-dessous. ComplaintSuccessConfirmationSent - PL: Potwierdzenie zwrotu zostało wysłane na adres: - EN: The return confirmation has been sent to: - DE: Die Rückgabebestätigung wurde an folgende Adresse gesendet: - FR: La confirmation de retour a été envoyée à : ComplaintSuccessStepsTitle - PL: Następne kroki - EN: Next steps - DE: Nächste Schritte - FR: Étapes suivantes ComplaintSuccessStep1 - PL: Bezpiecznie zapakuj swoje produkty - EN: Pack your products securely - DE: Verpacken Sie Ihre Produkte sicher - FR: Emballez vos produits en toute sécurité ComplaintSuccessStep2 - PL: Wyślij paczkę na adres: - EN: Send the parcel to: - DE: Senden Sie das Paket an folgende Adresse: - FR: Envoyez le colis à l'adresse : ComplaintSuccessStep3 - PL: Pieniądze zwrócimy niezwłocznie po otrzymaniu i sprawdzeniu Twojej paczki. - EN: We will refund the money immediately after receiving and inspecting your parcel. - DE: Wir erstatten den Betrag unverzüglich nach Erhalt und Prüfung Ihres Pakets. - FR: Nous rembourserons l'argent immédiatement après réception et vérification de votre colis. ReturnInThreeSteps - PL: Zwróć towar w 3 krokach - EN: Return the product in 3 steps - DE: Geben Sie die Ware in 3 Schritten zurück - FR: Retournez la marchandise en 3 étapes ReturnWithoutReasonInfo - PL: Przysługuje Ci możliwość zwrotu bez podania przyczyny. - EN: You have the right to return the product without giving a reason. - DE: Sie haben das Recht, die Ware ohne Angabe von Gründen zurückzugeben. - FR: Vous avez le droit de retourner la marchandise sans donner de motif. OrEnterOrderNumber - PL: lub podaj numer zamówienia - EN: or enter the order number - DE: oder geben Sie die Bestellnummer ein - FR: ou entrez le numéro de commande FillForm - PL: Wypełnij formularz - EN: Fill out the form - DE: Füllen Sie das Formular aus - FR: Remplissez le formulaire ReturnOnline - PL: zwrotu online - EN: online return - DE: Online-Rückgabe - FR: retour en ligne SendParcel - PL: Wyślij paczkę - EN: Send the parcel - DE: Senden Sie das Paket - FR: Envoyez le colis SendParcelToOurAddress - PL: nadaj przesyłkę na nasz adres - EN: send the parcel to our address - DE: senden Sie das Paket an unsere Adresse - FR: envoyez le colis à notre adresse FastSimpleSecure - PL: Szybko, prosto i bezpiecznie. - EN: Fast, simple and secure. - DE: Schnell, einfach und sicher. - FR: Rapide, simple et sûr. ReadyForReturn - PL: Gotowy do zwrotu? - EN: Ready for return? - DE: Bereit zur Rückgabe? - FR: Prêt pour le retour ? ReadyForReturnInfo - PL: Kliknij poniżej, aby rozpocząć proces zwrotu. Przeprowadzimy Cię przez wszystkie kroki. - EN: Click below to start the return process. We will guide you through all the steps. - DE: Klicken Sie unten, um den Rückgabeprozess zu starten. Wir führen Sie durch alle Schritte. - FR: Cliquez ci-dessous pour commencer le processus de retour. Nous vous guiderons à chaque étape. StartReturn - PL: Rozpocznij zwrot - EN: Start return - DE: Rückgabe starten - FR: Commencer le retour ProductReturn - PL: Zwrot produktu - EN: Product return - DE: Produktrückgabe - FR: Retour du produit ProductReturnFormInfo - PL: Wprowadź dane zamówienia, aby zlokalizować zakup i rozpocząć proces zwrotu. Numer zamówienia znajdziesz w e-mailu z potwierdzeniem. - EN: Enter the order details to locate the purchase and start the return process. You will find the order number in the confirmation e-mail. - DE: Geben Sie die Bestelldaten ein, um den Kauf zu lokalisieren und den Rückgabeprozess zu starten. Die Bestellnummer finden Sie in der Bestätigungs-E-Mail. - FR: Saisissez les données de la commande pour localiser l'achat et démarrer le processus de retour. Vous trouverez le numéro de commande dans l'e-mail de confirmation. FindOrder - PL: Znajdź zamówienie - EN: Find order - DE: Bestellung finden - FR: Trouver la commande RefundLookupError - PL: Wystąpił błąd podczas wyszukiwania zamówienia. Spróbuj ponownie później. - EN: An error occurred while searching for the order. Please try again later. - DE: Fehler beim Suchen nach der Bestellung. Versuchen Sie es später erneut. - FR: Une erreur s'est produite lors de la recherche de la commande. Veuillez réessayer plus tard. LoginToSeeOrdersAndReturn - PL: aby zobaczyć swoje zamówienia i dokonać zwrotu. - EN: to see your orders and make a return. - DE: um Ihre Bestellungen zu sehen und eine Rückgabe zu machen. - FR: pour voir vos commandes et faire un retour. InvalidEmail - PL: Nieprawidłowy adres e-mail - EN: Invalid e-mail address - DE: Ungültige E-Mail-Adresse - FR: L'adresse e-mail est incorrecte. RefundMethod - PL: Sposób zwrotu środków - EN: Refund method - DE: Rückerstattungsmethode - FR: Mode de remboursement RefundAsPaid - PL: Zwrot na sposób płatności - EN: Refund to the original payment method - DE: Rückerstattung auf die ursprüngliche Zahlungsmethode - FR: Remboursement sur le mode de paiement initial RefundToBankAccount - PL: Zwrot na konto bankowe - EN: Refund to bank account - DE: Rückerstattung auf das Bankkonto - FR: Remboursement sur un compte bancaire

2. Nowa strona Szybkie zwroty

Funkcja szybkich zwrotów wymaga utworzenia dodatkowej strony statycznej refunds. Wykonaj poniższe kroki.

Plik refunds.html w katalogu głównym szablonu

W katalogu głównym szablonu utwórz nowy plik refunds.html z następującą zawartością:
{% extends '_layout.html' -%}
{% block pageContent -%}
{% include 'static-elements/refunds/refunds.html' -%}
{% endblock -%}

Plik static-elements/refunds/refunds.html

W folderze static-elements utwórz nowy katalog refunds, a w nim plik refunds.html:
{% include 'partials/common/breadcrumbs.html' -%}

<div class="container my-5 refunds-page-wrapper">

    <!-- Nagłówek główny -->
    <div class="text-center mb-5">
        <h1 class="mb-3">{{ translations.ReturnInThreeSteps }}</h1>
        <p class="lead text-muted">{{ translations.ReturnWithoutReasonInfo }}</p>
    </div>

    <!-- Sekcja 3 kroków (Siatka 3-kolumnowa) -->
    <div class="row text-center mb-5">
        <div class="col-md-4 mb-4">
            <div class="p-4 border rounded bg-light h-100">
                <h3 class="h5">1. {{ translations.Log_Login }}</h3>
                <p class="mb-0">{{ translations.OrEnterOrderNumber }}</p>
            </div>
        </div>
        <div class="col-md-4 mb-4">
            <div class="p-4 border rounded bg-light h-100">
                <h3 class="h5">2. {{ translations.FillForm }}</h3>
                <p class="mb-0">{{ translations.ReturnOnline }}</p>
            </div>
        </div>
        <div class="col-md-4 mb-4">
            <div class="p-4 border rounded bg-light h-100">
                <h3 class="h5">3. {{ translations.SendParcel }}</h3>
                <p class="mb-0">{{ translations.SendParcelToOurAddress }}</p>
            </div>
        </div>
    </div>

    <!-- Wyróżniony tekst -->
    <div class="text-center mb-5">
        <h2 class="text-success h3">{{ translations.FastSimpleSecure }}</h2>
    </div>

    <!-- Sekcja gotowości do zwrotu (Call to Action) -->
    <div class="text-center p-5 border rounded mb-5">
        <h2 class="h3">{{ translations.ReadyForReturn }}</h2>
        <p>{{ translations.ReadyForReturnInfo }}</p>

        <div class="mt-4">
            {% if customer.Authenticated -%}
                <a href="/Return/List" class="btn btn-primary btn-lg">{{ translations.StartReturn }}</a>
            {% else -%}
                <a href="/Return/List" class="btn btn-primary btn-lg">{{ translations.StartReturn }}</a>
            {% endif -%}
        </div>
    </div>

    <!-- Wyszukiwanie zamówienia dla niezalogowanych -->
    <div class="row justify-content-center mb-5">
        <div class="col-md-6 col-lg-5">
            <div class="text-center mb-4">
                <h3 class="h4">{{ translations.ProductReturn }}</h3>
                <p class="text-muted">{{ translations.ProductReturnFormInfo }}</p>
            </div>

            <form action="/Return/FindOrder" method="POST" class="border p-4 rounded bg-white">
                <div class="form-group mb-3">
                    <label class="font-weight-bold">{{ translations.Com_OrderNumber }}</label>
                    <input type="text" class="form-control" name="OrderNumber" required>
                </div>
                <div class="form-group mb-4">
                    <label class="font-weight-bold">{{ translations.EmailAddress }}</label>
                    <input type="email" class="form-control" name="Email" required>
                </div>
                <button type="submit" class="btn btn-dark w-100 btn-lg">{{ translations.FindOrder }}</button>
            </form>
        </div>
    </div>

    <!-- Zachęta do logowania dla niezalogowanych (Gości) -->
    {% if customer.Authenticated == false -%}
        <div class="text-center py-4 mt-4 border-top">
            <h4 class="h5">{{ translations.Reg_HaveAcc }}</h4>
            <p>{{ translations.LoginToSeeOrdersAndReturn }}</p>
            <!-- W Topaz przycisk logowania często otwiera popup ze zdefiniowaną klasą js-login-popup-trigger -->
            <button class="btn btn-outline-primary js-login-popup-trigger">{{ translations.Log_Login }}</button>
        </div>
        {% include 'partials/common/login-register-popup.html' -%}
    {% endif -%}

</div>

<!-- Globalny komponent Newslettera -->
{% if settings.newsletterOnFunctionalPages == 'yes' -%}
    {% include 'partials/newsletter-global.html' -%}
{% endif -%}

Pliki SCSS strony Szybkie zwroty

W folderze scss/static-elements utwórz nowy katalog refunds, a w nim trzy pliki: refunds-g.scss (style ogólne), refunds-d.scss (desktop) oraz refunds-m.scss (mobile). scss/static-elements/refunds/refunds-g.scss:
.refunds-container {
    box-sizing: border-box;
    margin: 0 auto;
    color: $primaryFontColor;
    background-color: $primaryPageBg;

    .refunds-view {
        display: flex;
        flex-direction: column;
        align-items: center;

        &.hidden-js {
            display: none;
        }
    }

    .refunds-intro {
        width: 100%;
        align-self: stretch;

        &__heading {
            margin: 0 0 16px;
            font-size: $mediumFontSize;
            font-weight: 600;
            line-height: 1.4;
            color: $primaryFontColor;
        }

        &__lead {
            margin: 0 0 16px;
            font-size: 16px;
            font-weight: 500;
            line-height: 1.5;
            color: $primaryFontColor;
        }

        &__hint {
            margin: 16px 0 0;
            font-size: $extraSmallFontSize;
            color: $secondaryFontColor;
        }
    }

    .refunds-steps {
        list-style: none;
        counter-reset: refund-step;
        margin: 0;
        padding: 0;
        display: flex;
        flex-direction: column;
        gap: 8px;

        &__item {
            counter-increment: refund-step;
            display: flex;
            align-items: center;
            gap: 12px;

            &::before {
                content: counter(refund-step);
                flex: 0 0 auto;
                width: 32px;
                height: 32px;
                border-radius: 50%;
                background-color: $primaryBtnBg;
                color: $primaryBtnFontColor;
                font-weight: 600;
                font-size: $smallFontSize;
                line-height: 1;
                display: inline-flex;
                align-items: center;
                justify-content: center;
            }
        }

        &__text {
            font-size: $smallFontSize;
            line-height: 1.5;
            color: $primaryFontColor;

            strong {
                font-weight: 600;
            }
        }
    }

    .refunds-card,
    .refunds-lookup {
        box-sizing: border-box;
        width: 100%;
        background-color: $primaryPageBg;
        border: 1px solid $borderColor;
        border-radius: 8px;
        display: flex;
        flex-direction: column;
        margin-left: auto;
        margin-right: auto;
    }

    .refunds-card {
        align-items: center;
        text-align: center;
        gap: 12px;

        &__heading {
            margin: 0;
            font-size: $bigFontSize;
            font-weight: 600;
            line-height: 1.3;
            color: $primaryFontColor;
        }

        &__text {
            margin: 0;
            font-size: 16px;
            line-height: 1.5;
            color: $secondaryFontColor;
        }

        &__btn {
            width: 100%;
            margin-top: 12px;
        }
    }

    .refund-form-js {
        .form__invalid-input {
            margin: 4px 0 0;
            font-size: $extraSmallFontSize;
            line-height: 16px;
            color: $messageErrorColor;
        }
    }

    .refunds-lookup {
        gap: 16px;

        &__heading {
            margin: 0;
            font-size: $bigFontSize;
            font-weight: 600;
            line-height: 1.3;
            color: $primaryFontColor;
        }

        &__lead {
            margin: 0;
            font-size: $smallFontSize;
            line-height: 1.5;
            color: $secondaryFontColor;
        }

        &__loginPrompt {
            margin: 8px 0 0;
            font-size: $smallFontSize;
            color: $primaryFontColor;
        }

        &__loginLink {
            color: $linkFontColor;
            font-weight: 600;
            text-decoration: underline;

            &:hover,
            &:focus {
                text-decoration: none;
            }
        }

        &__error {
            margin: 0;
            font-size: $smallFontSize;
            color: $messageErrorColor;
        }
    }
}

.loginRegister--login-only {
    .loginRegisterTabsContainer {
        display: none;
    }

    .registrationForm-js {
        display: none;
    }
}
scss/static-elements/refunds/refunds-d.scss:
@media screen and (min-width: 769px) {
    .refunds-container {
        max-width: 1400px;
        padding-top: 32px;
        padding-bottom: 64px;

        .refunds-view {
            gap: 32px;
        }

        .refunds-intro {
            &__heading {
                font-size: 20px;
            }

            &__lead {
                margin-bottom: 24px;
            }
        }

        .refunds-card,
        .refunds-lookup {
            max-width: 578px;
        }

        .refunds-card {
            padding: 40px;
        }

        .refunds-lookup {
            padding: 32px;
        }
    }
}
scss/static-elements/refunds/refunds-m.scss:
@media screen and (max-width: 768px) {
    .refunds-container {
        padding: 16px 3% 40px;

        .refunds-view {
            gap: 24px;
        }

        .refunds-intro {
            &__heading {
                font-size: 18px;
            }

            &__lead {
                font-size: $smallFontSize;
                margin-bottom: 16px;
            }
        }

        .refunds-steps {
            &__item {
                &::before {
                    width: 28px;
                    height: 28px;
                }
            }
        }

        .refunds-card {
            padding: 24px 16px;

            &__heading {
                font-size: $mediumFontSize;
            }

            &__text {
                font-size: $smallFontSize;
            }
        }

        .refunds-lookup {
            padding: 20px 16px;

            &__heading {
                font-size: $mediumFontSize;
            }
        }
    }
}

3. Modyfikacje istniejących plików HTML

partials/customer/order-content.html

W pliku partials/customer/order-content.html wykonaj poniższe zmiany. a) Bezpośrednio po otwarciu kontenera <div class="orderContent order-content-js"> dodaj dwa nowe bannery informacyjne (jeden o ukrytych danych zamówienia, drugi o terminie zwrotu, wraz z wyliczaniem flagi hasReturnableProduct):
{% if order.Restricted -%}
<div class="orderContent__returnInfo" role="note">
    <!-- TODO: ikona SVG informacyjna z klasą orderContent__returnInfo__icon -->
    {{ translations.RestrictedOrderViewInfo }}
</div>
{% endif -%}
{% assign hasReturnableProduct = false -%}
{% if config.Complaints.ReturnsEnabled -%}
{% for product in order.Products -%}
{% if product.CanReturn -%}
{% assign hasReturnableProduct = true -%}
{% break -%}
{% endif -%}
{% endfor -%}
{% endif -%}
{% if hasReturnableProduct -%}
<div class="orderContent__returnInfo" role="note">
    <!-- TODO: ikona SVG informacyjna z klasą orderContent__returnInfo__icon -->
    {{ translations.Prf_ReturnPeriodInfo | Format: config.Complaints.DaysToReturn }}
</div>
{% endif -%}
b) Kontener <div class="orderContent__docsToPrint">...</div> (z dokumentami do druku) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}, aby ukrywać go dla zamówień typu restricted. c) Cały dotychczasowy blok przycisków reklamacji/zwrotu (oparty na konstrukcji {% if ComplaintsEnabled and ReturnsEnabled %} ... {% elseif ComplaintsEnabled %} ... {% elseif ReturnsEnabled %} ... {% endif %} z jednym wspólnym przyciskiem) zamień na dwa niezależne warunki, dzięki czemu dla produktu uprawnionego zarówno do reklamacji, jak i do zwrotu, oba przyciski wyświetlają się obok siebie. Strukturę wewnątrz warunku {% if product.CanComplain or product.CanReturn -%} zastąp poniższym kodem:
{% if config.Complaints.ComplaintsEnabled == true and product.CanComplain -%}
<button class="orderContent__complainBtn orderContent__complainBtn--complaint showPopupBtn-js addDataToComplaintForm-js" data-popup-class="popupDialog" data-form-type="complaint" data-product-id="{{product.No}}" data-image-id="{{product.ImageId}}" data-imageext="{{product.Image.ExternalUrl}}" data-product-name="{{product.NameNoHtml | H}}" data-product-complain="{{product.CanComplain}}" data-product-count="{{ newProductQuantity }} {{ product.Unit }}" data-product-unit="{{ product.Unit }}" data-product-description="{{ productAttributes | Join: ' / ' | H }}" data-product-return="false" data-product-quantity="{{newProductQuantity}}" data-order-id="{{order.Id}}" data-order-date="{{order.Date | Date: 'yyyy-MM-dd'}}">
    <svg width="16" height="16">
        <use href="#comment-alt-regular"></use>
    </svg>
    {{translations.Prf_SendComplaint }}
</button>
{% endif -%}
{% if config.Complaints.ReturnsEnabled == true and product.CanReturn -%}
<button class="orderContent__complainBtn orderContent__complainBtn--return showPopupBtn-js addDataToComplaintForm-js" data-popup-class="popupDialog" data-form-type="return" data-product-id="{{product.No}}" data-image-id="{{product.ImageId}}" data-imageext="{{product.Image.ExternalUrl}}" data-product-name="{{product.NameNoHtml | H}}" data-product-complain="false" data-product-count="{{ newProductQuantity }} {{ product.Unit }}" data-product-unit="{{ product.Unit }}" data-product-description="{{ productAttributes | Join: ' / ' | H }}" data-product-return="{{product.CanReturn}}" data-product-quantity="{{newProductQuantity}}" data-order-id="{{order.Id}}" data-order-date="{{order.Date | Date: 'yyyy-MM-dd'}}">
    <svg width="16" height="16">
        <use href="#sync-regular"></use>
    </svg>
    {{ translations.Prf_OrderReturn }}
</button>
{% endif -%}
Kluczowe różnice w stosunku do poprzedniej wersji: każdy przycisk renderowany jest niezależnie (oba mogą wystąpić równocześnie), przyciski mają modyfikatory orderContent__complainBtn--complaint i orderContent__complainBtn--return, atrybut data-form-type (odczytywany w JS), w przycisku reklamacji wymuszone data-product-return="false", w przycisku zwrotu wymuszone data-product-complain="false", ikony 16x16 (#comment-alt-regular dla reklamacji, #sync-regular dla zwrotu), a etykieta przycisku zawiera już tylko jedno tłumaczenie. d) W pozostałych miejscach z przyciskami reklamacji/zwrotu (sekcje, w których nie zmieniają się klasy i ikony) dodaj jedynie dwa nowe atrybuty:
data-product-unit="{{ product.Unit }}"
data-product-description="{{ productAttributes | Join: ' / ' | H }}"
e) W sekcji załączników zamówienia zamień:
{% if order.Attachments[0] -%}
na:
{% if order.Attachments[0] and order.Restricted == false -%}
f) W kontenerze <div class="orderContent__recipient orderContent__infoBox"> zamień wyświetlanie adresu dostawy:
<span class="orderContent__lightText">{{ order.Customer.DeliveryAddress.Street }} {{ order.Customer.DeliveryAddress.StreetNo }} / {{ order.Customer.DeliveryAddress.UnitNo }}</span>
na:
<span class="orderContent__lightText">{{ order.Customer.DeliveryAddress.Street }} {{ order.Customer.DeliveryAddress.StreetNo }}{% if order.Customer.DeliveryAddress.UnitNo != null and order.Customer.DeliveryAddress.UnitNo != '' -%} / {{ order.Customer.DeliveryAddress.UnitNo }}{% endif -%}</span>
g) Sekcję z przyciskami akcji zamówienia (orderCancel-js, ponowienie płatności itd.) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}. Wstaw {% unless order.Restricted -%} bezpośrednio przed warunkiem {% if order.CanRestorePayment -%}, a {% endunless -%} po zamykającym {% endif -%} bloku z przyciskiem anulowania zamówienia.

partials/common/complaint-popup.html

Plik partials/common/complaint-popup.html wymaga gruntownej przebudowy. Usuwamy z niego radiowe przyciski wyboru "reklamacja/zwrot", a typ formularza jest teraz przekazywany z zewnątrz przez parametr __include. Sterowanie ilością zostało przeniesione do kafelka z produktem (z etykietą i obsługą wariantu statycznego, gdy zostaje tylko 1 sztuka). W formularzu zwrotu zamiast samego pola numeru konta pojawia się sekcja wyboru sposobu zwrotu środków (refundMethod-js) – z opcją „zwrot na sposób płatności" (domyślna) lub „zwrot na konto bankowe". Pole numeru konta jest domyślnie ukryte i disabled; pokazuje się dopiero po wybraniu opcji „konto bankowe" (obsługa w JS w metodzie changeRefundMethod). Tytuł, kafelek produktu i formularz oznaczone są dodatkową klasą complain-form-view-js, dzięki czemu po pomyślnym wysłaniu formularza można je ukryć i wyświetlić ekran sukcesu (complain-success-view-js). Zastąp całą zawartość pliku poniższym kodem:
{% if hideContent -%}
{% else -%}
{% assign formType = include -%}
{% assign isReturn = false -%}
{% if formType == 'return' -%}
{% assign isReturn = true -%}
{% endif -%}
<div class="popupDialog popupDialog__complain popupDialog-js">
    {% assign order = customer-profile.Order -%}
    <div class="popupDialog__wrapper">
        <button class="popupDialog__closeBtn closePopupBtn-js">
            <!-- TODO: ikona SVG zamknięcia – jak w pozostałych popupach szablonu -->
        </button>
        <span class="popupDialog__title complain-form-view-js">
            {% if isReturn -%}
            {{ translations.Prf_OrderReturn }}
            {% else -%}
            {{ translations.Prf_SendComplaint }}
            {% endif -%}
        </span>
        <div class="complain__product complain-form-view-js">
            <figure><img class="productImage-js" alt="product_image" /></figure>
            <div class="complain__productInfo">
                <!-- TODO: zweryfikuj z szablonem elementy z klasami productName-js i productDescription-js (nazwa i opis produktu) -->
                <span class="productName-js"></span>
                <span class="productDescription-js"></span>
                <div class="complain__quantity">
                    <label class="complain__quantityLabel" for="complaint-quantity">{{translations.Com_Quantity}}:</label>
                    <div class="complain__quantityControl min-js quantityControl-js">
                        <button class="button-minus-add-product" type="button" aria-label="{{translations.ButtonMinusAddProduct}}" data-field="quantity">
                            <!-- TODO: ikona SVG minus -->
                        </button>
                        <input id="complaint-quantity" class="quantity-field quantity__field-js" max="" min="1" name="quantity" type="number" value="1" data-decimal="false" />
                        <button class="button-plus-add-product" type="button" aria-label="{{ translations.ButtonPlusAddProduct }}" data-field="quantity">
                            <!-- TODO: ikona SVG plus -->
                        </button>
                    </div>
                    <span class="quantityStatic-js hidden"></span>
                    <span class="productUnit-js"></span>
                </div>
            </div>
        </div>
        <div class="form complain__form inputs-container-js complain-form-view-js" data-success-info="{{ translations.ReportSuccessInfo }}">
            <input name="__action" type="hidden" value="{% if isReturn -%}Order/ReturnAdd{% else -%}Order/ComplaintAdd{% endif -%}" />
            <strong>{{ translations.ReportDetails }}</strong>
            {% unless isReturn -%}
            <div class="form__input-wrapper">
                {% if config.Complaints.Defects <> null -%}
                {% assign defectsSize = config.Complaints.Defects | Size -%}
                <label class="hidden" for="defectId">{{ translations.ChooseComplaintCause }}</label>
                <select class="form__input-value form__input-value-js {% if settings.themeName == 'Dark' -%} darkTheme {% endif -%}" name="defectId" required="">
                    {% if defectsSize > 1 -%}
                    <option value="-1">* {{translations.ChooseComplaintCause}}</option>
                    {% endif -%}
                    {% for def in config.Complaints.Defects -%}
                    <option value="{{def.Id}}">{{def.Name}}</option>
                    {% endfor -%}
                </select>
                {% endif -%}
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            <div class="form__input-wrapper">
                <span class="form__icons">
                    <!-- TODO: ikona SVG kalendarza -->
                </span>
                <input id="defectDate" class="form__input-value form__icon_padding form__input-value-js orderDate-js" max="{{config.Now | Date: 'yyyy-MM-dd'}}" min="{{order.Date | Date: 'yyyy-MM-dd'}}" name="defectDate" type="date" value="{{config.Now | Date: 'yyyy-MM-dd'}}" placeholder="yyyy-MM-dd" />
                <label class="form__input-info" for="defectDate">* {{translations.Prf_DefectDate}}</label>
            </div>
            <div class="form__input-wrapper">
                {% if config.Complaints.Requests <> null -%}
                {% assign requestsSize = config.Complaints.Requests | Size -%}
                <label class="hidden" for="requestId">{{ translations.Prf_ComplainRequest }}</label>
                <select class="form__input-value form__input-value-js {% if settings.themeName == 'Dark' -%} darkTheme {% endif -%}" name="requestId" required="">
                    {% if requestsSize > 1 -%}
                    <option value="-1">* {{translations.Prf_ComplainRequest}}</option>
                    {% endif -%}
                    {% for req in config.Complaints.Requests -%}
                    <option value="{{req.Id}}">{{req.Name}}</option>
                    {% endfor -%}
                </select>
                {% endif -%}
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            {% else -%}
            {% assign returnTypes = config.Complaints.Returns | Size -%}
            {% if returnTypes > 1 -%}
            <div class="form__input-wrapper">
                <label class="hidden" for="returnId">{{ translations.ChooseReturn }}</label>
                <select class="form__input-value form__input-value-js {% if settings.themeName == 'Dark' -%} darkTheme {% endif -%}" name="returnId" required="">
                    <option value="-1">* {{translations.ChooseReturn}}</option>
                    {% for return in config.Complaints.Returns -%}
                    <option value="{{return.Id}}">{{return.Name}}</option>
                    {% endfor -%}
                </select>
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            {% endif %}
            {% endunless -%}
            <div class="form__input-wrapper returnInputWrapper-js refundMethodWrapper-js">
                <label class="complain__sectionLabel" for="refundMethod">{{ translations.RefundMethod }}</label>
                <select id="refundMethod" class="form__input-value form__input-value-js refundMethod-js {% if settings.themeName == 'Dark' -%}darkTheme{% endif -%}" name="refundMethod">
                    <option value="payment">{{ translations.RefundAsPaid }}{% if order.Payment.Name != null and order.Payment.Name != '' %} ({{ order.Payment.Name }}){% endif %}</option>
                    <option value="account">{{ translations.RefundToBankAccount }}</option>
                </select>
            </div>
            <div class="form__input-wrapper accountNumberWrapper-js" style="display: none;">
                <input id="accountNumber" class="form__input-value form__input-value-js" disabled="disabled" maxlength="50" name="accountNumber" type="text" />
                <label class="form__input-info form__input-info-js" for="accountNumber">{{translations.Crt_BankAccountNumber}}</label>
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            <div class="form__input-wrapper">
                {{translations.Prf_AdditionalInfo}}
                <textarea class="form__input-value" name="message" aria-label="{{ translations.Prf_AdditionalInfo }}"></textarea>
            </div>
            <div class="form__input-wrapper">
                <span class="form__requiredFields--info">* {{ translations.Com_RequiredFields }}</span>
            </div>
            {% if config.Complaints.AttachmentsEnabled -%}
            <div class="form__input-wrapper attachementsInputWrapper" data-not-added-info="{{translations.AttachementsNotAdded}}">
                <button class="form__attachementsLabel form__attachementsLabel--btn form__attachementsLabel-js" data-page="complaints">
                    <!-- TODO: ikona SVG dodawania załącznika -->
                    {{ translations.AddAttachment }}
                </button>
                {% capture maxSize -%}{{config.Complaints.AttachmentMaxSize | DividedBy: 1024}}KB{% endcapture -%}
                {% for i in (1..config.Complaints.AttachmentsMaxCount) -%}
                <div class="form__attachement-input-container form__attachement-input-container-attachments form__attachement-input-container--hidden">
                    <!-- TODO: ikona SVG oraz element z nazwą pliku (form__attachement-input-container-attachments__text) -->
                    <input class="addAttachementInComplaint-js" accept="{{ config.Complaints.AttachmentExtensions }}" name="file" type="file" aria-label="{{ translations.AddAttachment }}" data-file-size="{{ config.Complaints.AttachmentMaxSize }}" data-size-exceeded="{{ translations.Com_FileSizeExceeded | Format: maxSize }}" data-invalid-file="{{ translations.Com_InvalidFile | Format: config.Complaints.AttachmentExtensions }}" />
                    <button class="form__clear-attachement-input clearFileInput-js" style="display: none;">
                        <!-- TODO: ikona SVG usuwania załącznika -->
                    </button>
                </div>
                {% endfor -%}
            </div>
            {% endif -%}
            <input class="productId-js" name="no" type="hidden" value="" />
            <input class="orderId-js" name="orderId" type="hidden" value="{{order.Id}}" />
            <button class="primary-action-button orderComplaintOrReturnAdd-js" type="button" data-id="{{order.Id}}">{{translations.Report}}</button>
        </div>
        <div class="complain__successView complain-success-view-js hidden">
            <div class="complain__successIcon">
                <!-- TODO: ikona SVG potwierdzenia (zielony "check", klasa svgIcon) -->
            </div>
            <h2 class="complain__successTitle">{{ translations.ComplaintSuccessTitle }}</h2>
            <p class="complain__successDescription">{{ translations.ComplaintSuccessDescription }}</p>
            <div class="complain__successInfoBox">
                <!-- TODO: ikona SVG informacyjna (klasa svgIcon) -->
                <span>{{ translations.ComplaintSuccessConfirmationSent }}
                    <strong>{{ order.Customer.Email }}</strong>
                </span>
            </div>
            <h3 class="complain__successStepsTitle">{{ translations.ComplaintSuccessStepsTitle }}</h3>
            <ol class="complain__successSteps">
                <li>{{ translations.ComplaintSuccessStep1 }}</li>
                <li>{{ translations.ComplaintSuccessStep2 }} {{ config.Shop.Address.Street }} {{ config.Shop.Address.StreetNo }}{% if config.Shop.Address.UnitNo != '' %}/{{ config.Shop.Address.UnitNo }}{% endif %}, {{ config.Shop.Address.ZipCode }} {{ config.Shop.Address.City }}</li>
                <li>{{ translations.ComplaintSuccessStep3 }}</li>
            </ol>
            <div class="complain__successActions">
                <button class="primary-action-button closePopupBtn-js" type="button">{{ translations.BtnClose }}</button>
            </div>
        </div>
    </div>
</div>
{% endif -%}

4. Modyfikacje pliku js/layout1.js

Poniższe zmiany dotyczą pliku js/layout1.js. Po edycji pamiętaj o zminifikowaniu pliku do layout1.min.js. a) W obiekcie customerProfile usuń całą metodę setComplainReturnRadioButtons (radiowy przełącznik reklamacja/zwrot nie jest już potrzebny – typ formularza jest teraz przekazywany przy otwieraniu popupu). b) W tym samym obiekcie zastąp całą metodę addDataToComplaintForm nową implementacją, która odczytuje typ formularza z atrybutu data-form-type przycisku i przekazuje go do szablonu jako parametr __include:
addDataToComplaintForm: function (e) {
    const template = 'partials/common/complaint-popup.html';
    const data = e.currentTarget;
    const formType = data.dataset.formType === 'return' ? 'return' : 'complaint';

    $.get('', {__template: template, __include: "'" + formType + "'"}, function(result) {
        $('.customer__content-js').append(result.template);
        $('.popupDialog__complain').show();
        $('body').addClass('customerProfileNoScroll');

        const image = $('.productImage-js');
        const productName = $('.productName-js');
        const inputId = $('.productId-js');
        const productQuantity = $('.quantity__field-js');
        const quantityControl = $('.quantityControl-js');
        const quantityStatic = $('.quantityStatic-js');
        const productUnit = $('.productUnit-js');
        const productDescription = $('.productDescription-js');

        const orderId = $('.orderId-js');
        const buttonOrderId = $('.orderComplaintOrReturnAdd-js');
        const orderDate = $('.orderDate-js');

        productName.text(data.dataset.productName);
        productUnit.text(data.dataset.productUnit || '');
        productDescription.text(data.dataset.productDescription || '');
        inputId.val(data.dataset.productId);
        productQuantity.attr('max', data.dataset.productQuantity);

        if (parseInt(data.dataset.productQuantity, 10) <= 1) {
            quantityControl.addClass('hidden');
            quantityStatic.text(data.dataset.productQuantity).removeClass('hidden');
        } else {
            quantityControl.removeClass('hidden');
            quantityStatic.addClass('hidden');
        }

        orderId.val(data.dataset.orderId);
        buttonOrderId.attr('data-id', data.dataset.orderId);
        orderDate.attr('min', data.dataset.orderDate);

        if (data.dataset.imageext != null && data.dataset.imageext != "") {
            image.attr('src', data.dataset.imageext);
        } else if (data.dataset.imageId != null && data.dataset.imageId != "") {
            image.attr('src', '/Image/?id=' + data.dataset.imageId);
        }

        if (image.attr('src') === '' || image.attr('src') == null) {
            image.closest('figure').addClass('noImage-js');
        }

        setTimeout(function() {
            app.activateFocusTrap('.popupDialog__complain', e.target);
        }, 200);
    });
},
c) Zastąp metodę changeReturnComplaintForm nową wersją (obsługuje również pole numeru konta i wywołuje changeRefundMethod po przełączeniu na zwrot):
changeReturnComplaintForm: function (e) {
    const form = $(e.currentTarget).closest('.inputs-container-js');
    const complaintInputs = form.find('.complaintInputWrapper-js');
    const returnInputs = form.find('.returnInputWrapper-js');
    const accountWrapper = form.find('.accountNumberWrapper-js');
    const accountInput = accountWrapper.find('input[name="accountNumber"]');

    if ($(e.currentTarget).is(':checked') && e.currentTarget.dataset.name === 'complaint' ) {
        $.each(complaintInputs, function (index, value) {
            $(value).find('input, select').first().removeAttr('disabled');
            $(value).show(300);
        });
        returnInputs.each(function () {
            $(this).find('input, select').first().attr('disabled', 'true');
        });
        returnInputs.hide(300);
        accountInput.removeAttr('disabled').removeAttr('required').removeClass('form__validation-error-js');
        accountWrapper.find('.form__validation-required-js').hide();
        accountWrapper.show(300);
    }

    if ($(e.currentTarget).is(':checked') && e.currentTarget.dataset.name === 'return' ) {
        $.each(complaintInputs, function (index, value) {
            $(value).find('input, select').first().attr('disabled', 'true');
            $(value).hide(300);
        });
        returnInputs.each(function () {
            $(this).find('input, select').first().removeAttr('disabled');
        });
        returnInputs.show(300);
        customerProfile.changeRefundMethod(form);
    }
},
d) Tuż za metodą changeReturnComplaintForm dodaj nową metodę changeRefundMethod (pokazuje / ukrywa pole numeru konta bankowego na podstawie wybranego sposobu zwrotu):
changeRefundMethod: function (formOrEvent) {
    const form = formOrEvent && formOrEvent.currentTarget
        ? $(formOrEvent.currentTarget).closest('.inputs-container-js')
        : $(formOrEvent);
    const select = form.find('.refundMethod-js');
    const accountWrapper = form.find('.accountNumberWrapper-js');
    const accountInput = accountWrapper.find('input[name="accountNumber"]');

    if (select.val() === 'account') {
        accountInput.removeAttr('disabled').attr('required', 'required');
        accountWrapper.show(300);
    } else {
        accountInput.attr('disabled', 'true').removeAttr('required').removeClass('form__validation-error-js');
        accountWrapper.find('.form__validation-required-js').hide();
        accountWrapper.hide(300);
    }
},
e) W metodzie wysyłającej formularz reklamacji/zwrotu (gdzie znajduje się pętla for (let i=0; i<dataFromHTML.length; i++)) zaraz po pętli dodaj fragment dołączający parametr qrHash z URL-a przy wysyłaniu zwrotu:
if (form.find('input[name="__action"]').val() === 'Order/ReturnAdd') {
    const qrHash = new URLSearchParams(globalThis.location.search).get('qrHash');
    if (qrHash) {
        fd.append('qrHash', qrHash);
    }
}
f) W tej samej metodzie, w callbacku success po pomyślnym wysłaniu, zamień fragment:
if (data.action.Result) {
    const message = form.data('success-info');
    app.showTemporaryPopup(message, 'success', '', 8000);
    $('.clearFileInput-js').hide();
    app.hidePopup(e);
    sessionStorage.removeItem('complains');
    sessionStorage.removeItem('order' + (e.currentTarget).dataset.id);
    $('.order' + (e.currentTarget).dataset.id).remove();
    $('.popupDialog__complain').remove();
    $('body').removeClass('customerProfileNoScroll');
    customerProfile.showOrderDetails(e);
}
na:
if (data.action.Result) {
    $('.clearFileInput-js').hide();
    sessionStorage.removeItem('complains');
    sessionStorage.removeItem('order' + (e.currentTarget).dataset.id);
    const popup = $(e.currentTarget).closest('.popupDialog__complain');
    popup.find('.complain-form-view-js').addClass('hidden');
    popup.find('.complain-success-view-js').removeClass('hidden');
    popup.find('.popupDialog__wrapper').scrollTop(0);
}
g) W sekcji rejestracji zdarzeń profilu klienta (tam, gdzie znajdują się m.in. mainSection.on('change', '.radioComplaint-js, .radioReturn-js', ...)) tuż za istniejącym handlerem zmiany typu formularza dopisz nowy handler:
mainSection.on('change', '.refundMethod-js', function (e) {
    customerProfile.changeRefundMethod(e);
});
h) Znajdź globalny handler obsługujący keydown z selektorem zaczynającym się od .radioReturn-js label, .radioComplaint-js label, ... i usuń z niego dwa pierwsze selektory (po zmianie zaczyna się od .showHideSection-js):
// PRZED
$('body').on('keydown', '.radioReturn-js label, .radioComplaint-js label, .showHideSection-js, .checkBoxes__container label, .customerPagination__form-js, .discountsDetails-js, .customer-focus, .customer__menuActivate-js', function(e) { ... });

// PO
$('body').on('keydown', '.showHideSection-js, .checkBoxes__container label, .customerPagination__form-js, .discountsDetails-js, .customer-focus, .customer__menuActivate-js', function(e) { ... });
i) W obiekcie app w pliku js/layout1.js obsłuż przekierowanie po zalogowaniu z parametrem #login-redirect= (używanym przez stronę szybkich zwrotów). W bloku rejestracji/logowania, w miejscu gdzie obsługiwany jest hash #back-to-cart, tuż po nim dodaj:
if (globalThis.location.hash.startsWith('#login-redirect=')) {
    url = globalThis.location.hash.slice('#login-redirect='.length);
}
Następnie w handlerze sukcesu logowania, gdzie znajduje się sprawdzenie window.location.hash.includes('#back-to-cart') wraz z przekierowaniem, tuż za nim dodaj analogiczny blok przekierowujący w przypadku #login-redirect=:
if (globalThis.location.hash.startsWith('#login-redirect=')) {
    globalThis.location.assign(globalThis.location.hash.slice('#login-redirect='.length));
    return;
}

5. Modyfikacje plików SCSS profilu klienta

Poniższe style należy dodać do plików scss/static-elements/customer-profile/customer-profile-g.scss (style ogólne), customer-profile-d.scss (desktop) i customer-profile-m.scss (mobile). Po zmianach pamiętaj o kompilacji SCSS – nie edytuj ręcznie wynikowych plików CSS.

Plik customer-profile-g.scss

a) Wewnątrz selektora opakowującego (tam, gdzie znajdują się istniejące reguły .orderContent__complainBtn) dodaj nowe reguły dla banera informacyjnego oraz kontenera grupującego przyciski reklamacji/zwrotu:
.orderContent__returnInfo {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 16px 0 24px;
    padding: 12px 16px;
    background-color: color-mix(in srgb, #{$linkFontColor} 4%, transparent);
    border: 1px solid color-mix(in srgb, #{$linkFontColor} 20%, transparent);
    border-radius: 4px;
    font-size: 13px;
    line-height: 1.4;
    color: $primaryFontColor;

    &__icon {
        flex-shrink: 0;
        fill: $linkFontColor;
    }
}

.orderContent__complainBtns {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin: 16px 0 4px;
}
b) Następnie zastąp istniejące style .orderContent__complainBtn nowym wyglądem przycisku (z tłem, obramowaniem i hoverem):
.orderContent__complainBtn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 16px 0 4px;
    padding: 6px 12px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 4px;
    color: $linkFontColor;
    fill: $linkFontColor;
    font-size: 13px;
    font-weight: 500;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 180ms, border-color 180ms;

    .orderContent__complainBtns & {
        margin: 0;
    }

    svg {
        margin: 0;
        flex-shrink: 0;
    }

    &:hover,
    &:focus-visible {
        background-color: color-mix(in srgb, #{$linkFontColor} 6%, transparent);
        border-color: color-mix(in srgb, #{$linkFontColor} 25%, transparent);
        outline: none;
    }
}
c) Dodaj style etykiety sekcji oraz kontenera sposobu zwrotu w popupie reklamacji:
.complain__sectionLabel {
    display: block;
    margin-bottom: 8px;
    font-size: 14px;
    font-weight: 500;
    color: $primaryFontColor;
}

.refundMethodWrapper-js {
    margin-bottom: 18px;
}
d) Dodaj kompletne style ekranu sukcesu zwrotu (m.in. ikona, tytuł, lista kolejnych kroków, sekcja z e-mailem i przyciskiem zamknięcia):
.complain__successView {
    text-align: center;
    padding: 16px 0 0;
}

.complain__successIcon {
    display: flex;
    justify-content: center;
    margin: 8px 0 20px;

    .svgIcon {
        width: 64px;
        height: 64px;
        fill: #2d8c4a;
    }
}

.complain__successTitle {
    font-size: 20px;
    font-weight: 600;
    line-height: 1.3;
    margin: 0 0 12px;
    color: $primaryFontColor;
}

.complain__successDescription {
    font-size: 14px;
    line-height: 1.5;
    color: $primaryFontColor;
    margin: 0 0 20px;
}

.complain__successInfoBox {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 14px;
    margin: 0 0 24px;
    border: 1px solid #cfdcef;
    background-color: #f0f5fc;
    border-radius: 6px;
    text-align: left;

    .svgIcon {
        flex-shrink: 0;
        margin-top: 2px;
        fill: #3a6ea5;
    }

    span {
        font-size: 13px;
        line-height: 1.5;
        color: $primaryFontColor;
    }

    strong {
        display: block;
        font-weight: 600;
        margin-top: 2px;
        word-break: break-all;
    }
}

.complain__successStepsTitle {
    font-size: 15px;
    font-weight: 600;
    margin: 0 0 12px;
    text-align: left;
    color: $primaryFontColor;
}

.complain__successSteps {
    margin: 0 0 24px;
    padding-left: 22px;
    text-align: left;

    li {
        font-size: 14px;
        line-height: 1.6;
        margin-bottom: 6px;
        color: $primaryFontColor;
    }
}

.complain__successActions {
    display: flex;
    justify-content: flex-end;
    padding-top: 16px;
    padding-bottom: 30px;
    margin-top: 8px;
    border-top: 1px solid $borderColor;

    .primary-action-button {
        min-width: 140px;
        margin: 0;
    }

    @media screen and (max-width: 599px) {
        .primary-action-button {
            width: 100%;
            min-width: 0;
        }
    }
}
e) Zaktualizuj style załączników – znajdź istniejące reguły .form__clear-attachement-input oraz reguły z position: absolute; top: 11px; i zastąp je nowymi (które ustawiają załączniki w układzie statycznym z poprawnym overflowem i przyciskiem usuwania):
.form__attachement-input-container-attachments__text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.form__attachement-input-container--hidden,
.form__attachement-input-container-attachments.form__attachement-input-container--hidden {
    display: none;
}

.form__clear-attachement-input {
    position: static;
    background: transparent;
    border: none;
    padding: 2px 4px;
    margin: 0 0 0 4px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;

    svg {
        fill: $linkFontColor;
        transition: opacity 200ms;
    }

    &:hover svg {
        opacity: 0.7;
    }
}

Plik customer-profile-d.scss

Wewnątrz wrappera @media screen and (min-width: 769px) zamień istniejące style przycisku reklamacji:
.customer .orderContent__complainBtn {
    position: absolute;
    bottom: 8px;
}
na poniższy fragment (dodaje pozycjonowanie kontenera grupującego przyciski oraz osobny selektor dla pojedynczych przycisków w wierszu produktu):
.customer .orderContent__complainBtns {
    position: absolute;
    bottom: 8px;
    right: 0;
    margin: 0;
}

.customer .orderContent__productDetails > .orderContent__complainBtn {
    position: absolute;
    bottom: 8px;
    right: 0;
    margin: 0;
}

Plik customer-profile-m.scss

W obrębie selektora .customer zamień istniejący media-query @media screen and (max-width: 359px) wraz z jego wnętrzem na rozszerzoną wersję (układająca przyciski reklamacji/zwrotu pionowo na szerokościach do 450px):
@media screen and (max-width: 450px) {
    .customer__orderContent .orderContent__productsRow {
        max-height: none;
    }

    .customer__orderContent .orderContent__productDetails {
        display: flex;
        flex-direction: column;
        align-items: stretch;
    }

    .customer__orderContent .orderContent__complainBtns {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 8px;
        width: 100%;
        margin: 12px 0 4px;
        padding-top: 12px;
        border-top: 1px solid $borderColor;
    }

    .customer__orderContent .orderContent__complainBtn {
        display: flex;
        width: 100%;
        justify-content: center;
        padding: 10px 12px;
        margin: 12px 0 4px;
        border-color: color-mix(in srgb, #{$linkFontColor} 25%, transparent);
    }

    .customer__orderContent .orderContent__complainBtns .orderContent__complainBtn {
        margin: 0;
    }
}

6. Szablon One Page Shop

Szablon One Page Shop ma praktycznie identyczną strukturę plików jak Topaz. Wszystkie powyższe modyfikacje (tłumaczenia, nowa strona zwrotów, edycje plików partials/common/complaint-popup.html oraz partials/customer/order-content.html, zmiany w js/layout1.js oraz w plikach SCSS profilu klienta i strony zwrotów) wykonaj 1:1 w plikach szablonu OPS pod tymi samymi ścieżkami. Treść kodu jest taka sama, ścieżki plików są takie same – instrukcja dla Topaza w pełni stosuje się również do One Page Shopa. Po wprowadzeniu wszystkich powyższych zmian w szablonie Topaz (oraz One Page Shop) pamiętaj o kompilacji oraz minifikacji plików js i scss, zgodnie z artykułem dostępnym pod linkiem https://pomoc.comarchesklep.pl/artykul/kompilacja-i-minifikacja-plikow/.
Wskazówka
Potrzebujesz pomocy lub masz pytania? Skontaktuj się z nami poprzez portal asysta.comarch.pl.

Jak zaprezentować kupony rabatowe w szablonach?

Wstęp

Kupon rabatowy jest wygenerowanym kodem, który umożliwia klientom otrzymanie obniżki procentowej lub wartościowej, a także opcji darmowej dostawy. Jeżeli klient zastosuje kupon rabatowy w koszyku, odpowiednia promocja zostanie naliczona w ramach zamówienia. Kupon rabatowy może być szansą na zwiększenie sprzedaży –  klienci widząc możliwość obniżki chętniej skorzystają z zakupu towarów. W tym momencie możliwe jest zaprezentowanie kuponów w ramach szablonów Topaz, Rubin oraz Szafir.
Wskazówka
Sposób konfiguracji kuponów rabatowych został opisany w artykule Kupony rabatowe.

Jak pokazać klientom dostępne kupony rabatowe?

W sklepie istnieje możliwość pokazania kuponów rabatowych ustawionych dla wszystkich bądź zalogowanych kontrahentów. Prezentacja kuponów odbywa się w ramach wskazanej dla kuponu grupy towarowej.
Wskazówka
W przypadku, gdy kupon rabatowy jest ustawiony na wszystkie kategorie, jest on wyłączony z prezentacji. Dzięki temu możliwe jest ustawienie takiego kuponu bez automatycznego prezentowania promocji na wszystkich towarach w sklepie. Z prezentacji są także wyłączone kupony rabatowe dla newslettera i wybranych subskrybentów, dzięki czemu są one unikalne w ramach mailingu.
Wskazane kody rabatowe można pokazać klientom zarówno na dedykowanej stronie, jak i w ramach towarów, na które obowiązują. Aby włączyć prezentację kuponów rabatowych, wykonaj następujące kroki: Krok 1. Przejdź do obszaru Ustawienia > Ustawienia sklepu > Towary > Etykiety towaru. Z tego poziomu włącz flagę Promocja dla towarów, dla których dodano kupony rabatowe: Na wskazanych towarach pojawi się flaga „Promocja”. Umożliwi to zaprezentowanie kuponów rabatowych w szablonie.
Wskazówka
Tak ustawiona flaga promocja umożliwia prezentację kuponów rabatowych - nie jest uwzględniana w przypadku filtrów na liście towarów. W tym celu należy użyć oznaczenia flagi promocja pochodzącej z systemu ERP lub ceny poprzedniej.
Krok 2. W obszarze Wygląd sklepu > Ustawienia > Prezentacja rabatów włącz prezentację kuponów rabatowych na dedykowanej stronie w strefie klienta: W wyniku wskazanych ustawień, dostępna dla klientów stanie się strona, na której będzie widoczna lista kodów, wraz ze szczegółami obniżki:

Strona w profilu klienta ze szczegółami kodów rabatowych w szablonie Szafir

Kupony rabatowe w profilu klienta w szablonie Topaz

Krok 3. Po włączeniu prezentacji kuponów rabatowych na liście, szczegółach towaru i w koszyku, na towarach będzie dostępny przycisk "Pokaż promocje":

Prezentacja kodów rabatowych na listach w szablonie Szafir

Kupony rabatowe na listach w szablonie Topaz

Kliknięcie na niego dostarczy klientom informację o kuponach obowiązujących na danym towarze: Na szczegółach towaru widoczne są etykiety, które informują o dostępnych kodach, które Klient może wykorzystać:

Prezentacja kuponów rabatowych na szczegołach towaru w szablonie Szafir

             

Prezentacja kuponów rabatowych na szczegołach towaru w szablonie Topaz

Prezentacja kuponów rabatowych na szczegołach towaru w szablonie Rubin
Prezentacja kuponów rabatowych na szczegołach towaru w szablonie Rubin
Dzięki wskazanej prezentacji kuponów, klient w prosty sposób będzie mógł skopiować kod rabatowy z poziomu popupu i zastosować go w ramach zamówienia. Tę funkcję można wykorzystać w celach marketingowych - poprzez zaprezentowaną obniżkę zwiększyć zainteresowanie ofertą sklepu.

Jak prezentować wiele kodów EAN na szczegółach towaru?

Wstęp

W Comarch e-Sklep połączonym z Comarch ERP XL możesz zaprezentować wiele kodów EAN (European Article Number) na szczegółach towaru. Znajdą one zastosowanie w wyszukiwarce, a także w przygotowaniu pliku csv za pomocą którego Twoi klienci dodadzą towary do koszyka. Wiele kodów EAN możesz dodać zarówno na podstawowej jak i dodatkowej jednostce miary towaru. W tym artykule dowiesz się jak dodać dodatkowe kody na towarze, jakie korzyści przynosi ich użycie oraz jak ich używać.

Aby w swoim e-Sklepie skorzystać z możliwości prezentacji wielu kodów EAN na towarze należy:
  • mieć Comarch ERP XL w wersji min. 2024.1,
  • mieć Comarch e-Sklep w wersji min. 2024.3,
  • mieć szablon Szafir, Topaz lub One Page Shop w wersji 2024.3,
  • aktywować prezentację dodatkowych kodów EAN w panelu administracyjnym e-Sklepu.

Jakie są korzyści z używania dodatkowych kodów EAN?

  • Łatwiejsze wyszukiwanie produktów: Dodatkowe kody EAN umożliwiają szybkie i precyzyjne wyszukiwanie towarów w Comarch e-Sklep. Wpisując jeden lub wiele kodów EAN (oddzielone przecinkami) w wyszukiwarkę Twoi klienci natychmiast otrzymają wyniki zawierające dokładnie ten produkt, którego szukają. Identyfikacja produktu odbywa się także zgodnie z przypisanym kodem EAN dla podstawowej (np. szt.) i dodatkowej (np. kartonu) jednostki miary.
  • Szybszy import produktów do koszyka: Funkcjonalność importu produktów za pomocą pliku CSV z wykorzystaniem różnych kodów EAN pozwoli na dywersyfikację towarów w koszyku w zależności od przypisanej jednostki miary do właściwego kodu EAN..

Jakie są sposoby prezentacji kodów EAN na towarach w e-Sklepie?

W Comarch e-Sklep istnieją 4 możliwości prezentacji kodów EAN na szczegółach towaru. Sposób 1. Standardowo prezentowany jest domyślny kod EAN, który został przyporządkowany dla głównej jednostki miary (np. szt) w systemie Comarch ERP XL na zakładce Ogólne. Sposób 2. W e-Sklepie możesz także prezentować kod EAN wskazywany na dodatkowej jednostce miary. Aby go dodać przejdź na zakładkę Jednostki, kody, VAT i wprowadź dedykowany kod EAN na jednostce, w której chcesz także sprzedawać w e-Sklepie. Tak wprowadzony kod EAN pojawi się na szczegółach towaru po wybraniu dedykowanej jednostki przez klienta Twojego e-Sklepu. Sposób 3. Wiele kodów EAN na podstawowej jednostce miary np. szt. Aby je dodać przejdź do zakładki Jednostki, kody, VAT > Kody kreskowe w systemie Comarch ERP XL. Krok 1. Za pomocą zielonego plusa dodaj nowy kod, Krok 2. Wybierz jego typ, Krok 3. Wprowadź kod, Krok 4. Wybierz jednostkę np. szt. Tak wprowadzony kod EAN pojawi się na szczegółach towaru po wybraniu dedykowanej jednostki przez klienta Twojego e-Sklepu. Sposób 4. Wiele kodów EAN na podstawowej i dodatkowej jednostce miary. Aby je dodać przejdź do zakładki Jednostki, kody, VAT > Kody kreskowe w systemie Comarch ERP XL. Krok 1. Za pomocą zielonego plusa dodaj nowy kod, Krok 2. Wybierz jego typ, Krok 3. Wprowadź kod, Krok 4. Wybierz jednostkę np. karton. Tak wprowadzony kod EAN pojawi się na szczegółach towaru po wybraniu dedykowanej jednostki przez klienta Twojego e-Sklepu. Aby tak skonfigurowane kody EAN mogły być widoczne w e-Sklepie należy w panelu administracyjnym e-Sklepu włączyć prezentację dodatkowych kodów EAN na szczegółach towaru w menu Wygląd sklepu > Ustawienia > Ustawienia szablonu > sekcja Ogólne.
Wskazówka
W sekcji Cechy towaru zostanie jako pierwszy zaprezentowany kod EAN dla domyślnej jednostki towaru. Pod warunkiem, że został dodana w systemie Comarch ERP.

Jak korzystać z dodatkowych kodów EAN w wyszukiwarce?

Aby skorzystać z dodatkowych kodów EAN w wyszukiwarce, wystarczy: Krok 1. W panelu administracyjnym e-Sklepu włączyć wyszukiwanie towarów po polu: Kod EAN w menu Ustawienia > Ustawienia sklepu > Wyszukiwanie. Krok 2. Wejść na stronę główną e-Sklepu. Krok 3. W polu wyszukiwania wpisać kod lub wiele kodów EAN oddzielonych przecinkami. Efekt:  Wyniki wyszukiwania będą zawierały produkty odpowiadające wprowadzonym kodom EAN.

Jak importować towary do koszyka za pomocą pliku CSV?(tylko dla wersji B2B)

Krok 1. Przygotowanie pliku CSV: Upewnij się, że plik CSV zawiera kolumnę z kodami EAN i przyporządkowanymi do nich jednostkami miary produktów. Krok 2. Import pliku CSV: Na stronie koszyka znajdziesz opcję importu pliku CSV. Kliknij przycisk "Importuj z pliku CSV", a następnie wybierz przygotowany plik ze swojego komputera. Efekt: Po zaimportowaniu pliku, system automatycznie doda do koszyka produkty odpowiadające kodom EAN i jednostkom miary z pliku CSV w podanej ilości.

Więcej informacji

Więcej informacji można znaleźć w artykułach: Jak skonfigurować jednostki pomocnicze oraz w Przeliczanie jednostki miary według wagi produktu.

Jak zarządzać strefą klienta w Comarch e-Sklep?

Wstęp

Od wersji 2023.5 w ustawieniach szablonów Szafir, Topaz i One Page Shop został dodany nowy obszar, który dotyczy edycji Strefy klienta. W tym artykule dowiesz się jak skonfigurować widok strefy klienta dla swoich klientów.

Konfiguracja

Ustawienia znajdują się w panelu administracyjnym: Wygląd sklepu/ Ustawienia/ Ustawienia szablonu/ Zarządzanie strefą klienta. Na stronie widoczna jest lista elementów widocznych w e-Sklepie. Lista składa się z następujących elementów:
  • Dostępne – ustawienie wyświetlania danego elementu na stronie. Jeżeli parametr jest zaznaczony (podświetla się na szaro) wówczas element będzie widoczny na stronie.
  • Kolejność – w tym polu za pomocą strzałek możemy zmienić kolejność przycisków.
  • Ikona – w tym miejscu należy wprowadzić nazwę ikony, która powinna się wyświetlać na dodanym elemencie. Więcej informacji o ikonach znajdziesz w dalszej części artykułu.
  • Etykieta PL – nazwa elementu, która będzie się wyświetlała w polskiej wersji strony.
  • Id tłumaczenia – id z którego będą pobierane tłumaczenia elementu wyświetlane w obcojęzycznej wersji strony. Tłumaczenia dodawane są w panelu administracyjnym: Wygląd sklepu/ Ustawienia/ Tłumaczenia.
  • Wyróżnij – jeżeli parametr jest zaznaczony, to powoduje zmianę koloru przycisku na inny
[/su_list

Dodawanie ikony

Ikony które są dostępne w szablonie Szafir pochodzą ze strony Themify. Na stronie dostępna jest lista możliwych do wykorzystania ikon. Jeżeli chcesz w swoim elemencie w e-Sklepie dodać ikonę wystarczy, że w polu Ikona wpiszesz nazwę ikony, na przykład: ti-link. Jeżeli jednak chcesz skorzystać z własnych ikon wówczas należy je we własnym zakresie zaimplementować w kodzie szablonu w pliku _layout.html.

Dodawanie tłumaczeń

Nazwę etykiety można wprowadzić na dwa sposoby:
  • w polu Etykieta PL - jeśli w e-Sklepie jest włączony tylko język polski,
  • w polu Id tłumaczenia - dodając id do wybranego tłumaczenia jeśli w e-Sklepie są włączone języki obce.
Jeżeli jest uzupełnione tylko pole Etykieta PL wówczas etykieta będzie miała taką nazwę jaka została wprowadzona w tym polu. Jeżeli jest uzupełnione tylko pole Id tłumaczenia wówczas etykieta będzie miała taką nazwę jaka została przypisana do danego id w sekcji Wygląd sklepu/ Ustawienia/ Tłumaczenia. Jeżeli zostały uzupełnione jednocześnie pola Etykieta PL oraz Id tłumaczenia wówczas etykieta będzie miała taką nazwę jaka została przypisana do danego id w sekcji Wygląd sklepu/ Ustawienia/ Tłumaczenia.
Wskazówka
Pamiętaj, aby elementy były widoczne w e-Sklepie wprowadzone zmiany należy zapisać i opublikować.

Wyróżnienie elementu w Strefie klienta

W szablonie Szafir możliwe jest ustawienie wyróżnienia czcionki wyróżnionego elementu w Strefie klienta. Aby to zrobić zaloguj się do panelu administracyjnego, a następnie do obszaru Wygląd sklepu/Ustawienia. W zakładce Ogólne odnajdź sekcję „Kolor czcionki wyróżnionego elementu w menu profilu klienta”. Wybierz kolory, którymi chcesz wyróżnić element w profilu klienta. Następnie zapisz zmiany. Teraz przejdź do zakładki Strefa klienta. Zaznacz te elementy, które mają zostać wyróżnione. Wystarczy, że wybierzesz odpowiedni checkbox pod Wyróżnij. W efekcie klienci odwiedzający stronę Twojego sklepu po zalogowaniu zobaczą wyróżnione elementy.

Jak zaprezentować rabaty progowe w szablonie B2B (Szafir)?

Wstęp

W Comarch e-Sklepie połączonym z Comarch ERP XL możesz przygotować dla swoich Klientów rabaty, które będą obowiązywać w e-Sklepie dla określonych progów ilościowych. Opcja dotyczy rabatów procentowych i typu stała cena, które naliczają się w e-Sklepie.

Jak skonfigurować ceny per próg ilościowy w Comarch ERP XL?

Aby w swoim e-Sklepie skorzystać z możliwości prezentacji cen dla określonych progów ilościowych ustalonych w systemie Comarch ERP XL należy:
  • mieć Comarch ERP XL w wersji min. 2023.1,
  • mieć Comarch e-Sklep w wersji min. 2023.5,
  • mieć szablon Szafir w wersji 2023.5,
  • aktywować prezentację rabatów progowych w e-Sklepie przy pomocy Asysty technicznej Comarch e-Sklep.
Wskazówka
Jeżeli chcesz prezentować rabaty progowe w swoim szablonie skontaktuj się z Asystą techniczną Comarch e-Sklep poprzez formularz celem aktywowania nowej funkcji.
W celu utworzenia promocji należy w Comarch ERP XL przejść do zakładki Zestawienia/ Promocje i rabaty i dodać rabat pozycji. Następnie można określić szczegóły rabatu na poszczególnych zakładkach:

Nagłówek:

  • Wskazać nazwę rabatu.
  • Określić priorytet.
  • Pomiń następne promocje.
  • Określić sposób łączenie z poprzednią.
  • Rodzaj dokumentu (musi być wskazany rozchodowy lub wszystkie).
  • Wskazać okres działania.
Wskazówka
Priorytet ma znaczenie przy opcji "Pomiń następne promocje". Zaznaczenie tego parametru spowoduje, że żadna promocja o niższym priorytecie (wyższej liczbie) nie powinna się już naliczyć. Jeżeli priorytet będzie wyższy (niższa liczba) to rabat się naliczy.

Kontrahenci:

W Comarch e-Sklep na promocji można wskazać:
  • Pojedynczego kontrahenta – wtedy promocja dotyczy jednego kontrahenta.
  • Grupę kontrahentów (grupa musi być wysyłana do e-Sklepu) – wtedy promocja dotyczy kontrahentów przypisanych do tej grupy.
  • Grupę główną kontrahentów – wtedy promocja dotyczy wszystkich kontrahentów w e-Sklepie: zalogowanych (którzy posiadają konta w e-Sklepie), niezalogowanych i jednorazowych (niezarejestrowanych). Przykład promocji został opisany w sekcji Przykłady użycia rabatów w e-Sklepie

Towary:

  • Wybrać towar albo grupę towarów.
  • Wskazać rodzaj rabatu (rabat od ceny sprzedaży lub stała cena).
  • Wybrać typ rabatu (procentowy lub wartościowy).
  • Wskazać progi ilościowe.
Aby tak skonfigurowane rabaty mogły być widoczne w e-Sklepie należy:
  • przesłać ustalone promocje do e-Sklepu za pomocą ręcznej synchronizacji różnicowej lub automatu synchronizacji,
  • w panelu administracyjnym e-Sklepu włączyć naliczanie rabatów przesyłanych z systemu ERP w menu Ustawienia/ Ustawienia sklepu/ Ceny i rabaty/ sekcja Rabaty  parametr Sposób liczenia rabatów z Comarch e-Sklep i systemu ERP.
  • w panelu administracyjnym e-Sklepu włączyć prezentację ceny dla ilościowych progów rabatowych w menu Wygląd sklepu/ Ustawienia/ Ustawienia szablonu/ sekcja Ogólne/ parametr Cena per próg ilościowy.
Wskazówka
Prezentacja ceny dla ilościowych progów rabatowy pochodzących z Comarch ERP XL jest możliwa tylko przy drugim widoku listy towarów w szablonie Szafir

Gdzie widać ceny dla progów ilościowych?

Prawidłowo udostępnione z systemu Comarch ERP XL rabaty z progiem ilościowym są widoczne w e-Sklepie w kilku miejscach:
  • w sekcji Polecane na stronie głównej e-Sklepu pod warunkiem, że:
    • na towarach w Comarch ERP XL ustawisz odpowiednią etykietę, która będzie tożsama z typem wybranej sekcji w szablonie Szafir. Na towarze zostanie wyświetlony zakres cen, od najniższej do najwyższej. Po kliknięciu w „Zobacz szczegóły cen” zostanie wyświetlony pop-up ze szczegółami pozostałych cen dla progów ilościowych.
  • na szczegółach towaru zostaną wyświetlone trzy pierwsze ceny dla określonych progów. Po kliknięciu w „Zobacz szczegóły cen” zostanie wyświetlony pop-up ze szczegółami pozostałych cen dla progów ilościowych.
  • na liście zakupów w Twoim e-Sklepie. Po kliknięciu w „Zobacz szczegóły cen” zostanie wyświetlony pop-up ze szczegółami pozostałych cen dla progów ilościowych.
  • w panelu administracyjnym w menu Marketing/ Rabaty (widok dla administratora sklepu):
    • na zakładce Z Comarch ERP XL dostępne są rabaty progowe
  • w profilu zalogowanego Klienta w Twoim e-Sklepie, pod warunkiem, że:
    • włączyłeś naliczanie rabatów przesyłanych z systemu ERP (parametr w panelu w menu Ustawienia/ Ustawienia sklepu/ Ceny i rabaty/ sekcja Rabaty > parametr Sposób liczenia rabatów z Comarch e-Sklep i z systemu ERP),
    • włączyłeś wyświetlanie informacji o rabatach w profilu klienta (parametr w panelu w menu Ustawienia/ Ustawienia sklepu/ Ceny i rabaty/ sekcja Rabaty),
    • włączyłeś prezentację rabatów w profilu klienta na zakładce Promocje jest ustawiona na Tak (parametr w panelu w menu Wygląd sklepu/  Ustawienia/  Ustawienia szablonu/ Ogólne > sekcja Prezentacja rabatów).
  • na składanym zamówieniu w Twoim e-Sklepie, pod warunkiem, że:
    • włączyłeś prezentację rabatów na pozycjach zamówienia i w podsumowaniu (parametr w panelu w menu Wygląd sklepu/ Ustawienia/ Ustawienia szablonu/ Ogólne/ sekcja Prezentacja rabatów).

Więcej informacji

Więcej informacji można znaleźć w artykułach:

Rozbudowana stopka w szablonach Topaz i Szafir - jak ją skonfigurować?

Wstęp

Stopka to jeden z podstawowych elementów każdego sklepu internetowego. Oprócz wymaganych informacji, które muszą się w niej znaleźć, może zawierać zbiór innych odniesień do konkretnych sekcji w Twoim e-Sklepie, do Twojego bloga lub profili w social mediach. Odnośniki mogą pozytywnie wpływać na wizerunek Twojego sklepu, przyczyniając się do wsparcia sprzedaży i generując większy ruch na stronie. W Kreatorze wyglądu obok standardowych widoków znajduje się dodatkowy, który jest bardziej rozbudowany. W przypadku szablonu Topaz jest to trzeci widok (footer-3), zaś w przypadku Szafira - drugi widok (footer-2). Dzięki modyfikacji obszaru możesz jeszcze bardziej spersonalizować swój sklep poprzez uzupełnienie stopki w więcej przydatnych informacji.

Konfiguracja rozbudowanej stopki

Jak przystąpić do edycji stopki?

Po zaimportowaniu z Kreatora wyglądu stopka będzie wyświetlać się w ograniczonym zakresie. Niezmiennie jej edycji dokonasz z perspektywy zakładek: Wygląd Sklepu/Ustawienia a następnie sekcji Nagłówek/Stopka. To tutaj zdecydujesz o ilości grup stron, konkretnych elementach w ich obrębie a następnie o kolejności w jakiej będą prezentować się w e-Sklepie. Również z tego poziomu dodasz odwołania do Twoich profili na portalach społecznościowych oraz ustawisz favicon dla swojego sklepu internetowego.

Więcej możliwości edycji stopki

Rozbudowana stopka w szablonie Topaz oraz Szafir umożliwia dodanie większej ilości grup stron niż dotychczas. Dzięki temu z łatwością zamieścisz w niej wszystko czego potrzebujesz. Dodatkowo sekcję uzupełniono o grafiki partnerów logistycznych oraz obsługiwanych operatorów płatności.

Przykładowy wygląd rozbudowanej stopki w szablonie Topaz

Przykładowy wygląd rozbudowanej stopki w szablonie Szafir

Jak skonfigurować poszczególne elementy?

    • Elementy 1-5: dodawanie kolejnych grup stron oraz zmiana ich kolejności dokonywana jest poprzez sekcję Nagłówek/Stopka w Ustawieniach w obrębie zakładki Wygląd Sklepu. W obrębie danej grupy możesz dodawać konkretne strony poprzez kliknięcie przycisku Dodaj stronę ze sklepu.
Wskazówka
Zmiany kolejności poszczególnych grup odnośników lub zmiany danych odnośników w obrębie danej grupy dokonuje się metodą Przeciągnij i upuść.
    • Element 6: odpowiada za wyświetlanie następujących informacji: e-mail, numer telefonu, telefon2 (jeśli nie istnieje, to zastępowany jest przez telefon komórkowy) fax lub skype. W celu edycji danych kontaktowych należy przejść w panelu e-Sklepu do zakładki Ustawienia/Ustawienia sklepu. Informacje o adresie e-mail pobierane są automatycznie z zakładki Ogólne z sekcji Konto e-mail sklepu. Aby dodać lub zmodyfikować numer telefonu konieczne jest wybranie zakładki Dane sprzedawcy, następnie Infolinia i zweryfikowanie pola Telefon.
      Wskazówka
      W elemencie wyświetlone zostaną maksymalnie 3 informacje (e-mail, telefon i jedno z wybranych pól np. telefon2, telefon komórkowy lub fax.
    • Element 7: odwołania do portali społecznościowych dodajemy bez zmian. Więcej o tym znajdziesz tutaj.
    • Elementy 8-9: aby dodać informację o operatorach płatności oraz partnerach logistycznych należy wybrać zakładkę Wygląd Sklepu/Ustawienia/Bannery. Edycji dokonasz z perspektywy kafelków: Logistics Partners oraz Payment Operators poprzez dodanie właściwych grafik operatorów i partnerów. Aby zmienić nazwę „Operator płatności” i/lub „Partnerzy logistyczni” wybierz zamiast zakładki Bannery, zakładkę Tłumaczenia. Wyszukaj po parametrze „ID” LogisticsPartnersBannerTitle oraz PaymentOperatorsBannerTitle i zmodyfikuj pole „Tekst” według własnych preferencji. Zmiany zapisz i opublikuj. W przypadku chęci usunięcia któregoś z elementów, zaznacz go i naciśnij przycisk „Usuń”.
Wskazówka
Zalecane parametry grafik dla operatorów płatności i partnerów logistycznych: szerokość maksymalna 64 px, rozszerzenie PNG.
    • Element 10: dane dotyczące firmy pobierane są z zakładki Ustawienia/Ustawienia sklepu/Dane sprzedawcy/Dane identyfikacyjne, a także z obszaru: Ustawienia/ Ustawienia sklepu/ Informacja o działalności gospodarczej/ Numer KRS lub CEIDG, Organ rejestrujący oraz Ustawienia/ Ustawienia sklepu/ Adres pocztowy, gdzie uwzględnione zostaną wszystkie pola za wyjątkiem Szerokości i długości geograficznej.

Szablon Topaz

Instrukcja: Jak dostosować samodzielnie szablon do szybkich zwrotów w e-Commerce?

Wskazówka
Wskazówka: W tym artykule trzeba będzie wprowadzać zmiany w plikach js oraz scss. Z tego artykułu dowiesz się jak je kompilować i minifikować.
W szablonach Rubin, Szafir oraz Topaz / One Page Shop wprowadziliśmy funkcję szybkich zwrotów. Umożliwia ona klientom składanie wniosku o zwrot produktu zarówno z poziomu profilu klienta (zalogowani), jak i z dedykowanej strony zwrotów po podaniu numeru zamówienia oraz adresu e-mail (niezalogowani). Wraz z funkcjonalnością pojawił się m.in. rozbudowany ekran potwierdzenia zwrotu zawierający kolejne kroki i adres do wysyłki, banery informacyjne dotyczące terminu zwrotu oraz przyciski akcji w tabeli produktów wyświetlane bezpośrednio (zamiast w rozwijanym menu). Aby Twój szablon poprawnie obsługiwał te zmiany, wprowadź modyfikacje opisane poniżej w sekcji dotyczącej Twojego szablonu. Po zakończeniu edycji pamiętaj o kompilacji i minifikacji plików js oraz scss.
Wskazówka
Potrzebujesz pomocy lub masz pytania? Skontaktuj się z nami poprzez portal asysta.comarch.pl.
Wskazówka
Obecnie w Polsce trwają prace nad ostatecznym kształtem przepisów oraz nowelizacją Ustawy o prawach konsumenta, która wdroży unijną dyrektywę UE 2023/2673 i wprowadzi nowe wymagania techniczne dla platform e-commerce (m.in. ułatwienia w procedurze zwrotów). W momencie publikacji ostatecznej wersji polskich przepisów, wdrożone funkcjonalności mogą wymagać dostosowania do ostatecznych wytycznych ustawodawcy. Prezentowane informacje mają charakter poglądowy a instrukcja dotyczy zmian, jakie wprowadziliśmy w szablonach Comarch – w przypadku pytań dotyczących indywidualnej sytuacji prawnej Twojego sklepu, zalecamy konsultację z radcą prawnym lub adwokatem.

Szablon Rubin

1. Tłumaczenia

W panelu administracyjnym sklepu zaktualizuj dwa istniejące tłumaczenia oraz dodaj nowe klucze wymagane przez funkcjonalność szybkich zwrotów. Zaktualizuj poniższe istniejące tłumaczenia: ReturnSuccessTitle - PL: Gotowe! Przyjęliśmy Twoje zgłoszenie - EN: Done! We have received your request - DE: Fertig! Wir haben Ihre Anfrage erhalten - FR: C'est fait ! Nous avons reçu votre demande ReturnSuccessInfo - PL: Przygotuj paczkę i odeślij ją do nas – wszystkie szczegóły znajdziesz poniżej. - EN: Prepare the package and send it back to us – all the details are below. - DE: Bereiten Sie das Paket vor und senden Sie es an uns zurück – alle Details finden Sie unten. - FR: Préparez le colis et renvoyez-le nous – tous les détails sont ci-dessous. Dodaj nowe tłumaczenia: OrderReturnDeadlineInfo - PL: Zamówienie można zwrócić w ciągu {0} dni od daty dostawy. - EN: You can return the order within {0} days from the delivery date. - DE: Sie können die Bestellung innerhalb von {0} Tagen ab Lieferdatum zurückgeben. - FR: Vous pouvez retourner la commande dans les {0} jours suivant la date de livraison. RestrictedOrderViewInfo - PL: Wybrane dane zamówienia zostały ukryte ze względów bezpieczeństwa. Możesz zwrócić produkty bez logowania. - EN: Some order details are hidden for security reasons. You can return products without signing in. - DE: Einige Bestelldetails wurden aus Sicherheitsgründen ausgeblendet. Sie können Produkte ohne Anmeldung zurücksenden. - FR: Certaines informations de la commande ont été masquées pour des raisons de sécurité. Vous pouvez retourner des produits sans vous connecter. Com_RefundMethod - PL: Sposób zwrotu środków - EN: Refund method - DE: Rückerstattungsmethode - FR: Mode de remboursement Com_RefundAsPaid - PL: Tak jak zapłacono - EN: Same as paid - DE: Wie bezahlt - FR: Comme payé Com_RefundToBankAccount - PL: Na konto bankowe - EN: To bank account - DE: Auf Bankkonto - FR: Sur le compte bancaire Com_BankAccountNumber - PL: Nr konta bankowego - EN: Bank account number - DE: Bankkontonummer - FR: Numéro de compte bancaire Com_ConfirmationSentTo - PL: Potwierdzenie zwrotu zostało wysłane na adres: - EN: Return confirmation has been sent to: - DE: Bestätigung wurde gesendet an: - FR: La confirmation de retour a été envoyée à: Com_NextSteps - PL: Następne kroki - EN: Next Steps - DE: Nächste Schritte - FR: Prochaines étapes Com_PackProducts - PL: Bezpiecznie zapakuj swoje produkty - EN: Safely pack your products - DE: Verpacken Sie Ihre Produkte sicher - FR: Emballez vos produits en toute sécurité Com_SendPackageTo - PL: Wyślij paczkę na adres: - EN: Send the package to the address: - DE: Senden Sie das Paket an die Adresse: - FR: Envoyez le colis à l'adresse: Com_RefundAfterReceive - PL: Pieniądze zwrócimy niezwłocznie po otrzymaniu i sprawdzeniu Twojej paczki - EN: We will refund the money promptly upon receipt and inspection of your package - DE: Wir erstatten das Geld umgehend nach Erhalt und Überprüfung Ihres Pakets zurück - FR: Nous rembourserons l'argent rapidement après réception et inspection de votre colis ReturnInThreeSteps - PL: Zwróć towar w 3 krokach - EN: Return the product in 3 steps - DE: Geben Sie die Ware in 3 Schritten zurück - FR: Retournez la marchandise en 3 étapes ReturnWithoutReasonInfo - PL: Przysługuje Ci możliwość zwrotu bez podania przyczyny. - EN: You have the right to return the product without giving a reason. - DE: Sie haben das Recht, die Ware ohne Angabe von Gründen zurückzugeben. - FR: Vous avez le droit de retourner la marchandise sans donner de motif. OrEnterOrderNumber - PL: lub podaj numer zamówienia - EN: or enter the order number - DE: oder geben Sie die Bestellnummer ein - FR: ou saisissez le numéro de commande FillForm - PL: Wypełnij formularz - EN: Fill out the form - DE: Füllen Sie das Formular aus - FR: Remplissez le formulaire ReturnOnline - PL: zwrotu online - EN: online return - DE: Online-Rückgabe - FR: retour en ligne SendParcel - PL: Wyślij paczkę - EN: Send the parcel - DE: Paket senden - FR: Envoyer le colis SendParcelToOurAddress - PL: nadaj przesyłkę na nasz adres - EN: send the parcel to our address - DE: senden Sie das Paket an unsere Adresse - FR: envoyez le colis à notre adresse FastSimpleSecure - PL: Szybko, prosto i bezpiecznie. - EN: Fast, simple and secure. - DE: Schnell, einfach und sicher. - FR: Rapide, simple et sécurisé. ReadyForReturn - PL: Gotowy do zwrotu? - EN: Ready for return? - DE: Bereit zur Rückgabe? - FR: Prêt pour le retour ? ReadyForReturnInfo - PL: Kliknij poniżej, aby rozpocząć proces zwrotu. Przeprowadzimy Cię przez wszystkie kroki. - EN: Click below to start the return process. We will guide you through all the steps. - DE: Klicken Sie unten, um den Rückgabeprozess zu starten. Wir führen Sie durch alle Schritte. - FR: Cliquez ci-dessous pour lancer le processus de retour. Nous vous guiderons à travers toutes les étapes. StartReturn - PL: Rozpocznij zwrot - EN: Start return - DE: Rückgabe starten - FR: Commencer le retour ProductReturn - PL: Zwrot produktu - EN: Product return - DE: Produktrückgabe - FR: Retour du produit ProductReturnFormInfo - PL: Wprowadź dane zamówienia, aby zlokalizować zakup i rozpocząć proces zwrotu. Numer zamówienia znajdziesz w e-mailu z potwierdzeniem. - EN: Enter the order details to locate the purchase and start the return process. You will find the order number in the confirmation e-mail. - DE: Geben Sie die Bestelldaten ein, um den Kauf zu lokalisieren und den Rückgabeprozess zu starten. Die Bestellnummer finden Sie in der Bestätigungs-E-Mail. - FR: Saisissez les données de la commande pour localiser l'achat et démarrer le processus de retour. Vous trouverez le numéro de commande dans l'e-mail de confirmation. InvalidOrderNumber - PL: Błędny numer zamówienia. Spróbuj ponownie. - EN: Invalid order number. Please try again. - DE: Ungültige Bestellnummer. Bitte versuchen Sie es erneut. - FR: Numéro de commande incorrect. Veuillez réessayer. FindOrder - PL: Znajdź zamówienie - EN: Find order - DE: Bestellung finden - FR: Trouver la commande LoginToSeeOrdersAndReturn - PL: aby zobaczyć swoje zamówienia i dokonać zwrotu. - EN: to see your orders and make a return. - DE: um Ihre Bestellungen einzusehen und eine Rückgabe vorzunehmen. - FR: pour voir vos commandes et effectuer un retour. RefundLookupError - PL: Wystąpił błąd podczas wyszukiwania zamówienia. Spróbuj ponownie później. - EN: An error occurred while searching for the order. Please try again later. - DE: Bei der Suche nach der Bestellung ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut. - FR: Une erreur s'est produite lors de la recherche de la commande. Veuillez réessayer plus tard.

2. Nowa strona Szybkie zwroty

Funkcjonalność szybkich zwrotów wymaga utworzenia dodatkowej strony statycznej refunds. Wykonaj poniższe kroki.

Plik refunds.html w katalogu głównym szablonu

W katalogu głównym szablonu utwórz nowy plik refunds.html z następującą zawartością:
{% extends '_layout.html' -%}

{% block pageContent -%}
{% include 'static-elements/refunds/refunds.html' -%}
{% endblock -%}

Plik static-elements/refunds/refunds.html

W folderze static-elements utwórz nowy katalog refunds, a w nim plik refunds.html:
<div class="page-padding">
    <h1 class="refunds-page-title refunds-initial-view-js">{{ translations.Returns }}</h1>
    <section class="refunds-container refunds-initial-view-js">
        <div class="refunds-info">
            <h2 class="refunds-info__title">{{ translations.ReturnInThreeSteps }}</h2>
            <p class="refunds-info__intro">{{ translations.ReturnWithoutReasonInfo }}</p>
            <ol class="refunds-steps">
                <li class="refunds-steps__item">
                    <span class="refunds-steps__number">1</span>
                    <p class="refunds-steps__text"><strong>{{ translations.LogIn }}</strong> {{ translations.OrEnterOrderNumber }}</p>
                </li>
                <li class="refunds-steps__item">
                    <span class="refunds-steps__number">2</span>
                    <p class="refunds-steps__text"><strong>{{ translations.FillForm }}</strong> {{ translations.ReturnOnline }}</p>
                </li>
                <li class="refunds-steps__item">
                    <span class="refunds-steps__number">3</span>
                    <p class="refunds-steps__text"><strong>{{ translations.SendParcel }}</strong> - {{ translations.SendParcelToOurAddress }}</p>
                </li>
            </ol>
            <p class="refunds-info__hint">{{ translations.FastSimpleSecure }}</p>
        </div>
        <div class="refunds-cta">
            <div class="refunds-cta__header">
                <h3 class="refunds-cta__title">{{ translations.ReadyForReturn }}</h3>
                <p class="refunds-cta__description">{{ translations.ReadyForReturnInfo }}</p>
            </div>
            {% if usr.Authenticated -%}
            <a class="primary-action-button refunds-cta__button" href="{{ config.DefinedPages.CustomerProfile.Url }}?tab=orders" rel="nofollow" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </a>
            {% else -%}
            <button class="primary-action-button refunds-cta__button start-refund-js" type="button" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </button>
            {% endif -%}
        </div>
    </section>
    {% unless usr.Authenticated -%}
    <section class="refund-form-section refund-form-view-js hidden-js">
        <div class="refund-form">
            <div class="refund-form__header">
                <h2 class="refund-form__title">{{ translations.ProductReturn }}</h2>
                <p class="refund-form__description">{{ translations.ProductReturnFormInfo }}</p>
            </div>
            <form class="refund-form__body refund-form-js" novalidate="" data-error="{{ translations.RefundLookupError }}">
                <div class="form__input-wrapper">
                    <label class="form__input-info input-info-js" for="refundOrderNumber">{{ translations.NumberOfOrder }}</label>
                    <input id="refundOrderNumber" class="form__input-value input-value-js" maxlength="50" name="orderNumber" required="" type="text" />
                    <div class="form__invalid-input validation-info-js validation-required-js hidden-js">{{ translations.FieldRequired }}</div>
                </div>
                <div class="form__input-wrapper">
                    <label class="form__input-info input-info-js" for="refundEmail" data-type="email">{{ translations.EmailAddress }}</label>
                    <input id="refundEmail" class="form__input-value input-value-js" autocomplete="email" maxlength="192" name="email" required="" type="email" />
                    <div class="form__invalid-input validation-info-js validation-required-js hidden-js">{{ translations.FieldRequired }}</div>
                    <div class="form__invalid-input validation-info-js email-valid-js hidden-js">{{ translations.FillProperEmail }}</div>
                </div>
                <button class="primary-action-button refund-form__submit refund-form-submit-js" type="button">
                    {{ translations.FindOrder }}
                </button>
                <p class="refund-form__login-info">{{ translations.HaveAccount }} <a class="refund-form__login-link show-login-popup-js" tabindex="0" role="button" rel="nofollow">{{ translations.LogIn }},</a> {{ translations.LoginToSeeOrdersAndReturn }}</p>
            </form>
        </div>
    </section>
    {% endunless -%}
</div>

Plik js/layout1.js – kod obsługi formularza zwrotu

Na końcu pliku js/layout1.js dodaj poniższy kod odpowiedzialny za walidację i wysłanie formularza wyszukiwania zamówienia (dla niezalogowanego klienta):
$(document).ready(function() {
    refunds.init();
})

const refunds = {
    init: function() {
        this.events();
    },

    findRefundOrder: function(orderNumber, email) {
        return $.post('', {
            __action: 'Order/QuickReturnLookup',
            orderId: orderNumber,
            email: email,
            __csrf: __CSRF
        });
    },

    showForm: function() {
        $('.refunds-initial-view-js').addClass('hidden-js');
        $('.refund-form-view-js').removeClass('hidden-js');
        $('.refund-form-js input[name="orderNumber"]').trigger('focus');
    },

    clearFieldError: function(input) {
        const $input = $(input);
        $input.removeClass('validation-error-js');
        $input.closest('.form__input-wrapper').find('.form__invalid-input').addClass('hidden-js');
    },

    submitForm: async function(button) {
        const $submit = $(button);
        const $form = $submit.closest('.refund-form-js');
        const $orderInput = $form.find('input[name="orderNumber"]');
        const $emailInput = $form.find('input[name="email"]');
        const orderValue = $orderInput.val().trim();
        const emailValue = $emailInput.val().trim();
        const emailRegex = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w{2,}$/;
        let hasError = false;

        $form.find('.form__invalid-input').addClass('hidden-js');
        $form.find('.form__input-value').removeClass('validation-error-js');

        if (orderValue.length === 0) {
            $orderInput.addClass('validation-error-js');
            $orderInput.closest('.form__input-wrapper').find('.validation-required-js').removeClass('hidden-js');
            hasError = true;
        }

        if (emailValue.length === 0) {
            $emailInput.addClass('validation-error-js');
            $emailInput.closest('.form__input-wrapper').find('.validation-required-js').removeClass('hidden-js');
            hasError = true;
        } else if (!emailRegex.test(emailValue)) {
            $emailInput.addClass('validation-error-js');
            $emailInput.closest('.form__input-wrapper').find('.email-valid-js').removeClass('hidden-js');
            hasError = true;
        }

        if (hasError) {
            return;
        }

        $submit.prop('disabled', true);

        try {
            const result = await refunds.findRefundOrder(orderValue, emailValue);
            const action = result.action;
            if (action.Redirect302) {
                globalThis.location.href = action.Redirect302;
                return;
            }
            app.temporaryPopupMessage(undefined, action.Message, action.Type);
        } catch (error) {
            console.error('Refund order lookup failed.', error);
            app.temporaryPopupMessage(undefined, $form.data('error'), 'err');
        } finally {
            $submit.prop('disabled', false);
        }
    },

    events: function() {
        $('body').on('click', '.start-refund-js', function() {
            refunds.showForm();
        });

        $('body').on('input', '.refund-form-js .form__input-value', function() {
            refunds.clearFieldError(this);
        });

        $('body').on('click', '.refund-form-submit-js', function(e) {
            e.preventDefault();
            refunds.submitForm(this);
        });

        $('body').on('keydown', '.refund-form-js input', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
                $(this).closest('.refund-form-js').find('.refund-form-submit-js').trigger('click');
            }
        });
    }
};

Pliki SCSS strony Szybkie zwroty

W folderze scss/static-elements utwórz nowy katalog refunds i umieść w nim trzy pliki: refunds-g.scss, refunds-m.scss i refunds-t.scss. scss/static-elements/refunds/refunds-g.scss:
.refunds-page-title {
    margin: 0 0 24px;
    font-size: 24px;
    font-weight: 500;
    line-height: 32px;
    color: $primaryColorFont;
}

.refunds-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 32px;
    margin-bottom: 32px;
    color: $primaryColorFont;
}

.refunds-info {
    align-self: flex-start;
    display: flex;
    flex-direction: column;
    gap: 16px;
    width: 100%;
    max-width: 800px;

    &__title {
        margin: 0;
        font-size: 20px;
        font-weight: 600;
        line-height: 28px;
        color: $primaryColorFont;
    }

    &__intro {
        margin: 0;
        font-size: 16px;
        font-weight: 500;
        line-height: 24px;
        color: $primaryColorFont;
    }

    &__hint {
        margin: 4px 0 0;
        font-size: 12px;
        font-weight: 400;
        line-height: 20px;
        color: $breadcrumbs;
    }
}

.refunds-steps {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;

    &__item {
        display: flex;
        align-items: center;
        gap: 12px;
    }

    &__number {
        flex-shrink: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        border-radius: 50%;
        background-color: #f3f3f3;
        color: $primaryColor;
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
    }

    &__text {
        margin: 0;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        color: $primaryColorFont;

        strong {
            font-weight: 600;
        }
    }
}

.refunds-cta {
    box-sizing: border-box;
    width: 100%;
    max-width: 578px;
    padding: 40px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 24px;
    background-color: $bgColor;
    border: 1px solid $lightBorderColor;
    border-radius: 8px;

    &__header {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 12px;
        width: 100%;
    }

    &__title {
        margin: 0;
        font-size: 24px;
        font-weight: 600;
        line-height: 32px;
        text-align: center;
        color: $primaryColorFont;
    }

    &__description {
        margin: 0;
        font-size: 16px;
        font-weight: 400;
        line-height: 24px;
        text-align: center;
        color: $breadcrumbs;
    }

    &__button {
        width: 100%;
        text-decoration: none;
    }
}

.refund-form-section {
    display: flex;
    justify-content: center;
    width: 100%;
    margin-bottom: 32px;
}

.refund-form {
    box-sizing: border-box;
    width: 100%;
    max-width: 578px;
    padding: 40px;
    background-color: $bgColor;
    border: 1px solid $lightBorderColor;
    border-radius: 8px;

    &__header {
        display: flex;
        flex-direction: column;
        gap: 12px;
        margin-bottom: 32px;
    }

    &__title {
        margin: 0;
        font-size: 24px;
        font-weight: 600;
        line-height: 32px;
        color: $primaryColorFont;
    }

    &__description {
        margin: 0;
        font-size: 14px;
        font-weight: 400;
        line-height: 20px;
        color: $breadcrumbs;
    }

    &__body {
        display: flex;
        flex-direction: column;
    }

    .form__input-wrapper {
        .form__input-value {
            &.validation-error-js {
                border-color: $dangerColor;
                color: $dangerColor;
            }
        }

        .form__invalid-input {
            position: static;
            display: block;
            margin: 4px 0 0;
            padding-left: 16px;
            text-align: left;
            color: $dangerColor;
            font-size: 12px;
            font-weight: 400;
            line-height: 16px;
        }
    }

    &__submit {
        width: 100%;
        margin-top: 4px;
    }

    &__login-info {
        margin: 16px 0 0;
        text-align: center;
        font-size: 14px;
        font-weight: 400;
        line-height: 20px;
        color: $primaryColorFont;
    }

    &__login-link {
        color: $primaryColor;
        font-weight: 600;
        cursor: pointer;
        text-decoration: none;

        &:hover {
            text-decoration: underline;
        }
    }
}
scss/static-elements/refunds/refunds-m.scss:
@media screen and (max-width: 767px) {
    .refunds-page-title {
        font-size: 20px;
        line-height: 28px;
        margin-bottom: 16px;
    }

    .refunds-container {
        gap: 24px;
        margin-bottom: 24px;
    }

    .refunds-info {
        max-width: 100%;
        gap: 12px;

        &__title {
            font-size: 18px;
            line-height: 24px;
        }

        &__intro {
            font-size: 14px;
            line-height: 22px;
        }
    }

    .refunds-steps {
        &__item {
            align-items: flex-start;
            gap: 10px;
        }

        &__number {
            width: 28px;
            height: 28px;
            font-size: 13px;
        }

        &__text {
            font-size: 13px;
            line-height: 20px;
            padding-top: 3px;
        }
    }

    .refunds-cta {
        padding: 24px;

        &__title {
            font-size: 20px;
            line-height: 28px;
        }

        &__description {
            font-size: 14px;
            line-height: 22px;
        }
    }

    .refund-form {
        padding: 24px;

        &__header {
            margin-bottom: 24px;
        }

        &__title {
            font-size: 20px;
            line-height: 28px;
        }

        &__description {
            font-size: 13px;
            line-height: 18px;
        }

        &__login-info {
            font-size: 13px;
        }
    }
}
scss/static-elements/refunds/refunds-t.scss:
@media screen and (min-width: 768px) and (max-width: 1439px) {
    .refunds-info {
        max-width: 100%;
    }
}

3. Modyfikacje istniejących plików HTML

partials/cart/thx.html

W pliku partials/cart/thx.html znajdź fragment generujący etykietę zgody w sekcji zgód marketingowych:
<label class="cart__tos-label tos-js" tabindex="0" role="checkbox" for="{{ consent.FieldValue }}" aria-checked="false"></label>
Usuń z niego atrybut for="{{ consent.FieldValue }}". Po zmianie linia powinna wyglądać tak:
<label class="cart__tos-label tos-js" tabindex="0" role="checkbox" aria-checked="false"></label>

partials/common/login.html

1. W pliku partials/common/login.html w kontenerze opakowującym formularz dodaj klasę login-container-popup. Zamień linię:
<div class="{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id -%} login-popup-js{% else -%} login-container {% endif -%}">
na:
<div class="{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id -%} login-popup-js login-container-popup{% else -%} login-container {% endif -%}">
2. W warunku otaczającym przycisk zamykający popup logowania usuń warunek and settings.signIn == "popup". Zamień linię:
{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id and settings.signIn == "popup" -%}
na:
{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id -%}

partials/product/amount-stepper.html

W pliku partials/product/amount-stepper.html znajdź blok ustawiający zmienne dla typów complaint i return:
{% if type == 'complaint' or type == 'return' -%}
{% assign reloadClass = '' -%}
{% assign complaintOrReturn = true -%}
{% endif -%}
i dodaj w jego wnętrzu nową linię ustawiającą maksymalną ilość produktu:
{% if type == 'complaint' or type == 'return' -%}
{% assign reloadClass = '' -%}
{% assign complaintOrReturn = true -%}
{% assign max = product.Quantity | Normalize -%}
{% endif -%}

partials/order/products-partials/product-table-header.html

Na samym początku pliku partials/order/products-partials/product-table-header.html dodaj blok przypisujący flagę complaintsOrReturnsEnabled:
{% if config.Complaints.ComplaintsEnabled or config.Complaints.ReturnsEnabled -%}
{% assign complaintsOrReturnsEnabled = true -%}
{% endif -%}

partials/product/products-table.html

Przyciski reklamacji i zwrotu są wyświetlane bezpośrednio w tabeli, zamiast w rozwijanym menu. W pliku partials/product/products-table.html znajdź komórkę z opcjami:
{% if order.Status == 3 and complaintsOrReturnsEnabled and product.CanComplain == true -%}
<button class="pure-button open-dropdown-js" aria-label="{{translations.Options}}">
    <!-- TODO: ikona SVG przycisku opcji – bez zmian, jak w istniejącym pliku -->
</button>
<div class="dropdown dropdown-js hidden-js" style="bottom: auto !important;">
    {% if config.Complaints.ComplaintsEnabled == true and product.CanComplain == true -%}
    <button class="pure-button open-complaint-form-js" data-type="complaint" data-product="{{ product.Url }}">
        {{ translations.Complain }}
    </button>
    {% endif -%}
    {% if config.Complaints.ReturnsEnabled == true and product.CanReturn == true and product.IsSetElement == false -%}
    <button class="pure-button open-complaint-form-js" data-type="return" data-product="{{ product.Url }}">
        {{ translations.Return }}
    </button>
    {% endif -%}
</div>
{% endif -%}
i zastąp ją następującym fragmentem:
{% if order.Status == 3 and complaintsOrReturnsEnabled -%}
{% if config.Complaints.ComplaintsEnabled == true and product.CanComplain == true -%}
<button class="pure-button open-complaint-form-js complaint-action-btn" data-type="complaint" data-product="{{ product.Url }}">
    {{ translations.Complain }}
</button>
{% endif -%}
{% if config.Complaints.ReturnsEnabled == true and product.CanReturn == true and product.IsSetElement == false -%}
<button class="pure-button open-complaint-form-js complaint-action-btn" data-type="return" data-product="{{ product.Url }}">
    {{ translations.Return }}
</button>
{% endif -%}
{% endif -%}
Następnie w tym samym pliku znajdź zewnętrzny warunek otaczający kontenery formularzy reklamacji i zwrotu i poluzuj go (usuń warunek product.CanComplain == true). Zamień:
{% if order.Status == 3 and complaintsOrReturnsEnabled and product.CanComplain == true -%}
na:
{% if order.Status == 3 and complaintsOrReturnsEnabled -%}

partials/customer-profile/orders/order-details.html

W pliku partials/customer-profile/orders/order-details.html wykonaj poniższe zmiany. a) Bloki Opcje (zawierające klasę options submenu z przyciskami akcji zamówienia) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}, aby ukryć je dla niezalogowanych klientów dokonujących szybkiego zwrotu. Wstaw {% unless order.Restricted -%} bezpośrednio przed otwierającym <div class="options submenu">, a {% endunless -%} po jego zamykającym </div>:
{% unless order.Restricted -%}
<div class="options submenu">
    ...
</div>
{% endunless -%}
b) W kontenerze messages-container-js na początku (przed istniejącymi komunikatami typu OrderEditable) dodaj baner informujący o ukrytych danych zamówienia oraz, na końcu kontenera, baner informujący o terminie zwrotu:
{% if order.Restricted -%}
<div class="return-info-banner">
    <!-- TODO: ikona SVG informacyjna (z klasą icon) -->
    {{ translations.RestrictedOrderViewInfo }}
</div>
{% endif -%}
{% if order.Status == 3 and config.Complaints.ReturnsEnabled -%}
<div class="return-info-banner">
    <!-- TODO: ikona SVG informacyjna (z klasą icon) -->
    {{ translations.OrderReturnDeadlineInfo | Format: config.Complaints.DaysToReturn }}
</div>
{% endif -%}
c) We wszystkich miejscach wyświetlających numer telefonu klienta zamień warunki sprawdzające jedynie pusty ciąg na warunki sprawdzające również wartość null. Zamień każde wystąpienie:
{% if order.Customer.DeliveryAddress.PhoneNo != '' -%}
na:
{% if order.Customer.DeliveryAddress.PhoneNo != null and order.Customer.DeliveryAddress.PhoneNo != '' -%}
d) Analogicznie zaktualizuj warunek wyświetlania NIP-u/TIN-u w sekcji danych do faktury. Zamień:
{% elseif order.Customer.TIN != '' -%}
na:
{% elseif order.Customer.TIN != null and order.Customer.TIN != '' -%}
e) W sekcji adresu dostawy zamień otwierający warunek alternatywny {% else -%} (bezpośrednio przed kontenerem z translations.DelivAddress) na bardziej restrykcyjny:
{% elseif order.Customer.DeliveryAddress != null -%}
f) Sekcję wybranego dokumentu (ChoosenDocument) opakuj warunkiem ukrywającym ją dla zamówień typu restricted. Wstaw {% unless order.Restricted -%} przed kontenerem order-details-item z tytułem translations.ChoosenDocument oraz {% endunless -%} za jego zamykającym </div>. g) W sekcji dokumentów zamówienia dodaj do warunku sprawdzenie order.Restricted == false. Zamień:
{% if orderDocumentsSize > 0 -%}
na:
{% if orderDocumentsSize > 0 and order.Restricted == false -%}
h) W sekcji załączników zamówienia dodaj analogiczne sprawdzenie. Zamień:
{% if config.Orders.AttachmentsEnabled and orderAttachmentsSize > 0 -%}
na:
{% if config.Orders.AttachmentsEnabled and orderAttachmentsSize > 0 and order.Restricted == false -%}
i) W sekcji zamówień powiązanych zamień:
{% if order.RelatedOrders[0] -%}
na:
{% if order.RelatedOrders[0] and order.Restricted == false -%}

partials/customer-profile/complaints/complaint-form.html

W pliku partials/customer-profile/complaints/complaint-form.html wprowadź poniższe zmiany. a) W kontenerze amount-stepper-container (wewnątrz warunku {% if type != 'set-return' -%}) na samym początku dodaj nową etykietę:
<span class="amount-stepper-container__label">{{ translations.Quantity }}:</span>
b) Pod sekcją z komentarzem reklamacji/zwrotu (po zamykającym {% endif -%} z sekcji complaint-message-textarea) wewnątrz warunku {% if type != 'set-return' -%} dodaj sekcję wyboru sposobu zwrotu środków:
<div class="refund-method-wrapper">
    <div class="refund-method-wrapper__title">{{ translations.Com_RefundMethod }} <span class="required">*</span></div>
    <label class="refund-method-option">
        <input class="refund-method-option__radio refund-method-radio-js" checked="checked" name="refundMethod" type="radio" value="asPaid" />
        <span class="refund-method-option__box"></span>
        <span class="refund-method-option__label">
            {{ translations.Com_RefundAsPaid }} {% if order.Payment.Name and order.Payment.Name != '' -%} ({{ order.Payment.Name }}){% endif -%}
        </span>
    </label>
    <label class="refund-method-option">
        <input class="refund-method-option__radio refund-method-radio-js" name="refundMethod" type="radio" value="bankAccount" />
        <span class="refund-method-option__box"></span>
        <span class="refund-method-option__label">{{ translations.Com_RefundToBankAccount }}</span>
    </label>
</div>
<div class="form__input-wrapper account-number-wrapper-js hidden-js">
    <label class="form__input-info input-info-js" for="accountNumber">{{ translations.Com_BankAccountNumber }} <span class="required">*</span></label>
    <input id="accountNumber" class="form__input-value input-value-js" disabled="disabled" maxlength="50" name="accountNumber" type="text" />
    <div class="form__invalid-input validation-info-js validation-required-js hidden-js">{{ translations.FieldRequired }}</div>
</div>
c) W sekcji załączników plików zamień prosty licznik file-{{forloop.index}} na prefiks zawierający identyfikator zamówienia, numer produktu i typ formularza. Tuż przed pętlą {% for i in (1..config.Complaints.AttachmentsMaxCount) -%} dodaj nową linię:
{% capture filePrefix -%}file-{{ order.Id }}-{{ product.No }}-{{ type }}{% endcapture -%}
Następnie wewnątrz pętli zamień:
<label class="file" for="file-{{forloop.index}}">
<input id="file-{{forloop.index}}" class="add-attachement-in-complaint-js hidden-js" type="file" /></label>
na:
<label class="file" for="{{ filePrefix }}-{{ forloop.index }}">
<input id="{{ filePrefix }}-{{ forloop.index }}" class="add-attachement-in-complaint-js hidden-js" type="file" /></label>
d) Komunikat sukcesu wyświetlany po wysłaniu formularza ma być inny dla reklamacji, a inny dla zwrotu. Znajdź kontener <div class="success-message-js hidden-js"> i jego dotychczasową zawartość:
<div class="success-message-js hidden-js">
    {{ successInfo }}
</div>
zastąp:
<div class="success-message-js hidden-js">
    {% if complaint -%}
    {{ successInfo }}
    {% else -%}
    <div class="data-form__header return-success__header">
        <button class="close-button hide-container-js closing-modal-js" aria-label="{{ translations.Close }}">
            <!-- TODO: ikona SVG zamknięcia – jak w pozostałych popupach szablonu -->
        </button>
    </div>
    <div class="return-success__icon">
        <!-- TODO: ikona SVG potwierdzenia (zielony "check") -->
    </div>
    <div class="return-success__title">{{ successTitle }}</div>
    <div class="return-success__subtitle">{{ successInfo }}</div>
    {% if order.Customer.Email and order.Customer.Email != '' -%}
    <div class="return-success__email-box">
        <!-- TODO: ikona SVG informacyjna -->
        <div>
            <div>{{ translations.Com_ConfirmationSentTo }}</div>
            <strong>{{ order.Customer.Email }}</strong>
        </div>
    </div>
    {% endif -%}
    <div class="return-success__steps-title">{{ translations.Com_NextSteps }}</div>
    <ol class="return-success__steps">
        <li>{{ translations.Com_PackProducts }}</li>
        <li>{{ translations.Com_SendPackageTo }}
            {% if config.Shop.Address.Street != '' -%} {{ config.Shop.Address.Street }}{% endif -%}
            {% if config.Shop.Address.StreetNo != '' -%} {{ config.Shop.Address.StreetNo }}{% endif -%}
            {% if config.Shop.Address.UnitNo != '' -%}/{{ config.Shop.Address.UnitNo }}{% endif -%}
            {% if config.Shop.Address.ZipCode != '' or config.Shop.Address.City != '' -%}, {{ config.Shop.Address.ZipCode }} {{ config.Shop.Address.City }}{% endif -%}</li>
        <li>{{ translations.Com_RefundAfterReceive }}</li>
    </ol>
    <div class="buttons-container short">
        <button class="primary-action-button hide-container-js closing-modal-js">
            {{ translations.Close }}
        </button>
    </div>
    {% endif -%}
</div>

4. Modyfikacje pliku js/layout-customerprofile0.js

Poniższe zmiany dotyczą pliku js/layout-customerprofile0.js (jego nieskompresowanej wersji, którą po edycji należy ponownie zminifikować do layout-customerprofile0.min.js). a) W funkcji openComplaintForm wewnątrz warunku if (hiddenContainer) – tuż po linii hiddenContainer.querySelector('.success-message-js').classList.add('hidden-js'); – dodaj kod ujawniający nagłówek formularza oraz resetujący wybór sposobu zwrotu do opcji domyślnej:
const mainHeader = hiddenContainer.querySelector(':scope > .data-form__header');
if (mainHeader) {
    mainHeader.classList.remove('hidden-js');
}
hiddenContainer.classList.remove('hidden-js');

const asPaidRadio = hiddenContainer.querySelector('.refund-method-radio-js[value="asPaid"]');
if (asPaidRadio) {
    asPaidRadio.checked = true;
    $(asPaidRadio).trigger('change');
}
(Linia hiddenContainer.classList.remove('hidden-js'); już istnieje – pokazana jest dla kontekstu. Nowe są bloki const mainHeader i const asPaidRadio.) b) W funkcji sendComplaint, w bloku przygotowującym dane formularza – po pętli for (const item of dataFromHTML) dokładającej pola do fd – dodaj fragment dołączający parametr qrHash z adresu URL przy wysyłaniu zwrotu:
if (form.find('input[name="__action"]').val() === 'Order/ReturnAdd') {
    const qrHash = new URLSearchParams(globalThis.location.search).get('qrHash');
    if (qrHash) {
        fd.append('qrHash', qrHash);
    }
}
c) W tej samej funkcji sendComplaint, w callbacku success po pomyślnym wysłaniu, zamień fragment:
form.parents('.add-complaint-form-js').find('.success-message-js').removeClass('hidden-js');
na:
const container = form.parents('.add-complaint-form-js');
container.find('.success-message-js').removeClass('hidden-js');
container.children('.data-form__header').addClass('hidden-js');
d) Na samym końcu pliku js/layout-customerprofile0.js dodaj nowy handler obsługujący przełączanie sposobu zwrotu środków. Pokazuje on / ukrywa pole na numer konta bankowego:
$('body').on('change', '.refund-method-radio-js', function(e) {
    const radio = $(e.currentTarget);
    const form = radio.closest('.form-js');
    const wrapper = form.find('.account-number-wrapper-js');
    const input = wrapper.find('input[name="accountNumber"]');
    if (radio.val() === 'bankAccount' && radio.prop('checked')) {
        wrapper.removeClass('hidden-js');
        input.prop('disabled', false);
        input.prop('required', true);
    } else {
        wrapper.addClass('hidden-js');
        wrapper.find('.validation-required-js').addClass('hidden-js');
        wrapper.find('.form__input-info').removeClass('validation-error');
        input.removeClass('validation-error-js');
        input.prop('required', false);
        input.prop('disabled', true);
        input.val('');
    }
});

5. Modyfikacje plików SCSS profilu klienta

Poniższe style należy dodać do plików scss/static-elements/customer-profile/customer-profile-g.scss (wersja desktop) oraz scss/static-elements/customer-profile/customer-profile-m.scss (wersja mobile). Po zmianach pamiętaj o kompilacji – nie edytuj ręcznie wynikowych plików CSS.

Plik scss/static-elements/customer-profile/customer-profile-g.scss

a) Dla "przyklejonej" kolumny z akcjami reklamacji/zwrotu w tabeli produktów dodaj reguły wewnątrz selektora otaczającego tabelę zamówienia (tam, gdzie znajdują się style dla thead tr th):
thead tr th.open-complaint-form-container-js {
    position: sticky;
    right: 0;
    background: transparent;
    z-index: 5;

    &::before {
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        right: 0;
        width: 200px;
        background: linear-gradient(to right, rgba(255, 255, 255, 0), #fff 50%);
        pointer-events: none;
    }
}

td.complaint-actions-inline {
    white-space: nowrap;
    text-align: right;
    padding-left: 16px;
    padding-right: 8px;
    position: sticky;
    right: 0;
    background: #fff;
    z-index: 2;

    &::before {
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        left: -32px;
        width: 32px;
        background: linear-gradient(to right, rgba(255, 255, 255, 0), #fff 100%);
        pointer-events: none;
    }

    .pure-button.complaint-action-btn {
        display: inline-flex;
        background: transparent;
        border: 0;
        border-radius: 4px;
        color: $primaryColor;
        padding: 4px 8px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
        transition: background-color 150ms ease;

        &:hover,
        &:focus-visible {
            color: $primaryColor;
            background: rgba(0, 0, 0, 0.06);
        }

        & + .complaint-action-btn {
            margin-left: 8px;
        }
    }
}
b) Style hovera dla wiersza tabeli z akcjami reklamacji/zwrotu (umieść w głównym zakresie pliku):
.row {
    &:hover,
    &:focus-within,
    &.hovered-js {
        td.complaint-actions-inline {
            background: #F1DDDE;

            &::before {
                background: linear-gradient(to right, rgba(241, 221, 222, 0), #F1DDDE 100%);
            }
        }
    }

    &.set td.complaint-actions-inline {
        background: #ececec;

        &::before {
            background: linear-gradient(to right, rgba(236, 236, 236, 0), #ececec 100%);
        }
    }
}
c) Style banera informacyjnego (termin zwrotu / ukryte dane zamówienia):
.return-info-banner {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    margin: 0 0 24px 0;
    background: #E8F1F8;
    border: 1px solid #C7DCEE;
    border-radius: 5px;
    font-size: 14px;
    line-height: 20px;
    color: #2C3E50;

    .icon {
        flex-shrink: 0;
        fill: #4A90BC;
    }

    strong {
        font-weight: 600;
    }
}
d) Style sekcji wyboru sposobu zwrotu środków oraz radio-buttonów:
.refund-method-wrapper {
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin-bottom: 24px;

    &__title {
        color: $primaryColorFont;
        font-size: 14px;
        font-weight: 500;
        line-height: 20px;
    }
}

.refund-method-option {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;

    &__radio {
        display: none;

        &:checked ~ .refund-method-option__box {
            border-color: $primaryColor;

            &::after {
                content: "";
                display: block;
                width: 8px;
                height: 8px;
                border-radius: 50%;
                background: $primaryColor;
            }
        }
    }

    &__box {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 16px;
        height: 16px;
        border: 1px solid #767676;
        border-radius: 50%;
        flex-shrink: 0;
    }

    &__label {
        font-size: 14px;
        line-height: 20px;
    }
}
e) Style ekranu sukcesu po wysłaniu zwrotu (m.in. ikona, tytuł, lista kolejnych kroków):
.add-complaint-form-js .characters-length {
    margin-top: 0;
    bottom: 23px;
}

.add-complaint-form-js {
    .quantity__plus.disabled-js,
    .quantity__minus.disabled-js {
        opacity: 0.4;
    }
}

.add-complaint-form-js .data-form__header.return-success__header {
    margin-bottom: 8px;
}

.return-success {
    &__icon {
        display: flex;
        justify-content: center;
        margin-bottom: 16px;

        svg {
            fill: #2E7D32;
        }
    }

    &__title {
        text-align: center;
        font-size: 20px;
        font-weight: 600;
        line-height: 28px;
        color: $primaryColorFont;
        margin-bottom: 8px;
    }

    &__subtitle {
        text-align: center;
        font-size: 14px;
        line-height: 20px;
        color: $labelsColor;
        padding-bottom: 24px;
        border-bottom: 1px solid #E7E7E7;
        margin-bottom: 24px;
    }

    &__email-box {
        display: flex;
        align-items: flex-start;
        gap: 12px;
        padding: 12px 16px;
        background: #F0F6FC;
        border: 1px solid #D6E4F0;
        border-radius: 6px;
        margin-bottom: 24px;
        font-size: 14px;
        line-height: 20px;
        color: $primaryColorFont;

        svg {
            fill: #1976D2;
            flex-shrink: 0;
            margin-top: 2px;
        }
    }

    &__steps-title {
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
        color: $primaryColorFont;
        margin-bottom: 12px;
    }

    &__steps {
        margin: 0 0 24px;
        padding-left: 20px;
        font-size: 14px;
        line-height: 20px;
        color: $primaryColorFont;

        li {
            margin-bottom: 8px;

            &:last-child {
                margin-bottom: 0;
            }
        }
    }
}
f) Uzupełnij wnętrze selektora .file-attachements-wrapper o style dla kontenera pojedynczego załącznika:
.file-container {
    .file {
        align-items: center;
        font-weight: 400;
        color: $primaryColorFont;
        justify-content: flex-start;
    }

    .icon-js svg {
        fill: $primaryColorFont;
    }

    .clear-file-input-js {
        flex-shrink: 0;
        display: flex;
        align-items: center;

        svg {
            width: 14px;
            height: 14px;
            fill: $primaryColor;
        }
    }
}

Plik scss/static-elements/customer-profile/customer-profile-m.scss

Na końcu pliku customer-profile-m.scss dodaj reguły dopasowujące przyciski reklamacji/zwrotu do widoku mobilnego (układają się one wówczas jeden pod drugim):
.eshop__table-container {
    thead tr th.open-complaint-form-container-js::before {
        width: 100px;
    }

    td.complaint-actions-inline {
        .pure-button.complaint-action-btn {
            display: block;
            width: max-content;
            margin-left: auto;
            text-align: right;

            & + .complaint-action-btn {
                margin-left: auto;
                margin-top: 4px;
            }
        }
    }
}
Po wprowadzeniu wszystkich powyższych zmian w szablonie Rubin pamiętaj o kompilacji oraz minifikacji plików js i scss, zgodnie z artykułem dostępnym pod linkiem https://pomoc.comarchesklep.pl/artykul/kompilacja-i-minifikacja-plikow/.

Szablon Szafir

1. Tłumaczenia

W panelu administracyjnym sklepu dodaj nowe klucze tłumaczeń wymagane przez funkcjonalność szybkich zwrotów w szablonie Szafir. OrderReturnDeadlineInfo - PL: Zamówienie można zwrócić w ciągu {0} dni od daty dostawy. - EN: You can return the order within {0} days from the delivery date. - DE: Sie können die Bestellung innerhalb von {0} Tagen ab Lieferdatum zurückgeben. - FR: Vous pouvez retourner la commande dans les {0} jours suivant la date de livraison. RestrictedOrderViewInfo - PL: Wybrane dane zamówienia zostały ukryte ze względów bezpieczeństwa. Możesz zwrócić produkty bez logowania. - EN: Some order details are hidden for security reasons. You can return products without signing in. - DE: Einige Bestelldetails wurden aus Sicherheitsgründen ausgeblendet. Sie können Produkte ohne Anmeldung zurücksenden. - FR: Certaines informations de la commande ont été masquées pour des raisons de sécurité. Vous pouvez retourner des produits sans vous connecter. RefundMethod - PL: Sposób zwrotu środków - EN: Refund method - DE: Rückerstattungsmethode - FR: Méthode de remboursement RefundAsPaid - PL: Tak jak zapłacono - EN: As paid - DE: Wie bezahlt - FR: Comme payé RefundToBankAccount - PL: Na konto bankowe - EN: To bank account - DE: Auf Bankkonto - FR: Sur le compte bancaire BankAccountNumber - PL: Nr konta bankowego - EN: Bank account number - DE: Bankkontonummer - FR: Numéro de compte bancaire ReturnConfirmationTitle - PL: Gotowe! Przyjęliśmy Twoje zgłoszenie - EN: Done! We have received your request - DE: Fertig! Wir haben Ihre Anfrage erhalten - FR: Terminé! Nous avons reçu votre demande ReturnConfirmationInfo - PL: Przygotuj paczkę i odeślij ją do nas – wszystkie szczegóły znajdziesz poniżej. - EN: Prepare the package and send it back to us – all details can be found below. - DE: Bereiten Sie das Paket vor und senden Sie es an uns zurück – alle Details finden Sie unten. - FR: Préparez le colis et renvoyez-le nous – tous les détails se trouvent ci-dessous. ReturnConfirmationEmailSent - PL: Potwierdzenie zwrotu zostało wysłane na adres: - EN: Return confirmation has been sent to: - DE: Die Rücksendebestätigung wurde gesendet an: - FR: La confirmation de retour a été envoyée à: NextSteps - PL: Następne kroki - EN: Next steps - DE: Nächste Schritte - FR: Prochaines étapes ReturnStep1 - PL: Bezpiecznie zapakuj swoje produkty - EN: Safely pack your products - DE: Verpacken Sie Ihre Produkte sicher - FR: Emballez vos produits en toute sécurité ReturnStep2Address - PL: Wyślij paczkę na adres - EN: Send the package to - DE: Senden Sie das Paket an - FR: Envoyez le colis à ReturnStep3 - PL: Pieniądze zwrócimy niezwłocznie po otrzymaniu i sprawdzeniu Twojej paczki. - EN: We will refund the money promptly after receiving and checking your package. - DE: Wir erstatten das Geld umgehend nach Erhalt und Überprüfung Ihres Pakets. - FR: Nous rembourserons l'argent rapidement après réception et vérification de votre colis. ReturnInThreeSteps - PL: Zwróć towar w 3 krokach - EN: Return the product in 3 steps - DE: Geben Sie die Ware in 3 Schritten zurück - FR: Retournez la marchandise en 3 étapes ReturnWithoutReasonInfo - PL: Przysługuje Ci możliwość zwrotu bez podania przyczyny. - EN: You have the right to return the product without giving a reason. - DE: Sie haben das Recht, die Ware ohne Angabe von Gründen zurückzugeben. - FR: Vous avez le droit de retourner la marchandise sans donner de motif. OrEnterOrderNumber - PL: lub podaj numer zamówienia - EN: or enter the order number - DE: oder geben Sie die Bestellnummer ein - FR: ou saisissez le numéro de commande FillForm - PL: Wypełnij formularz - EN: Fill out the form - DE: Füllen Sie das Formular aus - FR: Remplissez le formulaire ReturnOnline - PL: zwrotu online - EN: online return - DE: Online-Rückgabe - FR: retour en ligne SendParcel - PL: Wyślij paczkę - EN: Send the parcel - DE: Paket senden - FR: Envoyer le colis SendParcelToOurAddress - PL: nadaj przesyłkę na nasz adres - EN: send the parcel to our address - DE: senden Sie das Paket an unsere Adresse - FR: envoyez le colis à notre adresse FastSimpleSecure - PL: Szybko, prosto i bezpiecznie. - EN: Fast, simple and secure. - DE: Schnell, einfach und sicher. - FR: Rapide, simple et sécurisé. ReadyForReturn - PL: Gotowy do zwrotu? - EN: Ready for return? - DE: Bereit zur Rückgabe? - FR: Prêt pour le retour ? ReadyForReturnInfo - PL: Kliknij poniżej, aby rozpocząć proces zwrotu. Przeprowadzimy Cię przez wszystkie kroki. - EN: Click below to start the return process. We will guide you through all the steps. - DE: Klicken Sie unten, um den Rückgabeprozess zu starten. Wir führen Sie durch alle Schritte. - FR: Cliquez ci-dessous pour lancer le processus de retour. Nous vous guiderons à travers toutes les étapes. StartReturn - PL: Rozpocznij zwrot - EN: Start return - DE: Rückgabe starten - FR: Commencer le retour ProductReturn - PL: Zwrot produktu - EN: Product return - DE: Produktrückgabe - FR: Retour du produit ProductReturnFormInfo - PL: Wprowadź dane zamówienia, aby zlokalizować zakup i rozpocząć proces zwrotu. Numer zamówienia znajdziesz w e-mailu z potwierdzeniem. - EN: Enter the order details to locate the purchase and start the return process. You will find the order number in the confirmation e-mail. - DE: Geben Sie die Bestelldaten ein, um den Kauf zu lokalisieren und den Rückgabeprozess zu starten. Die Bestellnummer finden Sie in der Bestätigungs-E-Mail. - FR: Saisissez les données de la commande pour localiser l'achat et démarrer le processus de retour. Vous trouverez le numéro de commande dans l'e-mail de confirmation. InvalidOrderNumber - PL: Błędny numer zamówienia. Spróbuj ponownie. - EN: Invalid order number. Please try again. - DE: Ungültige Bestellnummer. Bitte versuchen Sie es erneut. - FR: Numéro de commande incorrect. Veuillez réessayer. FindOrder - PL: Znajdź zamówienie - EN: Find order - DE: Bestellung finden - FR: Trouver la commande LoginToSeeOrdersAndReturn - PL: aby zobaczyć swoje zamówienia i dokonać zwrotu. - EN: to see your orders and make a return. - DE: um Ihre Bestellungen einzusehen und eine Rückgabe vorzunehmen. - FR: pour voir vos commandes et effectuer un retour. RefundLookupError - PL: Wystąpił błąd podczas wyszukiwania zamówienia. Spróbuj ponownie później. - EN: An error occurred while searching for the order. Please try again later. - DE: Bei der Suche nach der Bestellung ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut. - FR: Une erreur s'est produite lors de la recherche de la commande. Veuillez réessayer plus tard.

2. Nowa strona Szybkie zwroty

Funkcjonalność szybkich zwrotów wymaga utworzenia dodatkowej strony statycznej refunds. Wykonaj poniższe kroki.

Plik refunds.html w katalogu głównym szablonu

W katalogu głównym szablonu utwórz nowy plik refunds.html z następującą zawartością:
{% extends '_layout.html' %}

{% block content %}
{% include 'static-elements/refunds/refunds.html' %}
{% endblock %}

Plik static-elements/refunds/refunds.html

W folderze static-elements utwórz nowy katalog refunds, a w nim plik refunds.html:
<section class="refunds refunds-js form-js">
    <p class="refunds-header refunds-initial-view-js">{{ translations.Returns }}</p>
    <div class="refunds-intro refunds-initial-view-js">
        <div class="refunds-info">
            <p class="refunds-info-title">{{ translations.ReturnInThreeSteps }}</p>
            <p class="refunds-info-desc">{{ translations.ReturnWithoutReasonInfo }}</p>
            <ol class="refunds-steps">
                <li class="refunds-steps-item">
                    <span class="refunds-steps-number">1</span>
                    <p class="refunds-steps-text"><strong>{{ translations.SignIn }}</strong> {{ translations.OrEnterOrderNumber }}</p>
                </li>
                <li class="refunds-steps-item">
                    <span class="refunds-steps-number">2</span>
                    <p class="refunds-steps-text"><strong>{{ translations.FillForm }}</strong> {{ translations.ReturnOnline }}</p>
                </li>
                <li class="refunds-steps-item">
                    <span class="refunds-steps-number">3</span>
                    <p class="refunds-steps-text"><strong>{{ translations.SendParcel }}</strong> - {{ translations.SendParcelToOurAddress }}</p>
                </li>
            </ol>
            <p class="refunds-info-hint">{{ translations.FastSimpleSecure }}</p>
        </div>
        <div class="refunds-cta">
            <p class="refunds-cta-title">{{ translations.ReadyForReturn }}</p>
            <p class="refunds-cta-desc">{{ translations.ReadyForReturnInfo }}</p>
            {% if usr.Authenticated -%}
            <a class="refunds-cta-button" href="{{ config.DefinedPages.CustomerProfile.Url }}?tab=orders" rel="nofollow" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </a>
            {% else -%}
            <button class="refunds-cta-button start-refund-js" type="button" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </button>
            {% endif -%}
        </div>
    </div>
    {% unless usr.Authenticated -%}
    <div class="refunds-form-section refund-form-view-js hidden-js">
        <div class="refunds-form">
            <p class="refunds-form-title">{{ translations.ProductReturn }}</p>
            <p class="refunds-form-desc">{{ translations.ProductReturnFormInfo }}</p>
            <div class="refund-form-js" data-cp-url="{{ config.DefinedPages.CustomerProfile.Url }}">
                <div class="message-bar-ui warning-bar-ui refund-lookup-error-js hidden-js">{{ translations.RefundLookupError }}</div>
                <div class="form__input-wrapper">
                    <label class="form__input-info form__input-info-js" for="refundOrderNumber" data-type="text">{{ translations.OrderNumber }} <span class="required-ui">*</span></label>
                    <input id="refundOrderNumber" class="form__input-value form__input-value-js" maxlength="50" name="orderNumber" required="" type="text" aria-label="{{ translations.OrderNumber }}" />
                    <span class="error-ui validation-info-js validation-required-js hidden-js">{{ translations.RequiredField }}</span>
                </div>
                <div class="form__input-wrapper">
                    <label class="form__input-info form__input-info-js" for="refundEmail" data-type="email">{{ translations.EmailAddress }} <span class="required-ui">*</span></label>
                    <input id="refundEmail" class="form__input-value form__input-value-js" autocomplete="email" maxlength="192" name="email" required="" type="email" aria-label="{{ translations.EmailAddress }}" />
                    <span class="error-ui validation-info-js validation-required-js hidden-js">{{ translations.RequiredField }}</span>
                    <span class="error-ui validation-info-js email-valid-js hidden-js">{{ translations.FillProperEmail }}</span>
                </div>
                <div class="required-fields-info-ui form__required-fields-info"><span class="required-ui">* </span>{{ translations.RequiredFields }}</div>
                <button class="refunds-form-submit refund-form-submit-js" type="button" aria-label="{{ translations.FindOrder }}">
                    {{ translations.FindOrder }}
                </button>
                <p class="refunds-form-login-info">{{ translations.HaveAccount }} <a class="refunds-form-login-link" href="{{ config.DefinedPages.Login.Url }}" rel="nofollow">{{ translations.SignIn }}</a>, {{ translations.LoginToSeeOrdersAndReturn }}</p>
            </div>
        </div>
    </div>
    {% endunless -%}
</section>

Plik js/layout0.js – kod obsługi formularza zwrotu

Na końcu pliku js/layout0.js dodaj poniższy kod odpowiedzialny za walidację i wysłanie formularza wyszukiwania zamówienia (dla niezalogowanego klienta). Po zapisaniu pliku pamiętaj o zminifikowaniu go do layout0.min.js.
const refunds = {
    findRefundOrder(orderNumber, email) {
        return $.post('', {
            __action: 'Order/QuickReturnLookup',
            orderId: orderNumber,
            email: email,
            __csrf: __CSRF
        });
    },

    showForm() {
        document.querySelectorAll('.refunds-initial-view-js').forEach((el) => el.classList.add('hidden-js'));
        document.querySelectorAll('.refund-form-view-js').forEach((el) => el.classList.remove('hidden-js'));
        document.querySelector('.refund-form-js input[name="orderNumber"]')?.focus();
    },

    clearFieldError(input) {
        input.classList.remove('validation-error-ui', 'validation-error-lq');
        input.closest('.form__input-wrapper')
            ?.querySelectorAll('.error-ui')
            .forEach((el) => el.classList.add('hidden-js'));
    },

    markFieldError(input, errorSelector) {
        input.classList.add('validation-error-ui', 'validation-error-lq');
        input.closest('.form__input-wrapper')?.querySelector(errorSelector)?.classList.remove('hidden-js');
    },

    validateForm({ orderInput, emailInput }) {
        const orderValue = orderInput.value.trim();
        const emailValue = emailInput.value.trim();
        const emailRegex = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w{2,}$/;
        let hasError = false;

        if (orderValue.length === 0) {
            refunds.markFieldError(orderInput, '.validation-required-js');
            hasError = true;
        }

        if (emailValue.length === 0) {
            refunds.markFieldError(emailInput, '.validation-required-js');
            hasError = true;
        } else if (!emailRegex.test(emailValue)) {
            refunds.markFieldError(emailInput, '.email-valid-js');
            hasError = true;
        }

        return { hasError, orderValue };
    },

    async submitForm(button) {
        const form = button.closest('.refund-form-js');
        if (!form) {
            return;
        }
        const orderInput = form.querySelector('input[name="orderNumber"]');
        const emailInput = form.querySelector('input[name="email"]');

        form.querySelectorAll('.error-ui').forEach((el) => el.classList.add('hidden-js'));
        form.querySelector('.refund-lookup-error-js')?.classList.add('hidden-js');
        form.querySelectorAll('.form__input-value').forEach((el) => {
            el.classList.remove('validation-error-ui', 'validation-error-lq');
        });

        const { hasError, orderValue } = refunds.validateForm({ orderInput, emailInput });
        if (hasError) {
            return;
        }

        button.disabled = true;
        const errorBar = form.querySelector('.refund-lookup-error-js');
        try {
            const result = await refunds.findRefundOrder(orderValue, emailInput.value.trim());
            const action = result.action;
            if (action.Redirect302) {
                globalThis.location.href = action.Redirect302;
                return;
            }
            if (errorBar) {
                errorBar.textContent = action.Message;
                errorBar.classList.remove('hidden-js');
            }
        } catch (error) {
            console.error('Refund order lookup failed.', error);
            errorBar?.classList.remove('hidden-js');
        } finally {
            button.disabled = false;
        }
    }
};

js.delegate(document.body, 'click', '.start-refund-js', () => refunds.showForm());

js.delegate(document.body, 'input', '.refund-form-js .form__input-value', function () {
    refunds.clearFieldError(this);
});

js.delegate(document.body, 'click', '.refund-form-submit-js', function (event) {
    event.preventDefault();
    refunds.submitForm(this);
});

js.delegate(document.body, 'keydown', '.refund-form-js input', function (event) {
    if (event.key !== 'Enter') {
        return;
    }
    event.preventDefault();
    this.closest('.refund-form-js')?.querySelector('.refund-form-submit-js')?.click();
});

Pliki SCSS strony Szybkie zwroty

W folderze scss/static-elements utwórz nowy katalog refunds i umieść w nim dwa pliki: refunds-g.scss (style desktop) oraz refunds-m.scss (style mobilne). scss/static-elements/refunds/refunds-g.scss:
.refunds {
    padding: 40px 110px;
    background-color: $bgColor;
    color: $primaryColorFont;

    .refunds-header {
        display: block;
        width: 100%;
        margin: 0 0 24px;
        color: $primaryColorFont;
        text-align: left;
        font-size: 32px;
        font-weight: 500;
        line-height: 42px;
        letter-spacing: 0.8px;
    }

    .refunds-intro {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 32px;
        margin-bottom: 40px;
    }

    .refunds-info {
        align-self: flex-start;
        width: 100%;
        max-width: 800px;
        display: flex;
        flex-direction: column;
        gap: 16px;
        color: $primaryColorFont;

        @media screen and (min-width: 769px) and (max-width: 1279px) {
            max-width: 100%;
        }
    }

    .refunds-info-title {
        margin: 0;
        font-size: 20px;
        font-weight: 500;
        line-height: 28px;
        letter-spacing: 0.4px;
    }

    .refunds-info-desc {
        margin: 0;
        font-size: 16px;
        font-weight: 400;
        line-height: 24px;
        letter-spacing: 0.3px;
    }

    .refunds-info-hint {
        margin: 4px 0 0;
        color: $secondaryColorFont;
        font-size: 12px;
        font-weight: 400;
        line-height: 20px;
        letter-spacing: 0.2px;
    }

    .refunds-steps {
        list-style: none;
        margin: 0;
        padding: 0;
        display: flex;
        flex-direction: column;
        gap: 12px;
    }

    .refunds-steps-item {
        display: flex;
        align-items: center;
        gap: 12px;
    }

    .refunds-steps-number {
        flex-shrink: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        border-radius: 50%;
        background-color: $formsBgColor;
        color: $primaryColor;
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
    }

    .refunds-steps-text {
        margin: 0;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        letter-spacing: 0.3px;

        strong {
            font-weight: 600;
        }
    }

    .refunds-cta {
        box-sizing: border-box;
        width: 100%;
        max-width: 578px;
        padding: 32px 40px;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 12px;
        background-color: $bgColor;
        border: 1px solid $lightBorderColor;
    }

    .refunds-cta-title {
        margin: 0;
        text-align: center;
        font-size: 22px;
        font-weight: 500;
        line-height: 30px;
        letter-spacing: 0.5px;
        color: $primaryColorFont;
    }

    .refunds-cta-desc {
        margin: 0;
        text-align: center;
        color: $secondaryColorFont;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        letter-spacing: 0.3px;
    }

    .refunds-cta-button,
    .refunds-form-submit {
        display: inline-block;
        width: 100%;
        margin-top: 8px;
        padding: 12px 16px;
        background: $btnSolidBgColor;
        color: $btnSolidTextColor;
        border: 1px solid $btnSolidBgColor;
        font-size: 14px;
        font-weight: 500;
        line-height: 20px;
        text-align: center;
        text-decoration: none;
        cursor: pointer;
        transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;

        &:hover,
        &:focus {
            background: $btnSolidHoverBgColor;
            color: $btnSolidHoverTextColor;
            border-color: $btnSolidHoverBgColor;
        }

        &[disabled],
        &[disabled]:hover {
            background: $btnDisabledBg;
            border-color: $btnDisabledFont;
            color: $btnDisabledFont;
            cursor: default;
        }
    }

    .refunds-form-section {
        display: flex;
        justify-content: center;
        width: 100%;
        margin-top: 32px;
        margin-bottom: 40px;
    }

    .refunds-form {
        box-sizing: border-box;
        width: 100%;
        max-width: 578px;
        padding: 32px 40px;
        background-color: $bgColor;
        border: 1px solid $lightBorderColor;
    }

    .refunds-form-title {
        margin: 0 0 8px;
        font-size: 22px;
        font-weight: 500;
        line-height: 30px;
        letter-spacing: 0.5px;
        color: $primaryColorFont;
    }

    .refunds-form-desc {
        margin: 0 0 20px;
        color: $secondaryColorFont;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        letter-spacing: 0.3px;
    }

    .refund-form-js {
        display: flex;
        flex-direction: column;

        .form__input-wrapper {
            position: relative;
            margin-bottom: 16px;

            .form__input-info {
                display: block;
                margin: 0 0 4px;
                color: $primaryColorFont;
                font-size: 13px;
                font-weight: 400;
                line-height: 18px;
            }

            input {
                width: 100%;
                height: 36px;
                margin: 0;
                padding: 0 10px;
                box-sizing: border-box;
                border: 1px solid $lightBorderColor;
                font-size: 14px;

                &::placeholder {
                    font-size: 14px;
                }

                &.validation-error-ui,
                &.validation-error-lq {
                    border-color: $dangerColor;
                    color: $dangerColor;
                }
            }

            .error-ui {
                position: static;
                display: block;
                margin: 4px 0 0;
                padding: 0;
                text-align: left;
                color: $dangerColor;
                font-size: 12px;
                font-weight: 400;
                line-height: 16px;
            }
        }

        .form__required-fields-info {
            margin: 4px 0 16px;
            color: $primaryColorFont;
            font-size: 12px;
            font-weight: 300;
            line-height: 18px;
        }
    }

    .refunds-form-login-info {
        margin: 12px 0 0;
        text-align: center;
        color: $primaryColorFont;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
    }

    .refunds-form-login-link {
        color: $primaryColor;
        font-weight: 600;
        cursor: pointer;
        text-decoration: none;

        &:hover {
            text-decoration: underline;
        }
    }
}
scss/static-elements/refunds/refunds-m.scss:
@media screen and (max-width: 768px) {
    .refunds {
        padding: 20px 16px;

        .refunds-header {
            font-size: 24px;
            line-height: 32px;
            margin-bottom: 16px;
        }

        .refunds-intro {
            gap: 24px;
            margin-bottom: 24px;
        }

        .refunds-info {
            max-width: 100%;
            gap: 12px;
        }

        .refunds-info-title {
            font-size: 18px;
            line-height: 24px;
        }

        .refunds-info-desc {
            font-size: 14px;
            line-height: 22px;
        }

        .refunds-steps-item {
            align-items: flex-start;
            gap: 10px;
        }

        .refunds-steps-number {
            width: 28px;
            height: 28px;
            font-size: 13px;
        }

        .refunds-steps-text {
            font-size: 13px;
            line-height: 20px;
            padding-top: 3px;
        }

        .refunds-cta {
            padding: 24px;
        }

        .refunds-cta-title {
            font-size: 20px;
            line-height: 28px;
        }

        .refunds-form-section {
            margin-top: 20px;
            margin-bottom: 24px;
        }

        .refunds-form {
            padding: 24px;
            border: none;
        }

        .refunds-form-title {
            font-size: 20px;
            line-height: 28px;
        }

        .refunds-form-desc {
            margin-bottom: 16px;
        }

        .refunds-form-login-info {
            font-size: 13px;
        }
    }
}

3. Modyfikacje istniejących plików HTML

partials/customer-profile/orders/order-details.html

W pliku partials/customer-profile/orders/order-details.html wykonaj poniższe zmiany. a) Blok z przyciskami akcji nawigacji zamówienia (zawierający {% if order.EditingAllowed -%}, opcje anulowania, edycji, ponowienia, druku itp.) opakuj warunkiem ukrywającym go dla zamówień typu restricted. Bezpośrednio po linii z elementem <li class="active-ui only-text-ui ...">...</li> wstaw:
{% unless order.Restricted -%}
a tuż przed zamykającym znacznikiem </ul> tej samej nawigacji dodaj:
{% endunless -%}
b) Na początku kontenera messages-container-lq messages-container-ui (zaraz po jego otwarciu) dodaj baner informujący o ukrytych danych zamówienia:
{% if order.Restricted -%}
<div class="message-bar-ui no-margin-ui">
    <i class="not-clickable-ui ti-info-alt"></i>
    {{ translations.RestrictedOrderViewInfo }}
</div>
{% endif -%}
c) Na końcu tego samego kontenera (przed zamykającym </div>) dodaj baner informujący o terminie zwrotu wraz z przypisaniem flagi complaintsOrReturnsEnabled:
{% if config.Complaints.ComplaintsEnabled or config.Complaints.ReturnsEnabled -%}
{% assign complaintsOrReturnsEnabled = true -%}
{% endif -%}

{% if order.Status == 3 and complaintsOrReturnsEnabled -%}
<div class="message-bar-ui no-margin-ui">
    <i class="not-clickable-ui ti-info-alt"></i>
    {{translations.OrderReturnDeadlineInfo | Format: config.Complaints.DaysToReturn}}
</div>
{% endif -%}
d) Blok z przyciskami akcji wewnątrz info-container-js (zawierający przyciski order.CanCancel, edycji, ponowienia zakupu itd.) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}. Wstaw {% unless order.Restricted -%} bezpośrednio przed pierwszym {% if order.CanCancel -%}, a {% endunless -%} po zamykającym warunku odpowiedzialnym za popup potwierdzenia ({% include 'partials/common/confirmation-popup.html' with 0 -%}). e) W sekcji wyświetlającej dokumenty zamówienia zamień:
{% if order.Documents %}
na:
{% if order.Documents and order.Restricted == false %}
f) We wszystkich miejscach wyświetlających numer telefonu klienta zamień warunki sprawdzające jedynie pusty ciąg na warunki sprawdzające również wartość null. Zamień każde wystąpienie:
{% if order.Customer.DeliveryAddress.PhoneNo != '' -%}
na:
{% if order.Customer.DeliveryAddress.PhoneNo != null and order.Customer.DeliveryAddress.PhoneNo != '' -%}
g) Każdą sekcję z tytułem translations.ChoosenDocument opakuj warunkiem ukrywającym ją dla zamówień restricted. Wstaw {% unless order.Restricted -%} bezpośrednio przed <div class="name-ui mt20-ui">{{ translations.ChoosenDocument }}</div> oraz {% endunless -%} po jej zamykającym </div>. h) W sekcji wyświetlającej alternatywny adres dostawy zamień warunek {% else -%} (bezpośrednio przed order-info-item-ui z translations.DelivAddress) na bardziej restrykcyjny:
{% elseif order.Customer.DeliveryAddress != null -%}
i) W sekcji danych do faktury zamień warunek wyświetlania NIP-u/TIN-u. Zamień:
{% elseif order.Customer.TIN != '' -%}
na:
{% elseif order.Customer.TIN != null and order.Customer.TIN != '' -%}
j) W sekcji załączników zamówienia (kontener attachements-ui remarks-ui) zamień warunek otaczający. Zamień:
{% if config.Orders.AttachmentsEnabled -%}
na:
{% if config.Orders.AttachmentsEnabled and order.Restricted == false -%}
k) W sekcji zamówień powiązanych (kontener remarks-ui eshop-order-ui) zamień:
{% if order.RelatedOrders -%}
na:
{% if order.RelatedOrders and order.Restricted == false -%}

partials/customer-profile/complaints/complaint-form.html

W pliku partials/customer-profile/complaints/complaint-form.html wprowadź poniższe zmiany. a) W kontenerze amount-stepper-container-ui amount-stepper-container-lq (wewnątrz warunku {% if type != 'set-return' -%}) na samym początku dodaj etykietę widoczną tylko dla zwrotów:
{% unless complaint -%}
<span class="amount-stepper-label-ui">{{ translations.Quantity }}:</span>
{% endunless -%}
b) Bezpośrednio po zamknięciu kontenera amount-stepper-container-ui (po jego </div> i odpowiadającym {% endif -%}) dodaj sekcję wyboru sposobu zwrotu środków – widoczną tylko w formularzu zwrotu:
{% unless complaint -%}
<div class="refund-method-container-ui refund-method-container-js">
    <label class="label-ui" for="refundMethod">{{ translations.RefundMethod }} <span class="required-ui">*</span></label>
    <div>
        <span class="select-background-ui">
            <select id="refundMethod" class="refund-method-select-js" name="refundMethod" aria-label="{{ translations.RefundMethod }}">
                <option selected="selected" value="original">{{ translations.RefundAsPaid }} {% if order.Payment.Name and order.Payment.Name != "" -%} ({{ order.Payment.Name }}){% endif -%}</option>
                <option value="bank">{{ translations.RefundToBankAccount }}</option>
            </select>
        </span>
        <i class="ti-angle-down select-arrow-ui"></i>
    </div>
    <div class="bank-account-container-ui bank-account-container-js hidden-js">
        <label class="label-ui" for="bankAccountNumber">{{ translations.BankAccountNumber }} <span class="required-ui">*</span></label>
        <div>
            <input id="bankAccountNumber" disabled="disabled" name="bankAccountNumber" type="text" placeholder="{{ translations.BankAccountNumber }}" aria-label="{{ translations.BankAccountNumber }}" />
            <span class="error-ui validation-info-js validation-required-js hidden-js">{{ translations.RequiredField }}</span>
        </div>
    </div>
</div>
{% endunless -%}
c) Komunikat sukcesu wyświetlany po wysłaniu formularza ma być inny dla reklamacji, a inny dla zwrotu. Znajdź kontener <div class="success-message-js hidden-js"> wraz z jego dotychczasową zawartością (komunikat ComplaintAdded + successInfo):
<div class="success-message-js hidden-js">
    <div class="complaint-added-ui">
        <i class="va-mid-ui ti-check"></i>
        <span class="va-mid-ui line-height-1-ui">
            {{ translations.ComplaintAdded }}
        </span>
    </div>
    <div class="info-ui">{{ successInfo }}</div>
</div>
i zastąp go nową, rozszerzoną wersją z dwoma wariantami (reklamacja / zwrot):
<div class="success-message-js hidden-js">
    {% if complaint -%}
    <div class="complaint-added-ui">
        <i class="va-mid-ui ti-check"></i>
        <span class="va-mid-ui line-height-1-ui">
            {{ translations.ComplaintAdded }}
        </span>
    </div>
    <div class="info-ui">{{ successInfo }}</div>
    {% else -%}
    <div class="return-success-popup-ui">
        <div class="return-success-icon-ui">
            <i class="ti-check"></i>
        </div>
        <div class="return-success-title-ui">{{ translations.ReturnConfirmationTitle }}</div>
        <div class="return-success-desc-ui">{{ translations.ReturnConfirmationInfo }}</div>
        {% if order.Customer.Email and order.Customer.Email != "" -%}
        <div class="return-success-email-info-ui">
            <i class="ti-info-alt"></i>
            {{ translations.ReturnConfirmationEmailSent }} <strong>{{ order.Customer.Email }}</strong>
        </div>
        {% endif -%}
        <div class="return-success-steps-title-ui">{{ translations.NextSteps }}</div>
        <ol class="return-success-steps-ui">
            <li>{{ translations.ReturnStep1 }}</li>
            <li>{{ translations.ReturnStep2Address }}: {{ config.Shop.Address.Street }} {{ config.Shop.Address.StreetNo }}{% if config.Shop.Address.UnitNo and config.Shop.Address.UnitNo != "" -%}/{{ config.Shop.Address.UnitNo }}{% endif -%}, {{ config.Shop.Address.ZipCode }} {{ config.Shop.Address.City }}</li>
            <li>{{ translations.ReturnStep3 }}</li>
        </ol>
        <div class="return-success-actions-ui">
            <button class="btn-ui return-success-close-ui hide-container-js closing-modal-js" aria-label="{{ translations.Close }}">
                {{ translations.Close }}
            </button>
        </div>
    </div>
    {% endif -%}
</div>

4. Modyfikacje pliku js/init-ui2.js

Poniższe zmiany dotyczą pliku js/init-ui2.js (po edycji pamiętaj o zminifikowaniu go do init-ui2.min.js). a) Tuż po linii rejestrującej handler openComplaintForm:
js.delegate(document.body, 'click', '.open-complaint-form-js', openComplaintForm);
dodaj poniższy handler obsługujący przełączanie sposobu zwrotu środków – pokazuje on / ukrywa pole na numer konta bankowego:
js.delegate(document.body, 'change', '.refund-method-select-js', function() {
    const container = js.parents(this, 'refund-method-container-js');
    if(!container) return;
    const bankWrapper = container.getElementsByClassName('bank-account-container-js')[0];
    if(!bankWrapper) return;
    const bankInput = bankWrapper.querySelector('input[name="bankAccountNumber"]');
    const validationMsg = bankWrapper.getElementsByClassName('validation-required-js')[0];
    if(this.value === 'bank') {
        bankWrapper.classList.remove('hidden-js');
        if(bankInput) {
            bankInput.disabled = false;
            bankInput.required = true;
        }
    } else {
        bankWrapper.classList.add('hidden-js');
        if(bankInput) {
            bankInput.disabled = true;
            bankInput.required = false;
            bankInput.value = '';
            bankInput.classList.remove('validation-error-lq', 'validation-error-ui');
        }
        if(validationMsg) validationMsg.classList.add('hidden-js');
    }
});
b) W funkcji sendComplaint, bezpośrednio po pętli for (var i=0; i<dataFromHTML.length; i++) dokładającej pola do fd, dodaj fragment dołączający parametr qrHash z adresu URL przy wysyłaniu zwrotu:
if (form.find('input[name="__action"]').val() === 'Order/ReturnAdd') {
    var qrHash = new URLSearchParams(globalThis.location.search).get('qrHash');
    if (qrHash) {
        fd.append('qrHash', qrHash);
    }
}

5. Modyfikacje pliku scss/globals/_globals2.scss

W pliku scss/globals/_globals2.scss wewnątrz selektora opakowującego (tego, który zawiera m.in. .note-ui) dodaj poniższe reguły. Po zmianach pamiętaj o kompilacji SCSS – nie edytuj ręcznie wynikowych plików CSS. a) Style etykiety ilości oraz kontenera wyboru sposobu zwrotu środków (wstaw w sąsiedztwie istniejących reguł sekcji formularza reklamacji/zwrotu):
.amount-stepper-label-ui {
    margin-right: 10px;
    vertical-align: middle;
}

.refund-method-container-ui {
    margin-bottom: 20px;

    .bank-account-container-ui {
        margin-top: 10px;

        input {
            width: 100%;
        }
    }
}
b) Style ekranu sukcesu po wysłaniu zwrotu (ikona, tytuł, lista kolejnych kroków, sekcja z e-mailem i przyciskiem zamknięcia):
.return-success-popup-ui {
    padding: 30px 20px 20px;

    .return-success-icon-ui {
        width: 60px;
        height: 60px;
        border-radius: 50%;
        border: 2px solid #68a204;
        margin: 0 auto 20px;
        display: flex;
        align-items: center;
        justify-content: center;

        i {
            color: #68a204;
            font-size: 26px;
        }
    }

    .return-success-title-ui {
        font-size: 18px;
        font-weight: 500;
        text-align: center;
        margin-bottom: 10px;
    }

    .return-success-desc-ui {
        font-size: 14px;
        color: $primaryColorFont;
        text-align: center;
        margin-bottom: 20px;
    }

    .return-success-email-info-ui {
        background-color: $bgColor;
        border: 1px solid $lightBorderColor;
        padding: 12px;
        border-radius: 4px;
        font-size: 14px;
        margin-bottom: 20px;
        display: flex;
        align-items: flex-start;

        i {
            margin-right: 10px;
            color: $primaryColorFont;
            font-size: 16px;
            line-height: 1.4;
        }

        strong {
            display: block;
        }
    }

    .return-success-steps-title-ui {
        font-weight: 500;
        margin-bottom: 10px;
    }

    .return-success-steps-ui {
        padding-left: 20px;
        margin: 0 0 20px;
        font-size: 14px;

        li {
            margin-bottom: 8px;
            padding-left: 5px;
        }
    }

    .return-success-actions-ui {
        border-top: 1px solid $lightBorderColor;
        padding-top: 15px;
        text-align: right;

        .return-success-close-ui {
            padding: 10px 30px;
        }
    }
}
Po wprowadzeniu wszystkich powyższych zmian w szablonie Szafir pamiętaj o kompilacji oraz minifikacji plików js i scss, zgodnie z artykułem dostępnym pod linkiem https://pomoc.comarchesklep.pl/artykul/kompilacja-i-minifikacja-plikow/.

Szablon Topaz / One Page Shop

Zmiany opisane poniżej dotyczą szablonu Topaz. Szablon One Page Shop ma praktycznie identyczną strukturę – wszystkie modyfikacje dotyczą tych samych plików i mają tę samą zawartość. Wystarczy zastosować poniższą instrukcję w plikach szablonu OPS pod tymi samymi ścieżkami.

1. Tłumaczenia

W panelu administracyjnym sklepu dodaj nowe klucze tłumaczeń wymagane przez funkcjonalność szybkich zwrotów w szablonie Topaz / OPS. RestrictedOrderViewInfo - PL: Wybrane dane zamówienia zostały ukryte ze względów bezpieczeństwa. Możesz zwrócić produkty bez logowania. - EN: Some order details are hidden for security reasons. You can return products without signing in. - DE: Einige Bestelldetails wurden aus Sicherheitsgründen ausgeblendet. Sie können Produkte ohne Anmeldung zurücksenden. - FR: Certaines informations de la commande ont été masquées pour des raisons de sécurité. Vous pouvez retourner des produits sans vous connecter. Prf_ReturnPeriodInfo - PL: Zamówienie można zwrócić w ciągu {0} dni od daty dostawy. - EN: The order can be returned within {0} days from the delivery date. - DE: Die Bestellung kann innerhalb von {0} Tagen ab dem Lieferdatum zurückgegeben werden. - FR: La commande peut être retournée dans un délai de {0} jours à compter de la date de livraison. ComplaintSuccessTitle - PL: Gotowe! Przyjęliśmy Twoje zgłoszenie - EN: Done! We have received your request - DE: Fertig! Wir haben Ihre Meldung erhalten - FR: C'est fait ! Nous avons reçu votre demande ComplaintSuccessDescription - PL: Przygotuj paczkę i odeślij ją do nas – wszystkie szczegóły znajdziesz poniżej. - EN: Prepare the parcel and send it back to us – you will find all the details below. - DE: Bereiten Sie das Paket vor und senden Sie es an uns zurück – alle Details finden Sie unten. - FR: Préparez le colis et renvoyez-le-nous – vous trouverez tous les détails ci-dessous. ComplaintSuccessConfirmationSent - PL: Potwierdzenie zwrotu zostało wysłane na adres: - EN: The return confirmation has been sent to: - DE: Die Rückgabebestätigung wurde an folgende Adresse gesendet: - FR: La confirmation de retour a été envoyée à : ComplaintSuccessStepsTitle - PL: Następne kroki - EN: Next steps - DE: Nächste Schritte - FR: Étapes suivantes ComplaintSuccessStep1 - PL: Bezpiecznie zapakuj swoje produkty - EN: Pack your products securely - DE: Verpacken Sie Ihre Produkte sicher - FR: Emballez vos produits en toute sécurité ComplaintSuccessStep2 - PL: Wyślij paczkę na adres: - EN: Send the parcel to: - DE: Senden Sie das Paket an folgende Adresse: - FR: Envoyez le colis à l'adresse : ComplaintSuccessStep3 - PL: Pieniądze zwrócimy niezwłocznie po otrzymaniu i sprawdzeniu Twojej paczki. - EN: We will refund the money immediately after receiving and inspecting your parcel. - DE: Wir erstatten den Betrag unverzüglich nach Erhalt und Prüfung Ihres Pakets. - FR: Nous rembourserons l'argent immédiatement après réception et vérification de votre colis. ReturnInThreeSteps - PL: Zwróć towar w 3 krokach - EN: Return the product in 3 steps - DE: Geben Sie die Ware in 3 Schritten zurück - FR: Retournez la marchandise en 3 étapes ReturnWithoutReasonInfo - PL: Przysługuje Ci możliwość zwrotu bez podania przyczyny. - EN: You have the right to return the product without giving a reason. - DE: Sie haben das Recht, die Ware ohne Angabe von Gründen zurückzugeben. - FR: Vous avez le droit de retourner la marchandise sans donner de motif. OrEnterOrderNumber - PL: lub podaj numer zamówienia - EN: or enter the order number - DE: oder geben Sie die Bestellnummer ein - FR: ou entrez le numéro de commande FillForm - PL: Wypełnij formularz - EN: Fill out the form - DE: Füllen Sie das Formular aus - FR: Remplissez le formulaire ReturnOnline - PL: zwrotu online - EN: online return - DE: Online-Rückgabe - FR: retour en ligne SendParcel - PL: Wyślij paczkę - EN: Send the parcel - DE: Senden Sie das Paket - FR: Envoyez le colis SendParcelToOurAddress - PL: nadaj przesyłkę na nasz adres - EN: send the parcel to our address - DE: senden Sie das Paket an unsere Adresse - FR: envoyez le colis à notre adresse FastSimpleSecure - PL: Szybko, prosto i bezpiecznie. - EN: Fast, simple and secure. - DE: Schnell, einfach und sicher. - FR: Rapide, simple et sûr. ReadyForReturn - PL: Gotowy do zwrotu? - EN: Ready for return? - DE: Bereit zur Rückgabe? - FR: Prêt pour le retour ? ReadyForReturnInfo - PL: Kliknij poniżej, aby rozpocząć proces zwrotu. Przeprowadzimy Cię przez wszystkie kroki. - EN: Click below to start the return process. We will guide you through all the steps. - DE: Klicken Sie unten, um den Rückgabeprozess zu starten. Wir führen Sie durch alle Schritte. - FR: Cliquez ci-dessous pour commencer le processus de retour. Nous vous guiderons à chaque étape. StartReturn - PL: Rozpocznij zwrot - EN: Start return - DE: Rückgabe starten - FR: Commencer le retour ProductReturn - PL: Zwrot produktu - EN: Product return - DE: Produktrückgabe - FR: Retour du produit ProductReturnFormInfo - PL: Wprowadź dane zamówienia, aby zlokalizować zakup i rozpocząć proces zwrotu. Numer zamówienia znajdziesz w e-mailu z potwierdzeniem. - EN: Enter the order details to locate the purchase and start the return process. You will find the order number in the confirmation e-mail. - DE: Geben Sie die Bestelldaten ein, um den Kauf zu lokalisieren und den Rückgabeprozess zu starten. Die Bestellnummer finden Sie in der Bestätigungs-E-Mail. - FR: Saisissez les données de la commande pour localiser l'achat et démarrer le processus de retour. Vous trouverez le numéro de commande dans l'e-mail de confirmation. FindOrder - PL: Znajdź zamówienie - EN: Find order - DE: Bestellung finden - FR: Trouver la commande RefundLookupError - PL: Wystąpił błąd podczas wyszukiwania zamówienia. Spróbuj ponownie później. - EN: An error occurred while searching for the order. Please try again later. - DE: Fehler beim Suchen nach der Bestellung. Versuchen Sie es später erneut. - FR: Une erreur s'est produite lors de la recherche de la commande. Veuillez réessayer plus tard. LoginToSeeOrdersAndReturn - PL: aby zobaczyć swoje zamówienia i dokonać zwrotu. - EN: to see your orders and make a return. - DE: um Ihre Bestellungen zu sehen und eine Rückgabe zu machen. - FR: pour voir vos commandes et faire un retour. InvalidEmail - PL: Nieprawidłowy adres e-mail - EN: Invalid e-mail address - DE: Ungültige E-Mail-Adresse - FR: L'adresse e-mail est incorrecte. RefundMethod - PL: Sposób zwrotu środków - EN: Refund method - DE: Rückerstattungsmethode - FR: Mode de remboursement RefundAsPaid - PL: Zwrot na sposób płatności - EN: Refund to the original payment method - DE: Rückerstattung auf die ursprüngliche Zahlungsmethode - FR: Remboursement sur le mode de paiement initial RefundToBankAccount - PL: Zwrot na konto bankowe - EN: Refund to bank account - DE: Rückerstattung auf das Bankkonto - FR: Remboursement sur un compte bancaire

2. Nowa strona Szybkie zwroty

Funkcja szybkich zwrotów wymaga utworzenia dodatkowej strony statycznej refunds. Wykonaj poniższe kroki.

Plik refunds.html w katalogu głównym szablonu

W katalogu głównym szablonu utwórz nowy plik refunds.html z następującą zawartością:
{% extends '_layout.html' -%}
{% block pageContent -%}
{% include 'static-elements/refunds/refunds.html' -%}
{% endblock -%}

Plik static-elements/refunds/refunds.html

W folderze static-elements utwórz nowy katalog refunds, a w nim plik refunds.html:
{% include 'partials/common/breadcrumbs.html' -%}

<div class="container my-5 refunds-page-wrapper">

    <!-- Nagłówek główny -->
    <div class="text-center mb-5">
        <h1 class="mb-3">{{ translations.ReturnInThreeSteps }}</h1>
        <p class="lead text-muted">{{ translations.ReturnWithoutReasonInfo }}</p>
    </div>

    <!-- Sekcja 3 kroków (Siatka 3-kolumnowa) -->
    <div class="row text-center mb-5">
        <div class="col-md-4 mb-4">
            <div class="p-4 border rounded bg-light h-100">
                <h3 class="h5">1. {{ translations.Log_Login }}</h3>
                <p class="mb-0">{{ translations.OrEnterOrderNumber }}</p>
            </div>
        </div>
        <div class="col-md-4 mb-4">
            <div class="p-4 border rounded bg-light h-100">
                <h3 class="h5">2. {{ translations.FillForm }}</h3>
                <p class="mb-0">{{ translations.ReturnOnline }}</p>
            </div>
        </div>
        <div class="col-md-4 mb-4">
            <div class="p-4 border rounded bg-light h-100">
                <h3 class="h5">3. {{ translations.SendParcel }}</h3>
                <p class="mb-0">{{ translations.SendParcelToOurAddress }}</p>
            </div>
        </div>
    </div>

    <!-- Wyróżniony tekst -->
    <div class="text-center mb-5">
        <h2 class="text-success h3">{{ translations.FastSimpleSecure }}</h2>
    </div>

    <!-- Sekcja gotowości do zwrotu (Call to Action) -->
    <div class="text-center p-5 border rounded mb-5">
        <h2 class="h3">{{ translations.ReadyForReturn }}</h2>
        <p>{{ translations.ReadyForReturnInfo }}</p>

        <div class="mt-4">
            {% if customer.Authenticated -%}
                <a href="/Return/List" class="btn btn-primary btn-lg">{{ translations.StartReturn }}</a>
            {% else -%}
                <a href="/Return/List" class="btn btn-primary btn-lg">{{ translations.StartReturn }}</a>
            {% endif -%}
        </div>
    </div>

    <!-- Wyszukiwanie zamówienia dla niezalogowanych -->
    <div class="row justify-content-center mb-5">
        <div class="col-md-6 col-lg-5">
            <div class="text-center mb-4">
                <h3 class="h4">{{ translations.ProductReturn }}</h3>
                <p class="text-muted">{{ translations.ProductReturnFormInfo }}</p>
            </div>

            <form action="/Return/FindOrder" method="POST" class="border p-4 rounded bg-white">
                <div class="form-group mb-3">
                    <label class="font-weight-bold">{{ translations.Com_OrderNumber }}</label>
                    <input type="text" class="form-control" name="OrderNumber" required>
                </div>
                <div class="form-group mb-4">
                    <label class="font-weight-bold">{{ translations.EmailAddress }}</label>
                    <input type="email" class="form-control" name="Email" required>
                </div>
                <button type="submit" class="btn btn-dark w-100 btn-lg">{{ translations.FindOrder }}</button>
            </form>
        </div>
    </div>

    <!-- Zachęta do logowania dla niezalogowanych (Gości) -->
    {% if customer.Authenticated == false -%}
        <div class="text-center py-4 mt-4 border-top">
            <h4 class="h5">{{ translations.Reg_HaveAcc }}</h4>
            <p>{{ translations.LoginToSeeOrdersAndReturn }}</p>
            <!-- W Topaz przycisk logowania często otwiera popup ze zdefiniowaną klasą js-login-popup-trigger -->
            <button class="btn btn-outline-primary js-login-popup-trigger">{{ translations.Log_Login }}</button>
        </div>
        {% include 'partials/common/login-register-popup.html' -%}
    {% endif -%}

</div>

<!-- Globalny komponent Newslettera -->
{% if settings.newsletterOnFunctionalPages == 'yes' -%}
    {% include 'partials/newsletter-global.html' -%}
{% endif -%}

Pliki SCSS strony Szybkie zwroty

W folderze scss/static-elements utwórz nowy katalog refunds, a w nim trzy pliki: refunds-g.scss (style ogólne), refunds-d.scss (desktop) oraz refunds-m.scss (mobile). scss/static-elements/refunds/refunds-g.scss:
.refunds-container {
    box-sizing: border-box;
    margin: 0 auto;
    color: $primaryFontColor;
    background-color: $primaryPageBg;

    .refunds-view {
        display: flex;
        flex-direction: column;
        align-items: center;

        &.hidden-js {
            display: none;
        }
    }

    .refunds-intro {
        width: 100%;
        align-self: stretch;

        &__heading {
            margin: 0 0 16px;
            font-size: $mediumFontSize;
            font-weight: 600;
            line-height: 1.4;
            color: $primaryFontColor;
        }

        &__lead {
            margin: 0 0 16px;
            font-size: 16px;
            font-weight: 500;
            line-height: 1.5;
            color: $primaryFontColor;
        }

        &__hint {
            margin: 16px 0 0;
            font-size: $extraSmallFontSize;
            color: $secondaryFontColor;
        }
    }

    .refunds-steps {
        list-style: none;
        counter-reset: refund-step;
        margin: 0;
        padding: 0;
        display: flex;
        flex-direction: column;
        gap: 8px;

        &__item {
            counter-increment: refund-step;
            display: flex;
            align-items: center;
            gap: 12px;

            &::before {
                content: counter(refund-step);
                flex: 0 0 auto;
                width: 32px;
                height: 32px;
                border-radius: 50%;
                background-color: $primaryBtnBg;
                color: $primaryBtnFontColor;
                font-weight: 600;
                font-size: $smallFontSize;
                line-height: 1;
                display: inline-flex;
                align-items: center;
                justify-content: center;
            }
        }

        &__text {
            font-size: $smallFontSize;
            line-height: 1.5;
            color: $primaryFontColor;

            strong {
                font-weight: 600;
            }
        }
    }

    .refunds-card,
    .refunds-lookup {
        box-sizing: border-box;
        width: 100%;
        background-color: $primaryPageBg;
        border: 1px solid $borderColor;
        border-radius: 8px;
        display: flex;
        flex-direction: column;
        margin-left: auto;
        margin-right: auto;
    }

    .refunds-card {
        align-items: center;
        text-align: center;
        gap: 12px;

        &__heading {
            margin: 0;
            font-size: $bigFontSize;
            font-weight: 600;
            line-height: 1.3;
            color: $primaryFontColor;
        }

        &__text {
            margin: 0;
            font-size: 16px;
            line-height: 1.5;
            color: $secondaryFontColor;
        }

        &__btn {
            width: 100%;
            margin-top: 12px;
        }
    }

    .refund-form-js {
        .form__invalid-input {
            margin: 4px 0 0;
            font-size: $extraSmallFontSize;
            line-height: 16px;
            color: $messageErrorColor;
        }
    }

    .refunds-lookup {
        gap: 16px;

        &__heading {
            margin: 0;
            font-size: $bigFontSize;
            font-weight: 600;
            line-height: 1.3;
            color: $primaryFontColor;
        }

        &__lead {
            margin: 0;
            font-size: $smallFontSize;
            line-height: 1.5;
            color: $secondaryFontColor;
        }

        &__loginPrompt {
            margin: 8px 0 0;
            font-size: $smallFontSize;
            color: $primaryFontColor;
        }

        &__loginLink {
            color: $linkFontColor;
            font-weight: 600;
            text-decoration: underline;

            &:hover,
            &:focus {
                text-decoration: none;
            }
        }

        &__error {
            margin: 0;
            font-size: $smallFontSize;
            color: $messageErrorColor;
        }
    }
}

.loginRegister--login-only {
    .loginRegisterTabsContainer {
        display: none;
    }

    .registrationForm-js {
        display: none;
    }
}
scss/static-elements/refunds/refunds-d.scss:
@media screen and (min-width: 769px) {
    .refunds-container {
        max-width: 1400px;
        padding-top: 32px;
        padding-bottom: 64px;

        .refunds-view {
            gap: 32px;
        }

        .refunds-intro {
            &__heading {
                font-size: 20px;
            }

            &__lead {
                margin-bottom: 24px;
            }
        }

        .refunds-card,
        .refunds-lookup {
            max-width: 578px;
        }

        .refunds-card {
            padding: 40px;
        }

        .refunds-lookup {
            padding: 32px;
        }
    }
}
scss/static-elements/refunds/refunds-m.scss:
@media screen and (max-width: 768px) {
    .refunds-container {
        padding: 16px 3% 40px;

        .refunds-view {
            gap: 24px;
        }

        .refunds-intro {
            &__heading {
                font-size: 18px;
            }

            &__lead {
                font-size: $smallFontSize;
                margin-bottom: 16px;
            }
        }

        .refunds-steps {
            &__item {
                &::before {
                    width: 28px;
                    height: 28px;
                }
            }
        }

        .refunds-card {
            padding: 24px 16px;

            &__heading {
                font-size: $mediumFontSize;
            }

            &__text {
                font-size: $smallFontSize;
            }
        }

        .refunds-lookup {
            padding: 20px 16px;

            &__heading {
                font-size: $mediumFontSize;
            }
        }
    }
}

3. Modyfikacje istniejących plików HTML

partials/customer/order-content.html

W pliku partials/customer/order-content.html wykonaj poniższe zmiany. a) Bezpośrednio po otwarciu kontenera <div class="orderContent order-content-js"> dodaj dwa nowe bannery informacyjne (jeden o ukrytych danych zamówienia, drugi o terminie zwrotu, wraz z wyliczaniem flagi hasReturnableProduct):
{% if order.Restricted -%}
<div class="orderContent__returnInfo" role="note">
    <!-- TODO: ikona SVG informacyjna z klasą orderContent__returnInfo__icon -->
    {{ translations.RestrictedOrderViewInfo }}
</div>
{% endif -%}
{% assign hasReturnableProduct = false -%}
{% if config.Complaints.ReturnsEnabled -%}
{% for product in order.Products -%}
{% if product.CanReturn -%}
{% assign hasReturnableProduct = true -%}
{% break -%}
{% endif -%}
{% endfor -%}
{% endif -%}
{% if hasReturnableProduct -%}
<div class="orderContent__returnInfo" role="note">
    <!-- TODO: ikona SVG informacyjna z klasą orderContent__returnInfo__icon -->
    {{ translations.Prf_ReturnPeriodInfo | Format: config.Complaints.DaysToReturn }}
</div>
{% endif -%}
b) Kontener <div class="orderContent__docsToPrint">...</div> (z dokumentami do druku) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}, aby ukrywać go dla zamówień typu restricted. c) Cały dotychczasowy blok przycisków reklamacji/zwrotu (oparty na konstrukcji {% if ComplaintsEnabled and ReturnsEnabled %} ... {% elseif ComplaintsEnabled %} ... {% elseif ReturnsEnabled %} ... {% endif %} z jednym wspólnym przyciskiem) zamień na dwa niezależne warunki, dzięki czemu dla produktu uprawnionego zarówno do reklamacji, jak i do zwrotu, oba przyciski wyświetlają się obok siebie. Strukturę wewnątrz warunku {% if product.CanComplain or product.CanReturn -%} zastąp poniższym kodem:
{% if config.Complaints.ComplaintsEnabled == true and product.CanComplain -%}
<button class="orderContent__complainBtn orderContent__complainBtn--complaint showPopupBtn-js addDataToComplaintForm-js" data-popup-class="popupDialog" data-form-type="complaint" data-product-id="{{product.No}}" data-image-id="{{product.ImageId}}" data-imageext="{{product.Image.ExternalUrl}}" data-product-name="{{product.NameNoHtml | H}}" data-product-complain="{{product.CanComplain}}" data-product-count="{{ newProductQuantity }} {{ product.Unit }}" data-product-unit="{{ product.Unit }}" data-product-description="{{ productAttributes | Join: ' / ' | H }}" data-product-return="false" data-product-quantity="{{newProductQuantity}}" data-order-id="{{order.Id}}" data-order-date="{{order.Date | Date: 'yyyy-MM-dd'}}">
    <svg width="16" height="16">
        <use href="#comment-alt-regular"></use>
    </svg>
    {{translations.Prf_SendComplaint }}
</button>
{% endif -%}
{% if config.Complaints.ReturnsEnabled == true and product.CanReturn -%}
<button class="orderContent__complainBtn orderContent__complainBtn--return showPopupBtn-js addDataToComplaintForm-js" data-popup-class="popupDialog" data-form-type="return" data-product-id="{{product.No}}" data-image-id="{{product.ImageId}}" data-imageext="{{product.Image.ExternalUrl}}" data-product-name="{{product.NameNoHtml | H}}" data-product-complain="false" data-product-count="{{ newProductQuantity }} {{ product.Unit }}" data-product-unit="{{ product.Unit }}" data-product-description="{{ productAttributes | Join: ' / ' | H }}" data-product-return="{{product.CanReturn}}" data-product-quantity="{{newProductQuantity}}" data-order-id="{{order.Id}}" data-order-date="{{order.Date | Date: 'yyyy-MM-dd'}}">
    <svg width="16" height="16">
        <use href="#sync-regular"></use>
    </svg>
    {{ translations.Prf_OrderReturn }}
</button>
{% endif -%}
Kluczowe różnice w stosunku do poprzedniej wersji: każdy przycisk renderowany jest niezależnie (oba mogą wystąpić równocześnie), przyciski mają modyfikatory orderContent__complainBtn--complaint i orderContent__complainBtn--return, atrybut data-form-type (odczytywany w JS), w przycisku reklamacji wymuszone data-product-return="false", w przycisku zwrotu wymuszone data-product-complain="false", ikony 16x16 (#comment-alt-regular dla reklamacji, #sync-regular dla zwrotu), a etykieta przycisku zawiera już tylko jedno tłumaczenie. d) W pozostałych miejscach z przyciskami reklamacji/zwrotu (sekcje, w których nie zmieniają się klasy i ikony) dodaj jedynie dwa nowe atrybuty:
data-product-unit="{{ product.Unit }}"
data-product-description="{{ productAttributes | Join: ' / ' | H }}"
e) W sekcji załączników zamówienia zamień:
{% if order.Attachments[0] -%}
na:
{% if order.Attachments[0] and order.Restricted == false -%}
f) W kontenerze <div class="orderContent__recipient orderContent__infoBox"> zamień wyświetlanie adresu dostawy:
<span class="orderContent__lightText">{{ order.Customer.DeliveryAddress.Street }} {{ order.Customer.DeliveryAddress.StreetNo }} / {{ order.Customer.DeliveryAddress.UnitNo }}</span>
na:
<span class="orderContent__lightText">{{ order.Customer.DeliveryAddress.Street }} {{ order.Customer.DeliveryAddress.StreetNo }}{% if order.Customer.DeliveryAddress.UnitNo != null and order.Customer.DeliveryAddress.UnitNo != '' -%} / {{ order.Customer.DeliveryAddress.UnitNo }}{% endif -%}</span>
g) Sekcję z przyciskami akcji zamówienia (orderCancel-js, ponowienie płatności itd.) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}. Wstaw {% unless order.Restricted -%} bezpośrednio przed warunkiem {% if order.CanRestorePayment -%}, a {% endunless -%} po zamykającym {% endif -%} bloku z przyciskiem anulowania zamówienia.

partials/common/complaint-popup.html

Plik partials/common/complaint-popup.html wymaga gruntownej przebudowy. Usuwamy z niego radiowe przyciski wyboru "reklamacja/zwrot", a typ formularza jest teraz przekazywany z zewnątrz przez parametr __include. Sterowanie ilością zostało przeniesione do kafelka z produktem (z etykietą i obsługą wariantu statycznego, gdy zostaje tylko 1 sztuka). W formularzu zwrotu zamiast samego pola numeru konta pojawia się sekcja wyboru sposobu zwrotu środków (refundMethod-js) – z opcją „zwrot na sposób płatności" (domyślna) lub „zwrot na konto bankowe". Pole numeru konta jest domyślnie ukryte i disabled; pokazuje się dopiero po wybraniu opcji „konto bankowe" (obsługa w JS w metodzie changeRefundMethod). Tytuł, kafelek produktu i formularz oznaczone są dodatkową klasą complain-form-view-js, dzięki czemu po pomyślnym wysłaniu formularza można je ukryć i wyświetlić ekran sukcesu (complain-success-view-js). Zastąp całą zawartość pliku poniższym kodem:
{% if hideContent -%}
{% else -%}
{% assign formType = include -%}
{% assign isReturn = false -%}
{% if formType == 'return' -%}
{% assign isReturn = true -%}
{% endif -%}
<div class="popupDialog popupDialog__complain popupDialog-js">
    {% assign order = customer-profile.Order -%}
    <div class="popupDialog__wrapper">
        <button class="popupDialog__closeBtn closePopupBtn-js">
            <!-- TODO: ikona SVG zamknięcia – jak w pozostałych popupach szablonu -->
        </button>
        <span class="popupDialog__title complain-form-view-js">
            {% if isReturn -%}
            {{ translations.Prf_OrderReturn }}
            {% else -%}
            {{ translations.Prf_SendComplaint }}
            {% endif -%}
        </span>
        <div class="complain__product complain-form-view-js">
            <figure><img class="productImage-js" alt="product_image" /></figure>
            <div class="complain__productInfo">
                <!-- TODO: zweryfikuj z szablonem elementy z klasami productName-js i productDescription-js (nazwa i opis produktu) -->
                <span class="productName-js"></span>
                <span class="productDescription-js"></span>
                <div class="complain__quantity">
                    <label class="complain__quantityLabel" for="complaint-quantity">{{translations.Com_Quantity}}:</label>
                    <div class="complain__quantityControl min-js quantityControl-js">
                        <button class="button-minus-add-product" type="button" aria-label="{{translations.ButtonMinusAddProduct}}" data-field="quantity">
                            <!-- TODO: ikona SVG minus -->
                        </button>
                        <input id="complaint-quantity" class="quantity-field quantity__field-js" max="" min="1" name="quantity" type="number" value="1" data-decimal="false" />
                        <button class="button-plus-add-product" type="button" aria-label="{{ translations.ButtonPlusAddProduct }}" data-field="quantity">
                            <!-- TODO: ikona SVG plus -->
                        </button>
                    </div>
                    <span class="quantityStatic-js hidden"></span>
                    <span class="productUnit-js"></span>
                </div>
            </div>
        </div>
        <div class="form complain__form inputs-container-js complain-form-view-js" data-success-info="{{ translations.ReportSuccessInfo }}">
            <input name="__action" type="hidden" value="{% if isReturn -%}Order/ReturnAdd{% else -%}Order/ComplaintAdd{% endif -%}" />
            <strong>{{ translations.ReportDetails }}</strong>
            {% unless isReturn -%}
            <div class="form__input-wrapper">
                {% if config.Complaints.Defects <> null -%}
                {% assign defectsSize = config.Complaints.Defects | Size -%}
                <label class="hidden" for="defectId">{{ translations.ChooseComplaintCause }}</label>
                <select class="form__input-value form__input-value-js {% if settings.themeName == 'Dark' -%} darkTheme {% endif -%}" name="defectId" required="">
                    {% if defectsSize > 1 -%}
                    <option value="-1">* {{translations.ChooseComplaintCause}}</option>
                    {% endif -%}
                    {% for def in config.Complaints.Defects -%}
                    <option value="{{def.Id}}">{{def.Name}}</option>
                    {% endfor -%}
                </select>
                {% endif -%}
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            <div class="form__input-wrapper">
                <span class="form__icons">
                    <!-- TODO: ikona SVG kalendarza -->
                </span>
                <input id="defectDate" class="form__input-value form__icon_padding form__input-value-js orderDate-js" max="{{config.Now | Date: 'yyyy-MM-dd'}}" min="{{order.Date | Date: 'yyyy-MM-dd'}}" name="defectDate" type="date" value="{{config.Now | Date: 'yyyy-MM-dd'}}" placeholder="yyyy-MM-dd" />
                <label class="form__input-info" for="defectDate">* {{translations.Prf_DefectDate}}</label>
            </div>
            <div class="form__input-wrapper">
                {% if config.Complaints.Requests <> null -%}
                {% assign requestsSize = config.Complaints.Requests | Size -%}
                <label class="hidden" for="requestId">{{ translations.Prf_ComplainRequest }}</label>
                <select class="form__input-value form__input-value-js {% if settings.themeName == 'Dark' -%} darkTheme {% endif -%}" name="requestId" required="">
                    {% if requestsSize > 1 -%}
                    <option value="-1">* {{translations.Prf_ComplainRequest}}</option>
                    {% endif -%}
                    {% for req in config.Complaints.Requests -%}
                    <option value="{{req.Id}}">{{req.Name}}</option>
                    {% endfor -%}
                </select>
                {% endif -%}
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            {% else -%}
            {% assign returnTypes = config.Complaints.Returns | Size -%}
            {% if returnTypes > 1 -%}
            <div class="form__input-wrapper">
                <label class="hidden" for="returnId">{{ translations.ChooseReturn }}</label>
                <select class="form__input-value form__input-value-js {% if settings.themeName == 'Dark' -%} darkTheme {% endif -%}" name="returnId" required="">
                    <option value="-1">* {{translations.ChooseReturn}}</option>
                    {% for return in config.Complaints.Returns -%}
                    <option value="{{return.Id}}">{{return.Name}}</option>
                    {% endfor -%}
                </select>
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            {% endif %}
            {% endunless -%}
            <div class="form__input-wrapper returnInputWrapper-js refundMethodWrapper-js">
                <label class="complain__sectionLabel" for="refundMethod">{{ translations.RefundMethod }}</label>
                <select id="refundMethod" class="form__input-value form__input-value-js refundMethod-js {% if settings.themeName == 'Dark' -%}darkTheme{% endif -%}" name="refundMethod">
                    <option value="payment">{{ translations.RefundAsPaid }}{% if order.Payment.Name != null and order.Payment.Name != '' %} ({{ order.Payment.Name }}){% endif %}</option>
                    <option value="account">{{ translations.RefundToBankAccount }}</option>
                </select>
            </div>
            <div class="form__input-wrapper accountNumberWrapper-js" style="display: none;">
                <input id="accountNumber" class="form__input-value form__input-value-js" disabled="disabled" maxlength="50" name="accountNumber" type="text" />
                <label class="form__input-info form__input-info-js" for="accountNumber">{{translations.Crt_BankAccountNumber}}</label>
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            <div class="form__input-wrapper">
                {{translations.Prf_AdditionalInfo}}
                <textarea class="form__input-value" name="message" aria-label="{{ translations.Prf_AdditionalInfo }}"></textarea>
            </div>
            <div class="form__input-wrapper">
                <span class="form__requiredFields--info">* {{ translations.Com_RequiredFields }}</span>
            </div>
            {% if config.Complaints.AttachmentsEnabled -%}
            <div class="form__input-wrapper attachementsInputWrapper" data-not-added-info="{{translations.AttachementsNotAdded}}">
                <button class="form__attachementsLabel form__attachementsLabel--btn form__attachementsLabel-js" data-page="complaints">
                    <!-- TODO: ikona SVG dodawania załącznika -->
                    {{ translations.AddAttachment }}
                </button>
                {% capture maxSize -%}{{config.Complaints.AttachmentMaxSize | DividedBy: 1024}}KB{% endcapture -%}
                {% for i in (1..config.Complaints.AttachmentsMaxCount) -%}
                <div class="form__attachement-input-container form__attachement-input-container-attachments form__attachement-input-container--hidden">
                    <!-- TODO: ikona SVG oraz element z nazwą pliku (form__attachement-input-container-attachments__text) -->
                    <input class="addAttachementInComplaint-js" accept="{{ config.Complaints.AttachmentExtensions }}" name="file" type="file" aria-label="{{ translations.AddAttachment }}" data-file-size="{{ config.Complaints.AttachmentMaxSize }}" data-size-exceeded="{{ translations.Com_FileSizeExceeded | Format: maxSize }}" data-invalid-file="{{ translations.Com_InvalidFile | Format: config.Complaints.AttachmentExtensions }}" />
                    <button class="form__clear-attachement-input clearFileInput-js" style="display: none;">
                        <!-- TODO: ikona SVG usuwania załącznika -->
                    </button>
                </div>
                {% endfor -%}
            </div>
            {% endif -%}
            <input class="productId-js" name="no" type="hidden" value="" />
            <input class="orderId-js" name="orderId" type="hidden" value="{{order.Id}}" />
            <button class="primary-action-button orderComplaintOrReturnAdd-js" type="button" data-id="{{order.Id}}">{{translations.Report}}</button>
        </div>
        <div class="complain__successView complain-success-view-js hidden">
            <div class="complain__successIcon">
                <!-- TODO: ikona SVG potwierdzenia (zielony "check", klasa svgIcon) -->
            </div>
            <h2 class="complain__successTitle">{{ translations.ComplaintSuccessTitle }}</h2>
            <p class="complain__successDescription">{{ translations.ComplaintSuccessDescription }}</p>
            <div class="complain__successInfoBox">
                <!-- TODO: ikona SVG informacyjna (klasa svgIcon) -->
                <span>{{ translations.ComplaintSuccessConfirmationSent }}
                    <strong>{{ order.Customer.Email }}</strong>
                </span>
            </div>
            <h3 class="complain__successStepsTitle">{{ translations.ComplaintSuccessStepsTitle }}</h3>
            <ol class="complain__successSteps">
                <li>{{ translations.ComplaintSuccessStep1 }}</li>
                <li>{{ translations.ComplaintSuccessStep2 }} {{ config.Shop.Address.Street }} {{ config.Shop.Address.StreetNo }}{% if config.Shop.Address.UnitNo != '' %}/{{ config.Shop.Address.UnitNo }}{% endif %}, {{ config.Shop.Address.ZipCode }} {{ config.Shop.Address.City }}</li>
                <li>{{ translations.ComplaintSuccessStep3 }}</li>
            </ol>
            <div class="complain__successActions">
                <button class="primary-action-button closePopupBtn-js" type="button">{{ translations.BtnClose }}</button>
            </div>
        </div>
    </div>
</div>
{% endif -%}

4. Modyfikacje pliku js/layout1.js

Poniższe zmiany dotyczą pliku js/layout1.js. Po edycji pamiętaj o zminifikowaniu pliku do layout1.min.js. a) W obiekcie customerProfile usuń całą metodę setComplainReturnRadioButtons (radiowy przełącznik reklamacja/zwrot nie jest już potrzebny – typ formularza jest teraz przekazywany przy otwieraniu popupu). b) W tym samym obiekcie zastąp całą metodę addDataToComplaintForm nową implementacją, która odczytuje typ formularza z atrybutu data-form-type przycisku i przekazuje go do szablonu jako parametr __include:
addDataToComplaintForm: function (e) {
    const template = 'partials/common/complaint-popup.html';
    const data = e.currentTarget;
    const formType = data.dataset.formType === 'return' ? 'return' : 'complaint';

    $.get('', {__template: template, __include: "'" + formType + "'"}, function(result) {
        $('.customer__content-js').append(result.template);
        $('.popupDialog__complain').show();
        $('body').addClass('customerProfileNoScroll');

        const image = $('.productImage-js');
        const productName = $('.productName-js');
        const inputId = $('.productId-js');
        const productQuantity = $('.quantity__field-js');
        const quantityControl = $('.quantityControl-js');
        const quantityStatic = $('.quantityStatic-js');
        const productUnit = $('.productUnit-js');
        const productDescription = $('.productDescription-js');

        const orderId = $('.orderId-js');
        const buttonOrderId = $('.orderComplaintOrReturnAdd-js');
        const orderDate = $('.orderDate-js');

        productName.text(data.dataset.productName);
        productUnit.text(data.dataset.productUnit || '');
        productDescription.text(data.dataset.productDescription || '');
        inputId.val(data.dataset.productId);
        productQuantity.attr('max', data.dataset.productQuantity);

        if (parseInt(data.dataset.productQuantity, 10) <= 1) {
            quantityControl.addClass('hidden');
            quantityStatic.text(data.dataset.productQuantity).removeClass('hidden');
        } else {
            quantityControl.removeClass('hidden');
            quantityStatic.addClass('hidden');
        }

        orderId.val(data.dataset.orderId);
        buttonOrderId.attr('data-id', data.dataset.orderId);
        orderDate.attr('min', data.dataset.orderDate);

        if (data.dataset.imageext != null && data.dataset.imageext != "") {
            image.attr('src', data.dataset.imageext);
        } else if (data.dataset.imageId != null && data.dataset.imageId != "") {
            image.attr('src', '/Image/?id=' + data.dataset.imageId);
        }

        if (image.attr('src') === '' || image.attr('src') == null) {
            image.closest('figure').addClass('noImage-js');
        }

        setTimeout(function() {
            app.activateFocusTrap('.popupDialog__complain', e.target);
        }, 200);
    });
},
c) Zastąp metodę changeReturnComplaintForm nową wersją (obsługuje również pole numeru konta i wywołuje changeRefundMethod po przełączeniu na zwrot):
changeReturnComplaintForm: function (e) {
    const form = $(e.currentTarget).closest('.inputs-container-js');
    const complaintInputs = form.find('.complaintInputWrapper-js');
    const returnInputs = form.find('.returnInputWrapper-js');
    const accountWrapper = form.find('.accountNumberWrapper-js');
    const accountInput = accountWrapper.find('input[name="accountNumber"]');

    if ($(e.currentTarget).is(':checked') && e.currentTarget.dataset.name === 'complaint' ) {
        $.each(complaintInputs, function (index, value) {
            $(value).find('input, select').first().removeAttr('disabled');
            $(value).show(300);
        });
        returnInputs.each(function () {
            $(this).find('input, select').first().attr('disabled', 'true');
        });
        returnInputs.hide(300);
        accountInput.removeAttr('disabled').removeAttr('required').removeClass('form__validation-error-js');
        accountWrapper.find('.form__validation-required-js').hide();
        accountWrapper.show(300);
    }

    if ($(e.currentTarget).is(':checked') && e.currentTarget.dataset.name === 'return' ) {
        $.each(complaintInputs, function (index, value) {
            $(value).find('input, select').first().attr('disabled', 'true');
            $(value).hide(300);
        });
        returnInputs.each(function () {
            $(this).find('input, select').first().removeAttr('disabled');
        });
        returnInputs.show(300);
        customerProfile.changeRefundMethod(form);
    }
},
d) Tuż za metodą changeReturnComplaintForm dodaj nową metodę changeRefundMethod (pokazuje / ukrywa pole numeru konta bankowego na podstawie wybranego sposobu zwrotu):
changeRefundMethod: function (formOrEvent) {
    const form = formOrEvent && formOrEvent.currentTarget
        ? $(formOrEvent.currentTarget).closest('.inputs-container-js')
        : $(formOrEvent);
    const select = form.find('.refundMethod-js');
    const accountWrapper = form.find('.accountNumberWrapper-js');
    const accountInput = accountWrapper.find('input[name="accountNumber"]');

    if (select.val() === 'account') {
        accountInput.removeAttr('disabled').attr('required', 'required');
        accountWrapper.show(300);
    } else {
        accountInput.attr('disabled', 'true').removeAttr('required').removeClass('form__validation-error-js');
        accountWrapper.find('.form__validation-required-js').hide();
        accountWrapper.hide(300);
    }
},
e) W metodzie wysyłającej formularz reklamacji/zwrotu (gdzie znajduje się pętla for (let i=0; i<dataFromHTML.length; i++)) zaraz po pętli dodaj fragment dołączający parametr qrHash z URL-a przy wysyłaniu zwrotu:
if (form.find('input[name="__action"]').val() === 'Order/ReturnAdd') {
    const qrHash = new URLSearchParams(globalThis.location.search).get('qrHash');
    if (qrHash) {
        fd.append('qrHash', qrHash);
    }
}
f) W tej samej metodzie, w callbacku success po pomyślnym wysłaniu, zamień fragment:
if (data.action.Result) {
    const message = form.data('success-info');
    app.showTemporaryPopup(message, 'success', '', 8000);
    $('.clearFileInput-js').hide();
    app.hidePopup(e);
    sessionStorage.removeItem('complains');
    sessionStorage.removeItem('order' + (e.currentTarget).dataset.id);
    $('.order' + (e.currentTarget).dataset.id).remove();
    $('.popupDialog__complain').remove();
    $('body').removeClass('customerProfileNoScroll');
    customerProfile.showOrderDetails(e);
}
na:
if (data.action.Result) {
    $('.clearFileInput-js').hide();
    sessionStorage.removeItem('complains');
    sessionStorage.removeItem('order' + (e.currentTarget).dataset.id);
    const popup = $(e.currentTarget).closest('.popupDialog__complain');
    popup.find('.complain-form-view-js').addClass('hidden');
    popup.find('.complain-success-view-js').removeClass('hidden');
    popup.find('.popupDialog__wrapper').scrollTop(0);
}
g) W sekcji rejestracji zdarzeń profilu klienta (tam, gdzie znajdują się m.in. mainSection.on('change', '.radioComplaint-js, .radioReturn-js', ...)) tuż za istniejącym handlerem zmiany typu formularza dopisz nowy handler:
mainSection.on('change', '.refundMethod-js', function (e) {
    customerProfile.changeRefundMethod(e);
});
h) Znajdź globalny handler obsługujący keydown z selektorem zaczynającym się od .radioReturn-js label, .radioComplaint-js label, ... i usuń z niego dwa pierwsze selektory (po zmianie zaczyna się od .showHideSection-js):
// PRZED
$('body').on('keydown', '.radioReturn-js label, .radioComplaint-js label, .showHideSection-js, .checkBoxes__container label, .customerPagination__form-js, .discountsDetails-js, .customer-focus, .customer__menuActivate-js', function(e) { ... });

// PO
$('body').on('keydown', '.showHideSection-js, .checkBoxes__container label, .customerPagination__form-js, .discountsDetails-js, .customer-focus, .customer__menuActivate-js', function(e) { ... });
i) W obiekcie app w pliku js/layout1.js obsłuż przekierowanie po zalogowaniu z parametrem #login-redirect= (używanym przez stronę szybkich zwrotów). W bloku rejestracji/logowania, w miejscu gdzie obsługiwany jest hash #back-to-cart, tuż po nim dodaj:
if (globalThis.location.hash.startsWith('#login-redirect=')) {
    url = globalThis.location.hash.slice('#login-redirect='.length);
}
Następnie w handlerze sukcesu logowania, gdzie znajduje się sprawdzenie window.location.hash.includes('#back-to-cart') wraz z przekierowaniem, tuż za nim dodaj analogiczny blok przekierowujący w przypadku #login-redirect=:
if (globalThis.location.hash.startsWith('#login-redirect=')) {
    globalThis.location.assign(globalThis.location.hash.slice('#login-redirect='.length));
    return;
}

5. Modyfikacje plików SCSS profilu klienta

Poniższe style należy dodać do plików scss/static-elements/customer-profile/customer-profile-g.scss (style ogólne), customer-profile-d.scss (desktop) i customer-profile-m.scss (mobile). Po zmianach pamiętaj o kompilacji SCSS – nie edytuj ręcznie wynikowych plików CSS.

Plik customer-profile-g.scss

a) Wewnątrz selektora opakowującego (tam, gdzie znajdują się istniejące reguły .orderContent__complainBtn) dodaj nowe reguły dla banera informacyjnego oraz kontenera grupującego przyciski reklamacji/zwrotu:
.orderContent__returnInfo {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 16px 0 24px;
    padding: 12px 16px;
    background-color: color-mix(in srgb, #{$linkFontColor} 4%, transparent);
    border: 1px solid color-mix(in srgb, #{$linkFontColor} 20%, transparent);
    border-radius: 4px;
    font-size: 13px;
    line-height: 1.4;
    color: $primaryFontColor;

    &__icon {
        flex-shrink: 0;
        fill: $linkFontColor;
    }
}

.orderContent__complainBtns {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin: 16px 0 4px;
}
b) Następnie zastąp istniejące style .orderContent__complainBtn nowym wyglądem przycisku (z tłem, obramowaniem i hoverem):
.orderContent__complainBtn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 16px 0 4px;
    padding: 6px 12px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 4px;
    color: $linkFontColor;
    fill: $linkFontColor;
    font-size: 13px;
    font-weight: 500;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 180ms, border-color 180ms;

    .orderContent__complainBtns & {
        margin: 0;
    }

    svg {
        margin: 0;
        flex-shrink: 0;
    }

    &:hover,
    &:focus-visible {
        background-color: color-mix(in srgb, #{$linkFontColor} 6%, transparent);
        border-color: color-mix(in srgb, #{$linkFontColor} 25%, transparent);
        outline: none;
    }
}
c) Dodaj style etykiety sekcji oraz kontenera sposobu zwrotu w popupie reklamacji:
.complain__sectionLabel {
    display: block;
    margin-bottom: 8px;
    font-size: 14px;
    font-weight: 500;
    color: $primaryFontColor;
}

.refundMethodWrapper-js {
    margin-bottom: 18px;
}
d) Dodaj kompletne style ekranu sukcesu zwrotu (m.in. ikona, tytuł, lista kolejnych kroków, sekcja z e-mailem i przyciskiem zamknięcia):
.complain__successView {
    text-align: center;
    padding: 16px 0 0;
}

.complain__successIcon {
    display: flex;
    justify-content: center;
    margin: 8px 0 20px;

    .svgIcon {
        width: 64px;
        height: 64px;
        fill: #2d8c4a;
    }
}

.complain__successTitle {
    font-size: 20px;
    font-weight: 600;
    line-height: 1.3;
    margin: 0 0 12px;
    color: $primaryFontColor;
}

.complain__successDescription {
    font-size: 14px;
    line-height: 1.5;
    color: $primaryFontColor;
    margin: 0 0 20px;
}

.complain__successInfoBox {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 14px;
    margin: 0 0 24px;
    border: 1px solid #cfdcef;
    background-color: #f0f5fc;
    border-radius: 6px;
    text-align: left;

    .svgIcon {
        flex-shrink: 0;
        margin-top: 2px;
        fill: #3a6ea5;
    }

    span {
        font-size: 13px;
        line-height: 1.5;
        color: $primaryFontColor;
    }

    strong {
        display: block;
        font-weight: 600;
        margin-top: 2px;
        word-break: break-all;
    }
}

.complain__successStepsTitle {
    font-size: 15px;
    font-weight: 600;
    margin: 0 0 12px;
    text-align: left;
    color: $primaryFontColor;
}

.complain__successSteps {
    margin: 0 0 24px;
    padding-left: 22px;
    text-align: left;

    li {
        font-size: 14px;
        line-height: 1.6;
        margin-bottom: 6px;
        color: $primaryFontColor;
    }
}

.complain__successActions {
    display: flex;
    justify-content: flex-end;
    padding-top: 16px;
    padding-bottom: 30px;
    margin-top: 8px;
    border-top: 1px solid $borderColor;

    .primary-action-button {
        min-width: 140px;
        margin: 0;
    }

    @media screen and (max-width: 599px) {
        .primary-action-button {
            width: 100%;
            min-width: 0;
        }
    }
}
e) Zaktualizuj style załączników – znajdź istniejące reguły .form__clear-attachement-input oraz reguły z position: absolute; top: 11px; i zastąp je nowymi (które ustawiają załączniki w układzie statycznym z poprawnym overflowem i przyciskiem usuwania):
.form__attachement-input-container-attachments__text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.form__attachement-input-container--hidden,
.form__attachement-input-container-attachments.form__attachement-input-container--hidden {
    display: none;
}

.form__clear-attachement-input {
    position: static;
    background: transparent;
    border: none;
    padding: 2px 4px;
    margin: 0 0 0 4px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;

    svg {
        fill: $linkFontColor;
        transition: opacity 200ms;
    }

    &:hover svg {
        opacity: 0.7;
    }
}

Plik customer-profile-d.scss

Wewnątrz wrappera @media screen and (min-width: 769px) zamień istniejące style przycisku reklamacji:
.customer .orderContent__complainBtn {
    position: absolute;
    bottom: 8px;
}
na poniższy fragment (dodaje pozycjonowanie kontenera grupującego przyciski oraz osobny selektor dla pojedynczych przycisków w wierszu produktu):
.customer .orderContent__complainBtns {
    position: absolute;
    bottom: 8px;
    right: 0;
    margin: 0;
}

.customer .orderContent__productDetails > .orderContent__complainBtn {
    position: absolute;
    bottom: 8px;
    right: 0;
    margin: 0;
}

Plik customer-profile-m.scss

W obrębie selektora .customer zamień istniejący media-query @media screen and (max-width: 359px) wraz z jego wnętrzem na rozszerzoną wersję (układająca przyciski reklamacji/zwrotu pionowo na szerokościach do 450px):
@media screen and (max-width: 450px) {
    .customer__orderContent .orderContent__productsRow {
        max-height: none;
    }

    .customer__orderContent .orderContent__productDetails {
        display: flex;
        flex-direction: column;
        align-items: stretch;
    }

    .customer__orderContent .orderContent__complainBtns {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 8px;
        width: 100%;
        margin: 12px 0 4px;
        padding-top: 12px;
        border-top: 1px solid $borderColor;
    }

    .customer__orderContent .orderContent__complainBtn {
        display: flex;
        width: 100%;
        justify-content: center;
        padding: 10px 12px;
        margin: 12px 0 4px;
        border-color: color-mix(in srgb, #{$linkFontColor} 25%, transparent);
    }

    .customer__orderContent .orderContent__complainBtns .orderContent__complainBtn {
        margin: 0;
    }
}

6. Szablon One Page Shop

Szablon One Page Shop ma praktycznie identyczną strukturę plików jak Topaz. Wszystkie powyższe modyfikacje (tłumaczenia, nowa strona zwrotów, edycje plików partials/common/complaint-popup.html oraz partials/customer/order-content.html, zmiany w js/layout1.js oraz w plikach SCSS profilu klienta i strony zwrotów) wykonaj 1:1 w plikach szablonu OPS pod tymi samymi ścieżkami. Treść kodu jest taka sama, ścieżki plików są takie same – instrukcja dla Topaza w pełni stosuje się również do One Page Shopa. Po wprowadzeniu wszystkich powyższych zmian w szablonie Topaz (oraz One Page Shop) pamiętaj o kompilacji oraz minifikacji plików js i scss, zgodnie z artykułem dostępnym pod linkiem https://pomoc.comarchesklep.pl/artykul/kompilacja-i-minifikacja-plikow/.
Wskazówka
Potrzebujesz pomocy lub masz pytania? Skontaktuj się z nami poprzez portal asysta.comarch.pl.

Posiadam gotowy szablon Comarch. Jak mogę go dostosować do kryteriów WCAG 2.1/2.2?

Wstęp

Z dniem 28 czerwca 2025 roku w życie wejdą przepisy związane z implementacją ustawy z dnia 26 kwietnia 2024 r. o zapewnianiu spełniania wymagań dostępności niektórych produktów i usług. Wdraża ona do polskiego prawa tzw. Europejski Akt o Dostępności (EAA) – unijną dyrektywę 2019/882. Celem ustawy jest zapewnienie, że kluczowe produkty i usługi będą dostępne dla wszystkich użytkowników, w tym osób z niepełnosprawnościami. Przedsiębiorcy mają czas do 28 czerwca 2025 roku, aby dostosować swoje produkty i usługi do nowych wymogów.
Wskazówka
Chcesz dowiedzieć się więcej o tych przepisach? Sprawdź artykuł w naszym Centrum Pomocy: Europejski Akt o Dostępności (EAA) i zapoznaj się ze szczegółami
W niniejszym artykule wskazujemy, jakie czynności należy wykonać, jeśli posiadasz jeden ze standardowych szablonów Comarch, czyli: Rubin, Szafir, Topaz, One Page Shop lub Dla Gastronomii.   

Sprawdź, jaki szablon posiadasz

Nie wiesz, który szablon posiadasz? Możesz to sprawdzić w panelu administracyjnym Comarch e-Sklep. Aby to zrobić, z poziomu panelu administracyjnego przejdź do zakładki Wygląd sklepu/ Ustawienia a następnie, pod przyciskiem "Więcej" wybierz Edytuj ustawienia zaawansowane. W obszarze, który został wyświetlony, pojawi się kilka zakładek, a wśród nich zakładka "Szablon". Wybierz ją, po czym sprawdź szablon:   Jeśli Twój szablon to Rubin, Szafir, Topaz, One Page Shop lub Dla Gastronomii, to możesz przejść do kolejnej części artykułu. Jeśli posiadasz własny szablon z indywidualnymi modyfikacjami, to przejdź do artykułu: Posiadam własny szablon, jak mogę go dostosować do kryteriów WCAG 2.1/2.2?  Jeśli posiadasz szablon Bursztyn, Agat lub Opal, to przejdź do artykułu: Posiadam szablon Bursztyn, Opal lub Agat, jak mogę go dostosować do kryteriów WCAG 2.1/2.2?  

Co zrobić jako właściciel e-Sklepu lub Partner, jeśli używam gotowych szablonów Comarch?

Jako właściciel e-Sklepu lub Partner Comarch zadbaj, aby zadbać o dostosowanie swojej witryny do obowiązujących przepisów. Nowe wymogi to wspólna odpowiedzialność:
  • Comarch e-Sklep – zajmiemy się kwestiami technicznymi w przypadku Gotowych Szablonów Comarch, do których należą m.in. zmiany w kodzie,
  • Właściciel, administrator lub Partner sklepu – musisz zadbać o treści i elementy, które dodajesz samodzielnie. Chodzi tu głównie opis produktów, zdjęcia i grafiki czy identyfikację wizualną. 
 

Jak zacząć?

Jeśli korzystasz z gotowych szablonów, takich jak Rubin, Szafir, Topaz, One Page Shop lub Dla Gastronomii, nie musisz przejmować się samodzielnym edytowaniem ich kodu. Wszystkie usprawnienia zostaną udostępnione wraz z aktualizacją, która pojawi się w czerwcu 2025 roku.

Aktualizacja szablonu

Wskazówka
Aktualizację szablonu wykonaj wtedy, kiedy będzie ona dostępna. Realizacja wersji 2025.4 przewidywana jest przed 28 czerwca 2025 roku, poinformujemy o niej w aktualnościach. Będzie ona zawierała zmiany związane z omawianymi tutaj przepisami.

Jak zaktualizować szablon?

Aby zaktualizować szablon i przejść na Topaz, One Page Shop, Dla Gastronomii, Rubin lub Szafir, należy skorzystać z aktualnej wersji Kreatora Wyglądu. Pamiętaj, że szablony Rubin i Szafir przeznaczone są tylko dla sklepów Enterprise i B2B. Odnośnik znajduje się również w panelu administracyjnym e-Sklepu w sekcji Wygląd sklepu > Kreator wyglądu.  Istnieją trzy możliwości aktualizacji tych szablonów:
  • Wygenerowanie zupełnie nowego szablonu w Kreatorze Wyglądu oraz wgranie go do e-Sklepu,
  • Wybór i edycja jednego z gotowych układów i jego modyfikacja,
  • Import posiadanego szablonu do Kreatora Wyglądu oraz ponowne wygenerowanie go w najnowszej wersji.
Wygenerowany z Kreatora Wyglądu szablon należy wgrać do e-Sklepu. W panelu administracyjnym e-Sklepu, w sekcji Wygląd sklepu znajduje się bezpośredni odnośnik do importu szablonu z Kreatora wyglądu. Szczegółowa instrukcja dostępna jest w artykule Jak wyeksportować i zaimportować swój szablon w e-Sklepie?
Pamiętaj o zapisaniu szablonu oraz opublikowaniu go w e-Sklepie. Zmiany wprowadzone w ustawieniach zostaną zsynchronizowane do sklepu po 10 minutach.
Wskazówka
Informacje na temat aktualizacji znajdują się w Centrum Pomocy: Jak zaktualizować szablon do najnowszej wersji?  
Więcej informacji na temat Kreatora Wyglądu B2C oraz B2B znajduje się w Centrum Pomocy:

Odpowiedni kontrast kolorów w e-Sklepie – wymóg WCAG na poziomie AA

Jednym z głównych wymogów WCAG jest stosowanie odpowiednich kontrastów na stronach internetowych. Jeśli w wybranym szablonie graficznym wykorzystujesz któryś ze standardowych motywów kolorystycznych dostępnych w kreatorach, to zostaną one dostosowane do wymagań wynikających z przepisów. Jeśli natomiast masz przygotowany własny motyw kolorystyczny lub chcesz zmienić część kolorów zastosowanych w szablonie, to pamiętaj, że muszą one posiadać odpowiednie kontrasty. Wszelkich zmian kolorystycznych możesz dokonać w Kreatorze Wyglądu.  Odpowiedni kontrast między tekstem a tłem jest kluczowy dla osób z dysfunkcjami wzroku. WCAG 2.1 określa minimalny współczynnik kontrastu (4.5:1 dla tekstu zwykłego i 3:1 dla tekstu dużego). Ważne jest również unikanie łączenia kolorów, które mogą być trudne do rozróżnienia, takich jak czerwony i zielony. Kontrasty po modyfikacji kolorów możesz sprawdzić np. narzędziem WAVE. WAVE to popularny, dostępny dla wszystkich zestaw narzędzi do oceny dostępności stron internetowych. Rozszerzenia WAVE dla Chrome, Firefox i Edge, umożliwiają testowanie bezpośrednio w tych przeglądarkach, bez przesyłania danych na serwer WAVE. WAVE znajdziesz pod linkiem: WAVE Web Accessibility Evaluation Tools.  

Jak sprawdzić kontrast?

Przejdź na stronę swojego e-Sklepu. Włącz wtyczkę WAVE. Po prawej stronie ekranu wyświetli się panel boczny, na pierwszej zakładce widać podsumowanie całej strony: Już na tym etapie możesz przejść do szczegółów, klikając "View details". Możesz w tym miejscu przejść także do zakładki "Contrast".   Czerwone kwadraty oznaczają obszar do poprawy. Przejdź przez stronę, aby zobaczyć szczegóły każdego z nich. Po kliknięciu na jeden z kwadratów pokaże się komunikat dotyczący kontrastu: W panelu bocznym pojawi się dokładna informacja na temat koloru. W tym miejscu, korzystając z suwaków możesz od razu dostosować kolor tak, aby był odpowiedni i sprawdzić, czy spełnia wymagania WCAG.  

Gdzie dostosować kolory?

Kolory w szablonie możesz zmienić korzystając z Kreatora Wyglądu. Po imporcie szablonu, edycji lub stworzeniu nowego projektu, przejdź do zakładki "Style" i edytuj motyw kolorystyczny:   Następnie możesz zmieniać swobodnie kolor na wybranych elementach:   Zmian możesz dokonać także z poziomu panelu administracyjnego, przechodząc do zakładki Wygląd Sklepu > Ustawienia.

Pozostałe zmiany

Poza zmianami w szablonie graficznym sklepu należy uzupełnić szereg danych. Znaczącą część tych elementów możesz wykonać już teraz, nie czekając na aktualizację Comarch e-Sklep. Poniżej znajduje się lista zmian, które należy wdrożyć w swoim e-Sklepie.

Teksty alternatywne ("Alt", alty) w Comarch e-Sklep

Twój szablon musi obsługiwać parametr "alt" w obrazkach. Jeśli wykorzystasz aktualny szablon standardowy od Comarch to obsługę zapewnia Comarch e-Sklep, jeśli zdecydowałeś się na indywidualny szablon lub samodzielną aktualizację starszej wersji to upewnij się, że w szablonie są obsługiwane parametry "alt" we wskazanych elementach. Teksty alternatywne („alt”) to krótkie opisy obrazków, które pozwalają osobom korzystającym z czytników ekranu zrozumieć, co znajduje się na zdjęciu. Atrybut „alt” jest szczególnie ważny dla zdjęć produktów, ponieważ umożliwia przekazanie najważniejszych informacji o produktach.  Dlaczego tekst alternatywny jest taki ważny? 
  • Pomaga osobom korzystającym z czytników ekranu, które odczytują tekst alternatywny na głos,
  • Poprawia dostępność stron internetowych, czyniąc je bardziej przyjaznymi dla wszystkich użytkowników,
  • Wpływa na pozycjonowanie w wyszukiwarkach, ponieważ dobrze opisane obrazy są lepiej interpretowane przez algorytmy Google.   
Dobrze sformułowany opis powinien być zwięzły, ale wystarczająco informacyjny. Poniżej prezentujemy przykłady dobrego i złego zastosowania opisów alternatywnych:
Przyklad
Poprawne :
  • Czerwona sukienka maxi z rozcięciem, modelka na tle miejskiego pejzażu.
  • Białe sneakersy z grubą podeszwą, ustawione na drewnianej podłodze.
  • Nowoczesna sofa w kolorze szarym, z drewnianymi nogami, ustawiona w minimalistycznym salonie.
  • Słuchawki bezprzewodowe z aktywną redukcją szumów, na białym tle.
Niepoprawne:
  • Sukienka.
  • Buty sportowe.
  • Fajna kanapa.
  • Najlepszy sprzęt w dobrej cenie!

Gdzie należy uzupełnić teksty alternatywne (alt)?

1. Dla zdjęć towarów w systemach Comarch ERP

Korzystam z Comarch ERP Optima
Po uruchomieniu Comarch ERP Optima przejdź na pozycję cennika, a następnie edytuj wybrany towar. Następnie przejdź na zakładkę "Atrybuty", a następnie do sekcji "Zdjęcia i załączniki". W tym miejscu zobaczysz kolumnę "Atrybut Alt".
Po dwukrotnym kliknięciu możliwe jest uzupełnienie opisu alternatywnego: Po dokonaniu zmian należy je zapisać. Po wykonaniu wszystkich modyfikacji należy wykonać synchronizację.

Korzystam z Comarch ERP XL

Po uruchomieniu ERP XL przejdź do Sprzedaż > Towary , a następnie na zakładkę "Załączniki". Opis alternatywny dla towaru stanowi Kod:    
Korzystam z Comarch ERP XT
Przejdź na kartę produktu, a następnie do zakładki "Zdjęcia". Wśród pól do uzupełnienia znajdziesz "Opis alternatywny (Alt)".   W tym miejscu wpisz odpowiednią treść, a następnie zapisz wprowadzone zmiany.  

2. Dla zdjęć w bannerach – w panelu administracyjnym Comarch e-Sklep

Pamiętaj, alby alty (opisy alternatywne) były uzupełnione także w przypadku bannerów. Aby to zrobić, przejdź z poziomu panelu administracyjnego do Wygląd sklepu > Ustawienia > Bannery  do edycji swoich bannerów. Klikając na odpowiedni kafelek pojawią się opcje z uzupełnieniem Alt:

3. Dla zdjęć stosowanych na stronach z treściami formalnymi – w panelu administracyjnym Comarch e-Sklep

Obrazki możesz dodawać także do treści, które udostępniasz na specjalnych stronach, takich jak np. Regulamin sklepu, Polityka prywatności, Wysyłka itp. W obszarze do edycji, który jest dostępny z poziomu panelu administracyjnego w sekcji Ustawienia > Treści formalne edytuj interesującą Cię treść, a dodając obrazek uzupełnij alt:    

4. Dla zdjęć wprowadzonych w opisie towaru i opisie kategorii

Dodając opisy produktów i kategorii, warto upewnić się, że linkowane zdjęcia zawierają poprawnie uzupełniony atrybut "alt". To kluczowe dla osób korzystających z czytników ekranu. Dbałość o ten detal poprawia dostępność strony i zwiększa jej widoczność w sieci. Opis towaru i kategorii możesz dodać w systemach Comarch ERP.  Opis kategorii możesz ustawić również z poziomu panelu administracyjnego, bez konieczności korzystania z systemu ERP. Szczegółowe informacje znajdują się w artykule: Jak edytować kategorię w Comarch e-Sklep? 

5. Dla zdjęć w Blogu

Obrazki, które dodawane są dla wpisów blogowych od wersji 2025.4 będą posiadały atrybuty ALT oraz Title. Ich uzupełnienie będzie możliwe przy przejściu z poziomu panelu administracyjnego Comarch e-Sklep do sekcji Marketing > Blog przy dodawaniu wpisu:

6. Dla zdjęć w plikach użytkownika w sekcji "Twoje pliki"

Pliki użytkownika w e-Sklepie to dedykowana przestrzeń do przechowywania własnych materiałów, które mogą zostać wykorzystane w sklepie internetowym. Pliki można przesyłać za pośrednictwem panelu administracyjnego, w sekcji Ustawienia > Twoje pliki. Maksymalny rozmiar pojedynczego pliku: 3 MB. Pliki, które dodawane są we wspomnianym obszarze, od wersji 2025.4 będą posiadały atrybuty ALT oraz Title. Ich uzupełnienie będzie możliwe przy przejściu z poziomu panelu administracyjnego do sekcji Ustawienia > Twoje pliki przy edycji pliku lub jego dodaniu.
Wskazówka
Jeśli posiadasz sklep wielojęzyczny, to we wszystkich tych wymienionych powyżej obszarach, znajdują się również obrazki dla danego języka. Pamiętaj, alby atrybut ALT zdefiniować dla każdego z nich!
 

Atrybut title - obowiązkowy czy nie?

Atrybut title jest przydatny do przekazywania dodatkowych informacji o elementach HTML, widocznych jako podpowiedź po najechaniu kursorem. Może być używany w ikonach bez podpisu, formularzach czy linkach, aby dostarczyć kontekst. Nie jest jednak obowiązkowy według WCAG, ponieważ czytniki ekranu często go ignorują, a osoby nawigujące klawiaturą mogą nie mieć do niego dostępu.  

Zalecenia dla udostępnianych treści - ogranicz migające elementy

Jako właściciel sklepu musisz sam zadbać o to, jakie treści umieszczasz na swojej stronie. Migające elementy, takie jak animacje czy reklamy, mogą wywoływać problemy u osób z padaczką fotogenną. Według kryteriów WCAG 2.1 zalecane jest ograniczenie migających treści do maksymalnie trzech błysków na sekundę lub ich całkowite usunięcie. Jako właściciel sklepu musisz dbać o statyczne elementy lub spokojne animacje. Również treści zawarte w różnego typu prospektach, gazetkach czy folderach informacyjnych w formie dokumentów powinny być zgodne z wytycznymi WCAG.

1.Obrazki i bannery

W szablonach graficznych takie elementy mogą pojawić się na przykład w bannerach i elementach tekstowych ze zdjęciem. Upewnij się, że grafiki tam zamieszczone są odpowiednie, czyli bez intensywnych animacji i nieodpowiednich kolorów. Szczególną uwagę zwróć na pliki w formacie GIF. Sprawdź, w jaki sposób możesz skonfigurować bannery oraz elementy tekstowe ze zdjęciem.  

2.Materiały audio i viedo

Aby sklep internetowy był w pełni dostępny zgodnie z WCAG, właściciele muszą zadbać o dodanie audiodeskrypcji i transkrypcji do materiałów multimedialnych (filmy, nagrania dźwiękowe). Choć oba rozwiązania służą poprawie dostępności, mają różne funkcje.
  • Audiodeskrypcja to dodatkowy opis dźwiękowy, który przedstawia istotne elementy wizualne nagrania osobom niewidzącym,
  • Transkrypcja to zapis tekstowy całej treści audio, umożliwiający odbiór treści osobom niesłyszącym, może to być w formie napisów dla audiodeskrypcji.
Dodanie tych elementów leży po stronie właścicieli sklepów. Do filmów, które udostępniasz, dodaj zatem widoczne napisy, a także dobrej jakości opis dźwiękowy. Ich brak może wykluczyć część użytkowników i wpłynąć na komfort korzystania ze strony. Dobre praktyki dostępności to nie tylko wymóg, ale też inwestycja w lepsze doświadczenie klientów.

Dostosuj komunikację mailową - aktualizacja lub zmiana treści e-mail

Dostosowanie treści e-mail zgodnie z wytycznymi WCAG to kluczowy krok w budowaniu dostępnej i klarownej komunikacji. W tej części artykułu przedstawiamy rozwiązania zarówno dla domyślnych wiadomości, jak i tych modyfikowanych, aby zapewnić ich lepszą czytelność i dostępność dla wszystkich odbiorców.

1.Treści mailowe są domyślne, nie zostały sformatowane

Jeśli treści nie zostały przez Ciebie zmienione i stanowią domyślne treści, które są dostępne w Comarch e-Sklep, to wystarczy, że zaktualizujesz je. Aby to zrobić, należy przejść w panelu administracyjnym do zakładki Ustawienia > Treści formalne, a następnie wybrać „Wysyłka e-mail i SMS”. Zakładka ta zawiera treści wiadomości wysyłane do klientów po wykonaniu określonych akcji, np. po zakupie czy rejestracji. W Comarch e-Sklep istnieje możliwość przywrócenia standardowej treści pojedynczej wiadomości e-mail lub wszystkich jednocześnie. Opcja ta stanowi również aktualizację treści e-mail. "Przywróć domyślną treść" dostępna jest w panelu administracyjnym e-Sklepu w menu Ustawienia/ Treści formalne/ Wysyłka e-mail i SMS na szczegółach każdej wiadomości, po kliknięciu w przycisk Więcej:  

2.Treści mailowe są modyfikowane, zostały przeze mnie zmienione

Jeśli posiadasz własne, dostosowane do Twojej komunikacji marketingowej treści e-mail, to sprawdź, czy są one odpowiednio napisane i sformatowane. Zastosuj się do poniższych wskazówek. W jaki sposób poprawnie napisać i sformatować treści?
  • Struktura Stosuj nagłówki (<h1>, <h2> itd.) dla przejrzystości. Używaj krótkich akapitów i list punktowanych.
  • Tekst i formatowanie Zapewnij wysoki kontrast między tekstem a tłem. Wybieraj czytelne czcionki (sans-serif, min. 12-14 px). Nie używaj wyłącznie koloru do przekazywania informacji.
  • Obrazy i multimedia Dodawaj tekst alternatywny (alt text) do obrazów. Unikaj tekstu osadzonego w grafikach, jeśli można go przesłać jako tekst.
  • Linki i przyciski Stosuj opisowe teksty linków zamiast „Kliknij tutaj”. Upewnij się, że są łatwe do kliknięcia na ekranach dotykowych.
  • Język i czytelność Używaj prostego i zrozumiałego języka. Unikaj skrótów i branżowego żargonu, jeśli odbiorca może ich nie znać.
  • Testowanie Sprawdź wiadomość na różnych urządzeniach i czytnikach ekranu. Zweryfikuj zgodność ze standardami WCAG.
Szczegółowe informacje na temat edycji treści e-mail znajdują się a artykule: E-mail i SMS  

3.Załączniki (m.in. instrukcje, katalogi)

Należy zadbać o to, aby wszystkie udostępniane w sklepie załączniki, takie jak instrukcje czy katalogi, były zgodne z wytycznymi WCAG, zapewniając tym samym ich pełną dostępność dla wszystkich użytkowników.  

Dodatkowe narzędzia pomocne przy wdrażaniu WCAG

Przystosowanie e-Sklepu do wymogów nie musi wiązać się z dużymi wydatkami na zmiany w kodzie. Kluczowe aspekty dostępności można wdrożyć samodzielnie, wykorzystując opcje dostępne w systemach Comarch ERP, a także Kreatorze Wyglądu czy Panelu Administracyjnym. Warto pamiętać, że poprawa dostępności to nie tylko obowiązek wynikający z przepisów, ale także realna szansa na zwiększenie grona klientów oraz podniesienie komfortu ich zakupów. Istnieje kilka ogólnodostępnych narzędzi, które pomogą Ci dostosować sklep do wymogów. Obszerna lista narzędzi do oceny dostępności stron internetowych, zgodnych z WCAG znajduje się na stronie: Web Accessibility Evaluation Tools List .  

Podsumowanie

Dostępność cyfrowa to nie jednorazowe przedsięwzięcie, lecz ciągły rozwój i udoskonalanie. Regularne sprawdzanie funkcjonalności, optymalizacja elementów wizualnych i dostosowywanie sposobów interakcji pozwalają na stałe podnoszenie jakości doświadczeń użytkowników. Dążenie do pełnej zgodności ze standardami WCAG 2.1/2.2 oraz wymogami Europejskiego Aktu o Dostępności (EAA) nie tylko ułatwia nawigację wszystkim odwiedzającym, ale także buduje pozytywny wizerunek i wzmacnia pozycję na rynku. Wdrażanie kolejnych usprawnień to inwestycja w przyszłość, która przynosi korzyści zarówno właścicielom, jak i ich klientom.

Jak zaprezentować banner w liście towarów dla szablonu Topaz?

Wstęp

Banner prezentowany na listach towarowych Twojego e-Sklepu przyciągnie uwagę klientów i pomoże zwiększyć sprzedaż. Dzięki wyrazistym grafikom i atrakcyjnym komunikatom można promować konkretne produkty, sezonowe promocje lub nowości, wyróżniając je spośród innych ofert. Sprawdź jak łatwo można dodać i skonfigurować banner, który będzie wyświetlany na listach towarowych w Twoim sklepie.

Jak dodać banner do listy towarów?

Krok 1. Banner możesz dodać z poziomu Kreatora Wyglądu B2C  (zamiennie: panel administracyjny e-Sklepu: Wygląd sklepu > Kreator wyglądu).W Kreatorze banner znajduje się w sekcji Lista towarów > Banner w liście towarów. Aby dodać banner wystarczy w niego kliknąć:
Wskazówka
Aby zmienić banner wystarczy kliknąć inny banner, natomiast aby go usunąć należy ponownie kliknąć na dodany banner.
Krok 2. Ustawienia banneru możesz skonfigurować zarówno z poziomu Kreatora Wyglądu jak i panelu administracyjnego. W Kreatorze Wyglądu po dodaniu banneru do listy towarowej kliknij w symbol ustawień a następnie przejdź do zakładki Banner w liście towarów: Krok 3. Szablon z tak przygotowanym bannerem należy wygenerować. Po zaimportowaniu szablonu do panelu administracyjnego możesz przejść do dalszej konfiguracji. Krok 4. Przejdź do ustawień Wygląd sklepu > Ustawienia > Bannery. W tej sekcji znajdź banner o nazwie banner-in-list-1 lub jeśli wybrałeś drugą opcję to banner-in-list-2, a następnie przejdź do jego edycji. Krok 5. Za pomocą ikony plusa dodaj obrazek w rozmiarze 720x300 dla banner-in-list-1 lub 1400x300 dla banneru banner-in-list-2. Po przesłaniu właściwego obrazka kliknij na Widok zaawansowany, aby przejść do edycji pozostałych elementów.
Wskazówka
Pamiętaj o tym, aby zapisać i opublikować wprowadzone zmiany.
Krok 6. Gotowe! Twój banner będzie prezentował się w sklepie następująco:
Wskazówka
Ustawienia banneru osadzongo w liście towarów możesz zmienić także w panelu administracyjnym przechodząc do zakładki Wygląd sklepu > Ustawienia > Zarządzanie elementami na liście towarów.

Jak dodać wiele linków do banneru top?

Wstęp

Banner top jest bannerem, który wyświetla się na samej górze witryny. Ma on na celu wyróżnić informacje, które chcesz przekazać swoim klientom. Z tego względu w ramach banneru top możesz dodać zarówno treść, jak również linki, które będą prowadzić do istotnych obszarów. Dzięki temu możesz zaprezentować klientom informacje o ofercie w Twoim sklepie. Wskazana prezentacja wielu linków możliwa jest w szablonach Topaz oraz Dla gastronomii.

Jak zaprezentować wiele linków w bannerze top?

Krok 1. Aby ustawić wskazany banner według własnych potrzeb przejdź do sekcji Wygląd sklepu > Ustawienia > Bannery. W tym miejscu powinien znajdować się banner o nazwie top: Krok 2. W ramach edycji banneru przejdź do sekcji Widok zaawansowany: Krok 3. Po otwarciu wskazanego widoku masz możliwość kilku opcji konfiguracji banneru top - w ramach domyślnych ustawień dla banneru wypełniona jest sama treść. Do banneru można dodać także link. W takim wypadku całość banneru top będzie klikalna, a wypełniony tekst zostanie zaprezentowany na środku banneru: Krok 4. Do banneru top można dodać dodatkowe linki. Należy to zrobić wchodząc do edycji banneru lub poprzez opcję Dodaj więcej linków: Krok 5. Z poziomu wskazanej opcji w zakładce Linki za pomocą przycisku plusa masz możliwość dodania linku: Następnie możesz wprowadzić nazwę, dodać link oraz zadecydować czy ma się on otwierać w nowym oknie:
Wskazówka
Aby prezentować wiele linków w szablonie należy uzupełnić link i nazwę dla linku domyślnego.
Dzięki dodaniu wielu linków masz możliwość ich prezentacji banneru top w następujący sposób:
    • Jeżeli w bannerze top wskazany został tekst: zostanie on przesunięty do lewej strony, a po prawej stronie w ramach tej opcji będzie wyświetlane do 4 linków:
    • W przypadku, gdy potrzebujesz więcej linków możesz zrezygnować z wypełnionego tekstu – dzięki temu na bannerze top będziesz mógł dodać do 6 linków:
Wskazówka
Opcja wielu linków w bannerze top jest możliwa do skonfigurowania wraz z odliczaniem czasu. W ramach takiej konfiguracji możliwe jest wyświetlenie do 4 linków. Informacje o konfiguracji banneru top z odliczaniem czasu można znaleźć w artykule Jak zaprezentować banner z odliczaniem czasu w szablonach B2C? W takim przypadku należy uzupełnić konfigurację linków, ustawić opcję odliczania czasu, jak również uzupełnić pole "Tekst". Dzięki temu banner top zyska następujący wygląd:
 

Banner promocyjny w szablonie Topaz i One Page Shop

Banner promocyjny - jak to działa?

Banner promocyjny wyświetli się na stronie głównej Twojego e-Sklepu i będzie prezentował typ towaru, który wskażesz. Taki rodzaj banneru pomoże Ci w zwróceniu uwagi Klientów na towary, które zostały objęte na przykład ofertą specjalną.

Dodanie banneru

Banner możesz dodać z poziomu Kreatora Wyglądu B2C  (zamiennie: panel administracyjny e-Sklepu: Wygląd sklepu/ Kreator wyglądu). Aby dodać banner promocyjny do swojego szablonu, przejdź na stronę "Strona główna", po czym wybierz Banner promocyjny i przeciągnij go w wybrane przez Ciebie miejsce. W podglądzie układu szablonu, po najechaniu kursorem na obszar z bannerem promocyjnym, zobaczysz możliwość jego edycji. Wybierz ikonę "zębatki", aby móc edytować i określić liczbę wyświetlanych towarów oraz typ promowanych towarów. Zapisz wprowadzone zmiany. Jeśli pozostałe strony szablonu są gotowe i skonfigurowane, to możesz wygenerować szablon. Więcej informacji na temat Kreatora Wyglądu oraz poszczególnych sekcji znajdziesz w artykule: Kreator wyglądu Topaz (B2C) Po zaimportowaniu szablonu do panelu administracyjnego możesz przejść do edycji banneru. Postępuj zgodnie z poniższą instrukcją.

Edycja banneru

Modyfikacja wszystkich bannerów dostępnych w szablonach Comarch możliwa jest w panelu administracyjnym w obszarze Wygląd sklepu> Ustawienia> Bannery. Informacje odnośnie domyślnej, tradycyjnej modyfikacji bannerów znajdują się w artykule: Bannery

Odnajdź banner na liście nazwany "promotionalBanner", a następnie wybierz go, aby edytować i dodać zdjęcie

Po dokonaniu modyfikacji należy zapisać i opublikować zmiany. Gotowe! Teraz Twój banner promocyjny wyświetli się na stronie głównej.
Banner promocyjny w szablonie Topaz
Banner promocyjny w szablonie Topaz.

Jak dodać obrazek do nazwy kategorii i podkategorii w Comarch e-Sklep?

Wstęp

W Comarch e-Sklep możesz dodawać obrazki zarówno dla kategorii jak i dla podkategorii towarów. Odpowiednio dobrane grafiki zwiększają atrakcyjność wizualną sklepu, przyciągają wzrok klientów i zachęcają do dalszego przeglądania ofert w Twoim sklepie. Dodatkowo ułatwiają one nawigację i skracają czas poszukiwań Twoich klientów. W tym artykule dowiesz się, w jaki sposób skonfigurować funkcję dodawania zdjęć do kategorii i podkategorii w Twoim sklepie.

Jak dodać zdjęcie do nazwy kategorii w Comarch e-Sklep?

Comarch ERP Optima

Krok 1. Aby dodać zdjęcia kategorii w Comarch ERP Optima przejdź do zakładki Ogólne > Grupy towarowe i wybierz grupę do której ma zostać dodane zdjęcie.

Krok 2. Następnie na zakładce Atrybuty za pomocą symbolu Plusa dodaj atrybut binarny.

Wskazówka
Jeśli nie posiadasz atrybutu binarnego to aby go utworzyć przejdź do zakładki Ogólne > Atrybuty i w pierwszej zakładce symbolem Plusa dodaj atrybut w formacie binaria.

Krok 3. Po dodaniu zdjęć kategorii zmiany zapisz ikoną dyskietki oraz wykonaj synchronizację.

Comarch ERP XL

Wyświetlanie zdjęć kategorii w Comarch ERP XL możesz uzyskać poprzez dodanie odpowiedniego Załącznika. Krok 1. Aby wprowadzić zdjęcie w formie załącznika przejdź w module Sprzedaż do zakładki Ogólne > Towary i wejdź w edycję wybranej grupy. Krok 2. W zakładce Załączniki dodaj nowy załącznik ikoną Plusa. W polu Typ wskaż typ załącznika Obraz oraz zaznacz przy parametrze "Dostępność w aplikacji" e-Sklep. Następnie zaimportuj obraz ikoną z czerwoną strzałką. 3. Zmiany zapisz ikoną dyskietki oraz wykonaj synchronizację.

Comarch Betterfly

Krok 1. Zdjęcia kategorii w Comarch Betterfly możesz dodać po wybraniu Więcej funkcji > Comarch e-Sklep > Grupy w Comarch e-Sklep. Krok 2. Aby wprowadzić obrazek dla kategorii wybierz grupę do której chcesz dodać zdjęcie. Następnie wczytaj je wybierając jedną z 2 opcji: Z dysku lub Z internetu. Krok 3. Zapisz wprowadzone zmiany i wykonaj synchronizację.

Jak ustawić dodane zdjęcie jako ikonkę w nagłówku szablonu Topaz?

W szablonie Topaz istnieje możliwość ustawienia dodanych zdjęć kategorii jako ikonek przy nazwach kategorii w Twoim sklepie. Ta funkcja obsługuje nagłówki: header-1, header-2, header-3 oraz header-5, które są dostępne w Kreatorze Wyglądu. Zdjęcia w postaci ikon wyświetlają się w następujący sposób:
Widok nagłówka header-2 ze sklepu demonstracyjnego - https://demo.comarchesklep.pl/
Krok 1. Skonfiguruj funkcję wyświetlania się ikon nagłówka. Istnieją dwie możliwości konfiguracji tej funkcji:
  • Z poziomu Kreatora Wyglądu – Podczas tworzenia szablonu Topaz w Kreatorze Wyglądu dodaj nagłówek header-1,2,3 lub 5. Następnie przejdź do jego edycji i oznacz parametr „Ukryj ikony w nagłówku” na „tak”:
Zapisz zmiany, a następnie wygeneruj szablon.
  • Z poziomu panelu administracyjnego – W sytuacji gdy wgrałeś już wygenerowany szablon do Twojego sklepu i chcesz wprowadzić zmiany w zakresie wyświetlania się obrazków przy nazwach kategorii, przejdź do sekcji Wygląd sklepu > Ustawienia > Dodatkowe i wprowadź zmiany przy parametrze „Ukryj ikony w nagłówku”:
Wprowadzone zmiany zapisz i opublikuj.
Krok 2. Wgraj zdjęcia kategorii do Twojego systemu ERP. Informacje na temat jak wgrać zdjęcia kategorii do poszczególnych systemów ERP znajdziesz pod pierwszym punktem tego artykułu.
Wskazówka
Na stronie „Produkty” wyświetlają się zdjęcia kategorii. Należy pamiętać, iż jeśli w systemie ERP zostanie dodany obrazek kategorii w formie ikony, to taki sam obrazek wyświetli się na stronie „produkty”. Nie istnieje możliwość dodania dwóch osobnych zdjęć do nagłówka i do strony „Produkty”.

Jak mogę dodać zdjęcie do nazwy podkategorii?

W takich szablonach jak Topaz i dla Gastronomii istnieje możliwość dodania obrazków, które będą wyświetlały się przy nazwach podkategorii w Twoim sklepie. Ta funkcja obsługuje wszystkie układy list towarów: products-1, products-2, products-3, products-4, które są dostępne w Kreatorze Wyglądu. Obrazki do nazw podkategorii wyświetlają się w następujący sposób:
Widok zdjęć podkategorii na liście towarów ze sklepu demonstracyjnego - https://demo.comarchesklep.pl/
Aby dodać zdjęcia do podkategorii postępuj według poniższych kroków: Krok 1. Skonfiguruj funkcję wyświetlania podkategorii. Istnieją dwie możliwości konfiguracji tej funkcji:
  • Z poziomu Kreatora Wyglądu - Tworząc szablon Topaz lub dla Gastronomii przejdź do edycji Listy towarów w Kreatorze Wyglądu. Następnie dodaj układ listy towarów: products-1,2,3 lub 4 i edytując go oznacz parametr "Udostępnij zdjęcia podkategorii".
Zapisz zmiany, a następnie wygeneruj szablon.
  • Z poziomu panelu administracyjnego - W sytuacji gdy wgrałeś już wygenerowany szablon do Twojego sklepu i chcesz wprowadzić zmiany w zakresie wyświetlania się obrazków przy nazwach podkategorii, przejdź do sekcji Wygląd sklepu > Ustawienia > Ogólne i oznacz parametr "Udostępnij zdjęcia podkategorii":
Zapisz i opublikuj wprowadzone zmiany. Krok 2. Dodaj obrazki do podkategorii w systemie ERP. Skonfigurujesz je w podobny sposób jak obrazki dla kategorii, które zostały opisane w pierwszej części artykułu.

Więcej informacji

Więcej na temat dodawania obrazków w e-Sklepie można przeczytać w artykułach:

Modyfikacja informacji wyświetlanych na kaflu towaru

W Kreatorze Wyglądu Topaz powstała funkcja pozwalająca na modyfikację informacji wyświetlanych na kaflu towaru. Po wybraniu widoku listy towarów i stylu kafli, przechodząc do ustawień tej sekcji, masz możliwość edycji informacji o towarze, które będą widoczne na kaflu towaru. Dostępne są dwa widoki zdjęć kategorii: lista oraz mozaika. Domyślnie zaznaczona jest lista. Aby dokonać modyfikacji informacji na kaflu, musisz przejść do zakładki „Kafle”.  Jeśli korzystasz z list towarów 3 lub 4, masz możliwość edycji następujących informacji:
  • Kupowanie z listy towarów
  • Dodawanie do ulubionych z listy towarów
  • Prezentowanie drugiego zdjęcia towaru
  • Graficzna prezentacja wariantów towaru
  • Dodatkowe informacje na kaflu
  • Dodatkowe funkcje na kaflu
W przypadku list towarów 1 i 2, modyfikacja informacji jest uproszczona, ogranicza się jedynie do:
  • Kupowanie z listy towarów
  • Dodawanie do ulubionych z listy towarów
  • Prezentowanie drugiego zdjęcia towaru

One Page Shop - cały sklep na jednej stronie

Instrukcja: Jak dostosować samodzielnie szablon do szybkich zwrotów w e-Commerce?

Wskazówka
Wskazówka: W tym artykule trzeba będzie wprowadzać zmiany w plikach js oraz scss. Z tego artykułu dowiesz się jak je kompilować i minifikować.
W szablonach Rubin, Szafir oraz Topaz / One Page Shop wprowadziliśmy funkcję szybkich zwrotów. Umożliwia ona klientom składanie wniosku o zwrot produktu zarówno z poziomu profilu klienta (zalogowani), jak i z dedykowanej strony zwrotów po podaniu numeru zamówienia oraz adresu e-mail (niezalogowani). Wraz z funkcjonalnością pojawił się m.in. rozbudowany ekran potwierdzenia zwrotu zawierający kolejne kroki i adres do wysyłki, banery informacyjne dotyczące terminu zwrotu oraz przyciski akcji w tabeli produktów wyświetlane bezpośrednio (zamiast w rozwijanym menu). Aby Twój szablon poprawnie obsługiwał te zmiany, wprowadź modyfikacje opisane poniżej w sekcji dotyczącej Twojego szablonu. Po zakończeniu edycji pamiętaj o kompilacji i minifikacji plików js oraz scss.
Wskazówka
Potrzebujesz pomocy lub masz pytania? Skontaktuj się z nami poprzez portal asysta.comarch.pl.
Wskazówka
Obecnie w Polsce trwają prace nad ostatecznym kształtem przepisów oraz nowelizacją Ustawy o prawach konsumenta, która wdroży unijną dyrektywę UE 2023/2673 i wprowadzi nowe wymagania techniczne dla platform e-commerce (m.in. ułatwienia w procedurze zwrotów). W momencie publikacji ostatecznej wersji polskich przepisów, wdrożone funkcjonalności mogą wymagać dostosowania do ostatecznych wytycznych ustawodawcy. Prezentowane informacje mają charakter poglądowy a instrukcja dotyczy zmian, jakie wprowadziliśmy w szablonach Comarch – w przypadku pytań dotyczących indywidualnej sytuacji prawnej Twojego sklepu, zalecamy konsultację z radcą prawnym lub adwokatem.

Szablon Rubin

1. Tłumaczenia

W panelu administracyjnym sklepu zaktualizuj dwa istniejące tłumaczenia oraz dodaj nowe klucze wymagane przez funkcjonalność szybkich zwrotów. Zaktualizuj poniższe istniejące tłumaczenia: ReturnSuccessTitle - PL: Gotowe! Przyjęliśmy Twoje zgłoszenie - EN: Done! We have received your request - DE: Fertig! Wir haben Ihre Anfrage erhalten - FR: C'est fait ! Nous avons reçu votre demande ReturnSuccessInfo - PL: Przygotuj paczkę i odeślij ją do nas – wszystkie szczegóły znajdziesz poniżej. - EN: Prepare the package and send it back to us – all the details are below. - DE: Bereiten Sie das Paket vor und senden Sie es an uns zurück – alle Details finden Sie unten. - FR: Préparez le colis et renvoyez-le nous – tous les détails sont ci-dessous. Dodaj nowe tłumaczenia: OrderReturnDeadlineInfo - PL: Zamówienie można zwrócić w ciągu {0} dni od daty dostawy. - EN: You can return the order within {0} days from the delivery date. - DE: Sie können die Bestellung innerhalb von {0} Tagen ab Lieferdatum zurückgeben. - FR: Vous pouvez retourner la commande dans les {0} jours suivant la date de livraison. RestrictedOrderViewInfo - PL: Wybrane dane zamówienia zostały ukryte ze względów bezpieczeństwa. Możesz zwrócić produkty bez logowania. - EN: Some order details are hidden for security reasons. You can return products without signing in. - DE: Einige Bestelldetails wurden aus Sicherheitsgründen ausgeblendet. Sie können Produkte ohne Anmeldung zurücksenden. - FR: Certaines informations de la commande ont été masquées pour des raisons de sécurité. Vous pouvez retourner des produits sans vous connecter. Com_RefundMethod - PL: Sposób zwrotu środków - EN: Refund method - DE: Rückerstattungsmethode - FR: Mode de remboursement Com_RefundAsPaid - PL: Tak jak zapłacono - EN: Same as paid - DE: Wie bezahlt - FR: Comme payé Com_RefundToBankAccount - PL: Na konto bankowe - EN: To bank account - DE: Auf Bankkonto - FR: Sur le compte bancaire Com_BankAccountNumber - PL: Nr konta bankowego - EN: Bank account number - DE: Bankkontonummer - FR: Numéro de compte bancaire Com_ConfirmationSentTo - PL: Potwierdzenie zwrotu zostało wysłane na adres: - EN: Return confirmation has been sent to: - DE: Bestätigung wurde gesendet an: - FR: La confirmation de retour a été envoyée à: Com_NextSteps - PL: Następne kroki - EN: Next Steps - DE: Nächste Schritte - FR: Prochaines étapes Com_PackProducts - PL: Bezpiecznie zapakuj swoje produkty - EN: Safely pack your products - DE: Verpacken Sie Ihre Produkte sicher - FR: Emballez vos produits en toute sécurité Com_SendPackageTo - PL: Wyślij paczkę na adres: - EN: Send the package to the address: - DE: Senden Sie das Paket an die Adresse: - FR: Envoyez le colis à l'adresse: Com_RefundAfterReceive - PL: Pieniądze zwrócimy niezwłocznie po otrzymaniu i sprawdzeniu Twojej paczki - EN: We will refund the money promptly upon receipt and inspection of your package - DE: Wir erstatten das Geld umgehend nach Erhalt und Überprüfung Ihres Pakets zurück - FR: Nous rembourserons l'argent rapidement après réception et inspection de votre colis ReturnInThreeSteps - PL: Zwróć towar w 3 krokach - EN: Return the product in 3 steps - DE: Geben Sie die Ware in 3 Schritten zurück - FR: Retournez la marchandise en 3 étapes ReturnWithoutReasonInfo - PL: Przysługuje Ci możliwość zwrotu bez podania przyczyny. - EN: You have the right to return the product without giving a reason. - DE: Sie haben das Recht, die Ware ohne Angabe von Gründen zurückzugeben. - FR: Vous avez le droit de retourner la marchandise sans donner de motif. OrEnterOrderNumber - PL: lub podaj numer zamówienia - EN: or enter the order number - DE: oder geben Sie die Bestellnummer ein - FR: ou saisissez le numéro de commande FillForm - PL: Wypełnij formularz - EN: Fill out the form - DE: Füllen Sie das Formular aus - FR: Remplissez le formulaire ReturnOnline - PL: zwrotu online - EN: online return - DE: Online-Rückgabe - FR: retour en ligne SendParcel - PL: Wyślij paczkę - EN: Send the parcel - DE: Paket senden - FR: Envoyer le colis SendParcelToOurAddress - PL: nadaj przesyłkę na nasz adres - EN: send the parcel to our address - DE: senden Sie das Paket an unsere Adresse - FR: envoyez le colis à notre adresse FastSimpleSecure - PL: Szybko, prosto i bezpiecznie. - EN: Fast, simple and secure. - DE: Schnell, einfach und sicher. - FR: Rapide, simple et sécurisé. ReadyForReturn - PL: Gotowy do zwrotu? - EN: Ready for return? - DE: Bereit zur Rückgabe? - FR: Prêt pour le retour ? ReadyForReturnInfo - PL: Kliknij poniżej, aby rozpocząć proces zwrotu. Przeprowadzimy Cię przez wszystkie kroki. - EN: Click below to start the return process. We will guide you through all the steps. - DE: Klicken Sie unten, um den Rückgabeprozess zu starten. Wir führen Sie durch alle Schritte. - FR: Cliquez ci-dessous pour lancer le processus de retour. Nous vous guiderons à travers toutes les étapes. StartReturn - PL: Rozpocznij zwrot - EN: Start return - DE: Rückgabe starten - FR: Commencer le retour ProductReturn - PL: Zwrot produktu - EN: Product return - DE: Produktrückgabe - FR: Retour du produit ProductReturnFormInfo - PL: Wprowadź dane zamówienia, aby zlokalizować zakup i rozpocząć proces zwrotu. Numer zamówienia znajdziesz w e-mailu z potwierdzeniem. - EN: Enter the order details to locate the purchase and start the return process. You will find the order number in the confirmation e-mail. - DE: Geben Sie die Bestelldaten ein, um den Kauf zu lokalisieren und den Rückgabeprozess zu starten. Die Bestellnummer finden Sie in der Bestätigungs-E-Mail. - FR: Saisissez les données de la commande pour localiser l'achat et démarrer le processus de retour. Vous trouverez le numéro de commande dans l'e-mail de confirmation. InvalidOrderNumber - PL: Błędny numer zamówienia. Spróbuj ponownie. - EN: Invalid order number. Please try again. - DE: Ungültige Bestellnummer. Bitte versuchen Sie es erneut. - FR: Numéro de commande incorrect. Veuillez réessayer. FindOrder - PL: Znajdź zamówienie - EN: Find order - DE: Bestellung finden - FR: Trouver la commande LoginToSeeOrdersAndReturn - PL: aby zobaczyć swoje zamówienia i dokonać zwrotu. - EN: to see your orders and make a return. - DE: um Ihre Bestellungen einzusehen und eine Rückgabe vorzunehmen. - FR: pour voir vos commandes et effectuer un retour. RefundLookupError - PL: Wystąpił błąd podczas wyszukiwania zamówienia. Spróbuj ponownie później. - EN: An error occurred while searching for the order. Please try again later. - DE: Bei der Suche nach der Bestellung ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut. - FR: Une erreur s'est produite lors de la recherche de la commande. Veuillez réessayer plus tard.

2. Nowa strona Szybkie zwroty

Funkcjonalność szybkich zwrotów wymaga utworzenia dodatkowej strony statycznej refunds. Wykonaj poniższe kroki.

Plik refunds.html w katalogu głównym szablonu

W katalogu głównym szablonu utwórz nowy plik refunds.html z następującą zawartością:
{% extends '_layout.html' -%}

{% block pageContent -%}
{% include 'static-elements/refunds/refunds.html' -%}
{% endblock -%}

Plik static-elements/refunds/refunds.html

W folderze static-elements utwórz nowy katalog refunds, a w nim plik refunds.html:
<div class="page-padding">
    <h1 class="refunds-page-title refunds-initial-view-js">{{ translations.Returns }}</h1>
    <section class="refunds-container refunds-initial-view-js">
        <div class="refunds-info">
            <h2 class="refunds-info__title">{{ translations.ReturnInThreeSteps }}</h2>
            <p class="refunds-info__intro">{{ translations.ReturnWithoutReasonInfo }}</p>
            <ol class="refunds-steps">
                <li class="refunds-steps__item">
                    <span class="refunds-steps__number">1</span>
                    <p class="refunds-steps__text"><strong>{{ translations.LogIn }}</strong> {{ translations.OrEnterOrderNumber }}</p>
                </li>
                <li class="refunds-steps__item">
                    <span class="refunds-steps__number">2</span>
                    <p class="refunds-steps__text"><strong>{{ translations.FillForm }}</strong> {{ translations.ReturnOnline }}</p>
                </li>
                <li class="refunds-steps__item">
                    <span class="refunds-steps__number">3</span>
                    <p class="refunds-steps__text"><strong>{{ translations.SendParcel }}</strong> - {{ translations.SendParcelToOurAddress }}</p>
                </li>
            </ol>
            <p class="refunds-info__hint">{{ translations.FastSimpleSecure }}</p>
        </div>
        <div class="refunds-cta">
            <div class="refunds-cta__header">
                <h3 class="refunds-cta__title">{{ translations.ReadyForReturn }}</h3>
                <p class="refunds-cta__description">{{ translations.ReadyForReturnInfo }}</p>
            </div>
            {% if usr.Authenticated -%}
            <a class="primary-action-button refunds-cta__button" href="{{ config.DefinedPages.CustomerProfile.Url }}?tab=orders" rel="nofollow" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </a>
            {% else -%}
            <button class="primary-action-button refunds-cta__button start-refund-js" type="button" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </button>
            {% endif -%}
        </div>
    </section>
    {% unless usr.Authenticated -%}
    <section class="refund-form-section refund-form-view-js hidden-js">
        <div class="refund-form">
            <div class="refund-form__header">
                <h2 class="refund-form__title">{{ translations.ProductReturn }}</h2>
                <p class="refund-form__description">{{ translations.ProductReturnFormInfo }}</p>
            </div>
            <form class="refund-form__body refund-form-js" novalidate="" data-error="{{ translations.RefundLookupError }}">
                <div class="form__input-wrapper">
                    <label class="form__input-info input-info-js" for="refundOrderNumber">{{ translations.NumberOfOrder }}</label>
                    <input id="refundOrderNumber" class="form__input-value input-value-js" maxlength="50" name="orderNumber" required="" type="text" />
                    <div class="form__invalid-input validation-info-js validation-required-js hidden-js">{{ translations.FieldRequired }}</div>
                </div>
                <div class="form__input-wrapper">
                    <label class="form__input-info input-info-js" for="refundEmail" data-type="email">{{ translations.EmailAddress }}</label>
                    <input id="refundEmail" class="form__input-value input-value-js" autocomplete="email" maxlength="192" name="email" required="" type="email" />
                    <div class="form__invalid-input validation-info-js validation-required-js hidden-js">{{ translations.FieldRequired }}</div>
                    <div class="form__invalid-input validation-info-js email-valid-js hidden-js">{{ translations.FillProperEmail }}</div>
                </div>
                <button class="primary-action-button refund-form__submit refund-form-submit-js" type="button">
                    {{ translations.FindOrder }}
                </button>
                <p class="refund-form__login-info">{{ translations.HaveAccount }} <a class="refund-form__login-link show-login-popup-js" tabindex="0" role="button" rel="nofollow">{{ translations.LogIn }},</a> {{ translations.LoginToSeeOrdersAndReturn }}</p>
            </form>
        </div>
    </section>
    {% endunless -%}
</div>

Plik js/layout1.js – kod obsługi formularza zwrotu

Na końcu pliku js/layout1.js dodaj poniższy kod odpowiedzialny za walidację i wysłanie formularza wyszukiwania zamówienia (dla niezalogowanego klienta):
$(document).ready(function() {
    refunds.init();
})

const refunds = {
    init: function() {
        this.events();
    },

    findRefundOrder: function(orderNumber, email) {
        return $.post('', {
            __action: 'Order/QuickReturnLookup',
            orderId: orderNumber,
            email: email,
            __csrf: __CSRF
        });
    },

    showForm: function() {
        $('.refunds-initial-view-js').addClass('hidden-js');
        $('.refund-form-view-js').removeClass('hidden-js');
        $('.refund-form-js input[name="orderNumber"]').trigger('focus');
    },

    clearFieldError: function(input) {
        const $input = $(input);
        $input.removeClass('validation-error-js');
        $input.closest('.form__input-wrapper').find('.form__invalid-input').addClass('hidden-js');
    },

    submitForm: async function(button) {
        const $submit = $(button);
        const $form = $submit.closest('.refund-form-js');
        const $orderInput = $form.find('input[name="orderNumber"]');
        const $emailInput = $form.find('input[name="email"]');
        const orderValue = $orderInput.val().trim();
        const emailValue = $emailInput.val().trim();
        const emailRegex = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w{2,}$/;
        let hasError = false;

        $form.find('.form__invalid-input').addClass('hidden-js');
        $form.find('.form__input-value').removeClass('validation-error-js');

        if (orderValue.length === 0) {
            $orderInput.addClass('validation-error-js');
            $orderInput.closest('.form__input-wrapper').find('.validation-required-js').removeClass('hidden-js');
            hasError = true;
        }

        if (emailValue.length === 0) {
            $emailInput.addClass('validation-error-js');
            $emailInput.closest('.form__input-wrapper').find('.validation-required-js').removeClass('hidden-js');
            hasError = true;
        } else if (!emailRegex.test(emailValue)) {
            $emailInput.addClass('validation-error-js');
            $emailInput.closest('.form__input-wrapper').find('.email-valid-js').removeClass('hidden-js');
            hasError = true;
        }

        if (hasError) {
            return;
        }

        $submit.prop('disabled', true);

        try {
            const result = await refunds.findRefundOrder(orderValue, emailValue);
            const action = result.action;
            if (action.Redirect302) {
                globalThis.location.href = action.Redirect302;
                return;
            }
            app.temporaryPopupMessage(undefined, action.Message, action.Type);
        } catch (error) {
            console.error('Refund order lookup failed.', error);
            app.temporaryPopupMessage(undefined, $form.data('error'), 'err');
        } finally {
            $submit.prop('disabled', false);
        }
    },

    events: function() {
        $('body').on('click', '.start-refund-js', function() {
            refunds.showForm();
        });

        $('body').on('input', '.refund-form-js .form__input-value', function() {
            refunds.clearFieldError(this);
        });

        $('body').on('click', '.refund-form-submit-js', function(e) {
            e.preventDefault();
            refunds.submitForm(this);
        });

        $('body').on('keydown', '.refund-form-js input', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
                $(this).closest('.refund-form-js').find('.refund-form-submit-js').trigger('click');
            }
        });
    }
};

Pliki SCSS strony Szybkie zwroty

W folderze scss/static-elements utwórz nowy katalog refunds i umieść w nim trzy pliki: refunds-g.scss, refunds-m.scss i refunds-t.scss. scss/static-elements/refunds/refunds-g.scss:
.refunds-page-title {
    margin: 0 0 24px;
    font-size: 24px;
    font-weight: 500;
    line-height: 32px;
    color: $primaryColorFont;
}

.refunds-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 32px;
    margin-bottom: 32px;
    color: $primaryColorFont;
}

.refunds-info {
    align-self: flex-start;
    display: flex;
    flex-direction: column;
    gap: 16px;
    width: 100%;
    max-width: 800px;

    &__title {
        margin: 0;
        font-size: 20px;
        font-weight: 600;
        line-height: 28px;
        color: $primaryColorFont;
    }

    &__intro {
        margin: 0;
        font-size: 16px;
        font-weight: 500;
        line-height: 24px;
        color: $primaryColorFont;
    }

    &__hint {
        margin: 4px 0 0;
        font-size: 12px;
        font-weight: 400;
        line-height: 20px;
        color: $breadcrumbs;
    }
}

.refunds-steps {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;

    &__item {
        display: flex;
        align-items: center;
        gap: 12px;
    }

    &__number {
        flex-shrink: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        border-radius: 50%;
        background-color: #f3f3f3;
        color: $primaryColor;
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
    }

    &__text {
        margin: 0;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        color: $primaryColorFont;

        strong {
            font-weight: 600;
        }
    }
}

.refunds-cta {
    box-sizing: border-box;
    width: 100%;
    max-width: 578px;
    padding: 40px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 24px;
    background-color: $bgColor;
    border: 1px solid $lightBorderColor;
    border-radius: 8px;

    &__header {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 12px;
        width: 100%;
    }

    &__title {
        margin: 0;
        font-size: 24px;
        font-weight: 600;
        line-height: 32px;
        text-align: center;
        color: $primaryColorFont;
    }

    &__description {
        margin: 0;
        font-size: 16px;
        font-weight: 400;
        line-height: 24px;
        text-align: center;
        color: $breadcrumbs;
    }

    &__button {
        width: 100%;
        text-decoration: none;
    }
}

.refund-form-section {
    display: flex;
    justify-content: center;
    width: 100%;
    margin-bottom: 32px;
}

.refund-form {
    box-sizing: border-box;
    width: 100%;
    max-width: 578px;
    padding: 40px;
    background-color: $bgColor;
    border: 1px solid $lightBorderColor;
    border-radius: 8px;

    &__header {
        display: flex;
        flex-direction: column;
        gap: 12px;
        margin-bottom: 32px;
    }

    &__title {
        margin: 0;
        font-size: 24px;
        font-weight: 600;
        line-height: 32px;
        color: $primaryColorFont;
    }

    &__description {
        margin: 0;
        font-size: 14px;
        font-weight: 400;
        line-height: 20px;
        color: $breadcrumbs;
    }

    &__body {
        display: flex;
        flex-direction: column;
    }

    .form__input-wrapper {
        .form__input-value {
            &.validation-error-js {
                border-color: $dangerColor;
                color: $dangerColor;
            }
        }

        .form__invalid-input {
            position: static;
            display: block;
            margin: 4px 0 0;
            padding-left: 16px;
            text-align: left;
            color: $dangerColor;
            font-size: 12px;
            font-weight: 400;
            line-height: 16px;
        }
    }

    &__submit {
        width: 100%;
        margin-top: 4px;
    }

    &__login-info {
        margin: 16px 0 0;
        text-align: center;
        font-size: 14px;
        font-weight: 400;
        line-height: 20px;
        color: $primaryColorFont;
    }

    &__login-link {
        color: $primaryColor;
        font-weight: 600;
        cursor: pointer;
        text-decoration: none;

        &:hover {
            text-decoration: underline;
        }
    }
}
scss/static-elements/refunds/refunds-m.scss:
@media screen and (max-width: 767px) {
    .refunds-page-title {
        font-size: 20px;
        line-height: 28px;
        margin-bottom: 16px;
    }

    .refunds-container {
        gap: 24px;
        margin-bottom: 24px;
    }

    .refunds-info {
        max-width: 100%;
        gap: 12px;

        &__title {
            font-size: 18px;
            line-height: 24px;
        }

        &__intro {
            font-size: 14px;
            line-height: 22px;
        }
    }

    .refunds-steps {
        &__item {
            align-items: flex-start;
            gap: 10px;
        }

        &__number {
            width: 28px;
            height: 28px;
            font-size: 13px;
        }

        &__text {
            font-size: 13px;
            line-height: 20px;
            padding-top: 3px;
        }
    }

    .refunds-cta {
        padding: 24px;

        &__title {
            font-size: 20px;
            line-height: 28px;
        }

        &__description {
            font-size: 14px;
            line-height: 22px;
        }
    }

    .refund-form {
        padding: 24px;

        &__header {
            margin-bottom: 24px;
        }

        &__title {
            font-size: 20px;
            line-height: 28px;
        }

        &__description {
            font-size: 13px;
            line-height: 18px;
        }

        &__login-info {
            font-size: 13px;
        }
    }
}
scss/static-elements/refunds/refunds-t.scss:
@media screen and (min-width: 768px) and (max-width: 1439px) {
    .refunds-info {
        max-width: 100%;
    }
}

3. Modyfikacje istniejących plików HTML

partials/cart/thx.html

W pliku partials/cart/thx.html znajdź fragment generujący etykietę zgody w sekcji zgód marketingowych:
<label class="cart__tos-label tos-js" tabindex="0" role="checkbox" for="{{ consent.FieldValue }}" aria-checked="false"></label>
Usuń z niego atrybut for="{{ consent.FieldValue }}". Po zmianie linia powinna wyglądać tak:
<label class="cart__tos-label tos-js" tabindex="0" role="checkbox" aria-checked="false"></label>

partials/common/login.html

1. W pliku partials/common/login.html w kontenerze opakowującym formularz dodaj klasę login-container-popup. Zamień linię:
<div class="{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id -%} login-popup-js{% else -%} login-container {% endif -%}">
na:
<div class="{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id -%} login-popup-js login-container-popup{% else -%} login-container {% endif -%}">
2. W warunku otaczającym przycisk zamykający popup logowania usuń warunek and settings.signIn == "popup". Zamień linię:
{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id and settings.signIn == "popup" -%}
na:
{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id -%}

partials/product/amount-stepper.html

W pliku partials/product/amount-stepper.html znajdź blok ustawiający zmienne dla typów complaint i return:
{% if type == 'complaint' or type == 'return' -%}
{% assign reloadClass = '' -%}
{% assign complaintOrReturn = true -%}
{% endif -%}
i dodaj w jego wnętrzu nową linię ustawiającą maksymalną ilość produktu:
{% if type == 'complaint' or type == 'return' -%}
{% assign reloadClass = '' -%}
{% assign complaintOrReturn = true -%}
{% assign max = product.Quantity | Normalize -%}
{% endif -%}

partials/order/products-partials/product-table-header.html

Na samym początku pliku partials/order/products-partials/product-table-header.html dodaj blok przypisujący flagę complaintsOrReturnsEnabled:
{% if config.Complaints.ComplaintsEnabled or config.Complaints.ReturnsEnabled -%}
{% assign complaintsOrReturnsEnabled = true -%}
{% endif -%}

partials/product/products-table.html

Przyciski reklamacji i zwrotu są wyświetlane bezpośrednio w tabeli, zamiast w rozwijanym menu. W pliku partials/product/products-table.html znajdź komórkę z opcjami:
{% if order.Status == 3 and complaintsOrReturnsEnabled and product.CanComplain == true -%}
<button class="pure-button open-dropdown-js" aria-label="{{translations.Options}}">
    <!-- TODO: ikona SVG przycisku opcji – bez zmian, jak w istniejącym pliku -->
</button>
<div class="dropdown dropdown-js hidden-js" style="bottom: auto !important;">
    {% if config.Complaints.ComplaintsEnabled == true and product.CanComplain == true -%}
    <button class="pure-button open-complaint-form-js" data-type="complaint" data-product="{{ product.Url }}">
        {{ translations.Complain }}
    </button>
    {% endif -%}
    {% if config.Complaints.ReturnsEnabled == true and product.CanReturn == true and product.IsSetElement == false -%}
    <button class="pure-button open-complaint-form-js" data-type="return" data-product="{{ product.Url }}">
        {{ translations.Return }}
    </button>
    {% endif -%}
</div>
{% endif -%}
i zastąp ją następującym fragmentem:
{% if order.Status == 3 and complaintsOrReturnsEnabled -%}
{% if config.Complaints.ComplaintsEnabled == true and product.CanComplain == true -%}
<button class="pure-button open-complaint-form-js complaint-action-btn" data-type="complaint" data-product="{{ product.Url }}">
    {{ translations.Complain }}
</button>
{% endif -%}
{% if config.Complaints.ReturnsEnabled == true and product.CanReturn == true and product.IsSetElement == false -%}
<button class="pure-button open-complaint-form-js complaint-action-btn" data-type="return" data-product="{{ product.Url }}">
    {{ translations.Return }}
</button>
{% endif -%}
{% endif -%}
Następnie w tym samym pliku znajdź zewnętrzny warunek otaczający kontenery formularzy reklamacji i zwrotu i poluzuj go (usuń warunek product.CanComplain == true). Zamień:
{% if order.Status == 3 and complaintsOrReturnsEnabled and product.CanComplain == true -%}
na:
{% if order.Status == 3 and complaintsOrReturnsEnabled -%}

partials/customer-profile/orders/order-details.html

W pliku partials/customer-profile/orders/order-details.html wykonaj poniższe zmiany. a) Bloki Opcje (zawierające klasę options submenu z przyciskami akcji zamówienia) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}, aby ukryć je dla niezalogowanych klientów dokonujących szybkiego zwrotu. Wstaw {% unless order.Restricted -%} bezpośrednio przed otwierającym <div class="options submenu">, a {% endunless -%} po jego zamykającym </div>:
{% unless order.Restricted -%}
<div class="options submenu">
    ...
</div>
{% endunless -%}
b) W kontenerze messages-container-js na początku (przed istniejącymi komunikatami typu OrderEditable) dodaj baner informujący o ukrytych danych zamówienia oraz, na końcu kontenera, baner informujący o terminie zwrotu:
{% if order.Restricted -%}
<div class="return-info-banner">
    <!-- TODO: ikona SVG informacyjna (z klasą icon) -->
    {{ translations.RestrictedOrderViewInfo }}
</div>
{% endif -%}
{% if order.Status == 3 and config.Complaints.ReturnsEnabled -%}
<div class="return-info-banner">
    <!-- TODO: ikona SVG informacyjna (z klasą icon) -->
    {{ translations.OrderReturnDeadlineInfo | Format: config.Complaints.DaysToReturn }}
</div>
{% endif -%}
c) We wszystkich miejscach wyświetlających numer telefonu klienta zamień warunki sprawdzające jedynie pusty ciąg na warunki sprawdzające również wartość null. Zamień każde wystąpienie:
{% if order.Customer.DeliveryAddress.PhoneNo != '' -%}
na:
{% if order.Customer.DeliveryAddress.PhoneNo != null and order.Customer.DeliveryAddress.PhoneNo != '' -%}
d) Analogicznie zaktualizuj warunek wyświetlania NIP-u/TIN-u w sekcji danych do faktury. Zamień:
{% elseif order.Customer.TIN != '' -%}
na:
{% elseif order.Customer.TIN != null and order.Customer.TIN != '' -%}
e) W sekcji adresu dostawy zamień otwierający warunek alternatywny {% else -%} (bezpośrednio przed kontenerem z translations.DelivAddress) na bardziej restrykcyjny:
{% elseif order.Customer.DeliveryAddress != null -%}
f) Sekcję wybranego dokumentu (ChoosenDocument) opakuj warunkiem ukrywającym ją dla zamówień typu restricted. Wstaw {% unless order.Restricted -%} przed kontenerem order-details-item z tytułem translations.ChoosenDocument oraz {% endunless -%} za jego zamykającym </div>. g) W sekcji dokumentów zamówienia dodaj do warunku sprawdzenie order.Restricted == false. Zamień:
{% if orderDocumentsSize > 0 -%}
na:
{% if orderDocumentsSize > 0 and order.Restricted == false -%}
h) W sekcji załączników zamówienia dodaj analogiczne sprawdzenie. Zamień:
{% if config.Orders.AttachmentsEnabled and orderAttachmentsSize > 0 -%}
na:
{% if config.Orders.AttachmentsEnabled and orderAttachmentsSize > 0 and order.Restricted == false -%}
i) W sekcji zamówień powiązanych zamień:
{% if order.RelatedOrders[0] -%}
na:
{% if order.RelatedOrders[0] and order.Restricted == false -%}

partials/customer-profile/complaints/complaint-form.html

W pliku partials/customer-profile/complaints/complaint-form.html wprowadź poniższe zmiany. a) W kontenerze amount-stepper-container (wewnątrz warunku {% if type != 'set-return' -%}) na samym początku dodaj nową etykietę:
<span class="amount-stepper-container__label">{{ translations.Quantity }}:</span>
b) Pod sekcją z komentarzem reklamacji/zwrotu (po zamykającym {% endif -%} z sekcji complaint-message-textarea) wewnątrz warunku {% if type != 'set-return' -%} dodaj sekcję wyboru sposobu zwrotu środków:
<div class="refund-method-wrapper">
    <div class="refund-method-wrapper__title">{{ translations.Com_RefundMethod }} <span class="required">*</span></div>
    <label class="refund-method-option">
        <input class="refund-method-option__radio refund-method-radio-js" checked="checked" name="refundMethod" type="radio" value="asPaid" />
        <span class="refund-method-option__box"></span>
        <span class="refund-method-option__label">
            {{ translations.Com_RefundAsPaid }} {% if order.Payment.Name and order.Payment.Name != '' -%} ({{ order.Payment.Name }}){% endif -%}
        </span>
    </label>
    <label class="refund-method-option">
        <input class="refund-method-option__radio refund-method-radio-js" name="refundMethod" type="radio" value="bankAccount" />
        <span class="refund-method-option__box"></span>
        <span class="refund-method-option__label">{{ translations.Com_RefundToBankAccount }}</span>
    </label>
</div>
<div class="form__input-wrapper account-number-wrapper-js hidden-js">
    <label class="form__input-info input-info-js" for="accountNumber">{{ translations.Com_BankAccountNumber }} <span class="required">*</span></label>
    <input id="accountNumber" class="form__input-value input-value-js" disabled="disabled" maxlength="50" name="accountNumber" type="text" />
    <div class="form__invalid-input validation-info-js validation-required-js hidden-js">{{ translations.FieldRequired }}</div>
</div>
c) W sekcji załączników plików zamień prosty licznik file-{{forloop.index}} na prefiks zawierający identyfikator zamówienia, numer produktu i typ formularza. Tuż przed pętlą {% for i in (1..config.Complaints.AttachmentsMaxCount) -%} dodaj nową linię:
{% capture filePrefix -%}file-{{ order.Id }}-{{ product.No }}-{{ type }}{% endcapture -%}
Następnie wewnątrz pętli zamień:
<label class="file" for="file-{{forloop.index}}">
<input id="file-{{forloop.index}}" class="add-attachement-in-complaint-js hidden-js" type="file" /></label>
na:
<label class="file" for="{{ filePrefix }}-{{ forloop.index }}">
<input id="{{ filePrefix }}-{{ forloop.index }}" class="add-attachement-in-complaint-js hidden-js" type="file" /></label>
d) Komunikat sukcesu wyświetlany po wysłaniu formularza ma być inny dla reklamacji, a inny dla zwrotu. Znajdź kontener <div class="success-message-js hidden-js"> i jego dotychczasową zawartość:
<div class="success-message-js hidden-js">
    {{ successInfo }}
</div>
zastąp:
<div class="success-message-js hidden-js">
    {% if complaint -%}
    {{ successInfo }}
    {% else -%}
    <div class="data-form__header return-success__header">
        <button class="close-button hide-container-js closing-modal-js" aria-label="{{ translations.Close }}">
            <!-- TODO: ikona SVG zamknięcia – jak w pozostałych popupach szablonu -->
        </button>
    </div>
    <div class="return-success__icon">
        <!-- TODO: ikona SVG potwierdzenia (zielony "check") -->
    </div>
    <div class="return-success__title">{{ successTitle }}</div>
    <div class="return-success__subtitle">{{ successInfo }}</div>
    {% if order.Customer.Email and order.Customer.Email != '' -%}
    <div class="return-success__email-box">
        <!-- TODO: ikona SVG informacyjna -->
        <div>
            <div>{{ translations.Com_ConfirmationSentTo }}</div>
            <strong>{{ order.Customer.Email }}</strong>
        </div>
    </div>
    {% endif -%}
    <div class="return-success__steps-title">{{ translations.Com_NextSteps }}</div>
    <ol class="return-success__steps">
        <li>{{ translations.Com_PackProducts }}</li>
        <li>{{ translations.Com_SendPackageTo }}
            {% if config.Shop.Address.Street != '' -%} {{ config.Shop.Address.Street }}{% endif -%}
            {% if config.Shop.Address.StreetNo != '' -%} {{ config.Shop.Address.StreetNo }}{% endif -%}
            {% if config.Shop.Address.UnitNo != '' -%}/{{ config.Shop.Address.UnitNo }}{% endif -%}
            {% if config.Shop.Address.ZipCode != '' or config.Shop.Address.City != '' -%}, {{ config.Shop.Address.ZipCode }} {{ config.Shop.Address.City }}{% endif -%}</li>
        <li>{{ translations.Com_RefundAfterReceive }}</li>
    </ol>
    <div class="buttons-container short">
        <button class="primary-action-button hide-container-js closing-modal-js">
            {{ translations.Close }}
        </button>
    </div>
    {% endif -%}
</div>

4. Modyfikacje pliku js/layout-customerprofile0.js

Poniższe zmiany dotyczą pliku js/layout-customerprofile0.js (jego nieskompresowanej wersji, którą po edycji należy ponownie zminifikować do layout-customerprofile0.min.js). a) W funkcji openComplaintForm wewnątrz warunku if (hiddenContainer) – tuż po linii hiddenContainer.querySelector('.success-message-js').classList.add('hidden-js'); – dodaj kod ujawniający nagłówek formularza oraz resetujący wybór sposobu zwrotu do opcji domyślnej:
const mainHeader = hiddenContainer.querySelector(':scope > .data-form__header');
if (mainHeader) {
    mainHeader.classList.remove('hidden-js');
}
hiddenContainer.classList.remove('hidden-js');

const asPaidRadio = hiddenContainer.querySelector('.refund-method-radio-js[value="asPaid"]');
if (asPaidRadio) {
    asPaidRadio.checked = true;
    $(asPaidRadio).trigger('change');
}
(Linia hiddenContainer.classList.remove('hidden-js'); już istnieje – pokazana jest dla kontekstu. Nowe są bloki const mainHeader i const asPaidRadio.) b) W funkcji sendComplaint, w bloku przygotowującym dane formularza – po pętli for (const item of dataFromHTML) dokładającej pola do fd – dodaj fragment dołączający parametr qrHash z adresu URL przy wysyłaniu zwrotu:
if (form.find('input[name="__action"]').val() === 'Order/ReturnAdd') {
    const qrHash = new URLSearchParams(globalThis.location.search).get('qrHash');
    if (qrHash) {
        fd.append('qrHash', qrHash);
    }
}
c) W tej samej funkcji sendComplaint, w callbacku success po pomyślnym wysłaniu, zamień fragment:
form.parents('.add-complaint-form-js').find('.success-message-js').removeClass('hidden-js');
na:
const container = form.parents('.add-complaint-form-js');
container.find('.success-message-js').removeClass('hidden-js');
container.children('.data-form__header').addClass('hidden-js');
d) Na samym końcu pliku js/layout-customerprofile0.js dodaj nowy handler obsługujący przełączanie sposobu zwrotu środków. Pokazuje on / ukrywa pole na numer konta bankowego:
$('body').on('change', '.refund-method-radio-js', function(e) {
    const radio = $(e.currentTarget);
    const form = radio.closest('.form-js');
    const wrapper = form.find('.account-number-wrapper-js');
    const input = wrapper.find('input[name="accountNumber"]');
    if (radio.val() === 'bankAccount' && radio.prop('checked')) {
        wrapper.removeClass('hidden-js');
        input.prop('disabled', false);
        input.prop('required', true);
    } else {
        wrapper.addClass('hidden-js');
        wrapper.find('.validation-required-js').addClass('hidden-js');
        wrapper.find('.form__input-info').removeClass('validation-error');
        input.removeClass('validation-error-js');
        input.prop('required', false);
        input.prop('disabled', true);
        input.val('');
    }
});

5. Modyfikacje plików SCSS profilu klienta

Poniższe style należy dodać do plików scss/static-elements/customer-profile/customer-profile-g.scss (wersja desktop) oraz scss/static-elements/customer-profile/customer-profile-m.scss (wersja mobile). Po zmianach pamiętaj o kompilacji – nie edytuj ręcznie wynikowych plików CSS.

Plik scss/static-elements/customer-profile/customer-profile-g.scss

a) Dla "przyklejonej" kolumny z akcjami reklamacji/zwrotu w tabeli produktów dodaj reguły wewnątrz selektora otaczającego tabelę zamówienia (tam, gdzie znajdują się style dla thead tr th):
thead tr th.open-complaint-form-container-js {
    position: sticky;
    right: 0;
    background: transparent;
    z-index: 5;

    &::before {
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        right: 0;
        width: 200px;
        background: linear-gradient(to right, rgba(255, 255, 255, 0), #fff 50%);
        pointer-events: none;
    }
}

td.complaint-actions-inline {
    white-space: nowrap;
    text-align: right;
    padding-left: 16px;
    padding-right: 8px;
    position: sticky;
    right: 0;
    background: #fff;
    z-index: 2;

    &::before {
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        left: -32px;
        width: 32px;
        background: linear-gradient(to right, rgba(255, 255, 255, 0), #fff 100%);
        pointer-events: none;
    }

    .pure-button.complaint-action-btn {
        display: inline-flex;
        background: transparent;
        border: 0;
        border-radius: 4px;
        color: $primaryColor;
        padding: 4px 8px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
        transition: background-color 150ms ease;

        &:hover,
        &:focus-visible {
            color: $primaryColor;
            background: rgba(0, 0, 0, 0.06);
        }

        & + .complaint-action-btn {
            margin-left: 8px;
        }
    }
}
b) Style hovera dla wiersza tabeli z akcjami reklamacji/zwrotu (umieść w głównym zakresie pliku):
.row {
    &:hover,
    &:focus-within,
    &.hovered-js {
        td.complaint-actions-inline {
            background: #F1DDDE;

            &::before {
                background: linear-gradient(to right, rgba(241, 221, 222, 0), #F1DDDE 100%);
            }
        }
    }

    &.set td.complaint-actions-inline {
        background: #ececec;

        &::before {
            background: linear-gradient(to right, rgba(236, 236, 236, 0), #ececec 100%);
        }
    }
}
c) Style banera informacyjnego (termin zwrotu / ukryte dane zamówienia):
.return-info-banner {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    margin: 0 0 24px 0;
    background: #E8F1F8;
    border: 1px solid #C7DCEE;
    border-radius: 5px;
    font-size: 14px;
    line-height: 20px;
    color: #2C3E50;

    .icon {
        flex-shrink: 0;
        fill: #4A90BC;
    }

    strong {
        font-weight: 600;
    }
}
d) Style sekcji wyboru sposobu zwrotu środków oraz radio-buttonów:
.refund-method-wrapper {
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin-bottom: 24px;

    &__title {
        color: $primaryColorFont;
        font-size: 14px;
        font-weight: 500;
        line-height: 20px;
    }
}

.refund-method-option {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;

    &__radio {
        display: none;

        &:checked ~ .refund-method-option__box {
            border-color: $primaryColor;

            &::after {
                content: "";
                display: block;
                width: 8px;
                height: 8px;
                border-radius: 50%;
                background: $primaryColor;
            }
        }
    }

    &__box {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 16px;
        height: 16px;
        border: 1px solid #767676;
        border-radius: 50%;
        flex-shrink: 0;
    }

    &__label {
        font-size: 14px;
        line-height: 20px;
    }
}
e) Style ekranu sukcesu po wysłaniu zwrotu (m.in. ikona, tytuł, lista kolejnych kroków):
.add-complaint-form-js .characters-length {
    margin-top: 0;
    bottom: 23px;
}

.add-complaint-form-js {
    .quantity__plus.disabled-js,
    .quantity__minus.disabled-js {
        opacity: 0.4;
    }
}

.add-complaint-form-js .data-form__header.return-success__header {
    margin-bottom: 8px;
}

.return-success {
    &__icon {
        display: flex;
        justify-content: center;
        margin-bottom: 16px;

        svg {
            fill: #2E7D32;
        }
    }

    &__title {
        text-align: center;
        font-size: 20px;
        font-weight: 600;
        line-height: 28px;
        color: $primaryColorFont;
        margin-bottom: 8px;
    }

    &__subtitle {
        text-align: center;
        font-size: 14px;
        line-height: 20px;
        color: $labelsColor;
        padding-bottom: 24px;
        border-bottom: 1px solid #E7E7E7;
        margin-bottom: 24px;
    }

    &__email-box {
        display: flex;
        align-items: flex-start;
        gap: 12px;
        padding: 12px 16px;
        background: #F0F6FC;
        border: 1px solid #D6E4F0;
        border-radius: 6px;
        margin-bottom: 24px;
        font-size: 14px;
        line-height: 20px;
        color: $primaryColorFont;

        svg {
            fill: #1976D2;
            flex-shrink: 0;
            margin-top: 2px;
        }
    }

    &__steps-title {
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
        color: $primaryColorFont;
        margin-bottom: 12px;
    }

    &__steps {
        margin: 0 0 24px;
        padding-left: 20px;
        font-size: 14px;
        line-height: 20px;
        color: $primaryColorFont;

        li {
            margin-bottom: 8px;

            &:last-child {
                margin-bottom: 0;
            }
        }
    }
}
f) Uzupełnij wnętrze selektora .file-attachements-wrapper o style dla kontenera pojedynczego załącznika:
.file-container {
    .file {
        align-items: center;
        font-weight: 400;
        color: $primaryColorFont;
        justify-content: flex-start;
    }

    .icon-js svg {
        fill: $primaryColorFont;
    }

    .clear-file-input-js {
        flex-shrink: 0;
        display: flex;
        align-items: center;

        svg {
            width: 14px;
            height: 14px;
            fill: $primaryColor;
        }
    }
}

Plik scss/static-elements/customer-profile/customer-profile-m.scss

Na końcu pliku customer-profile-m.scss dodaj reguły dopasowujące przyciski reklamacji/zwrotu do widoku mobilnego (układają się one wówczas jeden pod drugim):
.eshop__table-container {
    thead tr th.open-complaint-form-container-js::before {
        width: 100px;
    }

    td.complaint-actions-inline {
        .pure-button.complaint-action-btn {
            display: block;
            width: max-content;
            margin-left: auto;
            text-align: right;

            & + .complaint-action-btn {
                margin-left: auto;
                margin-top: 4px;
            }
        }
    }
}
Po wprowadzeniu wszystkich powyższych zmian w szablonie Rubin pamiętaj o kompilacji oraz minifikacji plików js i scss, zgodnie z artykułem dostępnym pod linkiem https://pomoc.comarchesklep.pl/artykul/kompilacja-i-minifikacja-plikow/.

Szablon Szafir

1. Tłumaczenia

W panelu administracyjnym sklepu dodaj nowe klucze tłumaczeń wymagane przez funkcjonalność szybkich zwrotów w szablonie Szafir. OrderReturnDeadlineInfo - PL: Zamówienie można zwrócić w ciągu {0} dni od daty dostawy. - EN: You can return the order within {0} days from the delivery date. - DE: Sie können die Bestellung innerhalb von {0} Tagen ab Lieferdatum zurückgeben. - FR: Vous pouvez retourner la commande dans les {0} jours suivant la date de livraison. RestrictedOrderViewInfo - PL: Wybrane dane zamówienia zostały ukryte ze względów bezpieczeństwa. Możesz zwrócić produkty bez logowania. - EN: Some order details are hidden for security reasons. You can return products without signing in. - DE: Einige Bestelldetails wurden aus Sicherheitsgründen ausgeblendet. Sie können Produkte ohne Anmeldung zurücksenden. - FR: Certaines informations de la commande ont été masquées pour des raisons de sécurité. Vous pouvez retourner des produits sans vous connecter. RefundMethod - PL: Sposób zwrotu środków - EN: Refund method - DE: Rückerstattungsmethode - FR: Méthode de remboursement RefundAsPaid - PL: Tak jak zapłacono - EN: As paid - DE: Wie bezahlt - FR: Comme payé RefundToBankAccount - PL: Na konto bankowe - EN: To bank account - DE: Auf Bankkonto - FR: Sur le compte bancaire BankAccountNumber - PL: Nr konta bankowego - EN: Bank account number - DE: Bankkontonummer - FR: Numéro de compte bancaire ReturnConfirmationTitle - PL: Gotowe! Przyjęliśmy Twoje zgłoszenie - EN: Done! We have received your request - DE: Fertig! Wir haben Ihre Anfrage erhalten - FR: Terminé! Nous avons reçu votre demande ReturnConfirmationInfo - PL: Przygotuj paczkę i odeślij ją do nas – wszystkie szczegóły znajdziesz poniżej. - EN: Prepare the package and send it back to us – all details can be found below. - DE: Bereiten Sie das Paket vor und senden Sie es an uns zurück – alle Details finden Sie unten. - FR: Préparez le colis et renvoyez-le nous – tous les détails se trouvent ci-dessous. ReturnConfirmationEmailSent - PL: Potwierdzenie zwrotu zostało wysłane na adres: - EN: Return confirmation has been sent to: - DE: Die Rücksendebestätigung wurde gesendet an: - FR: La confirmation de retour a été envoyée à: NextSteps - PL: Następne kroki - EN: Next steps - DE: Nächste Schritte - FR: Prochaines étapes ReturnStep1 - PL: Bezpiecznie zapakuj swoje produkty - EN: Safely pack your products - DE: Verpacken Sie Ihre Produkte sicher - FR: Emballez vos produits en toute sécurité ReturnStep2Address - PL: Wyślij paczkę na adres - EN: Send the package to - DE: Senden Sie das Paket an - FR: Envoyez le colis à ReturnStep3 - PL: Pieniądze zwrócimy niezwłocznie po otrzymaniu i sprawdzeniu Twojej paczki. - EN: We will refund the money promptly after receiving and checking your package. - DE: Wir erstatten das Geld umgehend nach Erhalt und Überprüfung Ihres Pakets. - FR: Nous rembourserons l'argent rapidement après réception et vérification de votre colis. ReturnInThreeSteps - PL: Zwróć towar w 3 krokach - EN: Return the product in 3 steps - DE: Geben Sie die Ware in 3 Schritten zurück - FR: Retournez la marchandise en 3 étapes ReturnWithoutReasonInfo - PL: Przysługuje Ci możliwość zwrotu bez podania przyczyny. - EN: You have the right to return the product without giving a reason. - DE: Sie haben das Recht, die Ware ohne Angabe von Gründen zurückzugeben. - FR: Vous avez le droit de retourner la marchandise sans donner de motif. OrEnterOrderNumber - PL: lub podaj numer zamówienia - EN: or enter the order number - DE: oder geben Sie die Bestellnummer ein - FR: ou saisissez le numéro de commande FillForm - PL: Wypełnij formularz - EN: Fill out the form - DE: Füllen Sie das Formular aus - FR: Remplissez le formulaire ReturnOnline - PL: zwrotu online - EN: online return - DE: Online-Rückgabe - FR: retour en ligne SendParcel - PL: Wyślij paczkę - EN: Send the parcel - DE: Paket senden - FR: Envoyer le colis SendParcelToOurAddress - PL: nadaj przesyłkę na nasz adres - EN: send the parcel to our address - DE: senden Sie das Paket an unsere Adresse - FR: envoyez le colis à notre adresse FastSimpleSecure - PL: Szybko, prosto i bezpiecznie. - EN: Fast, simple and secure. - DE: Schnell, einfach und sicher. - FR: Rapide, simple et sécurisé. ReadyForReturn - PL: Gotowy do zwrotu? - EN: Ready for return? - DE: Bereit zur Rückgabe? - FR: Prêt pour le retour ? ReadyForReturnInfo - PL: Kliknij poniżej, aby rozpocząć proces zwrotu. Przeprowadzimy Cię przez wszystkie kroki. - EN: Click below to start the return process. We will guide you through all the steps. - DE: Klicken Sie unten, um den Rückgabeprozess zu starten. Wir führen Sie durch alle Schritte. - FR: Cliquez ci-dessous pour lancer le processus de retour. Nous vous guiderons à travers toutes les étapes. StartReturn - PL: Rozpocznij zwrot - EN: Start return - DE: Rückgabe starten - FR: Commencer le retour ProductReturn - PL: Zwrot produktu - EN: Product return - DE: Produktrückgabe - FR: Retour du produit ProductReturnFormInfo - PL: Wprowadź dane zamówienia, aby zlokalizować zakup i rozpocząć proces zwrotu. Numer zamówienia znajdziesz w e-mailu z potwierdzeniem. - EN: Enter the order details to locate the purchase and start the return process. You will find the order number in the confirmation e-mail. - DE: Geben Sie die Bestelldaten ein, um den Kauf zu lokalisieren und den Rückgabeprozess zu starten. Die Bestellnummer finden Sie in der Bestätigungs-E-Mail. - FR: Saisissez les données de la commande pour localiser l'achat et démarrer le processus de retour. Vous trouverez le numéro de commande dans l'e-mail de confirmation. InvalidOrderNumber - PL: Błędny numer zamówienia. Spróbuj ponownie. - EN: Invalid order number. Please try again. - DE: Ungültige Bestellnummer. Bitte versuchen Sie es erneut. - FR: Numéro de commande incorrect. Veuillez réessayer. FindOrder - PL: Znajdź zamówienie - EN: Find order - DE: Bestellung finden - FR: Trouver la commande LoginToSeeOrdersAndReturn - PL: aby zobaczyć swoje zamówienia i dokonać zwrotu. - EN: to see your orders and make a return. - DE: um Ihre Bestellungen einzusehen und eine Rückgabe vorzunehmen. - FR: pour voir vos commandes et effectuer un retour. RefundLookupError - PL: Wystąpił błąd podczas wyszukiwania zamówienia. Spróbuj ponownie później. - EN: An error occurred while searching for the order. Please try again later. - DE: Bei der Suche nach der Bestellung ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut. - FR: Une erreur s'est produite lors de la recherche de la commande. Veuillez réessayer plus tard.

2. Nowa strona Szybkie zwroty

Funkcjonalność szybkich zwrotów wymaga utworzenia dodatkowej strony statycznej refunds. Wykonaj poniższe kroki.

Plik refunds.html w katalogu głównym szablonu

W katalogu głównym szablonu utwórz nowy plik refunds.html z następującą zawartością:
{% extends '_layout.html' %}

{% block content %}
{% include 'static-elements/refunds/refunds.html' %}
{% endblock %}

Plik static-elements/refunds/refunds.html

W folderze static-elements utwórz nowy katalog refunds, a w nim plik refunds.html:
<section class="refunds refunds-js form-js">
    <p class="refunds-header refunds-initial-view-js">{{ translations.Returns }}</p>
    <div class="refunds-intro refunds-initial-view-js">
        <div class="refunds-info">
            <p class="refunds-info-title">{{ translations.ReturnInThreeSteps }}</p>
            <p class="refunds-info-desc">{{ translations.ReturnWithoutReasonInfo }}</p>
            <ol class="refunds-steps">
                <li class="refunds-steps-item">
                    <span class="refunds-steps-number">1</span>
                    <p class="refunds-steps-text"><strong>{{ translations.SignIn }}</strong> {{ translations.OrEnterOrderNumber }}</p>
                </li>
                <li class="refunds-steps-item">
                    <span class="refunds-steps-number">2</span>
                    <p class="refunds-steps-text"><strong>{{ translations.FillForm }}</strong> {{ translations.ReturnOnline }}</p>
                </li>
                <li class="refunds-steps-item">
                    <span class="refunds-steps-number">3</span>
                    <p class="refunds-steps-text"><strong>{{ translations.SendParcel }}</strong> - {{ translations.SendParcelToOurAddress }}</p>
                </li>
            </ol>
            <p class="refunds-info-hint">{{ translations.FastSimpleSecure }}</p>
        </div>
        <div class="refunds-cta">
            <p class="refunds-cta-title">{{ translations.ReadyForReturn }}</p>
            <p class="refunds-cta-desc">{{ translations.ReadyForReturnInfo }}</p>
            {% if usr.Authenticated -%}
            <a class="refunds-cta-button" href="{{ config.DefinedPages.CustomerProfile.Url }}?tab=orders" rel="nofollow" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </a>
            {% else -%}
            <button class="refunds-cta-button start-refund-js" type="button" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </button>
            {% endif -%}
        </div>
    </div>
    {% unless usr.Authenticated -%}
    <div class="refunds-form-section refund-form-view-js hidden-js">
        <div class="refunds-form">
            <p class="refunds-form-title">{{ translations.ProductReturn }}</p>
            <p class="refunds-form-desc">{{ translations.ProductReturnFormInfo }}</p>
            <div class="refund-form-js" data-cp-url="{{ config.DefinedPages.CustomerProfile.Url }}">
                <div class="message-bar-ui warning-bar-ui refund-lookup-error-js hidden-js">{{ translations.RefundLookupError }}</div>
                <div class="form__input-wrapper">
                    <label class="form__input-info form__input-info-js" for="refundOrderNumber" data-type="text">{{ translations.OrderNumber }} <span class="required-ui">*</span></label>
                    <input id="refundOrderNumber" class="form__input-value form__input-value-js" maxlength="50" name="orderNumber" required="" type="text" aria-label="{{ translations.OrderNumber }}" />
                    <span class="error-ui validation-info-js validation-required-js hidden-js">{{ translations.RequiredField }}</span>
                </div>
                <div class="form__input-wrapper">
                    <label class="form__input-info form__input-info-js" for="refundEmail" data-type="email">{{ translations.EmailAddress }} <span class="required-ui">*</span></label>
                    <input id="refundEmail" class="form__input-value form__input-value-js" autocomplete="email" maxlength="192" name="email" required="" type="email" aria-label="{{ translations.EmailAddress }}" />
                    <span class="error-ui validation-info-js validation-required-js hidden-js">{{ translations.RequiredField }}</span>
                    <span class="error-ui validation-info-js email-valid-js hidden-js">{{ translations.FillProperEmail }}</span>
                </div>
                <div class="required-fields-info-ui form__required-fields-info"><span class="required-ui">* </span>{{ translations.RequiredFields }}</div>
                <button class="refunds-form-submit refund-form-submit-js" type="button" aria-label="{{ translations.FindOrder }}">
                    {{ translations.FindOrder }}
                </button>
                <p class="refunds-form-login-info">{{ translations.HaveAccount }} <a class="refunds-form-login-link" href="{{ config.DefinedPages.Login.Url }}" rel="nofollow">{{ translations.SignIn }}</a>, {{ translations.LoginToSeeOrdersAndReturn }}</p>
            </div>
        </div>
    </div>
    {% endunless -%}
</section>

Plik js/layout0.js – kod obsługi formularza zwrotu

Na końcu pliku js/layout0.js dodaj poniższy kod odpowiedzialny za walidację i wysłanie formularza wyszukiwania zamówienia (dla niezalogowanego klienta). Po zapisaniu pliku pamiętaj o zminifikowaniu go do layout0.min.js.
const refunds = {
    findRefundOrder(orderNumber, email) {
        return $.post('', {
            __action: 'Order/QuickReturnLookup',
            orderId: orderNumber,
            email: email,
            __csrf: __CSRF
        });
    },

    showForm() {
        document.querySelectorAll('.refunds-initial-view-js').forEach((el) => el.classList.add('hidden-js'));
        document.querySelectorAll('.refund-form-view-js').forEach((el) => el.classList.remove('hidden-js'));
        document.querySelector('.refund-form-js input[name="orderNumber"]')?.focus();
    },

    clearFieldError(input) {
        input.classList.remove('validation-error-ui', 'validation-error-lq');
        input.closest('.form__input-wrapper')
            ?.querySelectorAll('.error-ui')
            .forEach((el) => el.classList.add('hidden-js'));
    },

    markFieldError(input, errorSelector) {
        input.classList.add('validation-error-ui', 'validation-error-lq');
        input.closest('.form__input-wrapper')?.querySelector(errorSelector)?.classList.remove('hidden-js');
    },

    validateForm({ orderInput, emailInput }) {
        const orderValue = orderInput.value.trim();
        const emailValue = emailInput.value.trim();
        const emailRegex = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w{2,}$/;
        let hasError = false;

        if (orderValue.length === 0) {
            refunds.markFieldError(orderInput, '.validation-required-js');
            hasError = true;
        }

        if (emailValue.length === 0) {
            refunds.markFieldError(emailInput, '.validation-required-js');
            hasError = true;
        } else if (!emailRegex.test(emailValue)) {
            refunds.markFieldError(emailInput, '.email-valid-js');
            hasError = true;
        }

        return { hasError, orderValue };
    },

    async submitForm(button) {
        const form = button.closest('.refund-form-js');
        if (!form) {
            return;
        }
        const orderInput = form.querySelector('input[name="orderNumber"]');
        const emailInput = form.querySelector('input[name="email"]');

        form.querySelectorAll('.error-ui').forEach((el) => el.classList.add('hidden-js'));
        form.querySelector('.refund-lookup-error-js')?.classList.add('hidden-js');
        form.querySelectorAll('.form__input-value').forEach((el) => {
            el.classList.remove('validation-error-ui', 'validation-error-lq');
        });

        const { hasError, orderValue } = refunds.validateForm({ orderInput, emailInput });
        if (hasError) {
            return;
        }

        button.disabled = true;
        const errorBar = form.querySelector('.refund-lookup-error-js');
        try {
            const result = await refunds.findRefundOrder(orderValue, emailInput.value.trim());
            const action = result.action;
            if (action.Redirect302) {
                globalThis.location.href = action.Redirect302;
                return;
            }
            if (errorBar) {
                errorBar.textContent = action.Message;
                errorBar.classList.remove('hidden-js');
            }
        } catch (error) {
            console.error('Refund order lookup failed.', error);
            errorBar?.classList.remove('hidden-js');
        } finally {
            button.disabled = false;
        }
    }
};

js.delegate(document.body, 'click', '.start-refund-js', () => refunds.showForm());

js.delegate(document.body, 'input', '.refund-form-js .form__input-value', function () {
    refunds.clearFieldError(this);
});

js.delegate(document.body, 'click', '.refund-form-submit-js', function (event) {
    event.preventDefault();
    refunds.submitForm(this);
});

js.delegate(document.body, 'keydown', '.refund-form-js input', function (event) {
    if (event.key !== 'Enter') {
        return;
    }
    event.preventDefault();
    this.closest('.refund-form-js')?.querySelector('.refund-form-submit-js')?.click();
});

Pliki SCSS strony Szybkie zwroty

W folderze scss/static-elements utwórz nowy katalog refunds i umieść w nim dwa pliki: refunds-g.scss (style desktop) oraz refunds-m.scss (style mobilne). scss/static-elements/refunds/refunds-g.scss:
.refunds {
    padding: 40px 110px;
    background-color: $bgColor;
    color: $primaryColorFont;

    .refunds-header {
        display: block;
        width: 100%;
        margin: 0 0 24px;
        color: $primaryColorFont;
        text-align: left;
        font-size: 32px;
        font-weight: 500;
        line-height: 42px;
        letter-spacing: 0.8px;
    }

    .refunds-intro {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 32px;
        margin-bottom: 40px;
    }

    .refunds-info {
        align-self: flex-start;
        width: 100%;
        max-width: 800px;
        display: flex;
        flex-direction: column;
        gap: 16px;
        color: $primaryColorFont;

        @media screen and (min-width: 769px) and (max-width: 1279px) {
            max-width: 100%;
        }
    }

    .refunds-info-title {
        margin: 0;
        font-size: 20px;
        font-weight: 500;
        line-height: 28px;
        letter-spacing: 0.4px;
    }

    .refunds-info-desc {
        margin: 0;
        font-size: 16px;
        font-weight: 400;
        line-height: 24px;
        letter-spacing: 0.3px;
    }

    .refunds-info-hint {
        margin: 4px 0 0;
        color: $secondaryColorFont;
        font-size: 12px;
        font-weight: 400;
        line-height: 20px;
        letter-spacing: 0.2px;
    }

    .refunds-steps {
        list-style: none;
        margin: 0;
        padding: 0;
        display: flex;
        flex-direction: column;
        gap: 12px;
    }

    .refunds-steps-item {
        display: flex;
        align-items: center;
        gap: 12px;
    }

    .refunds-steps-number {
        flex-shrink: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        border-radius: 50%;
        background-color: $formsBgColor;
        color: $primaryColor;
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
    }

    .refunds-steps-text {
        margin: 0;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        letter-spacing: 0.3px;

        strong {
            font-weight: 600;
        }
    }

    .refunds-cta {
        box-sizing: border-box;
        width: 100%;
        max-width: 578px;
        padding: 32px 40px;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 12px;
        background-color: $bgColor;
        border: 1px solid $lightBorderColor;
    }

    .refunds-cta-title {
        margin: 0;
        text-align: center;
        font-size: 22px;
        font-weight: 500;
        line-height: 30px;
        letter-spacing: 0.5px;
        color: $primaryColorFont;
    }

    .refunds-cta-desc {
        margin: 0;
        text-align: center;
        color: $secondaryColorFont;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        letter-spacing: 0.3px;
    }

    .refunds-cta-button,
    .refunds-form-submit {
        display: inline-block;
        width: 100%;
        margin-top: 8px;
        padding: 12px 16px;
        background: $btnSolidBgColor;
        color: $btnSolidTextColor;
        border: 1px solid $btnSolidBgColor;
        font-size: 14px;
        font-weight: 500;
        line-height: 20px;
        text-align: center;
        text-decoration: none;
        cursor: pointer;
        transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;

        &:hover,
        &:focus {
            background: $btnSolidHoverBgColor;
            color: $btnSolidHoverTextColor;
            border-color: $btnSolidHoverBgColor;
        }

        &[disabled],
        &[disabled]:hover {
            background: $btnDisabledBg;
            border-color: $btnDisabledFont;
            color: $btnDisabledFont;
            cursor: default;
        }
    }

    .refunds-form-section {
        display: flex;
        justify-content: center;
        width: 100%;
        margin-top: 32px;
        margin-bottom: 40px;
    }

    .refunds-form {
        box-sizing: border-box;
        width: 100%;
        max-width: 578px;
        padding: 32px 40px;
        background-color: $bgColor;
        border: 1px solid $lightBorderColor;
    }

    .refunds-form-title {
        margin: 0 0 8px;
        font-size: 22px;
        font-weight: 500;
        line-height: 30px;
        letter-spacing: 0.5px;
        color: $primaryColorFont;
    }

    .refunds-form-desc {
        margin: 0 0 20px;
        color: $secondaryColorFont;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        letter-spacing: 0.3px;
    }

    .refund-form-js {
        display: flex;
        flex-direction: column;

        .form__input-wrapper {
            position: relative;
            margin-bottom: 16px;

            .form__input-info {
                display: block;
                margin: 0 0 4px;
                color: $primaryColorFont;
                font-size: 13px;
                font-weight: 400;
                line-height: 18px;
            }

            input {
                width: 100%;
                height: 36px;
                margin: 0;
                padding: 0 10px;
                box-sizing: border-box;
                border: 1px solid $lightBorderColor;
                font-size: 14px;

                &::placeholder {
                    font-size: 14px;
                }

                &.validation-error-ui,
                &.validation-error-lq {
                    border-color: $dangerColor;
                    color: $dangerColor;
                }
            }

            .error-ui {
                position: static;
                display: block;
                margin: 4px 0 0;
                padding: 0;
                text-align: left;
                color: $dangerColor;
                font-size: 12px;
                font-weight: 400;
                line-height: 16px;
            }
        }

        .form__required-fields-info {
            margin: 4px 0 16px;
            color: $primaryColorFont;
            font-size: 12px;
            font-weight: 300;
            line-height: 18px;
        }
    }

    .refunds-form-login-info {
        margin: 12px 0 0;
        text-align: center;
        color: $primaryColorFont;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
    }

    .refunds-form-login-link {
        color: $primaryColor;
        font-weight: 600;
        cursor: pointer;
        text-decoration: none;

        &:hover {
            text-decoration: underline;
        }
    }
}
scss/static-elements/refunds/refunds-m.scss:
@media screen and (max-width: 768px) {
    .refunds {
        padding: 20px 16px;

        .refunds-header {
            font-size: 24px;
            line-height: 32px;
            margin-bottom: 16px;
        }

        .refunds-intro {
            gap: 24px;
            margin-bottom: 24px;
        }

        .refunds-info {
            max-width: 100%;
            gap: 12px;
        }

        .refunds-info-title {
            font-size: 18px;
            line-height: 24px;
        }

        .refunds-info-desc {
            font-size: 14px;
            line-height: 22px;
        }

        .refunds-steps-item {
            align-items: flex-start;
            gap: 10px;
        }

        .refunds-steps-number {
            width: 28px;
            height: 28px;
            font-size: 13px;
        }

        .refunds-steps-text {
            font-size: 13px;
            line-height: 20px;
            padding-top: 3px;
        }

        .refunds-cta {
            padding: 24px;
        }

        .refunds-cta-title {
            font-size: 20px;
            line-height: 28px;
        }

        .refunds-form-section {
            margin-top: 20px;
            margin-bottom: 24px;
        }

        .refunds-form {
            padding: 24px;
            border: none;
        }

        .refunds-form-title {
            font-size: 20px;
            line-height: 28px;
        }

        .refunds-form-desc {
            margin-bottom: 16px;
        }

        .refunds-form-login-info {
            font-size: 13px;
        }
    }
}

3. Modyfikacje istniejących plików HTML

partials/customer-profile/orders/order-details.html

W pliku partials/customer-profile/orders/order-details.html wykonaj poniższe zmiany. a) Blok z przyciskami akcji nawigacji zamówienia (zawierający {% if order.EditingAllowed -%}, opcje anulowania, edycji, ponowienia, druku itp.) opakuj warunkiem ukrywającym go dla zamówień typu restricted. Bezpośrednio po linii z elementem <li class="active-ui only-text-ui ...">...</li> wstaw:
{% unless order.Restricted -%}
a tuż przed zamykającym znacznikiem </ul> tej samej nawigacji dodaj:
{% endunless -%}
b) Na początku kontenera messages-container-lq messages-container-ui (zaraz po jego otwarciu) dodaj baner informujący o ukrytych danych zamówienia:
{% if order.Restricted -%}
<div class="message-bar-ui no-margin-ui">
    <i class="not-clickable-ui ti-info-alt"></i>
    {{ translations.RestrictedOrderViewInfo }}
</div>
{% endif -%}
c) Na końcu tego samego kontenera (przed zamykającym </div>) dodaj baner informujący o terminie zwrotu wraz z przypisaniem flagi complaintsOrReturnsEnabled:
{% if config.Complaints.ComplaintsEnabled or config.Complaints.ReturnsEnabled -%}
{% assign complaintsOrReturnsEnabled = true -%}
{% endif -%}

{% if order.Status == 3 and complaintsOrReturnsEnabled -%}
<div class="message-bar-ui no-margin-ui">
    <i class="not-clickable-ui ti-info-alt"></i>
    {{translations.OrderReturnDeadlineInfo | Format: config.Complaints.DaysToReturn}}
</div>
{% endif -%}
d) Blok z przyciskami akcji wewnątrz info-container-js (zawierający przyciski order.CanCancel, edycji, ponowienia zakupu itd.) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}. Wstaw {% unless order.Restricted -%} bezpośrednio przed pierwszym {% if order.CanCancel -%}, a {% endunless -%} po zamykającym warunku odpowiedzialnym za popup potwierdzenia ({% include 'partials/common/confirmation-popup.html' with 0 -%}). e) W sekcji wyświetlającej dokumenty zamówienia zamień:
{% if order.Documents %}
na:
{% if order.Documents and order.Restricted == false %}
f) We wszystkich miejscach wyświetlających numer telefonu klienta zamień warunki sprawdzające jedynie pusty ciąg na warunki sprawdzające również wartość null. Zamień każde wystąpienie:
{% if order.Customer.DeliveryAddress.PhoneNo != '' -%}
na:
{% if order.Customer.DeliveryAddress.PhoneNo != null and order.Customer.DeliveryAddress.PhoneNo != '' -%}
g) Każdą sekcję z tytułem translations.ChoosenDocument opakuj warunkiem ukrywającym ją dla zamówień restricted. Wstaw {% unless order.Restricted -%} bezpośrednio przed <div class="name-ui mt20-ui">{{ translations.ChoosenDocument }}</div> oraz {% endunless -%} po jej zamykającym </div>. h) W sekcji wyświetlającej alternatywny adres dostawy zamień warunek {% else -%} (bezpośrednio przed order-info-item-ui z translations.DelivAddress) na bardziej restrykcyjny:
{% elseif order.Customer.DeliveryAddress != null -%}
i) W sekcji danych do faktury zamień warunek wyświetlania NIP-u/TIN-u. Zamień:
{% elseif order.Customer.TIN != '' -%}
na:
{% elseif order.Customer.TIN != null and order.Customer.TIN != '' -%}
j) W sekcji załączników zamówienia (kontener attachements-ui remarks-ui) zamień warunek otaczający. Zamień:
{% if config.Orders.AttachmentsEnabled -%}
na:
{% if config.Orders.AttachmentsEnabled and order.Restricted == false -%}
k) W sekcji zamówień powiązanych (kontener remarks-ui eshop-order-ui) zamień:
{% if order.RelatedOrders -%}
na:
{% if order.RelatedOrders and order.Restricted == false -%}

partials/customer-profile/complaints/complaint-form.html

W pliku partials/customer-profile/complaints/complaint-form.html wprowadź poniższe zmiany. a) W kontenerze amount-stepper-container-ui amount-stepper-container-lq (wewnątrz warunku {% if type != 'set-return' -%}) na samym początku dodaj etykietę widoczną tylko dla zwrotów:
{% unless complaint -%}
<span class="amount-stepper-label-ui">{{ translations.Quantity }}:</span>
{% endunless -%}
b) Bezpośrednio po zamknięciu kontenera amount-stepper-container-ui (po jego </div> i odpowiadającym {% endif -%}) dodaj sekcję wyboru sposobu zwrotu środków – widoczną tylko w formularzu zwrotu:
{% unless complaint -%}
<div class="refund-method-container-ui refund-method-container-js">
    <label class="label-ui" for="refundMethod">{{ translations.RefundMethod }} <span class="required-ui">*</span></label>
    <div>
        <span class="select-background-ui">
            <select id="refundMethod" class="refund-method-select-js" name="refundMethod" aria-label="{{ translations.RefundMethod }}">
                <option selected="selected" value="original">{{ translations.RefundAsPaid }} {% if order.Payment.Name and order.Payment.Name != "" -%} ({{ order.Payment.Name }}){% endif -%}</option>
                <option value="bank">{{ translations.RefundToBankAccount }}</option>
            </select>
        </span>
        <i class="ti-angle-down select-arrow-ui"></i>
    </div>
    <div class="bank-account-container-ui bank-account-container-js hidden-js">
        <label class="label-ui" for="bankAccountNumber">{{ translations.BankAccountNumber }} <span class="required-ui">*</span></label>
        <div>
            <input id="bankAccountNumber" disabled="disabled" name="bankAccountNumber" type="text" placeholder="{{ translations.BankAccountNumber }}" aria-label="{{ translations.BankAccountNumber }}" />
            <span class="error-ui validation-info-js validation-required-js hidden-js">{{ translations.RequiredField }}</span>
        </div>
    </div>
</div>
{% endunless -%}
c) Komunikat sukcesu wyświetlany po wysłaniu formularza ma być inny dla reklamacji, a inny dla zwrotu. Znajdź kontener <div class="success-message-js hidden-js"> wraz z jego dotychczasową zawartością (komunikat ComplaintAdded + successInfo):
<div class="success-message-js hidden-js">
    <div class="complaint-added-ui">
        <i class="va-mid-ui ti-check"></i>
        <span class="va-mid-ui line-height-1-ui">
            {{ translations.ComplaintAdded }}
        </span>
    </div>
    <div class="info-ui">{{ successInfo }}</div>
</div>
i zastąp go nową, rozszerzoną wersją z dwoma wariantami (reklamacja / zwrot):
<div class="success-message-js hidden-js">
    {% if complaint -%}
    <div class="complaint-added-ui">
        <i class="va-mid-ui ti-check"></i>
        <span class="va-mid-ui line-height-1-ui">
            {{ translations.ComplaintAdded }}
        </span>
    </div>
    <div class="info-ui">{{ successInfo }}</div>
    {% else -%}
    <div class="return-success-popup-ui">
        <div class="return-success-icon-ui">
            <i class="ti-check"></i>
        </div>
        <div class="return-success-title-ui">{{ translations.ReturnConfirmationTitle }}</div>
        <div class="return-success-desc-ui">{{ translations.ReturnConfirmationInfo }}</div>
        {% if order.Customer.Email and order.Customer.Email != "" -%}
        <div class="return-success-email-info-ui">
            <i class="ti-info-alt"></i>
            {{ translations.ReturnConfirmationEmailSent }} <strong>{{ order.Customer.Email }}</strong>
        </div>
        {% endif -%}
        <div class="return-success-steps-title-ui">{{ translations.NextSteps }}</div>
        <ol class="return-success-steps-ui">
            <li>{{ translations.ReturnStep1 }}</li>
            <li>{{ translations.ReturnStep2Address }}: {{ config.Shop.Address.Street }} {{ config.Shop.Address.StreetNo }}{% if config.Shop.Address.UnitNo and config.Shop.Address.UnitNo != "" -%}/{{ config.Shop.Address.UnitNo }}{% endif -%}, {{ config.Shop.Address.ZipCode }} {{ config.Shop.Address.City }}</li>
            <li>{{ translations.ReturnStep3 }}</li>
        </ol>
        <div class="return-success-actions-ui">
            <button class="btn-ui return-success-close-ui hide-container-js closing-modal-js" aria-label="{{ translations.Close }}">
                {{ translations.Close }}
            </button>
        </div>
    </div>
    {% endif -%}
</div>

4. Modyfikacje pliku js/init-ui2.js

Poniższe zmiany dotyczą pliku js/init-ui2.js (po edycji pamiętaj o zminifikowaniu go do init-ui2.min.js). a) Tuż po linii rejestrującej handler openComplaintForm:
js.delegate(document.body, 'click', '.open-complaint-form-js', openComplaintForm);
dodaj poniższy handler obsługujący przełączanie sposobu zwrotu środków – pokazuje on / ukrywa pole na numer konta bankowego:
js.delegate(document.body, 'change', '.refund-method-select-js', function() {
    const container = js.parents(this, 'refund-method-container-js');
    if(!container) return;
    const bankWrapper = container.getElementsByClassName('bank-account-container-js')[0];
    if(!bankWrapper) return;
    const bankInput = bankWrapper.querySelector('input[name="bankAccountNumber"]');
    const validationMsg = bankWrapper.getElementsByClassName('validation-required-js')[0];
    if(this.value === 'bank') {
        bankWrapper.classList.remove('hidden-js');
        if(bankInput) {
            bankInput.disabled = false;
            bankInput.required = true;
        }
    } else {
        bankWrapper.classList.add('hidden-js');
        if(bankInput) {
            bankInput.disabled = true;
            bankInput.required = false;
            bankInput.value = '';
            bankInput.classList.remove('validation-error-lq', 'validation-error-ui');
        }
        if(validationMsg) validationMsg.classList.add('hidden-js');
    }
});
b) W funkcji sendComplaint, bezpośrednio po pętli for (var i=0; i<dataFromHTML.length; i++) dokładającej pola do fd, dodaj fragment dołączający parametr qrHash z adresu URL przy wysyłaniu zwrotu:
if (form.find('input[name="__action"]').val() === 'Order/ReturnAdd') {
    var qrHash = new URLSearchParams(globalThis.location.search).get('qrHash');
    if (qrHash) {
        fd.append('qrHash', qrHash);
    }
}

5. Modyfikacje pliku scss/globals/_globals2.scss

W pliku scss/globals/_globals2.scss wewnątrz selektora opakowującego (tego, który zawiera m.in. .note-ui) dodaj poniższe reguły. Po zmianach pamiętaj o kompilacji SCSS – nie edytuj ręcznie wynikowych plików CSS. a) Style etykiety ilości oraz kontenera wyboru sposobu zwrotu środków (wstaw w sąsiedztwie istniejących reguł sekcji formularza reklamacji/zwrotu):
.amount-stepper-label-ui {
    margin-right: 10px;
    vertical-align: middle;
}

.refund-method-container-ui {
    margin-bottom: 20px;

    .bank-account-container-ui {
        margin-top: 10px;

        input {
            width: 100%;
        }
    }
}
b) Style ekranu sukcesu po wysłaniu zwrotu (ikona, tytuł, lista kolejnych kroków, sekcja z e-mailem i przyciskiem zamknięcia):
.return-success-popup-ui {
    padding: 30px 20px 20px;

    .return-success-icon-ui {
        width: 60px;
        height: 60px;
        border-radius: 50%;
        border: 2px solid #68a204;
        margin: 0 auto 20px;
        display: flex;
        align-items: center;
        justify-content: center;

        i {
            color: #68a204;
            font-size: 26px;
        }
    }

    .return-success-title-ui {
        font-size: 18px;
        font-weight: 500;
        text-align: center;
        margin-bottom: 10px;
    }

    .return-success-desc-ui {
        font-size: 14px;
        color: $primaryColorFont;
        text-align: center;
        margin-bottom: 20px;
    }

    .return-success-email-info-ui {
        background-color: $bgColor;
        border: 1px solid $lightBorderColor;
        padding: 12px;
        border-radius: 4px;
        font-size: 14px;
        margin-bottom: 20px;
        display: flex;
        align-items: flex-start;

        i {
            margin-right: 10px;
            color: $primaryColorFont;
            font-size: 16px;
            line-height: 1.4;
        }

        strong {
            display: block;
        }
    }

    .return-success-steps-title-ui {
        font-weight: 500;
        margin-bottom: 10px;
    }

    .return-success-steps-ui {
        padding-left: 20px;
        margin: 0 0 20px;
        font-size: 14px;

        li {
            margin-bottom: 8px;
            padding-left: 5px;
        }
    }

    .return-success-actions-ui {
        border-top: 1px solid $lightBorderColor;
        padding-top: 15px;
        text-align: right;

        .return-success-close-ui {
            padding: 10px 30px;
        }
    }
}
Po wprowadzeniu wszystkich powyższych zmian w szablonie Szafir pamiętaj o kompilacji oraz minifikacji plików js i scss, zgodnie z artykułem dostępnym pod linkiem https://pomoc.comarchesklep.pl/artykul/kompilacja-i-minifikacja-plikow/.

Szablon Topaz / One Page Shop

Zmiany opisane poniżej dotyczą szablonu Topaz. Szablon One Page Shop ma praktycznie identyczną strukturę – wszystkie modyfikacje dotyczą tych samych plików i mają tę samą zawartość. Wystarczy zastosować poniższą instrukcję w plikach szablonu OPS pod tymi samymi ścieżkami.

1. Tłumaczenia

W panelu administracyjnym sklepu dodaj nowe klucze tłumaczeń wymagane przez funkcjonalność szybkich zwrotów w szablonie Topaz / OPS. RestrictedOrderViewInfo - PL: Wybrane dane zamówienia zostały ukryte ze względów bezpieczeństwa. Możesz zwrócić produkty bez logowania. - EN: Some order details are hidden for security reasons. You can return products without signing in. - DE: Einige Bestelldetails wurden aus Sicherheitsgründen ausgeblendet. Sie können Produkte ohne Anmeldung zurücksenden. - FR: Certaines informations de la commande ont été masquées pour des raisons de sécurité. Vous pouvez retourner des produits sans vous connecter. Prf_ReturnPeriodInfo - PL: Zamówienie można zwrócić w ciągu {0} dni od daty dostawy. - EN: The order can be returned within {0} days from the delivery date. - DE: Die Bestellung kann innerhalb von {0} Tagen ab dem Lieferdatum zurückgegeben werden. - FR: La commande peut être retournée dans un délai de {0} jours à compter de la date de livraison. ComplaintSuccessTitle - PL: Gotowe! Przyjęliśmy Twoje zgłoszenie - EN: Done! We have received your request - DE: Fertig! Wir haben Ihre Meldung erhalten - FR: C'est fait ! Nous avons reçu votre demande ComplaintSuccessDescription - PL: Przygotuj paczkę i odeślij ją do nas – wszystkie szczegóły znajdziesz poniżej. - EN: Prepare the parcel and send it back to us – you will find all the details below. - DE: Bereiten Sie das Paket vor und senden Sie es an uns zurück – alle Details finden Sie unten. - FR: Préparez le colis et renvoyez-le-nous – vous trouverez tous les détails ci-dessous. ComplaintSuccessConfirmationSent - PL: Potwierdzenie zwrotu zostało wysłane na adres: - EN: The return confirmation has been sent to: - DE: Die Rückgabebestätigung wurde an folgende Adresse gesendet: - FR: La confirmation de retour a été envoyée à : ComplaintSuccessStepsTitle - PL: Następne kroki - EN: Next steps - DE: Nächste Schritte - FR: Étapes suivantes ComplaintSuccessStep1 - PL: Bezpiecznie zapakuj swoje produkty - EN: Pack your products securely - DE: Verpacken Sie Ihre Produkte sicher - FR: Emballez vos produits en toute sécurité ComplaintSuccessStep2 - PL: Wyślij paczkę na adres: - EN: Send the parcel to: - DE: Senden Sie das Paket an folgende Adresse: - FR: Envoyez le colis à l'adresse : ComplaintSuccessStep3 - PL: Pieniądze zwrócimy niezwłocznie po otrzymaniu i sprawdzeniu Twojej paczki. - EN: We will refund the money immediately after receiving and inspecting your parcel. - DE: Wir erstatten den Betrag unverzüglich nach Erhalt und Prüfung Ihres Pakets. - FR: Nous rembourserons l'argent immédiatement après réception et vérification de votre colis. ReturnInThreeSteps - PL: Zwróć towar w 3 krokach - EN: Return the product in 3 steps - DE: Geben Sie die Ware in 3 Schritten zurück - FR: Retournez la marchandise en 3 étapes ReturnWithoutReasonInfo - PL: Przysługuje Ci możliwość zwrotu bez podania przyczyny. - EN: You have the right to return the product without giving a reason. - DE: Sie haben das Recht, die Ware ohne Angabe von Gründen zurückzugeben. - FR: Vous avez le droit de retourner la marchandise sans donner de motif. OrEnterOrderNumber - PL: lub podaj numer zamówienia - EN: or enter the order number - DE: oder geben Sie die Bestellnummer ein - FR: ou entrez le numéro de commande FillForm - PL: Wypełnij formularz - EN: Fill out the form - DE: Füllen Sie das Formular aus - FR: Remplissez le formulaire ReturnOnline - PL: zwrotu online - EN: online return - DE: Online-Rückgabe - FR: retour en ligne SendParcel - PL: Wyślij paczkę - EN: Send the parcel - DE: Senden Sie das Paket - FR: Envoyez le colis SendParcelToOurAddress - PL: nadaj przesyłkę na nasz adres - EN: send the parcel to our address - DE: senden Sie das Paket an unsere Adresse - FR: envoyez le colis à notre adresse FastSimpleSecure - PL: Szybko, prosto i bezpiecznie. - EN: Fast, simple and secure. - DE: Schnell, einfach und sicher. - FR: Rapide, simple et sûr. ReadyForReturn - PL: Gotowy do zwrotu? - EN: Ready for return? - DE: Bereit zur Rückgabe? - FR: Prêt pour le retour ? ReadyForReturnInfo - PL: Kliknij poniżej, aby rozpocząć proces zwrotu. Przeprowadzimy Cię przez wszystkie kroki. - EN: Click below to start the return process. We will guide you through all the steps. - DE: Klicken Sie unten, um den Rückgabeprozess zu starten. Wir führen Sie durch alle Schritte. - FR: Cliquez ci-dessous pour commencer le processus de retour. Nous vous guiderons à chaque étape. StartReturn - PL: Rozpocznij zwrot - EN: Start return - DE: Rückgabe starten - FR: Commencer le retour ProductReturn - PL: Zwrot produktu - EN: Product return - DE: Produktrückgabe - FR: Retour du produit ProductReturnFormInfo - PL: Wprowadź dane zamówienia, aby zlokalizować zakup i rozpocząć proces zwrotu. Numer zamówienia znajdziesz w e-mailu z potwierdzeniem. - EN: Enter the order details to locate the purchase and start the return process. You will find the order number in the confirmation e-mail. - DE: Geben Sie die Bestelldaten ein, um den Kauf zu lokalisieren und den Rückgabeprozess zu starten. Die Bestellnummer finden Sie in der Bestätigungs-E-Mail. - FR: Saisissez les données de la commande pour localiser l'achat et démarrer le processus de retour. Vous trouverez le numéro de commande dans l'e-mail de confirmation. FindOrder - PL: Znajdź zamówienie - EN: Find order - DE: Bestellung finden - FR: Trouver la commande RefundLookupError - PL: Wystąpił błąd podczas wyszukiwania zamówienia. Spróbuj ponownie później. - EN: An error occurred while searching for the order. Please try again later. - DE: Fehler beim Suchen nach der Bestellung. Versuchen Sie es später erneut. - FR: Une erreur s'est produite lors de la recherche de la commande. Veuillez réessayer plus tard. LoginToSeeOrdersAndReturn - PL: aby zobaczyć swoje zamówienia i dokonać zwrotu. - EN: to see your orders and make a return. - DE: um Ihre Bestellungen zu sehen und eine Rückgabe zu machen. - FR: pour voir vos commandes et faire un retour. InvalidEmail - PL: Nieprawidłowy adres e-mail - EN: Invalid e-mail address - DE: Ungültige E-Mail-Adresse - FR: L'adresse e-mail est incorrecte. RefundMethod - PL: Sposób zwrotu środków - EN: Refund method - DE: Rückerstattungsmethode - FR: Mode de remboursement RefundAsPaid - PL: Zwrot na sposób płatności - EN: Refund to the original payment method - DE: Rückerstattung auf die ursprüngliche Zahlungsmethode - FR: Remboursement sur le mode de paiement initial RefundToBankAccount - PL: Zwrot na konto bankowe - EN: Refund to bank account - DE: Rückerstattung auf das Bankkonto - FR: Remboursement sur un compte bancaire

2. Nowa strona Szybkie zwroty

Funkcja szybkich zwrotów wymaga utworzenia dodatkowej strony statycznej refunds. Wykonaj poniższe kroki.

Plik refunds.html w katalogu głównym szablonu

W katalogu głównym szablonu utwórz nowy plik refunds.html z następującą zawartością:
{% extends '_layout.html' -%}
{% block pageContent -%}
{% include 'static-elements/refunds/refunds.html' -%}
{% endblock -%}

Plik static-elements/refunds/refunds.html

W folderze static-elements utwórz nowy katalog refunds, a w nim plik refunds.html:
{% include 'partials/common/breadcrumbs.html' -%}

<div class="container my-5 refunds-page-wrapper">

    <!-- Nagłówek główny -->
    <div class="text-center mb-5">
        <h1 class="mb-3">{{ translations.ReturnInThreeSteps }}</h1>
        <p class="lead text-muted">{{ translations.ReturnWithoutReasonInfo }}</p>
    </div>

    <!-- Sekcja 3 kroków (Siatka 3-kolumnowa) -->
    <div class="row text-center mb-5">
        <div class="col-md-4 mb-4">
            <div class="p-4 border rounded bg-light h-100">
                <h3 class="h5">1. {{ translations.Log_Login }}</h3>
                <p class="mb-0">{{ translations.OrEnterOrderNumber }}</p>
            </div>
        </div>
        <div class="col-md-4 mb-4">
            <div class="p-4 border rounded bg-light h-100">
                <h3 class="h5">2. {{ translations.FillForm }}</h3>
                <p class="mb-0">{{ translations.ReturnOnline }}</p>
            </div>
        </div>
        <div class="col-md-4 mb-4">
            <div class="p-4 border rounded bg-light h-100">
                <h3 class="h5">3. {{ translations.SendParcel }}</h3>
                <p class="mb-0">{{ translations.SendParcelToOurAddress }}</p>
            </div>
        </div>
    </div>

    <!-- Wyróżniony tekst -->
    <div class="text-center mb-5">
        <h2 class="text-success h3">{{ translations.FastSimpleSecure }}</h2>
    </div>

    <!-- Sekcja gotowości do zwrotu (Call to Action) -->
    <div class="text-center p-5 border rounded mb-5">
        <h2 class="h3">{{ translations.ReadyForReturn }}</h2>
        <p>{{ translations.ReadyForReturnInfo }}</p>

        <div class="mt-4">
            {% if customer.Authenticated -%}
                <a href="/Return/List" class="btn btn-primary btn-lg">{{ translations.StartReturn }}</a>
            {% else -%}
                <a href="/Return/List" class="btn btn-primary btn-lg">{{ translations.StartReturn }}</a>
            {% endif -%}
        </div>
    </div>

    <!-- Wyszukiwanie zamówienia dla niezalogowanych -->
    <div class="row justify-content-center mb-5">
        <div class="col-md-6 col-lg-5">
            <div class="text-center mb-4">
                <h3 class="h4">{{ translations.ProductReturn }}</h3>
                <p class="text-muted">{{ translations.ProductReturnFormInfo }}</p>
            </div>

            <form action="/Return/FindOrder" method="POST" class="border p-4 rounded bg-white">
                <div class="form-group mb-3">
                    <label class="font-weight-bold">{{ translations.Com_OrderNumber }}</label>
                    <input type="text" class="form-control" name="OrderNumber" required>
                </div>
                <div class="form-group mb-4">
                    <label class="font-weight-bold">{{ translations.EmailAddress }}</label>
                    <input type="email" class="form-control" name="Email" required>
                </div>
                <button type="submit" class="btn btn-dark w-100 btn-lg">{{ translations.FindOrder }}</button>
            </form>
        </div>
    </div>

    <!-- Zachęta do logowania dla niezalogowanych (Gości) -->
    {% if customer.Authenticated == false -%}
        <div class="text-center py-4 mt-4 border-top">
            <h4 class="h5">{{ translations.Reg_HaveAcc }}</h4>
            <p>{{ translations.LoginToSeeOrdersAndReturn }}</p>
            <!-- W Topaz przycisk logowania często otwiera popup ze zdefiniowaną klasą js-login-popup-trigger -->
            <button class="btn btn-outline-primary js-login-popup-trigger">{{ translations.Log_Login }}</button>
        </div>
        {% include 'partials/common/login-register-popup.html' -%}
    {% endif -%}

</div>

<!-- Globalny komponent Newslettera -->
{% if settings.newsletterOnFunctionalPages == 'yes' -%}
    {% include 'partials/newsletter-global.html' -%}
{% endif -%}

Pliki SCSS strony Szybkie zwroty

W folderze scss/static-elements utwórz nowy katalog refunds, a w nim trzy pliki: refunds-g.scss (style ogólne), refunds-d.scss (desktop) oraz refunds-m.scss (mobile). scss/static-elements/refunds/refunds-g.scss:
.refunds-container {
    box-sizing: border-box;
    margin: 0 auto;
    color: $primaryFontColor;
    background-color: $primaryPageBg;

    .refunds-view {
        display: flex;
        flex-direction: column;
        align-items: center;

        &.hidden-js {
            display: none;
        }
    }

    .refunds-intro {
        width: 100%;
        align-self: stretch;

        &__heading {
            margin: 0 0 16px;
            font-size: $mediumFontSize;
            font-weight: 600;
            line-height: 1.4;
            color: $primaryFontColor;
        }

        &__lead {
            margin: 0 0 16px;
            font-size: 16px;
            font-weight: 500;
            line-height: 1.5;
            color: $primaryFontColor;
        }

        &__hint {
            margin: 16px 0 0;
            font-size: $extraSmallFontSize;
            color: $secondaryFontColor;
        }
    }

    .refunds-steps {
        list-style: none;
        counter-reset: refund-step;
        margin: 0;
        padding: 0;
        display: flex;
        flex-direction: column;
        gap: 8px;

        &__item {
            counter-increment: refund-step;
            display: flex;
            align-items: center;
            gap: 12px;

            &::before {
                content: counter(refund-step);
                flex: 0 0 auto;
                width: 32px;
                height: 32px;
                border-radius: 50%;
                background-color: $primaryBtnBg;
                color: $primaryBtnFontColor;
                font-weight: 600;
                font-size: $smallFontSize;
                line-height: 1;
                display: inline-flex;
                align-items: center;
                justify-content: center;
            }
        }

        &__text {
            font-size: $smallFontSize;
            line-height: 1.5;
            color: $primaryFontColor;

            strong {
                font-weight: 600;
            }
        }
    }

    .refunds-card,
    .refunds-lookup {
        box-sizing: border-box;
        width: 100%;
        background-color: $primaryPageBg;
        border: 1px solid $borderColor;
        border-radius: 8px;
        display: flex;
        flex-direction: column;
        margin-left: auto;
        margin-right: auto;
    }

    .refunds-card {
        align-items: center;
        text-align: center;
        gap: 12px;

        &__heading {
            margin: 0;
            font-size: $bigFontSize;
            font-weight: 600;
            line-height: 1.3;
            color: $primaryFontColor;
        }

        &__text {
            margin: 0;
            font-size: 16px;
            line-height: 1.5;
            color: $secondaryFontColor;
        }

        &__btn {
            width: 100%;
            margin-top: 12px;
        }
    }

    .refund-form-js {
        .form__invalid-input {
            margin: 4px 0 0;
            font-size: $extraSmallFontSize;
            line-height: 16px;
            color: $messageErrorColor;
        }
    }

    .refunds-lookup {
        gap: 16px;

        &__heading {
            margin: 0;
            font-size: $bigFontSize;
            font-weight: 600;
            line-height: 1.3;
            color: $primaryFontColor;
        }

        &__lead {
            margin: 0;
            font-size: $smallFontSize;
            line-height: 1.5;
            color: $secondaryFontColor;
        }

        &__loginPrompt {
            margin: 8px 0 0;
            font-size: $smallFontSize;
            color: $primaryFontColor;
        }

        &__loginLink {
            color: $linkFontColor;
            font-weight: 600;
            text-decoration: underline;

            &:hover,
            &:focus {
                text-decoration: none;
            }
        }

        &__error {
            margin: 0;
            font-size: $smallFontSize;
            color: $messageErrorColor;
        }
    }
}

.loginRegister--login-only {
    .loginRegisterTabsContainer {
        display: none;
    }

    .registrationForm-js {
        display: none;
    }
}
scss/static-elements/refunds/refunds-d.scss:
@media screen and (min-width: 769px) {
    .refunds-container {
        max-width: 1400px;
        padding-top: 32px;
        padding-bottom: 64px;

        .refunds-view {
            gap: 32px;
        }

        .refunds-intro {
            &__heading {
                font-size: 20px;
            }

            &__lead {
                margin-bottom: 24px;
            }
        }

        .refunds-card,
        .refunds-lookup {
            max-width: 578px;
        }

        .refunds-card {
            padding: 40px;
        }

        .refunds-lookup {
            padding: 32px;
        }
    }
}
scss/static-elements/refunds/refunds-m.scss:
@media screen and (max-width: 768px) {
    .refunds-container {
        padding: 16px 3% 40px;

        .refunds-view {
            gap: 24px;
        }

        .refunds-intro {
            &__heading {
                font-size: 18px;
            }

            &__lead {
                font-size: $smallFontSize;
                margin-bottom: 16px;
            }
        }

        .refunds-steps {
            &__item {
                &::before {
                    width: 28px;
                    height: 28px;
                }
            }
        }

        .refunds-card {
            padding: 24px 16px;

            &__heading {
                font-size: $mediumFontSize;
            }

            &__text {
                font-size: $smallFontSize;
            }
        }

        .refunds-lookup {
            padding: 20px 16px;

            &__heading {
                font-size: $mediumFontSize;
            }
        }
    }
}

3. Modyfikacje istniejących plików HTML

partials/customer/order-content.html

W pliku partials/customer/order-content.html wykonaj poniższe zmiany. a) Bezpośrednio po otwarciu kontenera <div class="orderContent order-content-js"> dodaj dwa nowe bannery informacyjne (jeden o ukrytych danych zamówienia, drugi o terminie zwrotu, wraz z wyliczaniem flagi hasReturnableProduct):
{% if order.Restricted -%}
<div class="orderContent__returnInfo" role="note">
    <!-- TODO: ikona SVG informacyjna z klasą orderContent__returnInfo__icon -->
    {{ translations.RestrictedOrderViewInfo }}
</div>
{% endif -%}
{% assign hasReturnableProduct = false -%}
{% if config.Complaints.ReturnsEnabled -%}
{% for product in order.Products -%}
{% if product.CanReturn -%}
{% assign hasReturnableProduct = true -%}
{% break -%}
{% endif -%}
{% endfor -%}
{% endif -%}
{% if hasReturnableProduct -%}
<div class="orderContent__returnInfo" role="note">
    <!-- TODO: ikona SVG informacyjna z klasą orderContent__returnInfo__icon -->
    {{ translations.Prf_ReturnPeriodInfo | Format: config.Complaints.DaysToReturn }}
</div>
{% endif -%}
b) Kontener <div class="orderContent__docsToPrint">...</div> (z dokumentami do druku) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}, aby ukrywać go dla zamówień typu restricted. c) Cały dotychczasowy blok przycisków reklamacji/zwrotu (oparty na konstrukcji {% if ComplaintsEnabled and ReturnsEnabled %} ... {% elseif ComplaintsEnabled %} ... {% elseif ReturnsEnabled %} ... {% endif %} z jednym wspólnym przyciskiem) zamień na dwa niezależne warunki, dzięki czemu dla produktu uprawnionego zarówno do reklamacji, jak i do zwrotu, oba przyciski wyświetlają się obok siebie. Strukturę wewnątrz warunku {% if product.CanComplain or product.CanReturn -%} zastąp poniższym kodem:
{% if config.Complaints.ComplaintsEnabled == true and product.CanComplain -%}
<button class="orderContent__complainBtn orderContent__complainBtn--complaint showPopupBtn-js addDataToComplaintForm-js" data-popup-class="popupDialog" data-form-type="complaint" data-product-id="{{product.No}}" data-image-id="{{product.ImageId}}" data-imageext="{{product.Image.ExternalUrl}}" data-product-name="{{product.NameNoHtml | H}}" data-product-complain="{{product.CanComplain}}" data-product-count="{{ newProductQuantity }} {{ product.Unit }}" data-product-unit="{{ product.Unit }}" data-product-description="{{ productAttributes | Join: ' / ' | H }}" data-product-return="false" data-product-quantity="{{newProductQuantity}}" data-order-id="{{order.Id}}" data-order-date="{{order.Date | Date: 'yyyy-MM-dd'}}">
    <svg width="16" height="16">
        <use href="#comment-alt-regular"></use>
    </svg>
    {{translations.Prf_SendComplaint }}
</button>
{% endif -%}
{% if config.Complaints.ReturnsEnabled == true and product.CanReturn -%}
<button class="orderContent__complainBtn orderContent__complainBtn--return showPopupBtn-js addDataToComplaintForm-js" data-popup-class="popupDialog" data-form-type="return" data-product-id="{{product.No}}" data-image-id="{{product.ImageId}}" data-imageext="{{product.Image.ExternalUrl}}" data-product-name="{{product.NameNoHtml | H}}" data-product-complain="false" data-product-count="{{ newProductQuantity }} {{ product.Unit }}" data-product-unit="{{ product.Unit }}" data-product-description="{{ productAttributes | Join: ' / ' | H }}" data-product-return="{{product.CanReturn}}" data-product-quantity="{{newProductQuantity}}" data-order-id="{{order.Id}}" data-order-date="{{order.Date | Date: 'yyyy-MM-dd'}}">
    <svg width="16" height="16">
        <use href="#sync-regular"></use>
    </svg>
    {{ translations.Prf_OrderReturn }}
</button>
{% endif -%}
Kluczowe różnice w stosunku do poprzedniej wersji: każdy przycisk renderowany jest niezależnie (oba mogą wystąpić równocześnie), przyciski mają modyfikatory orderContent__complainBtn--complaint i orderContent__complainBtn--return, atrybut data-form-type (odczytywany w JS), w przycisku reklamacji wymuszone data-product-return="false", w przycisku zwrotu wymuszone data-product-complain="false", ikony 16x16 (#comment-alt-regular dla reklamacji, #sync-regular dla zwrotu), a etykieta przycisku zawiera już tylko jedno tłumaczenie. d) W pozostałych miejscach z przyciskami reklamacji/zwrotu (sekcje, w których nie zmieniają się klasy i ikony) dodaj jedynie dwa nowe atrybuty:
data-product-unit="{{ product.Unit }}"
data-product-description="{{ productAttributes | Join: ' / ' | H }}"
e) W sekcji załączników zamówienia zamień:
{% if order.Attachments[0] -%}
na:
{% if order.Attachments[0] and order.Restricted == false -%}
f) W kontenerze <div class="orderContent__recipient orderContent__infoBox"> zamień wyświetlanie adresu dostawy:
<span class="orderContent__lightText">{{ order.Customer.DeliveryAddress.Street }} {{ order.Customer.DeliveryAddress.StreetNo }} / {{ order.Customer.DeliveryAddress.UnitNo }}</span>
na:
<span class="orderContent__lightText">{{ order.Customer.DeliveryAddress.Street }} {{ order.Customer.DeliveryAddress.StreetNo }}{% if order.Customer.DeliveryAddress.UnitNo != null and order.Customer.DeliveryAddress.UnitNo != '' -%} / {{ order.Customer.DeliveryAddress.UnitNo }}{% endif -%}</span>
g) Sekcję z przyciskami akcji zamówienia (orderCancel-js, ponowienie płatności itd.) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}. Wstaw {% unless order.Restricted -%} bezpośrednio przed warunkiem {% if order.CanRestorePayment -%}, a {% endunless -%} po zamykającym {% endif -%} bloku z przyciskiem anulowania zamówienia.

partials/common/complaint-popup.html

Plik partials/common/complaint-popup.html wymaga gruntownej przebudowy. Usuwamy z niego radiowe przyciski wyboru "reklamacja/zwrot", a typ formularza jest teraz przekazywany z zewnątrz przez parametr __include. Sterowanie ilością zostało przeniesione do kafelka z produktem (z etykietą i obsługą wariantu statycznego, gdy zostaje tylko 1 sztuka). W formularzu zwrotu zamiast samego pola numeru konta pojawia się sekcja wyboru sposobu zwrotu środków (refundMethod-js) – z opcją „zwrot na sposób płatności" (domyślna) lub „zwrot na konto bankowe". Pole numeru konta jest domyślnie ukryte i disabled; pokazuje się dopiero po wybraniu opcji „konto bankowe" (obsługa w JS w metodzie changeRefundMethod). Tytuł, kafelek produktu i formularz oznaczone są dodatkową klasą complain-form-view-js, dzięki czemu po pomyślnym wysłaniu formularza można je ukryć i wyświetlić ekran sukcesu (complain-success-view-js). Zastąp całą zawartość pliku poniższym kodem:
{% if hideContent -%}
{% else -%}
{% assign formType = include -%}
{% assign isReturn = false -%}
{% if formType == 'return' -%}
{% assign isReturn = true -%}
{% endif -%}
<div class="popupDialog popupDialog__complain popupDialog-js">
    {% assign order = customer-profile.Order -%}
    <div class="popupDialog__wrapper">
        <button class="popupDialog__closeBtn closePopupBtn-js">
            <!-- TODO: ikona SVG zamknięcia – jak w pozostałych popupach szablonu -->
        </button>
        <span class="popupDialog__title complain-form-view-js">
            {% if isReturn -%}
            {{ translations.Prf_OrderReturn }}
            {% else -%}
            {{ translations.Prf_SendComplaint }}
            {% endif -%}
        </span>
        <div class="complain__product complain-form-view-js">
            <figure><img class="productImage-js" alt="product_image" /></figure>
            <div class="complain__productInfo">
                <!-- TODO: zweryfikuj z szablonem elementy z klasami productName-js i productDescription-js (nazwa i opis produktu) -->
                <span class="productName-js"></span>
                <span class="productDescription-js"></span>
                <div class="complain__quantity">
                    <label class="complain__quantityLabel" for="complaint-quantity">{{translations.Com_Quantity}}:</label>
                    <div class="complain__quantityControl min-js quantityControl-js">
                        <button class="button-minus-add-product" type="button" aria-label="{{translations.ButtonMinusAddProduct}}" data-field="quantity">
                            <!-- TODO: ikona SVG minus -->
                        </button>
                        <input id="complaint-quantity" class="quantity-field quantity__field-js" max="" min="1" name="quantity" type="number" value="1" data-decimal="false" />
                        <button class="button-plus-add-product" type="button" aria-label="{{ translations.ButtonPlusAddProduct }}" data-field="quantity">
                            <!-- TODO: ikona SVG plus -->
                        </button>
                    </div>
                    <span class="quantityStatic-js hidden"></span>
                    <span class="productUnit-js"></span>
                </div>
            </div>
        </div>
        <div class="form complain__form inputs-container-js complain-form-view-js" data-success-info="{{ translations.ReportSuccessInfo }}">
            <input name="__action" type="hidden" value="{% if isReturn -%}Order/ReturnAdd{% else -%}Order/ComplaintAdd{% endif -%}" />
            <strong>{{ translations.ReportDetails }}</strong>
            {% unless isReturn -%}
            <div class="form__input-wrapper">
                {% if config.Complaints.Defects <> null -%}
                {% assign defectsSize = config.Complaints.Defects | Size -%}
                <label class="hidden" for="defectId">{{ translations.ChooseComplaintCause }}</label>
                <select class="form__input-value form__input-value-js {% if settings.themeName == 'Dark' -%} darkTheme {% endif -%}" name="defectId" required="">
                    {% if defectsSize > 1 -%}
                    <option value="-1">* {{translations.ChooseComplaintCause}}</option>
                    {% endif -%}
                    {% for def in config.Complaints.Defects -%}
                    <option value="{{def.Id}}">{{def.Name}}</option>
                    {% endfor -%}
                </select>
                {% endif -%}
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            <div class="form__input-wrapper">
                <span class="form__icons">
                    <!-- TODO: ikona SVG kalendarza -->
                </span>
                <input id="defectDate" class="form__input-value form__icon_padding form__input-value-js orderDate-js" max="{{config.Now | Date: 'yyyy-MM-dd'}}" min="{{order.Date | Date: 'yyyy-MM-dd'}}" name="defectDate" type="date" value="{{config.Now | Date: 'yyyy-MM-dd'}}" placeholder="yyyy-MM-dd" />
                <label class="form__input-info" for="defectDate">* {{translations.Prf_DefectDate}}</label>
            </div>
            <div class="form__input-wrapper">
                {% if config.Complaints.Requests <> null -%}
                {% assign requestsSize = config.Complaints.Requests | Size -%}
                <label class="hidden" for="requestId">{{ translations.Prf_ComplainRequest }}</label>
                <select class="form__input-value form__input-value-js {% if settings.themeName == 'Dark' -%} darkTheme {% endif -%}" name="requestId" required="">
                    {% if requestsSize > 1 -%}
                    <option value="-1">* {{translations.Prf_ComplainRequest}}</option>
                    {% endif -%}
                    {% for req in config.Complaints.Requests -%}
                    <option value="{{req.Id}}">{{req.Name}}</option>
                    {% endfor -%}
                </select>
                {% endif -%}
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            {% else -%}
            {% assign returnTypes = config.Complaints.Returns | Size -%}
            {% if returnTypes > 1 -%}
            <div class="form__input-wrapper">
                <label class="hidden" for="returnId">{{ translations.ChooseReturn }}</label>
                <select class="form__input-value form__input-value-js {% if settings.themeName == 'Dark' -%} darkTheme {% endif -%}" name="returnId" required="">
                    <option value="-1">* {{translations.ChooseReturn}}</option>
                    {% for return in config.Complaints.Returns -%}
                    <option value="{{return.Id}}">{{return.Name}}</option>
                    {% endfor -%}
                </select>
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            {% endif %}
            {% endunless -%}
            <div class="form__input-wrapper returnInputWrapper-js refundMethodWrapper-js">
                <label class="complain__sectionLabel" for="refundMethod">{{ translations.RefundMethod }}</label>
                <select id="refundMethod" class="form__input-value form__input-value-js refundMethod-js {% if settings.themeName == 'Dark' -%}darkTheme{% endif -%}" name="refundMethod">
                    <option value="payment">{{ translations.RefundAsPaid }}{% if order.Payment.Name != null and order.Payment.Name != '' %} ({{ order.Payment.Name }}){% endif %}</option>
                    <option value="account">{{ translations.RefundToBankAccount }}</option>
                </select>
            </div>
            <div class="form__input-wrapper accountNumberWrapper-js" style="display: none;">
                <input id="accountNumber" class="form__input-value form__input-value-js" disabled="disabled" maxlength="50" name="accountNumber" type="text" />
                <label class="form__input-info form__input-info-js" for="accountNumber">{{translations.Crt_BankAccountNumber}}</label>
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            <div class="form__input-wrapper">
                {{translations.Prf_AdditionalInfo}}
                <textarea class="form__input-value" name="message" aria-label="{{ translations.Prf_AdditionalInfo }}"></textarea>
            </div>
            <div class="form__input-wrapper">
                <span class="form__requiredFields--info">* {{ translations.Com_RequiredFields }}</span>
            </div>
            {% if config.Complaints.AttachmentsEnabled -%}
            <div class="form__input-wrapper attachementsInputWrapper" data-not-added-info="{{translations.AttachementsNotAdded}}">
                <button class="form__attachementsLabel form__attachementsLabel--btn form__attachementsLabel-js" data-page="complaints">
                    <!-- TODO: ikona SVG dodawania załącznika -->
                    {{ translations.AddAttachment }}
                </button>
                {% capture maxSize -%}{{config.Complaints.AttachmentMaxSize | DividedBy: 1024}}KB{% endcapture -%}
                {% for i in (1..config.Complaints.AttachmentsMaxCount) -%}
                <div class="form__attachement-input-container form__attachement-input-container-attachments form__attachement-input-container--hidden">
                    <!-- TODO: ikona SVG oraz element z nazwą pliku (form__attachement-input-container-attachments__text) -->
                    <input class="addAttachementInComplaint-js" accept="{{ config.Complaints.AttachmentExtensions }}" name="file" type="file" aria-label="{{ translations.AddAttachment }}" data-file-size="{{ config.Complaints.AttachmentMaxSize }}" data-size-exceeded="{{ translations.Com_FileSizeExceeded | Format: maxSize }}" data-invalid-file="{{ translations.Com_InvalidFile | Format: config.Complaints.AttachmentExtensions }}" />
                    <button class="form__clear-attachement-input clearFileInput-js" style="display: none;">
                        <!-- TODO: ikona SVG usuwania załącznika -->
                    </button>
                </div>
                {% endfor -%}
            </div>
            {% endif -%}
            <input class="productId-js" name="no" type="hidden" value="" />
            <input class="orderId-js" name="orderId" type="hidden" value="{{order.Id}}" />
            <button class="primary-action-button orderComplaintOrReturnAdd-js" type="button" data-id="{{order.Id}}">{{translations.Report}}</button>
        </div>
        <div class="complain__successView complain-success-view-js hidden">
            <div class="complain__successIcon">
                <!-- TODO: ikona SVG potwierdzenia (zielony "check", klasa svgIcon) -->
            </div>
            <h2 class="complain__successTitle">{{ translations.ComplaintSuccessTitle }}</h2>
            <p class="complain__successDescription">{{ translations.ComplaintSuccessDescription }}</p>
            <div class="complain__successInfoBox">
                <!-- TODO: ikona SVG informacyjna (klasa svgIcon) -->
                <span>{{ translations.ComplaintSuccessConfirmationSent }}
                    <strong>{{ order.Customer.Email }}</strong>
                </span>
            </div>
            <h3 class="complain__successStepsTitle">{{ translations.ComplaintSuccessStepsTitle }}</h3>
            <ol class="complain__successSteps">
                <li>{{ translations.ComplaintSuccessStep1 }}</li>
                <li>{{ translations.ComplaintSuccessStep2 }} {{ config.Shop.Address.Street }} {{ config.Shop.Address.StreetNo }}{% if config.Shop.Address.UnitNo != '' %}/{{ config.Shop.Address.UnitNo }}{% endif %}, {{ config.Shop.Address.ZipCode }} {{ config.Shop.Address.City }}</li>
                <li>{{ translations.ComplaintSuccessStep3 }}</li>
            </ol>
            <div class="complain__successActions">
                <button class="primary-action-button closePopupBtn-js" type="button">{{ translations.BtnClose }}</button>
            </div>
        </div>
    </div>
</div>
{% endif -%}

4. Modyfikacje pliku js/layout1.js

Poniższe zmiany dotyczą pliku js/layout1.js. Po edycji pamiętaj o zminifikowaniu pliku do layout1.min.js. a) W obiekcie customerProfile usuń całą metodę setComplainReturnRadioButtons (radiowy przełącznik reklamacja/zwrot nie jest już potrzebny – typ formularza jest teraz przekazywany przy otwieraniu popupu). b) W tym samym obiekcie zastąp całą metodę addDataToComplaintForm nową implementacją, która odczytuje typ formularza z atrybutu data-form-type przycisku i przekazuje go do szablonu jako parametr __include:
addDataToComplaintForm: function (e) {
    const template = 'partials/common/complaint-popup.html';
    const data = e.currentTarget;
    const formType = data.dataset.formType === 'return' ? 'return' : 'complaint';

    $.get('', {__template: template, __include: "'" + formType + "'"}, function(result) {
        $('.customer__content-js').append(result.template);
        $('.popupDialog__complain').show();
        $('body').addClass('customerProfileNoScroll');

        const image = $('.productImage-js');
        const productName = $('.productName-js');
        const inputId = $('.productId-js');
        const productQuantity = $('.quantity__field-js');
        const quantityControl = $('.quantityControl-js');
        const quantityStatic = $('.quantityStatic-js');
        const productUnit = $('.productUnit-js');
        const productDescription = $('.productDescription-js');

        const orderId = $('.orderId-js');
        const buttonOrderId = $('.orderComplaintOrReturnAdd-js');
        const orderDate = $('.orderDate-js');

        productName.text(data.dataset.productName);
        productUnit.text(data.dataset.productUnit || '');
        productDescription.text(data.dataset.productDescription || '');
        inputId.val(data.dataset.productId);
        productQuantity.attr('max', data.dataset.productQuantity);

        if (parseInt(data.dataset.productQuantity, 10) <= 1) {
            quantityControl.addClass('hidden');
            quantityStatic.text(data.dataset.productQuantity).removeClass('hidden');
        } else {
            quantityControl.removeClass('hidden');
            quantityStatic.addClass('hidden');
        }

        orderId.val(data.dataset.orderId);
        buttonOrderId.attr('data-id', data.dataset.orderId);
        orderDate.attr('min', data.dataset.orderDate);

        if (data.dataset.imageext != null && data.dataset.imageext != "") {
            image.attr('src', data.dataset.imageext);
        } else if (data.dataset.imageId != null && data.dataset.imageId != "") {
            image.attr('src', '/Image/?id=' + data.dataset.imageId);
        }

        if (image.attr('src') === '' || image.attr('src') == null) {
            image.closest('figure').addClass('noImage-js');
        }

        setTimeout(function() {
            app.activateFocusTrap('.popupDialog__complain', e.target);
        }, 200);
    });
},
c) Zastąp metodę changeReturnComplaintForm nową wersją (obsługuje również pole numeru konta i wywołuje changeRefundMethod po przełączeniu na zwrot):
changeReturnComplaintForm: function (e) {
    const form = $(e.currentTarget).closest('.inputs-container-js');
    const complaintInputs = form.find('.complaintInputWrapper-js');
    const returnInputs = form.find('.returnInputWrapper-js');
    const accountWrapper = form.find('.accountNumberWrapper-js');
    const accountInput = accountWrapper.find('input[name="accountNumber"]');

    if ($(e.currentTarget).is(':checked') && e.currentTarget.dataset.name === 'complaint' ) {
        $.each(complaintInputs, function (index, value) {
            $(value).find('input, select').first().removeAttr('disabled');
            $(value).show(300);
        });
        returnInputs.each(function () {
            $(this).find('input, select').first().attr('disabled', 'true');
        });
        returnInputs.hide(300);
        accountInput.removeAttr('disabled').removeAttr('required').removeClass('form__validation-error-js');
        accountWrapper.find('.form__validation-required-js').hide();
        accountWrapper.show(300);
    }

    if ($(e.currentTarget).is(':checked') && e.currentTarget.dataset.name === 'return' ) {
        $.each(complaintInputs, function (index, value) {
            $(value).find('input, select').first().attr('disabled', 'true');
            $(value).hide(300);
        });
        returnInputs.each(function () {
            $(this).find('input, select').first().removeAttr('disabled');
        });
        returnInputs.show(300);
        customerProfile.changeRefundMethod(form);
    }
},
d) Tuż za metodą changeReturnComplaintForm dodaj nową metodę changeRefundMethod (pokazuje / ukrywa pole numeru konta bankowego na podstawie wybranego sposobu zwrotu):
changeRefundMethod: function (formOrEvent) {
    const form = formOrEvent && formOrEvent.currentTarget
        ? $(formOrEvent.currentTarget).closest('.inputs-container-js')
        : $(formOrEvent);
    const select = form.find('.refundMethod-js');
    const accountWrapper = form.find('.accountNumberWrapper-js');
    const accountInput = accountWrapper.find('input[name="accountNumber"]');

    if (select.val() === 'account') {
        accountInput.removeAttr('disabled').attr('required', 'required');
        accountWrapper.show(300);
    } else {
        accountInput.attr('disabled', 'true').removeAttr('required').removeClass('form__validation-error-js');
        accountWrapper.find('.form__validation-required-js').hide();
        accountWrapper.hide(300);
    }
},
e) W metodzie wysyłającej formularz reklamacji/zwrotu (gdzie znajduje się pętla for (let i=0; i<dataFromHTML.length; i++)) zaraz po pętli dodaj fragment dołączający parametr qrHash z URL-a przy wysyłaniu zwrotu:
if (form.find('input[name="__action"]').val() === 'Order/ReturnAdd') {
    const qrHash = new URLSearchParams(globalThis.location.search).get('qrHash');
    if (qrHash) {
        fd.append('qrHash', qrHash);
    }
}
f) W tej samej metodzie, w callbacku success po pomyślnym wysłaniu, zamień fragment:
if (data.action.Result) {
    const message = form.data('success-info');
    app.showTemporaryPopup(message, 'success', '', 8000);
    $('.clearFileInput-js').hide();
    app.hidePopup(e);
    sessionStorage.removeItem('complains');
    sessionStorage.removeItem('order' + (e.currentTarget).dataset.id);
    $('.order' + (e.currentTarget).dataset.id).remove();
    $('.popupDialog__complain').remove();
    $('body').removeClass('customerProfileNoScroll');
    customerProfile.showOrderDetails(e);
}
na:
if (data.action.Result) {
    $('.clearFileInput-js').hide();
    sessionStorage.removeItem('complains');
    sessionStorage.removeItem('order' + (e.currentTarget).dataset.id);
    const popup = $(e.currentTarget).closest('.popupDialog__complain');
    popup.find('.complain-form-view-js').addClass('hidden');
    popup.find('.complain-success-view-js').removeClass('hidden');
    popup.find('.popupDialog__wrapper').scrollTop(0);
}
g) W sekcji rejestracji zdarzeń profilu klienta (tam, gdzie znajdują się m.in. mainSection.on('change', '.radioComplaint-js, .radioReturn-js', ...)) tuż za istniejącym handlerem zmiany typu formularza dopisz nowy handler:
mainSection.on('change', '.refundMethod-js', function (e) {
    customerProfile.changeRefundMethod(e);
});
h) Znajdź globalny handler obsługujący keydown z selektorem zaczynającym się od .radioReturn-js label, .radioComplaint-js label, ... i usuń z niego dwa pierwsze selektory (po zmianie zaczyna się od .showHideSection-js):
// PRZED
$('body').on('keydown', '.radioReturn-js label, .radioComplaint-js label, .showHideSection-js, .checkBoxes__container label, .customerPagination__form-js, .discountsDetails-js, .customer-focus, .customer__menuActivate-js', function(e) { ... });

// PO
$('body').on('keydown', '.showHideSection-js, .checkBoxes__container label, .customerPagination__form-js, .discountsDetails-js, .customer-focus, .customer__menuActivate-js', function(e) { ... });
i) W obiekcie app w pliku js/layout1.js obsłuż przekierowanie po zalogowaniu z parametrem #login-redirect= (używanym przez stronę szybkich zwrotów). W bloku rejestracji/logowania, w miejscu gdzie obsługiwany jest hash #back-to-cart, tuż po nim dodaj:
if (globalThis.location.hash.startsWith('#login-redirect=')) {
    url = globalThis.location.hash.slice('#login-redirect='.length);
}
Następnie w handlerze sukcesu logowania, gdzie znajduje się sprawdzenie window.location.hash.includes('#back-to-cart') wraz z przekierowaniem, tuż za nim dodaj analogiczny blok przekierowujący w przypadku #login-redirect=:
if (globalThis.location.hash.startsWith('#login-redirect=')) {
    globalThis.location.assign(globalThis.location.hash.slice('#login-redirect='.length));
    return;
}

5. Modyfikacje plików SCSS profilu klienta

Poniższe style należy dodać do plików scss/static-elements/customer-profile/customer-profile-g.scss (style ogólne), customer-profile-d.scss (desktop) i customer-profile-m.scss (mobile). Po zmianach pamiętaj o kompilacji SCSS – nie edytuj ręcznie wynikowych plików CSS.

Plik customer-profile-g.scss

a) Wewnątrz selektora opakowującego (tam, gdzie znajdują się istniejące reguły .orderContent__complainBtn) dodaj nowe reguły dla banera informacyjnego oraz kontenera grupującego przyciski reklamacji/zwrotu:
.orderContent__returnInfo {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 16px 0 24px;
    padding: 12px 16px;
    background-color: color-mix(in srgb, #{$linkFontColor} 4%, transparent);
    border: 1px solid color-mix(in srgb, #{$linkFontColor} 20%, transparent);
    border-radius: 4px;
    font-size: 13px;
    line-height: 1.4;
    color: $primaryFontColor;

    &__icon {
        flex-shrink: 0;
        fill: $linkFontColor;
    }
}

.orderContent__complainBtns {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin: 16px 0 4px;
}
b) Następnie zastąp istniejące style .orderContent__complainBtn nowym wyglądem przycisku (z tłem, obramowaniem i hoverem):
.orderContent__complainBtn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 16px 0 4px;
    padding: 6px 12px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 4px;
    color: $linkFontColor;
    fill: $linkFontColor;
    font-size: 13px;
    font-weight: 500;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 180ms, border-color 180ms;

    .orderContent__complainBtns & {
        margin: 0;
    }

    svg {
        margin: 0;
        flex-shrink: 0;
    }

    &:hover,
    &:focus-visible {
        background-color: color-mix(in srgb, #{$linkFontColor} 6%, transparent);
        border-color: color-mix(in srgb, #{$linkFontColor} 25%, transparent);
        outline: none;
    }
}
c) Dodaj style etykiety sekcji oraz kontenera sposobu zwrotu w popupie reklamacji:
.complain__sectionLabel {
    display: block;
    margin-bottom: 8px;
    font-size: 14px;
    font-weight: 500;
    color: $primaryFontColor;
}

.refundMethodWrapper-js {
    margin-bottom: 18px;
}
d) Dodaj kompletne style ekranu sukcesu zwrotu (m.in. ikona, tytuł, lista kolejnych kroków, sekcja z e-mailem i przyciskiem zamknięcia):
.complain__successView {
    text-align: center;
    padding: 16px 0 0;
}

.complain__successIcon {
    display: flex;
    justify-content: center;
    margin: 8px 0 20px;

    .svgIcon {
        width: 64px;
        height: 64px;
        fill: #2d8c4a;
    }
}

.complain__successTitle {
    font-size: 20px;
    font-weight: 600;
    line-height: 1.3;
    margin: 0 0 12px;
    color: $primaryFontColor;
}

.complain__successDescription {
    font-size: 14px;
    line-height: 1.5;
    color: $primaryFontColor;
    margin: 0 0 20px;
}

.complain__successInfoBox {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 14px;
    margin: 0 0 24px;
    border: 1px solid #cfdcef;
    background-color: #f0f5fc;
    border-radius: 6px;
    text-align: left;

    .svgIcon {
        flex-shrink: 0;
        margin-top: 2px;
        fill: #3a6ea5;
    }

    span {
        font-size: 13px;
        line-height: 1.5;
        color: $primaryFontColor;
    }

    strong {
        display: block;
        font-weight: 600;
        margin-top: 2px;
        word-break: break-all;
    }
}

.complain__successStepsTitle {
    font-size: 15px;
    font-weight: 600;
    margin: 0 0 12px;
    text-align: left;
    color: $primaryFontColor;
}

.complain__successSteps {
    margin: 0 0 24px;
    padding-left: 22px;
    text-align: left;

    li {
        font-size: 14px;
        line-height: 1.6;
        margin-bottom: 6px;
        color: $primaryFontColor;
    }
}

.complain__successActions {
    display: flex;
    justify-content: flex-end;
    padding-top: 16px;
    padding-bottom: 30px;
    margin-top: 8px;
    border-top: 1px solid $borderColor;

    .primary-action-button {
        min-width: 140px;
        margin: 0;
    }

    @media screen and (max-width: 599px) {
        .primary-action-button {
            width: 100%;
            min-width: 0;
        }
    }
}
e) Zaktualizuj style załączników – znajdź istniejące reguły .form__clear-attachement-input oraz reguły z position: absolute; top: 11px; i zastąp je nowymi (które ustawiają załączniki w układzie statycznym z poprawnym overflowem i przyciskiem usuwania):
.form__attachement-input-container-attachments__text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.form__attachement-input-container--hidden,
.form__attachement-input-container-attachments.form__attachement-input-container--hidden {
    display: none;
}

.form__clear-attachement-input {
    position: static;
    background: transparent;
    border: none;
    padding: 2px 4px;
    margin: 0 0 0 4px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;

    svg {
        fill: $linkFontColor;
        transition: opacity 200ms;
    }

    &:hover svg {
        opacity: 0.7;
    }
}

Plik customer-profile-d.scss

Wewnątrz wrappera @media screen and (min-width: 769px) zamień istniejące style przycisku reklamacji:
.customer .orderContent__complainBtn {
    position: absolute;
    bottom: 8px;
}
na poniższy fragment (dodaje pozycjonowanie kontenera grupującego przyciski oraz osobny selektor dla pojedynczych przycisków w wierszu produktu):
.customer .orderContent__complainBtns {
    position: absolute;
    bottom: 8px;
    right: 0;
    margin: 0;
}

.customer .orderContent__productDetails > .orderContent__complainBtn {
    position: absolute;
    bottom: 8px;
    right: 0;
    margin: 0;
}

Plik customer-profile-m.scss

W obrębie selektora .customer zamień istniejący media-query @media screen and (max-width: 359px) wraz z jego wnętrzem na rozszerzoną wersję (układająca przyciski reklamacji/zwrotu pionowo na szerokościach do 450px):
@media screen and (max-width: 450px) {
    .customer__orderContent .orderContent__productsRow {
        max-height: none;
    }

    .customer__orderContent .orderContent__productDetails {
        display: flex;
        flex-direction: column;
        align-items: stretch;
    }

    .customer__orderContent .orderContent__complainBtns {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 8px;
        width: 100%;
        margin: 12px 0 4px;
        padding-top: 12px;
        border-top: 1px solid $borderColor;
    }

    .customer__orderContent .orderContent__complainBtn {
        display: flex;
        width: 100%;
        justify-content: center;
        padding: 10px 12px;
        margin: 12px 0 4px;
        border-color: color-mix(in srgb, #{$linkFontColor} 25%, transparent);
    }

    .customer__orderContent .orderContent__complainBtns .orderContent__complainBtn {
        margin: 0;
    }
}

6. Szablon One Page Shop

Szablon One Page Shop ma praktycznie identyczną strukturę plików jak Topaz. Wszystkie powyższe modyfikacje (tłumaczenia, nowa strona zwrotów, edycje plików partials/common/complaint-popup.html oraz partials/customer/order-content.html, zmiany w js/layout1.js oraz w plikach SCSS profilu klienta i strony zwrotów) wykonaj 1:1 w plikach szablonu OPS pod tymi samymi ścieżkami. Treść kodu jest taka sama, ścieżki plików są takie same – instrukcja dla Topaza w pełni stosuje się również do One Page Shopa. Po wprowadzeniu wszystkich powyższych zmian w szablonie Topaz (oraz One Page Shop) pamiętaj o kompilacji oraz minifikacji plików js i scss, zgodnie z artykułem dostępnym pod linkiem https://pomoc.comarchesklep.pl/artykul/kompilacja-i-minifikacja-plikow/.
Wskazówka
Potrzebujesz pomocy lub masz pytania? Skontaktuj się z nami poprzez portal asysta.comarch.pl.

Posiadam gotowy szablon Comarch. Jak mogę go dostosować do kryteriów WCAG 2.1/2.2?

Wstęp

Z dniem 28 czerwca 2025 roku w życie wejdą przepisy związane z implementacją ustawy z dnia 26 kwietnia 2024 r. o zapewnianiu spełniania wymagań dostępności niektórych produktów i usług. Wdraża ona do polskiego prawa tzw. Europejski Akt o Dostępności (EAA) – unijną dyrektywę 2019/882. Celem ustawy jest zapewnienie, że kluczowe produkty i usługi będą dostępne dla wszystkich użytkowników, w tym osób z niepełnosprawnościami. Przedsiębiorcy mają czas do 28 czerwca 2025 roku, aby dostosować swoje produkty i usługi do nowych wymogów.
Wskazówka
Chcesz dowiedzieć się więcej o tych przepisach? Sprawdź artykuł w naszym Centrum Pomocy: Europejski Akt o Dostępności (EAA) i zapoznaj się ze szczegółami
W niniejszym artykule wskazujemy, jakie czynności należy wykonać, jeśli posiadasz jeden ze standardowych szablonów Comarch, czyli: Rubin, Szafir, Topaz, One Page Shop lub Dla Gastronomii.   

Sprawdź, jaki szablon posiadasz

Nie wiesz, który szablon posiadasz? Możesz to sprawdzić w panelu administracyjnym Comarch e-Sklep. Aby to zrobić, z poziomu panelu administracyjnego przejdź do zakładki Wygląd sklepu/ Ustawienia a następnie, pod przyciskiem "Więcej" wybierz Edytuj ustawienia zaawansowane. W obszarze, który został wyświetlony, pojawi się kilka zakładek, a wśród nich zakładka "Szablon". Wybierz ją, po czym sprawdź szablon:   Jeśli Twój szablon to Rubin, Szafir, Topaz, One Page Shop lub Dla Gastronomii, to możesz przejść do kolejnej części artykułu. Jeśli posiadasz własny szablon z indywidualnymi modyfikacjami, to przejdź do artykułu: Posiadam własny szablon, jak mogę go dostosować do kryteriów WCAG 2.1/2.2?  Jeśli posiadasz szablon Bursztyn, Agat lub Opal, to przejdź do artykułu: Posiadam szablon Bursztyn, Opal lub Agat, jak mogę go dostosować do kryteriów WCAG 2.1/2.2?  

Co zrobić jako właściciel e-Sklepu lub Partner, jeśli używam gotowych szablonów Comarch?

Jako właściciel e-Sklepu lub Partner Comarch zadbaj, aby zadbać o dostosowanie swojej witryny do obowiązujących przepisów. Nowe wymogi to wspólna odpowiedzialność:
  • Comarch e-Sklep – zajmiemy się kwestiami technicznymi w przypadku Gotowych Szablonów Comarch, do których należą m.in. zmiany w kodzie,
  • Właściciel, administrator lub Partner sklepu – musisz zadbać o treści i elementy, które dodajesz samodzielnie. Chodzi tu głównie opis produktów, zdjęcia i grafiki czy identyfikację wizualną. 
 

Jak zacząć?

Jeśli korzystasz z gotowych szablonów, takich jak Rubin, Szafir, Topaz, One Page Shop lub Dla Gastronomii, nie musisz przejmować się samodzielnym edytowaniem ich kodu. Wszystkie usprawnienia zostaną udostępnione wraz z aktualizacją, która pojawi się w czerwcu 2025 roku.

Aktualizacja szablonu

Wskazówka
Aktualizację szablonu wykonaj wtedy, kiedy będzie ona dostępna. Realizacja wersji 2025.4 przewidywana jest przed 28 czerwca 2025 roku, poinformujemy o niej w aktualnościach. Będzie ona zawierała zmiany związane z omawianymi tutaj przepisami.

Jak zaktualizować szablon?

Aby zaktualizować szablon i przejść na Topaz, One Page Shop, Dla Gastronomii, Rubin lub Szafir, należy skorzystać z aktualnej wersji Kreatora Wyglądu. Pamiętaj, że szablony Rubin i Szafir przeznaczone są tylko dla sklepów Enterprise i B2B. Odnośnik znajduje się również w panelu administracyjnym e-Sklepu w sekcji Wygląd sklepu > Kreator wyglądu.  Istnieją trzy możliwości aktualizacji tych szablonów:
  • Wygenerowanie zupełnie nowego szablonu w Kreatorze Wyglądu oraz wgranie go do e-Sklepu,
  • Wybór i edycja jednego z gotowych układów i jego modyfikacja,
  • Import posiadanego szablonu do Kreatora Wyglądu oraz ponowne wygenerowanie go w najnowszej wersji.
Wygenerowany z Kreatora Wyglądu szablon należy wgrać do e-Sklepu. W panelu administracyjnym e-Sklepu, w sekcji Wygląd sklepu znajduje się bezpośredni odnośnik do importu szablonu z Kreatora wyglądu. Szczegółowa instrukcja dostępna jest w artykule Jak wyeksportować i zaimportować swój szablon w e-Sklepie?
Pamiętaj o zapisaniu szablonu oraz opublikowaniu go w e-Sklepie. Zmiany wprowadzone w ustawieniach zostaną zsynchronizowane do sklepu po 10 minutach.
Wskazówka
Informacje na temat aktualizacji znajdują się w Centrum Pomocy: Jak zaktualizować szablon do najnowszej wersji?  
Więcej informacji na temat Kreatora Wyglądu B2C oraz B2B znajduje się w Centrum Pomocy:

Odpowiedni kontrast kolorów w e-Sklepie – wymóg WCAG na poziomie AA

Jednym z głównych wymogów WCAG jest stosowanie odpowiednich kontrastów na stronach internetowych. Jeśli w wybranym szablonie graficznym wykorzystujesz któryś ze standardowych motywów kolorystycznych dostępnych w kreatorach, to zostaną one dostosowane do wymagań wynikających z przepisów. Jeśli natomiast masz przygotowany własny motyw kolorystyczny lub chcesz zmienić część kolorów zastosowanych w szablonie, to pamiętaj, że muszą one posiadać odpowiednie kontrasty. Wszelkich zmian kolorystycznych możesz dokonać w Kreatorze Wyglądu.  Odpowiedni kontrast między tekstem a tłem jest kluczowy dla osób z dysfunkcjami wzroku. WCAG 2.1 określa minimalny współczynnik kontrastu (4.5:1 dla tekstu zwykłego i 3:1 dla tekstu dużego). Ważne jest również unikanie łączenia kolorów, które mogą być trudne do rozróżnienia, takich jak czerwony i zielony. Kontrasty po modyfikacji kolorów możesz sprawdzić np. narzędziem WAVE. WAVE to popularny, dostępny dla wszystkich zestaw narzędzi do oceny dostępności stron internetowych. Rozszerzenia WAVE dla Chrome, Firefox i Edge, umożliwiają testowanie bezpośrednio w tych przeglądarkach, bez przesyłania danych na serwer WAVE. WAVE znajdziesz pod linkiem: WAVE Web Accessibility Evaluation Tools.  

Jak sprawdzić kontrast?

Przejdź na stronę swojego e-Sklepu. Włącz wtyczkę WAVE. Po prawej stronie ekranu wyświetli się panel boczny, na pierwszej zakładce widać podsumowanie całej strony: Już na tym etapie możesz przejść do szczegółów, klikając "View details". Możesz w tym miejscu przejść także do zakładki "Contrast".   Czerwone kwadraty oznaczają obszar do poprawy. Przejdź przez stronę, aby zobaczyć szczegóły każdego z nich. Po kliknięciu na jeden z kwadratów pokaże się komunikat dotyczący kontrastu: W panelu bocznym pojawi się dokładna informacja na temat koloru. W tym miejscu, korzystając z suwaków możesz od razu dostosować kolor tak, aby był odpowiedni i sprawdzić, czy spełnia wymagania WCAG.  

Gdzie dostosować kolory?

Kolory w szablonie możesz zmienić korzystając z Kreatora Wyglądu. Po imporcie szablonu, edycji lub stworzeniu nowego projektu, przejdź do zakładki "Style" i edytuj motyw kolorystyczny:   Następnie możesz zmieniać swobodnie kolor na wybranych elementach:   Zmian możesz dokonać także z poziomu panelu administracyjnego, przechodząc do zakładki Wygląd Sklepu > Ustawienia.

Pozostałe zmiany

Poza zmianami w szablonie graficznym sklepu należy uzupełnić szereg danych. Znaczącą część tych elementów możesz wykonać już teraz, nie czekając na aktualizację Comarch e-Sklep. Poniżej znajduje się lista zmian, które należy wdrożyć w swoim e-Sklepie.

Teksty alternatywne ("Alt", alty) w Comarch e-Sklep

Twój szablon musi obsługiwać parametr "alt" w obrazkach. Jeśli wykorzystasz aktualny szablon standardowy od Comarch to obsługę zapewnia Comarch e-Sklep, jeśli zdecydowałeś się na indywidualny szablon lub samodzielną aktualizację starszej wersji to upewnij się, że w szablonie są obsługiwane parametry "alt" we wskazanych elementach. Teksty alternatywne („alt”) to krótkie opisy obrazków, które pozwalają osobom korzystającym z czytników ekranu zrozumieć, co znajduje się na zdjęciu. Atrybut „alt” jest szczególnie ważny dla zdjęć produktów, ponieważ umożliwia przekazanie najważniejszych informacji o produktach.  Dlaczego tekst alternatywny jest taki ważny? 
  • Pomaga osobom korzystającym z czytników ekranu, które odczytują tekst alternatywny na głos,
  • Poprawia dostępność stron internetowych, czyniąc je bardziej przyjaznymi dla wszystkich użytkowników,
  • Wpływa na pozycjonowanie w wyszukiwarkach, ponieważ dobrze opisane obrazy są lepiej interpretowane przez algorytmy Google.   
Dobrze sformułowany opis powinien być zwięzły, ale wystarczająco informacyjny. Poniżej prezentujemy przykłady dobrego i złego zastosowania opisów alternatywnych:
Przyklad
Poprawne :
  • Czerwona sukienka maxi z rozcięciem, modelka na tle miejskiego pejzażu.
  • Białe sneakersy z grubą podeszwą, ustawione na drewnianej podłodze.
  • Nowoczesna sofa w kolorze szarym, z drewnianymi nogami, ustawiona w minimalistycznym salonie.
  • Słuchawki bezprzewodowe z aktywną redukcją szumów, na białym tle.
Niepoprawne:
  • Sukienka.
  • Buty sportowe.
  • Fajna kanapa.
  • Najlepszy sprzęt w dobrej cenie!

Gdzie należy uzupełnić teksty alternatywne (alt)?

1. Dla zdjęć towarów w systemach Comarch ERP

Korzystam z Comarch ERP Optima
Po uruchomieniu Comarch ERP Optima przejdź na pozycję cennika, a następnie edytuj wybrany towar. Następnie przejdź na zakładkę "Atrybuty", a następnie do sekcji "Zdjęcia i załączniki". W tym miejscu zobaczysz kolumnę "Atrybut Alt".
Po dwukrotnym kliknięciu możliwe jest uzupełnienie opisu alternatywnego: Po dokonaniu zmian należy je zapisać. Po wykonaniu wszystkich modyfikacji należy wykonać synchronizację.

Korzystam z Comarch ERP XL

Po uruchomieniu ERP XL przejdź do Sprzedaż > Towary , a następnie na zakładkę "Załączniki". Opis alternatywny dla towaru stanowi Kod:    
Korzystam z Comarch ERP XT
Przejdź na kartę produktu, a następnie do zakładki "Zdjęcia". Wśród pól do uzupełnienia znajdziesz "Opis alternatywny (Alt)".   W tym miejscu wpisz odpowiednią treść, a następnie zapisz wprowadzone zmiany.  

2. Dla zdjęć w bannerach – w panelu administracyjnym Comarch e-Sklep

Pamiętaj, alby alty (opisy alternatywne) były uzupełnione także w przypadku bannerów. Aby to zrobić, przejdź z poziomu panelu administracyjnego do Wygląd sklepu > Ustawienia > Bannery  do edycji swoich bannerów. Klikając na odpowiedni kafelek pojawią się opcje z uzupełnieniem Alt:

3. Dla zdjęć stosowanych na stronach z treściami formalnymi – w panelu administracyjnym Comarch e-Sklep

Obrazki możesz dodawać także do treści, które udostępniasz na specjalnych stronach, takich jak np. Regulamin sklepu, Polityka prywatności, Wysyłka itp. W obszarze do edycji, który jest dostępny z poziomu panelu administracyjnego w sekcji Ustawienia > Treści formalne edytuj interesującą Cię treść, a dodając obrazek uzupełnij alt:    

4. Dla zdjęć wprowadzonych w opisie towaru i opisie kategorii

Dodając opisy produktów i kategorii, warto upewnić się, że linkowane zdjęcia zawierają poprawnie uzupełniony atrybut "alt". To kluczowe dla osób korzystających z czytników ekranu. Dbałość o ten detal poprawia dostępność strony i zwiększa jej widoczność w sieci. Opis towaru i kategorii możesz dodać w systemach Comarch ERP.  Opis kategorii możesz ustawić również z poziomu panelu administracyjnego, bez konieczności korzystania z systemu ERP. Szczegółowe informacje znajdują się w artykule: Jak edytować kategorię w Comarch e-Sklep? 

5. Dla zdjęć w Blogu

Obrazki, które dodawane są dla wpisów blogowych od wersji 2025.4 będą posiadały atrybuty ALT oraz Title. Ich uzupełnienie będzie możliwe przy przejściu z poziomu panelu administracyjnego Comarch e-Sklep do sekcji Marketing > Blog przy dodawaniu wpisu:

6. Dla zdjęć w plikach użytkownika w sekcji "Twoje pliki"

Pliki użytkownika w e-Sklepie to dedykowana przestrzeń do przechowywania własnych materiałów, które mogą zostać wykorzystane w sklepie internetowym. Pliki można przesyłać za pośrednictwem panelu administracyjnego, w sekcji Ustawienia > Twoje pliki. Maksymalny rozmiar pojedynczego pliku: 3 MB. Pliki, które dodawane są we wspomnianym obszarze, od wersji 2025.4 będą posiadały atrybuty ALT oraz Title. Ich uzupełnienie będzie możliwe przy przejściu z poziomu panelu administracyjnego do sekcji Ustawienia > Twoje pliki przy edycji pliku lub jego dodaniu.
Wskazówka
Jeśli posiadasz sklep wielojęzyczny, to we wszystkich tych wymienionych powyżej obszarach, znajdują się również obrazki dla danego języka. Pamiętaj, alby atrybut ALT zdefiniować dla każdego z nich!
 

Atrybut title - obowiązkowy czy nie?

Atrybut title jest przydatny do przekazywania dodatkowych informacji o elementach HTML, widocznych jako podpowiedź po najechaniu kursorem. Może być używany w ikonach bez podpisu, formularzach czy linkach, aby dostarczyć kontekst. Nie jest jednak obowiązkowy według WCAG, ponieważ czytniki ekranu często go ignorują, a osoby nawigujące klawiaturą mogą nie mieć do niego dostępu.  

Zalecenia dla udostępnianych treści - ogranicz migające elementy

Jako właściciel sklepu musisz sam zadbać o to, jakie treści umieszczasz na swojej stronie. Migające elementy, takie jak animacje czy reklamy, mogą wywoływać problemy u osób z padaczką fotogenną. Według kryteriów WCAG 2.1 zalecane jest ograniczenie migających treści do maksymalnie trzech błysków na sekundę lub ich całkowite usunięcie. Jako właściciel sklepu musisz dbać o statyczne elementy lub spokojne animacje. Również treści zawarte w różnego typu prospektach, gazetkach czy folderach informacyjnych w formie dokumentów powinny być zgodne z wytycznymi WCAG.

1.Obrazki i bannery

W szablonach graficznych takie elementy mogą pojawić się na przykład w bannerach i elementach tekstowych ze zdjęciem. Upewnij się, że grafiki tam zamieszczone są odpowiednie, czyli bez intensywnych animacji i nieodpowiednich kolorów. Szczególną uwagę zwróć na pliki w formacie GIF. Sprawdź, w jaki sposób możesz skonfigurować bannery oraz elementy tekstowe ze zdjęciem.  

2.Materiały audio i viedo

Aby sklep internetowy był w pełni dostępny zgodnie z WCAG, właściciele muszą zadbać o dodanie audiodeskrypcji i transkrypcji do materiałów multimedialnych (filmy, nagrania dźwiękowe). Choć oba rozwiązania służą poprawie dostępności, mają różne funkcje.
  • Audiodeskrypcja to dodatkowy opis dźwiękowy, który przedstawia istotne elementy wizualne nagrania osobom niewidzącym,
  • Transkrypcja to zapis tekstowy całej treści audio, umożliwiający odbiór treści osobom niesłyszącym, może to być w formie napisów dla audiodeskrypcji.
Dodanie tych elementów leży po stronie właścicieli sklepów. Do filmów, które udostępniasz, dodaj zatem widoczne napisy, a także dobrej jakości opis dźwiękowy. Ich brak może wykluczyć część użytkowników i wpłynąć na komfort korzystania ze strony. Dobre praktyki dostępności to nie tylko wymóg, ale też inwestycja w lepsze doświadczenie klientów.

Dostosuj komunikację mailową - aktualizacja lub zmiana treści e-mail

Dostosowanie treści e-mail zgodnie z wytycznymi WCAG to kluczowy krok w budowaniu dostępnej i klarownej komunikacji. W tej części artykułu przedstawiamy rozwiązania zarówno dla domyślnych wiadomości, jak i tych modyfikowanych, aby zapewnić ich lepszą czytelność i dostępność dla wszystkich odbiorców.

1.Treści mailowe są domyślne, nie zostały sformatowane

Jeśli treści nie zostały przez Ciebie zmienione i stanowią domyślne treści, które są dostępne w Comarch e-Sklep, to wystarczy, że zaktualizujesz je. Aby to zrobić, należy przejść w panelu administracyjnym do zakładki Ustawienia > Treści formalne, a następnie wybrać „Wysyłka e-mail i SMS”. Zakładka ta zawiera treści wiadomości wysyłane do klientów po wykonaniu określonych akcji, np. po zakupie czy rejestracji. W Comarch e-Sklep istnieje możliwość przywrócenia standardowej treści pojedynczej wiadomości e-mail lub wszystkich jednocześnie. Opcja ta stanowi również aktualizację treści e-mail. "Przywróć domyślną treść" dostępna jest w panelu administracyjnym e-Sklepu w menu Ustawienia/ Treści formalne/ Wysyłka e-mail i SMS na szczegółach każdej wiadomości, po kliknięciu w przycisk Więcej:  

2.Treści mailowe są modyfikowane, zostały przeze mnie zmienione

Jeśli posiadasz własne, dostosowane do Twojej komunikacji marketingowej treści e-mail, to sprawdź, czy są one odpowiednio napisane i sformatowane. Zastosuj się do poniższych wskazówek. W jaki sposób poprawnie napisać i sformatować treści?
  • Struktura Stosuj nagłówki (<h1>, <h2> itd.) dla przejrzystości. Używaj krótkich akapitów i list punktowanych.
  • Tekst i formatowanie Zapewnij wysoki kontrast między tekstem a tłem. Wybieraj czytelne czcionki (sans-serif, min. 12-14 px). Nie używaj wyłącznie koloru do przekazywania informacji.
  • Obrazy i multimedia Dodawaj tekst alternatywny (alt text) do obrazów. Unikaj tekstu osadzonego w grafikach, jeśli można go przesłać jako tekst.
  • Linki i przyciski Stosuj opisowe teksty linków zamiast „Kliknij tutaj”. Upewnij się, że są łatwe do kliknięcia na ekranach dotykowych.
  • Język i czytelność Używaj prostego i zrozumiałego języka. Unikaj skrótów i branżowego żargonu, jeśli odbiorca może ich nie znać.
  • Testowanie Sprawdź wiadomość na różnych urządzeniach i czytnikach ekranu. Zweryfikuj zgodność ze standardami WCAG.
Szczegółowe informacje na temat edycji treści e-mail znajdują się a artykule: E-mail i SMS  

3.Załączniki (m.in. instrukcje, katalogi)

Należy zadbać o to, aby wszystkie udostępniane w sklepie załączniki, takie jak instrukcje czy katalogi, były zgodne z wytycznymi WCAG, zapewniając tym samym ich pełną dostępność dla wszystkich użytkowników.  

Dodatkowe narzędzia pomocne przy wdrażaniu WCAG

Przystosowanie e-Sklepu do wymogów nie musi wiązać się z dużymi wydatkami na zmiany w kodzie. Kluczowe aspekty dostępności można wdrożyć samodzielnie, wykorzystując opcje dostępne w systemach Comarch ERP, a także Kreatorze Wyglądu czy Panelu Administracyjnym. Warto pamiętać, że poprawa dostępności to nie tylko obowiązek wynikający z przepisów, ale także realna szansa na zwiększenie grona klientów oraz podniesienie komfortu ich zakupów. Istnieje kilka ogólnodostępnych narzędzi, które pomogą Ci dostosować sklep do wymogów. Obszerna lista narzędzi do oceny dostępności stron internetowych, zgodnych z WCAG znajduje się na stronie: Web Accessibility Evaluation Tools List .  

Podsumowanie

Dostępność cyfrowa to nie jednorazowe przedsięwzięcie, lecz ciągły rozwój i udoskonalanie. Regularne sprawdzanie funkcjonalności, optymalizacja elementów wizualnych i dostosowywanie sposobów interakcji pozwalają na stałe podnoszenie jakości doświadczeń użytkowników. Dążenie do pełnej zgodności ze standardami WCAG 2.1/2.2 oraz wymogami Europejskiego Aktu o Dostępności (EAA) nie tylko ułatwia nawigację wszystkim odwiedzającym, ale także buduje pozytywny wizerunek i wzmacnia pozycję na rynku. Wdrażanie kolejnych usprawnień to inwestycja w przyszłość, która przynosi korzyści zarówno właścicielom, jak i ich klientom.

Kreator Wyglądu One Page Shop (B2C)

Wstęp

Jednym z kluczowych elementów, który przyczynia się do sukcesu w branży e-commerce jest oprawa wizualna sklepu. W dużym stopniu to właśnie ona wpływa na całościowe wrażenia użytkowników i ich proces zakupowy. Dzięki narzędziu - Kreator Wyglądu Comarch e-Sklep, właściciele sklepów mają możliwość stworzyć swój własny, niepowtarzalny szablon, który będzie dostosowany do ich preferencji oraz do potrzeb użytkowników.

Kreator jest dostępny pod linkiem: Kreator szablonu Comarch e-Sklep. Odnośnik znajduje się w panelu administracyjnym e-Sklepu Wygląd sklepu > Kreator wyglądu.

Zastosowanie

Kreator jest intuicyjnym narzędziem służącym do tworzenia szablonów. Jego obsługa nie wymaga umiejętności technicznych ani programowania. Wszystko odbywa się na poziomie strony internetowej, gdzie z gotowych elementów za pomocą metody "przeciągnij i upuść" możesz zaprojektować wygląd swojego sklepu. Dodatkowo, stworzony szablon jest dostosowany do wyświetlania na różnych urządzeniach (RWD).

W ramach kreatora zaprojektujesz wszystkie niezbędne obszary sklepu. Po utworzeniu szkieletu e-Sklepu, przychodzi czas na modyfikację oprawy wizualnej szablonu. Możesz dowolnie zmieniać kolory elementów znajdujących się na stronie, ikony, a także czcionkę.

Kto może używać tej opcji?

Aby móc używać tego narzędzia należy posiadać:

  • Comarch e-Sklep obsługujący procesy B2C,
  • szerokość ekranu powyżej 1280 px, a zalecana to 1920 px,
  • oraz jedną z przeglądarek internetowych w aktualnej wersji.

Wskazówka
Kreator wyglądu Comarch e-Sklep dostępny jedynie w wersji przeglądarkowej.

Tworzymy!

Jak zaprojektować układ szablonu?

Aby rozpocząć tworzenie szablonu należy przejść na stronę Kreatora Wyglądu. Wyświetlony zostanie powitalny komunikat. Na początku należy określić, dla jakiego modelu sprzedaży projektujesz szablon dla swojego e-Sklepu. Do wyboru masz sprzedaż detaliczną lub hurtową. Sprzedaż detaliczna przeznaczona jest dla użytkowników, którzy chcą sprzedawać swoje produkty głównie klientom indywidualnym. Wybierz odpowiedni model, a następnie naciśnij przycisk Rozpocznij pracę. Po jego kliknięciu będzie można stworzyć nowy szablon lub edytować jeden z kilku gotowych.

W sytuacji gdy wcześniej tworzony był już projekt, widoczny będzie przycisk umożliwiający dokończenie szablonu lub rozpoczęcie nowego projektu. Opcja Nowy szablon umożliwia zbudowanie od początku nowego szablonu Topazu według Twojego indywidualnego pomysłu.
Wskazówka
Szablon One Page Shop - Demo jest gotowym szablonem, który możesz zainstalować bezpośrednio z obszaru Wygląd sklepu > Gotowe szablony Comarch.
W trzech krótkich krokach zapoznasz się z podstawowymi funkcjami kreatora. Następnie możesz już przystąpić do dalszych modyfikacji szablonu lub od razu wygenerować przygotowaną wersję szablonu One Page Shop.

Od czego zacząć?

Wybierz wersję językową Kreatora i rozpocznij pracę nad swoim szablonem. Wersje do wyboru to: język polski, angielski, niemiecki oraz francuski. Język wybieramy klikając strzałkę obok flagi i nazwy języka w lewym dolnym rogu. Przy podglądzie prac na pełnym ekranie, wybrany język zostaje zachowany i szablon będzie wyświetlał się w wybranej wersji językowej.

Gdy już wybierzesz wersję językową dla swojego Kreatora warto zacząć od nazwania swojego przyszłego szablonu. Można to zrobić klikając Zmień i wpisując nazwę w lewym górnym rogu, zastępując nazwę "One Page Shop (2023.1)". Nazwa ta będzie widoczna po zaimportowaniu szablonu do panelu administracyjnego oraz po wyeksportowaniu szablonu do pliku XML wraz z datą i godziną jego wygenerowania.

Krok 1 - Sekcja Szablon

W tej sekcji należy zaprojektować wygląd strony głównej naszego Comarch e-Sklepu. Strona główna może składać się z następujących elementów:

  • Nagłówek,
  • Baner,
  • Widget,
  • Siatka towarów
  • Newsletter,
  • Sekcja z filmami
  • Blog,
  • Element tekstowy,
  • Banner informacyjny,
  • Lookbook
  • Stopka.

Po rozwinięciu każdej z sekcji ukażą się dostępne elementy:

Metodą "Przeciągnij i upuść" przenosimy wybrane elementy na obszar po prawej stronie:

Postępuj analogicznie z pozostałymi elementami.

Nagłówek

Sekcja „Nagłówek” prezentuje dwa widoki.

Banner

Sekcja "Banner" pozwala wybrać jedną z sześciu możliwości prezentacji banerów. Informacje dotyczące rekomendowanych rozmiarów obrazków w bannerach opisaliśmy w tym artykule. Jest on widoczna tylko dla strony głównej i listy towarowej.

Banner promocyjny

Sekcja "Banner promocyjny" dodać banner prezentujący promocje.

Widget

Sekcja "Widget" pozwala dodać jeden z dwóch dostępnych wariantów, które pozwolą zaprezentować następujące funkcje:
  • Widget-banner-1
    • Dodanie zdjęcia,
    • Dodanie tekstu nagłówka (tekst pionowy),
    • Dodanie tekstu przycisku (tooltip).
    • Dodanie linku do przycisku,
    • Dodanie tekstu..
  • Widget-banner-1
    • Dodanie zdjęcia,
    • Dodanie tekstu nagłówka (tekst pod zdjęciem),
    • Dodanie tekstu,
    • Dodanie linku do tekstu.

Siatka towarów

Na szczegółach wybranego obiektu (Siatka towarów) określamy jakie dokładnie towary zostaną zaprezentowane w sekcji „Nasze produkty".

Dodatkowo po najechaniu kursorem na tę sekcję, wybierając Opcje, możemy ustawić następujące opcje:
  • wybierz sposób wyświetlania produktów na liście,
  • prezentowanie drugiego zdjęcia towaru na kiście,
  • dodatkowe informacje na liście towarów,
  • graficzna prezentacja wariantów towaru,
  • po dodaniu do koszyka,
  • pozwalaj na udostępnianie towarów,,
  • pomijaj popup ze szczegółami przy kupowaniu towarów prostych.
 

Newsletter

Sekcja "Newsletter" pozwala dodać jeden z czterech dostępnych wariantów zapisu klientów do subskrypcji. Dwie sekcje pokazują się w formie wyskakującego okienka (pop-up), które prezentowane są wyłącznie na stronie głównej e-Sklepu (newsletter-3, newsletter-4). Wszystkie teksty dostępne w nowym newsletterze są edytowalne w ustawieniach szablonu w menu Wygląd sklepu > Ustawienia > Bannery > Newsletter banner. 

Sekcja z filmami

Sekcja z filmami prezentuje jeden widok. Film wprowadza się w ustawieniach szablonu w sekcji Strona główna > Ustawienia sekcji z filmami.

Blog

Sekcja "Blog" pozwala wybrać spośród dwóch dostępnych wariantów. Blog -1 prezentuje tylko zdjęcia, natomiast Blog-2 oraz Blog-3 zawiera również krótkie opisy wprowadzające do pozostałej treści wpisu.

Element tekstowy

Element tekstowy pozwala na zamieszczenie dłuższego opisu, który będzie wyświetlany na stronie głównej Comarch e-Sklep. W kreatorze wyglądu Comarch są do wyboru dwa warianty:
  • element tekstowy z samym tekstem,
  • element tekstowy z możliwością dodania zdjęcia.
Tekst wprowadza się edytując obiekt tekstowy w ustawieniach szablonu: Wygląd sklepu > Ustawienia > Edytuj ustawienia zaawansowane > Obiekty:
  • text-el-no-photo-mp-1 – element bez obrazka,
  • text-el-photo-mp-2 – element z obrazkiem.

Po wybraniu wszystkich niezbędnych sekcji nasza strona główna powinna być gotowa. Efekt naszej pracy możemy podejrzeć klikając Podgląd w prawym górnym rogu. Dostępny jest podgląd w wersji mobilnej i desktopowej.

Strona główna wymaga dwóch podstawowych elementów: nagłówka oraz stopki. Pozostałe elementy nie są obowiązkowe.

Banner informacyjny

Banner informacyjny pozwala na zaprezentowanie w przejrzysty sposób korzyści z zakupach w Twoim sklepie. Dotyczą one obszarów: dostawy, jakości i kontaktu z klientem. Banner możesz dodać tylko do strony głównej lub do wszystkich stron. Sekcja Odkryj Comarch e-Sklep różni się prezentacją oraz elementami między bannerami i zawiera:
  • info-banner-1 – element z ikonkami i podpisem
    • Szybka dostawa,
    • Gwarancja jakości,
    • Odbiór osobisty,
    • Reklamacje,
    • Zwroty towarów,
  • info-banner-3 – element z ikonkami i krótką informacją
    • Ekspresowa wysyłka,
    • Darmowa dostawa,
    • Obsługa klienta,
  • info-banner-3 – element z ikonkami i krótkim opisem
    • Ekspresowa dostawa,
    • Darmowa dostawa,
    • Strefa kontaktu.
  • info-banner- 4 – Poznaj produkt
    • Wyróżnij główny towar – zdjęcie główne,
    • Pozostałe towary – zdjęcia na zewnątrz,

Lookbook

Sekcja "Lookbook" prezentuje jeden widok, który pozwoli na promowanie wielu towarów w bardzo atrakcyjnej formie.

Koszyk

Sekcja "Koszyk" pozwala dodać jeden z trzech dostępnych wariantów, gdzie każdy z nich posiada inną ilość kroków.

Stopka

Sekcja "Stopka" zawiera jeden widok do wyboru. W każdym widoku widnieją strony statyczne, którymi można zarządzać w sekcji Wygląd Sklepu > Ustawienia > Nagłówek i Stopka. Dla każdej z sekcji wyświetla się jej utworzona w panelu nazwa. W stopce znajdują się także informacje na temat rodzaju prezentowanych cen w e-Sklepie (brutto czy netto) oraz komunikat @Comarch SA 2023. All rights reserved Powered by Comarch e-Sklep. Dodatkowo istnieje możliwość umieszczenia w stopce odnośników do mediów społecznościowych oraz ich ikony. W stopce trzeciej możemy dodać ikony naszych dostawców oraz form płatności wykorzystywanych w sklepie.

Następnie możemy przejść do modyfikacji wyglądu naszego szablonu. W tym celu należy przejść do zakładki Style.

Style

Jak zmienić kolory, czcionki oraz ikony?

Po dodaniu elementów strony możemy dodatkowo podejrzeć, jak będzie wyglądał nasz przyszły szablon. W tym celu należy przejść do zakładki Style.

Dodatkowo w zakładce Style możemy zmodyfikować wygląd naszego szablonu. Zmianie podlegają:

  • motyw kolorystyczny,
  • czcionka,
  • ikony,
  • styl okien i przycisków.

Motyw kolorystyczny

Aby zmienić kolor naszego szablonu należy przejść do sekcji Motyw kolorystyczny, gdzie do wyboru przygotowaliśmy 7 gotowych motywów.

Wskazówka
W aktualnej wersji Kreatora dodaliśmy nowy, ciemny motyw kolorystyczny.

Każdy z motywów możemy edytować według indywidualnych preferencji. Możemy zmodyfikować kolor poszczególnych elementów (m.in.: tło strony, tło nagłówka, nazwę towaru, czy nawet drugorzędny kolor tekstu w newsletterze). Zmiany należy zapisać klikając Zapisz. Jeśli wykonane zmiany nie są zadowalające, możemy przywrócić ustawienia domyśle dla danego motywu kolorystycznego, klikając przycisk Przywróć.

Możliwe jest również wprowadzenie szesnastkowego zapisu kolorów. Heksadecymalny zapis kolorów dla poszczególnych sekcji w szablonie dostępny jest podczas edycji wybranego motywu kolorystycznego.

Czcionki

W zależności od potrzeb istnieje możliwość wybrania czcionki. Dla naszych klientów udostępniliśmy jej 13 różnych typów. Pod nazwą każdej z nich znajduje się przykładowy wygląd w różnych formatach.

Ikony

Mamy do wyboru 3 różne warianty wyglądu ikon. Dodatkowo istnieje możliwość wyboru w jakiej postaci wyświetla się ikona koszyka (torba, wózek lub koszyk) oraz loader.

Wskazówka
Od teraz możesz zmienić rodzaj loadera, wybierając jedną z 5 propozycji widocznych powyżej.

Styl okien i przycisków

Ostatnim elementem, który możemy modyfikować z poziomu zakładki Style jest styl okien i przycisków. Mamy do wyboru 3 różne warianty zaokrągleń.

Generowanie i wgrywanie szablonu

Po zaprojektowaniu wyglądu szablonu możemy go wygenerować i pobrać na dysk korzystając z przycisku Generuj widocznego w prawym górnym rogu:

Obok przycisku Generuj dostępna jest również opcja Importuj szablon, umożliwiająca wgranie wcześniej zapisanego szablonu z dysku i ponowną jego edycję.

W przypadku prawidłowego wygenerowania szablonu wyświetlony zostanie komunikat informujący o tym fakcie i pobrany plik.

Pobrany szablon należy zaimportować w Comarch e-Sklep w zakładce Wygląd sklepu > Zaimportuj szablon z Kreatora Wyglądu.

W szablonie Topaz znajduje się informacja na temat godziny wygenerowania szablonu w Kreatorze. Taka informacja znajduje się w panelu administracyjnym w menu: Wygląd sklepu > Ustawienia > Więcej (trzy kropki), gdzie należy wybrać opcję Edytuj ustawienia zaawansowane, a potem ponownie Więcej > Edytuj HTML. Następnie z listy plików należy wybrać _layout.html. Informacje na temat modyfikacji, w tym godzina ostatniej modyfikacji, znajdują się nad oknem edycji pliku. Jeżeli plik nie był modyfikowany, wówczas godzina odpowiada godzinie wygenerowania szablonu w kreatorze.

W przypadku braku obowiązkowych elementów szablonu nie będzie możliwe jego wygenerowanie. przycisk Generuj będzie wyszarzały, a w prawym dolnym rogu pojawi się komunikat „Uzupełnij elementy wymagane w szablonie”. Sekcje, gdzie element nie został wybrany będą się wyświetlać z odpowiednią ikoną.

  Kreatorze wyglądu istnieje również możliwość cofania się podczas tworzenia szablonu, w ramach której obsługujemy do 30 kroków w wstecz. Dodatkowo możemy także wykonywać krok do przodu. Zapisywane są wszystkie zmiany na elementach, informacje odnośnie styli, czcionek, ikonach oraz nazwie szablonu.

Aktualizacja szablonu

W Kreatorze Wyglądu znajduje się opcja aktualizacji poprzednich wersji szablonu. W celu zaktualizowania całego szablonu należy wgrać plik z poprzednim szablonem do Kreatora Wyglądu, według tej instrukcji:
  • po uruchomieniu strony kreatora wybierz opcję: Stwórz nowy projekt,
  • wybierz Nowy szablon,
  • w prawym górnym rogu wybierz opcję Importuj szablon,
  • następnie zaimportuj plik z szablonem, który ma być zaktualizowany. Po poprawnym zaimportowaniu szablonu otrzymasz informację zwrotną:
  • po wgraniu szablonu do aktualizacji użyj opcji Generuj. 
Dzięki temu w prosty sposób można starsze szablony Topaz podnieść do wersji aktualnej.

Więcej informacji

Więcej informacji można znaleźć w artykułach o wyglądzie sklepu oraz o dostosowaniu wyglądu.

Banner promocyjny w szablonie Topaz i One Page Shop

Banner promocyjny - jak to działa?

Banner promocyjny wyświetli się na stronie głównej Twojego e-Sklepu i będzie prezentował typ towaru, który wskażesz. Taki rodzaj banneru pomoże Ci w zwróceniu uwagi Klientów na towary, które zostały objęte na przykład ofertą specjalną.

Dodanie banneru

Banner możesz dodać z poziomu Kreatora Wyglądu B2C  (zamiennie: panel administracyjny e-Sklepu: Wygląd sklepu/ Kreator wyglądu). Aby dodać banner promocyjny do swojego szablonu, przejdź na stronę "Strona główna", po czym wybierz Banner promocyjny i przeciągnij go w wybrane przez Ciebie miejsce. W podglądzie układu szablonu, po najechaniu kursorem na obszar z bannerem promocyjnym, zobaczysz możliwość jego edycji. Wybierz ikonę "zębatki", aby móc edytować i określić liczbę wyświetlanych towarów oraz typ promowanych towarów. Zapisz wprowadzone zmiany. Jeśli pozostałe strony szablonu są gotowe i skonfigurowane, to możesz wygenerować szablon. Więcej informacji na temat Kreatora Wyglądu oraz poszczególnych sekcji znajdziesz w artykule: Kreator wyglądu Topaz (B2C) Po zaimportowaniu szablonu do panelu administracyjnego możesz przejść do edycji banneru. Postępuj zgodnie z poniższą instrukcją.

Edycja banneru

Modyfikacja wszystkich bannerów dostępnych w szablonach Comarch możliwa jest w panelu administracyjnym w obszarze Wygląd sklepu> Ustawienia> Bannery. Informacje odnośnie domyślnej, tradycyjnej modyfikacji bannerów znajdują się w artykule: Bannery

Odnajdź banner na liście nazwany "promotionalBanner", a następnie wybierz go, aby edytować i dodać zdjęcie

Po dokonaniu modyfikacji należy zapisać i opublikować zmiany. Gotowe! Teraz Twój banner promocyjny wyświetli się na stronie głównej.
Banner promocyjny w szablonie Topaz
Banner promocyjny w szablonie Topaz.

Jak zaktualizować szablon do najnowszej wersji?

Jak zaktualizować szablon do najnowszej wersji?

Wskazówka
Od 1 czerwca 2025 roku zakończyliśmy aktualizację oraz wydawanie nowych wersji szablonów Bursztyn, Agat i Opal, a tym samym ich wsparcie, aby skupić się na nowoczesnych rozwiązaniach, które jeszcze lepiej odpowiadają na potrzeby dynamicznie rozwijającego się rynku e-commerce. Zachęcamy Was do przejścia na nasze nowe, udoskonalone szablony. Dla sklepów B2C polecamy szablony Topaz, One Page Shop oraz Dla Gastronomii, natomiast dla platform B2B idealnym wyborem będą Rubin i Szafir.

Wstęp

W e-Sklepie możesz dowolnie zmieniać szablony. Możesz je także modyfikować oraz aktualizować. Wiąże się to z wgraniem zupełnie nowego szablonu na miejsce starego. Aktualizacja wyglądu powoduje zmianę dotychczasowych ustawień. Przed każdą aktualizacją polecamy utworzyć odpowiednią dla siebie instrukcję, która będzie zawierała Twoje ustawienia kolorów czy modyfikacje w kodzie szablonu. Możesz także wyeksportować dotychczasowy szablon, aby stanowił on kopię bezpieczeństwa.

Jak zaktualizować szablon?

Instrukcja aktualizacji szablonów: Rubin, Szafir, Topaz i One Page Shop (dostępnych w Kreatorze Wyglądu)

Aby zaktualizować szablon Rubin, Szafir, Topaz lub One Page Shop należy skorzystać z aktualnej wersji Kreatora Wyglądu, do którego odnośnik znajduje się w panelu administracyjnym e-Sklepu w sekcji Wygląd sklepu/ Kreator wyglądu. Istnieją dwie możliwości aktualizacji tych szablonów:

  • wygenerowanie nowego szablonu w Kreatorze Wyglądu oraz wgranie go do e-Sklepu,
  • import posiadanego szablonu do Kreatora Wyglądu oraz ponowne wygenerowanie go w najnowszej wersji.

Wyeksportowany z Kreatora Wyglądu szablon należy wgrać do e-Sklepu. W panelu administracyjnym e-Sklepu, w sekcji Wygląd sklepu znajduje się bezpośredni odnośnik do importu szablonu z Kreatora wyglądu. Szczegółowa instrukcja dostępna jest w artykule Jak wyeksportować i zaimportować swój szablon w e-Sklepie?

Podczas dokonywania modyfikacji w szablonach zachęcamy do skorzystania z naszego Centrum Pomocy.

Wskazówka
Pamiętaj o zapisaniu szablonu oraz opublikowaniu go w e-Sklepie. Zmiany wprowadzone w ustawieniach zostaną zsynchronizowane do sklepu po 10 minutach.

Instrukcja aktualizacji szablonów: Bursztyn, Agat i Opal.

Aby zaktualizować szablon Bursztyn, Agat lub Opal należy w panelu administracyjnym e-Sklepu przejść do sekcji Wygląd Sklepu/ Gotowe szablony Comarch, w której znajdują się najnowsze wersje szablonów dostępne do zainstalowania. Z wyświetlonej listy należy wybrać szablon, który ma zostać wgrany do e-Sklepu. W tym celu wybierz przycisk Chcę pobrać i zainstalować szablon:

Następnie wyświetli się nowe okno, w którym należy:

  • wybrać tzw. slot, który zostanie nadpisany nowym (aktualnym) szablonem. W każdym e-Sklepie dostępne są 4 miejsca na wgranie szablonu, spośród których jeden szablon oznacza się jako aktywny i domyślny,
  • określić, czy wgrywany szablon ma podmienić istniejące bannery. Gdy parametr zostanie zaznaczony, wówczas wszystkie bannery zapisane na danym slocie zostaną usunięte i zastąpione bannerami z importowanego szablonu. Jeżeli w nadpisywanym szablonie znajdują się bannery oraz lookbooki, które mają nadal wyświetlać się w e-Sklepie, należy wskazany parametr zostawić odznaczony. Gdy parametr nie zostanie zaznaczony, wówczas dotychczasowe bannery i lookbooki nie zostaną usunięte.
  • Zaimportować szablon do e-Sklepu.
    Wskazówka
    Import szablonu jest operacją nieodwracalną i spowoduje nadpisanie dotychczasowego szablonu. W przypadku, gdy szablon był modyfikowany (dokonywano zmian w kodzie HTML) jego aktualizacja spowoduje, iż zmiany nie zostaną przeniesione. Warto wykonać eksport posiadanego szablonu do pliku w celu zapisania oraz posiadania wglądu to wprowadzanych modyfikacji. Jeżeli istnieje taka konieczność należy ponownie dokonać samodzielnej edycji szablonu.

Aby nowy szablon pojawił się w e-Sklepie należy upewnić się, czy jest on aktywny oraz ustawiony jako domyślny. W sekcji Wygląd sklepu/Ustawienia/Edytuj ustawienia zaawansowane w zakładce Szablon znajdują się odpowiedzialne za to parametry, które powinny być zaznaczone.

Wszelkie zmiany należy zapisać, a następnie opublikować.

Uwaga
Jeżeli szablon nie zostanie opublikowany, wówczas nie pojawi się on w e-Sklepie.

Instrukcja aktualizacji innych szablonów (niż szablonów Comarch) oraz aktualizacji szablonów z własnymi modyfikacjami

Jeżeli w swoim Comarch e-Sklepie korzystasz z własnego szablonu, czyli innego niż gotowe szablony Comarch, to powinieneś jego aktualizację przeprowadzić we własnym zakresie lub zlecić ją firmie/ osobie, która dla Ciebie przygotowała ten szablon. W przypadku, gdy korzystasz z gotowego szablonu Comarch, ale wprowadziłeś do niego indywidualne zmiany (poza Kreatorem Wyglądu), to również we własnym zakresie (lub ze wsparciem autora zmian) musisz zadbać o aktualizację swojej wersji szablonu.

One Page Shop - podstawowe informacje

Wstęp

One Page Shop to szablon zaprojektowany z myślą o użytkownikach, którzy w swojej ofercie posiadają jedynie kilka towarów. Dzięki niemu zaprezentujesz na głównej stronie wyjątkowe produkty, które posiadasz w swojej ofercie. Struktura szablonu skupiona jest na zaprezentowaniu asortymentu tak, aby decyzje zakupowe Twoich Klientów zapadały szybciej. Potencjalny klient może odnaleźć najważniejsze informacje na temat Twojej oferty przeglądając jedną stronę witryny. Szablon One Page Shop:
  • dostępny jest we wszystkich wariantach Comarch e-Sklep,
  • pozwala na prezentację 20 towarów prostych,
  • dostępny jest w dwóch motywach kolorystycznych,
  • jest prosty w konfiguracji bezpośrednio w panelu.
Przejdź do naszego sklepu demonstracyjnego i zobacz, jak wygląda One Page Shop w Comarch e-Sklep.   W tym artykule zawarliśmy podstawowe informacje na temat funkcji dostępnych w szablonie. Dzięki udogodnieniom i możliwości edycji niektórych elementów możesz łatwo spersonalizować swój e-Sklep.

Konfiguracja One Page Shop w panelu administracyjnym

Z poziomu panelu administracyjnego możesz dokonywać edycji każdego elementu znajdującego się na stronie. Możesz także ustalać sposoby dostaw oraz płatności. Po przejściu do sekcji Wygląd sklepu/ Ustawienia dostępne są ustawienia dla trzech zakładek: Ogólne, Strona główna, Dodatkowe.
  • W zakładce Ogólne możesz dokonać zmian w motywie kolorystycznym Twojego e-Sklepu. Z tego poziomu również możesz dokonać m.in takich zmian, jak: prezentacja punktów osobistego, edycji terminu dostaw czy umożliwienie prezentacji informacji o najniższej cenie towaru lub usługi jaka obowiązywała w okresie 30 dni przed wprowadzeniem obniżki.
  • W zakładce Strona główna znajdują się ustawienia, które pomagają „układać” poszczególne elementy na stronie głównej. W tym miejscu możesz zdecydować, gdzie powinny wyświetlać się produkty, lookbook i bannery. Część wyświetlanych elementów możesz ukryć.
  • W zakładce Dodatkowe widnieją ustawienia, dzięki którym możesz decydować o możliwości udostępniania towarów w poszczególnych mediach społecznościowych, czy udostępniania przycisku obliczającego ratę lub leasing. Dodatkowo możesz włączyć prezentację tabeli rozmiarów na stronie towaru.

Ustawienia Strony Głównej

Ustawienia zawarte w tym miejscu odpowiadają za elementy, które wyświetlane są na stronie głównej. Możesz zmieniać ich kolejność, nazwę, ukryć lub wyróżnić. W tym miejscu wyróżnia się następujące sekcje:

Ustawienia nagłówka strony

W nagłówku znajdują się następujące elementy:
  • Logotyp,
  • Odnośnik do listy z produktami (nasze produkty),
  • Blog,
  • Lookbook,
  • Informacje o firmie,
  • Kontakt,
  • Koszyk,
  • Możliwość wyboru języka i waluty w e-Sklepie.
W tym miejscu możesz nie tylko dodać link do nagłówka, ale także ustalić, czy i jakie odnośniki do stron mają być widoczne. Możliwa jest też zmiana kolejności wyświetlania poszczególnych elementów.

Ustawienia treści strony

Pozostając w obszarze Wygląd sklepu/ Ustawienia/ Strona główna możesz zmienić ustawienia treści strony. W tym miejscu również istnieje możliwość zmiany kolejności wyświetlania poszczególnych elementów na stronie głównej sklepu oraz ukrycia elementu. Szczegółowe informacje na temat konfiguracji znajdują się w artykule: Jak zmienić kolejność wyświetlanych elementów na stronie głównej w One Page Shop?

Elementy w szablonie

1. Sekcja z filmami

W One Page Shop masz możliwość dodania filmów promujących nie tylko produkty, ale także Twoją firmę, dostępne marki czy producentów. Film możesz dodać w prosty i szybki sposób z poziomu panelu administracyjnego. W sekcji możesz zaprezentować filmy:
  • udostępnione w sekcji Ustawienia/ Pliki użytkownika,
  • opublikowane w portalu YouTube,
  • dodane na zewnętrznym hostingu.
Szczegóły konfiguracji znajdują się w artykule: Jak dodać wideo w sekcji z filmami w szablonie One Page Shop?

2. Banner

Aby dodać zdjęcia do banneru przejdź do zakładki Wygląd sklepu/ Ustawienia/ Bannery, a następnie klikając na kafelek o nazwie mainBanner wybierz odpowiednie zdjęcie. 
Wskazówka
Rekomendowany rozmiar grafik dla banneru to 1920 x 540 px.
Szczegóły na temat dodawania i edycji bannerów znajdują się w artykule: Bannery.

3. Lookbook

Widok charakteryzuje się prezentacją zdjęć w formie listy i precyzyjnym oznaczeniem towarów na zdjęciu. Dzięki znacznikom umieszczonym na grafice Twoi klienci będą mogli podejrzeć towar i dodać go bezpośrednio do koszyka. Po kliknięciu na przycisk z plusem wyświetli się popup ze szczegółami towaru oraz opcją zakupu.
Wskazówka
Rekomendowany rozmiar grafik do lookbooka to 560 x 500 px.
Aby poprawnie skonfigurować lookbook, skorzystaj z naszej instrukcji zawartej w artykule: Jak skonfigurować Lookbook w Comarch e-Sklep?

4. Lista towarów

Szablon One Page Shop został stworzony z myślą o użytkownikach, którzy w swojej ofercie nie posiadają wielu produktów. Z tego powodu, na stronie głównej wyświetlanych jest 20 towarów prostych, które zostały przypisane do pierwszej kategorii w systemie Comarch ERP. Z tego powodu zalecamy utworzenie jednej kategorii, która ma być przesyłana do One Page Shop'a.
Przyklad
W systemie ERP posiadasz kategorię A, B oraz C. W kategorii A i B znajduje się po 5 produktów, zaś w kategorii C, która liczy 10 produktów. Po wykonaniu synchronizacji zostanie wyświetlonych 5 produktów z kategorii A, ponieważ jest ona pierwsza w systemie Comarch ERP.
Lista produktów wyświetlana jest w formie kafli.
Sekcja z listą towarów w One Page Shop Comarch

5. Szczegóły towaru – jakie informacje widnieją na pop-upie?

W szablonie One Page Shop Klient będzie mógł zobaczyć szczegóły danego towaru nie musząc przechodzić na osobną stronę. Wystarczy, że kliknie na kafelek z interesującym go artykułem lub naciśnie Kup teraz. Wyświetli się wówczas pop up, który zawiera w sobie szereg informacji na temat towaru, między innymi:
  • Cenę wraz z formą dostawy, kalkulatorami ratalnymi oraz leasingowymi,
  • Dostępność produktu,
  • Cechy towaru,
  • Opis towaru,
  • Tabelę rozmiarów,
  • Liczbę opinii oraz zakładkę z wystawionymi już komentarzami,
  • Informację o ilości osób, która kupiła dany towar,
  • Możliwość udostępnienia towaru w social mediach lub za pomocą linku,
  • Opcję „Zapytaj o towar”,
  • Zestawy promocyjne.
Pop-up ze szczegółami towaru w One Page Shop Comarch
Jeśli posiadasz produkt, który nie posiada wariantów istnieje możliwość zakupu tego towaru z pominięciem pop-up podczas kliknięcia w przycisk "Kup teraz". Klikając w inne miejsce na towarze, pop-up ze szczegółami wyświetli się. Jeśli chcesz wyłączyć pop-up, możesz to zrobić z poziomu Panelu Administracyjnego przechodząc do sekcji Wygląd sklepu/ Ustawienia:

6. Koszyk

W szablonie One Page Shop składanie zamówienia jest szybkie i wygodne dla użytkownika. Koszyk został zaprojektowany tak, aby użytkownik mógł w jednym kroku wypełnić niezbędne dane: 
  • Formularz z danymi zamawiającego oraz danymi do faktury,
  • Sposób dostawy,
  • Sposób płatności,
  • Miejsce na wpisanie kodu rabatowego.
Po uzupełnieniu powyższych informacji można przejść do podsumowania, w którym prezentowane są wcześniej wprowadzone dane klienta. Oprócz tego w koszyku One Page Shop jest możliwość wyświetlania ceny za sztukę. Pojawi się ona po dodaniu do koszyka kilku sztuk produktu. Przy jednej sztuce towaru wyświetlana będzie tylko cena. Od wersji 2024.1.1 w szablonie One Page Shop dodano możliwość wyświetlania w koszyku informacji jakiej kwoty brakuje do darmowej dostawy.  Funkcja ta możliwa jest do uruchomienia z poziomu Panelu Administracyjnego w sekcji Wygląd sklepu/ Ustawienia/ Ustawienia szablonu/ Ogólne: Ustawienia te można zmienić według własnego uznania, a następnie należy użyć opcji Zapisz i Publikuj.

7. Blog

Prowadzenie bloga jest istotnym elementem sklepu internetowego. Dzięki niemu sprzedawca może dzielić się swoją wiedzą i spostrzeżeniami na temat reklamowanych produktów. W ten sposób sprzedawca może podpowiedzieć klientom w jaki sposób mogą oni wykorzystać oferowane przez niego artykuły. Prowadzenie bloga ma również dobry wpływ na pozycjonowanie, ze względu na unikalne treści. Dzięki temu Twój e-Sklep może częściej pojawiać się w wynikach wyszukiwania. W szablonie One Page Shop masz możliwość tworzenia dowolnej ilości wpisów. Na stronie głównej wyświetlone zostaną trzy najnowsze. Użytkownik ma możliwość podglądu całej listy artykułów. Wystarczy, że kliknie w etykietę Najnowsze wpisy. Szczegółowe informacje na temat konfiguracji bloga w e-Sklepie znajdują się w artykule: Jak skonfigurować blog?

8. Info-banner

Banner informacyjny pozwala na zaprezentowanie w przejrzysty sposób korzyści z zakupach w Twoim e-Sklepie. Modyfikacji tego obszaru dokonasz z poziomu panelu administracyjnego, przechodząc do sekcji Wygląd sklepu/ Ustawienia/ Bannery. Następnie przechodząc do szczegółów banneru o nazwie info-banner dostosujesz element do swoich preferencji. Możesz skorzystać z domyślnych grafik lub dodać własne.

9. Element tekstowy ze zdjęciem

Element tekstowy ze zdjęciem charakteryzuje się możliwością wprowadzenia statycznego opisu na stronie głównej w twoim e-Sklepie. Możesz zawrzeć w nim np. podstawowe informacje na temat Twojej firmy, asortymentu sklepu lub inne wartościowe dla Ciebie treści. Element tekstowy możesz odpowiednio skonfigurować przechodząc do sekcji Wygląd sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane, a następnie do zakładki Obiekty, gdzie skonfigurujesz zawartość elementu.
Wskazówka
Za wyświetlanie elementu tekstowego w szablonie One Page Shop odpowiada obiekt o nazwie text-el-photo-mp-1.
Więcej informacji na temat konfiguracji znajduje się w artykule: Element tekstowy w szablonie.

10. Stopka

Dzięki modyfikacji obszaru możesz jeszcze bardziej spersonalizować swój sklep poprzez uzupełnienie stopki w szereg przydatnych informacji. Elementem tym możesz zarządzać z poziomu sekcji Wygląd Sklepu/ Ustawienia/ Nagłówek i Stopka. Szczegółowe informacje na temat konfiguracji stopki znajdują się w artykule: Rozbudowana stopka w szablonach – jak ją skonfigurować?

11. Strefa Klienta

Do Strefy Klienta w szablonie One Page Shop masz możliwość zalogowania się poprzez Facebooka oraz przez Google. Więcej na temat konfiguracji logowania przez Facebooka i Google znajdziesz tutaj. Masz także możliwość całkowitego ukrycia Strefy Klienta na stronie sklepu internetowego. Zdecydujesz o tym zaznaczając właściwą opcję w zakładce Wygląd sklepu/ Ustawienia/ Ustawienia szablonu/ Ogólne: Wprowadzone zmiany standardowo należy zapisać i opublikować.

Jak wykonać kopię bezpieczeństwa mojego szablonu?

Jak wykonać kopię bezpieczeństwa mojego szablonu?

Oprawa wizualna sklepu jest bardzo ważnym elementem podczas prowadzenia sprzedaży w sieci. Narzędzie Kreator Wyglądu Comarch e-Sklep umożliwia stworzenie własnych, niepowtarzalnych szablonów wedle preferencji i potrzeb użytkowników. W intuicyjnym narzędziu jakim jest Kreator, będziesz w stanie zaprojektować wszelkie niezbędne funkcje, takie jak stronę główną, listę towarów, szczegóły towaru oraz koszyk. Jeśli Twój projekt szablonu został zaimportowany do e-Sklepu oraz skonfigurowany wedle Twoich preferencji (dodanie grafik do bannerów, modyfikacje kolorystyczne) masz możliwość jego zapisania, co będzie stanowić kopię bezpieczeństwa. Kopia bezpieczeństwa to dane, które w każdej chwili można odtworzyć w przypadku ich utracenia (np. poprzez przypadkowe usunięcie) lub częstego wprowadzania zmian. Dane, jakie może zawierać kopia bezpieczeństwa to szablon, który wcześniej został przez nas wygenerowany wraz z bannerami. Zaleca się wykonywanie kopii zapasowych oraz zabezpieczenie ich hasłem. Każda wykonana kopia zapasowa powinna zostać zapisana w bezpiecznym i dogodnym dla Użytkownika miejscu.

Jak wykonać kopię bezpieczeństwa?

W Panelu Administracyjnym przejdź do sekcji Wygląd sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane, a następnie przejdź do zakładki Eksport szablonu. W pustych polach znajdujących się w zakładce Eksport szablonu, opcjonalnie przed eksportem możesz uzupełnić powyższe dane, tj. Autora szablonu, e-mail, telefon i stronę WWW sklepu. Aby wyeksportować szablon, kliknij Eksportuj szablon. Wyeksportowany plik jest w formacie XML, a jego nazwa zawiera szablon oraz wersję, co znacznie ułatwia zarządzanie kopiami bezpieczeństwa w przypadku wykonywania ich regularnie.

Jak wyeksportować bannery?

Bannery, które znajdują się w Twoim sklepie możesz również wyeksportować tworząc kopię bezpieczeństwa. W tym celu także musisz przejść do Wygląd sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane, a następnie do zakładki Eksport szablonu. Obok przycisku Eksportuj szablon, znajduje się przycisk Eksportuj bannery, który musisz kliknąć aby bannery, które posiadasz w e-Sklepie zostały weksportowane. Kopia bezpieczeństwa jest również zapisywana w formacie XML, a nazwa pliku wskazuje na szablon, wersję i zawartość bannerów.

Jak zabezpieczyć hasłem swój szablon?

Jeśli chcesz, aby Twój szablon został zabezpieczony hasłem, a znajomość hasła była niezbędna podczas zaimportowania tego szablonu do e-Sklepu, musisz w tym celu przejść w Panelu Administracyjnym do sekcji Wygląd sklepu/ Ustawienia/ Ustawienia zaawansowane, następnie do zakładki Szablon. W tym miejscu nadasz hasło dla swojego szablonu. Zgodnie z Polityką bezpieczeństwa haseł, hasło powinno:
  • Składać się z minimum 8 znaków,
  • Zawierać dużą literę,
  • Zawierać małą literę,
  • Zawierać cyfrę 0-9,
  • Zawierać znak specjalny – ‘!.+?;^]=-(&_)#=
Gotowe! Teraz Twój szablon został zabezpieczony hasłem. Jeśli wyeksportujesz szablon, który zabezpieczyłeś hasłem – podczas importu tego szablonu, będziesz musiał podać nadane wcześniej hasło. Jego brak uniemożliwi import szablonu, a podanie błędnego hasła spowoduje nieprawidłowe działanie szablonu po imporcie. Więcej informacji znajdziesz:

Jak zmienić kolejność wyświetlanych elementów na stronie głównej w One Page Shop?

W szablonie One Page Shop możesz zmieniać dowolnie kolejność wyświetlanych na głównej stronie elementów. Możesz dzięki temu spersonalizować swój e-Sklep tak, by był bardziej unikalny.

Konfiguracja strony głównej

Aby dokonać zmian w kolejności wyświetlanych elementów na stronie głównej wystarczy, że zalogujesz się do panelu administracyjnego, a następnie przejdziesz do sekcji Wygląd sklepu/ Ustawienia/ Strona Główna. Wyświetli się wówczas panel, który zawiera w sobie ustawienia nagłówka strony, treści strony oraz sekcji z filmami.

Ustawienia nagłówka strony

W nagłówku znajdują się następujące elementy:
  • Logotyp,
  • Produkty,
  • Blog,
  • Lookbook,
  • O firmie,
  • Kontakt,
  • Koszyk,
  • Informacje o języku i walucie, możliwość wyboru. 

Lista elementów w nagłówku strony

W tym miejscu możesz nie tylko dodać link do nagłówka, ale także ustalić, czy odnośniki do stron mają być widoczne. Możliwa jest też zmiana kolejności wyświetlania poszczególnych elementów. Wystarczy, że przesuniesz wybrany element za pomocą strzałki w kolumnie Kolejność. Możesz także określić, który odnośnik powinien być wyróżniony, a dokładniej, który link w nagłówku będzie posiadała inny kolor. Zmiany koloru czcionki możesz dokonać w sekcji Wygląd sklepu/ Ustawienia/ Ogólne. Odpowiadają za to sekcje:
   

Ustawienia treści strony

Pozostając w obszarze Wygląd sklepu/ Ustawienia/ Strona główna możesz zmienić ustawienia treści strony. W tym miejscu również istnieje możliwość zmiany kolejności wyświetlania poszczególnych elementów na stronie głównej sklepu oraz ukrycia elementu. Wystarczy, że odznaczysz checkbox w kolumnie Dostępne.

Ustawienia sekcji z filmami

W szablonie One Page Shop dostępna jest sekcja, w której możesz publikować filmy, które pomogą Ci wypromować oferowany przez Ciebie towar. Film możesz dodać w prosty i szybki sposób z poziomu panelu administracyjnego. Szczegóły konfiguracji znajdują się w artykule: Jak dodać wideo w sekcji z filmami w szablonie One Page Shop?

Jak dodać wideo w sekcji z filmami?

Filmy produktowe na rynku e-commerce są dziś powszechną formą prezentowania towarów w sklepach internetowych. Producenci czy właściciele sklepów chcą wyróżniać swój asortyment. Niejednokrotnie pomaga to także w ukazaniu zastosowania produktu. Każdy film wyróżnia się sposobem prezentacji. W szablonie One Page Shop i Topaz dostępna jest sekcja, gdzie możesz publikować filmy, które pomogą Ci wypromować oferowany przez Ciebie towar.

Konfiguracja sekcji z filmami

Z poziomu panelu administracyjnego możesz w łatwy i szybki sposób dodać wideo. Postępuj zgodnie z poniższą instrukcją. Krok 1. Zaloguj się do panelu administracyjnego. Krok 2. Przejdź do zakładki Wygląd sklepu/ Ustawienia/ Strona główna. Na dole strony znajdź Ustawienia sekcji z filmami. Krok 3. Uzupełnij informacje o filmie: Etykietę PL oraz wstaw Link do filmu. W sekcji możesz zaprezentować filmy:
  • udostępnione w sekcji Ustawienia/ Pliki użytkownika – przykładowy link: usr/nazwafilmu.mp4
  • opublikowane w portalu YouTube – przykładowy link: https://www.youtube.com/embed/jq3B5jp8QwI
  • dodane na zewnętrznym hostingu – przykładowy link: https://twojhosting.pl/filmy/nazwafilmu.mp4
Krok 4. Uzupełnij tłumaczenia dla nazwy filmów prezentowanych w szablonie. Naciśnij link videoElement1, a zostaniesz przekierowany do edycji tłumaczenia. W polu tekst wpisz odpowiednią nazwę filmu i zapisz zmiany. Krok 5. Zapisz i opublikuj zmiany. Gotowe! Od teraz Klienci zobaczą w szablonie skonfigurowaną sekcję z opublikowanymi filmami. Przejdź do naszego sklepu demonstracyjnego i zobacz, jak wygląda skonfigurowana sekcja.

Jak wyeksportować i zaimportować swój szablon w e-Sklepie?

Comarch e-Sklep daje możliwość dostosowania wyglądu do preferencji sprzedawcy oraz potrzeb Klientów. Jeśli utworzyłeś już swój autorski projekt, to masz możliwość jego zapisania. Plik będzie potrzebny przy chęci modyfikacji wyglądu. Zapisana wersja szablonu może również stanowić kopię bezpieczeństwa. Warto jest więc wyeksportować szablon do pliku.

Jak wyeksportować swój szablon z Comarch e-Sklep?

Krok 1. W panelu administracyjnym przejdź do sekcji Wygląd Sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane/ zakładka Eksport szablonu.

Krok 2. W tym miejscu możesz opcjonalnie (przed eksportem) określić autora szablonu, podać adres e-mail, telefon oraz adres WWW swojego e-Sklepu.

Krok 3. Jeżeli chcesz wyeksportować szablon do pliku użyj przycisku Eksportuj szablon.

Gotowe! Szablon został wyeksportowany do pliku na Twoim urządzeniu.

Wskazówka
Z tego miejsca możesz także wyeksportować posiadane w e-Sklepie bannery, korzystając z przycisku Eksportuj bannery.

Jak wgrać własny szablon do Comarch e-Sklep?

Własny szablon. Jak go wgrać?

Po skomponowaniu swojego własnego szablonu możesz wgrać go do e-Sklepu. Postępuj zgodnie z poniższymi krokami.

Krok 1. W panelu administracyjnym przejdź do sekcji Wygląd Sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane/ zakładka Import szablonu.

Krok 2. Określ, czy wgrywany szablon ma podmienić istniejące bannery. Gdy parametr zostanie zaznaczony, wówczas wszystkie bannery zapisane na danym slocie zostaną usunięte i zastąpione bannerami z importowanego szablonu.

Krok 3. Wybierz plik XML swojego szablonu i naciśnij Importuj szablon.

Uwaga
Import szablonu jest operacją nieodwracalną i spowoduje nadpisanie dotychczasowego szablonu. W przypadku, gdy szablon był modyfikowany (dokonywano zmian w kodzie HTML) jego aktualizacja spowoduje, iż zmiany nie zostaną przeniesione. Warto wykonać eksport posiadanego szablonu do pliku w celu zapisania oraz posiadania wglądu to wprowadzanych modyfikacji. Jeżeli istnieje taka konieczność należy ponownie dokonać samodzielnej edycji szablonu

Wskazówka
W zakładce Szablony możesz określić, czy wgrywany szablon ma być domyślny i aktywny w e-Sklepie.

Krok 4. Teraz możesz podejrzeć zmiany, jakie zaszły w wyglądzie Twojego e-Sklepu. W tym celu możesz podejrzeć zmiany w czasie rzeczywistym lub przejść w tryb incognito. Pamiętaj, że wszelkie zmiany zostaną opublikowane po pełnej synchronizacji, która wciągu 10 minut zgodnie z wyświetlanym komunikatem.

Gotowe! Twój szablon został zaimportowany do e-Sklepu.

Szablon dla Gastronomii

Instrukcja: Jak dostosować samodzielnie szablon do szybkich zwrotów w e-Commerce?

Wskazówka
Wskazówka: W tym artykule trzeba będzie wprowadzać zmiany w plikach js oraz scss. Z tego artykułu dowiesz się jak je kompilować i minifikować.
W szablonach Rubin, Szafir oraz Topaz / One Page Shop wprowadziliśmy funkcję szybkich zwrotów. Umożliwia ona klientom składanie wniosku o zwrot produktu zarówno z poziomu profilu klienta (zalogowani), jak i z dedykowanej strony zwrotów po podaniu numeru zamówienia oraz adresu e-mail (niezalogowani). Wraz z funkcjonalnością pojawił się m.in. rozbudowany ekran potwierdzenia zwrotu zawierający kolejne kroki i adres do wysyłki, banery informacyjne dotyczące terminu zwrotu oraz przyciski akcji w tabeli produktów wyświetlane bezpośrednio (zamiast w rozwijanym menu). Aby Twój szablon poprawnie obsługiwał te zmiany, wprowadź modyfikacje opisane poniżej w sekcji dotyczącej Twojego szablonu. Po zakończeniu edycji pamiętaj o kompilacji i minifikacji plików js oraz scss.
Wskazówka
Potrzebujesz pomocy lub masz pytania? Skontaktuj się z nami poprzez portal asysta.comarch.pl.
Wskazówka
Obecnie w Polsce trwają prace nad ostatecznym kształtem przepisów oraz nowelizacją Ustawy o prawach konsumenta, która wdroży unijną dyrektywę UE 2023/2673 i wprowadzi nowe wymagania techniczne dla platform e-commerce (m.in. ułatwienia w procedurze zwrotów). W momencie publikacji ostatecznej wersji polskich przepisów, wdrożone funkcjonalności mogą wymagać dostosowania do ostatecznych wytycznych ustawodawcy. Prezentowane informacje mają charakter poglądowy a instrukcja dotyczy zmian, jakie wprowadziliśmy w szablonach Comarch – w przypadku pytań dotyczących indywidualnej sytuacji prawnej Twojego sklepu, zalecamy konsultację z radcą prawnym lub adwokatem.

Szablon Rubin

1. Tłumaczenia

W panelu administracyjnym sklepu zaktualizuj dwa istniejące tłumaczenia oraz dodaj nowe klucze wymagane przez funkcjonalność szybkich zwrotów. Zaktualizuj poniższe istniejące tłumaczenia: ReturnSuccessTitle - PL: Gotowe! Przyjęliśmy Twoje zgłoszenie - EN: Done! We have received your request - DE: Fertig! Wir haben Ihre Anfrage erhalten - FR: C'est fait ! Nous avons reçu votre demande ReturnSuccessInfo - PL: Przygotuj paczkę i odeślij ją do nas – wszystkie szczegóły znajdziesz poniżej. - EN: Prepare the package and send it back to us – all the details are below. - DE: Bereiten Sie das Paket vor und senden Sie es an uns zurück – alle Details finden Sie unten. - FR: Préparez le colis et renvoyez-le nous – tous les détails sont ci-dessous. Dodaj nowe tłumaczenia: OrderReturnDeadlineInfo - PL: Zamówienie można zwrócić w ciągu {0} dni od daty dostawy. - EN: You can return the order within {0} days from the delivery date. - DE: Sie können die Bestellung innerhalb von {0} Tagen ab Lieferdatum zurückgeben. - FR: Vous pouvez retourner la commande dans les {0} jours suivant la date de livraison. RestrictedOrderViewInfo - PL: Wybrane dane zamówienia zostały ukryte ze względów bezpieczeństwa. Możesz zwrócić produkty bez logowania. - EN: Some order details are hidden for security reasons. You can return products without signing in. - DE: Einige Bestelldetails wurden aus Sicherheitsgründen ausgeblendet. Sie können Produkte ohne Anmeldung zurücksenden. - FR: Certaines informations de la commande ont été masquées pour des raisons de sécurité. Vous pouvez retourner des produits sans vous connecter. Com_RefundMethod - PL: Sposób zwrotu środków - EN: Refund method - DE: Rückerstattungsmethode - FR: Mode de remboursement Com_RefundAsPaid - PL: Tak jak zapłacono - EN: Same as paid - DE: Wie bezahlt - FR: Comme payé Com_RefundToBankAccount - PL: Na konto bankowe - EN: To bank account - DE: Auf Bankkonto - FR: Sur le compte bancaire Com_BankAccountNumber - PL: Nr konta bankowego - EN: Bank account number - DE: Bankkontonummer - FR: Numéro de compte bancaire Com_ConfirmationSentTo - PL: Potwierdzenie zwrotu zostało wysłane na adres: - EN: Return confirmation has been sent to: - DE: Bestätigung wurde gesendet an: - FR: La confirmation de retour a été envoyée à: Com_NextSteps - PL: Następne kroki - EN: Next Steps - DE: Nächste Schritte - FR: Prochaines étapes Com_PackProducts - PL: Bezpiecznie zapakuj swoje produkty - EN: Safely pack your products - DE: Verpacken Sie Ihre Produkte sicher - FR: Emballez vos produits en toute sécurité Com_SendPackageTo - PL: Wyślij paczkę na adres: - EN: Send the package to the address: - DE: Senden Sie das Paket an die Adresse: - FR: Envoyez le colis à l'adresse: Com_RefundAfterReceive - PL: Pieniądze zwrócimy niezwłocznie po otrzymaniu i sprawdzeniu Twojej paczki - EN: We will refund the money promptly upon receipt and inspection of your package - DE: Wir erstatten das Geld umgehend nach Erhalt und Überprüfung Ihres Pakets zurück - FR: Nous rembourserons l'argent rapidement après réception et inspection de votre colis ReturnInThreeSteps - PL: Zwróć towar w 3 krokach - EN: Return the product in 3 steps - DE: Geben Sie die Ware in 3 Schritten zurück - FR: Retournez la marchandise en 3 étapes ReturnWithoutReasonInfo - PL: Przysługuje Ci możliwość zwrotu bez podania przyczyny. - EN: You have the right to return the product without giving a reason. - DE: Sie haben das Recht, die Ware ohne Angabe von Gründen zurückzugeben. - FR: Vous avez le droit de retourner la marchandise sans donner de motif. OrEnterOrderNumber - PL: lub podaj numer zamówienia - EN: or enter the order number - DE: oder geben Sie die Bestellnummer ein - FR: ou saisissez le numéro de commande FillForm - PL: Wypełnij formularz - EN: Fill out the form - DE: Füllen Sie das Formular aus - FR: Remplissez le formulaire ReturnOnline - PL: zwrotu online - EN: online return - DE: Online-Rückgabe - FR: retour en ligne SendParcel - PL: Wyślij paczkę - EN: Send the parcel - DE: Paket senden - FR: Envoyer le colis SendParcelToOurAddress - PL: nadaj przesyłkę na nasz adres - EN: send the parcel to our address - DE: senden Sie das Paket an unsere Adresse - FR: envoyez le colis à notre adresse FastSimpleSecure - PL: Szybko, prosto i bezpiecznie. - EN: Fast, simple and secure. - DE: Schnell, einfach und sicher. - FR: Rapide, simple et sécurisé. ReadyForReturn - PL: Gotowy do zwrotu? - EN: Ready for return? - DE: Bereit zur Rückgabe? - FR: Prêt pour le retour ? ReadyForReturnInfo - PL: Kliknij poniżej, aby rozpocząć proces zwrotu. Przeprowadzimy Cię przez wszystkie kroki. - EN: Click below to start the return process. We will guide you through all the steps. - DE: Klicken Sie unten, um den Rückgabeprozess zu starten. Wir führen Sie durch alle Schritte. - FR: Cliquez ci-dessous pour lancer le processus de retour. Nous vous guiderons à travers toutes les étapes. StartReturn - PL: Rozpocznij zwrot - EN: Start return - DE: Rückgabe starten - FR: Commencer le retour ProductReturn - PL: Zwrot produktu - EN: Product return - DE: Produktrückgabe - FR: Retour du produit ProductReturnFormInfo - PL: Wprowadź dane zamówienia, aby zlokalizować zakup i rozpocząć proces zwrotu. Numer zamówienia znajdziesz w e-mailu z potwierdzeniem. - EN: Enter the order details to locate the purchase and start the return process. You will find the order number in the confirmation e-mail. - DE: Geben Sie die Bestelldaten ein, um den Kauf zu lokalisieren und den Rückgabeprozess zu starten. Die Bestellnummer finden Sie in der Bestätigungs-E-Mail. - FR: Saisissez les données de la commande pour localiser l'achat et démarrer le processus de retour. Vous trouverez le numéro de commande dans l'e-mail de confirmation. InvalidOrderNumber - PL: Błędny numer zamówienia. Spróbuj ponownie. - EN: Invalid order number. Please try again. - DE: Ungültige Bestellnummer. Bitte versuchen Sie es erneut. - FR: Numéro de commande incorrect. Veuillez réessayer. FindOrder - PL: Znajdź zamówienie - EN: Find order - DE: Bestellung finden - FR: Trouver la commande LoginToSeeOrdersAndReturn - PL: aby zobaczyć swoje zamówienia i dokonać zwrotu. - EN: to see your orders and make a return. - DE: um Ihre Bestellungen einzusehen und eine Rückgabe vorzunehmen. - FR: pour voir vos commandes et effectuer un retour. RefundLookupError - PL: Wystąpił błąd podczas wyszukiwania zamówienia. Spróbuj ponownie później. - EN: An error occurred while searching for the order. Please try again later. - DE: Bei der Suche nach der Bestellung ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut. - FR: Une erreur s'est produite lors de la recherche de la commande. Veuillez réessayer plus tard.

2. Nowa strona Szybkie zwroty

Funkcjonalność szybkich zwrotów wymaga utworzenia dodatkowej strony statycznej refunds. Wykonaj poniższe kroki.

Plik refunds.html w katalogu głównym szablonu

W katalogu głównym szablonu utwórz nowy plik refunds.html z następującą zawartością:
{% extends '_layout.html' -%}

{% block pageContent -%}
{% include 'static-elements/refunds/refunds.html' -%}
{% endblock -%}

Plik static-elements/refunds/refunds.html

W folderze static-elements utwórz nowy katalog refunds, a w nim plik refunds.html:
<div class="page-padding">
    <h1 class="refunds-page-title refunds-initial-view-js">{{ translations.Returns }}</h1>
    <section class="refunds-container refunds-initial-view-js">
        <div class="refunds-info">
            <h2 class="refunds-info__title">{{ translations.ReturnInThreeSteps }}</h2>
            <p class="refunds-info__intro">{{ translations.ReturnWithoutReasonInfo }}</p>
            <ol class="refunds-steps">
                <li class="refunds-steps__item">
                    <span class="refunds-steps__number">1</span>
                    <p class="refunds-steps__text"><strong>{{ translations.LogIn }}</strong> {{ translations.OrEnterOrderNumber }}</p>
                </li>
                <li class="refunds-steps__item">
                    <span class="refunds-steps__number">2</span>
                    <p class="refunds-steps__text"><strong>{{ translations.FillForm }}</strong> {{ translations.ReturnOnline }}</p>
                </li>
                <li class="refunds-steps__item">
                    <span class="refunds-steps__number">3</span>
                    <p class="refunds-steps__text"><strong>{{ translations.SendParcel }}</strong> - {{ translations.SendParcelToOurAddress }}</p>
                </li>
            </ol>
            <p class="refunds-info__hint">{{ translations.FastSimpleSecure }}</p>
        </div>
        <div class="refunds-cta">
            <div class="refunds-cta__header">
                <h3 class="refunds-cta__title">{{ translations.ReadyForReturn }}</h3>
                <p class="refunds-cta__description">{{ translations.ReadyForReturnInfo }}</p>
            </div>
            {% if usr.Authenticated -%}
            <a class="primary-action-button refunds-cta__button" href="{{ config.DefinedPages.CustomerProfile.Url }}?tab=orders" rel="nofollow" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </a>
            {% else -%}
            <button class="primary-action-button refunds-cta__button start-refund-js" type="button" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </button>
            {% endif -%}
        </div>
    </section>
    {% unless usr.Authenticated -%}
    <section class="refund-form-section refund-form-view-js hidden-js">
        <div class="refund-form">
            <div class="refund-form__header">
                <h2 class="refund-form__title">{{ translations.ProductReturn }}</h2>
                <p class="refund-form__description">{{ translations.ProductReturnFormInfo }}</p>
            </div>
            <form class="refund-form__body refund-form-js" novalidate="" data-error="{{ translations.RefundLookupError }}">
                <div class="form__input-wrapper">
                    <label class="form__input-info input-info-js" for="refundOrderNumber">{{ translations.NumberOfOrder }}</label>
                    <input id="refundOrderNumber" class="form__input-value input-value-js" maxlength="50" name="orderNumber" required="" type="text" />
                    <div class="form__invalid-input validation-info-js validation-required-js hidden-js">{{ translations.FieldRequired }}</div>
                </div>
                <div class="form__input-wrapper">
                    <label class="form__input-info input-info-js" for="refundEmail" data-type="email">{{ translations.EmailAddress }}</label>
                    <input id="refundEmail" class="form__input-value input-value-js" autocomplete="email" maxlength="192" name="email" required="" type="email" />
                    <div class="form__invalid-input validation-info-js validation-required-js hidden-js">{{ translations.FieldRequired }}</div>
                    <div class="form__invalid-input validation-info-js email-valid-js hidden-js">{{ translations.FillProperEmail }}</div>
                </div>
                <button class="primary-action-button refund-form__submit refund-form-submit-js" type="button">
                    {{ translations.FindOrder }}
                </button>
                <p class="refund-form__login-info">{{ translations.HaveAccount }} <a class="refund-form__login-link show-login-popup-js" tabindex="0" role="button" rel="nofollow">{{ translations.LogIn }},</a> {{ translations.LoginToSeeOrdersAndReturn }}</p>
            </form>
        </div>
    </section>
    {% endunless -%}
</div>

Plik js/layout1.js – kod obsługi formularza zwrotu

Na końcu pliku js/layout1.js dodaj poniższy kod odpowiedzialny za walidację i wysłanie formularza wyszukiwania zamówienia (dla niezalogowanego klienta):
$(document).ready(function() {
    refunds.init();
})

const refunds = {
    init: function() {
        this.events();
    },

    findRefundOrder: function(orderNumber, email) {
        return $.post('', {
            __action: 'Order/QuickReturnLookup',
            orderId: orderNumber,
            email: email,
            __csrf: __CSRF
        });
    },

    showForm: function() {
        $('.refunds-initial-view-js').addClass('hidden-js');
        $('.refund-form-view-js').removeClass('hidden-js');
        $('.refund-form-js input[name="orderNumber"]').trigger('focus');
    },

    clearFieldError: function(input) {
        const $input = $(input);
        $input.removeClass('validation-error-js');
        $input.closest('.form__input-wrapper').find('.form__invalid-input').addClass('hidden-js');
    },

    submitForm: async function(button) {
        const $submit = $(button);
        const $form = $submit.closest('.refund-form-js');
        const $orderInput = $form.find('input[name="orderNumber"]');
        const $emailInput = $form.find('input[name="email"]');
        const orderValue = $orderInput.val().trim();
        const emailValue = $emailInput.val().trim();
        const emailRegex = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w{2,}$/;
        let hasError = false;

        $form.find('.form__invalid-input').addClass('hidden-js');
        $form.find('.form__input-value').removeClass('validation-error-js');

        if (orderValue.length === 0) {
            $orderInput.addClass('validation-error-js');
            $orderInput.closest('.form__input-wrapper').find('.validation-required-js').removeClass('hidden-js');
            hasError = true;
        }

        if (emailValue.length === 0) {
            $emailInput.addClass('validation-error-js');
            $emailInput.closest('.form__input-wrapper').find('.validation-required-js').removeClass('hidden-js');
            hasError = true;
        } else if (!emailRegex.test(emailValue)) {
            $emailInput.addClass('validation-error-js');
            $emailInput.closest('.form__input-wrapper').find('.email-valid-js').removeClass('hidden-js');
            hasError = true;
        }

        if (hasError) {
            return;
        }

        $submit.prop('disabled', true);

        try {
            const result = await refunds.findRefundOrder(orderValue, emailValue);
            const action = result.action;
            if (action.Redirect302) {
                globalThis.location.href = action.Redirect302;
                return;
            }
            app.temporaryPopupMessage(undefined, action.Message, action.Type);
        } catch (error) {
            console.error('Refund order lookup failed.', error);
            app.temporaryPopupMessage(undefined, $form.data('error'), 'err');
        } finally {
            $submit.prop('disabled', false);
        }
    },

    events: function() {
        $('body').on('click', '.start-refund-js', function() {
            refunds.showForm();
        });

        $('body').on('input', '.refund-form-js .form__input-value', function() {
            refunds.clearFieldError(this);
        });

        $('body').on('click', '.refund-form-submit-js', function(e) {
            e.preventDefault();
            refunds.submitForm(this);
        });

        $('body').on('keydown', '.refund-form-js input', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
                $(this).closest('.refund-form-js').find('.refund-form-submit-js').trigger('click');
            }
        });
    }
};

Pliki SCSS strony Szybkie zwroty

W folderze scss/static-elements utwórz nowy katalog refunds i umieść w nim trzy pliki: refunds-g.scss, refunds-m.scss i refunds-t.scss. scss/static-elements/refunds/refunds-g.scss:
.refunds-page-title {
    margin: 0 0 24px;
    font-size: 24px;
    font-weight: 500;
    line-height: 32px;
    color: $primaryColorFont;
}

.refunds-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 32px;
    margin-bottom: 32px;
    color: $primaryColorFont;
}

.refunds-info {
    align-self: flex-start;
    display: flex;
    flex-direction: column;
    gap: 16px;
    width: 100%;
    max-width: 800px;

    &__title {
        margin: 0;
        font-size: 20px;
        font-weight: 600;
        line-height: 28px;
        color: $primaryColorFont;
    }

    &__intro {
        margin: 0;
        font-size: 16px;
        font-weight: 500;
        line-height: 24px;
        color: $primaryColorFont;
    }

    &__hint {
        margin: 4px 0 0;
        font-size: 12px;
        font-weight: 400;
        line-height: 20px;
        color: $breadcrumbs;
    }
}

.refunds-steps {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;

    &__item {
        display: flex;
        align-items: center;
        gap: 12px;
    }

    &__number {
        flex-shrink: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        border-radius: 50%;
        background-color: #f3f3f3;
        color: $primaryColor;
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
    }

    &__text {
        margin: 0;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        color: $primaryColorFont;

        strong {
            font-weight: 600;
        }
    }
}

.refunds-cta {
    box-sizing: border-box;
    width: 100%;
    max-width: 578px;
    padding: 40px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 24px;
    background-color: $bgColor;
    border: 1px solid $lightBorderColor;
    border-radius: 8px;

    &__header {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 12px;
        width: 100%;
    }

    &__title {
        margin: 0;
        font-size: 24px;
        font-weight: 600;
        line-height: 32px;
        text-align: center;
        color: $primaryColorFont;
    }

    &__description {
        margin: 0;
        font-size: 16px;
        font-weight: 400;
        line-height: 24px;
        text-align: center;
        color: $breadcrumbs;
    }

    &__button {
        width: 100%;
        text-decoration: none;
    }
}

.refund-form-section {
    display: flex;
    justify-content: center;
    width: 100%;
    margin-bottom: 32px;
}

.refund-form {
    box-sizing: border-box;
    width: 100%;
    max-width: 578px;
    padding: 40px;
    background-color: $bgColor;
    border: 1px solid $lightBorderColor;
    border-radius: 8px;

    &__header {
        display: flex;
        flex-direction: column;
        gap: 12px;
        margin-bottom: 32px;
    }

    &__title {
        margin: 0;
        font-size: 24px;
        font-weight: 600;
        line-height: 32px;
        color: $primaryColorFont;
    }

    &__description {
        margin: 0;
        font-size: 14px;
        font-weight: 400;
        line-height: 20px;
        color: $breadcrumbs;
    }

    &__body {
        display: flex;
        flex-direction: column;
    }

    .form__input-wrapper {
        .form__input-value {
            &.validation-error-js {
                border-color: $dangerColor;
                color: $dangerColor;
            }
        }

        .form__invalid-input {
            position: static;
            display: block;
            margin: 4px 0 0;
            padding-left: 16px;
            text-align: left;
            color: $dangerColor;
            font-size: 12px;
            font-weight: 400;
            line-height: 16px;
        }
    }

    &__submit {
        width: 100%;
        margin-top: 4px;
    }

    &__login-info {
        margin: 16px 0 0;
        text-align: center;
        font-size: 14px;
        font-weight: 400;
        line-height: 20px;
        color: $primaryColorFont;
    }

    &__login-link {
        color: $primaryColor;
        font-weight: 600;
        cursor: pointer;
        text-decoration: none;

        &:hover {
            text-decoration: underline;
        }
    }
}
scss/static-elements/refunds/refunds-m.scss:
@media screen and (max-width: 767px) {
    .refunds-page-title {
        font-size: 20px;
        line-height: 28px;
        margin-bottom: 16px;
    }

    .refunds-container {
        gap: 24px;
        margin-bottom: 24px;
    }

    .refunds-info {
        max-width: 100%;
        gap: 12px;

        &__title {
            font-size: 18px;
            line-height: 24px;
        }

        &__intro {
            font-size: 14px;
            line-height: 22px;
        }
    }

    .refunds-steps {
        &__item {
            align-items: flex-start;
            gap: 10px;
        }

        &__number {
            width: 28px;
            height: 28px;
            font-size: 13px;
        }

        &__text {
            font-size: 13px;
            line-height: 20px;
            padding-top: 3px;
        }
    }

    .refunds-cta {
        padding: 24px;

        &__title {
            font-size: 20px;
            line-height: 28px;
        }

        &__description {
            font-size: 14px;
            line-height: 22px;
        }
    }

    .refund-form {
        padding: 24px;

        &__header {
            margin-bottom: 24px;
        }

        &__title {
            font-size: 20px;
            line-height: 28px;
        }

        &__description {
            font-size: 13px;
            line-height: 18px;
        }

        &__login-info {
            font-size: 13px;
        }
    }
}
scss/static-elements/refunds/refunds-t.scss:
@media screen and (min-width: 768px) and (max-width: 1439px) {
    .refunds-info {
        max-width: 100%;
    }
}

3. Modyfikacje istniejących plików HTML

partials/cart/thx.html

W pliku partials/cart/thx.html znajdź fragment generujący etykietę zgody w sekcji zgód marketingowych:
<label class="cart__tos-label tos-js" tabindex="0" role="checkbox" for="{{ consent.FieldValue }}" aria-checked="false"></label>
Usuń z niego atrybut for="{{ consent.FieldValue }}". Po zmianie linia powinna wyglądać tak:
<label class="cart__tos-label tos-js" tabindex="0" role="checkbox" aria-checked="false"></label>

partials/common/login.html

1. W pliku partials/common/login.html w kontenerze opakowującym formularz dodaj klasę login-container-popup. Zamień linię:
<div class="{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id -%} login-popup-js{% else -%} login-container {% endif -%}">
na:
<div class="{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id -%} login-popup-js login-container-popup{% else -%} login-container {% endif -%}">
2. W warunku otaczającym przycisk zamykający popup logowania usuń warunek and settings.signIn == "popup". Zamień linię:
{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id and settings.signIn == "popup" -%}
na:
{% if page.PageId != config.DefinedPages.Login.Id and page.PageId != config.DefinedPages.CustomerProfile.Id and page.PageId != config.DefinedPages.Order.Id -%}

partials/product/amount-stepper.html

W pliku partials/product/amount-stepper.html znajdź blok ustawiający zmienne dla typów complaint i return:
{% if type == 'complaint' or type == 'return' -%}
{% assign reloadClass = '' -%}
{% assign complaintOrReturn = true -%}
{% endif -%}
i dodaj w jego wnętrzu nową linię ustawiającą maksymalną ilość produktu:
{% if type == 'complaint' or type == 'return' -%}
{% assign reloadClass = '' -%}
{% assign complaintOrReturn = true -%}
{% assign max = product.Quantity | Normalize -%}
{% endif -%}

partials/order/products-partials/product-table-header.html

Na samym początku pliku partials/order/products-partials/product-table-header.html dodaj blok przypisujący flagę complaintsOrReturnsEnabled:
{% if config.Complaints.ComplaintsEnabled or config.Complaints.ReturnsEnabled -%}
{% assign complaintsOrReturnsEnabled = true -%}
{% endif -%}

partials/product/products-table.html

Przyciski reklamacji i zwrotu są wyświetlane bezpośrednio w tabeli, zamiast w rozwijanym menu. W pliku partials/product/products-table.html znajdź komórkę z opcjami:
{% if order.Status == 3 and complaintsOrReturnsEnabled and product.CanComplain == true -%}
<button class="pure-button open-dropdown-js" aria-label="{{translations.Options}}">
    <!-- TODO: ikona SVG przycisku opcji – bez zmian, jak w istniejącym pliku -->
</button>
<div class="dropdown dropdown-js hidden-js" style="bottom: auto !important;">
    {% if config.Complaints.ComplaintsEnabled == true and product.CanComplain == true -%}
    <button class="pure-button open-complaint-form-js" data-type="complaint" data-product="{{ product.Url }}">
        {{ translations.Complain }}
    </button>
    {% endif -%}
    {% if config.Complaints.ReturnsEnabled == true and product.CanReturn == true and product.IsSetElement == false -%}
    <button class="pure-button open-complaint-form-js" data-type="return" data-product="{{ product.Url }}">
        {{ translations.Return }}
    </button>
    {% endif -%}
</div>
{% endif -%}
i zastąp ją następującym fragmentem:
{% if order.Status == 3 and complaintsOrReturnsEnabled -%}
{% if config.Complaints.ComplaintsEnabled == true and product.CanComplain == true -%}
<button class="pure-button open-complaint-form-js complaint-action-btn" data-type="complaint" data-product="{{ product.Url }}">
    {{ translations.Complain }}
</button>
{% endif -%}
{% if config.Complaints.ReturnsEnabled == true and product.CanReturn == true and product.IsSetElement == false -%}
<button class="pure-button open-complaint-form-js complaint-action-btn" data-type="return" data-product="{{ product.Url }}">
    {{ translations.Return }}
</button>
{% endif -%}
{% endif -%}
Następnie w tym samym pliku znajdź zewnętrzny warunek otaczający kontenery formularzy reklamacji i zwrotu i poluzuj go (usuń warunek product.CanComplain == true). Zamień:
{% if order.Status == 3 and complaintsOrReturnsEnabled and product.CanComplain == true -%}
na:
{% if order.Status == 3 and complaintsOrReturnsEnabled -%}

partials/customer-profile/orders/order-details.html

W pliku partials/customer-profile/orders/order-details.html wykonaj poniższe zmiany. a) Bloki Opcje (zawierające klasę options submenu z przyciskami akcji zamówienia) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}, aby ukryć je dla niezalogowanych klientów dokonujących szybkiego zwrotu. Wstaw {% unless order.Restricted -%} bezpośrednio przed otwierającym <div class="options submenu">, a {% endunless -%} po jego zamykającym </div>:
{% unless order.Restricted -%}
<div class="options submenu">
    ...
</div>
{% endunless -%}
b) W kontenerze messages-container-js na początku (przed istniejącymi komunikatami typu OrderEditable) dodaj baner informujący o ukrytych danych zamówienia oraz, na końcu kontenera, baner informujący o terminie zwrotu:
{% if order.Restricted -%}
<div class="return-info-banner">
    <!-- TODO: ikona SVG informacyjna (z klasą icon) -->
    {{ translations.RestrictedOrderViewInfo }}
</div>
{% endif -%}
{% if order.Status == 3 and config.Complaints.ReturnsEnabled -%}
<div class="return-info-banner">
    <!-- TODO: ikona SVG informacyjna (z klasą icon) -->
    {{ translations.OrderReturnDeadlineInfo | Format: config.Complaints.DaysToReturn }}
</div>
{% endif -%}
c) We wszystkich miejscach wyświetlających numer telefonu klienta zamień warunki sprawdzające jedynie pusty ciąg na warunki sprawdzające również wartość null. Zamień każde wystąpienie:
{% if order.Customer.DeliveryAddress.PhoneNo != '' -%}
na:
{% if order.Customer.DeliveryAddress.PhoneNo != null and order.Customer.DeliveryAddress.PhoneNo != '' -%}
d) Analogicznie zaktualizuj warunek wyświetlania NIP-u/TIN-u w sekcji danych do faktury. Zamień:
{% elseif order.Customer.TIN != '' -%}
na:
{% elseif order.Customer.TIN != null and order.Customer.TIN != '' -%}
e) W sekcji adresu dostawy zamień otwierający warunek alternatywny {% else -%} (bezpośrednio przed kontenerem z translations.DelivAddress) na bardziej restrykcyjny:
{% elseif order.Customer.DeliveryAddress != null -%}
f) Sekcję wybranego dokumentu (ChoosenDocument) opakuj warunkiem ukrywającym ją dla zamówień typu restricted. Wstaw {% unless order.Restricted -%} przed kontenerem order-details-item z tytułem translations.ChoosenDocument oraz {% endunless -%} za jego zamykającym </div>. g) W sekcji dokumentów zamówienia dodaj do warunku sprawdzenie order.Restricted == false. Zamień:
{% if orderDocumentsSize > 0 -%}
na:
{% if orderDocumentsSize > 0 and order.Restricted == false -%}
h) W sekcji załączników zamówienia dodaj analogiczne sprawdzenie. Zamień:
{% if config.Orders.AttachmentsEnabled and orderAttachmentsSize > 0 -%}
na:
{% if config.Orders.AttachmentsEnabled and orderAttachmentsSize > 0 and order.Restricted == false -%}
i) W sekcji zamówień powiązanych zamień:
{% if order.RelatedOrders[0] -%}
na:
{% if order.RelatedOrders[0] and order.Restricted == false -%}

partials/customer-profile/complaints/complaint-form.html

W pliku partials/customer-profile/complaints/complaint-form.html wprowadź poniższe zmiany. a) W kontenerze amount-stepper-container (wewnątrz warunku {% if type != 'set-return' -%}) na samym początku dodaj nową etykietę:
<span class="amount-stepper-container__label">{{ translations.Quantity }}:</span>
b) Pod sekcją z komentarzem reklamacji/zwrotu (po zamykającym {% endif -%} z sekcji complaint-message-textarea) wewnątrz warunku {% if type != 'set-return' -%} dodaj sekcję wyboru sposobu zwrotu środków:
<div class="refund-method-wrapper">
    <div class="refund-method-wrapper__title">{{ translations.Com_RefundMethod }} <span class="required">*</span></div>
    <label class="refund-method-option">
        <input class="refund-method-option__radio refund-method-radio-js" checked="checked" name="refundMethod" type="radio" value="asPaid" />
        <span class="refund-method-option__box"></span>
        <span class="refund-method-option__label">
            {{ translations.Com_RefundAsPaid }} {% if order.Payment.Name and order.Payment.Name != '' -%} ({{ order.Payment.Name }}){% endif -%}
        </span>
    </label>
    <label class="refund-method-option">
        <input class="refund-method-option__radio refund-method-radio-js" name="refundMethod" type="radio" value="bankAccount" />
        <span class="refund-method-option__box"></span>
        <span class="refund-method-option__label">{{ translations.Com_RefundToBankAccount }}</span>
    </label>
</div>
<div class="form__input-wrapper account-number-wrapper-js hidden-js">
    <label class="form__input-info input-info-js" for="accountNumber">{{ translations.Com_BankAccountNumber }} <span class="required">*</span></label>
    <input id="accountNumber" class="form__input-value input-value-js" disabled="disabled" maxlength="50" name="accountNumber" type="text" />
    <div class="form__invalid-input validation-info-js validation-required-js hidden-js">{{ translations.FieldRequired }}</div>
</div>
c) W sekcji załączników plików zamień prosty licznik file-{{forloop.index}} na prefiks zawierający identyfikator zamówienia, numer produktu i typ formularza. Tuż przed pętlą {% for i in (1..config.Complaints.AttachmentsMaxCount) -%} dodaj nową linię:
{% capture filePrefix -%}file-{{ order.Id }}-{{ product.No }}-{{ type }}{% endcapture -%}
Następnie wewnątrz pętli zamień:
<label class="file" for="file-{{forloop.index}}">
<input id="file-{{forloop.index}}" class="add-attachement-in-complaint-js hidden-js" type="file" /></label>
na:
<label class="file" for="{{ filePrefix }}-{{ forloop.index }}">
<input id="{{ filePrefix }}-{{ forloop.index }}" class="add-attachement-in-complaint-js hidden-js" type="file" /></label>
d) Komunikat sukcesu wyświetlany po wysłaniu formularza ma być inny dla reklamacji, a inny dla zwrotu. Znajdź kontener <div class="success-message-js hidden-js"> i jego dotychczasową zawartość:
<div class="success-message-js hidden-js">
    {{ successInfo }}
</div>
zastąp:
<div class="success-message-js hidden-js">
    {% if complaint -%}
    {{ successInfo }}
    {% else -%}
    <div class="data-form__header return-success__header">
        <button class="close-button hide-container-js closing-modal-js" aria-label="{{ translations.Close }}">
            <!-- TODO: ikona SVG zamknięcia – jak w pozostałych popupach szablonu -->
        </button>
    </div>
    <div class="return-success__icon">
        <!-- TODO: ikona SVG potwierdzenia (zielony "check") -->
    </div>
    <div class="return-success__title">{{ successTitle }}</div>
    <div class="return-success__subtitle">{{ successInfo }}</div>
    {% if order.Customer.Email and order.Customer.Email != '' -%}
    <div class="return-success__email-box">
        <!-- TODO: ikona SVG informacyjna -->
        <div>
            <div>{{ translations.Com_ConfirmationSentTo }}</div>
            <strong>{{ order.Customer.Email }}</strong>
        </div>
    </div>
    {% endif -%}
    <div class="return-success__steps-title">{{ translations.Com_NextSteps }}</div>
    <ol class="return-success__steps">
        <li>{{ translations.Com_PackProducts }}</li>
        <li>{{ translations.Com_SendPackageTo }}
            {% if config.Shop.Address.Street != '' -%} {{ config.Shop.Address.Street }}{% endif -%}
            {% if config.Shop.Address.StreetNo != '' -%} {{ config.Shop.Address.StreetNo }}{% endif -%}
            {% if config.Shop.Address.UnitNo != '' -%}/{{ config.Shop.Address.UnitNo }}{% endif -%}
            {% if config.Shop.Address.ZipCode != '' or config.Shop.Address.City != '' -%}, {{ config.Shop.Address.ZipCode }} {{ config.Shop.Address.City }}{% endif -%}</li>
        <li>{{ translations.Com_RefundAfterReceive }}</li>
    </ol>
    <div class="buttons-container short">
        <button class="primary-action-button hide-container-js closing-modal-js">
            {{ translations.Close }}
        </button>
    </div>
    {% endif -%}
</div>

4. Modyfikacje pliku js/layout-customerprofile0.js

Poniższe zmiany dotyczą pliku js/layout-customerprofile0.js (jego nieskompresowanej wersji, którą po edycji należy ponownie zminifikować do layout-customerprofile0.min.js). a) W funkcji openComplaintForm wewnątrz warunku if (hiddenContainer) – tuż po linii hiddenContainer.querySelector('.success-message-js').classList.add('hidden-js'); – dodaj kod ujawniający nagłówek formularza oraz resetujący wybór sposobu zwrotu do opcji domyślnej:
const mainHeader = hiddenContainer.querySelector(':scope > .data-form__header');
if (mainHeader) {
    mainHeader.classList.remove('hidden-js');
}
hiddenContainer.classList.remove('hidden-js');

const asPaidRadio = hiddenContainer.querySelector('.refund-method-radio-js[value="asPaid"]');
if (asPaidRadio) {
    asPaidRadio.checked = true;
    $(asPaidRadio).trigger('change');
}
(Linia hiddenContainer.classList.remove('hidden-js'); już istnieje – pokazana jest dla kontekstu. Nowe są bloki const mainHeader i const asPaidRadio.) b) W funkcji sendComplaint, w bloku przygotowującym dane formularza – po pętli for (const item of dataFromHTML) dokładającej pola do fd – dodaj fragment dołączający parametr qrHash z adresu URL przy wysyłaniu zwrotu:
if (form.find('input[name="__action"]').val() === 'Order/ReturnAdd') {
    const qrHash = new URLSearchParams(globalThis.location.search).get('qrHash');
    if (qrHash) {
        fd.append('qrHash', qrHash);
    }
}
c) W tej samej funkcji sendComplaint, w callbacku success po pomyślnym wysłaniu, zamień fragment:
form.parents('.add-complaint-form-js').find('.success-message-js').removeClass('hidden-js');
na:
const container = form.parents('.add-complaint-form-js');
container.find('.success-message-js').removeClass('hidden-js');
container.children('.data-form__header').addClass('hidden-js');
d) Na samym końcu pliku js/layout-customerprofile0.js dodaj nowy handler obsługujący przełączanie sposobu zwrotu środków. Pokazuje on / ukrywa pole na numer konta bankowego:
$('body').on('change', '.refund-method-radio-js', function(e) {
    const radio = $(e.currentTarget);
    const form = radio.closest('.form-js');
    const wrapper = form.find('.account-number-wrapper-js');
    const input = wrapper.find('input[name="accountNumber"]');
    if (radio.val() === 'bankAccount' && radio.prop('checked')) {
        wrapper.removeClass('hidden-js');
        input.prop('disabled', false);
        input.prop('required', true);
    } else {
        wrapper.addClass('hidden-js');
        wrapper.find('.validation-required-js').addClass('hidden-js');
        wrapper.find('.form__input-info').removeClass('validation-error');
        input.removeClass('validation-error-js');
        input.prop('required', false);
        input.prop('disabled', true);
        input.val('');
    }
});

5. Modyfikacje plików SCSS profilu klienta

Poniższe style należy dodać do plików scss/static-elements/customer-profile/customer-profile-g.scss (wersja desktop) oraz scss/static-elements/customer-profile/customer-profile-m.scss (wersja mobile). Po zmianach pamiętaj o kompilacji – nie edytuj ręcznie wynikowych plików CSS.

Plik scss/static-elements/customer-profile/customer-profile-g.scss

a) Dla "przyklejonej" kolumny z akcjami reklamacji/zwrotu w tabeli produktów dodaj reguły wewnątrz selektora otaczającego tabelę zamówienia (tam, gdzie znajdują się style dla thead tr th):
thead tr th.open-complaint-form-container-js {
    position: sticky;
    right: 0;
    background: transparent;
    z-index: 5;

    &::before {
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        right: 0;
        width: 200px;
        background: linear-gradient(to right, rgba(255, 255, 255, 0), #fff 50%);
        pointer-events: none;
    }
}

td.complaint-actions-inline {
    white-space: nowrap;
    text-align: right;
    padding-left: 16px;
    padding-right: 8px;
    position: sticky;
    right: 0;
    background: #fff;
    z-index: 2;

    &::before {
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        left: -32px;
        width: 32px;
        background: linear-gradient(to right, rgba(255, 255, 255, 0), #fff 100%);
        pointer-events: none;
    }

    .pure-button.complaint-action-btn {
        display: inline-flex;
        background: transparent;
        border: 0;
        border-radius: 4px;
        color: $primaryColor;
        padding: 4px 8px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
        transition: background-color 150ms ease;

        &:hover,
        &:focus-visible {
            color: $primaryColor;
            background: rgba(0, 0, 0, 0.06);
        }

        & + .complaint-action-btn {
            margin-left: 8px;
        }
    }
}
b) Style hovera dla wiersza tabeli z akcjami reklamacji/zwrotu (umieść w głównym zakresie pliku):
.row {
    &:hover,
    &:focus-within,
    &.hovered-js {
        td.complaint-actions-inline {
            background: #F1DDDE;

            &::before {
                background: linear-gradient(to right, rgba(241, 221, 222, 0), #F1DDDE 100%);
            }
        }
    }

    &.set td.complaint-actions-inline {
        background: #ececec;

        &::before {
            background: linear-gradient(to right, rgba(236, 236, 236, 0), #ececec 100%);
        }
    }
}
c) Style banera informacyjnego (termin zwrotu / ukryte dane zamówienia):
.return-info-banner {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    margin: 0 0 24px 0;
    background: #E8F1F8;
    border: 1px solid #C7DCEE;
    border-radius: 5px;
    font-size: 14px;
    line-height: 20px;
    color: #2C3E50;

    .icon {
        flex-shrink: 0;
        fill: #4A90BC;
    }

    strong {
        font-weight: 600;
    }
}
d) Style sekcji wyboru sposobu zwrotu środków oraz radio-buttonów:
.refund-method-wrapper {
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin-bottom: 24px;

    &__title {
        color: $primaryColorFont;
        font-size: 14px;
        font-weight: 500;
        line-height: 20px;
    }
}

.refund-method-option {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;

    &__radio {
        display: none;

        &:checked ~ .refund-method-option__box {
            border-color: $primaryColor;

            &::after {
                content: "";
                display: block;
                width: 8px;
                height: 8px;
                border-radius: 50%;
                background: $primaryColor;
            }
        }
    }

    &__box {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 16px;
        height: 16px;
        border: 1px solid #767676;
        border-radius: 50%;
        flex-shrink: 0;
    }

    &__label {
        font-size: 14px;
        line-height: 20px;
    }
}
e) Style ekranu sukcesu po wysłaniu zwrotu (m.in. ikona, tytuł, lista kolejnych kroków):
.add-complaint-form-js .characters-length {
    margin-top: 0;
    bottom: 23px;
}

.add-complaint-form-js {
    .quantity__plus.disabled-js,
    .quantity__minus.disabled-js {
        opacity: 0.4;
    }
}

.add-complaint-form-js .data-form__header.return-success__header {
    margin-bottom: 8px;
}

.return-success {
    &__icon {
        display: flex;
        justify-content: center;
        margin-bottom: 16px;

        svg {
            fill: #2E7D32;
        }
    }

    &__title {
        text-align: center;
        font-size: 20px;
        font-weight: 600;
        line-height: 28px;
        color: $primaryColorFont;
        margin-bottom: 8px;
    }

    &__subtitle {
        text-align: center;
        font-size: 14px;
        line-height: 20px;
        color: $labelsColor;
        padding-bottom: 24px;
        border-bottom: 1px solid #E7E7E7;
        margin-bottom: 24px;
    }

    &__email-box {
        display: flex;
        align-items: flex-start;
        gap: 12px;
        padding: 12px 16px;
        background: #F0F6FC;
        border: 1px solid #D6E4F0;
        border-radius: 6px;
        margin-bottom: 24px;
        font-size: 14px;
        line-height: 20px;
        color: $primaryColorFont;

        svg {
            fill: #1976D2;
            flex-shrink: 0;
            margin-top: 2px;
        }
    }

    &__steps-title {
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
        color: $primaryColorFont;
        margin-bottom: 12px;
    }

    &__steps {
        margin: 0 0 24px;
        padding-left: 20px;
        font-size: 14px;
        line-height: 20px;
        color: $primaryColorFont;

        li {
            margin-bottom: 8px;

            &:last-child {
                margin-bottom: 0;
            }
        }
    }
}
f) Uzupełnij wnętrze selektora .file-attachements-wrapper o style dla kontenera pojedynczego załącznika:
.file-container {
    .file {
        align-items: center;
        font-weight: 400;
        color: $primaryColorFont;
        justify-content: flex-start;
    }

    .icon-js svg {
        fill: $primaryColorFont;
    }

    .clear-file-input-js {
        flex-shrink: 0;
        display: flex;
        align-items: center;

        svg {
            width: 14px;
            height: 14px;
            fill: $primaryColor;
        }
    }
}

Plik scss/static-elements/customer-profile/customer-profile-m.scss

Na końcu pliku customer-profile-m.scss dodaj reguły dopasowujące przyciski reklamacji/zwrotu do widoku mobilnego (układają się one wówczas jeden pod drugim):
.eshop__table-container {
    thead tr th.open-complaint-form-container-js::before {
        width: 100px;
    }

    td.complaint-actions-inline {
        .pure-button.complaint-action-btn {
            display: block;
            width: max-content;
            margin-left: auto;
            text-align: right;

            & + .complaint-action-btn {
                margin-left: auto;
                margin-top: 4px;
            }
        }
    }
}
Po wprowadzeniu wszystkich powyższych zmian w szablonie Rubin pamiętaj o kompilacji oraz minifikacji plików js i scss, zgodnie z artykułem dostępnym pod linkiem https://pomoc.comarchesklep.pl/artykul/kompilacja-i-minifikacja-plikow/.

Szablon Szafir

1. Tłumaczenia

W panelu administracyjnym sklepu dodaj nowe klucze tłumaczeń wymagane przez funkcjonalność szybkich zwrotów w szablonie Szafir. OrderReturnDeadlineInfo - PL: Zamówienie można zwrócić w ciągu {0} dni od daty dostawy. - EN: You can return the order within {0} days from the delivery date. - DE: Sie können die Bestellung innerhalb von {0} Tagen ab Lieferdatum zurückgeben. - FR: Vous pouvez retourner la commande dans les {0} jours suivant la date de livraison. RestrictedOrderViewInfo - PL: Wybrane dane zamówienia zostały ukryte ze względów bezpieczeństwa. Możesz zwrócić produkty bez logowania. - EN: Some order details are hidden for security reasons. You can return products without signing in. - DE: Einige Bestelldetails wurden aus Sicherheitsgründen ausgeblendet. Sie können Produkte ohne Anmeldung zurücksenden. - FR: Certaines informations de la commande ont été masquées pour des raisons de sécurité. Vous pouvez retourner des produits sans vous connecter. RefundMethod - PL: Sposób zwrotu środków - EN: Refund method - DE: Rückerstattungsmethode - FR: Méthode de remboursement RefundAsPaid - PL: Tak jak zapłacono - EN: As paid - DE: Wie bezahlt - FR: Comme payé RefundToBankAccount - PL: Na konto bankowe - EN: To bank account - DE: Auf Bankkonto - FR: Sur le compte bancaire BankAccountNumber - PL: Nr konta bankowego - EN: Bank account number - DE: Bankkontonummer - FR: Numéro de compte bancaire ReturnConfirmationTitle - PL: Gotowe! Przyjęliśmy Twoje zgłoszenie - EN: Done! We have received your request - DE: Fertig! Wir haben Ihre Anfrage erhalten - FR: Terminé! Nous avons reçu votre demande ReturnConfirmationInfo - PL: Przygotuj paczkę i odeślij ją do nas – wszystkie szczegóły znajdziesz poniżej. - EN: Prepare the package and send it back to us – all details can be found below. - DE: Bereiten Sie das Paket vor und senden Sie es an uns zurück – alle Details finden Sie unten. - FR: Préparez le colis et renvoyez-le nous – tous les détails se trouvent ci-dessous. ReturnConfirmationEmailSent - PL: Potwierdzenie zwrotu zostało wysłane na adres: - EN: Return confirmation has been sent to: - DE: Die Rücksendebestätigung wurde gesendet an: - FR: La confirmation de retour a été envoyée à: NextSteps - PL: Następne kroki - EN: Next steps - DE: Nächste Schritte - FR: Prochaines étapes ReturnStep1 - PL: Bezpiecznie zapakuj swoje produkty - EN: Safely pack your products - DE: Verpacken Sie Ihre Produkte sicher - FR: Emballez vos produits en toute sécurité ReturnStep2Address - PL: Wyślij paczkę na adres - EN: Send the package to - DE: Senden Sie das Paket an - FR: Envoyez le colis à ReturnStep3 - PL: Pieniądze zwrócimy niezwłocznie po otrzymaniu i sprawdzeniu Twojej paczki. - EN: We will refund the money promptly after receiving and checking your package. - DE: Wir erstatten das Geld umgehend nach Erhalt und Überprüfung Ihres Pakets. - FR: Nous rembourserons l'argent rapidement après réception et vérification de votre colis. ReturnInThreeSteps - PL: Zwróć towar w 3 krokach - EN: Return the product in 3 steps - DE: Geben Sie die Ware in 3 Schritten zurück - FR: Retournez la marchandise en 3 étapes ReturnWithoutReasonInfo - PL: Przysługuje Ci możliwość zwrotu bez podania przyczyny. - EN: You have the right to return the product without giving a reason. - DE: Sie haben das Recht, die Ware ohne Angabe von Gründen zurückzugeben. - FR: Vous avez le droit de retourner la marchandise sans donner de motif. OrEnterOrderNumber - PL: lub podaj numer zamówienia - EN: or enter the order number - DE: oder geben Sie die Bestellnummer ein - FR: ou saisissez le numéro de commande FillForm - PL: Wypełnij formularz - EN: Fill out the form - DE: Füllen Sie das Formular aus - FR: Remplissez le formulaire ReturnOnline - PL: zwrotu online - EN: online return - DE: Online-Rückgabe - FR: retour en ligne SendParcel - PL: Wyślij paczkę - EN: Send the parcel - DE: Paket senden - FR: Envoyer le colis SendParcelToOurAddress - PL: nadaj przesyłkę na nasz adres - EN: send the parcel to our address - DE: senden Sie das Paket an unsere Adresse - FR: envoyez le colis à notre adresse FastSimpleSecure - PL: Szybko, prosto i bezpiecznie. - EN: Fast, simple and secure. - DE: Schnell, einfach und sicher. - FR: Rapide, simple et sécurisé. ReadyForReturn - PL: Gotowy do zwrotu? - EN: Ready for return? - DE: Bereit zur Rückgabe? - FR: Prêt pour le retour ? ReadyForReturnInfo - PL: Kliknij poniżej, aby rozpocząć proces zwrotu. Przeprowadzimy Cię przez wszystkie kroki. - EN: Click below to start the return process. We will guide you through all the steps. - DE: Klicken Sie unten, um den Rückgabeprozess zu starten. Wir führen Sie durch alle Schritte. - FR: Cliquez ci-dessous pour lancer le processus de retour. Nous vous guiderons à travers toutes les étapes. StartReturn - PL: Rozpocznij zwrot - EN: Start return - DE: Rückgabe starten - FR: Commencer le retour ProductReturn - PL: Zwrot produktu - EN: Product return - DE: Produktrückgabe - FR: Retour du produit ProductReturnFormInfo - PL: Wprowadź dane zamówienia, aby zlokalizować zakup i rozpocząć proces zwrotu. Numer zamówienia znajdziesz w e-mailu z potwierdzeniem. - EN: Enter the order details to locate the purchase and start the return process. You will find the order number in the confirmation e-mail. - DE: Geben Sie die Bestelldaten ein, um den Kauf zu lokalisieren und den Rückgabeprozess zu starten. Die Bestellnummer finden Sie in der Bestätigungs-E-Mail. - FR: Saisissez les données de la commande pour localiser l'achat et démarrer le processus de retour. Vous trouverez le numéro de commande dans l'e-mail de confirmation. InvalidOrderNumber - PL: Błędny numer zamówienia. Spróbuj ponownie. - EN: Invalid order number. Please try again. - DE: Ungültige Bestellnummer. Bitte versuchen Sie es erneut. - FR: Numéro de commande incorrect. Veuillez réessayer. FindOrder - PL: Znajdź zamówienie - EN: Find order - DE: Bestellung finden - FR: Trouver la commande LoginToSeeOrdersAndReturn - PL: aby zobaczyć swoje zamówienia i dokonać zwrotu. - EN: to see your orders and make a return. - DE: um Ihre Bestellungen einzusehen und eine Rückgabe vorzunehmen. - FR: pour voir vos commandes et effectuer un retour. RefundLookupError - PL: Wystąpił błąd podczas wyszukiwania zamówienia. Spróbuj ponownie później. - EN: An error occurred while searching for the order. Please try again later. - DE: Bei der Suche nach der Bestellung ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut. - FR: Une erreur s'est produite lors de la recherche de la commande. Veuillez réessayer plus tard.

2. Nowa strona Szybkie zwroty

Funkcjonalność szybkich zwrotów wymaga utworzenia dodatkowej strony statycznej refunds. Wykonaj poniższe kroki.

Plik refunds.html w katalogu głównym szablonu

W katalogu głównym szablonu utwórz nowy plik refunds.html z następującą zawartością:
{% extends '_layout.html' %}

{% block content %}
{% include 'static-elements/refunds/refunds.html' %}
{% endblock %}

Plik static-elements/refunds/refunds.html

W folderze static-elements utwórz nowy katalog refunds, a w nim plik refunds.html:
<section class="refunds refunds-js form-js">
    <p class="refunds-header refunds-initial-view-js">{{ translations.Returns }}</p>
    <div class="refunds-intro refunds-initial-view-js">
        <div class="refunds-info">
            <p class="refunds-info-title">{{ translations.ReturnInThreeSteps }}</p>
            <p class="refunds-info-desc">{{ translations.ReturnWithoutReasonInfo }}</p>
            <ol class="refunds-steps">
                <li class="refunds-steps-item">
                    <span class="refunds-steps-number">1</span>
                    <p class="refunds-steps-text"><strong>{{ translations.SignIn }}</strong> {{ translations.OrEnterOrderNumber }}</p>
                </li>
                <li class="refunds-steps-item">
                    <span class="refunds-steps-number">2</span>
                    <p class="refunds-steps-text"><strong>{{ translations.FillForm }}</strong> {{ translations.ReturnOnline }}</p>
                </li>
                <li class="refunds-steps-item">
                    <span class="refunds-steps-number">3</span>
                    <p class="refunds-steps-text"><strong>{{ translations.SendParcel }}</strong> - {{ translations.SendParcelToOurAddress }}</p>
                </li>
            </ol>
            <p class="refunds-info-hint">{{ translations.FastSimpleSecure }}</p>
        </div>
        <div class="refunds-cta">
            <p class="refunds-cta-title">{{ translations.ReadyForReturn }}</p>
            <p class="refunds-cta-desc">{{ translations.ReadyForReturnInfo }}</p>
            {% if usr.Authenticated -%}
            <a class="refunds-cta-button" href="{{ config.DefinedPages.CustomerProfile.Url }}?tab=orders" rel="nofollow" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </a>
            {% else -%}
            <button class="refunds-cta-button start-refund-js" type="button" aria-label="{{ translations.StartReturn }}">
                {{ translations.StartReturn }}
            </button>
            {% endif -%}
        </div>
    </div>
    {% unless usr.Authenticated -%}
    <div class="refunds-form-section refund-form-view-js hidden-js">
        <div class="refunds-form">
            <p class="refunds-form-title">{{ translations.ProductReturn }}</p>
            <p class="refunds-form-desc">{{ translations.ProductReturnFormInfo }}</p>
            <div class="refund-form-js" data-cp-url="{{ config.DefinedPages.CustomerProfile.Url }}">
                <div class="message-bar-ui warning-bar-ui refund-lookup-error-js hidden-js">{{ translations.RefundLookupError }}</div>
                <div class="form__input-wrapper">
                    <label class="form__input-info form__input-info-js" for="refundOrderNumber" data-type="text">{{ translations.OrderNumber }} <span class="required-ui">*</span></label>
                    <input id="refundOrderNumber" class="form__input-value form__input-value-js" maxlength="50" name="orderNumber" required="" type="text" aria-label="{{ translations.OrderNumber }}" />
                    <span class="error-ui validation-info-js validation-required-js hidden-js">{{ translations.RequiredField }}</span>
                </div>
                <div class="form__input-wrapper">
                    <label class="form__input-info form__input-info-js" for="refundEmail" data-type="email">{{ translations.EmailAddress }} <span class="required-ui">*</span></label>
                    <input id="refundEmail" class="form__input-value form__input-value-js" autocomplete="email" maxlength="192" name="email" required="" type="email" aria-label="{{ translations.EmailAddress }}" />
                    <span class="error-ui validation-info-js validation-required-js hidden-js">{{ translations.RequiredField }}</span>
                    <span class="error-ui validation-info-js email-valid-js hidden-js">{{ translations.FillProperEmail }}</span>
                </div>
                <div class="required-fields-info-ui form__required-fields-info"><span class="required-ui">* </span>{{ translations.RequiredFields }}</div>
                <button class="refunds-form-submit refund-form-submit-js" type="button" aria-label="{{ translations.FindOrder }}">
                    {{ translations.FindOrder }}
                </button>
                <p class="refunds-form-login-info">{{ translations.HaveAccount }} <a class="refunds-form-login-link" href="{{ config.DefinedPages.Login.Url }}" rel="nofollow">{{ translations.SignIn }}</a>, {{ translations.LoginToSeeOrdersAndReturn }}</p>
            </div>
        </div>
    </div>
    {% endunless -%}
</section>

Plik js/layout0.js – kod obsługi formularza zwrotu

Na końcu pliku js/layout0.js dodaj poniższy kod odpowiedzialny za walidację i wysłanie formularza wyszukiwania zamówienia (dla niezalogowanego klienta). Po zapisaniu pliku pamiętaj o zminifikowaniu go do layout0.min.js.
const refunds = {
    findRefundOrder(orderNumber, email) {
        return $.post('', {
            __action: 'Order/QuickReturnLookup',
            orderId: orderNumber,
            email: email,
            __csrf: __CSRF
        });
    },

    showForm() {
        document.querySelectorAll('.refunds-initial-view-js').forEach((el) => el.classList.add('hidden-js'));
        document.querySelectorAll('.refund-form-view-js').forEach((el) => el.classList.remove('hidden-js'));
        document.querySelector('.refund-form-js input[name="orderNumber"]')?.focus();
    },

    clearFieldError(input) {
        input.classList.remove('validation-error-ui', 'validation-error-lq');
        input.closest('.form__input-wrapper')
            ?.querySelectorAll('.error-ui')
            .forEach((el) => el.classList.add('hidden-js'));
    },

    markFieldError(input, errorSelector) {
        input.classList.add('validation-error-ui', 'validation-error-lq');
        input.closest('.form__input-wrapper')?.querySelector(errorSelector)?.classList.remove('hidden-js');
    },

    validateForm({ orderInput, emailInput }) {
        const orderValue = orderInput.value.trim();
        const emailValue = emailInput.value.trim();
        const emailRegex = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w{2,}$/;
        let hasError = false;

        if (orderValue.length === 0) {
            refunds.markFieldError(orderInput, '.validation-required-js');
            hasError = true;
        }

        if (emailValue.length === 0) {
            refunds.markFieldError(emailInput, '.validation-required-js');
            hasError = true;
        } else if (!emailRegex.test(emailValue)) {
            refunds.markFieldError(emailInput, '.email-valid-js');
            hasError = true;
        }

        return { hasError, orderValue };
    },

    async submitForm(button) {
        const form = button.closest('.refund-form-js');
        if (!form) {
            return;
        }
        const orderInput = form.querySelector('input[name="orderNumber"]');
        const emailInput = form.querySelector('input[name="email"]');

        form.querySelectorAll('.error-ui').forEach((el) => el.classList.add('hidden-js'));
        form.querySelector('.refund-lookup-error-js')?.classList.add('hidden-js');
        form.querySelectorAll('.form__input-value').forEach((el) => {
            el.classList.remove('validation-error-ui', 'validation-error-lq');
        });

        const { hasError, orderValue } = refunds.validateForm({ orderInput, emailInput });
        if (hasError) {
            return;
        }

        button.disabled = true;
        const errorBar = form.querySelector('.refund-lookup-error-js');
        try {
            const result = await refunds.findRefundOrder(orderValue, emailInput.value.trim());
            const action = result.action;
            if (action.Redirect302) {
                globalThis.location.href = action.Redirect302;
                return;
            }
            if (errorBar) {
                errorBar.textContent = action.Message;
                errorBar.classList.remove('hidden-js');
            }
        } catch (error) {
            console.error('Refund order lookup failed.', error);
            errorBar?.classList.remove('hidden-js');
        } finally {
            button.disabled = false;
        }
    }
};

js.delegate(document.body, 'click', '.start-refund-js', () => refunds.showForm());

js.delegate(document.body, 'input', '.refund-form-js .form__input-value', function () {
    refunds.clearFieldError(this);
});

js.delegate(document.body, 'click', '.refund-form-submit-js', function (event) {
    event.preventDefault();
    refunds.submitForm(this);
});

js.delegate(document.body, 'keydown', '.refund-form-js input', function (event) {
    if (event.key !== 'Enter') {
        return;
    }
    event.preventDefault();
    this.closest('.refund-form-js')?.querySelector('.refund-form-submit-js')?.click();
});

Pliki SCSS strony Szybkie zwroty

W folderze scss/static-elements utwórz nowy katalog refunds i umieść w nim dwa pliki: refunds-g.scss (style desktop) oraz refunds-m.scss (style mobilne). scss/static-elements/refunds/refunds-g.scss:
.refunds {
    padding: 40px 110px;
    background-color: $bgColor;
    color: $primaryColorFont;

    .refunds-header {
        display: block;
        width: 100%;
        margin: 0 0 24px;
        color: $primaryColorFont;
        text-align: left;
        font-size: 32px;
        font-weight: 500;
        line-height: 42px;
        letter-spacing: 0.8px;
    }

    .refunds-intro {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 32px;
        margin-bottom: 40px;
    }

    .refunds-info {
        align-self: flex-start;
        width: 100%;
        max-width: 800px;
        display: flex;
        flex-direction: column;
        gap: 16px;
        color: $primaryColorFont;

        @media screen and (min-width: 769px) and (max-width: 1279px) {
            max-width: 100%;
        }
    }

    .refunds-info-title {
        margin: 0;
        font-size: 20px;
        font-weight: 500;
        line-height: 28px;
        letter-spacing: 0.4px;
    }

    .refunds-info-desc {
        margin: 0;
        font-size: 16px;
        font-weight: 400;
        line-height: 24px;
        letter-spacing: 0.3px;
    }

    .refunds-info-hint {
        margin: 4px 0 0;
        color: $secondaryColorFont;
        font-size: 12px;
        font-weight: 400;
        line-height: 20px;
        letter-spacing: 0.2px;
    }

    .refunds-steps {
        list-style: none;
        margin: 0;
        padding: 0;
        display: flex;
        flex-direction: column;
        gap: 12px;
    }

    .refunds-steps-item {
        display: flex;
        align-items: center;
        gap: 12px;
    }

    .refunds-steps-number {
        flex-shrink: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        border-radius: 50%;
        background-color: $formsBgColor;
        color: $primaryColor;
        font-size: 14px;
        font-weight: 600;
        line-height: 20px;
    }

    .refunds-steps-text {
        margin: 0;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        letter-spacing: 0.3px;

        strong {
            font-weight: 600;
        }
    }

    .refunds-cta {
        box-sizing: border-box;
        width: 100%;
        max-width: 578px;
        padding: 32px 40px;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 12px;
        background-color: $bgColor;
        border: 1px solid $lightBorderColor;
    }

    .refunds-cta-title {
        margin: 0;
        text-align: center;
        font-size: 22px;
        font-weight: 500;
        line-height: 30px;
        letter-spacing: 0.5px;
        color: $primaryColorFont;
    }

    .refunds-cta-desc {
        margin: 0;
        text-align: center;
        color: $secondaryColorFont;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        letter-spacing: 0.3px;
    }

    .refunds-cta-button,
    .refunds-form-submit {
        display: inline-block;
        width: 100%;
        margin-top: 8px;
        padding: 12px 16px;
        background: $btnSolidBgColor;
        color: $btnSolidTextColor;
        border: 1px solid $btnSolidBgColor;
        font-size: 14px;
        font-weight: 500;
        line-height: 20px;
        text-align: center;
        text-decoration: none;
        cursor: pointer;
        transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;

        &:hover,
        &:focus {
            background: $btnSolidHoverBgColor;
            color: $btnSolidHoverTextColor;
            border-color: $btnSolidHoverBgColor;
        }

        &[disabled],
        &[disabled]:hover {
            background: $btnDisabledBg;
            border-color: $btnDisabledFont;
            color: $btnDisabledFont;
            cursor: default;
        }
    }

    .refunds-form-section {
        display: flex;
        justify-content: center;
        width: 100%;
        margin-top: 32px;
        margin-bottom: 40px;
    }

    .refunds-form {
        box-sizing: border-box;
        width: 100%;
        max-width: 578px;
        padding: 32px 40px;
        background-color: $bgColor;
        border: 1px solid $lightBorderColor;
    }

    .refunds-form-title {
        margin: 0 0 8px;
        font-size: 22px;
        font-weight: 500;
        line-height: 30px;
        letter-spacing: 0.5px;
        color: $primaryColorFont;
    }

    .refunds-form-desc {
        margin: 0 0 20px;
        color: $secondaryColorFont;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
        letter-spacing: 0.3px;
    }

    .refund-form-js {
        display: flex;
        flex-direction: column;

        .form__input-wrapper {
            position: relative;
            margin-bottom: 16px;

            .form__input-info {
                display: block;
                margin: 0 0 4px;
                color: $primaryColorFont;
                font-size: 13px;
                font-weight: 400;
                line-height: 18px;
            }

            input {
                width: 100%;
                height: 36px;
                margin: 0;
                padding: 0 10px;
                box-sizing: border-box;
                border: 1px solid $lightBorderColor;
                font-size: 14px;

                &::placeholder {
                    font-size: 14px;
                }

                &.validation-error-ui,
                &.validation-error-lq {
                    border-color: $dangerColor;
                    color: $dangerColor;
                }
            }

            .error-ui {
                position: static;
                display: block;
                margin: 4px 0 0;
                padding: 0;
                text-align: left;
                color: $dangerColor;
                font-size: 12px;
                font-weight: 400;
                line-height: 16px;
            }
        }

        .form__required-fields-info {
            margin: 4px 0 16px;
            color: $primaryColorFont;
            font-size: 12px;
            font-weight: 300;
            line-height: 18px;
        }
    }

    .refunds-form-login-info {
        margin: 12px 0 0;
        text-align: center;
        color: $primaryColorFont;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
    }

    .refunds-form-login-link {
        color: $primaryColor;
        font-weight: 600;
        cursor: pointer;
        text-decoration: none;

        &:hover {
            text-decoration: underline;
        }
    }
}
scss/static-elements/refunds/refunds-m.scss:
@media screen and (max-width: 768px) {
    .refunds {
        padding: 20px 16px;

        .refunds-header {
            font-size: 24px;
            line-height: 32px;
            margin-bottom: 16px;
        }

        .refunds-intro {
            gap: 24px;
            margin-bottom: 24px;
        }

        .refunds-info {
            max-width: 100%;
            gap: 12px;
        }

        .refunds-info-title {
            font-size: 18px;
            line-height: 24px;
        }

        .refunds-info-desc {
            font-size: 14px;
            line-height: 22px;
        }

        .refunds-steps-item {
            align-items: flex-start;
            gap: 10px;
        }

        .refunds-steps-number {
            width: 28px;
            height: 28px;
            font-size: 13px;
        }

        .refunds-steps-text {
            font-size: 13px;
            line-height: 20px;
            padding-top: 3px;
        }

        .refunds-cta {
            padding: 24px;
        }

        .refunds-cta-title {
            font-size: 20px;
            line-height: 28px;
        }

        .refunds-form-section {
            margin-top: 20px;
            margin-bottom: 24px;
        }

        .refunds-form {
            padding: 24px;
            border: none;
        }

        .refunds-form-title {
            font-size: 20px;
            line-height: 28px;
        }

        .refunds-form-desc {
            margin-bottom: 16px;
        }

        .refunds-form-login-info {
            font-size: 13px;
        }
    }
}

3. Modyfikacje istniejących plików HTML

partials/customer-profile/orders/order-details.html

W pliku partials/customer-profile/orders/order-details.html wykonaj poniższe zmiany. a) Blok z przyciskami akcji nawigacji zamówienia (zawierający {% if order.EditingAllowed -%}, opcje anulowania, edycji, ponowienia, druku itp.) opakuj warunkiem ukrywającym go dla zamówień typu restricted. Bezpośrednio po linii z elementem <li class="active-ui only-text-ui ...">...</li> wstaw:
{% unless order.Restricted -%}
a tuż przed zamykającym znacznikiem </ul> tej samej nawigacji dodaj:
{% endunless -%}
b) Na początku kontenera messages-container-lq messages-container-ui (zaraz po jego otwarciu) dodaj baner informujący o ukrytych danych zamówienia:
{% if order.Restricted -%}
<div class="message-bar-ui no-margin-ui">
    <i class="not-clickable-ui ti-info-alt"></i>
    {{ translations.RestrictedOrderViewInfo }}
</div>
{% endif -%}
c) Na końcu tego samego kontenera (przed zamykającym </div>) dodaj baner informujący o terminie zwrotu wraz z przypisaniem flagi complaintsOrReturnsEnabled:
{% if config.Complaints.ComplaintsEnabled or config.Complaints.ReturnsEnabled -%}
{% assign complaintsOrReturnsEnabled = true -%}
{% endif -%}

{% if order.Status == 3 and complaintsOrReturnsEnabled -%}
<div class="message-bar-ui no-margin-ui">
    <i class="not-clickable-ui ti-info-alt"></i>
    {{translations.OrderReturnDeadlineInfo | Format: config.Complaints.DaysToReturn}}
</div>
{% endif -%}
d) Blok z przyciskami akcji wewnątrz info-container-js (zawierający przyciski order.CanCancel, edycji, ponowienia zakupu itd.) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}. Wstaw {% unless order.Restricted -%} bezpośrednio przed pierwszym {% if order.CanCancel -%}, a {% endunless -%} po zamykającym warunku odpowiedzialnym za popup potwierdzenia ({% include 'partials/common/confirmation-popup.html' with 0 -%}). e) W sekcji wyświetlającej dokumenty zamówienia zamień:
{% if order.Documents %}
na:
{% if order.Documents and order.Restricted == false %}
f) We wszystkich miejscach wyświetlających numer telefonu klienta zamień warunki sprawdzające jedynie pusty ciąg na warunki sprawdzające również wartość null. Zamień każde wystąpienie:
{% if order.Customer.DeliveryAddress.PhoneNo != '' -%}
na:
{% if order.Customer.DeliveryAddress.PhoneNo != null and order.Customer.DeliveryAddress.PhoneNo != '' -%}
g) Każdą sekcję z tytułem translations.ChoosenDocument opakuj warunkiem ukrywającym ją dla zamówień restricted. Wstaw {% unless order.Restricted -%} bezpośrednio przed <div class="name-ui mt20-ui">{{ translations.ChoosenDocument }}</div> oraz {% endunless -%} po jej zamykającym </div>. h) W sekcji wyświetlającej alternatywny adres dostawy zamień warunek {% else -%} (bezpośrednio przed order-info-item-ui z translations.DelivAddress) na bardziej restrykcyjny:
{% elseif order.Customer.DeliveryAddress != null -%}
i) W sekcji danych do faktury zamień warunek wyświetlania NIP-u/TIN-u. Zamień:
{% elseif order.Customer.TIN != '' -%}
na:
{% elseif order.Customer.TIN != null and order.Customer.TIN != '' -%}
j) W sekcji załączników zamówienia (kontener attachements-ui remarks-ui) zamień warunek otaczający. Zamień:
{% if config.Orders.AttachmentsEnabled -%}
na:
{% if config.Orders.AttachmentsEnabled and order.Restricted == false -%}
k) W sekcji zamówień powiązanych (kontener remarks-ui eshop-order-ui) zamień:
{% if order.RelatedOrders -%}
na:
{% if order.RelatedOrders and order.Restricted == false -%}

partials/customer-profile/complaints/complaint-form.html

W pliku partials/customer-profile/complaints/complaint-form.html wprowadź poniższe zmiany. a) W kontenerze amount-stepper-container-ui amount-stepper-container-lq (wewnątrz warunku {% if type != 'set-return' -%}) na samym początku dodaj etykietę widoczną tylko dla zwrotów:
{% unless complaint -%}
<span class="amount-stepper-label-ui">{{ translations.Quantity }}:</span>
{% endunless -%}
b) Bezpośrednio po zamknięciu kontenera amount-stepper-container-ui (po jego </div> i odpowiadającym {% endif -%}) dodaj sekcję wyboru sposobu zwrotu środków – widoczną tylko w formularzu zwrotu:
{% unless complaint -%}
<div class="refund-method-container-ui refund-method-container-js">
    <label class="label-ui" for="refundMethod">{{ translations.RefundMethod }} <span class="required-ui">*</span></label>
    <div>
        <span class="select-background-ui">
            <select id="refundMethod" class="refund-method-select-js" name="refundMethod" aria-label="{{ translations.RefundMethod }}">
                <option selected="selected" value="original">{{ translations.RefundAsPaid }} {% if order.Payment.Name and order.Payment.Name != "" -%} ({{ order.Payment.Name }}){% endif -%}</option>
                <option value="bank">{{ translations.RefundToBankAccount }}</option>
            </select>
        </span>
        <i class="ti-angle-down select-arrow-ui"></i>
    </div>
    <div class="bank-account-container-ui bank-account-container-js hidden-js">
        <label class="label-ui" for="bankAccountNumber">{{ translations.BankAccountNumber }} <span class="required-ui">*</span></label>
        <div>
            <input id="bankAccountNumber" disabled="disabled" name="bankAccountNumber" type="text" placeholder="{{ translations.BankAccountNumber }}" aria-label="{{ translations.BankAccountNumber }}" />
            <span class="error-ui validation-info-js validation-required-js hidden-js">{{ translations.RequiredField }}</span>
        </div>
    </div>
</div>
{% endunless -%}
c) Komunikat sukcesu wyświetlany po wysłaniu formularza ma być inny dla reklamacji, a inny dla zwrotu. Znajdź kontener <div class="success-message-js hidden-js"> wraz z jego dotychczasową zawartością (komunikat ComplaintAdded + successInfo):
<div class="success-message-js hidden-js">
    <div class="complaint-added-ui">
        <i class="va-mid-ui ti-check"></i>
        <span class="va-mid-ui line-height-1-ui">
            {{ translations.ComplaintAdded }}
        </span>
    </div>
    <div class="info-ui">{{ successInfo }}</div>
</div>
i zastąp go nową, rozszerzoną wersją z dwoma wariantami (reklamacja / zwrot):
<div class="success-message-js hidden-js">
    {% if complaint -%}
    <div class="complaint-added-ui">
        <i class="va-mid-ui ti-check"></i>
        <span class="va-mid-ui line-height-1-ui">
            {{ translations.ComplaintAdded }}
        </span>
    </div>
    <div class="info-ui">{{ successInfo }}</div>
    {% else -%}
    <div class="return-success-popup-ui">
        <div class="return-success-icon-ui">
            <i class="ti-check"></i>
        </div>
        <div class="return-success-title-ui">{{ translations.ReturnConfirmationTitle }}</div>
        <div class="return-success-desc-ui">{{ translations.ReturnConfirmationInfo }}</div>
        {% if order.Customer.Email and order.Customer.Email != "" -%}
        <div class="return-success-email-info-ui">
            <i class="ti-info-alt"></i>
            {{ translations.ReturnConfirmationEmailSent }} <strong>{{ order.Customer.Email }}</strong>
        </div>
        {% endif -%}
        <div class="return-success-steps-title-ui">{{ translations.NextSteps }}</div>
        <ol class="return-success-steps-ui">
            <li>{{ translations.ReturnStep1 }}</li>
            <li>{{ translations.ReturnStep2Address }}: {{ config.Shop.Address.Street }} {{ config.Shop.Address.StreetNo }}{% if config.Shop.Address.UnitNo and config.Shop.Address.UnitNo != "" -%}/{{ config.Shop.Address.UnitNo }}{% endif -%}, {{ config.Shop.Address.ZipCode }} {{ config.Shop.Address.City }}</li>
            <li>{{ translations.ReturnStep3 }}</li>
        </ol>
        <div class="return-success-actions-ui">
            <button class="btn-ui return-success-close-ui hide-container-js closing-modal-js" aria-label="{{ translations.Close }}">
                {{ translations.Close }}
            </button>
        </div>
    </div>
    {% endif -%}
</div>

4. Modyfikacje pliku js/init-ui2.js

Poniższe zmiany dotyczą pliku js/init-ui2.js (po edycji pamiętaj o zminifikowaniu go do init-ui2.min.js). a) Tuż po linii rejestrującej handler openComplaintForm:
js.delegate(document.body, 'click', '.open-complaint-form-js', openComplaintForm);
dodaj poniższy handler obsługujący przełączanie sposobu zwrotu środków – pokazuje on / ukrywa pole na numer konta bankowego:
js.delegate(document.body, 'change', '.refund-method-select-js', function() {
    const container = js.parents(this, 'refund-method-container-js');
    if(!container) return;
    const bankWrapper = container.getElementsByClassName('bank-account-container-js')[0];
    if(!bankWrapper) return;
    const bankInput = bankWrapper.querySelector('input[name="bankAccountNumber"]');
    const validationMsg = bankWrapper.getElementsByClassName('validation-required-js')[0];
    if(this.value === 'bank') {
        bankWrapper.classList.remove('hidden-js');
        if(bankInput) {
            bankInput.disabled = false;
            bankInput.required = true;
        }
    } else {
        bankWrapper.classList.add('hidden-js');
        if(bankInput) {
            bankInput.disabled = true;
            bankInput.required = false;
            bankInput.value = '';
            bankInput.classList.remove('validation-error-lq', 'validation-error-ui');
        }
        if(validationMsg) validationMsg.classList.add('hidden-js');
    }
});
b) W funkcji sendComplaint, bezpośrednio po pętli for (var i=0; i<dataFromHTML.length; i++) dokładającej pola do fd, dodaj fragment dołączający parametr qrHash z adresu URL przy wysyłaniu zwrotu:
if (form.find('input[name="__action"]').val() === 'Order/ReturnAdd') {
    var qrHash = new URLSearchParams(globalThis.location.search).get('qrHash');
    if (qrHash) {
        fd.append('qrHash', qrHash);
    }
}

5. Modyfikacje pliku scss/globals/_globals2.scss

W pliku scss/globals/_globals2.scss wewnątrz selektora opakowującego (tego, który zawiera m.in. .note-ui) dodaj poniższe reguły. Po zmianach pamiętaj o kompilacji SCSS – nie edytuj ręcznie wynikowych plików CSS. a) Style etykiety ilości oraz kontenera wyboru sposobu zwrotu środków (wstaw w sąsiedztwie istniejących reguł sekcji formularza reklamacji/zwrotu):
.amount-stepper-label-ui {
    margin-right: 10px;
    vertical-align: middle;
}

.refund-method-container-ui {
    margin-bottom: 20px;

    .bank-account-container-ui {
        margin-top: 10px;

        input {
            width: 100%;
        }
    }
}
b) Style ekranu sukcesu po wysłaniu zwrotu (ikona, tytuł, lista kolejnych kroków, sekcja z e-mailem i przyciskiem zamknięcia):
.return-success-popup-ui {
    padding: 30px 20px 20px;

    .return-success-icon-ui {
        width: 60px;
        height: 60px;
        border-radius: 50%;
        border: 2px solid #68a204;
        margin: 0 auto 20px;
        display: flex;
        align-items: center;
        justify-content: center;

        i {
            color: #68a204;
            font-size: 26px;
        }
    }

    .return-success-title-ui {
        font-size: 18px;
        font-weight: 500;
        text-align: center;
        margin-bottom: 10px;
    }

    .return-success-desc-ui {
        font-size: 14px;
        color: $primaryColorFont;
        text-align: center;
        margin-bottom: 20px;
    }

    .return-success-email-info-ui {
        background-color: $bgColor;
        border: 1px solid $lightBorderColor;
        padding: 12px;
        border-radius: 4px;
        font-size: 14px;
        margin-bottom: 20px;
        display: flex;
        align-items: flex-start;

        i {
            margin-right: 10px;
            color: $primaryColorFont;
            font-size: 16px;
            line-height: 1.4;
        }

        strong {
            display: block;
        }
    }

    .return-success-steps-title-ui {
        font-weight: 500;
        margin-bottom: 10px;
    }

    .return-success-steps-ui {
        padding-left: 20px;
        margin: 0 0 20px;
        font-size: 14px;

        li {
            margin-bottom: 8px;
            padding-left: 5px;
        }
    }

    .return-success-actions-ui {
        border-top: 1px solid $lightBorderColor;
        padding-top: 15px;
        text-align: right;

        .return-success-close-ui {
            padding: 10px 30px;
        }
    }
}
Po wprowadzeniu wszystkich powyższych zmian w szablonie Szafir pamiętaj o kompilacji oraz minifikacji plików js i scss, zgodnie z artykułem dostępnym pod linkiem https://pomoc.comarchesklep.pl/artykul/kompilacja-i-minifikacja-plikow/.

Szablon Topaz / One Page Shop

Zmiany opisane poniżej dotyczą szablonu Topaz. Szablon One Page Shop ma praktycznie identyczną strukturę – wszystkie modyfikacje dotyczą tych samych plików i mają tę samą zawartość. Wystarczy zastosować poniższą instrukcję w plikach szablonu OPS pod tymi samymi ścieżkami.

1. Tłumaczenia

W panelu administracyjnym sklepu dodaj nowe klucze tłumaczeń wymagane przez funkcjonalność szybkich zwrotów w szablonie Topaz / OPS. RestrictedOrderViewInfo - PL: Wybrane dane zamówienia zostały ukryte ze względów bezpieczeństwa. Możesz zwrócić produkty bez logowania. - EN: Some order details are hidden for security reasons. You can return products without signing in. - DE: Einige Bestelldetails wurden aus Sicherheitsgründen ausgeblendet. Sie können Produkte ohne Anmeldung zurücksenden. - FR: Certaines informations de la commande ont été masquées pour des raisons de sécurité. Vous pouvez retourner des produits sans vous connecter. Prf_ReturnPeriodInfo - PL: Zamówienie można zwrócić w ciągu {0} dni od daty dostawy. - EN: The order can be returned within {0} days from the delivery date. - DE: Die Bestellung kann innerhalb von {0} Tagen ab dem Lieferdatum zurückgegeben werden. - FR: La commande peut être retournée dans un délai de {0} jours à compter de la date de livraison. ComplaintSuccessTitle - PL: Gotowe! Przyjęliśmy Twoje zgłoszenie - EN: Done! We have received your request - DE: Fertig! Wir haben Ihre Meldung erhalten - FR: C'est fait ! Nous avons reçu votre demande ComplaintSuccessDescription - PL: Przygotuj paczkę i odeślij ją do nas – wszystkie szczegóły znajdziesz poniżej. - EN: Prepare the parcel and send it back to us – you will find all the details below. - DE: Bereiten Sie das Paket vor und senden Sie es an uns zurück – alle Details finden Sie unten. - FR: Préparez le colis et renvoyez-le-nous – vous trouverez tous les détails ci-dessous. ComplaintSuccessConfirmationSent - PL: Potwierdzenie zwrotu zostało wysłane na adres: - EN: The return confirmation has been sent to: - DE: Die Rückgabebestätigung wurde an folgende Adresse gesendet: - FR: La confirmation de retour a été envoyée à : ComplaintSuccessStepsTitle - PL: Następne kroki - EN: Next steps - DE: Nächste Schritte - FR: Étapes suivantes ComplaintSuccessStep1 - PL: Bezpiecznie zapakuj swoje produkty - EN: Pack your products securely - DE: Verpacken Sie Ihre Produkte sicher - FR: Emballez vos produits en toute sécurité ComplaintSuccessStep2 - PL: Wyślij paczkę na adres: - EN: Send the parcel to: - DE: Senden Sie das Paket an folgende Adresse: - FR: Envoyez le colis à l'adresse : ComplaintSuccessStep3 - PL: Pieniądze zwrócimy niezwłocznie po otrzymaniu i sprawdzeniu Twojej paczki. - EN: We will refund the money immediately after receiving and inspecting your parcel. - DE: Wir erstatten den Betrag unverzüglich nach Erhalt und Prüfung Ihres Pakets. - FR: Nous rembourserons l'argent immédiatement après réception et vérification de votre colis. ReturnInThreeSteps - PL: Zwróć towar w 3 krokach - EN: Return the product in 3 steps - DE: Geben Sie die Ware in 3 Schritten zurück - FR: Retournez la marchandise en 3 étapes ReturnWithoutReasonInfo - PL: Przysługuje Ci możliwość zwrotu bez podania przyczyny. - EN: You have the right to return the product without giving a reason. - DE: Sie haben das Recht, die Ware ohne Angabe von Gründen zurückzugeben. - FR: Vous avez le droit de retourner la marchandise sans donner de motif. OrEnterOrderNumber - PL: lub podaj numer zamówienia - EN: or enter the order number - DE: oder geben Sie die Bestellnummer ein - FR: ou entrez le numéro de commande FillForm - PL: Wypełnij formularz - EN: Fill out the form - DE: Füllen Sie das Formular aus - FR: Remplissez le formulaire ReturnOnline - PL: zwrotu online - EN: online return - DE: Online-Rückgabe - FR: retour en ligne SendParcel - PL: Wyślij paczkę - EN: Send the parcel - DE: Senden Sie das Paket - FR: Envoyez le colis SendParcelToOurAddress - PL: nadaj przesyłkę na nasz adres - EN: send the parcel to our address - DE: senden Sie das Paket an unsere Adresse - FR: envoyez le colis à notre adresse FastSimpleSecure - PL: Szybko, prosto i bezpiecznie. - EN: Fast, simple and secure. - DE: Schnell, einfach und sicher. - FR: Rapide, simple et sûr. ReadyForReturn - PL: Gotowy do zwrotu? - EN: Ready for return? - DE: Bereit zur Rückgabe? - FR: Prêt pour le retour ? ReadyForReturnInfo - PL: Kliknij poniżej, aby rozpocząć proces zwrotu. Przeprowadzimy Cię przez wszystkie kroki. - EN: Click below to start the return process. We will guide you through all the steps. - DE: Klicken Sie unten, um den Rückgabeprozess zu starten. Wir führen Sie durch alle Schritte. - FR: Cliquez ci-dessous pour commencer le processus de retour. Nous vous guiderons à chaque étape. StartReturn - PL: Rozpocznij zwrot - EN: Start return - DE: Rückgabe starten - FR: Commencer le retour ProductReturn - PL: Zwrot produktu - EN: Product return - DE: Produktrückgabe - FR: Retour du produit ProductReturnFormInfo - PL: Wprowadź dane zamówienia, aby zlokalizować zakup i rozpocząć proces zwrotu. Numer zamówienia znajdziesz w e-mailu z potwierdzeniem. - EN: Enter the order details to locate the purchase and start the return process. You will find the order number in the confirmation e-mail. - DE: Geben Sie die Bestelldaten ein, um den Kauf zu lokalisieren und den Rückgabeprozess zu starten. Die Bestellnummer finden Sie in der Bestätigungs-E-Mail. - FR: Saisissez les données de la commande pour localiser l'achat et démarrer le processus de retour. Vous trouverez le numéro de commande dans l'e-mail de confirmation. FindOrder - PL: Znajdź zamówienie - EN: Find order - DE: Bestellung finden - FR: Trouver la commande RefundLookupError - PL: Wystąpił błąd podczas wyszukiwania zamówienia. Spróbuj ponownie później. - EN: An error occurred while searching for the order. Please try again later. - DE: Fehler beim Suchen nach der Bestellung. Versuchen Sie es später erneut. - FR: Une erreur s'est produite lors de la recherche de la commande. Veuillez réessayer plus tard. LoginToSeeOrdersAndReturn - PL: aby zobaczyć swoje zamówienia i dokonać zwrotu. - EN: to see your orders and make a return. - DE: um Ihre Bestellungen zu sehen und eine Rückgabe zu machen. - FR: pour voir vos commandes et faire un retour. InvalidEmail - PL: Nieprawidłowy adres e-mail - EN: Invalid e-mail address - DE: Ungültige E-Mail-Adresse - FR: L'adresse e-mail est incorrecte. RefundMethod - PL: Sposób zwrotu środków - EN: Refund method - DE: Rückerstattungsmethode - FR: Mode de remboursement RefundAsPaid - PL: Zwrot na sposób płatności - EN: Refund to the original payment method - DE: Rückerstattung auf die ursprüngliche Zahlungsmethode - FR: Remboursement sur le mode de paiement initial RefundToBankAccount - PL: Zwrot na konto bankowe - EN: Refund to bank account - DE: Rückerstattung auf das Bankkonto - FR: Remboursement sur un compte bancaire

2. Nowa strona Szybkie zwroty

Funkcja szybkich zwrotów wymaga utworzenia dodatkowej strony statycznej refunds. Wykonaj poniższe kroki.

Plik refunds.html w katalogu głównym szablonu

W katalogu głównym szablonu utwórz nowy plik refunds.html z następującą zawartością:
{% extends '_layout.html' -%}
{% block pageContent -%}
{% include 'static-elements/refunds/refunds.html' -%}
{% endblock -%}

Plik static-elements/refunds/refunds.html

W folderze static-elements utwórz nowy katalog refunds, a w nim plik refunds.html:
{% include 'partials/common/breadcrumbs.html' -%}

<div class="container my-5 refunds-page-wrapper">

    <!-- Nagłówek główny -->
    <div class="text-center mb-5">
        <h1 class="mb-3">{{ translations.ReturnInThreeSteps }}</h1>
        <p class="lead text-muted">{{ translations.ReturnWithoutReasonInfo }}</p>
    </div>

    <!-- Sekcja 3 kroków (Siatka 3-kolumnowa) -->
    <div class="row text-center mb-5">
        <div class="col-md-4 mb-4">
            <div class="p-4 border rounded bg-light h-100">
                <h3 class="h5">1. {{ translations.Log_Login }}</h3>
                <p class="mb-0">{{ translations.OrEnterOrderNumber }}</p>
            </div>
        </div>
        <div class="col-md-4 mb-4">
            <div class="p-4 border rounded bg-light h-100">
                <h3 class="h5">2. {{ translations.FillForm }}</h3>
                <p class="mb-0">{{ translations.ReturnOnline }}</p>
            </div>
        </div>
        <div class="col-md-4 mb-4">
            <div class="p-4 border rounded bg-light h-100">
                <h3 class="h5">3. {{ translations.SendParcel }}</h3>
                <p class="mb-0">{{ translations.SendParcelToOurAddress }}</p>
            </div>
        </div>
    </div>

    <!-- Wyróżniony tekst -->
    <div class="text-center mb-5">
        <h2 class="text-success h3">{{ translations.FastSimpleSecure }}</h2>
    </div>

    <!-- Sekcja gotowości do zwrotu (Call to Action) -->
    <div class="text-center p-5 border rounded mb-5">
        <h2 class="h3">{{ translations.ReadyForReturn }}</h2>
        <p>{{ translations.ReadyForReturnInfo }}</p>

        <div class="mt-4">
            {% if customer.Authenticated -%}
                <a href="/Return/List" class="btn btn-primary btn-lg">{{ translations.StartReturn }}</a>
            {% else -%}
                <a href="/Return/List" class="btn btn-primary btn-lg">{{ translations.StartReturn }}</a>
            {% endif -%}
        </div>
    </div>

    <!-- Wyszukiwanie zamówienia dla niezalogowanych -->
    <div class="row justify-content-center mb-5">
        <div class="col-md-6 col-lg-5">
            <div class="text-center mb-4">
                <h3 class="h4">{{ translations.ProductReturn }}</h3>
                <p class="text-muted">{{ translations.ProductReturnFormInfo }}</p>
            </div>

            <form action="/Return/FindOrder" method="POST" class="border p-4 rounded bg-white">
                <div class="form-group mb-3">
                    <label class="font-weight-bold">{{ translations.Com_OrderNumber }}</label>
                    <input type="text" class="form-control" name="OrderNumber" required>
                </div>
                <div class="form-group mb-4">
                    <label class="font-weight-bold">{{ translations.EmailAddress }}</label>
                    <input type="email" class="form-control" name="Email" required>
                </div>
                <button type="submit" class="btn btn-dark w-100 btn-lg">{{ translations.FindOrder }}</button>
            </form>
        </div>
    </div>

    <!-- Zachęta do logowania dla niezalogowanych (Gości) -->
    {% if customer.Authenticated == false -%}
        <div class="text-center py-4 mt-4 border-top">
            <h4 class="h5">{{ translations.Reg_HaveAcc }}</h4>
            <p>{{ translations.LoginToSeeOrdersAndReturn }}</p>
            <!-- W Topaz przycisk logowania często otwiera popup ze zdefiniowaną klasą js-login-popup-trigger -->
            <button class="btn btn-outline-primary js-login-popup-trigger">{{ translations.Log_Login }}</button>
        </div>
        {% include 'partials/common/login-register-popup.html' -%}
    {% endif -%}

</div>

<!-- Globalny komponent Newslettera -->
{% if settings.newsletterOnFunctionalPages == 'yes' -%}
    {% include 'partials/newsletter-global.html' -%}
{% endif -%}

Pliki SCSS strony Szybkie zwroty

W folderze scss/static-elements utwórz nowy katalog refunds, a w nim trzy pliki: refunds-g.scss (style ogólne), refunds-d.scss (desktop) oraz refunds-m.scss (mobile). scss/static-elements/refunds/refunds-g.scss:
.refunds-container {
    box-sizing: border-box;
    margin: 0 auto;
    color: $primaryFontColor;
    background-color: $primaryPageBg;

    .refunds-view {
        display: flex;
        flex-direction: column;
        align-items: center;

        &.hidden-js {
            display: none;
        }
    }

    .refunds-intro {
        width: 100%;
        align-self: stretch;

        &__heading {
            margin: 0 0 16px;
            font-size: $mediumFontSize;
            font-weight: 600;
            line-height: 1.4;
            color: $primaryFontColor;
        }

        &__lead {
            margin: 0 0 16px;
            font-size: 16px;
            font-weight: 500;
            line-height: 1.5;
            color: $primaryFontColor;
        }

        &__hint {
            margin: 16px 0 0;
            font-size: $extraSmallFontSize;
            color: $secondaryFontColor;
        }
    }

    .refunds-steps {
        list-style: none;
        counter-reset: refund-step;
        margin: 0;
        padding: 0;
        display: flex;
        flex-direction: column;
        gap: 8px;

        &__item {
            counter-increment: refund-step;
            display: flex;
            align-items: center;
            gap: 12px;

            &::before {
                content: counter(refund-step);
                flex: 0 0 auto;
                width: 32px;
                height: 32px;
                border-radius: 50%;
                background-color: $primaryBtnBg;
                color: $primaryBtnFontColor;
                font-weight: 600;
                font-size: $smallFontSize;
                line-height: 1;
                display: inline-flex;
                align-items: center;
                justify-content: center;
            }
        }

        &__text {
            font-size: $smallFontSize;
            line-height: 1.5;
            color: $primaryFontColor;

            strong {
                font-weight: 600;
            }
        }
    }

    .refunds-card,
    .refunds-lookup {
        box-sizing: border-box;
        width: 100%;
        background-color: $primaryPageBg;
        border: 1px solid $borderColor;
        border-radius: 8px;
        display: flex;
        flex-direction: column;
        margin-left: auto;
        margin-right: auto;
    }

    .refunds-card {
        align-items: center;
        text-align: center;
        gap: 12px;

        &__heading {
            margin: 0;
            font-size: $bigFontSize;
            font-weight: 600;
            line-height: 1.3;
            color: $primaryFontColor;
        }

        &__text {
            margin: 0;
            font-size: 16px;
            line-height: 1.5;
            color: $secondaryFontColor;
        }

        &__btn {
            width: 100%;
            margin-top: 12px;
        }
    }

    .refund-form-js {
        .form__invalid-input {
            margin: 4px 0 0;
            font-size: $extraSmallFontSize;
            line-height: 16px;
            color: $messageErrorColor;
        }
    }

    .refunds-lookup {
        gap: 16px;

        &__heading {
            margin: 0;
            font-size: $bigFontSize;
            font-weight: 600;
            line-height: 1.3;
            color: $primaryFontColor;
        }

        &__lead {
            margin: 0;
            font-size: $smallFontSize;
            line-height: 1.5;
            color: $secondaryFontColor;
        }

        &__loginPrompt {
            margin: 8px 0 0;
            font-size: $smallFontSize;
            color: $primaryFontColor;
        }

        &__loginLink {
            color: $linkFontColor;
            font-weight: 600;
            text-decoration: underline;

            &:hover,
            &:focus {
                text-decoration: none;
            }
        }

        &__error {
            margin: 0;
            font-size: $smallFontSize;
            color: $messageErrorColor;
        }
    }
}

.loginRegister--login-only {
    .loginRegisterTabsContainer {
        display: none;
    }

    .registrationForm-js {
        display: none;
    }
}
scss/static-elements/refunds/refunds-d.scss:
@media screen and (min-width: 769px) {
    .refunds-container {
        max-width: 1400px;
        padding-top: 32px;
        padding-bottom: 64px;

        .refunds-view {
            gap: 32px;
        }

        .refunds-intro {
            &__heading {
                font-size: 20px;
            }

            &__lead {
                margin-bottom: 24px;
            }
        }

        .refunds-card,
        .refunds-lookup {
            max-width: 578px;
        }

        .refunds-card {
            padding: 40px;
        }

        .refunds-lookup {
            padding: 32px;
        }
    }
}
scss/static-elements/refunds/refunds-m.scss:
@media screen and (max-width: 768px) {
    .refunds-container {
        padding: 16px 3% 40px;

        .refunds-view {
            gap: 24px;
        }

        .refunds-intro {
            &__heading {
                font-size: 18px;
            }

            &__lead {
                font-size: $smallFontSize;
                margin-bottom: 16px;
            }
        }

        .refunds-steps {
            &__item {
                &::before {
                    width: 28px;
                    height: 28px;
                }
            }
        }

        .refunds-card {
            padding: 24px 16px;

            &__heading {
                font-size: $mediumFontSize;
            }

            &__text {
                font-size: $smallFontSize;
            }
        }

        .refunds-lookup {
            padding: 20px 16px;

            &__heading {
                font-size: $mediumFontSize;
            }
        }
    }
}

3. Modyfikacje istniejących plików HTML

partials/customer/order-content.html

W pliku partials/customer/order-content.html wykonaj poniższe zmiany. a) Bezpośrednio po otwarciu kontenera <div class="orderContent order-content-js"> dodaj dwa nowe bannery informacyjne (jeden o ukrytych danych zamówienia, drugi o terminie zwrotu, wraz z wyliczaniem flagi hasReturnableProduct):
{% if order.Restricted -%}
<div class="orderContent__returnInfo" role="note">
    <!-- TODO: ikona SVG informacyjna z klasą orderContent__returnInfo__icon -->
    {{ translations.RestrictedOrderViewInfo }}
</div>
{% endif -%}
{% assign hasReturnableProduct = false -%}
{% if config.Complaints.ReturnsEnabled -%}
{% for product in order.Products -%}
{% if product.CanReturn -%}
{% assign hasReturnableProduct = true -%}
{% break -%}
{% endif -%}
{% endfor -%}
{% endif -%}
{% if hasReturnableProduct -%}
<div class="orderContent__returnInfo" role="note">
    <!-- TODO: ikona SVG informacyjna z klasą orderContent__returnInfo__icon -->
    {{ translations.Prf_ReturnPeriodInfo | Format: config.Complaints.DaysToReturn }}
</div>
{% endif -%}
b) Kontener <div class="orderContent__docsToPrint">...</div> (z dokumentami do druku) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}, aby ukrywać go dla zamówień typu restricted. c) Cały dotychczasowy blok przycisków reklamacji/zwrotu (oparty na konstrukcji {% if ComplaintsEnabled and ReturnsEnabled %} ... {% elseif ComplaintsEnabled %} ... {% elseif ReturnsEnabled %} ... {% endif %} z jednym wspólnym przyciskiem) zamień na dwa niezależne warunki, dzięki czemu dla produktu uprawnionego zarówno do reklamacji, jak i do zwrotu, oba przyciski wyświetlają się obok siebie. Strukturę wewnątrz warunku {% if product.CanComplain or product.CanReturn -%} zastąp poniższym kodem:
{% if config.Complaints.ComplaintsEnabled == true and product.CanComplain -%}
<button class="orderContent__complainBtn orderContent__complainBtn--complaint showPopupBtn-js addDataToComplaintForm-js" data-popup-class="popupDialog" data-form-type="complaint" data-product-id="{{product.No}}" data-image-id="{{product.ImageId}}" data-imageext="{{product.Image.ExternalUrl}}" data-product-name="{{product.NameNoHtml | H}}" data-product-complain="{{product.CanComplain}}" data-product-count="{{ newProductQuantity }} {{ product.Unit }}" data-product-unit="{{ product.Unit }}" data-product-description="{{ productAttributes | Join: ' / ' | H }}" data-product-return="false" data-product-quantity="{{newProductQuantity}}" data-order-id="{{order.Id}}" data-order-date="{{order.Date | Date: 'yyyy-MM-dd'}}">
    <svg width="16" height="16">
        <use href="#comment-alt-regular"></use>
    </svg>
    {{translations.Prf_SendComplaint }}
</button>
{% endif -%}
{% if config.Complaints.ReturnsEnabled == true and product.CanReturn -%}
<button class="orderContent__complainBtn orderContent__complainBtn--return showPopupBtn-js addDataToComplaintForm-js" data-popup-class="popupDialog" data-form-type="return" data-product-id="{{product.No}}" data-image-id="{{product.ImageId}}" data-imageext="{{product.Image.ExternalUrl}}" data-product-name="{{product.NameNoHtml | H}}" data-product-complain="false" data-product-count="{{ newProductQuantity }} {{ product.Unit }}" data-product-unit="{{ product.Unit }}" data-product-description="{{ productAttributes | Join: ' / ' | H }}" data-product-return="{{product.CanReturn}}" data-product-quantity="{{newProductQuantity}}" data-order-id="{{order.Id}}" data-order-date="{{order.Date | Date: 'yyyy-MM-dd'}}">
    <svg width="16" height="16">
        <use href="#sync-regular"></use>
    </svg>
    {{ translations.Prf_OrderReturn }}
</button>
{% endif -%}
Kluczowe różnice w stosunku do poprzedniej wersji: każdy przycisk renderowany jest niezależnie (oba mogą wystąpić równocześnie), przyciski mają modyfikatory orderContent__complainBtn--complaint i orderContent__complainBtn--return, atrybut data-form-type (odczytywany w JS), w przycisku reklamacji wymuszone data-product-return="false", w przycisku zwrotu wymuszone data-product-complain="false", ikony 16x16 (#comment-alt-regular dla reklamacji, #sync-regular dla zwrotu), a etykieta przycisku zawiera już tylko jedno tłumaczenie. d) W pozostałych miejscach z przyciskami reklamacji/zwrotu (sekcje, w których nie zmieniają się klasy i ikony) dodaj jedynie dwa nowe atrybuty:
data-product-unit="{{ product.Unit }}"
data-product-description="{{ productAttributes | Join: ' / ' | H }}"
e) W sekcji załączników zamówienia zamień:
{% if order.Attachments[0] -%}
na:
{% if order.Attachments[0] and order.Restricted == false -%}
f) W kontenerze <div class="orderContent__recipient orderContent__infoBox"> zamień wyświetlanie adresu dostawy:
<span class="orderContent__lightText">{{ order.Customer.DeliveryAddress.Street }} {{ order.Customer.DeliveryAddress.StreetNo }} / {{ order.Customer.DeliveryAddress.UnitNo }}</span>
na:
<span class="orderContent__lightText">{{ order.Customer.DeliveryAddress.Street }} {{ order.Customer.DeliveryAddress.StreetNo }}{% if order.Customer.DeliveryAddress.UnitNo != null and order.Customer.DeliveryAddress.UnitNo != '' -%} / {{ order.Customer.DeliveryAddress.UnitNo }}{% endif -%}</span>
g) Sekcję z przyciskami akcji zamówienia (orderCancel-js, ponowienie płatności itd.) opakuj warunkiem {% unless order.Restricted -%} ... {% endunless -%}. Wstaw {% unless order.Restricted -%} bezpośrednio przed warunkiem {% if order.CanRestorePayment -%}, a {% endunless -%} po zamykającym {% endif -%} bloku z przyciskiem anulowania zamówienia.

partials/common/complaint-popup.html

Plik partials/common/complaint-popup.html wymaga gruntownej przebudowy. Usuwamy z niego radiowe przyciski wyboru "reklamacja/zwrot", a typ formularza jest teraz przekazywany z zewnątrz przez parametr __include. Sterowanie ilością zostało przeniesione do kafelka z produktem (z etykietą i obsługą wariantu statycznego, gdy zostaje tylko 1 sztuka). W formularzu zwrotu zamiast samego pola numeru konta pojawia się sekcja wyboru sposobu zwrotu środków (refundMethod-js) – z opcją „zwrot na sposób płatności" (domyślna) lub „zwrot na konto bankowe". Pole numeru konta jest domyślnie ukryte i disabled; pokazuje się dopiero po wybraniu opcji „konto bankowe" (obsługa w JS w metodzie changeRefundMethod). Tytuł, kafelek produktu i formularz oznaczone są dodatkową klasą complain-form-view-js, dzięki czemu po pomyślnym wysłaniu formularza można je ukryć i wyświetlić ekran sukcesu (complain-success-view-js). Zastąp całą zawartość pliku poniższym kodem:
{% if hideContent -%}
{% else -%}
{% assign formType = include -%}
{% assign isReturn = false -%}
{% if formType == 'return' -%}
{% assign isReturn = true -%}
{% endif -%}
<div class="popupDialog popupDialog__complain popupDialog-js">
    {% assign order = customer-profile.Order -%}
    <div class="popupDialog__wrapper">
        <button class="popupDialog__closeBtn closePopupBtn-js">
            <!-- TODO: ikona SVG zamknięcia – jak w pozostałych popupach szablonu -->
        </button>
        <span class="popupDialog__title complain-form-view-js">
            {% if isReturn -%}
            {{ translations.Prf_OrderReturn }}
            {% else -%}
            {{ translations.Prf_SendComplaint }}
            {% endif -%}
        </span>
        <div class="complain__product complain-form-view-js">
            <figure><img class="productImage-js" alt="product_image" /></figure>
            <div class="complain__productInfo">
                <!-- TODO: zweryfikuj z szablonem elementy z klasami productName-js i productDescription-js (nazwa i opis produktu) -->
                <span class="productName-js"></span>
                <span class="productDescription-js"></span>
                <div class="complain__quantity">
                    <label class="complain__quantityLabel" for="complaint-quantity">{{translations.Com_Quantity}}:</label>
                    <div class="complain__quantityControl min-js quantityControl-js">
                        <button class="button-minus-add-product" type="button" aria-label="{{translations.ButtonMinusAddProduct}}" data-field="quantity">
                            <!-- TODO: ikona SVG minus -->
                        </button>
                        <input id="complaint-quantity" class="quantity-field quantity__field-js" max="" min="1" name="quantity" type="number" value="1" data-decimal="false" />
                        <button class="button-plus-add-product" type="button" aria-label="{{ translations.ButtonPlusAddProduct }}" data-field="quantity">
                            <!-- TODO: ikona SVG plus -->
                        </button>
                    </div>
                    <span class="quantityStatic-js hidden"></span>
                    <span class="productUnit-js"></span>
                </div>
            </div>
        </div>
        <div class="form complain__form inputs-container-js complain-form-view-js" data-success-info="{{ translations.ReportSuccessInfo }}">
            <input name="__action" type="hidden" value="{% if isReturn -%}Order/ReturnAdd{% else -%}Order/ComplaintAdd{% endif -%}" />
            <strong>{{ translations.ReportDetails }}</strong>
            {% unless isReturn -%}
            <div class="form__input-wrapper">
                {% if config.Complaints.Defects <> null -%}
                {% assign defectsSize = config.Complaints.Defects | Size -%}
                <label class="hidden" for="defectId">{{ translations.ChooseComplaintCause }}</label>
                <select class="form__input-value form__input-value-js {% if settings.themeName == 'Dark' -%} darkTheme {% endif -%}" name="defectId" required="">
                    {% if defectsSize > 1 -%}
                    <option value="-1">* {{translations.ChooseComplaintCause}}</option>
                    {% endif -%}
                    {% for def in config.Complaints.Defects -%}
                    <option value="{{def.Id}}">{{def.Name}}</option>
                    {% endfor -%}
                </select>
                {% endif -%}
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            <div class="form__input-wrapper">
                <span class="form__icons">
                    <!-- TODO: ikona SVG kalendarza -->
                </span>
                <input id="defectDate" class="form__input-value form__icon_padding form__input-value-js orderDate-js" max="{{config.Now | Date: 'yyyy-MM-dd'}}" min="{{order.Date | Date: 'yyyy-MM-dd'}}" name="defectDate" type="date" value="{{config.Now | Date: 'yyyy-MM-dd'}}" placeholder="yyyy-MM-dd" />
                <label class="form__input-info" for="defectDate">* {{translations.Prf_DefectDate}}</label>
            </div>
            <div class="form__input-wrapper">
                {% if config.Complaints.Requests <> null -%}
                {% assign requestsSize = config.Complaints.Requests | Size -%}
                <label class="hidden" for="requestId">{{ translations.Prf_ComplainRequest }}</label>
                <select class="form__input-value form__input-value-js {% if settings.themeName == 'Dark' -%} darkTheme {% endif -%}" name="requestId" required="">
                    {% if requestsSize > 1 -%}
                    <option value="-1">* {{translations.Prf_ComplainRequest}}</option>
                    {% endif -%}
                    {% for req in config.Complaints.Requests -%}
                    <option value="{{req.Id}}">{{req.Name}}</option>
                    {% endfor -%}
                </select>
                {% endif -%}
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            {% else -%}
            {% assign returnTypes = config.Complaints.Returns | Size -%}
            {% if returnTypes > 1 -%}
            <div class="form__input-wrapper">
                <label class="hidden" for="returnId">{{ translations.ChooseReturn }}</label>
                <select class="form__input-value form__input-value-js {% if settings.themeName == 'Dark' -%} darkTheme {% endif -%}" name="returnId" required="">
                    <option value="-1">* {{translations.ChooseReturn}}</option>
                    {% for return in config.Complaints.Returns -%}
                    <option value="{{return.Id}}">{{return.Name}}</option>
                    {% endfor -%}
                </select>
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            {% endif %}
            {% endunless -%}
            <div class="form__input-wrapper returnInputWrapper-js refundMethodWrapper-js">
                <label class="complain__sectionLabel" for="refundMethod">{{ translations.RefundMethod }}</label>
                <select id="refundMethod" class="form__input-value form__input-value-js refundMethod-js {% if settings.themeName == 'Dark' -%}darkTheme{% endif -%}" name="refundMethod">
                    <option value="payment">{{ translations.RefundAsPaid }}{% if order.Payment.Name != null and order.Payment.Name != '' %} ({{ order.Payment.Name }}){% endif %}</option>
                    <option value="account">{{ translations.RefundToBankAccount }}</option>
                </select>
            </div>
            <div class="form__input-wrapper accountNumberWrapper-js" style="display: none;">
                <input id="accountNumber" class="form__input-value form__input-value-js" disabled="disabled" maxlength="50" name="accountNumber" type="text" />
                <label class="form__input-info form__input-info-js" for="accountNumber">{{translations.Crt_BankAccountNumber}}</label>
                <p class="form__invalid-input form__validation-required-js" style="display: none;">{{ translations.Com_FieldIsMandatory }}</p>
            </div>
            <div class="form__input-wrapper">
                {{translations.Prf_AdditionalInfo}}
                <textarea class="form__input-value" name="message" aria-label="{{ translations.Prf_AdditionalInfo }}"></textarea>
            </div>
            <div class="form__input-wrapper">
                <span class="form__requiredFields--info">* {{ translations.Com_RequiredFields }}</span>
            </div>
            {% if config.Complaints.AttachmentsEnabled -%}
            <div class="form__input-wrapper attachementsInputWrapper" data-not-added-info="{{translations.AttachementsNotAdded}}">
                <button class="form__attachementsLabel form__attachementsLabel--btn form__attachementsLabel-js" data-page="complaints">
                    <!-- TODO: ikona SVG dodawania załącznika -->
                    {{ translations.AddAttachment }}
                </button>
                {% capture maxSize -%}{{config.Complaints.AttachmentMaxSize | DividedBy: 1024}}KB{% endcapture -%}
                {% for i in (1..config.Complaints.AttachmentsMaxCount) -%}
                <div class="form__attachement-input-container form__attachement-input-container-attachments form__attachement-input-container--hidden">
                    <!-- TODO: ikona SVG oraz element z nazwą pliku (form__attachement-input-container-attachments__text) -->
                    <input class="addAttachementInComplaint-js" accept="{{ config.Complaints.AttachmentExtensions }}" name="file" type="file" aria-label="{{ translations.AddAttachment }}" data-file-size="{{ config.Complaints.AttachmentMaxSize }}" data-size-exceeded="{{ translations.Com_FileSizeExceeded | Format: maxSize }}" data-invalid-file="{{ translations.Com_InvalidFile | Format: config.Complaints.AttachmentExtensions }}" />
                    <button class="form__clear-attachement-input clearFileInput-js" style="display: none;">
                        <!-- TODO: ikona SVG usuwania załącznika -->
                    </button>
                </div>
                {% endfor -%}
            </div>
            {% endif -%}
            <input class="productId-js" name="no" type="hidden" value="" />
            <input class="orderId-js" name="orderId" type="hidden" value="{{order.Id}}" />
            <button class="primary-action-button orderComplaintOrReturnAdd-js" type="button" data-id="{{order.Id}}">{{translations.Report}}</button>
        </div>
        <div class="complain__successView complain-success-view-js hidden">
            <div class="complain__successIcon">
                <!-- TODO: ikona SVG potwierdzenia (zielony "check", klasa svgIcon) -->
            </div>
            <h2 class="complain__successTitle">{{ translations.ComplaintSuccessTitle }}</h2>
            <p class="complain__successDescription">{{ translations.ComplaintSuccessDescription }}</p>
            <div class="complain__successInfoBox">
                <!-- TODO: ikona SVG informacyjna (klasa svgIcon) -->
                <span>{{ translations.ComplaintSuccessConfirmationSent }}
                    <strong>{{ order.Customer.Email }}</strong>
                </span>
            </div>
            <h3 class="complain__successStepsTitle">{{ translations.ComplaintSuccessStepsTitle }}</h3>
            <ol class="complain__successSteps">
                <li>{{ translations.ComplaintSuccessStep1 }}</li>
                <li>{{ translations.ComplaintSuccessStep2 }} {{ config.Shop.Address.Street }} {{ config.Shop.Address.StreetNo }}{% if config.Shop.Address.UnitNo != '' %}/{{ config.Shop.Address.UnitNo }}{% endif %}, {{ config.Shop.Address.ZipCode }} {{ config.Shop.Address.City }}</li>
                <li>{{ translations.ComplaintSuccessStep3 }}</li>
            </ol>
            <div class="complain__successActions">
                <button class="primary-action-button closePopupBtn-js" type="button">{{ translations.BtnClose }}</button>
            </div>
        </div>
    </div>
</div>
{% endif -%}

4. Modyfikacje pliku js/layout1.js

Poniższe zmiany dotyczą pliku js/layout1.js. Po edycji pamiętaj o zminifikowaniu pliku do layout1.min.js. a) W obiekcie customerProfile usuń całą metodę setComplainReturnRadioButtons (radiowy przełącznik reklamacja/zwrot nie jest już potrzebny – typ formularza jest teraz przekazywany przy otwieraniu popupu). b) W tym samym obiekcie zastąp całą metodę addDataToComplaintForm nową implementacją, która odczytuje typ formularza z atrybutu data-form-type przycisku i przekazuje go do szablonu jako parametr __include:
addDataToComplaintForm: function (e) {
    const template = 'partials/common/complaint-popup.html';
    const data = e.currentTarget;
    const formType = data.dataset.formType === 'return' ? 'return' : 'complaint';

    $.get('', {__template: template, __include: "'" + formType + "'"}, function(result) {
        $('.customer__content-js').append(result.template);
        $('.popupDialog__complain').show();
        $('body').addClass('customerProfileNoScroll');

        const image = $('.productImage-js');
        const productName = $('.productName-js');
        const inputId = $('.productId-js');
        const productQuantity = $('.quantity__field-js');
        const quantityControl = $('.quantityControl-js');
        const quantityStatic = $('.quantityStatic-js');
        const productUnit = $('.productUnit-js');
        const productDescription = $('.productDescription-js');

        const orderId = $('.orderId-js');
        const buttonOrderId = $('.orderComplaintOrReturnAdd-js');
        const orderDate = $('.orderDate-js');

        productName.text(data.dataset.productName);
        productUnit.text(data.dataset.productUnit || '');
        productDescription.text(data.dataset.productDescription || '');
        inputId.val(data.dataset.productId);
        productQuantity.attr('max', data.dataset.productQuantity);

        if (parseInt(data.dataset.productQuantity, 10) <= 1) {
            quantityControl.addClass('hidden');
            quantityStatic.text(data.dataset.productQuantity).removeClass('hidden');
        } else {
            quantityControl.removeClass('hidden');
            quantityStatic.addClass('hidden');
        }

        orderId.val(data.dataset.orderId);
        buttonOrderId.attr('data-id', data.dataset.orderId);
        orderDate.attr('min', data.dataset.orderDate);

        if (data.dataset.imageext != null && data.dataset.imageext != "") {
            image.attr('src', data.dataset.imageext);
        } else if (data.dataset.imageId != null && data.dataset.imageId != "") {
            image.attr('src', '/Image/?id=' + data.dataset.imageId);
        }

        if (image.attr('src') === '' || image.attr('src') == null) {
            image.closest('figure').addClass('noImage-js');
        }

        setTimeout(function() {
            app.activateFocusTrap('.popupDialog__complain', e.target);
        }, 200);
    });
},
c) Zastąp metodę changeReturnComplaintForm nową wersją (obsługuje również pole numeru konta i wywołuje changeRefundMethod po przełączeniu na zwrot):
changeReturnComplaintForm: function (e) {
    const form = $(e.currentTarget).closest('.inputs-container-js');
    const complaintInputs = form.find('.complaintInputWrapper-js');
    const returnInputs = form.find('.returnInputWrapper-js');
    const accountWrapper = form.find('.accountNumberWrapper-js');
    const accountInput = accountWrapper.find('input[name="accountNumber"]');

    if ($(e.currentTarget).is(':checked') && e.currentTarget.dataset.name === 'complaint' ) {
        $.each(complaintInputs, function (index, value) {
            $(value).find('input, select').first().removeAttr('disabled');
            $(value).show(300);
        });
        returnInputs.each(function () {
            $(this).find('input, select').first().attr('disabled', 'true');
        });
        returnInputs.hide(300);
        accountInput.removeAttr('disabled').removeAttr('required').removeClass('form__validation-error-js');
        accountWrapper.find('.form__validation-required-js').hide();
        accountWrapper.show(300);
    }

    if ($(e.currentTarget).is(':checked') && e.currentTarget.dataset.name === 'return' ) {
        $.each(complaintInputs, function (index, value) {
            $(value).find('input, select').first().attr('disabled', 'true');
            $(value).hide(300);
        });
        returnInputs.each(function () {
            $(this).find('input, select').first().removeAttr('disabled');
        });
        returnInputs.show(300);
        customerProfile.changeRefundMethod(form);
    }
},
d) Tuż za metodą changeReturnComplaintForm dodaj nową metodę changeRefundMethod (pokazuje / ukrywa pole numeru konta bankowego na podstawie wybranego sposobu zwrotu):
changeRefundMethod: function (formOrEvent) {
    const form = formOrEvent && formOrEvent.currentTarget
        ? $(formOrEvent.currentTarget).closest('.inputs-container-js')
        : $(formOrEvent);
    const select = form.find('.refundMethod-js');
    const accountWrapper = form.find('.accountNumberWrapper-js');
    const accountInput = accountWrapper.find('input[name="accountNumber"]');

    if (select.val() === 'account') {
        accountInput.removeAttr('disabled').attr('required', 'required');
        accountWrapper.show(300);
    } else {
        accountInput.attr('disabled', 'true').removeAttr('required').removeClass('form__validation-error-js');
        accountWrapper.find('.form__validation-required-js').hide();
        accountWrapper.hide(300);
    }
},
e) W metodzie wysyłającej formularz reklamacji/zwrotu (gdzie znajduje się pętla for (let i=0; i<dataFromHTML.length; i++)) zaraz po pętli dodaj fragment dołączający parametr qrHash z URL-a przy wysyłaniu zwrotu:
if (form.find('input[name="__action"]').val() === 'Order/ReturnAdd') {
    const qrHash = new URLSearchParams(globalThis.location.search).get('qrHash');
    if (qrHash) {
        fd.append('qrHash', qrHash);
    }
}
f) W tej samej metodzie, w callbacku success po pomyślnym wysłaniu, zamień fragment:
if (data.action.Result) {
    const message = form.data('success-info');
    app.showTemporaryPopup(message, 'success', '', 8000);
    $('.clearFileInput-js').hide();
    app.hidePopup(e);
    sessionStorage.removeItem('complains');
    sessionStorage.removeItem('order' + (e.currentTarget).dataset.id);
    $('.order' + (e.currentTarget).dataset.id).remove();
    $('.popupDialog__complain').remove();
    $('body').removeClass('customerProfileNoScroll');
    customerProfile.showOrderDetails(e);
}
na:
if (data.action.Result) {
    $('.clearFileInput-js').hide();
    sessionStorage.removeItem('complains');
    sessionStorage.removeItem('order' + (e.currentTarget).dataset.id);
    const popup = $(e.currentTarget).closest('.popupDialog__complain');
    popup.find('.complain-form-view-js').addClass('hidden');
    popup.find('.complain-success-view-js').removeClass('hidden');
    popup.find('.popupDialog__wrapper').scrollTop(0);
}
g) W sekcji rejestracji zdarzeń profilu klienta (tam, gdzie znajdują się m.in. mainSection.on('change', '.radioComplaint-js, .radioReturn-js', ...)) tuż za istniejącym handlerem zmiany typu formularza dopisz nowy handler:
mainSection.on('change', '.refundMethod-js', function (e) {
    customerProfile.changeRefundMethod(e);
});
h) Znajdź globalny handler obsługujący keydown z selektorem zaczynającym się od .radioReturn-js label, .radioComplaint-js label, ... i usuń z niego dwa pierwsze selektory (po zmianie zaczyna się od .showHideSection-js):
// PRZED
$('body').on('keydown', '.radioReturn-js label, .radioComplaint-js label, .showHideSection-js, .checkBoxes__container label, .customerPagination__form-js, .discountsDetails-js, .customer-focus, .customer__menuActivate-js', function(e) { ... });

// PO
$('body').on('keydown', '.showHideSection-js, .checkBoxes__container label, .customerPagination__form-js, .discountsDetails-js, .customer-focus, .customer__menuActivate-js', function(e) { ... });
i) W obiekcie app w pliku js/layout1.js obsłuż przekierowanie po zalogowaniu z parametrem #login-redirect= (używanym przez stronę szybkich zwrotów). W bloku rejestracji/logowania, w miejscu gdzie obsługiwany jest hash #back-to-cart, tuż po nim dodaj:
if (globalThis.location.hash.startsWith('#login-redirect=')) {
    url = globalThis.location.hash.slice('#login-redirect='.length);
}
Następnie w handlerze sukcesu logowania, gdzie znajduje się sprawdzenie window.location.hash.includes('#back-to-cart') wraz z przekierowaniem, tuż za nim dodaj analogiczny blok przekierowujący w przypadku #login-redirect=:
if (globalThis.location.hash.startsWith('#login-redirect=')) {
    globalThis.location.assign(globalThis.location.hash.slice('#login-redirect='.length));
    return;
}

5. Modyfikacje plików SCSS profilu klienta

Poniższe style należy dodać do plików scss/static-elements/customer-profile/customer-profile-g.scss (style ogólne), customer-profile-d.scss (desktop) i customer-profile-m.scss (mobile). Po zmianach pamiętaj o kompilacji SCSS – nie edytuj ręcznie wynikowych plików CSS.

Plik customer-profile-g.scss

a) Wewnątrz selektora opakowującego (tam, gdzie znajdują się istniejące reguły .orderContent__complainBtn) dodaj nowe reguły dla banera informacyjnego oraz kontenera grupującego przyciski reklamacji/zwrotu:
.orderContent__returnInfo {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 16px 0 24px;
    padding: 12px 16px;
    background-color: color-mix(in srgb, #{$linkFontColor} 4%, transparent);
    border: 1px solid color-mix(in srgb, #{$linkFontColor} 20%, transparent);
    border-radius: 4px;
    font-size: 13px;
    line-height: 1.4;
    color: $primaryFontColor;

    &__icon {
        flex-shrink: 0;
        fill: $linkFontColor;
    }
}

.orderContent__complainBtns {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin: 16px 0 4px;
}
b) Następnie zastąp istniejące style .orderContent__complainBtn nowym wyglądem przycisku (z tłem, obramowaniem i hoverem):
.orderContent__complainBtn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 16px 0 4px;
    padding: 6px 12px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 4px;
    color: $linkFontColor;
    fill: $linkFontColor;
    font-size: 13px;
    font-weight: 500;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 180ms, border-color 180ms;

    .orderContent__complainBtns & {
        margin: 0;
    }

    svg {
        margin: 0;
        flex-shrink: 0;
    }

    &:hover,
    &:focus-visible {
        background-color: color-mix(in srgb, #{$linkFontColor} 6%, transparent);
        border-color: color-mix(in srgb, #{$linkFontColor} 25%, transparent);
        outline: none;
    }
}
c) Dodaj style etykiety sekcji oraz kontenera sposobu zwrotu w popupie reklamacji:
.complain__sectionLabel {
    display: block;
    margin-bottom: 8px;
    font-size: 14px;
    font-weight: 500;
    color: $primaryFontColor;
}

.refundMethodWrapper-js {
    margin-bottom: 18px;
}
d) Dodaj kompletne style ekranu sukcesu zwrotu (m.in. ikona, tytuł, lista kolejnych kroków, sekcja z e-mailem i przyciskiem zamknięcia):
.complain__successView {
    text-align: center;
    padding: 16px 0 0;
}

.complain__successIcon {
    display: flex;
    justify-content: center;
    margin: 8px 0 20px;

    .svgIcon {
        width: 64px;
        height: 64px;
        fill: #2d8c4a;
    }
}

.complain__successTitle {
    font-size: 20px;
    font-weight: 600;
    line-height: 1.3;
    margin: 0 0 12px;
    color: $primaryFontColor;
}

.complain__successDescription {
    font-size: 14px;
    line-height: 1.5;
    color: $primaryFontColor;
    margin: 0 0 20px;
}

.complain__successInfoBox {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 14px;
    margin: 0 0 24px;
    border: 1px solid #cfdcef;
    background-color: #f0f5fc;
    border-radius: 6px;
    text-align: left;

    .svgIcon {
        flex-shrink: 0;
        margin-top: 2px;
        fill: #3a6ea5;
    }

    span {
        font-size: 13px;
        line-height: 1.5;
        color: $primaryFontColor;
    }

    strong {
        display: block;
        font-weight: 600;
        margin-top: 2px;
        word-break: break-all;
    }
}

.complain__successStepsTitle {
    font-size: 15px;
    font-weight: 600;
    margin: 0 0 12px;
    text-align: left;
    color: $primaryFontColor;
}

.complain__successSteps {
    margin: 0 0 24px;
    padding-left: 22px;
    text-align: left;

    li {
        font-size: 14px;
        line-height: 1.6;
        margin-bottom: 6px;
        color: $primaryFontColor;
    }
}

.complain__successActions {
    display: flex;
    justify-content: flex-end;
    padding-top: 16px;
    padding-bottom: 30px;
    margin-top: 8px;
    border-top: 1px solid $borderColor;

    .primary-action-button {
        min-width: 140px;
        margin: 0;
    }

    @media screen and (max-width: 599px) {
        .primary-action-button {
            width: 100%;
            min-width: 0;
        }
    }
}
e) Zaktualizuj style załączników – znajdź istniejące reguły .form__clear-attachement-input oraz reguły z position: absolute; top: 11px; i zastąp je nowymi (które ustawiają załączniki w układzie statycznym z poprawnym overflowem i przyciskiem usuwania):
.form__attachement-input-container-attachments__text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.form__attachement-input-container--hidden,
.form__attachement-input-container-attachments.form__attachement-input-container--hidden {
    display: none;
}

.form__clear-attachement-input {
    position: static;
    background: transparent;
    border: none;
    padding: 2px 4px;
    margin: 0 0 0 4px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;

    svg {
        fill: $linkFontColor;
        transition: opacity 200ms;
    }

    &:hover svg {
        opacity: 0.7;
    }
}

Plik customer-profile-d.scss

Wewnątrz wrappera @media screen and (min-width: 769px) zamień istniejące style przycisku reklamacji:
.customer .orderContent__complainBtn {
    position: absolute;
    bottom: 8px;
}
na poniższy fragment (dodaje pozycjonowanie kontenera grupującego przyciski oraz osobny selektor dla pojedynczych przycisków w wierszu produktu):
.customer .orderContent__complainBtns {
    position: absolute;
    bottom: 8px;
    right: 0;
    margin: 0;
}

.customer .orderContent__productDetails > .orderContent__complainBtn {
    position: absolute;
    bottom: 8px;
    right: 0;
    margin: 0;
}

Plik customer-profile-m.scss

W obrębie selektora .customer zamień istniejący media-query @media screen and (max-width: 359px) wraz z jego wnętrzem na rozszerzoną wersję (układająca przyciski reklamacji/zwrotu pionowo na szerokościach do 450px):
@media screen and (max-width: 450px) {
    .customer__orderContent .orderContent__productsRow {
        max-height: none;
    }

    .customer__orderContent .orderContent__productDetails {
        display: flex;
        flex-direction: column;
        align-items: stretch;
    }

    .customer__orderContent .orderContent__complainBtns {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 8px;
        width: 100%;
        margin: 12px 0 4px;
        padding-top: 12px;
        border-top: 1px solid $borderColor;
    }

    .customer__orderContent .orderContent__complainBtn {
        display: flex;
        width: 100%;
        justify-content: center;
        padding: 10px 12px;
        margin: 12px 0 4px;
        border-color: color-mix(in srgb, #{$linkFontColor} 25%, transparent);
    }

    .customer__orderContent .orderContent__complainBtns .orderContent__complainBtn {
        margin: 0;
    }
}

6. Szablon One Page Shop

Szablon One Page Shop ma praktycznie identyczną strukturę plików jak Topaz. Wszystkie powyższe modyfikacje (tłumaczenia, nowa strona zwrotów, edycje plików partials/common/complaint-popup.html oraz partials/customer/order-content.html, zmiany w js/layout1.js oraz w plikach SCSS profilu klienta i strony zwrotów) wykonaj 1:1 w plikach szablonu OPS pod tymi samymi ścieżkami. Treść kodu jest taka sama, ścieżki plików są takie same – instrukcja dla Topaza w pełni stosuje się również do One Page Shopa. Po wprowadzeniu wszystkich powyższych zmian w szablonie Topaz (oraz One Page Shop) pamiętaj o kompilacji oraz minifikacji plików js i scss, zgodnie z artykułem dostępnym pod linkiem https://pomoc.comarchesklep.pl/artykul/kompilacja-i-minifikacja-plikow/.
Wskazówka
Potrzebujesz pomocy lub masz pytania? Skontaktuj się z nami poprzez portal asysta.comarch.pl.

Posiadam gotowy szablon Comarch. Jak mogę go dostosować do kryteriów WCAG 2.1/2.2?

Wstęp

Z dniem 28 czerwca 2025 roku w życie wejdą przepisy związane z implementacją ustawy z dnia 26 kwietnia 2024 r. o zapewnianiu spełniania wymagań dostępności niektórych produktów i usług. Wdraża ona do polskiego prawa tzw. Europejski Akt o Dostępności (EAA) – unijną dyrektywę 2019/882. Celem ustawy jest zapewnienie, że kluczowe produkty i usługi będą dostępne dla wszystkich użytkowników, w tym osób z niepełnosprawnościami. Przedsiębiorcy mają czas do 28 czerwca 2025 roku, aby dostosować swoje produkty i usługi do nowych wymogów.
Wskazówka
Chcesz dowiedzieć się więcej o tych przepisach? Sprawdź artykuł w naszym Centrum Pomocy: Europejski Akt o Dostępności (EAA) i zapoznaj się ze szczegółami
W niniejszym artykule wskazujemy, jakie czynności należy wykonać, jeśli posiadasz jeden ze standardowych szablonów Comarch, czyli: Rubin, Szafir, Topaz, One Page Shop lub Dla Gastronomii.   

Sprawdź, jaki szablon posiadasz

Nie wiesz, który szablon posiadasz? Możesz to sprawdzić w panelu administracyjnym Comarch e-Sklep. Aby to zrobić, z poziomu panelu administracyjnego przejdź do zakładki Wygląd sklepu/ Ustawienia a następnie, pod przyciskiem "Więcej" wybierz Edytuj ustawienia zaawansowane. W obszarze, który został wyświetlony, pojawi się kilka zakładek, a wśród nich zakładka "Szablon". Wybierz ją, po czym sprawdź szablon:   Jeśli Twój szablon to Rubin, Szafir, Topaz, One Page Shop lub Dla Gastronomii, to możesz przejść do kolejnej części artykułu. Jeśli posiadasz własny szablon z indywidualnymi modyfikacjami, to przejdź do artykułu: Posiadam własny szablon, jak mogę go dostosować do kryteriów WCAG 2.1/2.2?  Jeśli posiadasz szablon Bursztyn, Agat lub Opal, to przejdź do artykułu: Posiadam szablon Bursztyn, Opal lub Agat, jak mogę go dostosować do kryteriów WCAG 2.1/2.2?  

Co zrobić jako właściciel e-Sklepu lub Partner, jeśli używam gotowych szablonów Comarch?

Jako właściciel e-Sklepu lub Partner Comarch zadbaj, aby zadbać o dostosowanie swojej witryny do obowiązujących przepisów. Nowe wymogi to wspólna odpowiedzialność:
  • Comarch e-Sklep – zajmiemy się kwestiami technicznymi w przypadku Gotowych Szablonów Comarch, do których należą m.in. zmiany w kodzie,
  • Właściciel, administrator lub Partner sklepu – musisz zadbać o treści i elementy, które dodajesz samodzielnie. Chodzi tu głównie opis produktów, zdjęcia i grafiki czy identyfikację wizualną. 
 

Jak zacząć?

Jeśli korzystasz z gotowych szablonów, takich jak Rubin, Szafir, Topaz, One Page Shop lub Dla Gastronomii, nie musisz przejmować się samodzielnym edytowaniem ich kodu. Wszystkie usprawnienia zostaną udostępnione wraz z aktualizacją, która pojawi się w czerwcu 2025 roku.

Aktualizacja szablonu

Wskazówka
Aktualizację szablonu wykonaj wtedy, kiedy będzie ona dostępna. Realizacja wersji 2025.4 przewidywana jest przed 28 czerwca 2025 roku, poinformujemy o niej w aktualnościach. Będzie ona zawierała zmiany związane z omawianymi tutaj przepisami.

Jak zaktualizować szablon?

Aby zaktualizować szablon i przejść na Topaz, One Page Shop, Dla Gastronomii, Rubin lub Szafir, należy skorzystać z aktualnej wersji Kreatora Wyglądu. Pamiętaj, że szablony Rubin i Szafir przeznaczone są tylko dla sklepów Enterprise i B2B. Odnośnik znajduje się również w panelu administracyjnym e-Sklepu w sekcji Wygląd sklepu > Kreator wyglądu.  Istnieją trzy możliwości aktualizacji tych szablonów:
  • Wygenerowanie zupełnie nowego szablonu w Kreatorze Wyglądu oraz wgranie go do e-Sklepu,
  • Wybór i edycja jednego z gotowych układów i jego modyfikacja,
  • Import posiadanego szablonu do Kreatora Wyglądu oraz ponowne wygenerowanie go w najnowszej wersji.
Wygenerowany z Kreatora Wyglądu szablon należy wgrać do e-Sklepu. W panelu administracyjnym e-Sklepu, w sekcji Wygląd sklepu znajduje się bezpośredni odnośnik do importu szablonu z Kreatora wyglądu. Szczegółowa instrukcja dostępna jest w artykule Jak wyeksportować i zaimportować swój szablon w e-Sklepie?
Pamiętaj o zapisaniu szablonu oraz opublikowaniu go w e-Sklepie. Zmiany wprowadzone w ustawieniach zostaną zsynchronizowane do sklepu po 10 minutach.
Wskazówka
Informacje na temat aktualizacji znajdują się w Centrum Pomocy: Jak zaktualizować szablon do najnowszej wersji?  
Więcej informacji na temat Kreatora Wyglądu B2C oraz B2B znajduje się w Centrum Pomocy:

Odpowiedni kontrast kolorów w e-Sklepie – wymóg WCAG na poziomie AA

Jednym z głównych wymogów WCAG jest stosowanie odpowiednich kontrastów na stronach internetowych. Jeśli w wybranym szablonie graficznym wykorzystujesz któryś ze standardowych motywów kolorystycznych dostępnych w kreatorach, to zostaną one dostosowane do wymagań wynikających z przepisów. Jeśli natomiast masz przygotowany własny motyw kolorystyczny lub chcesz zmienić część kolorów zastosowanych w szablonie, to pamiętaj, że muszą one posiadać odpowiednie kontrasty. Wszelkich zmian kolorystycznych możesz dokonać w Kreatorze Wyglądu.  Odpowiedni kontrast między tekstem a tłem jest kluczowy dla osób z dysfunkcjami wzroku. WCAG 2.1 określa minimalny współczynnik kontrastu (4.5:1 dla tekstu zwykłego i 3:1 dla tekstu dużego). Ważne jest również unikanie łączenia kolorów, które mogą być trudne do rozróżnienia, takich jak czerwony i zielony. Kontrasty po modyfikacji kolorów możesz sprawdzić np. narzędziem WAVE. WAVE to popularny, dostępny dla wszystkich zestaw narzędzi do oceny dostępności stron internetowych. Rozszerzenia WAVE dla Chrome, Firefox i Edge, umożliwiają testowanie bezpośrednio w tych przeglądarkach, bez przesyłania danych na serwer WAVE. WAVE znajdziesz pod linkiem: WAVE Web Accessibility Evaluation Tools.  

Jak sprawdzić kontrast?

Przejdź na stronę swojego e-Sklepu. Włącz wtyczkę WAVE. Po prawej stronie ekranu wyświetli się panel boczny, na pierwszej zakładce widać podsumowanie całej strony: Już na tym etapie możesz przejść do szczegółów, klikając "View details". Możesz w tym miejscu przejść także do zakładki "Contrast".   Czerwone kwadraty oznaczają obszar do poprawy. Przejdź przez stronę, aby zobaczyć szczegóły każdego z nich. Po kliknięciu na jeden z kwadratów pokaże się komunikat dotyczący kontrastu: W panelu bocznym pojawi się dokładna informacja na temat koloru. W tym miejscu, korzystając z suwaków możesz od razu dostosować kolor tak, aby był odpowiedni i sprawdzić, czy spełnia wymagania WCAG.  

Gdzie dostosować kolory?

Kolory w szablonie możesz zmienić korzystając z Kreatora Wyglądu. Po imporcie szablonu, edycji lub stworzeniu nowego projektu, przejdź do zakładki "Style" i edytuj motyw kolorystyczny:   Następnie możesz zmieniać swobodnie kolor na wybranych elementach:   Zmian możesz dokonać także z poziomu panelu administracyjnego, przechodząc do zakładki Wygląd Sklepu > Ustawienia.

Pozostałe zmiany

Poza zmianami w szablonie graficznym sklepu należy uzupełnić szereg danych. Znaczącą część tych elementów możesz wykonać już teraz, nie czekając na aktualizację Comarch e-Sklep. Poniżej znajduje się lista zmian, które należy wdrożyć w swoim e-Sklepie.

Teksty alternatywne ("Alt", alty) w Comarch e-Sklep

Twój szablon musi obsługiwać parametr "alt" w obrazkach. Jeśli wykorzystasz aktualny szablon standardowy od Comarch to obsługę zapewnia Comarch e-Sklep, jeśli zdecydowałeś się na indywidualny szablon lub samodzielną aktualizację starszej wersji to upewnij się, że w szablonie są obsługiwane parametry "alt" we wskazanych elementach. Teksty alternatywne („alt”) to krótkie opisy obrazków, które pozwalają osobom korzystającym z czytników ekranu zrozumieć, co znajduje się na zdjęciu. Atrybut „alt” jest szczególnie ważny dla zdjęć produktów, ponieważ umożliwia przekazanie najważniejszych informacji o produktach.  Dlaczego tekst alternatywny jest taki ważny? 
  • Pomaga osobom korzystającym z czytników ekranu, które odczytują tekst alternatywny na głos,
  • Poprawia dostępność stron internetowych, czyniąc je bardziej przyjaznymi dla wszystkich użytkowników,
  • Wpływa na pozycjonowanie w wyszukiwarkach, ponieważ dobrze opisane obrazy są lepiej interpretowane przez algorytmy Google.   
Dobrze sformułowany opis powinien być zwięzły, ale wystarczająco informacyjny. Poniżej prezentujemy przykłady dobrego i złego zastosowania opisów alternatywnych:
Przyklad
Poprawne :
  • Czerwona sukienka maxi z rozcięciem, modelka na tle miejskiego pejzażu.
  • Białe sneakersy z grubą podeszwą, ustawione na drewnianej podłodze.
  • Nowoczesna sofa w kolorze szarym, z drewnianymi nogami, ustawiona w minimalistycznym salonie.
  • Słuchawki bezprzewodowe z aktywną redukcją szumów, na białym tle.
Niepoprawne:
  • Sukienka.
  • Buty sportowe.
  • Fajna kanapa.
  • Najlepszy sprzęt w dobrej cenie!

Gdzie należy uzupełnić teksty alternatywne (alt)?

1. Dla zdjęć towarów w systemach Comarch ERP

Korzystam z Comarch ERP Optima
Po uruchomieniu Comarch ERP Optima przejdź na pozycję cennika, a następnie edytuj wybrany towar. Następnie przejdź na zakładkę "Atrybuty", a następnie do sekcji "Zdjęcia i załączniki". W tym miejscu zobaczysz kolumnę "Atrybut Alt".
Po dwukrotnym kliknięciu możliwe jest uzupełnienie opisu alternatywnego: Po dokonaniu zmian należy je zapisać. Po wykonaniu wszystkich modyfikacji należy wykonać synchronizację.

Korzystam z Comarch ERP XL

Po uruchomieniu ERP XL przejdź do Sprzedaż > Towary , a następnie na zakładkę "Załączniki". Opis alternatywny dla towaru stanowi Kod:    
Korzystam z Comarch ERP XT
Przejdź na kartę produktu, a następnie do zakładki "Zdjęcia". Wśród pól do uzupełnienia znajdziesz "Opis alternatywny (Alt)".   W tym miejscu wpisz odpowiednią treść, a następnie zapisz wprowadzone zmiany.  

2. Dla zdjęć w bannerach – w panelu administracyjnym Comarch e-Sklep

Pamiętaj, alby alty (opisy alternatywne) były uzupełnione także w przypadku bannerów. Aby to zrobić, przejdź z poziomu panelu administracyjnego do Wygląd sklepu > Ustawienia > Bannery  do edycji swoich bannerów. Klikając na odpowiedni kafelek pojawią się opcje z uzupełnieniem Alt:

3. Dla zdjęć stosowanych na stronach z treściami formalnymi – w panelu administracyjnym Comarch e-Sklep

Obrazki możesz dodawać także do treści, które udostępniasz na specjalnych stronach, takich jak np. Regulamin sklepu, Polityka prywatności, Wysyłka itp. W obszarze do edycji, który jest dostępny z poziomu panelu administracyjnego w sekcji Ustawienia > Treści formalne edytuj interesującą Cię treść, a dodając obrazek uzupełnij alt:    

4. Dla zdjęć wprowadzonych w opisie towaru i opisie kategorii

Dodając opisy produktów i kategorii, warto upewnić się, że linkowane zdjęcia zawierają poprawnie uzupełniony atrybut "alt". To kluczowe dla osób korzystających z czytników ekranu. Dbałość o ten detal poprawia dostępność strony i zwiększa jej widoczność w sieci. Opis towaru i kategorii możesz dodać w systemach Comarch ERP.  Opis kategorii możesz ustawić również z poziomu panelu administracyjnego, bez konieczności korzystania z systemu ERP. Szczegółowe informacje znajdują się w artykule: Jak edytować kategorię w Comarch e-Sklep? 

5. Dla zdjęć w Blogu

Obrazki, które dodawane są dla wpisów blogowych od wersji 2025.4 będą posiadały atrybuty ALT oraz Title. Ich uzupełnienie będzie możliwe przy przejściu z poziomu panelu administracyjnego Comarch e-Sklep do sekcji Marketing > Blog przy dodawaniu wpisu:

6. Dla zdjęć w plikach użytkownika w sekcji "Twoje pliki"

Pliki użytkownika w e-Sklepie to dedykowana przestrzeń do przechowywania własnych materiałów, które mogą zostać wykorzystane w sklepie internetowym. Pliki można przesyłać za pośrednictwem panelu administracyjnego, w sekcji Ustawienia > Twoje pliki. Maksymalny rozmiar pojedynczego pliku: 3 MB. Pliki, które dodawane są we wspomnianym obszarze, od wersji 2025.4 będą posiadały atrybuty ALT oraz Title. Ich uzupełnienie będzie możliwe przy przejściu z poziomu panelu administracyjnego do sekcji Ustawienia > Twoje pliki przy edycji pliku lub jego dodaniu.
Wskazówka
Jeśli posiadasz sklep wielojęzyczny, to we wszystkich tych wymienionych powyżej obszarach, znajdują się również obrazki dla danego języka. Pamiętaj, alby atrybut ALT zdefiniować dla każdego z nich!
 

Atrybut title - obowiązkowy czy nie?

Atrybut title jest przydatny do przekazywania dodatkowych informacji o elementach HTML, widocznych jako podpowiedź po najechaniu kursorem. Może być używany w ikonach bez podpisu, formularzach czy linkach, aby dostarczyć kontekst. Nie jest jednak obowiązkowy według WCAG, ponieważ czytniki ekranu często go ignorują, a osoby nawigujące klawiaturą mogą nie mieć do niego dostępu.  

Zalecenia dla udostępnianych treści - ogranicz migające elementy

Jako właściciel sklepu musisz sam zadbać o to, jakie treści umieszczasz na swojej stronie. Migające elementy, takie jak animacje czy reklamy, mogą wywoływać problemy u osób z padaczką fotogenną. Według kryteriów WCAG 2.1 zalecane jest ograniczenie migających treści do maksymalnie trzech błysków na sekundę lub ich całkowite usunięcie. Jako właściciel sklepu musisz dbać o statyczne elementy lub spokojne animacje. Również treści zawarte w różnego typu prospektach, gazetkach czy folderach informacyjnych w formie dokumentów powinny być zgodne z wytycznymi WCAG.

1.Obrazki i bannery

W szablonach graficznych takie elementy mogą pojawić się na przykład w bannerach i elementach tekstowych ze zdjęciem. Upewnij się, że grafiki tam zamieszczone są odpowiednie, czyli bez intensywnych animacji i nieodpowiednich kolorów. Szczególną uwagę zwróć na pliki w formacie GIF. Sprawdź, w jaki sposób możesz skonfigurować bannery oraz elementy tekstowe ze zdjęciem.  

2.Materiały audio i viedo

Aby sklep internetowy był w pełni dostępny zgodnie z WCAG, właściciele muszą zadbać o dodanie audiodeskrypcji i transkrypcji do materiałów multimedialnych (filmy, nagrania dźwiękowe). Choć oba rozwiązania służą poprawie dostępności, mają różne funkcje.
  • Audiodeskrypcja to dodatkowy opis dźwiękowy, który przedstawia istotne elementy wizualne nagrania osobom niewidzącym,
  • Transkrypcja to zapis tekstowy całej treści audio, umożliwiający odbiór treści osobom niesłyszącym, może to być w formie napisów dla audiodeskrypcji.
Dodanie tych elementów leży po stronie właścicieli sklepów. Do filmów, które udostępniasz, dodaj zatem widoczne napisy, a także dobrej jakości opis dźwiękowy. Ich brak może wykluczyć część użytkowników i wpłynąć na komfort korzystania ze strony. Dobre praktyki dostępności to nie tylko wymóg, ale też inwestycja w lepsze doświadczenie klientów.

Dostosuj komunikację mailową - aktualizacja lub zmiana treści e-mail

Dostosowanie treści e-mail zgodnie z wytycznymi WCAG to kluczowy krok w budowaniu dostępnej i klarownej komunikacji. W tej części artykułu przedstawiamy rozwiązania zarówno dla domyślnych wiadomości, jak i tych modyfikowanych, aby zapewnić ich lepszą czytelność i dostępność dla wszystkich odbiorców.

1.Treści mailowe są domyślne, nie zostały sformatowane

Jeśli treści nie zostały przez Ciebie zmienione i stanowią domyślne treści, które są dostępne w Comarch e-Sklep, to wystarczy, że zaktualizujesz je. Aby to zrobić, należy przejść w panelu administracyjnym do zakładki Ustawienia > Treści formalne, a następnie wybrać „Wysyłka e-mail i SMS”. Zakładka ta zawiera treści wiadomości wysyłane do klientów po wykonaniu określonych akcji, np. po zakupie czy rejestracji. W Comarch e-Sklep istnieje możliwość przywrócenia standardowej treści pojedynczej wiadomości e-mail lub wszystkich jednocześnie. Opcja ta stanowi również aktualizację treści e-mail. "Przywróć domyślną treść" dostępna jest w panelu administracyjnym e-Sklepu w menu Ustawienia/ Treści formalne/ Wysyłka e-mail i SMS na szczegółach każdej wiadomości, po kliknięciu w przycisk Więcej:  

2.Treści mailowe są modyfikowane, zostały przeze mnie zmienione

Jeśli posiadasz własne, dostosowane do Twojej komunikacji marketingowej treści e-mail, to sprawdź, czy są one odpowiednio napisane i sformatowane. Zastosuj się do poniższych wskazówek. W jaki sposób poprawnie napisać i sformatować treści?
  • Struktura Stosuj nagłówki (<h1>, <h2> itd.) dla przejrzystości. Używaj krótkich akapitów i list punktowanych.
  • Tekst i formatowanie Zapewnij wysoki kontrast między tekstem a tłem. Wybieraj czytelne czcionki (sans-serif, min. 12-14 px). Nie używaj wyłącznie koloru do przekazywania informacji.
  • Obrazy i multimedia Dodawaj tekst alternatywny (alt text) do obrazów. Unikaj tekstu osadzonego w grafikach, jeśli można go przesłać jako tekst.
  • Linki i przyciski Stosuj opisowe teksty linków zamiast „Kliknij tutaj”. Upewnij się, że są łatwe do kliknięcia na ekranach dotykowych.
  • Język i czytelność Używaj prostego i zrozumiałego języka. Unikaj skrótów i branżowego żargonu, jeśli odbiorca może ich nie znać.
  • Testowanie Sprawdź wiadomość na różnych urządzeniach i czytnikach ekranu. Zweryfikuj zgodność ze standardami WCAG.
Szczegółowe informacje na temat edycji treści e-mail znajdują się a artykule: E-mail i SMS  

3.Załączniki (m.in. instrukcje, katalogi)

Należy zadbać o to, aby wszystkie udostępniane w sklepie załączniki, takie jak instrukcje czy katalogi, były zgodne z wytycznymi WCAG, zapewniając tym samym ich pełną dostępność dla wszystkich użytkowników.  

Dodatkowe narzędzia pomocne przy wdrażaniu WCAG

Przystosowanie e-Sklepu do wymogów nie musi wiązać się z dużymi wydatkami na zmiany w kodzie. Kluczowe aspekty dostępności można wdrożyć samodzielnie, wykorzystując opcje dostępne w systemach Comarch ERP, a także Kreatorze Wyglądu czy Panelu Administracyjnym. Warto pamiętać, że poprawa dostępności to nie tylko obowiązek wynikający z przepisów, ale także realna szansa na zwiększenie grona klientów oraz podniesienie komfortu ich zakupów. Istnieje kilka ogólnodostępnych narzędzi, które pomogą Ci dostosować sklep do wymogów. Obszerna lista narzędzi do oceny dostępności stron internetowych, zgodnych z WCAG znajduje się na stronie: Web Accessibility Evaluation Tools List .  

Podsumowanie

Dostępność cyfrowa to nie jednorazowe przedsięwzięcie, lecz ciągły rozwój i udoskonalanie. Regularne sprawdzanie funkcjonalności, optymalizacja elementów wizualnych i dostosowywanie sposobów interakcji pozwalają na stałe podnoszenie jakości doświadczeń użytkowników. Dążenie do pełnej zgodności ze standardami WCAG 2.1/2.2 oraz wymogami Europejskiego Aktu o Dostępności (EAA) nie tylko ułatwia nawigację wszystkim odwiedzającym, ale także buduje pozytywny wizerunek i wzmacnia pozycję na rynku. Wdrażanie kolejnych usprawnień to inwestycja w przyszłość, która przynosi korzyści zarówno właścicielom, jak i ich klientom.

Jak dodać wiele linków do banneru top?

Wstęp

Banner top jest bannerem, który wyświetla się na samej górze witryny. Ma on na celu wyróżnić informacje, które chcesz przekazać swoim klientom. Z tego względu w ramach banneru top możesz dodać zarówno treść, jak również linki, które będą prowadzić do istotnych obszarów. Dzięki temu możesz zaprezentować klientom informacje o ofercie w Twoim sklepie. Wskazana prezentacja wielu linków możliwa jest w szablonach Topaz oraz Dla gastronomii.

Jak zaprezentować wiele linków w bannerze top?

Krok 1. Aby ustawić wskazany banner według własnych potrzeb przejdź do sekcji Wygląd sklepu > Ustawienia > Bannery. W tym miejscu powinien znajdować się banner o nazwie top: Krok 2. W ramach edycji banneru przejdź do sekcji Widok zaawansowany: Krok 3. Po otwarciu wskazanego widoku masz możliwość kilku opcji konfiguracji banneru top - w ramach domyślnych ustawień dla banneru wypełniona jest sama treść. Do banneru można dodać także link. W takim wypadku całość banneru top będzie klikalna, a wypełniony tekst zostanie zaprezentowany na środku banneru: Krok 4. Do banneru top można dodać dodatkowe linki. Należy to zrobić wchodząc do edycji banneru lub poprzez opcję Dodaj więcej linków: Krok 5. Z poziomu wskazanej opcji w zakładce Linki za pomocą przycisku plusa masz możliwość dodania linku: Następnie możesz wprowadzić nazwę, dodać link oraz zadecydować czy ma się on otwierać w nowym oknie:
Wskazówka
Aby prezentować wiele linków w szablonie należy uzupełnić link i nazwę dla linku domyślnego.
Dzięki dodaniu wielu linków masz możliwość ich prezentacji banneru top w następujący sposób:
    • Jeżeli w bannerze top wskazany został tekst: zostanie on przesunięty do lewej strony, a po prawej stronie w ramach tej opcji będzie wyświetlane do 4 linków:
    • W przypadku, gdy potrzebujesz więcej linków możesz zrezygnować z wypełnionego tekstu – dzięki temu na bannerze top będziesz mógł dodać do 6 linków:
Wskazówka
Opcja wielu linków w bannerze top jest możliwa do skonfigurowania wraz z odliczaniem czasu. W ramach takiej konfiguracji możliwe jest wyświetlenie do 4 linków. Informacje o konfiguracji banneru top z odliczaniem czasu można znaleźć w artykule Jak zaprezentować banner z odliczaniem czasu w szablonach B2C? W takim przypadku należy uzupełnić konfigurację linków, ustawić opcję odliczania czasu, jak również uzupełnić pole "Tekst". Dzięki temu banner top zyska następujący wygląd:
 

Dla Gastronomii - podstawowe informacje

Wstęp

Szablon jest dedykowany do sprzedaży jedzenia online, możliwy do swobodnej konfiguracji. Jest responsywny, dzięki czemu idealnie nadaje się do prezentacji przepisów, menu lub promocji produktów żywnościowych. Może zostać zastosowany zarówno do niewielkiej, lokalnej pizzerii, jak i do restauracji, piekarni czy cukierni. Wszystkie elementy są zaprojektowane tak, aby jak najlepiej zaprezentować ofertę oraz ułatwić użytkownikowi nawigację i szybkie złożenie zamówienia. Główne wyróżniki szablonu to:
  • dostosowana lista produktów w formie MENU,
  • popup z możliwością personalizacji zamówienia (dodanie kolejnych składników i dodatków),
  • wyświetlenie orientacyjnego czasu realizacji zamówienia,
  • komunikat o braku możliwości składania zamówienia w określonych dniach i godzinach,
  • możliwość ustawienia rejonu dostawy,
  • wyświetlanie alergenów.
Przejdź do naszego sklepu demonstracyjnego i zobacz, jak prezentuje się szablon dla gastronomii w Comarch e-Sklep. W niniejszym artykule zawarliśmy podstawowe informacje na temat funkcji dostępnych w szablonie. Dzięki udogodnieniom i możliwości edycji niektórych elementów możesz łatwo spersonalizować swój e-Sklep. Szczegółowe instrukcje z dedykowanymi konfiguracjami znajdziesz w artykule: Dla gastronomii - przewodnik konfiguracji. Szablon możesz dowolnie modyfikować z poziomu Kreatora Wyglądu dla sprzedaży detalicznej (B2C). Wystarczy, ze przejdziesz na stronę Kreatora i edytujesz szablon "Dla Gastronomii":  

Konfiguracja szablonu Dla Gastronomii w panelu administracyjnym

Z poziomu panelu administracyjnego możesz dokonywać edycji każdego elementu znajdującego się na stronie. Możesz także ustalać sposoby dostaw oraz płatności. Po przejściu do sekcji Wygląd sklepu/ Ustawienia dostępne są ustawienia dla zakładek: Ogólne, Strona główna, Dodatkowe, Zarządzanie strefą klienta oraz Zarządzanie kaflem produktu.
  • W zakładce Ogólne możesz dokonać zmian w motywie kolorystycznym Twojego e-Sklepu. Z tego poziomu również możesz dokonać m.in takich zmian, jak: prezentacja punktów odbioru osobistego, edycja terminu dostaw, ustalenie orientacyjnego czasu realizacji zamówienia czy określenie rejonu dostawy.
  • W zakładce Strona główna znajdują się ustawienia, które pomagają „układać” poszczególne elementy na stronie głównej. W tym miejscu możesz zdecydować, gdzie powinny wyświetlać się produkty, lookbook i bannery. Część wyświetlanych elementów możesz ukryć, a te które znajdują się w nagłówku, także wyróżnić.
  • W zakładce Dodatkowe widnieją ustawienia, dzięki którym możesz decydować o możliwości udostępniania towarów w poszczególnych mediach społecznościowych. Możesz włączyć prezentację tabeli alergenów na stronie towaru. Z tego poziomu możliwe jest również ustawienie poziomu zaokrągleń okien i przycisków w szablonie, a także zezwolenie na tłumaczenie strony przez Tłumacz Google.
  • W zakładce Zarzadzanie strefą klienta znajdziesz ustawienia listy elementów, które mają być widoczne dla niego po zalogowaniu do strefy klienta,
  • W zakładce Zarządzanie kaflem produktu możesz ustawić domyślny sposób wyświetlania menu (czyli towarów na liście) oraz zdecydować, czy Twoi klienci mogą kupować bezpośrednio z niego lub sekcji produktów proponowanych (na przykład promocji).

Ustawienia Strony Głównej

Ustawienia zawarte w tym miejscu odpowiadają za elementy, które wyświetlane są na stronie głównej. Możesz zmieniać ich kolejność, nazwę, ukryć je lub wyróżnić. W tym miejscu wyróżnia się następujące sekcje:

Ustawienia nagłówka strony

W nagłówku znajdują się następujące elementy:
  • Logotyp,
  • Odnośnik do listy z produktami (nasze produkty),
  • Blog,
  • Lookbook,
  • Informacje o firmie,
  • Kontakt,
  • Koszyk,
  • Możliwość wyboru języka i waluty w e-Sklepie.
W tym miejscu możesz nie tylko dodać link do nagłówka, ale także ustalić, czy i jakie odnośniki do stron mają być widoczne. Możliwa jest też zmiana kolejności wyświetlania poszczególnych elementów.

Ustawienia treści strony

Pozostając w obszarze Wygląd sklepu/ Ustawienia/ Strona główna możesz zmienić ustawienia treści strony. W tym miejscu również istnieje możliwość zmiany kolejności wyświetlania poszczególnych elementów na stronie głównej sklepu oraz ukrycia elementu.  

Elementy w szablonie

1. Nagłówek

W szablonie dla gastronomii dostępne są dwa rodzaje nagłówka: header-1 oraz header-6. Te rodzaje nagłówków dostępne są w Kreatorze i posiadają funkcję tzw. przyklejonego nagłówka. Przy przewijaniu strony u góry ekranu zawsze widoczny jest pasek z częścią elementów nagłówka (m.in. menu). Dzięki temu przeglądający ofertę w każdym miejscu strony ma dostęp do skróconej wersji nagłówka strony. Sekcja „Nagłówek” posiada dodatkowe opcje do ustawienia. Z listy menu, możesz decydować o:
  • Widoku wyszukiwanych towarów w nagłówku,
  • Wyświetlaniu top bannera,
  • Pokazywaniu rozwijanej listy towarów znajdującej się w koszyku.

2. Banner

W szablonie Dla Gastronomii udostępniliśmy sześć rodzajów bannerów. Z poziomu Kreatora Wyglądu możesz zdecydować, które z nich powinny znaleźć się na Twojej stronie. Aby dodać zdjęcia do banneru przejdź do zakładki Wygląd sklepu/ Ustawienia/ Bannery, a następnie klikając na kafelek o nazwie mainBanner wybierz odpowiednie zdjęcie.   
Banner poglądowy - banner-1
  Szczegóły na temat dodawania i edycji bannerów znajdują się w artykule: Bannery.  

3. Menu

W szablonie dla Gastronomii kupowanie jest możliwe bezpośrednio z listy. Menu, bo tak została nazwana sekcja z listą towarów, dostępne jest do prezentacji w dwóch wariantach: kafli oraz listy. Zmiana układu listy możliwa jest z poziomu panelu administracyjnego (Wygląd sklepu/ Ustawienia/ zakładka Zarządzanie kaflem produktu).

4. Popup – kupowanie z listy

Podczas kupowania bezpośrednio z menu wyświetli się popup, za pomocą którego możliwa jest personalizacja danego towaru: Dzięki temu klient w prosty i szybki sposób może wybrać dodatkowe składniki czy dodatki w postaci np. sosów. Może również wybrać rodzaj pieczywa czy rozmiar burgera.

5. Koszyk

W szablonie Dla Gastronomii składanie zamówienia jest szybkie i wygodne dla użytkownika. Koszyk został zaprojektowany tak, aby użytkownik mógł w jednym kroku wypełnić niezbędne dane: 
  • Formularz z danymi zamawiającego oraz danymi do faktury,
  • Sposób dostawy,
  • Sposób płatności,
  • Miejsce na wpisanie kodu rabatowego.
Po uzupełnieniu powyższych informacji można przejść do podsumowania, w którym prezentowane są wcześniej wprowadzone dane klienta. Oprócz tego w koszyku następuje sprawdzenie rejonu dostawy. Klient, po wpisaniu adresu, otrzyma natychmiast informację, czy znajduje się on w rejonie, gdzie dowozisz zamówienia. Dodatkowo, po finalizacji zamówienia, Klient zobaczy czas pozostały do jego realizacji:       W szablonie istnieje także możliwość wyświetlania w koszyku informacji o kwocie, której brakuje do darmowej dostawy.  Funkcja ta możliwa jest do uruchomienia z poziomu Panelu Administracyjnego w sekcji Wygląd sklepu/ Ustawienia/ Ustawienia szablonu/ Ogólne: Ustawienia można zmienić według własnego uznania. Po dokonaniu wyboru należy użyć opcji Zapisz i Publikuj.

6. Widget

Sekcja „Widget” pozwala dodać jeden z dwóch dostępnych wariantów, które pozwolą zaprezentować informacje, takie jak: zdjęcie, tytuł nagłówka, tekst przycisku, link do przycisku, a także opis. Widget można dodać podczas tworzenia szablonu dla Gastronomii w Kreatorze Wyglądu.

7. Lookbook

Widok ten charakteryzuje się prezentacją zdjęć w formie kafelków i precyzyjnym oznaczeniem towarów na zdjęciu. Dzięki znacznikom umieszczonym na grafice Twoi klienci będą mogli podejrzeć towar i dodać go bezpośrednio do koszyka. Po kliknięciu na przycisk wyświetli się popup ze szczegółami towaru oraz opcją zakupu.
Wskazówka
Rekomendowany rozmiar grafik do lookbooka to 560 x 500 px.
Aby poprawnie skonfigurować lookbook, skorzystaj z naszej instrukcji zawartej w artykule: Jak skonfigurować Lookbook w Comarch e-Sklep?

8. Blog

Prowadzenie bloga jest istotnym elementem sklepu internetowego. Dzięki niemu sprzedawca może dzielić się swoją wiedzą i spostrzeżeniami na temat reklamowanych produktów. W szablonie dla gastronomii blog możesz wykorzystać np. do prezentacji przepisów. Prowadzenie bloga ma również dobry wpływ na pozycjonowanie ze względu na unikalne treści. Dzięki temu Twój e-Sklep może częściej pojawiać się w wynikach wyszukiwania. W szablonie Dla Gastronomii masz możliwość tworzenia dowolnej ilości wpisów. Na stronie głównej wyświetlone zostaną trzy najnowsze. Użytkownik ma możliwość podglądu całej listy artykułów. Wystarczy, że kliknie w etykietę Najnowsze wpisy.   Szczegółowe informacje na temat konfiguracji bloga w e-Sklepie znajdują się w artykule: Jak skonfigurować blog?

9. Info-banner

Banner informacyjny pozwala na zaprezentowanie w przejrzysty sposób korzyści z zakupów w Twoim e-Sklepie. Modyfikacji tego obszaru dokonasz z poziomu panelu administracyjnego przechodząc do sekcji Wygląd sklepu/ Ustawienia/ Bannery. Następnie przechodząc do szczegółów banneru o nazwie info-banner dostosujesz element do swoich preferencji. Możesz skorzystać z domyślnych grafik lub dodać własne. Szczegółowe informacje na temat konfiguracji info-banneru znajdują się w artykule: Konfiguracja banneru informacyjnego w szablonie.

11. Element tekstowy ze zdjęciem

Element tekstowy ze zdjęciem charakteryzuje się możliwością wprowadzenia statycznego opisu na stronie głównej w twoim e-Sklepie. Możesz zawrzeć w nim np. podstawowe informacje na temat Twojej firmy, asortymentu lub inne wartościowe dla Ciebie treści. Element tekstowy możesz odpowiednio skonfigurować przechodząc do sekcji Wygląd sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane, a następnie do zakładki Obiekty, gdzie skonfigurujesz zawartość elementu.
Wskazówka
Za wyświetlanie elementu tekstowego w szablonie dla Gastronomii odpowiada obiekt o nazwie text-el-photo-mp-1.
Więcej informacji na temat konfiguracji znajduje się w artykule: Element tekstowy w szablonie.

11. Stopka

Dzięki modyfikacji obszaru możesz jeszcze bardziej spersonalizować swój sklep poprzez uzupełnienie stopki w szereg przydatnych informacji. Elementem tym możesz zarządzać z poziomu sekcji Wygląd Sklepu/ Ustawienia/ Nagłówek i Stopka.  Szczegółowe informacje na temat konfiguracji stopki znajdują się w artykule: Rozbudowana stopka w szablonach – jak ją skonfigurować?

12. Strefa Klienta

Do Strefy Klienta w szablonie Dla Gastronomii masz możliwość zalogowania się poprzez Facebooka oraz przez Google. Więcej na temat konfiguracji logowania przez Facebooka i Google znajdziesz tutaj.  

Dla Gastronomii - przewodnik konfiguracji

1. Wstęp

Szablon jest dedykowany do sprzedaży jedzenia online, możliwy do swobodnej konfiguracji. Jest responsywny, dzięki czemu idealnie nadaje się do prezentacji przepisów, menu lub promocji produktów żywnościowych. Może zostać zastosowany zarówno do niewielkiej, lokalnej pizzerii, jak i do restauracji, piekarni czy cukierni. Wszystkie elementy są zaprojektowane tak, aby jak najlepiej zaprezentować ofertę oraz ułatwić użytkownikowi nawigację i szybkie złożenie zamówienia. Główne wyróżniki szablonu to:
  • dostosowana lista produktów w formie MENU,
  • popup z możliwością personalizacji zamówienia (dodanie kolejnych składników i dodatków),
  • wyświetlenie orientacyjnego czasu realizacji zamówienia,
  • komunikat o braku możliwości składania zamówienia w określonych dniach i godzinach,
  • możliwość ustawienia rejonu dostawy,
  • wyświetlanie alergenów.
Szablon współpracuje z Comarch e-Sklep w każdej wersji (Light, Standard, Enterprice oraz B2B) oraz Comarch Betterfly, ERP XL oraz ERP Optima. Przejdź do naszego sklepu demonstracyjnego i zobacz, jak prezentuje się szablon dla gastronomii w Comarch e-Sklep. W tym artykule skupiliśmy się na prezentacji dedykowanych funkcji dla tego szablonu. Znajdziesz tu krótkie instrukcje konfiguracji. Podstawowe informacje na temat szablonu dla gastonomii znajdziesz w artykule: Dla gastronomii - podstawowe informacje.

2. Dedykowane konfiguracje

Szablon Dla Gastronomii posiada dedykowane funkcje, które są możliwe do swobodnej modyfikacji. Funkcje te nie są dostępne w innych, standardowych szablonach. W szablonie dla Gastronomii kupowanie jest możliwe bezpośrednio z listy. Menu, bo tak została nazwana sekcja z listą towarów, dostępne jest do prezentacji w dwóch wariantach: kafli oraz listy. Zmiana układu listy możliwa jest z poziomu panelu administracyjnego (Wygląd sklepu/ Ustawienia/ zakładka Zarządzanie kaflem produktu). Podczas kupowania bezpośrednio z menu wyświetla się popup, który posiada następujące informacje:
  • zdjęcie produktu,
  • opis,
  • możliwe do wyboru warianty,
  • dodatkowe produkty, ktore można umiejscowić pod nazwą „Składniki” czy „Dodatki”.
Dzięki temu możliwa jest personalizacja danego towaru, a Klient w szybki sposób może wybrać ekstra składniki czy dodatki w postaci np. sosów do dania głównego. Może również wybrać rodzaj pieczywa czy rozmiar burgera. Nad przyciskiem "dodaj do koszyka" znajduje się tzw. przycisk drugorzędny. Służy on do wpisania liczby, przez którą wartości wybrane w popupie oraz towar nadrzędny (jakim w tym przypadku jest burger) zostaną pomnożone.

2.1. Wybór wariantów - konfiguracja "rozmiar burgera" oraz "rodzaj pieczywa"

Burger został skonfigurowany jako fantom. Informacje takie jak "rozmiar burgera" czy "rodzaj pieczywa" to jego warianty. Instrukcję dotyczącą konfiguracji fantomów znajdziesz w artykule: Fantom (towar zgrupowany) – konfiguracja
Wskazówka
Na zrzucie ekranu w popupie widnieje fantom dwupoziomowy (rozmiar burgera i rodzaj pieczywa), co oznacza, że należy dodać dwa atrybuty grupujące na karcie towaru w systemie ERP.

2.2. Składniki i dodatki

"Składniki" oraz "dodatki" to towary proste, które klienci mogą dodać do dania głównego. Poprawnie skonfigurowane wyświetlą się na popupie podczas kupowania z listy. W systemach ERP definiowane są jako zamienniki lub towary podobne. Jest kilka rzeczy, o których musisz pamiętać podczas konfiguracji dodatków i składników:
  • towar nie może posiadać atrybutów grupujących,
  • produkty muszą mieć zdefiniowane przynajmniej jedno zdjęcie,
  • towar musi być zamiennikiem jednostronnym,
  • łączna ilość zamienników nie może przekraczać 20 towarów prostych. Ograniczenie to dotyczy każdego z niżej wskazanych systemów ERP.
Poniżej zamieściliśmy instrukcję konfiguracji dla poszczególnych systemów ERP.

2.3. Składniki

2.3.1. W jaki sposób zostały skonfigurowane "Składniki" w ERP Optima?

Towary znajdujące się w popupie jako "składniki" to zamienniki utworzone w systemie Comarch ERP Optima. Aby towar wyświetlił się poprawnie, należy: Krok 1. Utworzyć w systemie Comarch ERP Optima kategorię o nazwie i kodzie "INNE",
Wskazówka
Grupa musi być domyślną dla składników, które się w niej znajdują. Dodatkowo musi ona zostać dodana jako podgrupa grupy głównej, która została wybrana na definicji oddziału.
Krok 2. Utworzyć towar prosty (czyli np. dodatkowy ser), przyporządkować go do grupy INNE, Krok 3. Do towaru nadrzędnego (w tym przypadku burgera) dodać zamiennik jednostronny, Krok 4. Po wykonaniu synchronizacji produkty będą widoczne na popupie. Dodatkowo, produkty, które są w kategorii  "INNE" nie wyświetlą się w menu. Grupa ta nie jest także widoczna w menu kategorii.  

2.3.2 W jaki sposób zostały skonfigurowane "Składniki" w Comarch Betterfly?

Towary znajdujące się w popupie jako "składniki" to produkty podobne utworzone w systemie Comarch Betterfly. Aby towar wyświetlił się poprawnie, należy: Krok 1. Utworzyć w systemie Comarch Betterfly grupę produktów o nazwie "INNE", Krok 2. Utworzyć towar (np. dodatkowa szynka), przyporządkować go do grupy "INNE". Krok 3. Na karcie towaru nadrzędnego (w tym przypadku burgera) dodać produkt podobny (jednostronny), Krok 4. Po wykonaniu synchronizacji produkty będą widoczne na popupie. Dodatkowo, produkty, które są w kategorii  "INNE" nie wyświetlą się w menu. Grupa ta nie jest także widoczna w menu kategorii.  

2.3.3 W jaki sposób zostały skonfigurowane "Składniki" w ERP XL?

Towary znajdujące się w popupie jako "składniki", to produkty podobne utworzone w systemie Comarch ERP XL. Aby towar wyświetlił się poprawnie, należy: Krok 1. Utworzyć w systemie Comarch ERP XL grupę produktów o nazwie "INNE". Grupa musi zostać dodana jako podgrupa grupy głównej, która została wybrana na definicji oddziału,
Przyklad
Jeśli na definicji oddziału w zakładce Eksport/ Cennik wybierzesz grupę Szablon gastronomiczny: To należy w niej dodać podgrupę o nazwie "INNE".
Krok 2. Utworzyć towar prosty(np. szynka), przyporządkować go do grupy "INNE". Krok 3. Na karcie towaru nadrzędnego (w tym przypadku pizza hawajska) dodać zamiennik(jednostronny) w zakładce Zamienniki/ Zamienniki. Dodatkowo w edycji zamienników w zakładce "Miejsca w strukturze firmy" trzeba dodać oddział e-Sklepu, Krok 4. Po wykonaniu synchronizacji produkty z grupy "INNE" będą widoczne na popupie jako składniki, ale nie wyświetlą się jako osobna grupa "INNE" w menu kategorii.

2.4 Dodatki

2.4.1 W jaki sposób zostały skonfigurowane "Dodatki" w Comarch ERP Optima?

Towary znajdujące się w popupie jako "dodatki" to zamienniki utworzone w systemie Comarch ERP Optima. Aby towar wyświetlił się poprawnie, należy: Krok 1. Utworzyć towar prosty (czyli np. oliwa z oliwek), przyporządkować go do grupy, która jest udostępniona do e-Sklepu, najwygodniej jeśli posiada ona nazwę "DODATKI". Krok 2. Do towaru nadrzędnego (w tym przypadku burgera) dodać zamiennik jednostronny, Efekt: Po wykonaniu synchronizacji produkty będą widoczne na popupie. Dodatkowo, produkty z kategorii "DODATKI" wyświetlą się w menu, a grupa będzie widoczna w menu kategorii.

2.4.2 W jaki sposób zostały skonfigurowane "Dodatki" w Comarch Betterfly?

Towary znajdujące się w popupie jako "dodatki" to produkty podobne utworzone w systemie Comarch Betterfly. Aby towar wyświetlił się poprawnie, należy: Krok 1. Utworzyć towar (np. sos czosnkowy), przyporządkować go do grupy, która jest udostępniona do e-Sklepu, najwygodniej o nazwie "DODATKI" lub innej. Krok 2. Do towaru nadrzędnego (w tym przypadku burgera) dodać produkt podobny (jednostronny), Efekt: Po wykonaniu synchronizacji produkty będą widoczne na popupie jako dodatki. Kategoria "DODATKI" wyświetli się w Menu, obok innych kategorii stworzonych w systemie Comarch Betterfly.

2.4.3 W jaki sposób zostały skonfigurowane "Dodatki" w Comarch ERP XL?

Towary znajdujące się w popupie jako "dodatki" to zamienniki utworzone w systemie Comarch ERP XL. Aby towar wyświetlił się poprawnie, należy: Krok 1. Utworzyć towar prosty (czyli np. cola), przyporządkować go do grupy, która jest udostępniona do e-Sklepu, najwygodniej o nazwie "DODATKI". Krok 2. Na karcie towaru nadrzędnego (w tym przypadku pizza hawajska) dodać zamiennik(jednostronny) w zakładce Zamienniki/ Zamienniki. Dodatkowo w edycji zamienników w zakładce "Miejsca w strukturze firmy" trzeba dodać oddział e-Sklepu, Efekt: Po wykonaniu synchronizacji produkty będą widoczne na popupie. Dodatkowo, produkty z kategorii "DODATKI" wyświetlą się w menu kategorii, które widoczne jest nad menu  

3. Alergeny

Szablon dla Gastronomii został dostosowany do wyświetlania tabel z alergenami, które mogą znaleźć się w produktach. Alergeny możesz wyświetlić zatem za pomocą:
  • konfiguracji banneru „Tabela”,
  • dodania dowolnej treści na stronie użytkownika,
  • oznaczeniu ich jako atrybuty. 

3.1. Alergeny jako atrybuty - widoczność na szczegółach towaru - Konfiguracja ERP Optima

Aby dodać spis produktów lub substancji uczulających, który zostanie wyświetlony w zakładce "Alergeny" widocznej na szczegółach towaru, należy: Krok 1. Utworzyć w ERP Optima atrybut tekstowy o nazwie ALERGENY Krok 2. Atrybut należy dodać do towaru, na którym na być widoczny. Aby to zrobić, należy przejść z pozycji cennika do zakładki Atrybuty Krok 3. W polu "wartość" należy wpisać alergeny, które mogą się znaleźć w produkcie. Pole to posiada ograniczenie ilości znaków . W tym wypadku, jeśli zabraknie miejsca, to możliwe jest utworzenie kolejnego atrybutu, tym razem o nazwie ALERGENY_DWA. Kolejno można tworzyć atrybuty ALERGENY_TRZY itd. Efekt: Po synchronizacji alergeny zostaną wyświetlone na szczegółach towaru w zakładce "Alergeny"      

3.2. Alergeny jako atrybuty - widoczność na szczegółach towaru - Konfiguracja Comarch Betterfly

Aby dodać spis produktów lub substancji uczulających, który zostanie wyświetlony w zakładce "Alergeny" dostępnej na szczegółach towaru, należy: Krok 1. Utworzyć w systemie Comarch Betterfly atrybut o nazwie ALERGENY Krok 2. Atrybut należy dodać do towaru, na którym ma być widoczny. Aby to zrobić, należy przejść na kartę towaru w zakładkę e-Sklep: Krok 3. W polu "wartość PL" należy wpisać alergeny, które mogą się znaleźć w produkcie. Pole to posiada ograniczenie. W tym wypadku, jeśli zabraknie miejsca, to możliwe jest utworzenie kolejnego atrybutu, tym razem o nazwie Alergeny_dwa. Kolejno można tworzyć atrybuty Alergeny_trzy itd. Efekt: Po synchronizacji alergeny zostaną wyświetlone na szczegółach towaru w zakładce "Alergeny"  

3.3. Alergeny jako atrybuty - widoczność na szczegółach towaru - Konfiguracja ERP XL

Krok 1. Utworzyć w systemie ERP XL atrybut tekstowy o nazwie ALERGENY Krok 2. Atrybut należy dodać do towaru, na którym na być widoczny. Aby to zrobić, należy przejść z pozycji cennika do zakładki Atrybuty: Krok 3. W polu "wartość" należy wpisać alergeny, które mogą się znaleźć w produkcie. Pole to posiada ograniczenie ilości znaków . W tym wypadku, jeśli zabraknie miejsca, to możliwe jest utworzenie kolejnego atrybutu, tym razem o nazwie ALERGENY_DWA. Kolejno można tworzyć atrybuty ALERGENY_TRZY itd. Efekt: Po synchronizacji alergeny zostaną wyświetlone na szczegółach towaru w zakładce "Alergeny"  

4. Określenie i walidacja obszaru dostawy

W szablonie dla Gastronomii możesz określić obszar dostawy. Możesz to zrobić na dwa sposoby: określenie za pomocą kodu pocztowego oraz mapy. Aby użyć funkcji w swoim e-Sklepie należy: Krok 1. Przejść do panelu administracyjnego, a następnie do zakładki Wygląd Sklepu/ Ustawienia/ zakładka Ogólne.  Krok 2. Następnie odnajdź "obszar dostaw" i określ obszar dostawy za pomocą mapy lub kodów pocztowych. Możesz zrezygnować z określania obszaru dostawy, wybierając opcję "nie określaj obszaru".

4.1. Określenie obszaru za pomocą mapy

Krok 1. Aby określić obszar za pomocą mapy wybierz odpowiednią opcję z listy. Po zaznaczeniu "Mapy" ukaże się mała mapa. Kliknij niebieski przycisk "wybierz obszar", po czym ustaw odpowiednio pinezki. Krok 2. Następnie, po określeniu obszaru, zapisz obszar, wybierając przycisk znajdujący się poniżej mapki. Efekt: Po zapisaniu obszaru na mapie zaznaczony będzie odpowiedni, określony przez Ciebie rejon. Aby zmienić lub usunąć obszar, wystarczy wybrać przycisk "wyczyść obszar", który pojawi się w lewym, dolnym rogu poniżej mapy. Zmiany należy zapisać i opublikować.

4.2. Określenie obszaru za pomocą kodu pocztowego

Krok 1. Aby określić obszar za pomocą kodu pocztowego wybierz odpowiednią opcję z listy. Krok 2. Po zaznaczeniu "Kodów pocztowych" ukaże się obszar, w którym należy wpisać obsługiwane kody. Po wpisaniu kodu, aby dodać kolejny, kliknij "Dodaj kod pocztowy". Zmiany należy zapisać i opublikować. Efekt: Wprowadzone przez Ciebie kody pocztowe będą widoczne w panelu administracyjnym. Możesz je usunąć poprzez kliknięcie krzyżyka. Nie ma ograniczeń ilości dodawanych kodów. Efekt w e-Sklepie: Klient po uzupełnieniu danych zamawiającego otrzyma od razu informację, czy jego adres znajduje się w obszarze dostawy.  

5. Realizacja zamówień

W szablonie dla Gastronomii możesz określić orientacyjny czas realizacji zamówienia, a także określić, kiedy jest ono możliwe do złożenia.

5.1. Orientacyjny czas realizacji zamówienia

Krok 1. Aby włączyć funkcję wystarczy przejść z poziomu panelu administracyjnego do obszaru Wygląd sklepu/ Ustawienia/ zakładka Ogólne po czym odnaleźć sekcję "Realizacja zamówień". Krok 2. Następnie w "Orientacyjny czas realizacji zamówienia" należy wpisać czas, w jakim zazwyczaj dostarczasz zamówienie:   Efekt: Po złożeniu zamówienia Twoi Klienci zobaczą thank you page z odliczaniem czasu do realizacji:

5.2. Zezwól na składanie zamówień tylko w wybranym zakresie godzin

We wspomnianym obszarze "Realizacja zamówień" istnieje także funkcja, która pozwala na składanie zamówień tylko w wybranym zakresie godzin oraz blokowaniu składania zamówień w wybrane dni (np. święta). Krok 1. Aby ją uruchomić, wystarczy zaznaczyć checbox " Zezwój na składanie zamówień tylko w wybranym zakresie czasu" Krok 2. W tym miejscu możesz ustawić godziny oraz dni, w których klienci mogą składać zamówienia. Zapisz wprowadzone godziny. Jeśli chcesz usunąć "aktualnie zablokowane daty dostaw" , naciśnij krzyżyk znajdujący się po prawej stronie określonej daty. Efekt: Klient przeglądający menu przy próbie złożenia zamówienia w czasie, którego nie obejmuje zakres realizacji zamówień, zobaczy wówczas następujący komunikat:    

Szablon Opal

Szablon Opal

Wskazówka
Od 1 czerwca 2025 roku zakończyliśmy aktualizację oraz wydawanie nowych wersji szablonów Bursztyn, Agat i Opal, a tym samym ich wsparcie, aby skupić się na nowoczesnych rozwiązaniach, które jeszcze lepiej odpowiadają na potrzeby dynamicznie rozwijającego się rynku e-commerce. Zachęcamy Was do przejścia na nasze nowe, udoskonalone szablony. Dla sklepów B2C polecamy szablony Topaz, One Page Shop oraz Dla Gastronomii, natomiast dla platform B2B idealnym wyborem będą Rubin i Szafir.
      Główne wyróżniki szablonu:
  1. Nawigacja w szablonie
    • Podstawowe akcje w nagłówku (logowanie, wyszukiwanie, koszyk, profil klienta) w formie ikon.
    • Duży banner na stronie głównej w formie kafelków ułatwia prezentację aktualnych promocji lub konkretnych kategorii towarowych.
    • Lista produktów na stronie głównej, która idealnie zaprezentuje nowości, promocje, towary rekomendowane itp.
    • Graficzne menu producentów w formie slidera.
    • Płytkie dwupoziomowe menu w połączeniu z filtrami na liście produktów daje możliwość wygodnej i szybkiej nawigacji.
    • Graficzne menu kategorii na stronie „produkty”
    • Rozwijalna stopka.
  2. Towary
    • Produkty na liście danej kategorii zaprezentowane na dużych przejrzystych kafelkach.
    • Drugie zdjęcie towaru oraz jego warianty (np. kolor, rozmiar) wyświetlane po najechaniu kursorem na towar.
    • Warianty towaru wyświetlane są w takiej kolejności w jakiej zostały dodane w systemie ERP.
    • Bezpośrednie przejście na szczegóły produktu w wybranym wariancie.
    • Prezentacja stanów magazynowych w formie komunikatu „zostały ostatnie sztuki”.
    • Atrybuty grupujące wyświetlane jako kafelki. Dla wariantów kolorystycznych przedstawione w formie miniaturek zdjęć.
    • Zestawy na towarze w formie slidera.
    • Sekcja „polecane” prezentująca zamienniki.
    • Funkcja „powiadom o dostępności”
  3. Zamówienie
    • Wybór akcji podczas dodawania do koszyka.
    • Możliwość rejestracji na zamówieniu.
    • Macierz dostaw w formie kafelków.
    • Wybór paczkomatów i punktów odbioru osobistego z mapy.
    • Reklamacje i zwroty do zrealizowanych zamówień dostępne w profilu klienta,
    • Ponowienie nieudanej płatności dostępne zarówno dla klientów zarejestrowanych jak i jednorazowych,
    • Widok szczegółów złożonego zamówienia dla niezalogowanych klientów.
W szablonie graficznym Opal istnieje możliwość wyłączenia ukrywania stopki. W zależności od preferencji może być domyślnie zwinięta lub rozwinięta. Można to zmienić w ustawieniach szablonu w menu Wygląd sklepu/Ustawienia. W Profilu Klienta na liście zamówień widnieje informacja o statusach dostawy i płatności poszczególnych dokumentów. Wytyczne dla szablonu Opal znajdziesz w artykule Konfiguracja fantomów dla szablonu Opal Więcej o darmowych szablonach przeczytasz w artykule Gotowe szablony Comarch

Szablon Agat

Szablon Agat

Wskazówka
Od 1 czerwca 2025 roku zakończyliśmy aktualizację oraz wydawanie nowych wersji szablonów Bursztyn, Agat i Opal, a tym samym ich wsparcie, aby skupić się na nowoczesnych rozwiązaniach, które jeszcze lepiej odpowiadają na potrzeby dynamicznie rozwijającego się rynku e-commerce. Zachęcamy Was do przejścia na nasze nowe, udoskonalone szablony. Dla sklepów B2C polecamy szablony Topaz, One Page Shop oraz Dla Gastronomii, natomiast dla platform B2B idealnym wyborem będą Rubin i Szafir.
    Główne wyróżniki szablonu:
  1. Nawigacja w szablonie
    • Podstawowe akcje w nagłówku (logowanie, rejestracja, koszyk, profil klienta) w formie opisanych ikon,
    • Lista produktów na stronie głównej, która idealnie zaprezentuje nowości, promocje, towary rekomendowane itp.,
    • Duży banner w formie karuzeli z widocznymi brzegami zdjęć sąsiednich,
    • Głębokie wielopoziomowe menu na liście produktów oraz 3 poziomowe menu główne,
    • Graficzne menu kategorii na stronie „produkty”,
    • Duże zdjęcia kategorii na liście produktów,
    • Ostatnio przeglądane towary na stronie głównej.
  2. Towary
    • Bardzo duże zdjęcia na szczegółach produktu idealnie prezentujące asortyment,
    • Prezentacja stanów magazynowych w formie liczbowej i graficznej,
    • Atrybuty grupujące wyświetlane jako kafelki,
    • Zestawy na towarze w formie slidera,
    • Sekcje prezentujące towary podobne (zamienniki), towary typu akcesoria i towary polecane,
    • Mechanizm w postaci lupy, pozwalający na powiększanie zdjęcia na szczegółach towaru.
  3. Zamówienie
    • Wybór akcji podczas dodawania do koszyka,
    • Możliwość rejestracji na zamówieniu,
    • Macierz dostaw w formie kafelków w dwóch kolumnach (dostawa i płatność),
    • Wybór paczkomatów i punktów odbioru osobistego z mapy,
    • Ponowienie nieudanej płatności dostępne zarówno dla klientów zarejestrowanych jak i jednorazowych,
    • Widok szczegółów złożonego zamówienia dla niezalogowanych klientów.
W przypadku dużej ilości kategorii będzie wyświetlana druga linia menu. W Profilu Klienta na liście zamówień widnieje informacja o statusach dostawy i płatności poszczególnych dokumentów. Więcej o darmowych szablonach przeczytasz w artykule Gotowe szablony Comarch

Szablon Bursztyn

Szablon Bursztyn

Wskazówka
Od 1 czerwca 2025 roku zakończyliśmy aktualizację oraz wydawanie nowych wersji szablonów Bursztyn, Agat i Opal, a tym samym ich wsparcie, aby skupić się na nowoczesnych rozwiązaniach, które jeszcze lepiej odpowiadają na potrzeby dynamicznie rozwijającego się rynku e-commerce. Zachęcamy Was do przejścia na nasze nowe, udoskonalone szablony. Dla sklepów B2C polecamy szablony Topaz, One Page Shop oraz Dla Gastronomii, natomiast dla platform B2B idealnym wyborem będą Rubin i Szafir.
    Główne wyróżniki szablonu:
  1. Nawigacja w szablonie
    • Duży banner na stronie głównej w formie przewijalnego slidera ułatwia prezentację aktualnych nowości.
    • Dodatkowe bannery na dole strony idealne do zaprezentowania promocji w sklepie.
    • Lista produktów na stronie głównej, która zaprezentuje nowości, promocje, towary rekomendowane itp.
    • Graficzne menu producentów w formie slidera.
    • Towary polecane na stronie głównej.
    • Dwa rodzaje menu do wyboru w połączeniu z filtrami na liście produktów daje możliwość wygodnej i szybkiej nawigacji:
      • Dwupoziomowe menu poziome.
      • Wielopoziomowe menu pionowe z opcją prezentacji zdjęć kategorii.
  2. Towary
    • Lookbook – prezentacja zdjęć kolekcji lub katalogu z naniesionymi odnośnikami do towarów dostępnych w sklepie.
    • Produkty na liście danej kategorii w formie kafelków z możliwością bezpośredniego dodania do koszyka.
    • Atrybuty grupujące wyświetlane jako listy rozwijalne.
    • Zestawy promocyjne prezentowane na karcie towaru
    • Sekcja „polecane” prezentująca zamienniki.
    • Statusy dostępności na szczegółach produktu.
    • Funkcja „powiadom o dostępności”.
    • Funkcja porównywania produktów. Stany magazynowe w oknie Porównaj wyświetlają się w formie opisowej oraz obrazkowej.
  3. Zamówienie
    • Wybór akcji podczas dodawania do koszyka.
    • Macierz dostaw w formie czytelnej listy sposobów dostaw z podpiętymi sposobami płatności,
    • Wybór paczkomatów Inpost,
    • Reklamacje i zwroty do zrealizowanych zamówień dostępne w profilu klienta,
    • Ponowienie nieudanej płatności dostępne zarówno dla klientów zarejestrowanych jak i jednorazowych,
    • Widok szczegółów złożonego zamówienia dla niezalogowanych klientów.
W Profilu Klienta na liście zamówień widnieje informacja o statusach dostawy i płatności poszczególnych dokumentów. Więcej o darmowych szablonach przeczytasz w artykule Gotowe szablony Comarch.

Kreator sklepu hurtowego (B2B)

Szablon Rubin - podstawowe informacje

Wstęp

Szablon Rubin jest dedykowany dla sklepów w wersji B2B. Wyróżnia się nowoczesnym wyglądem zgodnym z najnowszymi trendami oraz intuicyjną nawigacją, co pozwala na szybkie i komfortowe zakupy. Oferuje funkcje dedykowane dla modelu B2B, w tym umożliwia wykorzystanie Comarch e-Sklep Sync do wyświetlania zamówień, faktur i wydań zewnętrznych z systemu ERP. Przy pomocy Kreatora wyglądu, można dostosować układ elementów szablonu względem indywidualnych oczekiwań. Elastyczność konfiguracji szablonu sprawia, że jest on idealnym rozwiązaniem dla zróżnicowanych potrzeb biznesowych. Główne wyróżniki szablonu:
  • obsługa sprzedaży dla klientów biznesowych oraz indywidualnych,
  • intuicyjna nawigacja boczna pozwalająca na szybki przegląd towarów dodanych do koszyka bądź zapytania o wycenę,
  • trzy widoki listy towarów, w tym lista pozwalająca na jednoczesne dodawanie wielu towarów zarówno do koszyka, jak i do list zakupów,
  • szczegóły towaru z paskiem nawigacji przyklejonym do nagłówka, który podczas przeglądania szczegółów oferty umożliwia natychmiastowy dostęp do najważniejszych sekcji i funkcji – w tym możliwość szybkiego dodania towaru do koszyka,
  • koszyk z rekomendacjami produktów oraz jednostronną finalizacją, ułatwiającą zakup,
  • profil klienta pozwalający na łatwą identyfikację statusów zamówień oraz dostęp do faktur i wydań zewnętrznych z systemu ERP,
  • obsługa wielu list zakupów,
  • możliwość składania zapytań o wycenę produków.
Przejdź do naszego sklepu demonstracyjnego i zobacz, jak wygląda Szablon Rubin w Comarch e-Sklep! W tym artykule zawarliśmy podstawowe informacje na temat funkcji dostępnych w szablonie. Dzięki możliwości konfiguracji elementów szablonu możesz łatwo spersonalizować swój e-Sklep.

Obsługa sprzedaży dla klientów biznesowych

Jako że szablon Rubin został zaprojektowany, aby umożliwić sprzedaż dla klientów biznesowych, obsługuje on funkcje dostosowane do modelu B2B. W ramach przykładowych udogodnień oferowanych przez szablon należy wymienić możliwości, takie jak:
  • obsługa klientów detalicznych oraz typu firma – połączenie modeli B2B oraz B2C,
  • możliwość włączenia tylko cen netto,
  • obsługa wielu koszyków (z możliwością edycji nazwy koszyka i usuwania całego koszyka jednym przyciskiem),
  • obsługa wielu list zakupowych, ułatwiająca powtórne zakupy tych samych towarów.
  • wyświetlanie zamówień, faktur i wydań zewnętrznych z systemu ERP w profilu klienta dzięki wykorzystaniu Comarch e-sklep Sync,
  • możliwość włączenia limitów kredytowych,
  • opcja dostępu do sklepu tylko dla zalogowanych użytkowników,
  • możliwość dodawania pracowników w profilu klienta,
  • opiekun handlowy dla kontrahenta.

Konfiguracja szablonu Rubin w panelu administracyjnym

Z poziomu panelu administracyjnego możesz dokonywać konfiguracji opcji wyglądu szablonu. Po przejściu do sekcji Wygląd sklepu > Ustawienia dostępne są ustawienia dla czterech zakładek:
  • W zakładce Ogólne możesz dokonać zmian w motywie kolorystycznym Twojego e-Sklepu. Z tego poziomu również możliwe do konfiguracji są takie opcje jak: ustawienia ceny netto, prezentacja promocji, rabatów progowych czy jednostek pomocniczych.
  • W zakładce Strona główna znajdują się ustawienia, dzięki którym możesz ustalić kolejność poszczególnych elementów na stronie głównej. Dodatkowo możesz zarządzać animacjami na poszczególnych bannerach i sliderach.
  • W zakładce Lista towarów znajdują się ustawienia dotyczące filtrów czy wyświetlania opisu danej kategorii towarowej. Z tego miejsca można zarządzać prezentacją informacji na kaflach w ramach listy.
  • W zakładce Zarzadzanie strefą klienta znajdziesz ustawienia elementów, które mają być widoczne po zalogowaniu do strefy klienta.

Strona główna

Strona główna w sklepie internetowym pełni rolę wprowadzenia do oferty sklepu. Jej głównym celem jest przyciągnięcie uwagi odwiedzających, zaprezentowanie najważniejszych produktów czy aktualnych promocji. Z tego względu na stronie głównej do skonfigurowania możliwe są takie elementy jak:

  • Banner w formie slidera – ustawienia dla banneru można znaleźć w sekcji Wygląd sklepu > Ustawienia > Bannery po przejściu do sekcji mainBanner. Domyślny rozmiar dla obrazka we wskazanym bannerze wynosi: 1574px x 425px. Więcej o ustawieniach można przeczytać w artykule dotyczącym konfiguracji bannerów.
  • Banner z infografikami – pozwala na zaprezentowanie korzyści z zakupów w Twoim sklepie. Domyślny rozmiar obrazków wynosi: 48px x 48px. Edycja banneru jest możliwa z poziomu opcji Wygląd sklepu > Ustawienia > Bannery po przejściu do sekcji homepage-small.
  • Banner popup – pozwala na poinformowanie klientów o bieżącej ofercie czy rabatach. Domyślny rozmiar grafiki w bannerze wynosi: 330px x 418px. Edycja banneru jest możliwa z poziomu opcji Wygląd sklepu > Ustawienia > Bannery po przejściu do sekcji banner_popup1.
 
  • Zapis do newslettera – newsletter to jeden z kluczowych elementów każdej strony internetowej, który pozwala na utrzymywanie kontaktu z użytkownikami i budowanie bazy subskrybentów. W przypadku szablonu Rubin, sekcja z zapisem do newslettera jest możliwa do ustawienia w formie stałej sekcji na stronie głównej.
Możliwe jest także zaprezentowania zapisu do newslettera w formie banneru.
  • Towary polecane – slider z wybranymi towarami. Mogą to być na przykład towary z wybraną flagą, najczęściej kupowane na sklepie lub ustawione ręcznie z poziomu Panelu Administracyjnego. Elementy te możliwe są do edycji w zakładce Wygląd Sklepu > Ustawienia > Edytuj ustawienia zaawansowane > Obiekty po przejściu do obiektu new-product-mp-x. Więcej informacji można znaleźć w ramach artykułu dotyczącego wyświetlania towarów polecanych w szablonach.
  • Tekst SEO – wskazany element charakteryzuje się możliwością wprowadzenia statycznego opisu na stronie głównej w e-Sklepie. Aby ustawić treść, przejdź do zakładki Wygląd Sklepu > Ustawienia > Edytuj ustawienia zaawansowane > Obiekty. W tym miejscu należy odszukać obiekt text-element-1-mp-1 i edytować element tekstowy.
  • Aktualności – w tej sekcji znajdziesz najnowsze artykuły z bloga w formie slidera. Każdy wpis zawiera obrazek, tytuł, krótki fragment treści, a także tagi tematyczne oraz datę ostatniej aktualizacji.
  • Slider marek oraz slider producentów – w ramach wskazanych sliderów będą pokazywały się loga marek i producentów, uzupełnionych po stronie systemów Comarch ERP.

Lista towarów

1. Widoki list towarów

Lista towarów zawiera trzy różne widoki. W zakładce Wygląd sklepu > Ustawienia > Lista towarów jest możliwość wybrania domyślnego widoku: Każdy z nich ma inne zastosowanie i cechy charakterystyczne:
  • W ramach widoku kafli użytkownicy mają możliwość szybkiego dodania pojedynczej sztuki towaru:
  • W przypadku listy z rozbudowanym kaflem, możesz zaprezentować opis towaru lub jego atrybutów zgodnie z ustawieniem:

Z poziomu kafli dostępne są również dodatkowe akcje, takie jak dodanie do zapytania o wycenę, list zakupów czy do porównania. Co więcej, dla wskazanej listy, została dodana możliwość kopiowania kodu towaru.

  • Szybka lista charakteryzuje się możliwością dodania wielu towarów jednocześnie. Na wskazanej liście jest możliwość dodawania równocześnie kilku towarów zarówno do listy zakupów, jak i do koszyka:
W przypadku ustawień dla widoków szybkiej listy i rozbudowanych kafli, istnieje możliwość ustalenia ilości wyświetlanych atrybutów:

2. Graficzna prezentacja wariantów

W ramach kafli możesz ustawić graficzną prezentację wariantów – po najechaniu na kafel zostaną zaprezentowane atrybuty w postaci:
  • miniatur zdjęć,
  • wariantów kolorystycznych,
  • wartości tekstowej.
Wskazaną prezentację można włączyć po przejściu do opcji Wygląd sklepu > Ustawienia > Lista towarów. W tym miejscu można wybrać sposób prezentacji wariantów:

3. Opis kategorii

Na liście towarów możesz wyświetlić także opis danej kategorii dodany po stronie systemu Comarch ERP. Jest on zaprezentowany w szablonie w następującej formie: Jeżeli został on wypełniony, możesz zdecydować czy ma być on domyślnie zwinięty czy rozwinięty:

4. Panel filtra

W ramach ustawień listy towarów do dostosowania możliwe są też filtry. Z tego poziomu dostępne do skonfigurowania są następujące opcje:
  • Liczba wyświetlanych wartości, która wskazuje ile domyślnie będzie pokazanych elementów danego filtra przed przyciskiem „Pokaż więcej”:

W przypadku takiego ustawienia przed wskazanym przyciskiem będzie prezentowane pięć wartości filtra – reszta zostanie zaprezentowana po rozwinięciu:

  • Filtruj po użyciu przycisku „Zastosuj”:

Zgodnie z ustawieniem filtry będą działać dopiero po kliknięciu wskazanego przycisku. Jeżeli parametr jest ustawiony na „Nie”, lista będzie filtrować się dynamicznie po wybraniu filtra.

  • Domyślne ustawienie filtrów jako zwiniętych bądź rozwiniętych:
Wskazane ustawienie wpływa na to, czy po wejściu na listę towarów będą wskazane wartości filtrów czy zostaną one zaprezentowane dopiero po rozwinięciu:
  • Wskazanie elementów, które mają być prezentowane w panelu filtrów:
  • Graficzna prezentacja filtra typu kolor, którą należy skonfigurować zarówno w Panelu administracyjnym, jak i systemie Comarch ERP według instrukcji. Po wykonaniu odpowiednich kroków, kolory będą prezentować się następująco:

Szczegóły towaru

1. Sekcja z towarem

W ramach szczegółów towaru możemy wyróżnić sekcje z towarem. W jej ramach prezentowane są zdjęcia towarów oraz informacje towarze, takie jak: 
  • Ceny, w tym prezentację:
  • Jednostki miary oraz przeliczniki do jednostki podstawowej lub domyślnej.
  • Stan magazynowy.
  • Dostępność produktu.
  • Cechy towaru.
  • Informacja o wartości dostawy danego towaru.
  • Możliwość udostępnienia towaru w social mediach lub za pomocą linku.
  • Opcję „Zapytaj o towar” bądź „Zapytaj opiekuna” w zależności od konfiguracji.
W tym miejscu klienci mają także dostęp do dodatkowych opcji takich jak:
  • Tabela rozmiarów – możliwa do ustawienia z poziomu ustawień Wygląd sklepu > Ustawienia > Ogólne. Tabela rozmiarów jest możliwa do skonfigurowania w formie strony, pliku pdf lub popupu.
  • Sprawdź dostępność w salonie – dzięki wskazanemu elementowi, potencjalni klienci będą mieli okazję sprawdzić, czy dany towar znajduje się w sklepie stacjonarnym (salonie). Funkcja jest dostępna po spełnieniu odpowiednich wymagań konfiguracyjnych opisanych w artykule: Sprawdź dostępność towaru w salonie.
  • Historia zakupów – dla sklepów w wersji B2B, powiązanych z systemem Comarch ERP XL oraz aktywną usługą e-Sklep Sync, możliwe jest włączenie wskazanego ustawienia w opcjach Wygląd sklepu > Ustawienia > Ogólne:

Dzięki temu możliwe będzie wskazanie historii zakupów z ostatnich 6 miesięcy

  • Harmonogram dostaw – funkcja służy do sprawdzania, czy towar został zamówiony u dostawcy, jak również udostępnia informacje o zamówionej ilości oraz planowanej dostawie. Więcej informacji na jej temat można przeczytać w artykule udostępnionym w Centrum Pomocy.
Poniżej wskazanych informacji o towarze znajdują się dodatkowe sekcje. Podczas przewijania strony widoczna jest nawigacja przyklejona do nagłówka, która ułatwia szybkie dodanie towaru do koszyka.

2. Opis i specyfikacja

W pierwszej kolejności wskazane są opis i specyfikacja danego towaru. Wskazane elementy takie jak opis czy atrybuty towaru są możliwe do dodania po stronie systemów Comarch ERP.

3. Podmiot odpowiedzialny

Zgodnie z rozporządzeniem GPSR w szablonie możliwe jest zaprezentowanie podmiotów odpowiedzialnych. Konfiguracja w ramach wyświetlenia wskazanych informacji w szablonie została opisana w artykule: Jak dostosować e-Sklep do wymogów Rozporządzenia GPSR?

4. Opinie o towarze

Na szczegółach towaru możliwe do wyświetlenia są opinie o towarze. Sekcja jest wzbogacona o paski informujące o ilości poszczególnych ocen. Obsłużone zostało również zgłaszanie opinii zgodnie z Aktem o usługach cyfrowych DSA.

5. Pliki do pobrania

Sekcja z plikami do pobrania zwiera pliki załączone na karcie towaru po stronie systemu Comarch ERP:

6. Zestawy

W przypadku korzystania z systemu Comarch ERP Optima, do zaprezentowania na stronie szczegółów towaru możliwe są zestawy: Dzięki wskazanej prezentacji, klient może dowiedzieć się o promocyjnej ofercie zakupu kilku towarów jednocześnie w tańszej cenie.

7. Towary podobne i akcesoria

Dla towarów skonfigurowanych w systemie Comarch ERP XL istnieje możliwość zdefiniowania Towarów podobnych lub Akcesoriów. Aby wskazana sekcja była dostępna w e-Sklepie, należy ją skonfigurować po stronie Comarch ERP XL zgodnie z fragmentem instrukcji, w którym opisano obsługę towarów podobnych lub akcesoriów dla towaru. W przypadku zamienników, możliwe jest także ich skonfigurowanie w Comarch ERP Optima.

Koszyk

Po przejściu na stronę koszyka wyświetla się podsumowanie dodanych do niego towarów. Wskazana sekcja ma na celu prezentację towarów w ramach rekomendacji zakupowych, aby zachęcić klienta do dalszych zakupów. W szablonie Rubin składanie zamówienia zostało zaprojektowane tak, aby użytkownik mógł w jednym kroku wypełnić niezbędne dane: 
  • Formularz z danymi zamawiającego oraz danymi do faktury.
  • Sposób dostawy.
  • Sposób płatności.
Po uzupełnieniu powyższych informacji i zakupie towaru można przejść do podsumowania, w którym prezentowane są m.in. wcześniej wprowadzone dane klienta. W ramach koszyka istnieje możliwość włączenia prezentacji wartości rabatów dla danego zamówienia, zgodnie z ustawieniem:

Dzięki temu promocja zostanie zaprezentowana w koszyku w następujący sposób:   Dodatkowo, w przypadku dostaw, możliwe jest także włączenie edycji daty dostawy:

Wskazane ustawienie prezentuje się następująco:

Zapytanie o wycenę

W modelu sprzedaży B2B często spotyka się spersonalizowane wyceny dla różnych kontrahentów. Na wysokość cen wpływają takie czynniki jak zmieniające się ceny towarów, ilość zamówionych produktów, sytuacja rynkowa oraz szczególne warunki ustalone w umowach między sprzedawcą a klientem. Z tego względu w szablonie Rubin istnieje możliwość dodawania towarów do zapytania o wycenę zgodnie z ustawieniem: Do zapytania o wycenę możesz przejść z poziomu nagłówka, klikając ikonę "Zapytanie o wycenę". Po kliknięciu w szablonie prezentowany jest panel boczny z towarami dodanymi do zapytania: Po przejściu do szczegółów, dostępny jest formularz: Obsługa zapytań jest w dalszej kolejności procesowana po stronie panelu administracyjnego. W dalszej kolejności zarówno zapytanie o wycenę, jak i utworzona z niego oferta sprzedaży jest dostępna dla klienta z poziomu Profilu klienta.

Profil klienta

1. Ustawienia profilu klienta

W przypadku ustawień profilu klienta w ramach: Wygląd sklepu > Ustawienia >  Zarządzanie strefą klienta widoczna jest lista elementów zamieszczonych w e-Sklepie. Lista składa się z następujących ustawień:
  • Dostępne – ustawienie wyświetlania danego elementu na stronie. Jeżeli parametr jest zaznaczony (podświetla się na szaro) wówczas element będzie widoczny na stronie.
  • Kolejność – w tym polu za pomocą strzałek możemy zmienić kolejność przycisków.
  • Ikona – w tym miejscu należy wprowadzić nazwę ikony, która powinna się wyświetlać na dodanym elemencie.
  • Etykieta PL – nazwa elementu, która będzie się wyświetlała w polskiej wersji strony.
  • Id tłumaczenia – id z którego będą pobierane tłumaczenia elementu wyświetlane w obcojęzycznej wersji strony. Tłumaczenia dodawane są w panelu administracyjnym: Wygląd sklepu > Ustawienia > Tłumaczenia.

2. Dokumenty dostępne w profilu klienta

W ramach profilu klienta dostępne są dokumenty związane z procesem zamówienia w e-Sklepie. Z tego poziomu klient ma dostęp do zakładek prezentujących:
  • zamówienia,
  • faktury,
  • wydania zewnętrzne,
  • wydania magazynowe.
Aby móc obsługiwać dokumenty pochodzące z systemu Comarch ERP, należy skonfigurować usługę Comarch e-Sklep Sync. Dzięki temu dla klientów widoczne staną się dokumenty udostępniane przez to narzędzie. Dokumenty, dla których wymagana jest wskazana usługa zostały opisane w artykule Dokumenty udostępniane przez Comarch e-Sklep Sync. Dzięki odpowiednim oznaczeniom kolorystycznym klient ma możliwość w prosty sposób zapoznać się ze statusami wskazanych dokumentów:

3. Zapytania o wycenę i oferty sprzedaży

Z tego poziomu klient ma dostęp również do listy z wykonanymi zapytaniami o wycenę. Po stworzeniu wyceny na dane zapytanie, w zakładce Oferta sprzedaży pojawi się oferta do zaakceptowania przez klienta: Więcej informacji na temat zapytań i ofert sprzedaży można znaleźć w artykułach: Zapytaj o cenę oraz Jak stworzyć ofertę sprzedaży i zapytanie ofertowe?

4. Reklamacje/zwroty

Klient ma możliwość zareklamowania towaru po przejściu na szczegóły zamówienia. Z tego poziomu jest możliwość wybrania opcji reklamacji dla towaru: Informacje o reklamacjach znajdą się w zakładce Reklamacje/ Zwroty:

5. Moje dane

W zakładce Moje dane klient ma możliwość weryfikacji wprowadzonych danych jako firma bądź osoba fizyczna. W tym miejscu wyświetlone są także uzupełnione adresy dostawy – wskazany jest także adres domyślny.

6. Pracownicy

We wskazanej zakładce istnieje możliwość dodania pracownika, jak również jego zablokowania. Dodatkowo jeżeli pracownik jest przypisany do kilku firm istnieje możliwość zmiany firmy z poziomu nagłówka sklepu: Więcej na temat pracowników w e-Sklepie możesz dowiedzieć się w artykule: Wielu pracowników kontrahenta.

7. Twoje konto

We wskazanej zakładce znajdują się dane kontaktowe klienta, jak i dane do logowania – e-mail i hasło. Z tego poziomu dostępna jest również historia konta

8. Zgody

W tym miejscu klientowi prezentowana jest lista zaakceptowanych zgód:

9. Do pobrania

Poprzez dodanie załączników do karty kontrahenta w systemie Comarch ERP XL  w szablonie Rubin jest możliwe wyświetlanie listy plików do pobrania dla zalogowanych użytkowników. Są one widoczne i dostępne do pobrania w Profilu Klienta we wskazanej zakładce. Sposób konfiguracji wskazanych plików został opisany w artykule: Lista plików Klienta – Do pobrania

10. Promocje

Dzięki wskazanej zakładce klienci mogą sprawdzić, jakie rabaty aktualnie posiadają. Widoczne w tej zakładce rabaty są przesyłane z systemu ERP oraz ustalane w Panelu Administracyjnym Comarch e-Sklep. Obsługiwane rabaty:
  • rabaty dla nowego klienta
  • rabaty od wartości zamówienia
  • rabat dla stałego klienta
  • rabaty z Comarch ERP
  • stała cena z Comarch ERP
Aby wskazane promocje wyświetlały się w profilu klienta należy włączyć ustawienie w Wygląd sklepu > Ustawienia > Ogólne: Informacje o konfiguracji rabatów można znaleźć w ramach artykułu: Rabaty – rodzaje i zasady wyliczania.

Listy zakupów

W szablonie Rubin dla wersji sklepu B2B możliwe jest posiadanie wielu list zakupów. Funkcja dostępna jest tylko dla zalogowanych klientów. Umożliwia ona zaplanowanie zakupów z wyprzedzeniem w uporządkowany sposób poprzez tworzenie list na różne okazje i ustawianie dla nich daty przypomnienia: Po przejściu do list istnieje możliwość utworzenia nowej listy: W ramach listy jest możliwa do ustawienia data przypomnienia: Dodatkowo z tego poziomu klient ma możliwość nadania liście nazwy, przeniesienia jej do zapytania o wycenę, jak również dodania towarów z listy do koszyka.

Lookbook

Lookbook oferuje możliwość przedstawienia towarów bezpośrednio na zdjęciu w formie zaznaczonych pinezek. W szablonie Rubin możliwe jest stworzenie wielu lookbooków. Będą one w takim wypadku prezentowane w formie listy: Szczegóły lookbooka charakteryzują się precyzyjnym oznaczeniem towarów na zdjęciu. Dzięki znacznikom umieszczonym na grafice Twoi klienci będą mogli podejrzeć towar i dodać go bezpośrednio do koszyka lub listy zakupów. Po kliknięciu na przycisk z plusem wyświetli się popup ze szczegółami towaru oraz opcją zakupu.
Wskazówka
Rekomendowany rozmiar grafik do lookbooka to 578 x 578 px.
Aby poprawnie skonfigurować lookbook, skorzystaj z naszej instrukcji zawartej w artykule: Jak skonfigurować Lookbook w Comarch e-Sklep?

Blog

Blog jest ważnym elementem w strategii każdego sklepu internetowego. Umożliwia sprzedawcy dzielenie się wiedzą i doświadczeniami dotyczącymi oferowanych produktów. Poprzez bloga, sklep może podpowiedzieć klientom, jak najlepiej wykorzystać dostępne artykuły. Dodatkowo, regularne publikowanie wartościowych treści ma korzystny wpływ na pozycjonowanie strony, dzięki unikalnym materiałom. To sprawia, że Twój sklep może być częściej widoczny w wynikach wyszukiwania.

W sekcji z blogiem prezentowane są aktualnie dodane artykuły, które są możliwe do konfiguracji w Panelu administracyjnym. Dla każdego wpisu przedstawione są: zdjęcie, treść, tagi oraz przewidywany czas czytania. Szczegółowe informacje na temat konfiguracji bloga w e-Sklepie znajdują się w artykule: Jak skonfigurować blog?

Szablon Szafir

      Szablon Szafir jest dedykowany dla sklepów w wersji B2B. Dostępny jest także dla sklepów w wersji Enterprise. Użytkownik może zainstalować szablon zarówno przy uruchomieniu nowego sklepu, jak i w obecnie używanym sklepie z poziomu panelu administracyjnego. W szablonie Szafir obsługiwana jest funkcja PWA, czyli Progressive Web App. W przypadku otworzenia na urządzeniu mobilnym (w trybie responsywnym) strony e-Sklep z szablonem Szafir, sklep wyświetl komunikat o możliwości pobrania skrótu na ekran główny urządzenia. W efekcie e-Sklep uruchomiony z takiego skrótu będzie wyglądał jak aplikacja natywna zainstalowana na urządzeniu mobilnym i dostosowana do wyświetlania na nim. W szablonie zaimplementowano także meta znaczniki Open Graph niezbędne do prawidłowej komunikacji z platformą Facebook oraz przesyłania towarów dla sklepu Facebook. Więcej na ten temat przeczytasz tutaj. Główne wyróżniki szablonu: 1. Funkcje B2B:
  • Obsługa klientów detalicznych oraz typu firma – połączenie modeli B2B oraz B2C,
  • Wyświetlanie zamówień, faktur i wydań zewnętrznych z systemu ERP w profilu klienta dzięki wykorzystaniu Comarch e-sklep Sync,
  • Inna prezentacja strony głównej przy wykorzystaniu parametru Dostęp tylko dla klientów zalogowanych,
  • Obsługa wielu koszyków (z możliwością edycji nazwy koszyka i usuwania całego koszyka jednym przyciskiem),
  • Zmiana firmy w nagłówku oraz możliwość dodawania pracowników w profilu klienta – obsługa wielu loginów,
  • Możliwość szybkich zakupów z list towarowych bez przechodzenia na szczegóły,
  • Szablon przystosowany do dużych zamówień z wieloma pozycjami,
  • Opiekun handlowy dla Kontrahenta – widoczny po zalogowaniu, zamiast danych kontaktowych sklepu w nagłówku,
  • Możliwość blokady zmiany Danych Firmy przez Kontrahenta. Więcej informacji na ten temat zostało przedstawione w artykule.
2. Nawigacja w szablonie:
  • Możliwość wyboru jednego z trzech widoków na listach towarowych,
  • Możliwość ustawienia krótkiego opisu towarów dla widoku o typie „Lista”,
  • Głębokie wielopoziomowe menu główne w orientacji pionowej,
  • Aktualności na stronie głównej w formie listy artykułów z bloga. Możliwość prezentacji artykułów na dwa sposoby: rozszerzony i kompaktowy (menu Wygląd sklepu > Ustawienia > Ustawienia szablonu),
  • Lista produktów na stronie głównej, która idealnie zaprezentuje nowości, promocje, towary rekomendowane itp.,
  • Duży przewijany banner na stronie głównej,
  • Małe banery nad stopką, po dodaniu powyżej pięciu obrazów – możliwe do przewijania,
  • Graficzne menu kategorii na stronie Produkty.
3. Towary:
  • Prezentacja stanów magazynowych w formie graficznej, tekstowej oraz liczbowej zgodnie z konfiguracją w panelu administracyjnym,
  • Prezentowanie i odtwarzanie plików w formacie MP4. Po przesłaniu filmu z systemu Comarch ERP Optima lub Comarch ERP XL do swojego e-Sklepu, zostanie on wyświetlony w sekcji z filmami lub w galerii w zależności od wariantu widoku na stronie ze szczegółami towaru.
  • Prezentacja towarów tylko w cenie netto (po włączeniu w menu Wygląd sklepu > Ustawienia > Ustawienia szablonu w sekcji Cena netto dla parametru Prezentacja tylko ceny netto na stronie prezentacji towaru opcji Tak).
  • Warianty towarów wyświetlane w formie tabelki z możliwością dodania do koszyka dowolnej ilości każdego wariantu,
  • Zestawy na towarze w formie slidera,
  • Sekcja prezentujące towary podobne (zamienniki). Wyświetlają się również inne typy (definiowane w systemie ERP) m.in. akcesoria, sugerowane, użytkownika.
  • W przypadku, gdy towar posiada jednostkę pomocniczą i zostanie ona wybrana przez kontrahenta, wówczas cena w jednostce podstawowej będzie wyświetlana nad ceną w jednostce pomocniczej.
  • Wyświetlanie daty od kiedy towar będzie dostępny w e-Sklepie, w przypadku jej określenia dla statusu Zapowiedź,
  • Wyświetlanie informacji o kosztach dostawy,
  • Po przejściu na stronę sklepu z końcówką /produkty,2 wyświetlane są grupy towarów. Użytkownik ma możliwość wybrania konkretnej kategorii, po jej wyborze zostanie wyświetlona lista towarów wybranej grupy.
  • Lista towarów dla widoku o typie „Lista” zawiera krótki opis towarów, który domyślnie jest zwinięty. Po rozwinięciu szczegółów, kontrahent ma możliwość uzyskania większej ilości informacji na temat produktu bez przechodzenia do karty towaru.
  • Dodawanie opinii do towaru. Dostępność tej funkcji zależy od ustawień w panelu administracyjnym: Ustawienia > Ustawienia sklepu > Towary > Opinie o towarze.
  • Możliwość prezentowania ceny poprzedniej jako sugerowanej ceny detalicznej (w menu Wygląd sklepu > Ustawienia > Ustawienia szablonu w sekcji Cena poprzednia dla parametru Prezentuj cenę poprzednią jako sugerowaną cenę detaliczną włączona opcja Tak (domyślnie zaznaczony jest parametr Nie). Zmiany w szablonie należy zapisać i opublikować.)
W panelu administracyjnym na zakładce Wygląd sklepu > Ustawienia > Ustawienia szablonu na zakładce Lista towarów znajdują się nowe parametry związane z wyświetlaniem listy produktów: do zmiany prezentowania kategorii, filtrów oraz graficznego menu. Aktualnie można zdecydować o ilości wyświetlanych filtrów, miejscu w którym mają się znajdować i tego, czy ta sekcja ma się rozwijać czy nie w e-Sklepie. Administrator sklepu może również zmienić formę graficzną prezentowania nazw, opisu i zdjęć kategorii oraz aktywować nowe graficzne menu nawigacji dla podgrup. Aby wprowadzone zmiany były widoczne w szablonie należy je zapisać i opublikować. 4. Zamówienie:
  • Zamówienie dla zarejestrowanych kontrahentów oraz niezarejestrowanych,
  • Możliwość wyboru skonfigurowanych adresów na zamówieniu,
  • Szybkie składanie zamówień w jednym kroku,
  • Macierz dostaw w formie list rozwijalnych (dostawa i płatność),
  • W profilu klienta możliwość pobierania kopii faktury elektronicznej w formacie PDF wystawionej do zamówienia w systemie ERP. Wyświetlane są także dokumenty ZS, FS i WZ,
  • Ponowienie nieudanej płatności dostępne zarówno dla klientów zarejestrowanych jak i jednorazowych,
  • Możliwość dodania załączników do zamówienia,
  • Widok szczegółów złożonego zamówienia dla niezalogowanych klientów,
  • Możliwość anulowania edytowalnego zamówienia, które nie zostało jeszcze wysłane do systemu ERP,
  • Anulowanie uprzednio edytowanego zamówienia usuwa również koszyk z towarami, które miały zostać dodane do danego zamówienia,
  • Obsługa zwrotów i reklamacji, wraz z załącznikami (jeżeli w panelu administracyjnym w menu Ustawienia > Ustawienia sklepu > Reklamacje / zwroty zostanie włączona opcja Załączniki do reklamacji i zwrotów) do zrealizowanych zamówień,
  • Klienci detaliczni podczas składania zamówienia z paragonem mają dostępne pole, w którym mogą podać numer NIP, na który w przyszłości może zostać wystawiona faktura do paragonu. Informacja o rodzaju dokumentu handlowego wybranego przez Klienta jest widoczna na szczegółach zamówienia w Strefie Klienta oraz w panelu administracyjnym, a także zostanie przeniesiona do systemu ERP,
  • Klienci firmowi podczas zakupów mogą zdecydować w koszyku, czy do danego zamówienia ma być wystawiony dokument handlowy w postaci faktury lub paragonu. Po wybraniu opcji Paragon widoczne jest pole z numerem NIP. Po jego uzupełnieniu możliwe jest wygenerowanie w systemie ERP w późniejszym terminie faktury sprzedaży do paragonu.
  • Formularz zamówienia zapamiętuje wprowadzony numer NIP. Zmiana z Faktury na Paragon przenosi wprowadzony numer NIP i nie wymaga ponownego wprowadzenia.
  • Dostępna kolumna na liście zamówień z adresem e-mail, która umożliwia rozpoznanie, czy zamówienie zostało złożone przez kontrahenta, czy przez któregoś z jego pracowników.
Wskazówka
Jeżeli w panelu e-Sklep w zakładce Ustawienia > Ustawienia sklepu > Zamówienia włączony jest parametr "Składanie zamówień tylko przez firmy" w e-Sklepie możliwe będzie wygenerowanie jedynie Faktury VAT. W przypadku, gdy klient wybierze opcję paragonu i nie poda nr NIP, a opcja ta będzie włączona, zostanie wystawiona faktura na podstawie nr NIP podanego podczas rejestracji.
5. Pobieranie danych:
6. Strefa Klienta:
  • dedykowane menu w profilu Klienta zalogowanego,
  • dostęp do wszystkich transakcji oraz dokumentów sprzedaży – zamówienia, zapytania o wycenę, oferty sprzedaży, faktury, wydania zewnętrzne,
  • wygodny proces reklamacji oraz zwrotów,
  • zarządzanie pracownikami oraz danymi firmy,
  • dostęp do programu lojalnościowego oraz dedykowanych promocji Klienta,
  • dodatkowe pliki do pobrania oraz zgody w e-Sklepie.
Każdą zakładkę w Strefie Klienta można odpowiednio obudować w link, w celu utworzenia bezpośredniego odnośnika. Poniżej znajduje się lista elementów w Strefie Klienta oraz ich nazwy, jakie można wykorzystać:
  • Zamówienia pochodzące z e-Sklepu – eshop-orders
  • Zamówienia pochodzące z systemu ERP (pobrane przez Comarch e-Sklep Sync) – erp-orders
  • Zapytania o Wycenę – inquiries
  • Oferty Sprzedaży – offers
  • Faktury – invoices
  • Wydania zewnętrzne – sor
  • Wydania magazynowe – wm
  • Reklamacje/Zwroty w trakcie realizacji – active-complaints
  • Reklamacje/Zwroty zrealizowane – executed-complaints
  • Dane firmy – customer-details
  • Pracownicy – employees-list
  • Twoje konto – your-account
  • Program lojalnościowy – loyalty
  • Zgody – consents
  • Do pobrania – to-download
  • Promocje – discounts.
Przyklad
Adres https://demob2b.comarchesklep.pl/profil-klienta/6?tab=discounts stanowi bezpośredni odnośnik do zakładki Promocje w Strefie Klienta.
Wskazówka
Jeżeli chcesz zaprezentować ceny netto na liście towarów, należy odpowiednio skonfigurować prezentację cen w e-Sklepie. Instrukcja dotycząca prezentacji cen netto znajduje się w artykule o Cenach i rabatach.
Konfiguracja paska nawigacji w szablonie Szafir oraz przykłady zastosowania zostały przedstawione w artykule Pasek nawigacji - Szablon Szafir. Dodatkowo w Strefie Klienta na liście zamówień z e-Sklepu (zakładka Sklep B2B) oraz na liście zamówień przesyłanych przez Comarch e-Sklep Sync (zakładka Pozostała sprzedaż) widnieją statusy płatności i dostaw dla poszczególnych zamówień. W szablonie możliwe jest wyświetlanie sugerowanej ceny detalicznej widocznej zarówno dla klientów zalogowanych jak i niezalogowanych. Sugerowana cena detaliczna wyświetlana jest na podstawie ceny poprzedniej z systemu ERP. Aby ją wyświetlić klientom niezalogowanym należy w panelu administracyjnym e-Sklepu w sekcji Ustawienia > Ustawienia sklepu > Ceny i rabaty włączyć parametr Ukrywanie cen dla klientów niezalogowanych. Następnie należy włączyć parametr  Wyświetlanie cen poprzednich dla klientów niezalogowanych. Po jego włączeniu w ustawieniach szablonu Szafir (Wygląd sklepu > Ustawienia) w sekcji Cena poprzednia - Prezentuj cenę poprzednią jako sugerowaną cenę detaliczną należy wybrać "Tak". W przypadku kiedy sklep jest dostępny dla klientów niezalogowanych i nie są ukrywane ceny, wystarczy aktywować tylko parametr w sekcji Wygląd sklepu. Po włączeniu powyższych ustawień, klient niezalogowany przeglądający ofertę e-Sklepu zobaczy towary w sugerowanych cenach detalicznych. Klient zalogowany lub każdy klient (jeśli ukrywanie cen klientom niezalogowanym jest wyłączone) także zobaczy sugerowaną cenę detaliczną. Sugerowana Cena detaliczna będzie widoczna również na liście towarów. W Strefie Klienta na zakładce Pracownicy istnieje możliwość blokowania pracowników. Domyślnie każdy nowo dodany pracownik jest oznaczany jako aktywny. Kontrahent ma możliwość blokowania pracowników, po kliknięciu w opcję Zablokuj. Wówczas taki pracownik nie może się zalogować do e-Sklepu. Po zablokowaniu istnieje możliwość odblokowana pracownika w efekcie czego zalogowanie ponownie jest możliwe. W Strefie Klienta na zakładce Promocje wyświetlane są rabaty przesyłane  z systemów Comarch ERP: Altum i XL. Promocje wyświetlane są wraz z opisami, jakie dodano do nich w systemie ERP. W Szablonie Szafir widnieją dodatkowe bannery, które wyświetlają się nad stopką strony. Na dodatkowych bannerach obsługa sklepu ma możliwość zaprezentowania informacji na temat sklepu, np. informacji o dostawie, płatnościach, rabatach czy programie lojalnościowym. Istnieje możliwość edycji bannerów udostępnionych przez e-Sklep lub dodania własnych obrazów. Powyżej pięciu zdjęć bannery są przewijalne. Dodatkowe bannery mieszczą się w katalogu homepage-small w panelu administracyjnym e-Sklepu, obszar: Wygląd sklepu > Ustawienia > Bannery. W szablonie znajduje się także graficzne menu producentów. Producenci wyświetlani są pod newsletterem na stronie głównej. Menu jest budowane na podstawie producentów i ich logotypów przesyłanych z systemu ERP. Producentów zdefiniowanych w systemie ERP należy przypisać do towarów zgodnie z instrukcją używanego systemu ERP. Dostępne w szablonie motywy kolorystyczne to: Granatowy (domyślny), Niebieski oraz Pomarańczowy. Zmiana wybranego motywu możliwa jest w panelu administracyjnym w sekcji Wygląd sklepu > Ustawienia zakładka Ustawienia szablonu. Po wyborze docelowego motywu zmiany należy zapisać i opublikować. Widok listy towarów o typie „Lista” zawiera krótki opis towaru, który domyślnie jest zwinięty. Istnieje możliwość rozwinięcia szczegółów w celu uzyskania większej ilości informacji na temat produktu, bez przechodzenia do strony produktu. Po rozwinięciu szczegółów na liście widoczny jest opis towaru oraz szczegóły towaru: producent, marka, waga, stan magazynowy, status dostępności, czas dostępności (dla statusu Dostępny) oraz data zapowiedzi (dla statusu Zapowiedź).  Krótki opis należy dodać w systemie ERP. W szablonie istnieje możliwość używania powszechnie stosowanych symboli walut: zł, €, £, $. Nowy widok symbolu waluty będzie dostępny:
  • na liście walut/języków do wyboru – każda waluta z odpowiednim symbolem;
  • na liście towarów;
  • na szczegółach towaru;
  • w koszyku: na pozycjach towarów, dla form płatności i dostaw;
  • w Strefie Klienta w Liście zakupów;
  • w Strefie Klienta w sekcjach: Zamówienia, Oferty sprzedaży, Reklamacje/Zwroty, Promocje;
  • w porównywarce towarów;
  • w wyszukiwarce prostej oraz zaawansowanej.
Aby uruchomić funkcję należy w systemie ERP udostępnić waluty obce do e-Sklepu oraz opcjonalnie w panelu administracyjnym e-Sklepu w menu Ustawienia > Ustawienia sklepu > Dane sklepu > Waluty wprowadzić swoje nazwy dla walut przesłanych z systemu ERP. Wybór oraz zmiana symbolu waluty będzie możliwa po kliknięciu w listę rozwijaną znajdująca się w prawym górnym rogu szablonu, z lewej strony przycisku "Zaloguj się": Aktualną czcionka szablonu Szafir jest czcionka Roboto – Google Font. Gotowa instrukcja dotycząca zmiany czcionki dostępna jest w artykule: Zmiana czcionki w szablonie.

Sprawdź historię zakupów

W e-Sklepie istnieje możliwość podglądu historii zakupów towaru dla klientów zalogowanych. Funkcja działa na podstawie wystawionych faktur do złożonego zamówienia na dany towar. Odnośnik "Sprawdź historię zakupów" widoczny jest na szczegółach towaru. Po kliknięciu przycisku widoczna będzie historia zakupów z ostatnich 6 miesięcy. Funkcję można aktywować, jeśli e-Sklep:
  • Jest w wersji B2B
  • Posiada zainstalowaną i aktywną usługę e-Sklep Sync
  • Jest powiązany z programem Comarch ERP XL.
Aby włączyć parametr, należy przejść do zakładki Wygląd sklepu > Ustawienia, a następnie w ustawieniach podglądu historii zakupów zaznaczyć Tak.
Widok ustawień w panelu administracyjnym
Efekt widoczny na szczegółach towaru w szablonie Szafir
Historia zakupów wyświetlana po naciśnięciu przycisku "Sprawdź historię zakupów"
 

Informacja o tym, że towar znajduje się w koszyku.

W szablonie Szafir Klient zostanie poinformowany o tym, że dany produkt znajduje się już w koszyku. Po wyborze towaru i kliknięciu "Kup teraz", przy ponownej próbie dodania do koszyka, na przycisku pojawi się ikona oraz odpowiedni tooltip: Informacja widnieje na szczegółach towaru.  W szablonie Szafir prezentacja tej informacji stanowi dodatek i domyślnie jest wyłączona. Żeby ją uruchomić, należy przejść do panelu administracyjnego, a następnie do sekcji Wygląd sklepu > Ustawienia zakładka Ogólne. Następnie po odnalezieniu sekcji "Informuj o tym, że towar znajduje się już w koszyku" należy zmienić opcję na "TAK". Po dokonaniu modyfikacji koniecznie zapisz i opublikuj zmiany. Więcej o darmowych szablonach przeczytasz w artykule Gotowe szablony Comarch.

Jak zaktualizować szablon do najnowszej wersji?

Jak zaktualizować szablon do najnowszej wersji?

Wskazówka
Od 1 czerwca 2025 roku zakończyliśmy aktualizację oraz wydawanie nowych wersji szablonów Bursztyn, Agat i Opal, a tym samym ich wsparcie, aby skupić się na nowoczesnych rozwiązaniach, które jeszcze lepiej odpowiadają na potrzeby dynamicznie rozwijającego się rynku e-commerce. Zachęcamy Was do przejścia na nasze nowe, udoskonalone szablony. Dla sklepów B2C polecamy szablony Topaz, One Page Shop oraz Dla Gastronomii, natomiast dla platform B2B idealnym wyborem będą Rubin i Szafir.

Wstęp

W e-Sklepie możesz dowolnie zmieniać szablony. Możesz je także modyfikować oraz aktualizować. Wiąże się to z wgraniem zupełnie nowego szablonu na miejsce starego. Aktualizacja wyglądu powoduje zmianę dotychczasowych ustawień. Przed każdą aktualizacją polecamy utworzyć odpowiednią dla siebie instrukcję, która będzie zawierała Twoje ustawienia kolorów czy modyfikacje w kodzie szablonu. Możesz także wyeksportować dotychczasowy szablon, aby stanowił on kopię bezpieczeństwa.

Jak zaktualizować szablon?

Instrukcja aktualizacji szablonów: Rubin, Szafir, Topaz i One Page Shop (dostępnych w Kreatorze Wyglądu)

Aby zaktualizować szablon Rubin, Szafir, Topaz lub One Page Shop należy skorzystać z aktualnej wersji Kreatora Wyglądu, do którego odnośnik znajduje się w panelu administracyjnym e-Sklepu w sekcji Wygląd sklepu/ Kreator wyglądu. Istnieją dwie możliwości aktualizacji tych szablonów:

  • wygenerowanie nowego szablonu w Kreatorze Wyglądu oraz wgranie go do e-Sklepu,
  • import posiadanego szablonu do Kreatora Wyglądu oraz ponowne wygenerowanie go w najnowszej wersji.

Wyeksportowany z Kreatora Wyglądu szablon należy wgrać do e-Sklepu. W panelu administracyjnym e-Sklepu, w sekcji Wygląd sklepu znajduje się bezpośredni odnośnik do importu szablonu z Kreatora wyglądu. Szczegółowa instrukcja dostępna jest w artykule Jak wyeksportować i zaimportować swój szablon w e-Sklepie?

Podczas dokonywania modyfikacji w szablonach zachęcamy do skorzystania z naszego Centrum Pomocy.

Wskazówka
Pamiętaj o zapisaniu szablonu oraz opublikowaniu go w e-Sklepie. Zmiany wprowadzone w ustawieniach zostaną zsynchronizowane do sklepu po 10 minutach.

Instrukcja aktualizacji szablonów: Bursztyn, Agat i Opal.

Aby zaktualizować szablon Bursztyn, Agat lub Opal należy w panelu administracyjnym e-Sklepu przejść do sekcji Wygląd Sklepu/ Gotowe szablony Comarch, w której znajdują się najnowsze wersje szablonów dostępne do zainstalowania. Z wyświetlonej listy należy wybrać szablon, który ma zostać wgrany do e-Sklepu. W tym celu wybierz przycisk Chcę pobrać i zainstalować szablon:

Następnie wyświetli się nowe okno, w którym należy:

  • wybrać tzw. slot, który zostanie nadpisany nowym (aktualnym) szablonem. W każdym e-Sklepie dostępne są 4 miejsca na wgranie szablonu, spośród których jeden szablon oznacza się jako aktywny i domyślny,
  • określić, czy wgrywany szablon ma podmienić istniejące bannery. Gdy parametr zostanie zaznaczony, wówczas wszystkie bannery zapisane na danym slocie zostaną usunięte i zastąpione bannerami z importowanego szablonu. Jeżeli w nadpisywanym szablonie znajdują się bannery oraz lookbooki, które mają nadal wyświetlać się w e-Sklepie, należy wskazany parametr zostawić odznaczony. Gdy parametr nie zostanie zaznaczony, wówczas dotychczasowe bannery i lookbooki nie zostaną usunięte.
  • Zaimportować szablon do e-Sklepu.
    Wskazówka
    Import szablonu jest operacją nieodwracalną i spowoduje nadpisanie dotychczasowego szablonu. W przypadku, gdy szablon był modyfikowany (dokonywano zmian w kodzie HTML) jego aktualizacja spowoduje, iż zmiany nie zostaną przeniesione. Warto wykonać eksport posiadanego szablonu do pliku w celu zapisania oraz posiadania wglądu to wprowadzanych modyfikacji. Jeżeli istnieje taka konieczność należy ponownie dokonać samodzielnej edycji szablonu.

Aby nowy szablon pojawił się w e-Sklepie należy upewnić się, czy jest on aktywny oraz ustawiony jako domyślny. W sekcji Wygląd sklepu/Ustawienia/Edytuj ustawienia zaawansowane w zakładce Szablon znajdują się odpowiedzialne za to parametry, które powinny być zaznaczone.

Wszelkie zmiany należy zapisać, a następnie opublikować.

Uwaga
Jeżeli szablon nie zostanie opublikowany, wówczas nie pojawi się on w e-Sklepie.

Instrukcja aktualizacji innych szablonów (niż szablonów Comarch) oraz aktualizacji szablonów z własnymi modyfikacjami

Jeżeli w swoim Comarch e-Sklepie korzystasz z własnego szablonu, czyli innego niż gotowe szablony Comarch, to powinieneś jego aktualizację przeprowadzić we własnym zakresie lub zlecić ją firmie/ osobie, która dla Ciebie przygotowała ten szablon. W przypadku, gdy korzystasz z gotowego szablonu Comarch, ale wprowadziłeś do niego indywidualne zmiany (poza Kreatorem Wyglądu), to również we własnym zakresie (lub ze wsparciem autora zmian) musisz zadbać o aktualizację swojej wersji szablonu.

Banner pop-up w szablonie Szafir i Topaz

W niniejszym artykule dowiesz się, w jaki sposób dodać banner pop-up w swoim szablonie Topaz i Szafir. Banner wyświetla się w formie wyskakującego pop-upa, na którym możesz zaprezentować zdjęcie, treść a także przejść do wybranego towaru.

Konfiguracja nowego bannera

Krok 1. Dodaj jeden z dostępnych wariantów banneru pop-up w Kreatorze Wyglądu. Za pomocą funkcji przeciągnij i upuść dodaj banner do nowo utworzonego szablonu Szafir lub Topaz: Krok 2. W panelu administracyjnym przejdź do sekcji Wygląd sklepu/ Ustawienia/ Bannery. Z listy dostępnych bannerów wybierz banner popup_2: Krok 3. Po wpisaniu nazwy nowego banneru wyświetla się nowy formularz. W tym miejscu masz możliwość dodania opisu dla administratora oraz obrazków do katalogu. Jeżeli powyższe kroki zostały wykonane, to możesz przejść do dodania obrazku. Po dodaniu obrazków istnieje również możliwość uzupełnienia szczegółów dotyczących konkretnego zdjęcia. Aby dokonać modyfikacji w tym obszarze przejdź w Widok zaawansowany. Po kliknięciu w odnośnik pojawi się panel, w którym można zmienić np. tekst na bannerze, nagłówek, czas jego wyświetlania, link do którego kieruje dany obrazek, a także tooltip i tekst alternatywny. Tak wprowadzone zmiany należy zapisać i opublikować. Gotowe! Banner pop - up został dodany i tak prezentuje się w szablonie Topaz. Po kliknięciu w znacznik "Sprawdź" Twoi klienci zostaną przeniesieni na kartę towaru, gdzie będą mogli dokonać towar do koszyka.

Jak wykonać kopię bezpieczeństwa mojego szablonu?

Jak wykonać kopię bezpieczeństwa mojego szablonu?

Oprawa wizualna sklepu jest bardzo ważnym elementem podczas prowadzenia sprzedaży w sieci. Narzędzie Kreator Wyglądu Comarch e-Sklep umożliwia stworzenie własnych, niepowtarzalnych szablonów wedle preferencji i potrzeb użytkowników. W intuicyjnym narzędziu jakim jest Kreator, będziesz w stanie zaprojektować wszelkie niezbędne funkcje, takie jak stronę główną, listę towarów, szczegóły towaru oraz koszyk. Jeśli Twój projekt szablonu został zaimportowany do e-Sklepu oraz skonfigurowany wedle Twoich preferencji (dodanie grafik do bannerów, modyfikacje kolorystyczne) masz możliwość jego zapisania, co będzie stanowić kopię bezpieczeństwa. Kopia bezpieczeństwa to dane, które w każdej chwili można odtworzyć w przypadku ich utracenia (np. poprzez przypadkowe usunięcie) lub częstego wprowadzania zmian. Dane, jakie może zawierać kopia bezpieczeństwa to szablon, który wcześniej został przez nas wygenerowany wraz z bannerami. Zaleca się wykonywanie kopii zapasowych oraz zabezpieczenie ich hasłem. Każda wykonana kopia zapasowa powinna zostać zapisana w bezpiecznym i dogodnym dla Użytkownika miejscu.

Jak wykonać kopię bezpieczeństwa?

W Panelu Administracyjnym przejdź do sekcji Wygląd sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane, a następnie przejdź do zakładki Eksport szablonu. W pustych polach znajdujących się w zakładce Eksport szablonu, opcjonalnie przed eksportem możesz uzupełnić powyższe dane, tj. Autora szablonu, e-mail, telefon i stronę WWW sklepu. Aby wyeksportować szablon, kliknij Eksportuj szablon. Wyeksportowany plik jest w formacie XML, a jego nazwa zawiera szablon oraz wersję, co znacznie ułatwia zarządzanie kopiami bezpieczeństwa w przypadku wykonywania ich regularnie.

Jak wyeksportować bannery?

Bannery, które znajdują się w Twoim sklepie możesz również wyeksportować tworząc kopię bezpieczeństwa. W tym celu także musisz przejść do Wygląd sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane, a następnie do zakładki Eksport szablonu. Obok przycisku Eksportuj szablon, znajduje się przycisk Eksportuj bannery, który musisz kliknąć aby bannery, które posiadasz w e-Sklepie zostały weksportowane. Kopia bezpieczeństwa jest również zapisywana w formacie XML, a nazwa pliku wskazuje na szablon, wersję i zawartość bannerów.

Jak zabezpieczyć hasłem swój szablon?

Jeśli chcesz, aby Twój szablon został zabezpieczony hasłem, a znajomość hasła była niezbędna podczas zaimportowania tego szablonu do e-Sklepu, musisz w tym celu przejść w Panelu Administracyjnym do sekcji Wygląd sklepu/ Ustawienia/ Ustawienia zaawansowane, następnie do zakładki Szablon. W tym miejscu nadasz hasło dla swojego szablonu. Zgodnie z Polityką bezpieczeństwa haseł, hasło powinno:
  • Składać się z minimum 8 znaków,
  • Zawierać dużą literę,
  • Zawierać małą literę,
  • Zawierać cyfrę 0-9,
  • Zawierać znak specjalny – ‘!.+?;^]=-(&_)#=
Gotowe! Teraz Twój szablon został zabezpieczony hasłem. Jeśli wyeksportujesz szablon, który zabezpieczyłeś hasłem – podczas importu tego szablonu, będziesz musiał podać nadane wcześniej hasło. Jego brak uniemożliwi import szablonu, a podanie błędnego hasła spowoduje nieprawidłowe działanie szablonu po imporcie. Więcej informacji znajdziesz:

Kreator wyglądu Szafir (B2B)

Wstęp

Jednym z kluczowych elementów, który przyczynia się do sukcesu w branży e-commerce jest oprawa wizualna sklepu. W dużym stopniu to właśnie ona wpływa na całościowe wrażenia użytkowników i ich proces zakupowy. Dzięki narzędziu - Kreator Szablonu Szafir (B2B), właściciele sklepów mają możliwość stworzyć swój własny, niepowtarzalny szablon, który będzie dostosowany do obsługi klientów detalicznych oraz typu firma - połączenie modeli B2B i B2C.

Zastosowanie

Kreator jest intuicyjnym narzędziem służącym do tworzenia szablonów. Jego obsługa nie wymaga umiejętności technicznych ani programowania. Wszystko odbywa się na poziomie strony internetowej, gdzie z gotowych elementów za pomocą metody "przeciągnij i upuść" możesz zaprojektować wygląd swojego sklepu. Dodatkowo, stworzony szablon jest dostosowany do wyświetlania na różnych urządzeniach (RWD).

W ramach kreatora zaprojektujesz wszystkie niezbędne obszary sklepu:
  • stronę główną,
  • listę towarów,
  • koszyk zakupowy.

Kto może używać tej opcji?

Aby móc używać tego narzędzia należy posiadać:

  • Comarch e-Sklep w wersji Enterprise lub B2B,
  • szerokość ekranu powyżej 1280 px, a zalecana to 1920 px,
  • oraz jedną z przeglądarek internetowych w aktualnej wersji.

Wskazówka
Kreator szablonu Szafir dostępny jedynie w wersji przeglądarkowej.

Zaczynamy!

Jak zaprojektować układ szablonu?

Aby rozpocząć tworzenie szablonu należy przejść na stronę Kreatora Wyglądu. Wyświetlony zostanie powitalny komunikat. Na początku należy określić, dla jakiego modelu sprzedaży projektujesz szablon dla swojego e-Sklepu. Do wyboru masz sprzedaż detaliczną lub hurtową. Sprzedaż hurtowa przeznaczona jest dla użytkowników, którzy chcą sprzedawać swoje produkty również klientom biznesowym w hurtowych ilościach. Wybierz odpowiedni model, a następnie naciśnij przycisk Rozpocznij pracę. Po jego kliknięciu będzie można stworzyć nowy szablon lub edytować jeden z kilku gotowych.

  W sytuacji gdy wcześniej tworzony był już projekt, widoczny będzie przycisk umożliwiający dokończenie szablonu lub rozpoczęcie nowego projektu. Opcja Nowy szablon umożliwia zbudowanie od początku nowego szablonu Szafir według Twojego indywidualnego pomysłu. Pozostałe trzy opcje do wyboru to gotowe wersje szablonu Szafir z możliwością ich edycji. Dzięki temu nie ma potrzeby tworzenia nowego szablonu od podstaw, ponieważ możesz wybrać jedną z gotowych propozycji, a następnie łatwo go edytować dostosowując do swoich potrzeb. Podwójne kliknięcie w wybrany kafelek pozwala przejść dalej. W trzech krótkich krokach zapoznasz się z podstawowymi funkcjami kreatora. Następnie możesz już przystąpić do dalszych modyfikacji szablonu lub od razu wygenerować przygotowaną wersję szablonu Szafir.

Od czego zacząć?

Wybierz wersję językową Kreatora i rozpocznij pracę nad swoim szablonem. Wersje do wyboru to: język polski, angielski, niemiecki oraz francuski. Język wybieramy klikając strzałkę obok flagi i nazwy języka w lewym dolnym rogu. Przy podglądzie prac na pełnym ekranie, wybrany język zostaje zachowany i szablon będzie wyświetlał się w wybranej wersji językowej.

Gdy już wybierzesz wersję językową dla swojego Kreatora warto zacząć od nazwania swojego przyszłego szablonu. Można to zrobić klikając Zmień i wpisując nazwę w lewym górnym rogu, zastępując nazwę "Szafir(2023)". Nazwa ta będzie widoczna po zaimportowaniu szablonu do panelu administracyjnego oraz po wyeksportowaniu szablonu do pliku XML wraz z datą i godziną jego wygenerowania.

Krok 1 - Strona główna

W tej sekcji należy zaprojektować wygląd strony głównej naszego Comarch e-Sklepu. Strona główna może składać się z następujących elementów:

  • Nagłówek,
  • Baner,
  • Widget,
  • Banner pop-up,
  • Polecane,
  • Newsletter,
  • Slider producentów,
  • Slider marek,
  • Aktualności
  • Banner infografika
  • Stopka.

Po rozwinięciu każdej z sekcji ukażą się dostępne elementy:

Metodą "Przeciągnij i upuść" przenosimy wybrane elementy na obszar po prawej stronie:

Postępuj analogicznie z pozostałymi elementami.

Nagłówek

Sekcja „Nagłówek” prezentuje jeden widok. Nagłówek dodatkowo można konfigurować w zakresie wielkości linków w Menu kategorii i prezentacji funkcji związanych ze składaniem Zapytań o wycenę.

Bannery

Sekcja "Bannery" pozwala wybrać jedną możliwości prezentacji banneru. Informacje dotyczące rekomendowanych rozmiarów obrazków w bannerach opisaliśmy w tym artykule.  

Widget

Sekcja "Widget" pozwala dodać jeden z dwóch dostępnych wariantów, które pozwolą zaprezentować następujące funkcje.
  • Widget-banner-1
    • Dodanie zdjęcia,
    • Dodanie tekstu nagłówka (tekst pionowy),
    • Dodanie tekstu przycisku (tooltip).
    • Dodanie linku do przycisku,
    • Dodanie tekstu..
  • Widget-banner-2
    • Dodanie zdjęcia,
    • Dodanie tekstu nagłówka (tekst pod zdjęciem),
    • Dodanie tekstu,
    • Dodanie linku do tekstu.

Banner pop-up

Sekcja "Banner pop-up" pozwala wybrać jedną z dwóch możliwości prezentacji banerów. Bannery będą możliwe do wyświetlenia jedynie na stronie głównej e-Sklepu.

Proponowane

Sekcja "Proponowane" posiada dodatkowe opcje do ustawienia. Z listy menu, dostępnej pod przyciskiem Zmień typ możesz wybrać jakiego rodzaju produkty mają się w tym obszarze wyświetlać (m.in. nowość, najczęściej oglądane, wyprzedaż, sugerowane). Po zmianie typu tej sekcji, będzie się ona odpowiednio nazywać po wgraniu szablonu do sklepu:

Dodatkowo po najechaniu kursorem na tę sekcję, wybierając Opcje, możemy ustawić liczbę towarów, która będzie się wyświetlać (maksymalnie 50).

    Podczas tworzenia szablonu w Kreatorze wyglądu Szafir po dodaniu sekcji towary polecane można określić typ wyświetlanych produktów. Nazwa sekcji jest zależna oraz adekwatna do określonego typu. Daną nazwę można modyfikować w tłumaczeniach szablonu. Dodatkowo każdy wybrany typ jest podlinkowany do wszystkich produktów wskazanego rodzaju. W zależności od wybranego typu, edycji parametrów wyświetlania dokonasz w panelu administracyjnym e-Sklepu. Z kolei informację o typie towaru ustawisz w systemie ERP. Typy towarów edytowane z poziomu panelu administracyjnego Comarch e-Sklep:
  • Promocja,
  • Nowość,
  • Najczęściej oglądane / najczęściej kupowane,
  • Cross-selling – oferowanie produktów uzupełniających wcześniejsze zakupy,
  • Producent,
  • Marka,
  • Ręcznie wybrane,
  • Kategoria,
  • Ostatnio oglądane.
Aby zdecydować o parametrach wyświetlania tych informacji należy przejść w panelu administracyjnym Comarch e-Sklep do zakładki Ustawienia/Ustawienia sklepu/sekcji Towary: Producent, marka, ręcznie wybrane, kategoria oraz ostatnio oglądane obsługiwane są w ramach obiektu lokalnego "Siatka towarów". Po wyborze jednego z wyżej wymienionych typów zmian ustawień należy dokonać z poziomu panelu administracyjnego przechodząc do obszaru zakładki Wygląd sklepu/Ustawienia/Ustawienia zaawansowane oraz zakładki Obiekty. Na szczegółach wybranego obiektu (Siatka towarów) określamy jakie dokładnie towary zostaną zaprezentowane w sekcji "Proponowane". W przypadku wyboru "Producenta" lub "Marki" należy samodzielnie określić producenta lub markę. Dodawanie informacji o typie produktu w systemie ERP dotyczy:
  • Nowości,
  • Produktu z gazetki,
  • Produktu polecanego,
  • Wyprzedaży,
  • Promocja,
  • Nowość,
  • Super jakości,
  • Super ceny,
  • Najlepszej oceny,
  • Rekomendacji sprzedawcy.
Informacja tego typu ustawiana jest bezpośrednio na karcie towaru w systemie ERP poprzez zaznaczenie odpowiedniej flagi w systemie ERP XL (zakładka aplikacje) lub atrybutu czasowego w ERP Optima (zakładka e-Sklep, sekcja atrybuty czasowe). Po wybraniu konkretnej opcji w systemie ERP na karcie danego produktu w Comarch e-Sklep zostanie dodana odpowiednia informacja:

Newsletter

Ustawienia parametrów newslettera można edytować w panelu administracyjnym, w zakładce Ustawienia/ Ustawienia sklepu/ Mailing.

Slider marek

Sekcja "Slider marek" umożliwia dodanie do szablonu jednego widoków slidera marek. Na sliderach wyświetlane są loga marek, które zostały zaimportowane z systemu ERP. Po kliknięciu w wybrane logo, pojawi się lista wszystkich towarów, dla których dodana jest konkretna marka. Sekcje mogą być dodane w szablonie w dowolnym miejscu na stronie głównej.

Slider producentów

Sekcja "Slider producentów " umożliwia dodanie do szablonu jednego widoków slidera producentów. Na sliderach wyświetlane są loga producentów, które zostały zaimportowane z systemu ERP. Po kliknięciu w wybrane logo, pojawi się lista wszystkich towarów, dla których dodany jest konkretny producent. Sekcje mogą być dodane w szablonie w dowolnym miejscu na stronie głównej.

Aktualności

Sekcja umożliwia zamieszczenie aktualności na stronie głównej w formie listy artykułów z bloga. Tekst wprowadza się w panelu administracyjnym przechodząc do zakładki  e-Marketing/Blog.

Banner infografika

Sekcja "Banner infografika" pozwala na zaprezentowanie korzyści z zakupów w Twoim sklepie. Dotyczą one obszarów: informacji o dostawie, płatnościach, rabatach czy programie lojalnościowym. Banner możesz dodać tylko do strony głównej. Dodatkowe bannery mieszczą się w katalogu homepage-small w panelu administracyjnym e-Sklepu, obszar: Wygląd sklepu/ Ustawienia/ Bannery.

Stopka

Sekcja "Stopka" zawiera jeden widok do wyboru. W widoku Stopki widnieją strony statyczne, którymi można zarządzać w sekcji Wygląd Sklepu/ Ustawienia/ Nagłówek i Stopka. Dla każdej z sekcji wyświetla się jej utworzona w panelu nazwa. W stopce znajdują się także informacje na temat rodzaju prezentowanych cen w e-Sklepie (brutto czy netto) oraz komunikat @Comarch SA 2022. All rights reserved Powered by Comarch e-Sklep. Dodatkowo istnieje możliwość umieszczenia w stopce odnośników do mediów społecznościowych oraz ich ikony. W stopce trzeciej możemy dodać ikony naszych dostawców oraz form płatności wykorzystywanych w sklepie.

Po wybraniu wszystkich niezbędnych sekcji nasza strona główna powinna być gotowa. Efekt naszej pracy możemy podejrzeć klikając Podgląd w prawym górnym rogu.

Dzięki tej opcji możesz zobaczyć, jak będzie prezentował się Twój szablon zarówno w wersji dekstop, jak i mobile.

Strona główna wymaga dwóch podstawowych elementów: nagłówka oraz stopki. Pozostałe elementy nie są obowiązkowe.

Krok 2 - Lista towarów

Kolejnym krokiem jest utworzenie listy towarów. Aby to zrobić, należy rozwinąć listę zgodnie z poniższym rysunkiem, a następnie przejść do wskazanej zakładki:

Bannery

Sekcja "Bannery" daje możliwość wyboru prezentacji bannerów na liście dostępnych towarów, dzięki którym masz możliwość prezentacji nowych grafik.

Panel filtra

Sekcja "Panel filtra" umożliwia dodanie do szablonu jednego z dwóch dostępnych wariantów. Dodatkowo możesz zdecydować o liczbie wyświetlanych wartości filtrów a także o widoku sekcji filtrów.

Podkategorie

Sekcja "Podkategorie" umożliwia dodanie jednego widoku podkategorii. Jeżeli główna kategoria ma swoje podkategorie, menu graficzne zostanie wyświetlone w następujący sposób:

Opis kategorii

Sekcja umożliwia dodanie jednego z dwóch dostępnych opisów kategorii. Wybierając jeden z nich możesz zdecydować czy forma graficzna prezentowania: nazwy, opisu i zdjęcia kategorii, ma być ustawiona jako zdjęcie lub zdjęcie po lewej stronie. Sekcja może być domyślnie zwinięta lub rozwinięta.

Lista towarów

Podobnie, jak w przypadku strony głównej konfigurujemy wygląd listy towarów. Dodatkowo możemy wskazać domyślny widok listy towarów, prezentację atrybutów a także zdecydować czy pozwolisz na zakup towarów wielowariantowych z listy towarów.

W Kreatorze Szablonu Szafir dostępny jest jeden widok listy towarów:  

Krok 3 - Koszyk

Po utworzeniu szczegółów towaru przechodzimy do wyboru wersji koszyka dostępnego w e-Sklepie. W Kreatorze Szablonu Szafir dostępne są dwie wersje koszyka. Dodatkowo na stronie koszyka możesz wskazać sposób prezentacji przeliczników jednostek miary i zdecydować o wyświetlaniu punktów lojalnościowych:

Następnie możemy przejść do modyfikacji wyglądu naszego szablonu. W tym celu należy przejść do zakładki Style.

Style

Jak zmienić kolory, czcionki oraz ikony?

Po dodaniu elementów strony możemy dodatkowo podejrzeć, jak będzie wyglądał nasz przyszły szablon. W tym celu należy przejść do zakładki Style.

Dodatkowo w zakładce Style możemy zmodyfikować wygląd naszego szablonu. Zmianie podlega motyw kolorystyczny.

Motyw kolorystyczny

Aby zmienić kolor naszego szablonu należy przejść do sekcji Motyw kolorystyczny, gdzie do wyboru przygotowaliśmy 3 gotowe motywy.

Każdy z motywów możemy edytować według indywidualnych preferencji. Możemy zmodyfikować kolor poszczególnych elementów (m.in.: tło strony, tło nagłówka, nazwę towaru). Zmiany należy zapisać klikając Zapisz. Jeśli wykonane zmiany nie są zadowalające, możemy przywrócić ustawienia domyśle dla danego motywu kolorystycznego, klikając przycisk Przywróć.

Możliwe jest również wprowadzenie szesnastkowego zapisu kolorów. Heksadecymalny zapis kolorów dla poszczególnych sekcji w szablonie dostępny jest podczas edycji wybranego motywu kolorystycznego.

Czcionki

W zależności od potrzeb istnieje możliwość wybrania czcionki. Dla naszych klientów udostępniliśmy jej 13 różnych typów. Pod nazwą każdej z nich znajduje się przykładowy wygląd w różnych formatach.

 

Ikony

Ostatnim elementem, który możemy modyfikować z poziomu zakładki Style jest wygląd ikon. Mamy do wyboru 3 różne warianty wyglądu ikon. Dodatkowo istnieje możliwość wyboru w jakiej postaci wyświetla się ikona koszyka (torba, wózek lub koszyk) oraz loader.

Wskazówka
Od teraz możesz zmienić rodzaj loadera, wybierając jedną z 5 propozycji widocznych powyżej.

 

Funkcja cofania zmian

Funkcja odpowiadająca za cofanie oraz powtórzenie wprowadzonych zmian oznaczona jest symbolem strzałek, zapamiętuje ona do 30 ostatnich modyfikacji szablonu. Nieaktywna strzałka oznacza, że aktualnie nie ma dostępnych kroków. Mamy możliwość przywracania zmian: dodawania/ usuwania elementów oraz edycji ich położenia, a także stylu w szablonie.
Wskazówka
Funkcję cofania obejmuje zmiany motywu kolorystycznego, natomiast edycja poszczególnych kolorów w motywie nie jest zapisywana.

Generowanie i wgrywanie szablonu

Po zaprojektowaniu wyglądu szablonu możemy go wygenerować i pobrać na dysk korzystając z przycisku Generuj widocznego w prawym górnym rogu:

Obok przycisku Generuj dostępna jest również opcja Importuj szablon, umożliwiająca wgranie wcześniej zapisanego szablonu z dysku i ponowną jego edycję.

W przypadku prawidłowego wygenerowania szablonu wyświetlony zostanie komunikat informujący o tym fakcie i pobrany plik.

Pobrany szablon należy zaimportować w Comarch e-Sklep w zakładce Wygląd sklepu/ Zaimportuj szablon z Kreatora Wyglądu.

W szablonie Szafir znajduje się informacja na temat godziny wygenerowania szablonu w Kreatorze. Taka informacja znajduje się w panelu administracyjnym w menu: Wygląd sklepu/ Ustawienia/ Więcej (trzy kropki), gdzie należy wybrać opcję Edytuj ustawienia zaawansowane, a potem ponownie Więcej/ Edytuj HTML. Następnie z listy plików należy wybrać _layout.html. Informacje na temat modyfikacji, w tym godzina ostatniej modyfikacji, znajdują się nad oknem edycji pliku. Jeżeli plik nie był modyfikowany, wówczas godzina odpowiada godzinie wygenerowania szablonu w kreatorze.

W przypadku braku obowiązkowych elementów szablonu nie będzie możliwe jego wygenerowanie. przycisk Generuj będzie wyszarzały, a w prawym dolnym rogu pojawi się komunikat „Uzupełnij elementy wymagane w szablonie”. Sekcje, gdzie element nie został wybrany będą się wyświetlać z odpowiednią ikoną.

 

Aktualizacja szablonu

W Kreatorze szablonu Szafir znajduje się opcja aktualizacji poprzednich wersji szablonu. W celu zaktualizowania całego szablonu należy wgrać plik z poprzednim szablonem do Kreatora szablonu Szafir według tej instrukcji:
  • po uruchomieniu strony kreatora wybierz opcję: Stwórz nowy projekt,
  • wybierz Nowy szablon,
  • w prawym górnym rogu wybierz opcję Importuj szablon,
  • następnie zaimportuj plik z szablonem, który ma być zaktualizowany. Po poprawnym zaimportowaniu szablonu otrzymasz informację zwrotną:
  • po wgraniu szablonu do aktualizacji użyj opcji Generuj. 
Dzięki temu w prosty sposób można starsze szablony Szafir podnieść do wersji aktualnej.

Więcej informacji

Więcej informacji można znaleźć w artykułach o wyglądzie sklepu oraz o dostosowaniu wyglądu.

Rozbudowana stopka w szablonach Topaz i Szafir - jak ją skonfigurować?

Wstęp

Stopka to jeden z podstawowych elementów każdego sklepu internetowego. Oprócz wymaganych informacji, które muszą się w niej znaleźć, może zawierać zbiór innych odniesień do konkretnych sekcji w Twoim e-Sklepie, do Twojego bloga lub profili w social mediach. Odnośniki mogą pozytywnie wpływać na wizerunek Twojego sklepu, przyczyniając się do wsparcia sprzedaży i generując większy ruch na stronie. W Kreatorze wyglądu obok standardowych widoków znajduje się dodatkowy, który jest bardziej rozbudowany. W przypadku szablonu Topaz jest to trzeci widok (footer-3), zaś w przypadku Szafira - drugi widok (footer-2). Dzięki modyfikacji obszaru możesz jeszcze bardziej spersonalizować swój sklep poprzez uzupełnienie stopki w więcej przydatnych informacji.

Konfiguracja rozbudowanej stopki

Jak przystąpić do edycji stopki?

Po zaimportowaniu z Kreatora wyglądu stopka będzie wyświetlać się w ograniczonym zakresie. Niezmiennie jej edycji dokonasz z perspektywy zakładek: Wygląd Sklepu/Ustawienia a następnie sekcji Nagłówek/Stopka. To tutaj zdecydujesz o ilości grup stron, konkretnych elementach w ich obrębie a następnie o kolejności w jakiej będą prezentować się w e-Sklepie. Również z tego poziomu dodasz odwołania do Twoich profili na portalach społecznościowych oraz ustawisz favicon dla swojego sklepu internetowego.

Więcej możliwości edycji stopki

Rozbudowana stopka w szablonie Topaz oraz Szafir umożliwia dodanie większej ilości grup stron niż dotychczas. Dzięki temu z łatwością zamieścisz w niej wszystko czego potrzebujesz. Dodatkowo sekcję uzupełniono o grafiki partnerów logistycznych oraz obsługiwanych operatorów płatności.

Przykładowy wygląd rozbudowanej stopki w szablonie Topaz

Przykładowy wygląd rozbudowanej stopki w szablonie Szafir

Jak skonfigurować poszczególne elementy?

    • Elementy 1-5: dodawanie kolejnych grup stron oraz zmiana ich kolejności dokonywana jest poprzez sekcję Nagłówek/Stopka w Ustawieniach w obrębie zakładki Wygląd Sklepu. W obrębie danej grupy możesz dodawać konkretne strony poprzez kliknięcie przycisku Dodaj stronę ze sklepu.
Wskazówka
Zmiany kolejności poszczególnych grup odnośników lub zmiany danych odnośników w obrębie danej grupy dokonuje się metodą Przeciągnij i upuść.
    • Element 6: odpowiada za wyświetlanie następujących informacji: e-mail, numer telefonu, telefon2 (jeśli nie istnieje, to zastępowany jest przez telefon komórkowy) fax lub skype. W celu edycji danych kontaktowych należy przejść w panelu e-Sklepu do zakładki Ustawienia/Ustawienia sklepu. Informacje o adresie e-mail pobierane są automatycznie z zakładki Ogólne z sekcji Konto e-mail sklepu. Aby dodać lub zmodyfikować numer telefonu konieczne jest wybranie zakładki Dane sprzedawcy, następnie Infolinia i zweryfikowanie pola Telefon.
      Wskazówka
      W elemencie wyświetlone zostaną maksymalnie 3 informacje (e-mail, telefon i jedno z wybranych pól np. telefon2, telefon komórkowy lub fax.
    • Element 7: odwołania do portali społecznościowych dodajemy bez zmian. Więcej o tym znajdziesz tutaj.
    • Elementy 8-9: aby dodać informację o operatorach płatności oraz partnerach logistycznych należy wybrać zakładkę Wygląd Sklepu/Ustawienia/Bannery. Edycji dokonasz z perspektywy kafelków: Logistics Partners oraz Payment Operators poprzez dodanie właściwych grafik operatorów i partnerów. Aby zmienić nazwę „Operator płatności” i/lub „Partnerzy logistyczni” wybierz zamiast zakładki Bannery, zakładkę Tłumaczenia. Wyszukaj po parametrze „ID” LogisticsPartnersBannerTitle oraz PaymentOperatorsBannerTitle i zmodyfikuj pole „Tekst” według własnych preferencji. Zmiany zapisz i opublikuj. W przypadku chęci usunięcia któregoś z elementów, zaznacz go i naciśnij przycisk „Usuń”.
Wskazówka
Zalecane parametry grafik dla operatorów płatności i partnerów logistycznych: szerokość maksymalna 64 px, rozszerzenie PNG.
    • Element 10: dane dotyczące firmy pobierane są z zakładki Ustawienia/Ustawienia sklepu/Dane sprzedawcy/Dane identyfikacyjne, a także z obszaru: Ustawienia/ Ustawienia sklepu/ Informacja o działalności gospodarczej/ Numer KRS lub CEIDG, Organ rejestrujący oraz Ustawienia/ Ustawienia sklepu/ Adres pocztowy, gdzie uwzględnione zostaną wszystkie pola za wyjątkiem Szerokości i długości geograficznej.

Tabela rozmiarów w szablonie Szafir

Wstęp

W sklepach internetowych, szczególnie tych z odzieżą, bardzo często widoczna jest tabela rozmiarów. Pozwala na prezentację szczegółowych informacji na temat asortymentu w sklepie. Odnośnik do tabeli umieszczony jest najczęściej na szczegółach towaru. Warto pamiętać, że tabela rozmiarów jest funkcją, którą możesz dostosować do swojej branży i zaprezentować w niej dowolne dane. W takiej formie prezentowane są m.in.: wymiary produktów, cechy charakterystyczne, a także zalecenia względem użytkowania. Aby móc skorzystać z przygotowanego przez nas mechanizmu tabeli rozmiarów w swoim e-Sklepie należy posiadać:
  • aktualną wersję szablonu Szafir (min. 2023.0.2),
  • oraz aktualną wersję e-Sklepu (min. 2023.0).
Postępuj zgodnie z poniższą instrukcją, aby poprawnie skonfigurować tabelę.

Aktywacja tabeli rozmiarów w szablonie Szafir

Tabela rozmiarów może być prezentowana na 3 różne sposoby, w zależności od oczekiwanego efektu:
  • jeżeli posiadasz wspólną tabelę dla całego asortymentu, ilość informacji jest niewielka i chcesz pokazać tabelę w formie popup’a, skorzystaj ze sposobu konfiguracji poprzez sekcję bannerową o nazwie SizeTable.
  • jeżeli posiadasz dużą ilość tabel, ponieważ posiadasz zróżnicowany asortyment skorzystaj z prezentacji poprzez osobną Stronę o nazwie Tabela rozmiarów,
  • jeżeli chcesz prezentować tabelę rozmiarów indywidualnie dla każdego towaru skorzystaj z konfiguracji tabeli, jako załącznika w formacie PDF – udostępnionego w systemie Comarch ERP.
Dodatkowo możesz wybrać, dla których towarów ma się wyświetlać tabela rozmiarowa:
  • dla wszystkich towarów,
  • tylko dla towarów z wariantami.
Aby skonfigurować tabelę z poziomu panelu administracyjnego, postępuj zgodnie z instrukcją: Krok 1. Zaloguj się do panelu administracyjnego, a następnie przejdź do sekcji Wygląd sklepu/ Ustawienia. Krok 2. W zakładce Ogólne odszukaj sekcję o nazwie Tabela rozmiarów. Krok 3. Spośród dostępnych parametrów wybierz, czy tabela rozmiarów ma się pojawiać na towarach z wariantami, czy na wszystkich Krok 4. Wybierz sposób, na podstawie jakiej konfiguracji będzie prezentowana tabela rozmiarów - banneru o nazwie SizeTable, dedykowanej stronie o nazwie Tabela rozmiarów, czy załącznika PDF.

Konfiguracja tabeli rozmiarów poprzez banner o nazwie SizeTable

Aby dodać tabelę rozmiaru poprzez banner o nazwie SizeTable postępuj zgodnie z instrukcją: Krok 1. W panelu administracyjnym przejdź do sekcji Wygląd sklepu/ Ustawienia/ zakładka Ogólne.  Pod parametrem: Tabela rozmiarów prezentowana na podstawie zaznacz SizeTable. Krok 2. Kolejno przejdź do zakładki: Wygląd sklepu/ Ustawienia, a następnie na zakładkę Bannery. Krok 3. Przejdź do szczegółów sekcji bannerowej o nazwie SizeTable, a następnie dodaj odpowiednie obrazki. Krok 4. Zapisz wprowadzone zmiany.   Efekt: Po zapisaniu i opublikowaniu zmian Klient przeglądający stronę przechodząc do tabeli rozmiarów ujrzy dodane przez Ciebie obrazki w następujący sposób:

Konfiguracja tabeli rozmiarów w formie dedykowanej Strony

Możliwe jest także dodanie tabeli rozmiarów wykorzystując gotowe Strony w panelu administracyjnym, gdzie przygotowaliśmy dedykowaną stronę oraz treść o nazwie Tabela Rozmiarów. Postępuj zgodnie z instrukcją, aby skonfigurować tabelę poprzez gotową stronę: Krok 1. W panelu administracyjnym przejdź do sekcji Wygląd sklepu/ Ustawienia/ zakładka Ogólne.  Pod parametrem: Tabela rozmiarów prezentowana na podstawie zaznacz Strony. Krok 2. Kolejno przejdź do sekcji: Ustawienia/ Treści/ zakładka Regulamin i inne. Krok 3. Z listy dostępnych treści przejdź do edycji treści o nazwie Tabela rozmiarów.  Jest to przygotowana przez nas propozycja dotycząca prezentacji tabeli rozmiarów. Treść możesz dowolnie edytować i dostosować ją do swoich oczekiwań.
Wskazówka
Pamiętaj, aby wszelkie wprowadzone zmiany zapisać oraz opublikować.
Efekt: Po naciśnięciu odnośnika do tabeli rozmiarów Klient zostanie przekierowany na utworzoną wcześniej stronę w e-Sklepie, gdzie widoczna będzie wcześniej wpisana przez Ciebie treść.

Konfiguracja tabeli w systemie Comarch ERP - plik PDF

Tabelę rozmiarów możesz także skonfigurować umieszczając plik PDF w formie załącznika na towarze, w swoim systemie Comarch ERP. Przykład konfiguracji w systemie Comarch ERP Optima: Krok 1. W panelu administracyjnym przejdź do sekcji Wygląd sklepu/ Ustawienia/ zakładka Ogólne.  Pod parametrem: Tabela rozmiarów prezentowana na podstawie zaznacz plik PDF. Krok 2. W systemie ERP Optima przejdź do szczegółów wybranego towaru. Krok 3. W zakładce Atrybuty dodaj załącznik w postacie pliku PDF, gdzie będzie zaprezentowana tabela rozmiarów.
Uwaga
Załącznik musi znajdować się na pierwszej pozycji.
Krok 4. Upewnij się, że załącznik jest udostępniany do Comarch e-Sklep. Krok 5. Zapisz zmiany i wykonaj synchronizację danych. Efekt: Klient po kliknięciu w przycisk tabela rozmiarów zobaczy przygotowany plik w osobnej karcie przeglądarki.

Wyróżnienie przycisku paska nawigacji w szablonie Szafir

Wstęp

W e-Sklepie jako sprzedawca możesz chcieć zwrócić szczególną uwagę swoich klientów na konkretny element strony. Takim elementem może być wyróżniony kafelek paska nawigacji, który będzie informował na przykład o trwającej promocji czy wyprzedaży. Dzięki wyróżnieniu i przekierowaniu klient szybciej trafi na stronę z interesującym go asortymentem.

Konfiguracja

W szablonie Szafir możliwe jest ustawienie wyróżnienia kolor tła oraz czcionki wyróżnionego elementu w pasku nawigacji. Aby to zrobić zaloguj się do panelu administracyjnego, a następnie do obszaru Wygląd sklepu/ Ustawienia. W zakładce Ogólne odnajdź sekcję „Kolor tła wyróżnionego elementu w pasku nawigacji”. Pod nią znajdują się również pozycje odpowiadające za zmianę koloru czcionki przed, jak i po najechaniu na kafelek kursorem. Wybierz kolory, którymi chcesz wyróżnić element w pasku nawigacji. Następnie zapisz zmiany. Teraz przejdź do zakładki Strona główna. Zaznacz te elementy, które mają zostać wyróżnione. Wystarczy, że wybierzesz odpowiedni checkbox pod Wyróżnij. W efekcie klienci odwiedzający stronę Twojego sklepu zobaczą wyróżnione elementy. Mogą się one różnić różnić się w zależności od tego, czy klient jest zalogowany czy też nie.  

Planowane dostawy towarów w e-Sklepie

Wstęp

Comarch e-Sklep umożliwia klientowi sprawdzenie dostępności towaru w sklepie. Dzięki funkcji Sprawdź dostępność towaru w sklepie, osoby odwiedzające Twój e-Sklep będą mogły sprawdzić z poziomu strony internetowej, czy dany towar został już zamówiony u dostawcy.

Zastosowanie

Funkcja służy do sprawdzania nie tylko, czy towar został zamówiony u dostawcy, ale również udostępnia informacje o zamówionej ilości oraz planowanej dostawie. Po wejściu na kartę produktu klient ma możliwość kliknięcia w napis Sprawdź dostawy. W tym momencie sklep uruchomi Comarch e-Sklep Sync, aby ten pobrał informacje z dokumentu Zamówienia Zakup (ZZ) o planowanych dostawach z systemu ERP XL. Opcja jest dostępna na stronie szczegółów towaru na wszystkich towarach w sklepie - zarówno na tych, które można kupić jak i na takich, gdzie nie ma opcji dodawania do koszyka (np. zapytaj o cenę, czy powiadom o dostępności).

Kto może używać tej opcji?

Aby skorzystać ze wspomnianej funkcjonalności należy posiadać:
  • e-Sklep w wersji B2B,
  • Działającą usługę Comarch e-Sklep Sync,
  • System ERP XL,
  • Zainstalowany szablon Szafir.

Konfiguracja

  1. W panelu administracyjnym Wygląd sklepu/ Ustawienia/ Ustawienia szablonu/ Ogólne należy znaleźć Dostawy towarów i wybrać opcję Tak.
  2. Po zapisaniu i opublikowaniu zmian klienci po przejściu do szczegółów towaru będą mieli możliwość sprawdzenia planowanych dostaw.

Skąd pobierane są informacje o planowanych dostawach?

Informację wyświetlane na szczegółach towaru są pobierane z listy zamówień zakupu z systemu Comarch ERP XL. W zależności od statusu dokumentu ZZ klient widzi inny status na oknie z informacjami. Status dokumentu ZZ:
  • Potwierdzone – Dostawa potwierdzona,
  • Niepotwierdzone – Dostawa niepotwierdzona,
  • Anulowane potwierdzenie – Brak informacji,
  • Zamknięte potwierdzone – Brak informacji.
Czas planowanej daty dostawy brany jest z dokumentu ZZ z pola Data realizacji. Datę na dokumencie można modyfikować po potwierdzeniu dostawy. Zmiany dokonują się w e-Sklepie w momencie ich zapisania.

Towary wielowartościowe

Dla towarów wielowartościowych (fantomów i towarów z cechami) sprawdzanie dostępności (oraz wyświetlanie planowanych dostaw) pokazuje się według wybranej cechy.
Wskazówka
W szablonie Szafir wybraną cechą jest ta, która w momencie wywołania funkcji sprawdzenia dostępności w salonie jest oznaczona widoczną granatową ramką.

Dodatkowe informacje

Szczegółowe informacje dotyczące działania Comarch e-Sklep Sync znajdziesz w artykule: Comarch e-Sklep Sync.

Jak wyeksportować i zaimportować swój szablon w e-Sklepie?

Comarch e-Sklep daje możliwość dostosowania wyglądu do preferencji sprzedawcy oraz potrzeb Klientów. Jeśli utworzyłeś już swój autorski projekt, to masz możliwość jego zapisania. Plik będzie potrzebny przy chęci modyfikacji wyglądu. Zapisana wersja szablonu może również stanowić kopię bezpieczeństwa. Warto jest więc wyeksportować szablon do pliku.

Jak wyeksportować swój szablon z Comarch e-Sklep?

Krok 1. W panelu administracyjnym przejdź do sekcji Wygląd Sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane/ zakładka Eksport szablonu.

Krok 2. W tym miejscu możesz opcjonalnie (przed eksportem) określić autora szablonu, podać adres e-mail, telefon oraz adres WWW swojego e-Sklepu.

Krok 3. Jeżeli chcesz wyeksportować szablon do pliku użyj przycisku Eksportuj szablon.

Gotowe! Szablon został wyeksportowany do pliku na Twoim urządzeniu.

Wskazówka
Z tego miejsca możesz także wyeksportować posiadane w e-Sklepie bannery, korzystając z przycisku Eksportuj bannery.

Jak wgrać własny szablon do Comarch e-Sklep?

Własny szablon. Jak go wgrać?

Po skomponowaniu swojego własnego szablonu możesz wgrać go do e-Sklepu. Postępuj zgodnie z poniższymi krokami.

Krok 1. W panelu administracyjnym przejdź do sekcji Wygląd Sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane/ zakładka Import szablonu.

Krok 2. Określ, czy wgrywany szablon ma podmienić istniejące bannery. Gdy parametr zostanie zaznaczony, wówczas wszystkie bannery zapisane na danym slocie zostaną usunięte i zastąpione bannerami z importowanego szablonu.

Krok 3. Wybierz plik XML swojego szablonu i naciśnij Importuj szablon.

Uwaga
Import szablonu jest operacją nieodwracalną i spowoduje nadpisanie dotychczasowego szablonu. W przypadku, gdy szablon był modyfikowany (dokonywano zmian w kodzie HTML) jego aktualizacja spowoduje, iż zmiany nie zostaną przeniesione. Warto wykonać eksport posiadanego szablonu do pliku w celu zapisania oraz posiadania wglądu to wprowadzanych modyfikacji. Jeżeli istnieje taka konieczność należy ponownie dokonać samodzielnej edycji szablonu

Wskazówka
W zakładce Szablony możesz określić, czy wgrywany szablon ma być domyślny i aktywny w e-Sklepie.

Krok 4. Teraz możesz podejrzeć zmiany, jakie zaszły w wyglądzie Twojego e-Sklepu. W tym celu możesz podejrzeć zmiany w czasie rzeczywistym lub przejść w tryb incognito. Pamiętaj, że wszelkie zmiany zostaną opublikowane po pełnej synchronizacji, która wciągu 10 minut zgodnie z wyświetlanym komunikatem.

Gotowe! Twój szablon został zaimportowany do e-Sklepu.

Obsługa sekcji Lista towarów w szablonie Szafir

Od wersji 2021.5 został dodany nowy widok listy towarów w szablonie Szafir. W panelu administracyjnym na zakładce Wygląd sklepu/ Ustawienia/ Ustawienia szablonu/ Lista towarów znajdują się nowe oraz dotychczasowe parametry związane z wyświetlaniem listy produktów, prezentacji filtrów, kategorii oraz możliwe jest wybranie menu graficznego. Dzięki zebraniu wszystkich ustawień listy towarów w jednym miejscu administrator ma do nich szybki dostęp oraz może jeszcze bardziej zindywidualizować wygląd swojego sklepu, a tym samym dostosować go do swoich potrzeb czy trendów panujących w danej branży.

Na zakładce Lista towarów można zdecydować np.: o ilości wyświetlanych filtrów lub miejscu na stronie, w którym mają się znajdować. Administrator sklepu może również zmienić formę graficzną prezentowania nazw, opisu i zdjęć kategorii oraz aktywować nowe graficzne menu nawigacji dla podgrup. Aby wprowadzone zmiany były widoczne w szablonie należy je zapisać i opublikować.

1. Filtry

  • Użytkownik może zdecydować, czy filtry mają wyświetlać się po lewej stronie pod menu kategorii, czy u góry nad listą towarów.
  • Użytkownik może określić, czy wyświetlana sekcja filtry domyślnie będzie domyślnie zwinięta, czy rozwinięta.
  • Użytkownik może określić liczbę wyświetlanych wartości w filtrze: 3, 5 lub 8. 
  • Użytkownik może wskazać czy filtrowanie ma być przeprowadzone po użyciu przycisku Zastosuj, czy dynamicznie po wybraniu właściwych checkboxów,
Przyklad
W ramach przykładu w panelu administracyjnym zostały zaznaczone parametry:
  • Liczba wyświetlanych wartości: 5,
  • Widok panelu filtra: U góry nad listą towarów,
  • Filtruj po użyciu przycisku „Zastosuj”: Tak,
  • Sekcja domyślnie: Rozwinięta.
 
Wskazówka
W przypadku zaznaczenia parametru Sekcja domyślnie - Zwinięta, aby otworzyć obszar filtry należy kliknąć ikonę filtra.

2. Kategoria

  • Obszar kategoria daje możliwość wyboru czy: nazwa, grafika i opis kategorii, będą znajdowały się nad listą towarów, czy pod listą towarów.
  • Forma graficzna prezentowania: nazwy, opisu i zdjęcia kategorii, może być ustawiona jako zdjęcie w tle i zdjęcie po lewej.
  • Sekcja może być domyślnie zwinięta lub rozwinięta.
Przyklad
W ramach przykładu w panelu administracyjnym zostały zaznaczone parametry:
  • Nazwa, grafika i opis Kategorii: Nad listą towarów.
  • Forma graficzna prezentowania nazwy, opisu i zdjęcia kategorii: Zdjęcie w tle.
  • Sekcja domyślnie: Rozwinięta.
W przypadku, gdy użytkownik ustawi np.:
  • Nazwa, grafika i opis kategorii: Pod listą towarów.
  • Forma graficzna prezentowania nazwy, opisu i zdjęcia kategorii: Zdjęcie po lewej.
  • Sekcja domyślnie: Rozwinięta.
 
  • Nazwa, grafika oraz opis ustawi się pod listą towarów.
  • Zdjęcie zostanie wyświetlone po lewej stronie, natomiast opis obok.
Uwaga
W przypadku, gdy Użytkownik ustawi Sekcja domyślnie - Zwinięta, klient zobaczy grafikę i opis dopiero po kliknięciu w strzałkę skierowaną w dół.

3. Domyślny widok listy produktów

Użytkownik ma możliwość ustawienia rodzaju wyświetlania się listy towarów na komputerze/laptopie i na urządzeniu mobilnym.
  • Desktop: szybkie zakupy, lista lub kafelki.
  • Mobile: szybkie zakupy lub lista.
Przyklad
  • Desktop – kafelki spowoduje, że Klient wchodząc do sklepu zobaczy towary w formie kafelków.
  • Poniżej przedstawiono różnicę pomiędzy widokami mobilnymi – szybkie zakupy oraz lista. Zrzut ekranu pierwszy po lewej przedstawia widok szybkie zakupy.

4. Filtr typu kolor

Użytkownik ma możliwość wyświetlania filtra kolor w formie graficznej.
Uwaga
Atrybut kolor wyświetli się wtedy i tylko wtedy gdy:
  • Użytkownik doda atrybut typu lista o wartości kolor na wybraną grupę towarową bez podanej wartości.
  • Użytkownik doda atrybut kolor na wybranym towarze i poda ustali wartość atrybutu.
Pełny opis konfiguracji tej funkcji w szablonie Szafir został przedstawiony w osobnym artykule.

5. Krótki opis

Użytkownik ma możliwość dodania krótkiego opisu na widoku typu lista domyślnie rozwinięty - oznacza to, że skrócony opis (dodany w systemie Comarch ERP Optima), będzie wyświetlany na liście towarów, gdy użytkownik zaznaczy parametry:
  • Krótki opis – Tak
  • Domyślny widok listy produktów:
    • Desktop – Lista,
    • Mobile – Lista (W przypadku urządzeń mobilnych).
Wskazówka
Krótki opis należy uzupełnić w Comarch ERP Optima: Ogólne/ Cennik/ Szczegóły wybranego towaru/  Zakładka e-Handel, Sekcja języki / Dodaj (Plusik) lub Otwórz (Lupka)/ Pozycjonowanie/ Opis skrócony:

6. Towary wielowariantowe

Użytkownik ma możliwość wyboru towarów wielowariantowych (fantomów) bezpośrednio z listy towarów. Oznacza to, że po kliknięciu w "Wybierz wariant towaru" użytkownik nie zostanie przełączony na szczegóły towaru - zamiast tego wyskoczy dodatkowe okno z możliwością wyboru wariantu towaru.

7. Graficzne menu

Użytkownik ma możliwość ustawienia graficznego menu, czyli wyświetlania zdjęć kategorii i podkategorii. Jeżeli główna kategoria ma swoje podkategorie, menu graficzne zostanie wyświetlone w następujący sposób. Dodawanie graficznego menu dostępne jest w Kreatorze wyglądu, poprzez dodanie do szablonu parametru subcategories-1 w widoku Listy towarów.

Kreator sklepu detalicznego (B2C)

Jak zaprezentować banner w liście towarów dla szablonu Topaz?

Wstęp

Banner prezentowany na listach towarowych Twojego e-Sklepu przyciągnie uwagę klientów i pomoże zwiększyć sprzedaż. Dzięki wyrazistym grafikom i atrakcyjnym komunikatom można promować konkretne produkty, sezonowe promocje lub nowości, wyróżniając je spośród innych ofert. Sprawdź jak łatwo można dodać i skonfigurować banner, który będzie wyświetlany na listach towarowych w Twoim sklepie.

Jak dodać banner do listy towarów?

Krok 1. Banner możesz dodać z poziomu Kreatora Wyglądu B2C  (zamiennie: panel administracyjny e-Sklepu: Wygląd sklepu > Kreator wyglądu).W Kreatorze banner znajduje się w sekcji Lista towarów > Banner w liście towarów. Aby dodać banner wystarczy w niego kliknąć:
Wskazówka
Aby zmienić banner wystarczy kliknąć inny banner, natomiast aby go usunąć należy ponownie kliknąć na dodany banner.
Krok 2. Ustawienia banneru możesz skonfigurować zarówno z poziomu Kreatora Wyglądu jak i panelu administracyjnego. W Kreatorze Wyglądu po dodaniu banneru do listy towarowej kliknij w symbol ustawień a następnie przejdź do zakładki Banner w liście towarów: Krok 3. Szablon z tak przygotowanym bannerem należy wygenerować. Po zaimportowaniu szablonu do panelu administracyjnego możesz przejść do dalszej konfiguracji. Krok 4. Przejdź do ustawień Wygląd sklepu > Ustawienia > Bannery. W tej sekcji znajdź banner o nazwie banner-in-list-1 lub jeśli wybrałeś drugą opcję to banner-in-list-2, a następnie przejdź do jego edycji. Krok 5. Za pomocą ikony plusa dodaj obrazek w rozmiarze 720x300 dla banner-in-list-1 lub 1400x300 dla banneru banner-in-list-2. Po przesłaniu właściwego obrazka kliknij na Widok zaawansowany, aby przejść do edycji pozostałych elementów.
Wskazówka
Pamiętaj o tym, aby zapisać i opublikować wprowadzone zmiany.
Krok 6. Gotowe! Twój banner będzie prezentował się w sklepie następująco:
Wskazówka
Ustawienia banneru osadzongo w liście towarów możesz zmienić także w panelu administracyjnym przechodząc do zakładki Wygląd sklepu > Ustawienia > Zarządzanie elementami na liście towarów.

Jak zaprezentować banner z odliczaniem czasu w szablonach B2C?

Wstęp

Banner promocyjny z odliczaniem czasu będzie prezentowany na stronie głównej Twojego e-Sklepu i będzie wskazywał czas do końca opisanej oferty. Taki rodzaj banneru pomoże Ci w zwróceniu uwagi Klientów na okazje ograniczone czasowo, które są dostępne w obrębie Twojego sklepu.

Jak na stronie głównej zaprezentować banner z odliczaniem czasu?

Krok 1. Banner możesz dodać z poziomu Kreatora Wyglądu B2C  (zamiennie: panel administracyjny e-Sklepu: Wygląd sklepu/ Kreator wyglądu).W Kreatorze banner znajduje się w sekcji Banner promocyjny. Stąd przeciągnij go w wybrane przez Ciebie miejsce w szablonie: Krok 2. Szablon z tak przygotowanym bannerem należy wygenerować. Po zaimportowaniu szablonu do panelu administracyjnego możesz przejść do dalszej konfiguracji odliczania czasu. Krok 3. Przejdź do ustawień Wygląd sklepu/ Ustawienia/ Bannery. W tej sekcji znajdź banner o nazwie promotionalBanner, a następnie przejdź do jego edycji. Krok 4. Za pomocą ikony plusa dodaj obrazek w rozmiarze 1920px na 680px do banneru. Po przesłaniu właściwego obrazka kliknij na niego, aby przejść do edycji. Krok 5. Wybierz zakładkę Ustawienia. Tutaj masz możliwość zdefiniowania do kiedy ma trwać odliczanie:
Wskazówka
Po skończeniu odliczania banner nadal będzie widoczny na sklepie, aby móc poinformować o zakończeniu oferty. Jeżeli chcesz, aby banner przestał być widoczny wraz z zakończeniem odliczania, należy przejść do sekcji Widok zaawansowany. Tutaj znajdują się dodatkowo ustawienia dotyczące czasu prezentowania banneru na sklepie:
  Krok 6. Gotowe! Twój banner będzie prezentował się w sklepie następująco:

Jak zaprezentować odliczanie czasu w bannerze top?

Odliczanie czasu jest także dostępne z poziomu banneru top. Jest to banner znajdujący się na samej górze witryny. Dzięki ustawieniu odliczania czasu w tym miejscu będziesz mógł od razu zwrócić uwagę klientów na dostępne okazje. Aby to zrobić, zastosuj się do poniższej instrukcji Krok 1. Przejdź do sekcji Wygląd sklepu/ Ustawienia/ Bannery i wybierz banner o nazwie top. Krok 2. Kliknij na edycję konfiguracji wskazanego banneru. Krok 3. W zakładce Ustawienia zdefiniuj czas odliczania:.
Wskazówka
Aby czas odliczania pokazywał się w bannerze top należy uzupełnić pole "Tekst" w Widoku zaawansowanym: Tekst będzie traktowany jako napis informacyjny przy odliczaniu czasu.
Krok 4. Banner top będzie prezentował się na sklepie następująco:
Wskazówka
Opcja odliczania czasu w bannerze top jest możliwa do skonfigurowania wraz z linkami. Informacje o konfiguracji banneru top z wieloma linkami można znaleźć w artykule Jak dodać wiele linków dla banneru top? W takim przypadku należy uzupełnić konfigurację linków, ustawić opcję odliczania czasu, jak również uzupełnić pole "Tekst". Dzięki temu banner top zyska następujący wygląd:
 

Jak edytować nagłówek w szablonie B2C?

Wstęp

Nagłówek w e-Sklepie to stały element, umieszczony na górze ekranu lub na dole w wersji mobilnej. Jego głównym celem jest umożliwienie użytkownikom szybkiego dostępu do różnych sekcji witryny, takich jak: “Strona główna”, “O nas” czy “Kontakt”. Dzięki opcji edycji nagłówka możesz prosto i szybko:
  • dodawać, edytować, wyróżniać i usuwać strony lub grupy stron,
  • dodać, edytować lub usuwać odnośniki do mediów społecznościowych,
  • w jednym miejscu zmienić logotyp i favicon.
Możliwość edycji nagłówka dostępna jest dla szablonów B2C: Topaz, One Page Shop oraz Dla Gastronomii. Aby edytować zawartość nagłówka sklepu, należy przejść w panelu administracyjnym do obszaru: Wygląd sklepu  > Ustawienia > Nagłówek: W tym miejscu masz możliwość:
  • ustawienia logotypu i faviconu,
  • ustalenia, które media społecznościowe powinny wyświetlać się w nagłówku,
  • dodania stron lub grupy stron,
  • przejścia do konfiguracji menu kategorii.

Jak dodać logotyp i favicon?

Aby dodać logotyp i favicon, wybierz przycisk „Wyślij plik”, a następnie wybierz plik z odpowiedniego miejsca na Twoim komputerze.
Wskazówka
Pamiętaj, że w przypadku logotypu, maksymalny rozmiar obrazka wynosi 30 KB, a wymiary to 200 x 200px. Rekomendowane formaty: PNG, JPG, JPEG, SVG. W przypadku faviconu maksymalny rozmiar obrazka wynosi 10 KB, a rekomendowane formaty to: PNG, JPG, JPEG, SVG.

 

Jak edytować odnośniki do mediów społecznościowych?

Wskazówka
Miniatury z odnośnikami do mediów społecznościowych są widoczne w drugim i trzecim typie nagłówka (header-2 oraz header-3) w szablonie Topaz.
Aby edytować istniejący odnośnik do mediów społecznościowych, przejdź do szczegółów logotypu wybranego serwisu, który chcesz podłączyć do e-Sklepu. W miejscu "# " w kodzie wklej link do swojego portalu. Dzięki temu możliwe będzie przekierowanie użytkownika do konkretnego medium społecznościowego. Następnie zapisz zmiany. Aby dodać nowy odnośnik do mediów społecznościowych wystarczy, że naciśniesz ikonę plusa. Wyświetli się wówczas edytor, do którego należy wkleić analogiczny kod, jak w przykładzie prezentowanym powyżej. Fragment kodu należy skopiować z poziomu panelu administracyjnego. W miejscu "#"w kodzie wklej link do swojego portalu. Jeśli chcesz zmienić obrazek, to we fragmencie kodu w miejscu linku wklej swój odnośnik do wybranego zdjęcia. Może to być odnośnik skopiowany z pliku, który znajduje się w Plikach użytkownika.
Wskazówka
W nagłówku wyświetli się pięć pierwszych ikon mediów społecznościowych, które zostały dodane w panelu administracyjnym.
 

Jak dodać strony lub grupy stron?

Z poziomu obszaru Wygląd sklepu > Ustawienia > Nagłówek możesz dodać Stronę lub Grupę stron. Aby to zrobić, należy wybrać sekcję "Dodaj stronę lub grupę stron". Po wybraniu tej opcji wyświetli się następujący popup: Z poziomu popupu należy zaznaczyć parametr: Stronę lub Grupę stron i uzupełnić obowiązkowe pole "Nazwa". Następnie, aby dodać odnośnik do strony, należy edytować dodaną stronę lub grupę.  Podczas edycji w panelu administracyjnym wyświetli się obszar, w którym możliwe jest dokonanie zmian. Możesz zdecydować, czy do strony lub grupy stron dodasz już istniejącą stronę ze sklepu, czy stronę zewnętrzną: Po wyborze opcji "Dodaj stronę ze sklepu" pokaże się popup z listą stron, które można wybrać i dodać do sekcji. Możesz także dodać stronę zewnętrzną, uzupełniając pola na formularzu: Przy dodanym odnośniku możesz zdecydować, czy chcesz go wyróżnić, otworzyć w nowej karcie, czy usunąć.   Wprowadzone zmiany należy zapisać i opublikować. Poniżej prezentujemy efekt wprowadzonych konfiguracji (dodanie mediów społecznościowych, grupy stron oraz wyróżnienia):
Topaz header-2
Topaz header-2
 
Topaz header-3
Topaz header-3
   

Indywidualny banner dla kategorii towarowej w szablonie Topaz

Indywidualny banner dla kategorii towarowej - jak to działa?

Od wersji 2024.5 w Twoim e-Sklepie masz możliwość dodania banneru do wybranej przez Ciebie grupy towarowej. Pomoże Ci to lepiej wyeksponować i dopasować zdjęcia czy komunikaty, które chcesz przedstawić przeglądającym ofertę Twojego sklepu. Możesz ustalić na przykład, który konkretny obrazek powinien wyświetlić się w kategorii z artykułami kosmetycznymi do twarzy, a który przy towarach związanych z pielęgnacją włosów.

Dodanie banneru

Banner możesz dodać z poziomu Kreatora wyglądu. Aby to zrobić, przejdź na stronę "Lista towarów", po czym wybierz dowolny banner i przeciągnij go w wybrane przez Ciebie miejsce. Jeśli pozostałe strony szablonu są gotowe i skonfigurowane, to możesz go w całości wygenerować. Więcej informacji na temat Kreatora Wyglądu oraz poszczególnych sekcji znajdziesz w artykule: Kreator wyglądu Topaz (B2C) Teraz możesz zaimportować szablon do panelu administracyjnego, w którym nastąpi reszta konfiguracji. Postępuj zgodnie z poniższą instrukcją.

Edycja banneru

Modyfikacja wszystkich bannerów dostępnych w szablonach Comarch możliwa jest w panelu administracyjnym w obszarze Wygląd sklepu> Ustawienia> Bannery. Informacje odnośnie domyślnej, tradycyjnej modyfikacji bannerów znajdują się w artykule: Bannery

Odnajdź odpowiedni banner na liście, a następnie wybierz go, aby edytować. Podczas edycji możesz wybrać jeden typ banneru spośród trzech: Standardowy, Lookbook oraz Dla kategorii. Dodaj obrazek ikoną plusa, a następnie zaznacz typ "Dla kategorii".

Aby wybrać kategorię, kliknij na dodany wcześniej obrazek, a następnie naciśnij "Zmień", aby zmienić kategorię.   Po naciśnięciu przycisku wyświetli się lista kategorii dostępnych w Twoim e-Sklepie. Wybierz tę, przy której chcesz wyświetlić banner. Po zmianie kategorii naciśnij "Wybierz", aby zatwierdzić. Dodana kategoria pojawiła się na liście. Możesz ją zmienić, usunąć, lub dodać kolejną. Po modyfikacjach wybierz przycisk "Zmień". Po modyfikacjach należy zapisać i opublikować zmiany. Gotowe! Teraz Twój banner dla kategorii wyświetli się na liście towarów przy wybranej przez Ciebie grupie towarowej.

Banner promocyjny w szablonie Topaz i One Page Shop

Banner promocyjny - jak to działa?

Banner promocyjny wyświetli się na stronie głównej Twojego e-Sklepu i będzie prezentował typ towaru, który wskażesz. Taki rodzaj banneru pomoże Ci w zwróceniu uwagi Klientów na towary, które zostały objęte na przykład ofertą specjalną.

Dodanie banneru

Banner możesz dodać z poziomu Kreatora Wyglądu B2C  (zamiennie: panel administracyjny e-Sklepu: Wygląd sklepu/ Kreator wyglądu). Aby dodać banner promocyjny do swojego szablonu, przejdź na stronę "Strona główna", po czym wybierz Banner promocyjny i przeciągnij go w wybrane przez Ciebie miejsce. W podglądzie układu szablonu, po najechaniu kursorem na obszar z bannerem promocyjnym, zobaczysz możliwość jego edycji. Wybierz ikonę "zębatki", aby móc edytować i określić liczbę wyświetlanych towarów oraz typ promowanych towarów. Zapisz wprowadzone zmiany. Jeśli pozostałe strony szablonu są gotowe i skonfigurowane, to możesz wygenerować szablon. Więcej informacji na temat Kreatora Wyglądu oraz poszczególnych sekcji znajdziesz w artykule: Kreator wyglądu Topaz (B2C) Po zaimportowaniu szablonu do panelu administracyjnego możesz przejść do edycji banneru. Postępuj zgodnie z poniższą instrukcją.

Edycja banneru

Modyfikacja wszystkich bannerów dostępnych w szablonach Comarch możliwa jest w panelu administracyjnym w obszarze Wygląd sklepu> Ustawienia> Bannery. Informacje odnośnie domyślnej, tradycyjnej modyfikacji bannerów znajdują się w artykule: Bannery

Odnajdź banner na liście nazwany "promotionalBanner", a następnie wybierz go, aby edytować i dodać zdjęcie

Po dokonaniu modyfikacji należy zapisać i opublikować zmiany. Gotowe! Teraz Twój banner promocyjny wyświetli się na stronie głównej.
Banner promocyjny w szablonie Topaz
Banner promocyjny w szablonie Topaz.

Jak dodać obrazek do nazwy kategorii i podkategorii w Comarch e-Sklep?

Wstęp

W Comarch e-Sklep możesz dodawać obrazki zarówno dla kategorii jak i dla podkategorii towarów. Odpowiednio dobrane grafiki zwiększają atrakcyjność wizualną sklepu, przyciągają wzrok klientów i zachęcają do dalszego przeglądania ofert w Twoim sklepie. Dodatkowo ułatwiają one nawigację i skracają czas poszukiwań Twoich klientów. W tym artykule dowiesz się, w jaki sposób skonfigurować funkcję dodawania zdjęć do kategorii i podkategorii w Twoim sklepie.

Jak dodać zdjęcie do nazwy kategorii w Comarch e-Sklep?

Comarch ERP Optima

Krok 1. Aby dodać zdjęcia kategorii w Comarch ERP Optima przejdź do zakładki Ogólne > Grupy towarowe i wybierz grupę do której ma zostać dodane zdjęcie.

Krok 2. Następnie na zakładce Atrybuty za pomocą symbolu Plusa dodaj atrybut binarny.

Wskazówka
Jeśli nie posiadasz atrybutu binarnego to aby go utworzyć przejdź do zakładki Ogólne > Atrybuty i w pierwszej zakładce symbolem Plusa dodaj atrybut w formacie binaria.

Krok 3. Po dodaniu zdjęć kategorii zmiany zapisz ikoną dyskietki oraz wykonaj synchronizację.

Comarch ERP XL

Wyświetlanie zdjęć kategorii w Comarch ERP XL możesz uzyskać poprzez dodanie odpowiedniego Załącznika. Krok 1. Aby wprowadzić zdjęcie w formie załącznika przejdź w module Sprzedaż do zakładki Ogólne > Towary i wejdź w edycję wybranej grupy. Krok 2. W zakładce Załączniki dodaj nowy załącznik ikoną Plusa. W polu Typ wskaż typ załącznika Obraz oraz zaznacz przy parametrze "Dostępność w aplikacji" e-Sklep. Następnie zaimportuj obraz ikoną z czerwoną strzałką. 3. Zmiany zapisz ikoną dyskietki oraz wykonaj synchronizację.

Comarch Betterfly

Krok 1. Zdjęcia kategorii w Comarch Betterfly możesz dodać po wybraniu Więcej funkcji > Comarch e-Sklep > Grupy w Comarch e-Sklep. Krok 2. Aby wprowadzić obrazek dla kategorii wybierz grupę do której chcesz dodać zdjęcie. Następnie wczytaj je wybierając jedną z 2 opcji: Z dysku lub Z internetu. Krok 3. Zapisz wprowadzone zmiany i wykonaj synchronizację.

Jak ustawić dodane zdjęcie jako ikonkę w nagłówku szablonu Topaz?

W szablonie Topaz istnieje możliwość ustawienia dodanych zdjęć kategorii jako ikonek przy nazwach kategorii w Twoim sklepie. Ta funkcja obsługuje nagłówki: header-1, header-2, header-3 oraz header-5, które są dostępne w Kreatorze Wyglądu. Zdjęcia w postaci ikon wyświetlają się w następujący sposób:
Widok nagłówka header-2 ze sklepu demonstracyjnego - https://demo.comarchesklep.pl/
Krok 1. Skonfiguruj funkcję wyświetlania się ikon nagłówka. Istnieją dwie możliwości konfiguracji tej funkcji:
  • Z poziomu Kreatora Wyglądu – Podczas tworzenia szablonu Topaz w Kreatorze Wyglądu dodaj nagłówek header-1,2,3 lub 5. Następnie przejdź do jego edycji i oznacz parametr „Ukryj ikony w nagłówku” na „tak”:
Zapisz zmiany, a następnie wygeneruj szablon.
  • Z poziomu panelu administracyjnego – W sytuacji gdy wgrałeś już wygenerowany szablon do Twojego sklepu i chcesz wprowadzić zmiany w zakresie wyświetlania się obrazków przy nazwach kategorii, przejdź do sekcji Wygląd sklepu > Ustawienia > Dodatkowe i wprowadź zmiany przy parametrze „Ukryj ikony w nagłówku”:
Wprowadzone zmiany zapisz i opublikuj.
Krok 2. Wgraj zdjęcia kategorii do Twojego systemu ERP. Informacje na temat jak wgrać zdjęcia kategorii do poszczególnych systemów ERP znajdziesz pod pierwszym punktem tego artykułu.
Wskazówka
Na stronie „Produkty” wyświetlają się zdjęcia kategorii. Należy pamiętać, iż jeśli w systemie ERP zostanie dodany obrazek kategorii w formie ikony, to taki sam obrazek wyświetli się na stronie „produkty”. Nie istnieje możliwość dodania dwóch osobnych zdjęć do nagłówka i do strony „Produkty”.

Jak mogę dodać zdjęcie do nazwy podkategorii?

W takich szablonach jak Topaz i dla Gastronomii istnieje możliwość dodania obrazków, które będą wyświetlały się przy nazwach podkategorii w Twoim sklepie. Ta funkcja obsługuje wszystkie układy list towarów: products-1, products-2, products-3, products-4, które są dostępne w Kreatorze Wyglądu. Obrazki do nazw podkategorii wyświetlają się w następujący sposób:
Widok zdjęć podkategorii na liście towarów ze sklepu demonstracyjnego - https://demo.comarchesklep.pl/
Aby dodać zdjęcia do podkategorii postępuj według poniższych kroków: Krok 1. Skonfiguruj funkcję wyświetlania podkategorii. Istnieją dwie możliwości konfiguracji tej funkcji:
  • Z poziomu Kreatora Wyglądu - Tworząc szablon Topaz lub dla Gastronomii przejdź do edycji Listy towarów w Kreatorze Wyglądu. Następnie dodaj układ listy towarów: products-1,2,3 lub 4 i edytując go oznacz parametr "Udostępnij zdjęcia podkategorii".
Zapisz zmiany, a następnie wygeneruj szablon.
  • Z poziomu panelu administracyjnego - W sytuacji gdy wgrałeś już wygenerowany szablon do Twojego sklepu i chcesz wprowadzić zmiany w zakresie wyświetlania się obrazków przy nazwach podkategorii, przejdź do sekcji Wygląd sklepu > Ustawienia > Ogólne i oznacz parametr "Udostępnij zdjęcia podkategorii":
Zapisz i opublikuj wprowadzone zmiany. Krok 2. Dodaj obrazki do podkategorii w systemie ERP. Skonfigurujesz je w podobny sposób jak obrazki dla kategorii, które zostały opisane w pierwszej części artykułu.

Więcej informacji

Więcej na temat dodawania obrazków w e-Sklepie można przeczytać w artykułach:

Jak edytować informacje o towarze z sekcji proponowane?

W Kreatorze Wyglądu B2C dla szablonu Topaz dostępne są parametry stylu wyświetlanych kafli towaru w sekcji proponowane. Dzięki temu możesz zwiększyć konwersję sprzedaży rekomendowanych swoim klientom produktów. Wybierz sekcję proponowane, następnie jej widok (pojedynczy lub podwójny), a potem przejdź do ustawień sekcji, gdzie masz możliwość edycji informacji o towarze, które będą widoczne na kaflu towaru. Aby dokonać modyfikacji sekcji proponowane, przejdź do zakładki „Kafle”. Tam masz możliwość wybrania następujących opcji:
  • Pozwalaj na kupowanie z sekcji towarów proponowanych,
  • Pozwalaj na dodawanie do ulubionych z sekcji towarów proponowanych,
  • Prezentuj drugie zdjęcie towaru w sekcji towarów proponowanych,
  • Powiększ kafel po najechaniu na niego kursorem.
Na podglądzie kafla możesz na bieżąco sprawdzać, jak prezentuje się towar z włączonymi parametrami.  

Dla Gastronomii - przewodnik konfiguracji

1. Wstęp

Szablon jest dedykowany do sprzedaży jedzenia online, możliwy do swobodnej konfiguracji. Jest responsywny, dzięki czemu idealnie nadaje się do prezentacji przepisów, menu lub promocji produktów żywnościowych. Może zostać zastosowany zarówno do niewielkiej, lokalnej pizzerii, jak i do restauracji, piekarni czy cukierni. Wszystkie elementy są zaprojektowane tak, aby jak najlepiej zaprezentować ofertę oraz ułatwić użytkownikowi nawigację i szybkie złożenie zamówienia. Główne wyróżniki szablonu to:
  • dostosowana lista produktów w formie MENU,
  • popup z możliwością personalizacji zamówienia (dodanie kolejnych składników i dodatków),
  • wyświetlenie orientacyjnego czasu realizacji zamówienia,
  • komunikat o braku możliwości składania zamówienia w określonych dniach i godzinach,
  • możliwość ustawienia rejonu dostawy,
  • wyświetlanie alergenów.
Szablon współpracuje z Comarch e-Sklep w każdej wersji (Light, Standard, Enterprice oraz B2B) oraz Comarch Betterfly, ERP XL oraz ERP Optima. Przejdź do naszego sklepu demonstracyjnego i zobacz, jak prezentuje się szablon dla gastronomii w Comarch e-Sklep. W tym artykule skupiliśmy się na prezentacji dedykowanych funkcji dla tego szablonu. Znajdziesz tu krótkie instrukcje konfiguracji. Podstawowe informacje na temat szablonu dla gastonomii znajdziesz w artykule: Dla gastronomii - podstawowe informacje.

2. Dedykowane konfiguracje

Szablon Dla Gastronomii posiada dedykowane funkcje, które są możliwe do swobodnej modyfikacji. Funkcje te nie są dostępne w innych, standardowych szablonach. W szablonie dla Gastronomii kupowanie jest możliwe bezpośrednio z listy. Menu, bo tak została nazwana sekcja z listą towarów, dostępne jest do prezentacji w dwóch wariantach: kafli oraz listy. Zmiana układu listy możliwa jest z poziomu panelu administracyjnego (Wygląd sklepu/ Ustawienia/ zakładka Zarządzanie kaflem produktu). Podczas kupowania bezpośrednio z menu wyświetla się popup, który posiada następujące informacje:
  • zdjęcie produktu,
  • opis,
  • możliwe do wyboru warianty,
  • dodatkowe produkty, ktore można umiejscowić pod nazwą „Składniki” czy „Dodatki”.
Dzięki temu możliwa jest personalizacja danego towaru, a Klient w szybki sposób może wybrać ekstra składniki czy dodatki w postaci np. sosów do dania głównego. Może również wybrać rodzaj pieczywa czy rozmiar burgera. Nad przyciskiem "dodaj do koszyka" znajduje się tzw. przycisk drugorzędny. Służy on do wpisania liczby, przez którą wartości wybrane w popupie oraz towar nadrzędny (jakim w tym przypadku jest burger) zostaną pomnożone.

2.1. Wybór wariantów - konfiguracja "rozmiar burgera" oraz "rodzaj pieczywa"

Burger został skonfigurowany jako fantom. Informacje takie jak "rozmiar burgera" czy "rodzaj pieczywa" to jego warianty. Instrukcję dotyczącą konfiguracji fantomów znajdziesz w artykule: Fantom (towar zgrupowany) – konfiguracja
Wskazówka
Na zrzucie ekranu w popupie widnieje fantom dwupoziomowy (rozmiar burgera i rodzaj pieczywa), co oznacza, że należy dodać dwa atrybuty grupujące na karcie towaru w systemie ERP.

2.2. Składniki i dodatki

"Składniki" oraz "dodatki" to towary proste, które klienci mogą dodać do dania głównego. Poprawnie skonfigurowane wyświetlą się na popupie podczas kupowania z listy. W systemach ERP definiowane są jako zamienniki lub towary podobne. Jest kilka rzeczy, o których musisz pamiętać podczas konfiguracji dodatków i składników:
  • towar nie może posiadać atrybutów grupujących,
  • produkty muszą mieć zdefiniowane przynajmniej jedno zdjęcie,
  • towar musi być zamiennikiem jednostronnym,
  • łączna ilość zamienników nie może przekraczać 20 towarów prostych. Ograniczenie to dotyczy każdego z niżej wskazanych systemów ERP.
Poniżej zamieściliśmy instrukcję konfiguracji dla poszczególnych systemów ERP.

2.3. Składniki

2.3.1. W jaki sposób zostały skonfigurowane "Składniki" w ERP Optima?

Towary znajdujące się w popupie jako "składniki" to zamienniki utworzone w systemie Comarch ERP Optima. Aby towar wyświetlił się poprawnie, należy: Krok 1. Utworzyć w systemie Comarch ERP Optima kategorię o nazwie i kodzie "INNE",
Wskazówka
Grupa musi być domyślną dla składników, które się w niej znajdują. Dodatkowo musi ona zostać dodana jako podgrupa grupy głównej, która została wybrana na definicji oddziału.
Krok 2. Utworzyć towar prosty (czyli np. dodatkowy ser), przyporządkować go do grupy INNE, Krok 3. Do towaru nadrzędnego (w tym przypadku burgera) dodać zamiennik jednostronny, Krok 4. Po wykonaniu synchronizacji produkty będą widoczne na popupie. Dodatkowo, produkty, które są w kategorii  "INNE" nie wyświetlą się w menu. Grupa ta nie jest także widoczna w menu kategorii.  

2.3.2 W jaki sposób zostały skonfigurowane "Składniki" w Comarch Betterfly?

Towary znajdujące się w popupie jako "składniki" to produkty podobne utworzone w systemie Comarch Betterfly. Aby towar wyświetlił się poprawnie, należy: Krok 1. Utworzyć w systemie Comarch Betterfly grupę produktów o nazwie "INNE", Krok 2. Utworzyć towar (np. dodatkowa szynka), przyporządkować go do grupy "INNE". Krok 3. Na karcie towaru nadrzędnego (w tym przypadku burgera) dodać produkt podobny (jednostronny), Krok 4. Po wykonaniu synchronizacji produkty będą widoczne na popupie. Dodatkowo, produkty, które są w kategorii  "INNE" nie wyświetlą się w menu. Grupa ta nie jest także widoczna w menu kategorii.  

2.3.3 W jaki sposób zostały skonfigurowane "Składniki" w ERP XL?

Towary znajdujące się w popupie jako "składniki", to produkty podobne utworzone w systemie Comarch ERP XL. Aby towar wyświetlił się poprawnie, należy: Krok 1. Utworzyć w systemie Comarch ERP XL grupę produktów o nazwie "INNE". Grupa musi zostać dodana jako podgrupa grupy głównej, która została wybrana na definicji oddziału,
Przyklad
Jeśli na definicji oddziału w zakładce Eksport/ Cennik wybierzesz grupę Szablon gastronomiczny: To należy w niej dodać podgrupę o nazwie "INNE".
Krok 2. Utworzyć towar prosty(np. szynka), przyporządkować go do grupy "INNE". Krok 3. Na karcie towaru nadrzędnego (w tym przypadku pizza hawajska) dodać zamiennik(jednostronny) w zakładce Zamienniki/ Zamienniki. Dodatkowo w edycji zamienników w zakładce "Miejsca w strukturze firmy" trzeba dodać oddział e-Sklepu, Krok 4. Po wykonaniu synchronizacji produkty z grupy "INNE" będą widoczne na popupie jako składniki, ale nie wyświetlą się jako osobna grupa "INNE" w menu kategorii.

2.4 Dodatki

2.4.1 W jaki sposób zostały skonfigurowane "Dodatki" w Comarch ERP Optima?

Towary znajdujące się w popupie jako "dodatki" to zamienniki utworzone w systemie Comarch ERP Optima. Aby towar wyświetlił się poprawnie, należy: Krok 1. Utworzyć towar prosty (czyli np. oliwa z oliwek), przyporządkować go do grupy, która jest udostępniona do e-Sklepu, najwygodniej jeśli posiada ona nazwę "DODATKI". Krok 2. Do towaru nadrzędnego (w tym przypadku burgera) dodać zamiennik jednostronny, Efekt: Po wykonaniu synchronizacji produkty będą widoczne na popupie. Dodatkowo, produkty z kategorii "DODATKI" wyświetlą się w menu, a grupa będzie widoczna w menu kategorii.

2.4.2 W jaki sposób zostały skonfigurowane "Dodatki" w Comarch Betterfly?

Towary znajdujące się w popupie jako "dodatki" to produkty podobne utworzone w systemie Comarch Betterfly. Aby towar wyświetlił się poprawnie, należy: Krok 1. Utworzyć towar (np. sos czosnkowy), przyporządkować go do grupy, która jest udostępniona do e-Sklepu, najwygodniej o nazwie "DODATKI" lub innej. Krok 2. Do towaru nadrzędnego (w tym przypadku burgera) dodać produkt podobny (jednostronny), Efekt: Po wykonaniu synchronizacji produkty będą widoczne na popupie jako dodatki. Kategoria "DODATKI" wyświetli się w Menu, obok innych kategorii stworzonych w systemie Comarch Betterfly.

2.4.3 W jaki sposób zostały skonfigurowane "Dodatki" w Comarch ERP XL?

Towary znajdujące się w popupie jako "dodatki" to zamienniki utworzone w systemie Comarch ERP XL. Aby towar wyświetlił się poprawnie, należy: Krok 1. Utworzyć towar prosty (czyli np. cola), przyporządkować go do grupy, która jest udostępniona do e-Sklepu, najwygodniej o nazwie "DODATKI". Krok 2. Na karcie towaru nadrzędnego (w tym przypadku pizza hawajska) dodać zamiennik(jednostronny) w zakładce Zamienniki/ Zamienniki. Dodatkowo w edycji zamienników w zakładce "Miejsca w strukturze firmy" trzeba dodać oddział e-Sklepu, Efekt: Po wykonaniu synchronizacji produkty będą widoczne na popupie. Dodatkowo, produkty z kategorii "DODATKI" wyświetlą się w menu kategorii, które widoczne jest nad menu  

3. Alergeny

Szablon dla Gastronomii został dostosowany do wyświetlania tabel z alergenami, które mogą znaleźć się w produktach. Alergeny możesz wyświetlić zatem za pomocą:
  • konfiguracji banneru „Tabela”,
  • dodania dowolnej treści na stronie użytkownika,
  • oznaczeniu ich jako atrybuty. 

3.1. Alergeny jako atrybuty - widoczność na szczegółach towaru - Konfiguracja ERP Optima

Aby dodać spis produktów lub substancji uczulających, który zostanie wyświetlony w zakładce "Alergeny" widocznej na szczegółach towaru, należy: Krok 1. Utworzyć w ERP Optima atrybut tekstowy o nazwie ALERGENY Krok 2. Atrybut należy dodać do towaru, na którym na być widoczny. Aby to zrobić, należy przejść z pozycji cennika do zakładki Atrybuty Krok 3. W polu "wartość" należy wpisać alergeny, które mogą się znaleźć w produkcie. Pole to posiada ograniczenie ilości znaków . W tym wypadku, jeśli zabraknie miejsca, to możliwe jest utworzenie kolejnego atrybutu, tym razem o nazwie ALERGENY_DWA. Kolejno można tworzyć atrybuty ALERGENY_TRZY itd. Efekt: Po synchronizacji alergeny zostaną wyświetlone na szczegółach towaru w zakładce "Alergeny"      

3.2. Alergeny jako atrybuty - widoczność na szczegółach towaru - Konfiguracja Comarch Betterfly

Aby dodać spis produktów lub substancji uczulających, który zostanie wyświetlony w zakładce "Alergeny" dostępnej na szczegółach towaru, należy: Krok 1. Utworzyć w systemie Comarch Betterfly atrybut o nazwie ALERGENY Krok 2. Atrybut należy dodać do towaru, na którym ma być widoczny. Aby to zrobić, należy przejść na kartę towaru w zakładkę e-Sklep: Krok 3. W polu "wartość PL" należy wpisać alergeny, które mogą się znaleźć w produkcie. Pole to posiada ograniczenie. W tym wypadku, jeśli zabraknie miejsca, to możliwe jest utworzenie kolejnego atrybutu, tym razem o nazwie Alergeny_dwa. Kolejno można tworzyć atrybuty Alergeny_trzy itd. Efekt: Po synchronizacji alergeny zostaną wyświetlone na szczegółach towaru w zakładce "Alergeny"  

3.3. Alergeny jako atrybuty - widoczność na szczegółach towaru - Konfiguracja ERP XL

Krok 1. Utworzyć w systemie ERP XL atrybut tekstowy o nazwie ALERGENY Krok 2. Atrybut należy dodać do towaru, na którym na być widoczny. Aby to zrobić, należy przejść z pozycji cennika do zakładki Atrybuty: Krok 3. W polu "wartość" należy wpisać alergeny, które mogą się znaleźć w produkcie. Pole to posiada ograniczenie ilości znaków . W tym wypadku, jeśli zabraknie miejsca, to możliwe jest utworzenie kolejnego atrybutu, tym razem o nazwie ALERGENY_DWA. Kolejno można tworzyć atrybuty ALERGENY_TRZY itd. Efekt: Po synchronizacji alergeny zostaną wyświetlone na szczegółach towaru w zakładce "Alergeny"  

4. Określenie i walidacja obszaru dostawy

W szablonie dla Gastronomii możesz określić obszar dostawy. Możesz to zrobić na dwa sposoby: określenie za pomocą kodu pocztowego oraz mapy. Aby użyć funkcji w swoim e-Sklepie należy: Krok 1. Przejść do panelu administracyjnego, a następnie do zakładki Wygląd Sklepu/ Ustawienia/ zakładka Ogólne.  Krok 2. Następnie odnajdź "obszar dostaw" i określ obszar dostawy za pomocą mapy lub kodów pocztowych. Możesz zrezygnować z określania obszaru dostawy, wybierając opcję "nie określaj obszaru".

4.1. Określenie obszaru za pomocą mapy

Krok 1. Aby określić obszar za pomocą mapy wybierz odpowiednią opcję z listy. Po zaznaczeniu "Mapy" ukaże się mała mapa. Kliknij niebieski przycisk "wybierz obszar", po czym ustaw odpowiednio pinezki. Krok 2. Następnie, po określeniu obszaru, zapisz obszar, wybierając przycisk znajdujący się poniżej mapki. Efekt: Po zapisaniu obszaru na mapie zaznaczony będzie odpowiedni, określony przez Ciebie rejon. Aby zmienić lub usunąć obszar, wystarczy wybrać przycisk "wyczyść obszar", który pojawi się w lewym, dolnym rogu poniżej mapy. Zmiany należy zapisać i opublikować.

4.2. Określenie obszaru za pomocą kodu pocztowego

Krok 1. Aby określić obszar za pomocą kodu pocztowego wybierz odpowiednią opcję z listy. Krok 2. Po zaznaczeniu "Kodów pocztowych" ukaże się obszar, w którym należy wpisać obsługiwane kody. Po wpisaniu kodu, aby dodać kolejny, kliknij "Dodaj kod pocztowy". Zmiany należy zapisać i opublikować. Efekt: Wprowadzone przez Ciebie kody pocztowe będą widoczne w panelu administracyjnym. Możesz je usunąć poprzez kliknięcie krzyżyka. Nie ma ograniczeń ilości dodawanych kodów. Efekt w e-Sklepie: Klient po uzupełnieniu danych zamawiającego otrzyma od razu informację, czy jego adres znajduje się w obszarze dostawy.  

5. Realizacja zamówień

W szablonie dla Gastronomii możesz określić orientacyjny czas realizacji zamówienia, a także określić, kiedy jest ono możliwe do złożenia.

5.1. Orientacyjny czas realizacji zamówienia

Krok 1. Aby włączyć funkcję wystarczy przejść z poziomu panelu administracyjnego do obszaru Wygląd sklepu/ Ustawienia/ zakładka Ogólne po czym odnaleźć sekcję "Realizacja zamówień". Krok 2. Następnie w "Orientacyjny czas realizacji zamówienia" należy wpisać czas, w jakim zazwyczaj dostarczasz zamówienie:   Efekt: Po złożeniu zamówienia Twoi Klienci zobaczą thank you page z odliczaniem czasu do realizacji:

5.2. Zezwól na składanie zamówień tylko w wybranym zakresie godzin

We wspomnianym obszarze "Realizacja zamówień" istnieje także funkcja, która pozwala na składanie zamówień tylko w wybranym zakresie godzin oraz blokowaniu składania zamówień w wybrane dni (np. święta). Krok 1. Aby ją uruchomić, wystarczy zaznaczyć checbox " Zezwój na składanie zamówień tylko w wybranym zakresie czasu" Krok 2. W tym miejscu możesz ustawić godziny oraz dni, w których klienci mogą składać zamówienia. Zapisz wprowadzone godziny. Jeśli chcesz usunąć "aktualnie zablokowane daty dostaw" , naciśnij krzyżyk znajdujący się po prawej stronie określonej daty. Efekt: Klient przeglądający menu przy próbie złożenia zamówienia w czasie, którego nie obejmuje zakres realizacji zamówień, zobaczy wówczas następujący komunikat:    

Kreator wyglądu Topaz (B2C)

Wstęp

Jednym z kluczowych elementów, który przyczynia się do sukcesu w branży e-commerce jest oprawa wizualna sklepu. W dużym stopniu to właśnie ona wpływa na całościowe wrażenia użytkowników i ich proces zakupowy. Dzięki narzędziu - Kreator Wyglądu Comarch e-Sklep, właściciele sklepów mają możliwość stworzyć swój własny, niepowtarzalny szablon, który będzie dostosowany do ich preferencji oraz do potrzeb użytkowników.

Kreator jest dostępny pod linkiem: Kreator szablonu Comarch e-Sklep. Odnośnik znajduje się w panelu administracyjnym e-Sklepu Wygląd sklepu/ Kreator wyglądu.

Zastosowanie

Kreator jest intuicyjnym narzędziem służącym do tworzenia szablonów. Jego obsługa nie wymaga umiejętności technicznych ani programowania. Wszystko odbywa się na poziomie strony internetowej, gdzie z gotowych elementów za pomocą metody "przeciągnij i upuść" możesz zaprojektować wygląd swojego sklepu. Dodatkowo, stworzony szablon jest dostosowany do wyświetlania na różnych urządzeniach (RWD).

W ramach kreatora zaprojektujesz wszystkie niezbędne obszary sklepu:
  • stronę główną,
  • listę towarów,
  • szczegóły towaru,
  • koszyk zakupowy.
Po utworzeniu szkieletu e-Sklepu, przychodzi czas na modyfikację oprawy wizualnej szablonu. Możesz dowolnie zmieniać kolory elementów znajdujących się na stronie, ikony, a także czcionkę.

Kto może używać tej opcji?

Aby móc używać tego narzędzia należy posiadać:

  • Comarch e-Sklep obsługujący procesy B2C,
  • szerokość ekranu powyżej 1280 px, a zalecana to 1920 px,
  • oraz jedną z przeglądarek internetowych w aktualnej wersji.

Wskazówka
Kreator wyglądu Comarch e-Sklep dostępny jedynie w wersji przeglądarkowej.

Zaczynamy!

Jak zaprojektować układ szablonu?

Aby rozpocząć tworzenie szablonu należy przejść na stronę Kreatora Wyglądu. Wyświetlony zostanie powitalny komunikat. Na początku należy określić, dla jakiego modelu sprzedaży projektujesz szablon dla swojego e-Sklepu. Do wyboru masz sprzedaż detaliczną lub hurtową. Sprzedaż detaliczna przeznaczona jest dla użytkowników, którzy chcą sprzedawać swoje produkty głównie klientom indywidualnym. Wybierz odpowiedni model, a następnie naciśnij przycisk Rozpocznij pracę. Po jego kliknięciu będzie można stworzyć nowy szablon lub edytować jeden z kilku gotowych.

W sytuacji gdy wcześniej tworzony był już projekt, widoczny będzie przycisk umożliwiający dokończenie szablonu lub rozpoczęcie nowego projektu. Opcja Nowy szablon umożliwia zbudowanie od początku nowego szablonu Topazu według Twojego indywidualnego pomysłu.
Wskazówka
Szablon Topaz - Demo jest gotowym szablonem, który możesz zainstalować bezpośrednio z obszaru Wygląd sklepu/Gotowe szablony Comarch.
Pozostałe sześć opcji do wyboru to gotowe wersje szablonu Topaz z możliwością ich edycji. Dzięki temu nie ma potrzeby tworzenia nowego szablonu od podstaw, ponieważ możesz wybrać jedną z gotowych propozycji, a następnie łatwo go edytować dostosowując do swoich potrzeb. Podwójne kliknięcie w wybrany kafelek pozwala przejść dalej. W trzech krótkich krokach zapoznasz się z podstawowymi funkcjami kreatora. Następnie możesz już przystąpić do dalszych modyfikacji szablonu lub od razu wygenerować przygotowaną wersję szablonu Topaz.

Od czego zacząć?

Wybierz wersję językową Kreatora i rozpocznij pracę nad swoim szablonem. Wersje do wyboru to: język polski, angielski, niemiecki oraz francuski. Język wybieramy klikając strzałkę obok flagi i nazwy języka w lewym dolnym rogu. Przy podglądzie prac na pełnym ekranie, wybrany język zostaje zachowany i szablon będzie wyświetlał się w wybranej wersji językowej.

Gdy już wybierzesz wersję językową dla swojego Kreatora warto zacząć od nazwania swojego przyszłego szablonu. Można to zrobić klikając Zmień i wpisując nazwę w lewym górnym rogu, zastępując nazwę "Topaz (2022.5)". Nazwa ta będzie widoczna po zaimportowaniu szablonu do panelu administracyjnego oraz po wyeksportowaniu szablonu do pliku XML wraz z datą i godziną jego wygenerowania.

Krok 1 - Strona główna

W tej sekcji należy zaprojektować wygląd strony głównej naszego Comarch e-Sklepu. Strona główna może składać się z następujących elementów:

  • Nagłówek,
  • Banner,
  • Banner pop-up,
  • Widget
  • Proponowane,
  • Newsletter,
  • Sekcja z filmami,
  • Blog,
  • Slider producentów,
  • Slider marek,
  • Element tekstowy,
  • Banner informacyjny,
  • Lookbook.
  • Stopka.

Po rozwinięciu każdej z sekcji ukażą się dostepne elementy:

Metodą "Przeciągnij i upuść" przenosimy wybrane elementy na obszar po prawej stronie:

Postępuj analogicznie z pozostałymi elementami.

Nagłówek

Sekcja "Nagłówek" prezentuje pięć widoków. Trzeci z nich zawiera pionowe menu, które pozwala wyświetlić standardowo trzy poziomy kategorii produktowych. Pierwszy poziom można dodatkowo konfigurować w zakresie ilości pokazywanych kategorii. W tym celu w menu Wygląd sklepu/ Ustawienia/ Ustawienia szablonu dodano nowy parametr: widok pierwszego poziomu menu głównego (dla trzeciego typu nagłówka) z następującymi opcjami:
  • wygodny (ustawiony domyślnie i pozwalający wyświetlić maksymalnie 10 kategorii w pierwszym poziomie menu)
  • oraz kompaktowy (wyświetla do 16 kategorii w pierwszym poziomie menu). Ten typ nagłówka połączony jest z bannerem (o zalecanych wymiarach 1118px x 534px), widocznym tylko na stronie głównej.
W piątym możesz zaprezentować zdjęcia kategorii w formie miniatur w nagłówku. Zdjęcia kategorii dodane w systemie ERP są pomniejszone i są wyświetlane przy nazwie kategorii. Wszystkie rodzaje nagłówków dostępnych w Kreatorze mają funkcję tzw. przyklejonego nagłówka. Przy przewijaniu strony sklepu w dół, u góry ekranu zawsze widoczny jest pasek z częścią elementów nagłówka (m.in. menu kategorii oraz wyszukiwarka). Dzięki temu przeglądający ofertę e-Sklepu, w każdym miejscu strony ma dostęp do skróconej wersji nagłówka strony. Sekcja "Nagłówek" posiada dodatkowe opcje do ustawienia. Z listy menu, można decydować o:
  • Widoku wyszukiwanych towarów w nagłówku,
  • Wyświetlanie top bannera,
  • Ukrywanie ikon w nagłówku,
  • Pokazywanie rozwijanej listy towarów znajdujących się w koszyku.

Banner

Sekcja "Banner" pozwala wybrać jedną z sześciu możliwości prezentacji banerów. Informacje dotyczące rekomendowanych rozmiarów obrazków w bannerach opisaliśmy w tym artykule. Jest on widoczna tylko dla strony głównej i listy towarowej.

Banner popup

Sekcja "Banner popup" pozwala wybrać jedną z dwóch możliwości prezentacji banerów. Bannery będą możliwe do wyświetlenia jedynie na stronie głównej e-Sklepu.

Banner promocyjny

Banner promocyjny to banner, który wyświetli się na stronie głównej Twojego e-Sklepu. Będzie prezentował typ towaru, który wskażesz. Taki rodzaj banneru pomoże Ci w prezentacji towarów, które zostały objęte na przykład promocją.

Widget

Sekcja "Widget" pozwala dodać jeden z dwóch dostępnych wariantów, które pozwolą zaprezentować następujące funkcje.
  • Widget-banner-1
    • Dodanie zdjęcia,
    • Dodanie tekstu nagłówka (tekst pionowy),
    • Dodanie tekstu przycisku (tooltip).
    • Dodanie linku do przycisku,
    • Dodanie tekstu..
  • Widget-banner-1
    • Dodanie zdjęcia,
    • Dodanie tekstu nagłówka (tekst pod zdjęciem),
    • Dodanie tekstu,
    • Dodanie linku do tekstu.

Proponowane

Sekcja "Proponowane" posiada dodatkowe opcje do ustawienia. Z listy menu, dostępnej pod przyciskiem Zmień typ możesz wybrać jakiego rodzaju produkty mają się w tym obszarze wyświetlać (m.in. nowość, najczęściej oglądane, wyprzedaż, sugerowane). Po zmianie typu tej sekcji, będzie się ona odpowiednio nazywać po wgraniu szablonu do sklepu:

Dodatkowo po najechaniu kursorem na tę sekcję, wybierając Opcje, możemy ustawić liczbę towarów, która będzie się wyświetlać (maksymalnie 50).

    Podczas tworzenia szablonu Topaz w Kreatorze wyglądu Comarch po dodaniu sekcji towary proponowane można określić typ wyświetlanych produktów. Nazwa sekcji jest zależna oraz adekwatna do określonego typu. Daną nazwę można modyfikować w tłumaczeniach szablonu. Dodatkowo każdy wybrany typ jest podlinkowany do wszystkich produktów wskazanego rodzaju. W zależności od wybranego typu, edycji parametrów wyświetlania dokonasz w panelu administracyjnym e-Sklepu. Z kolei informację o typie towaru ustawisz w systemie ERP. Typy towarów edytowane z poziomu panelu administracyjnego Comarch e-Sklep:
  • Promocja,
  • Nowość,
  • Najczęściej oglądane / najczęściej kupowane,
  • Cross-selling – oferowanie produktów uzupełniających wcześniejsze zakupy,
  • Producent,
  • Marka,
  • Ręcznie wybrane,
  • Kategoria,
  • Ostatnio oglądane.
Aby zdecydować o parametrach wyświetlania tych informacji należy przejść w panelu administracyjnym Comarch e-Sklep do zakładki Ustawienia/Ustawienia sklepu/sekcji Towary: Producent, marka, ręcznie wybrane, kategoria oraz ostatnio oglądane obsługiwane są w ramach obiektu lokalnego "Siatka towarów". Po wyborze jednego z wyżej wymienionych typów zmian ustawień należy dokonać z poziomu panelu administracyjnego przechodząc do obszaru zakładki Wygląd sklepu/Ustawienia/Ustawienia zaawansowane oraz zakładki Obiekty. Na szczegółach wybranego obiektu (Siatka towarów) określamy jakie dokładnie towary zostaną zaprezentowane w sekcji "Proponowane". W przypadku wyboru "Producenta" lub "Marki" należy samodzielnie określić producenta lub markę. Dodawanie informacji o typie produktu w systemie ERP dotyczy:
  • Nowości,
  • Produktu z gazetki,
  • Produktu polecanego,
  • Wyprzedaży,
  • Promocja,
  • Nowość,
  • Super jakości,
  • Super ceny,
  • Najlepszej oceny,
  • Rekomendacji sprzedawcy.
Informacja tego typu ustawiana jest bezpośrednio na karcie towaru w systemie ERP poprzez zaznaczenie odpowiedniej flagi w systemie ERP XL (zakładka aplikacje) lub atrybutu czasowego w ERP Optima (zakładka e-Sklep, sekcja atrybuty czasowe). Po wybraniu konkretnej opcji w systemie ERP na karcie danego produktu w Comarch e-Sklep zostanie dodana odpowiednia informacja:

Newsletter

Sekcja "Newsletter" pozwala dodać wybrany wariant zapisu klientów do subskrypcji. Dwa z nich są w formie wyskakującego okienka (pop-up), które prezentowane są wyłącznie na stronie głównej e-Sklepu (newsletter-3, newsletter-4). Dodatkowo, w wersji przeglądarkowej szablonu, w newsletterze w formie popup (newsletter-3) widoczny jest banner (niedostępny w wersji mobilnej) o wymiarach 275px x 475px. Wszystkie teksty dostępne w nowym newsletterze są edytowalne w ustawieniach szablonu w menu Wygląd sklepu/ Ustawienia/ Bannery/ Newsletter banner. Te typy newslettera mogą być używane jednocześnie z pozostałymi wersjami newslettera dostępnymi w szablonie Topaz.

Sekcja z filmami

Sekcja z filmami daje możliwość dodania filmów promujących nie tylko produkty, ale również Twoją firmę lub producentów czy marki. Filmy dodasz z poziomu panelu administracyjnego przechodząc do Wygląd sklepu/ Ustawienia/ Ustawienia szablonu/ Strona główna. W tej sekcji możesz zaprezentować filmy: udostępnione w sekcji Ustawienia/Pliki użytkownika, opublikowane w portalu Youtube, dodane na zewnętrznym hostingu.

Slider marek

Sekcja "Slider marek" umożliwia dodanie do szablonu dwóch widoków slidera marek. Pod przyciskiem Opcje możliwe jest wybranie jednego z trzech sposobów jego prezentacji: brak wyszarzenia (dodane logo mają zachowane oryginalne kolory), wyszarzenie (dodane logo jest szare, kolor pojawia się po najechaniu kursorem myszki na logo), błysk (po najechaniu myszką, na logo pojawia się animacja świetlna). Na sliderach wyświetlane są loga marek, które zostały zaimportowane z systemu ERP. Po kliknięciu w wybrane logo, pojawi się lista wszystkich towarów, dla których dodana jest konkretna marka. Sekcje mogą być dodane w szablonie w dowolnym miejscu na stronach: głównej, liście towarów i szczegółach towaru.

Slider producentów

Sekcja "Slider producentów " umożliwia dodanie do szablonu dwóch widoków slidera producentów. Pod przyciskiem Opcje możliwe jest wybranie jednego z trzech sposobów jego prezentacji: brak wyszarzenia (dodane logo mają zachowane oryginalne kolory), wyszarzenie (dodane logo jest szare, kolor pojawia się po najechaniu kursorem myszki na logo), błysk (po najechaniu myszką, na logo pojawia się animacja świetlna). Na sliderach wyświetlane są loga producentów, które zostały zaimportowane z systemu ERP. Po kliknięciu w wybrane logo, pojawi się lista wszystkich towarów, dla których dodany jest konkretny producent. Sekcje mogą być dodane w szablonie w dowolnym miejscu na stronach: głównej, liście towarów i szczegółach towaru.

Element tekstowy

Element tekstowy pozwala na zamieszczenie dłuższego opisu, który będzie wyświetlany na stronie głównej Comarch e-Sklep. W kreatorze wyglądu Comarch są do wyboru dwa warianty:
  • element tekstowy z samym tekstem,
  • element tekstowy z możliwością dodania zdjęcia.
Tekst wprowadza się edytując obiekt tekstowy w ustawieniach szablonu: Wygląd sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane/ Obiekty:
  • text-el-no-photo-mp-1 – element bez obrazka,
  • text-el-photo-mp-2 – element z obrazkiem.

Po wybraniu wszystkich niezbędnych sekcji nasza strona główna powinna być gotowa. Efekt naszej pracy możemy podejrzeć klikając Podgląd w prawym górnym rogu. Dostępny jest podgląd w wersji mobilnej i desktopowej.

Strona główna wymaga dwóch podstawowych elementów: nagłówka oraz stopki. Pozostałe elementy nie są obowiązkowe.

Banner informacyjny

Banner informacyjny pozwala na zaprezentowanie w przejrzysty sposób korzyści z zakupach w Twoim sklepie. Dotyczą one obszarów: dostawy, jakości i kontaktu z klientem. Banner możesz dodać tylko do strony głównej lub do wszystkich stron. Sekcja Odkryj Comarch e-Sklep różni się prezentacją oraz elementami między bannerami i zawiera:
  • info-banner-1 – element z ikonkami i podpisem
    • Szybka dostawa,
    • Gwarancja jakości,
    • Odbiór osobisty,
    • Reklamacje,
    • Zwroty towarów,
  • info-banner-2 – element z ikonkami i krótką informacją
    • Ekspresowa wysyłka,
    • Darmowa dostawa,
    • Obsługa klienta,
  • info-banner-2 – element z ikonkami i krótkim opisem
    • Ekspresowa dostawa,
    • Darmowa dostawa,
    • Strefa kontaktu.

Stopka

Sekcja "Stopka" zawiera trzy widoki do wyboru. W każdym widoku widnieją strony statyczne, którymi można zarządzać w sekcji Wygląd Sklepu/ Ustawienia/ Nagłówek i Stopka. Dla każdej z sekcji wyświetla się jej utworzona w panelu nazwa. W stopce znajdują się także informacje na temat rodzaju prezentowanych cen w e-Sklepie (brutto czy netto) oraz komunikat @Comarch SA 2022. All rights reserved Powered by Comarch e-Sklep. Dodatkowo istnieje możliwość umieszczenia w stopce odnośników do mediów społecznościowych oraz ich ikony. W stopce trzeciej możemy dodać ikony naszych dostawców oraz form płatności wykorzystywanych w sklepie.

Krok 2 - Lista towarów

Kolejnym krokiem jest utworzenie listy towarów. Aby to zrobić, należy rozwinąć listę zgodnie z poniższym rysunkiem, a następnie przejść do wskazanej zakładki:

 

Podobnie, jak w przypadku strony głównej konfigurujemy wygląd listy towarów. Dodatkowo możemy wskazać liczbę towarów, jaka ma się wyświetlać na liście (maksymalnie 50):

W zakładce Kafle, możemy dopasować wygląd kafli do swoich preferencji: W Kreatorze dostępnych jest 5 widoków listy towarów:   Dodatkowo poziomu listy towarów możliwe jest także dostosowanie wyglądu kafla. Dostępne są trzy warianty: Trzeci z wariantów kafli jest ustawiony jako domyślny. Posiada on ikonę koszyka, dzięki czemu można dodać produkty do koszyka z poziomu listy towarów. Po najechaniu myszką na dany produkt na liście towarów została obsłużona możliwość zmiany zdjęcia na drugie. Stanie się tak wówczas, gdy danemu produktowi zostały przypisane min. dwa zdjęcia w systemie ERP.
Wskazówka
Zalecamy dodawanie zdjęć produktów z białym tłem.
W niektórych widokach listy towarów przycisk dodawania do porównania oraz oceny jest widoczny bez konieczności logowania się do e-Sklepu. Na liście towarów przy nazwie produktu dodany jest także tooltip, który po najechaniu kursorem na nazwę towaru wyświetli pełną treść (w przypadku długich nazw).

Krok 3 - Szczegóły towaru

Po utworzeniu listy towarów przechodzimy do tworzenia szczegółów towaru.

Wskazówka
Warto zwrócić uwagę, że na każdej stronie sklepu możemy ustawić różne sekcje towarów polecanych o różnych typach (przykładowo na szczegółach towaru polecane towary mogą się inaczej wyświetlać niż na liście towarów).

Krok 4 - Koszyk

Po utworzeniu szczegółów towaru przechodzimy do wyboru wersji koszyka dostępnego w e-Sklepie. W Kreatorze Wyglądu dostępne są dwie wersje koszyka:
  • Koszyk 4 krokowy,
  • Koszyk 3 krokowy,
  • Koszyk 1 krokowy.

Następnie możemy przejść do modyfikacji wyglądu naszego szablonu. W tym celu należy przejść do zakładki Style.

Style

Jak zmienić kolory, czcionki oraz ikony?

Po dodaniu elementów strony możemy dodatkowo podejrzeć, jak będzie wyglądał nasz przyszły szablon. W tym celu należy przejść do zakładki Style.

Dodatkowo w zakładce Style możemy zmodyfikować wygląd naszego szablonu. Zmianie podlegają:

  • motyw kolorystyczny,
  • czcionka,
  • ikony,
  • styl okien i przycisków.

Motyw kolorystyczny

Aby zmienić kolor naszego szablonu należy przejść do sekcji Motyw kolorystyczny, gdzie do wyboru przygotowaliśmy 6 gotowych motywów.

Wskazówka
W aktualnej wersji Kreatora dodaliśmy nowy, ciemny motyw kolorystyczny.

Każdy z motywów możemy edytować według indywidualnych preferencji. Możemy zmodyfikować kolor poszczególnych elementów (m.in.: tło strony, tło nagłówka, nazwę towaru, czy nawet drugorzędny kolor tekstu w newsletterze). Zmiany należy zapisać klikając Zapisz. Jeśli wykonane zmiany nie są zadowalające, możemy przywrócić ustawienia domyśle dla danego motywu kolorystycznego, klikając przycisk Przywróć.

Możliwe jest również wprowadzenie szesnastkowego zapisu kolorów. Heksadecymalny zapis kolorów dla poszczególnych sekcji w szablonie dostępny jest podczas edycji wybranego motywu kolorystycznego.

Czcionki

W zależności od potrzeb istnieje możliwość wybrania czcionki. Dla naszych klientów udostępniliśmy jej 13 różnych typów. Pod nazwą każdej z nich znajduje się przykładowy wygląd w różnych formatach.

Ikony

Mamy do wyboru 3 różne warianty wyglądu ikon. Dodatkowo istnieje możliwość wyboru w jakiej postaci wyświetla się ikona koszyka (torba, wózek lub koszyk) oraz loader.

Wskazówka
Od teraz możesz zmienić rodzaj loadera, wybierając jedną z 5 propozycji widocznych powyżej.

Styl okien i przycisków

Ostatnim elementem, który możemy modyfikować z poziomu zakładki Style jest styl okien i przycisków. Mamy do wyboru 3 różne warianty zaokrągleń.  

Generowanie i wgrywanie szablonu

Po zaprojektowaniu wyglądu szablonu możemy go wygenerować i pobrać na dysk korzystając z przycisku Generuj widocznego w prawym górnym rogu:

Obok przycisku Generuj dostępna jest również opcja Importuj szablon, umożliwiająca wgranie wcześniej zapisanego szablonu z dysku i ponowną jego edycję.

W przypadku prawidłowego wygenerowania szablonu wyświetlony zostanie komunikat informujący o tym fakcie i pobrany plik.

Pobrany szablon należy zaimportować w Comarch e-Sklep w zakładce Wygląd sklepu/ Zaimportuj szablon z Kreatora Wyglądu.

W szablonie Topaz znajduje się informacja na temat godziny wygenerowania szablonu w Kreatorze. Taka informacja znajduje się w panelu administracyjnym w menu: Wygląd sklepu/ Ustawienia/ Więcej (trzy kropki), gdzie należy wybrać opcję Edytuj ustawienia zaawansowane, a potem ponownie Więcej/ Edytuj HTML. Następnie z listy plików należy wybrać _layout.html. Informacje na temat modyfikacji, w tym godzina ostatniej modyfikacji, znajdują się nad oknem edycji pliku. Jeżeli plik nie był modyfikowany, wówczas godzina odpowiada godzinie wygenerowania szablonu w kreatorze.

W przypadku braku obowiązkowych elementów szablonu nie będzie możliwe jego wygenerowanie. przycisk Generuj będzie wyszarzały, a w prawym dolnym rogu pojawi się komunikat „Uzupełnij elementy wymagane w szablonie”. Sekcje, gdzie element nie został wybrany będą się wyświetlać z odpowiednią ikoną.

  Kreatorze wyglądu istnieje również możliwość cofania się podczas tworzenia szablonu, w ramach której obsługujemy do 30 kroków w wstecz. Dodatkowo możemy także wykonywać krok do przodu. Zapisywane są wszystkie zmiany na elementach, informacje odnośnie styli, czcionek, ikonach oraz nazwie szablonu.

Aktualizacja szablonu

W Kreatorze Wyglądu znajduje się opcja aktualizacji poprzednich wersji szablonu. W celu zaktualizowania całego szablonu należy wgrać plik z poprzednim szablonem do Kreatora Wyglądu, według tej instrukcji:
  • po uruchomieniu strony kreatora wybierz opcję: Stwórz nowy projekt,
  • wybierz Nowy szablon,
  • w prawym górnym rogu wybierz opcję Importuj szablon,
  • następnie zaimportuj plik z szablonem, który ma być zaktualizowany. Po poprawnym zaimportowaniu szablonu otrzymasz informację zwrotną:
  • po wgraniu szablonu do aktualizacji użyj opcji Generuj. 
Dzięki temu w prosty sposób można starsze szablony Topaz podnieść do wersji aktualnej.

Przywracanie koszyka dla klientów niezalogowanych

W szablonie Topaz przywracany jest koszyk  dla niezalogowanych klientów. Po opuszczeniu strony lub wyłączeniu przeglądarki klient niezalogowany powracający do sklepu będzie widział towary dodane do koszyka wcześniej. Proces ten działa dzięki zapisywaniu informacji w ciasteczkach.

Więcej informacji

Więcej informacji można znaleźć w artykułach o wyglądzie sklepu oraz o dostosowaniu wyglądu.

Jak zaktualizować szablon do najnowszej wersji?

Jak zaktualizować szablon do najnowszej wersji?

Wskazówka
Od 1 czerwca 2025 roku zakończyliśmy aktualizację oraz wydawanie nowych wersji szablonów Bursztyn, Agat i Opal, a tym samym ich wsparcie, aby skupić się na nowoczesnych rozwiązaniach, które jeszcze lepiej odpowiadają na potrzeby dynamicznie rozwijającego się rynku e-commerce. Zachęcamy Was do przejścia na nasze nowe, udoskonalone szablony. Dla sklepów B2C polecamy szablony Topaz, One Page Shop oraz Dla Gastronomii, natomiast dla platform B2B idealnym wyborem będą Rubin i Szafir.

Wstęp

W e-Sklepie możesz dowolnie zmieniać szablony. Możesz je także modyfikować oraz aktualizować. Wiąże się to z wgraniem zupełnie nowego szablonu na miejsce starego. Aktualizacja wyglądu powoduje zmianę dotychczasowych ustawień. Przed każdą aktualizacją polecamy utworzyć odpowiednią dla siebie instrukcję, która będzie zawierała Twoje ustawienia kolorów czy modyfikacje w kodzie szablonu. Możesz także wyeksportować dotychczasowy szablon, aby stanowił on kopię bezpieczeństwa.

Jak zaktualizować szablon?

Instrukcja aktualizacji szablonów: Rubin, Szafir, Topaz i One Page Shop (dostępnych w Kreatorze Wyglądu)

Aby zaktualizować szablon Rubin, Szafir, Topaz lub One Page Shop należy skorzystać z aktualnej wersji Kreatora Wyglądu, do którego odnośnik znajduje się w panelu administracyjnym e-Sklepu w sekcji Wygląd sklepu/ Kreator wyglądu. Istnieją dwie możliwości aktualizacji tych szablonów:

  • wygenerowanie nowego szablonu w Kreatorze Wyglądu oraz wgranie go do e-Sklepu,
  • import posiadanego szablonu do Kreatora Wyglądu oraz ponowne wygenerowanie go w najnowszej wersji.

Wyeksportowany z Kreatora Wyglądu szablon należy wgrać do e-Sklepu. W panelu administracyjnym e-Sklepu, w sekcji Wygląd sklepu znajduje się bezpośredni odnośnik do importu szablonu z Kreatora wyglądu. Szczegółowa instrukcja dostępna jest w artykule Jak wyeksportować i zaimportować swój szablon w e-Sklepie?

Podczas dokonywania modyfikacji w szablonach zachęcamy do skorzystania z naszego Centrum Pomocy.

Wskazówka
Pamiętaj o zapisaniu szablonu oraz opublikowaniu go w e-Sklepie. Zmiany wprowadzone w ustawieniach zostaną zsynchronizowane do sklepu po 10 minutach.

Instrukcja aktualizacji szablonów: Bursztyn, Agat i Opal.

Aby zaktualizować szablon Bursztyn, Agat lub Opal należy w panelu administracyjnym e-Sklepu przejść do sekcji Wygląd Sklepu/ Gotowe szablony Comarch, w której znajdują się najnowsze wersje szablonów dostępne do zainstalowania. Z wyświetlonej listy należy wybrać szablon, który ma zostać wgrany do e-Sklepu. W tym celu wybierz przycisk Chcę pobrać i zainstalować szablon:

Następnie wyświetli się nowe okno, w którym należy:

  • wybrać tzw. slot, który zostanie nadpisany nowym (aktualnym) szablonem. W każdym e-Sklepie dostępne są 4 miejsca na wgranie szablonu, spośród których jeden szablon oznacza się jako aktywny i domyślny,
  • określić, czy wgrywany szablon ma podmienić istniejące bannery. Gdy parametr zostanie zaznaczony, wówczas wszystkie bannery zapisane na danym slocie zostaną usunięte i zastąpione bannerami z importowanego szablonu. Jeżeli w nadpisywanym szablonie znajdują się bannery oraz lookbooki, które mają nadal wyświetlać się w e-Sklepie, należy wskazany parametr zostawić odznaczony. Gdy parametr nie zostanie zaznaczony, wówczas dotychczasowe bannery i lookbooki nie zostaną usunięte.
  • Zaimportować szablon do e-Sklepu.
    Wskazówka
    Import szablonu jest operacją nieodwracalną i spowoduje nadpisanie dotychczasowego szablonu. W przypadku, gdy szablon był modyfikowany (dokonywano zmian w kodzie HTML) jego aktualizacja spowoduje, iż zmiany nie zostaną przeniesione. Warto wykonać eksport posiadanego szablonu do pliku w celu zapisania oraz posiadania wglądu to wprowadzanych modyfikacji. Jeżeli istnieje taka konieczność należy ponownie dokonać samodzielnej edycji szablonu.

Aby nowy szablon pojawił się w e-Sklepie należy upewnić się, czy jest on aktywny oraz ustawiony jako domyślny. W sekcji Wygląd sklepu/Ustawienia/Edytuj ustawienia zaawansowane w zakładce Szablon znajdują się odpowiedzialne za to parametry, które powinny być zaznaczone.

Wszelkie zmiany należy zapisać, a następnie opublikować.

Uwaga
Jeżeli szablon nie zostanie opublikowany, wówczas nie pojawi się on w e-Sklepie.

Instrukcja aktualizacji innych szablonów (niż szablonów Comarch) oraz aktualizacji szablonów z własnymi modyfikacjami

Jeżeli w swoim Comarch e-Sklepie korzystasz z własnego szablonu, czyli innego niż gotowe szablony Comarch, to powinieneś jego aktualizację przeprowadzić we własnym zakresie lub zlecić ją firmie/ osobie, która dla Ciebie przygotowała ten szablon. W przypadku, gdy korzystasz z gotowego szablonu Comarch, ale wprowadziłeś do niego indywidualne zmiany (poza Kreatorem Wyglądu), to również we własnym zakresie (lub ze wsparciem autora zmian) musisz zadbać o aktualizację swojej wersji szablonu.

Modyfikacja informacji wyświetlanych na kaflu towaru

W Kreatorze Wyglądu Topaz powstała funkcja pozwalająca na modyfikację informacji wyświetlanych na kaflu towaru. Po wybraniu widoku listy towarów i stylu kafli, przechodząc do ustawień tej sekcji, masz możliwość edycji informacji o towarze, które będą widoczne na kaflu towaru. Dostępne są dwa widoki zdjęć kategorii: lista oraz mozaika. Domyślnie zaznaczona jest lista. Aby dokonać modyfikacji informacji na kaflu, musisz przejść do zakładki „Kafle”.  Jeśli korzystasz z list towarów 3 lub 4, masz możliwość edycji następujących informacji:
  • Kupowanie z listy towarów
  • Dodawanie do ulubionych z listy towarów
  • Prezentowanie drugiego zdjęcia towaru
  • Graficzna prezentacja wariantów towaru
  • Dodatkowe informacje na kaflu
  • Dodatkowe funkcje na kaflu
W przypadku list towarów 1 i 2, modyfikacja informacji jest uproszczona, ogranicza się jedynie do:
  • Kupowanie z listy towarów
  • Dodawanie do ulubionych z listy towarów
  • Prezentowanie drugiego zdjęcia towaru

Polecane produkty, kategorie oraz bannery w wyszukiwarce

Wstęp

Parametry wyszukiwania stanowią istotny element w funkcjonowaniu sklepu internetowego. Wygodne oraz efektywne przeszukiwanie asortymentu zachęca klientów do kontynuacji zakupów. Aktualnie, po kliknięciu w pole wyszukiwania, klienci natychmiast uzyskują dostęp do polecanych produktów, kategorii i wybranych marek. Nowa funkcja nie tylko ułatwia skuteczne przeglądanie oferty, ale również pełni rolę skutecznego narzędzia do promowania asortymentu. Dzięki łatwemu dostępowi do rekomendacji, zwiększasz atrakcyjność swojego e-Sklepu, umożliwiając klientom bardziej intuicyjne odkrywanie interesujących produktów. Wyżej opisaną funkcjonalność możesz włączyć w dwóch miejscach:
  • Na ustawieniach nagłówka w Kreatorze wyglądu:
  • W panelu administracyjnym w zakładce Wygląd sklepu/ Ustawienia/ Ustawienia sklepu/ Dodatkowe. W tym miejscu wybierz w Widoku wyszukiwania towarów w nagłówku opcję ’Z rekomendacjami”.
Pojawiający się popup z rekomendacjami składa się z trzech osobnych elementów, jakimi są:
  • Polecane produkty
  • Polecane kategorie
  • Polecane marki
Produkty polecane skonfiguruj przechodząc do panelu administracyjnego do zakładki  Wygląd sklepu/ Ustawienia/ Więcej(trzy kropki)/ Edytuj ustawienia zaawansowane/ Obiekty. Odnajdź obiekt header-recomm-products, po czym wybierz jeden typ z listy. Do wyboru masz:
  • Ostatnio oglądane,
  • Ręczny,
  • Grupa towarowa,
  • Producent,
  • Marka.
Wskazówka
W popupie z rekomendacjami wyświetlonych zostanie maksymalnie 6 polecanych towarów
Kategorie polecane skonfiguruj przechodząc do panelu administracyjnego do zakładki Wygląd sklepu/ Ustawienia/ Więcej(trzy kropki)/ Edytuj ustawienia zaawansowane/ Obiekty. Odnajdź na obiekt header-recomm-categories, po czym wybierz jeden typ z listy:
  • Grupy najwyższego poziomu,
  • Podgrupy począwszy od,
  • Wybrane,
  • Zawężaj menu do wybranej grupy.
Przyklad
Jeśli kategoria ma więcej niż trzy podkategorie, to widoczna będzie jedynie ta, która jest ostatnia
Polecane marki skonfiguruj przechodząc do panelu administracyjnego do zakładki  Wygląd sklepu/ Ustawienia/ Bannery w obiekcie headerRecommLogos. Dodaj odpowiednie zdjęcia. Możesz także dodać link. Dzięki temu po kliknięciu w banner ostaną przekierowany na podany adres URL.
Wskazówka
Jeśli obiekt header-recomm-categories,  header-recomm-products lub banner headerRecommLogos zostanie usunięty, to popup z rekomendacjami nie będzie widoczny na stronie

Poznaj nasz produkt - konfiguracja banneru informacyjnego w szablonie

Wstęp

W Kreatorze Wyglądu (B2C) dla szablonu Topaz oraz One Page Shop jest możliwość dodania banneru informacyjnego, który zaprezentuje jeden z Twoich produktów w sklepie. Dzięki zastosowaniu infografik wraz z opisem klienci Twojego sklepu będą mogli zapoznać się z zaletami wyróżnionego towaru.

Konfiguracja

Aby skonfigurować dodany przez Ciebie banner należy przejść w Panelu Administracyjnym do zakładki: Wygląd sklepu/ Ustawienia / Bannery do konfiguracji banneru info-banner-0-A:
  • Zdjęcie na pierwszej pozycji będzie zdjęciem znajdującym się na środku.
  • Pozostałe zdjęcia to miniaturki do których można dodać opis (tekst).
  • Maksymalnie wyświetlać będzie się 7 zdjęć.
  • Minimalnie należy umieścić 2 zdjęcia.
Jeśli chcesz wyświetlić na środku zdjęcie swojego produktu wraz z przyciskiem kup teraz, należy przejść do konfiguracji ustawień zaawansowanych banneru wstawić pełny link z https do pierwszego zdjęcia, czyli URL/PHOTO.
Wskazówka
Pamiętaj, aby link do towaru zawierał pełny url wraz z zabezpieczeniem SSL - przykład adresu: https://demo.comarchesklep.pl/my-boo-pomadka-do-ust-w-plynie-01/3-140-5
Dodając następne zdjęcie będą one wyświetlały się jako miniatury. Można do nich dodać tekst, który wyświetli się pod zdjęciem.
Wskazówka
Maksymalnie można dodać 7 zdjęć. 
 

Banner pop-up w szablonie Szafir i Topaz

W niniejszym artykule dowiesz się, w jaki sposób dodać banner pop-up w swoim szablonie Topaz i Szafir. Banner wyświetla się w formie wyskakującego pop-upa, na którym możesz zaprezentować zdjęcie, treść a także przejść do wybranego towaru.

Konfiguracja nowego bannera

Krok 1. Dodaj jeden z dostępnych wariantów banneru pop-up w Kreatorze Wyglądu. Za pomocą funkcji przeciągnij i upuść dodaj banner do nowo utworzonego szablonu Szafir lub Topaz: Krok 2. W panelu administracyjnym przejdź do sekcji Wygląd sklepu/ Ustawienia/ Bannery. Z listy dostępnych bannerów wybierz banner popup_2: Krok 3. Po wpisaniu nazwy nowego banneru wyświetla się nowy formularz. W tym miejscu masz możliwość dodania opisu dla administratora oraz obrazków do katalogu. Jeżeli powyższe kroki zostały wykonane, to możesz przejść do dodania obrazku. Po dodaniu obrazków istnieje również możliwość uzupełnienia szczegółów dotyczących konkretnego zdjęcia. Aby dokonać modyfikacji w tym obszarze przejdź w Widok zaawansowany. Po kliknięciu w odnośnik pojawi się panel, w którym można zmienić np. tekst na bannerze, nagłówek, czas jego wyświetlania, link do którego kieruje dany obrazek, a także tooltip i tekst alternatywny. Tak wprowadzone zmiany należy zapisać i opublikować. Gotowe! Banner pop - up został dodany i tak prezentuje się w szablonie Topaz. Po kliknięciu w znacznik "Sprawdź" Twoi klienci zostaną przeniesieni na kartę towaru, gdzie będą mogli dokonać towar do koszyka.

Jak wykonać kopię bezpieczeństwa mojego szablonu?

Jak wykonać kopię bezpieczeństwa mojego szablonu?

Oprawa wizualna sklepu jest bardzo ważnym elementem podczas prowadzenia sprzedaży w sieci. Narzędzie Kreator Wyglądu Comarch e-Sklep umożliwia stworzenie własnych, niepowtarzalnych szablonów wedle preferencji i potrzeb użytkowników. W intuicyjnym narzędziu jakim jest Kreator, będziesz w stanie zaprojektować wszelkie niezbędne funkcje, takie jak stronę główną, listę towarów, szczegóły towaru oraz koszyk. Jeśli Twój projekt szablonu został zaimportowany do e-Sklepu oraz skonfigurowany wedle Twoich preferencji (dodanie grafik do bannerów, modyfikacje kolorystyczne) masz możliwość jego zapisania, co będzie stanowić kopię bezpieczeństwa. Kopia bezpieczeństwa to dane, które w każdej chwili można odtworzyć w przypadku ich utracenia (np. poprzez przypadkowe usunięcie) lub częstego wprowadzania zmian. Dane, jakie może zawierać kopia bezpieczeństwa to szablon, który wcześniej został przez nas wygenerowany wraz z bannerami. Zaleca się wykonywanie kopii zapasowych oraz zabezpieczenie ich hasłem. Każda wykonana kopia zapasowa powinna zostać zapisana w bezpiecznym i dogodnym dla Użytkownika miejscu.

Jak wykonać kopię bezpieczeństwa?

W Panelu Administracyjnym przejdź do sekcji Wygląd sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane, a następnie przejdź do zakładki Eksport szablonu. W pustych polach znajdujących się w zakładce Eksport szablonu, opcjonalnie przed eksportem możesz uzupełnić powyższe dane, tj. Autora szablonu, e-mail, telefon i stronę WWW sklepu. Aby wyeksportować szablon, kliknij Eksportuj szablon. Wyeksportowany plik jest w formacie XML, a jego nazwa zawiera szablon oraz wersję, co znacznie ułatwia zarządzanie kopiami bezpieczeństwa w przypadku wykonywania ich regularnie.

Jak wyeksportować bannery?

Bannery, które znajdują się w Twoim sklepie możesz również wyeksportować tworząc kopię bezpieczeństwa. W tym celu także musisz przejść do Wygląd sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane, a następnie do zakładki Eksport szablonu. Obok przycisku Eksportuj szablon, znajduje się przycisk Eksportuj bannery, który musisz kliknąć aby bannery, które posiadasz w e-Sklepie zostały weksportowane. Kopia bezpieczeństwa jest również zapisywana w formacie XML, a nazwa pliku wskazuje na szablon, wersję i zawartość bannerów.

Jak zabezpieczyć hasłem swój szablon?

Jeśli chcesz, aby Twój szablon został zabezpieczony hasłem, a znajomość hasła była niezbędna podczas zaimportowania tego szablonu do e-Sklepu, musisz w tym celu przejść w Panelu Administracyjnym do sekcji Wygląd sklepu/ Ustawienia/ Ustawienia zaawansowane, następnie do zakładki Szablon. W tym miejscu nadasz hasło dla swojego szablonu. Zgodnie z Polityką bezpieczeństwa haseł, hasło powinno:
  • Składać się z minimum 8 znaków,
  • Zawierać dużą literę,
  • Zawierać małą literę,
  • Zawierać cyfrę 0-9,
  • Zawierać znak specjalny – ‘!.+?;^]=-(&_)#=
Gotowe! Teraz Twój szablon został zabezpieczony hasłem. Jeśli wyeksportujesz szablon, który zabezpieczyłeś hasłem – podczas importu tego szablonu, będziesz musiał podać nadane wcześniej hasło. Jego brak uniemożliwi import szablonu, a podanie błędnego hasła spowoduje nieprawidłowe działanie szablonu po imporcie. Więcej informacji znajdziesz:

Ilość kupujących i ilość zakupionego towaru w szablonie Topaz

Wstęp

Funkcja prezentuje liczbę osób, które kupiły dany towar. Prezentowana jest także ilość zakupionego asortymentu w określonym czasie. Informacja ta widoczna będzie na szczegółach towaru w szablonie Topaz. Po najechaniu kursorem na ilość osób wyświetli się tooltip informujący dodatkowo o tym, ile sztuk danego towaru zostało sprzedanych.
Wskazówka
Funkcja jest dostępna w szablonie Topaz od wersji 2023.1
Przykład wyświetlania informacji na szczegółach towaru

Konfiguracja - panel administracyjny

Z poziomu panelu administracyjnego przejdź do zakładki Wygląd sklepu/ Ustawienia/ Ogólne. Odnajdź sekcje Informacja o ilości zakupionego towaru. Do wyboru masz trzy opcje:

  • Tak, zawsze pokazuj wartość zakupionych sztuk i klientów – po zaznaczeniu tego parametru klient będzie miał zawsze możliwość podejrzenia ilości kupionego towaru oraz liczby osób, które dokonały zakupu,
  • Tak, powyżej ilości sprzedanych sztuk – w tym przypadku po zaznaczeniu opcji klient będzie miał możliwość podejrzenia ilości kupionego towaru oraz liczby osób, które dokonały zakupu, ale tylko wtedy, gdy towar został sprzedany w ilości większej niż X sztuk,
  • Nie – informacja na temat ilości zakupionego towaru oraz kupujących nie będzie widoczna.
Po dokonaniu modyfikacji zmiany należy zapisać i opublikować.

Konfiguracja - Kreator wyglądu B2C

Z poziomu Kreatora wyglądu B2C również możesz ustawić wspomniany parametr. Podczas projektowania szablonu przejdź na widok dotyczący Szczegółów towaru. Następnie przejdź do ustawień sekcji Towar. Znajdź Informacje o ilości zakupionego towaru. Zaznacz odpowiedni parametr, po czym zapisz zmiany.   Po dokonaniu modyfikacji wygeneruj szablon, a następnie zaimportuj go w swoim e-Sklepie.

Graficzna prezentacja atrybutów na karcie produktu oraz na liście towarów w szablonie Topaz

Wstęp

Funkcja umożliwia prezentację atrybutów w formie kolorów oraz miniatur. Dotyczy ona towarów zgrupowanych (fantomów). W tym artykule dowiesz się jak poprawnie zmodyfikować ustawienia, aby Twój e-Sklep obsługiwał graficzną prezentację atrybutów.

Konfiguracja atrybutów graficznych

Aby skonfigurować atrybuty graficzne należy przejść w Panelu administracyjnym do zakładki Wygląd sklepu/ Ustawienia/Dodatkowe. W tym miejscu możesz dokonać wyboru w jaki sposób powinny być prezentowane atrybuty: jako kolory lub miniatury zdjęć. Po najechaniu kursorem na zdjęcie produktu, który znajduje się na liście towarów, zostanie wyświetlona odpowiednia wersja graficzna atrybutu.
Wskazówka
Pamiętaj, aby wprowadzone zmiany były widoczne w e-Sklepie należy je Zapisać i Opublikować.
Po przejściu do zakładki Dodatkowe domyślnie parametr odnoszący się do graficznej prezentacji wariantów towarów ustawiony jest na Nie. Funkcjonalność opisywanych wariantów zależy od wybranej wersji listy towarów oraz szczegółów towarów, które możemy edytować w Kreatorze Wyglądu Comarch e-Sklep. Aby sprawdzić, który wariant posiada nasz szablon, podczas jego tworzenia musimy najechać na ikonkę informacyjną i, znajdującą się na kafelkach danego szczegółu towaru, listy towarowej, etc. Products-4 oznacza 4 wariant listy towarów, a więc nazwa danego kafelku, a następnie przypisana jej cyfra oznacza dany wariant odpowiedniej sekcji. Kreator wyglądu Comarch e-Sklep

Wariant - Kolory

Po wybraniu wariantu Kolory, automatycznie w panelu administracyjnym pojawi się nowe okno z nazwami kolorów i ich odpowiednikami graficznymi w notacji heksadecymalnej. Związane jest to z samą konfiguracją wspomnianej funkcji i mapowaniem kolorów. Funkcja ta działa na podstawie atrybutów ustawianych na towarach w systemie ERP. Domyślnie wartości kolorów takie jak np. czerwony, zielony, etc. mapowane są automatycznie i wypełnianie poniższego okienka nie jest konieczne. Natomiast, jeżeli nasz atrybut zawiera niestandardowe nazwy kolorów np. brzoskwiniowy, wielokolorowy - wtedy musimy skorzystać z poniższego pola i przypisać odpowiedniej wartości atrybutu interesujący nas kolor.

Przykładowa konfiguracja wariantu - Kolory

W systemie ERP utwórz atrybut o nazwie Kolor i formacie lista, a następnie udostępnij go do Comarch e-Sklep. Wypełnij pozycje listy wpisując kolory, np. czerwony, zielony, niebieski itd. Następnie przypisz wspomniany atrybut do odpowiedniego towaru, który zostanie przesłany do e-Sklepu. Przy przypisywaniu tego atrybutu do danego towaru, jego Wartość pozostaw pustą, tak aby umożliwić wybór wariantów kolorystycznych. Po wykonaniu powyższych czynności wykonaj synchronizację z e-Sklepem.

Prezentacja wariantu Kolory na stronie e-Sklepu

Na liście towarów - dla wariantów 3 i 4 (products-3 oraz products-4) Na szczegółach towarów - dla wszystkich wariantów Ponadto jeżeli atrybut, który został użyty do utworzenia powyższych wariantów towarów, przypiszesz do swojej grupy towarowej w systemie Comarch ERP i utworzysz z niego filtr, pojawi się on także w formie graficznej.

Wariant - Miniatury (tylko dla towarów zgrupowanych - "fantomów")

Wybranie wariantu miniatury pozwoli na prezentację wariantu towarów w sposób graficzny przy użyciu pierwszego zdjęcia danego towaru zgrupowanego (fantoma). W związku z jej charakterystyką (do obsłużenia każdy z towarów potrzebuje swojego zdjęcia) funkcja ta dostępna jest tylko dla towarów zgrupowanych.

Przykładowa konfiguracja wariantu - Miniatury

W systemie Comarch ERP stwórz towar zgrupowany zgodnie z dokumentacją Comarch e-Sklep. Przykładowa konfiguracja w tym przykładzie została utworzona na podstawie atrybutu Kolor.

Prezentacja wariantu Miniatury na stronie e-Sklepu

Na liście towarów - dla wariantów 3 i 4 (products-3 oraz products-4) Na szczegółach towarów - dla wariantów 3 i 4 (product-details-3 oraz product-details-4)

 

Szablon Topaz - informacje

Autor: Comarch                                                                            Cena: bezpłatny                                                                          Kreator wyglądu: https://kreator.comarchesklep.pl/ Demo online:  https://demo-topaz2.comarchesklep.pl/             https://demo-topaz.comarchesklep.pl/ 

Kreator wyglądu Comarch e-Sklep umożliwia stworzenie oraz modyfikację nowego szablonu graficznego Topaz opartego na silniku DotLiquid.

Wygenerowany szablon jest również w technologii Responsive Web Design (RWD), dzięki czemu strona sklepu dostosowuje się automatycznie do rozdzielczości urządzenia, na którym jest wyświetlana i nie ma potrzeby tworzenia osobnych szablonów dla wersji mobilnej. Dodatkowo szablon jest dostosowany do wyświetlania w rozdzielczości 4K.

Od wersji 2019.6 szablon posiada obsługę funkcji PWA, czyli Progressive Web App. Gdy otworzysz e-Sklep z szablonem Topaz na urządzeniu mobilnym (w trybie responsywnym), sklep wyświetli komunikat o możliwości pobrania skrótu na ekran główny urządzenia. W rezultacie e-Sklep uruchomiony z takiego skrótu będzie wyświetlał się jak aplikacja natywna zainstalowana na urządzeniu mobilnym i dostosowana do wyświetlania na nim.

Szablon Topaz możesz samodzielnie zbudować w kreatorze, dzięki unikalnej kombinacji różnych elementów (dostępnych dla stron: strona główna, lista towarów oraz szczegóły towaru), a także motywów kolorystycznych, czcionki i wyglądu ikonofontów.

Wygenerowany szablon można dodatkowo poddać edycji w panelu administracyjnym. Proste ustawienia pozwalają spersonalizować wygląd sklepu poprzez zmianę następujących parametrów:

  1. Motyw kolorystyczny – możliwość skorzystania z predefiniowanych motywów i ich edycji. Możliwe jest wybieranie indywidualnych kolorów szablonu z wykazu bądź wprowadzanie kolorów przy użyciu zapisu szesnastkowego (heksadecymalnego),
  2. Ustawienia wstążek – zmiana kolorystyki flag promocyjnych na towarach,
  3. Bannery – możliwość edycji bannerów (zdjęcia, opis, linki),
  4. Logo i favicon – możliwość wgrania własnego logo i favicon (ikony widocznej na zakładce przeglądarki),
  5. Obiekty – konfigurowalne obiekty pozwalające zmienić np. ilość i sortowanie towarów wyświetlanych w kategoriach.
Wskazówka
Od wersji 2021.2 po uzupełnieniu pola Link (w widoku zaawansowanym) – cały baner staje się „klikalny”, to znaczy, że w przypadku kliknięcia na baner zostanie wykonane przekierowanie do określonego wcześniej linku (zarówno wewnętrznego - z danego e-Sklepu, jak i zewnętrznego - spoza danego e-Sklepu). W przypadku uzupełnienia obu pól: link oraz tekst – na banerze zostanie wyświetlony guzik: „Sprawdź”.
Wskazówka
Od wersji 2022 w szablonie zaimplementowano meta znaczniki Open Graph niezbędne do prawidłowej komunikacji z platformą Facebook oraz przesyłania towarów dla sklepu Facebook. Więcej na ten temat przeczytasz tutaj.
Możesz także skorzystać z Gotowych szablonów Comarch, dostępnych w panelu administracyjnym Wygląd sklepu/Gotowe szablony Comarch.Z tego poziomu możesz pobrać i zainstalować przygotowany przez nas szablon Topaz. Zalecane rozmiary zdjęć/banerów:
  • Podczas modyfikacji wyglądu szablonu Topaz w kreatorze istnieją trzy rodzaje nagłówków. Dla trzeciego rodzaju nagłówka (Header-3) wymiary dostępnego tam banneru wynoszą: 1118×534 px.
Wskazówka
W wersji 2021.2. w szablonie Topaz umożliwiono dodanie więcej niż jednego zdjęcia do banneru w nagłówku nr 3. Po dodaniu minimum dwóch obrazków na bannerze pojawi się slajder pozwalający na ich przewijanie (za pomocą strzałek).
  • Podczas modyfikacji wyglądu szablonu Topaz w kreatorze, mamy możliwość wyboru sześciu prezentacji banerów. Wymiary podane w jednostce px.
Banner-1: Banner-2: Banner-3: Banner-4: Banner-5: Banner-6:
Wskazówka
Możliwość edytowania wyżej opisanego banneru z poziomu panelu administracyjnego Comarch e-Sklepu: Wygląd Sklepu/Ustawienia/Bannery/kafelki homepage. Nazwa znajdująca się pod zalecanym rozmiarem grafiki wskazuje poprzez który kafelek ma zostać dodany obraz. O kolejności dodanych w obrębie jednego kafelka obrazków możesz zdecydować indywidualnie, przeciągając i upuszczając grafikę.
  • Rozmiar dla baneru, który pokazuje się po rozwinięciu kategorii wynosi 220px x 295px:

Wskazówka
Możliwość edytowania wyżej opisanego banneru z poziomu panelu administracyjnego Comarch e-Sklepu: Wygląd Sklepu/Ustawienia/Bannery/menuBanner

  • Rozmiar dla zdjęcia na stronie Kontakt wynosi 610px x 605px:

Wskazówka
Możliwość edytowania wyżej opisanego banneru z poziomu panelu administracyjnego Comarch e-Sklepu: Wygląd Sklepu/Ustawienia/Bannery/contactBanner

  • Rozmiary dla zdjęć na stronie Lookbook wynosi: 560px x 630px, 700px x 850px, 1260px x 540px, 630px x 950px, 560px x 630 px.

Wskazówka
Możliwość edytowania wyżej opisanego banneru z poziomu panelu administracyjnego Comarch e-Sklepu: Wygląd Sklepu/Ustawienia/Bannery/lookbook

 
  • Rozmiar dla baneru, który pokazuje się na zakładce Promocje, po otworzeniu sekcji Profil klienta wynosi 1920px x 680px.

Wskazówka
Możliwość edytowania wyżej opisanego banneru z poziomu panelu administracyjnego Comarch e-Sklepu: Wygląd Sklepu/Ustawienia/Bannery/CustomerProfileBanner

 
  • Rozmiary dla zdjęć kategorii na liście wynoszą 885×400 dla dużego obrazka i 430×400 dla małego obrazka. Zdjęcia w wersji mobilnej przycinane są centralnie do rozmiarów 380×360. Widok listy kategorii zależy od wybranej listy towarów.
    Lista kategorii w szablonie dla widoku 1 i 2 listy towarów (obiekty o nazwach: products-1 i products-2)
Lista kategorii w szablonie dla widoku 3 i 4 listy towarów (obiekty o nazwach: products-3 i products-4)
  • Rozmiar dla obrazu produktu wynosi 660px x 630px.

Dla bardziej zaawansowanych użytkowników znających technologie takie jak HTML, CSS, JS, DotLiquid udostępniony jest obszar z plikami szablonu, gdzie można dokonywać zmian na poziomie kodu szablonu, co daje dalsze, praktycznie nieograniczone możliwości edycji i personalizacji wyglądu sklepu.

Od wersji 2019.6 została dodana możliwość kopiowania wcześniej złożonego zamówienia do koszyka, a także możliwość sprawdzenia historii konta przez zalogowanych użytkowników. Niezarejestrowani użytkownicy mogą sprawdzić szczegóły złożonego zamówienia w Comarch e-Sklep. W tym celu kontrahent powinien przejść do szczegółów zamówienia za pomocą linku, który otrzymuje w wiadomości e-mail. Dodatkowo wprowadzona została możliwość włączenia w Szablonie Topaz sprzedaży w jednostkach niecałkowitych, a także sprawdzania poprawności wprowadzanego numeru NIP dla Polski. Więcej na ten temat opisane zostało w ulotce do wersji 2019.6.

Od wersji 2020 na liście towarów został rozszerzony obszar klikalny dla wybranego towaru poprzez który można przejść do jego szczegółów. Klient może przejść do szczegółów towaru klikając nie tylko w zdjęcie towaru, ale również w jego nazwę oraz cenę lub odpowiedni napis, na przykład Zapytaj o cenę. Również w tej wersji została dodana możliwość wprowadzenia przez Klientów podczas składania zamówienia daty dostawy zakupionego towaru. Dodatkowo od tej wersji w momencie, gdy zalogowany klient będzie chciał przejść do strony logowania lub rejestracji (na przykład klikając w odpowiednią sekcję stopki) zostanie on przeniesiony na stronę profilu klienta. Więcej na temat zmian opisano w ulotce do wersji 2020. Od wersji 2020.3 w szablonie Topaz została wprowadzona możliwość dodania do szablonu slajdera marek oraz producentów. Na sliderach wyświetlane są loga marek lub producentów, które zostały zaimportowane z systemu ERP. Również w tej wersji została dodana możliwość szesnastkowego zapisu kolorów wyświetlanych w e-Sklepie. Zapis heksadecymalny dla poszczególnych sekcji w szablonie dostępny jest w panelu administracyjnym na ustawieniach wyglądu sklepu. Więcej na ten temat zostało opisane w ulotce do wersji 2020.3. Również w wersji 2020.3 została udostępniona strona wyszukiwarki zaawansowanej. Umożliwia ona bardziej precyzyjne określenie poszukiwanych w sklepie towarów, poprzez:
  • określenie kategorii produktowej,
  • wybranie sposobu wyszukiwania (z wyrażeniem, z
  • określenie pól, które mają być sprawdzone podczas wyszukiwania (opis towaru, cechy towaru, symbol, kod towaru, kod EAN, kod producenta),
  • zawężenie cech wyszukiwanego towaru (ceny, produktów ze zdjęciem, czy flag dodanych do towaru, jak nowość czy wyprzedaż),
  • wybranie producentów,
  • określenie marek.
  Od wersji 2020.4 dodano możliwość prezentacji drugiego zdjęcia na liście towarów dla szablonu Topaz. Po najechaniu kursorem na zdjęcie główne pojawi się drugie zdjęcie. Opcję można włączyć w Ustawieniach szablonu w panelu administracyjnym e-Sklepu Wygląd sklepu/ Ustawienia w sekcji Prezentowanie drugiego zdjęcia towaru na liście. W wersji 2020.4 poprawiono również skalowanie bannerów na ekranach o niestandardowych rozdzielczościach dla szablonu Topaz. Co więcej, w wersji 2020.4 szablonu Topaz zmieniono sposób wyświetlania sekcji Blog na stronie głównej. Jeżeli w e-Sklepie nie opublikowano żadnych wpisów do bloga, to pomimo dodania tej sekcji w Kreatorze Wyglądu, nie będzie ona widoczna na stronie głównej. Publikacja minimum jednego wpisu spowoduje pojawienie się bloga w e-Sklepie. Od wersji 2020.4 dla szablonu Topaz dodano w Profilu Klienta na liście zamówień informacje o statusach dostawy i płatności poszczególnych dokumentów. Od wersji 2021.2. dla szablonu Topaz wprowadzono nowy sposób filtrowania towarów. Usprawniono sposób wyświetlania ilości wyników w danym filtrze. Jeżeli wyszukiwanie odbywa się na podstawie jednego filtra, wówczas liczba towarów w danym filtrze wyświetla łączną ilość dla poszczególnych pozycji, zaś dla pozostałych filtrów określa, ile z nich spełnia dane kryteria. Gdy filtrowanie odbywa się w kilku sekcjach, wówczas będą wyświetlane odpowiednie ilości towarów spełniające wskazane kryteria. Jeżeli ilość towarów w danej sekcji wyniesie 0 to zostanie ona wyłączona, bez możliwości zaznaczenia. W szablonie Topaz, na stronie szczegółów towaru dodano w wersji 2021.2. mechanizm pozwalający na powiększenie zdjęcia towaru. Po kliknięciu w miniaturkę zdjęcia pokazuje się jego powiększenie. Od wersji 2021.2 w szablonie Topaz w nagłówku 1 i 2 z poziomym menu, wprowadzono rozszerzanie menu, kiedy do e-Sklepu udostępnionych jest bardzo dużo kategorii oraz podkategorii. W ustawieniach szablonu Topaz (które dostępne są w panelu administracyjnym w menu Wygląd sklepu/ Ustawienia/ Ustawienia szablonu) dodano parametry umożliwiające zarządzanie edycją terminu dostawy podczas składania zamówienia. W wersji 2021.2. można pozwolić klientom na planowanie terminu dostawy poprzez określenie jej oczekiwanej daty lub daty dostawy oraz jej godziny. Dla włączonego parametru domyślnie ustawiono edycję daty dostawy.
Od wersji 2021.2. w ustawieniach szablonu Topaz dodano także parametr, który pozwala określenie, w jakiej kolejności mają zostać wyświetlone kategorie w e-Sklepie. Parametr znajduje się w panelu administracyjnym w sekcji Wygląd Sklepu/Ustawienia. Istnieją dwie możliwości: kolejność zgodna z ustawieniami w systemie ERP lub domyślna – zgodna z zaleceniami optymalizacyjnymi szablonu. Uwaga, aby wyświetlać kategorie zgodnie z ustawieniami w systemie ERP, należy odpowiednio w posiadanym systemie ERP ustalić kolejność kategorii, a następnie wykonać synchronizację danych. Podczas ustawienia minimalnej wartości zamówienia dla darmowej dostawy od wersji szablonu Topaz  2022, klient po wyborze dostawy, widzi komunikat określający, jaka jest minimalna wartość zamówienia by, dostawa była darmowa. Komunikat zostanie wyświetlony, gdy dla wybranej dostawy określono próg wartości zamówienia (większy od 0zł), po przekroczeniu, którego koszt dostawy będzie darmowy, a wartość samego koszyka nie spełnia jeszcze określonych warunków. Przykładowa konfiguracja darmowej dostawy o minimalnej wartości zamówienia. Od wersji 2022 dla nowo przygotowanych widoków listy towarów w szablonie Topaz zostały dodane i obsłużone następujące ustawienia w panelu administracyjnym w zakładce Wygląd sklepu/ Ustawienia: Dla powyższych punktów domyślnymi ustawieniami są opcje zaznaczone powyżej. Ustawienia te można zmienić według własnego uznania, a następnie należy użyć opcji Zapisz i Publikuj. Od wersji 2022.2 został dodany nowy widok szczegółów towaru. Obiekt o nazwie product-details-3 dostępny jest do wyboru podczas tworzenia nowego szablonu w Kreatorze Wyglądu Comarch. W nowym widoku została dodana nowoczesna galeria zdjęć, w której oprócz zdjęć można zaprezentować także film dodany dla towaru w systemie ERP. Widok charakteryzuje się przejrzystym układem, zawiera dodatkowe sekcje z towarami polecanymi, ostatnio oglądanymi, a także zestawami towarów dostępnych do kupienia. Od wersji 2022.4 dodany został nowy widok szczegółów towaru. Obiekt products-details-4 zawiera wszystkie dotychczasowe funkcje, obsługuje również wszystkie mechanizmy znane z poprzednich widoków szczegółów towaru. Najnowszy widok charakteryzuje się nowoczesną galerią zdjęć, w której dostępne są także filmy. Pod galerią w formie zakładek prezentowany jest opis towaru, cechy, opinie klientów oraz załączniki. Widoczne są również dodatkowe sekcje z zestawami towarów do kupienia, towarami polecanymi, a także ostatnio oglądanymi. Obiekt products-details-4 widoczny jest w Kreatorze Wyglądu Comarch. podczas tworzenia lub edycji szablonu. W najnowszej wersji szablonu Topaz możliwe jest prezentowanie i odtwarzanie plików w formacie MP4. Po przesłaniu filmu z systemu Comarch ERP Optima lub Comarch ERP XL do swojego e-Sklepu, zostanie on wyświetlony w sekcji z filmami lub w galerii w zależności od wariantu widoku na stronie ze szczegółami towaru. Również w wersji 2020.4 został udostępniony parametry do zarządzania prezentacją atrybutów, który znajduje się w Panelu Administracyjnym w sekcji: Wygląd sklepu/ Ustawienia/ Ustawienia szablonu/ Dodatkowe. Klient ma możliwość graficznej prezentacji atrybutów dla towarów:
  • zgrupowanych z atrybutami,
  • z cechami,
  • z atrybutami wielowartościowymi
W wersji 2022.5 dodano nowy motyw kolorystyczny dla szablonu Topaz. Dzięki motywowi ciemnemu interfejs graficzny przybiera ciemniejsze barwy, zastępując jasne tony. W kontraście do tła wszystkie ikony, przyciski oraz napisy przybierają barwę jasną. Domyślnie elementy szablonu składają się z granatowego, fioletowego oraz czerwonego koloru, jednak można je zmienić i dostosować do swoich indywidualnych potrzeb. Motyw ciemny w szablonie Topaz można zaprojektować samodzielnie, korzystając przy tym z Kreatora Wyglądu Comarch.

Obsługa wyświetlania kolorów w filtrze na liście towarów

Od wersji szablonu 2023.1.1 dodaliśmy obsługę filtru typu kolor w formie graficznej. Funkcję można uruchomić z poziomu panelu administracyjnego e-Sklepu, w zakładce Wygląd sklepu/Ustawienia/Ustawienia szablonu/Dodatkowe. Dodatkowo, jest ona dostępna jest ona także z poziomu Kreatora Wyglądu, w sekcji Lista towarów/Ustawienia. Po jej zaznaczeniu wyświetli się odpowiednia sekcja, pozwalająca na przypisanie odpowiednich wartości atrybutu odpowiadającego za kolor do konkretnych wartości heksadecymalnej. Aby poprawnie skonfigurować funkcję w systemie Comarch ERP potrzebny będzie atrybut o nazwie Kolor, którego typem będzie Lista, a za wartości listy obierzemy odpowiednie dla nas nazwy kolorów.
Wskazówka
Opcja ta posiada także funkcję automatycznego mapowania kolorów po ich nazwie. Dostępna będzie ona dla atrybutów, których struktura kolorów jest standardowa np. Nazwa atrybutu to Kolor, a jego wartości to czerwony, zielony, niebieski, itd. Mapowanie to nie zadziała dla atrybutów, których wartości będą takie jak np. wielokolorowy, zgniły zielony, etc. W tym wypadku konieczne będzie korzystanie z wyżej wspomnianego, mapowania ręcznego. [/indicator.] Poprawnie utworzone filtry graficznie, będą prezentować się na stronie następująco:

Ilość kupionych i kupujących towar

Od wersji 2023.1.1 w szablonie Topaz dodano możliwość liczenia ilości osób, która zakupiła dany towar. Funkcja ta możliwa jest do uruchomienia z poziomu Kreatora wyglądu w sekcji Szczegóły towaru/Towar/Ustawienia:   Możesz ją także skonfigurować z poziomu panelu administracyjnego, przechodząc do sekcji Wygląd sklepu/Ustawienia/Ustawienia szablonu/Ogólne w zakładce Informacja o ilości zakupionego towaru. Podczas konfiguracji możesz zaznaczyć jedną z dostępnych opcji:
  • Tak, zawsze pokazuj wartość zakupionych sztuk i klientów – po zaznaczeniu tego parametru klient będzie miał zawsze możliwość podejrzenia ilości kupionego towaru oraz liczby osób, które dokonały zakupu,
  • Tak, powyżej ilości sprzedanych sztuk – w tym przypadku po zaznaczeniu opcji klient będzie miał możliwość podejrzenia ilości dotychczas zakupionego towaru oraz liczby osób, które dokonały zakupu. Będzie to możliwe jednak tylko wtedy, gdy towar został sprzedany w ilości większej niż X sztuk,
  • Nie – informacja na temat ilości zakupionego towaru oraz kupujących nie będzie widoczna.
Dane dotyczące ilości sprzedanych sztuk nie są przetwarzane natychmiastowo. Informacje te aktualizują się po około 24 godzinach.  Po tym czasie są widoczne w e-Sklepie. Wspomniana funkcja prezentuje się następująco:

Przywracanie koszyka dla klientów niezalogowanych

W szablonie Topaz przywracany jest koszyk  dla niezalogowanych klientów. Po opuszczeniu strony lub wyłączeniu przeglądarki klient niezalogowany powracający do sklepu będzie widział towary dodane do koszyka wcześniej. Proces ten działa dzięki zapisywaniu informacji w ciasteczkach. Szczegóły dotyczące generowania szablonu Topaz znajdziesz w artykule o kreatorze szablonu.

Wymagania szablonu Topaz:

  • Comarch e-Sklep w wersji minimum 2019.2,
  • e-Sklep obsługujący procesy B2C,
  • przeglądarki internetowe:

Informacja o tym, że towar znajduje się w koszyku.

W szablonie Topaz Klient zostanie poinformowany o tym, że dany produkt znajduje się już w koszyku. Po wyborze towaru i kliknięciu "Kup teraz", przy ponownej próbie dodania do koszyka, na przycisku pojawi się ikona oraz odpowiedni tooltip: Informacja widnieje na szczegółach towaru oraz pop upie podczas kupowania z listy. W szablonie Topaz prezentacja tej informacji stanowi dodatek i domyślnie jest wyłączona. Żeby ją uruchomić, należy przejść do panelu administracyjnego, a następnie do sekcji Wygląd sklepu/ Ustawienia/ zakładka "dodatkowe". Następnie po odnalezieniu sekcji "Informuj o tym, że towar znajduje się już w koszyku" należy zmienić opcję na "TAK". Po dokonaniu modyfikacji koniecznie zapisz i opublikuj zmiany.
Wskazówka
Od nowej wersji 2024 w koszykach szablonów Topaz oraz One Page Shop jest możliwość wyświetlania ceny za sztukę. Pojawi się ona po dodaniu do koszyka kilku sztuk produktu. Przy jednej sztuce towaru wyświetlana będzie tylko cena.
Przeglądarki
  •   Mozilla Firefox – aktualna wersja przeglądarki, nie starsza niż trzy miesiące,
  •   Google Chrome – aktualna wersja przeglądarki, nie starsza niż trzy miesiące,
  •   Microsoft Edge – nie wspierana dla szablonu Topaz,
  •   Internet Explorer – nie wspierana dla szablonu Topaz.
Od wersji 2024.1.1 w szablonie Topaz dodano możliwość wyświetlania w koszyku informacji jakiej kwoty brakuje do darmowej dostawy.  Funkcja ta możliwa jest do uruchomienia z poziomu Panelu Administracyjnego w sekcji Wygląd sklepu/ Ustawienia/ Ustawienia szablonu/ Ogólne: Ustawienia te można zmienić według własnego uznania, a następnie należy użyć opcji Zapisz i Publikuj.

Rozbudowana stopka w szablonach Topaz i Szafir - jak ją skonfigurować?

Wstęp

Stopka to jeden z podstawowych elementów każdego sklepu internetowego. Oprócz wymaganych informacji, które muszą się w niej znaleźć, może zawierać zbiór innych odniesień do konkretnych sekcji w Twoim e-Sklepie, do Twojego bloga lub profili w social mediach. Odnośniki mogą pozytywnie wpływać na wizerunek Twojego sklepu, przyczyniając się do wsparcia sprzedaży i generując większy ruch na stronie. W Kreatorze wyglądu obok standardowych widoków znajduje się dodatkowy, który jest bardziej rozbudowany. W przypadku szablonu Topaz jest to trzeci widok (footer-3), zaś w przypadku Szafira - drugi widok (footer-2). Dzięki modyfikacji obszaru możesz jeszcze bardziej spersonalizować swój sklep poprzez uzupełnienie stopki w więcej przydatnych informacji.

Konfiguracja rozbudowanej stopki

Jak przystąpić do edycji stopki?

Po zaimportowaniu z Kreatora wyglądu stopka będzie wyświetlać się w ograniczonym zakresie. Niezmiennie jej edycji dokonasz z perspektywy zakładek: Wygląd Sklepu/Ustawienia a następnie sekcji Nagłówek/Stopka. To tutaj zdecydujesz o ilości grup stron, konkretnych elementach w ich obrębie a następnie o kolejności w jakiej będą prezentować się w e-Sklepie. Również z tego poziomu dodasz odwołania do Twoich profili na portalach społecznościowych oraz ustawisz favicon dla swojego sklepu internetowego.

Więcej możliwości edycji stopki

Rozbudowana stopka w szablonie Topaz oraz Szafir umożliwia dodanie większej ilości grup stron niż dotychczas. Dzięki temu z łatwością zamieścisz w niej wszystko czego potrzebujesz. Dodatkowo sekcję uzupełniono o grafiki partnerów logistycznych oraz obsługiwanych operatorów płatności.

Przykładowy wygląd rozbudowanej stopki w szablonie Topaz

Przykładowy wygląd rozbudowanej stopki w szablonie Szafir

Jak skonfigurować poszczególne elementy?

    • Elementy 1-5: dodawanie kolejnych grup stron oraz zmiana ich kolejności dokonywana jest poprzez sekcję Nagłówek/Stopka w Ustawieniach w obrębie zakładki Wygląd Sklepu. W obrębie danej grupy możesz dodawać konkretne strony poprzez kliknięcie przycisku Dodaj stronę ze sklepu.
Wskazówka
Zmiany kolejności poszczególnych grup odnośników lub zmiany danych odnośników w obrębie danej grupy dokonuje się metodą Przeciągnij i upuść.
    • Element 6: odpowiada za wyświetlanie następujących informacji: e-mail, numer telefonu, telefon2 (jeśli nie istnieje, to zastępowany jest przez telefon komórkowy) fax lub skype. W celu edycji danych kontaktowych należy przejść w panelu e-Sklepu do zakładki Ustawienia/Ustawienia sklepu. Informacje o adresie e-mail pobierane są automatycznie z zakładki Ogólne z sekcji Konto e-mail sklepu. Aby dodać lub zmodyfikować numer telefonu konieczne jest wybranie zakładki Dane sprzedawcy, następnie Infolinia i zweryfikowanie pola Telefon.
      Wskazówka
      W elemencie wyświetlone zostaną maksymalnie 3 informacje (e-mail, telefon i jedno z wybranych pól np. telefon2, telefon komórkowy lub fax.
    • Element 7: odwołania do portali społecznościowych dodajemy bez zmian. Więcej o tym znajdziesz tutaj.
    • Elementy 8-9: aby dodać informację o operatorach płatności oraz partnerach logistycznych należy wybrać zakładkę Wygląd Sklepu/Ustawienia/Bannery. Edycji dokonasz z perspektywy kafelków: Logistics Partners oraz Payment Operators poprzez dodanie właściwych grafik operatorów i partnerów. Aby zmienić nazwę „Operator płatności” i/lub „Partnerzy logistyczni” wybierz zamiast zakładki Bannery, zakładkę Tłumaczenia. Wyszukaj po parametrze „ID” LogisticsPartnersBannerTitle oraz PaymentOperatorsBannerTitle i zmodyfikuj pole „Tekst” według własnych preferencji. Zmiany zapisz i opublikuj. W przypadku chęci usunięcia któregoś z elementów, zaznacz go i naciśnij przycisk „Usuń”.
Wskazówka
Zalecane parametry grafik dla operatorów płatności i partnerów logistycznych: szerokość maksymalna 64 px, rozszerzenie PNG.
    • Element 10: dane dotyczące firmy pobierane są z zakładki Ustawienia/Ustawienia sklepu/Dane sprzedawcy/Dane identyfikacyjne, a także z obszaru: Ustawienia/ Ustawienia sklepu/ Informacja o działalności gospodarczej/ Numer KRS lub CEIDG, Organ rejestrujący oraz Ustawienia/ Ustawienia sklepu/ Adres pocztowy, gdzie uwzględnione zostaną wszystkie pola za wyjątkiem Szerokości i długości geograficznej.

Element tekstowy w szablonie Topaz

Wstęp

Szablon Topaz możesz samodzielnie zbudować w Kreatorze. Dzięki unikalnej kombinacji różnych elementów będzie on dostosowany do Twoich potrzeb. Jednym z nich jest element tekstowy, dostępny w wersji bez obrazka i z obrazkiem. Charakteryzuje się on możliwością wprowadzenia statycznego opisu na stronie głównej w e-Sklepie. Możesz zawrzeć w nim np. podstawowe informacje na temat Twojej firmy, asortymentu sklepu lub inne wartościowe dla Ciebie treści.
Wskazówka
Zobacz, jak wygląda element tekstowy z obrazkiem bezpośrednio w naszym sklepie demonstracyjnym pod adresem: demo.comarchesklep.pl.

Element tekstowy w Kreatorze Wyglądu Topaz

W Kreatorze Wyglądu masz do wyboru dwa rodzaje elementu tekstowego:
  • bez obrazka (sam tekst) (textElement-1),
  • z obrazkiem (textElement-2).
Dodaj element tekstowy do kompozycji Twojego projektu i dowiedz się, jak skonfigurować go pod swój e-Sklep. Element ten możesz dodać do strony głównej szablonu.
Element tekstowy w Kreatorze Wyglądu

Konfiguracja elementu tekstowego w panelu administracyjnym

Po wygenerowaniu szablonu wgraj go na zakładce Wygląd sklepu/ Zaimportuj szablon z Kreatora wyglądu, zgodnie z instrukcją.

Element bez obrazka

Jeżeli w Kreatorze wybrałeś element tekstowy bez obrazka (o nazwie textElement-1), przejdź do zakładki Wygląd Sklepu/ Ustawienia/ "Więcej" Edytuj ustawienia zaawansowane/ Obiekty. Znajdź na liście obiekt text-el-no-photo-mp-2 (typ tekstowy), a następnie przejdź do jego szczegółów klikając w nazwę obiektu. Domyślny element zawiera nagłówek pierwszego poziomu oraz drugiego poziomu, a także tekst podzielony na trzy kolumny. Masz możliwość edycji treści za pomocą znaczników języka HTML. Przed rozpoczęciem modyfikacji upewnij się, że masz wybrany odpowiedni język.
Wskazówka
Dla każdej wersji językowej należy osobno zmienić treść.
Po zakończonej edycji pamiętaj o zapisaniu oraz opublikowaniu zmian. Element textElement-1 na stronie sklepu prezentuje się domyślnie:

Element z obrazkiem

Jeżeli w Kreatorze wybrałeś element z obrazkiem (nazwa:textElement-2) konfigurację elementu rozpocznij od dodania zdjęcia dla elementu w plikach użytkownika. Aby to zrobić przejdź do zakładki Ustawienia/ Pliki użytkownika i ikoną plusa wgraj zdjęcie, które chcesz dodać do elementu tekstowego. Następnie przejdź do zakładki Wygląd Sklepu/ Ustawienia/ "Więcej" Edytuj ustawienia zaawansowane/ Obiekty. Znajdź na liście obiekt text-el-photo-mp-1(typ tekstowy) i przejdź do jego szczegółów.  Domyślny element zawiera nagłówek pierwszego poziomu oraz drugiego poziomu, miejsce na zdjęcie oraz tekst podzielony na dwie kolumny. Masz możliwość edycji treści oraz zmiany położenia obrazka za pomocą znaczników języka HTML. Przed rozpoczęciem modyfikacji upewnij się, że masz wybrany odpowiedni język.
Wskazówka
Dla każdej wersji językowej należy osobno zmienić treść.
Aby obrazek został wgrany do elementu tekstowego, pomiędzy znacznikami <image></image> musisz poprawnie wpisać ścieżkę dla wgranego wcześniej obrazka. Dla plików użytkownika jest to user/nazwa obrazka. Po zakończonej edycji pamiętaj o zapisaniu oraz opublikowaniu zmian. Element textElement-2 z wgranym obrazkiem na stronie sklepu prezentuje się następująco: W wersji mobilnej e-Sklepu masz możliwość widoku elementu tekstowego w wersji zwiniętej lub rozwiniętej. Część treści jest początkowo ukryta, ale odwiedzający może wyświetlić pełny tekst, klikając przycisk Więcej, który następnie może zwinąć za pomocą przycisku Mniej.
Wskazówka
Zobacz element tekstowy z obrazkiem bezpośrednio w naszym sklepie demonstracyjnym pod adresem: demo.comarchesklep.pl. 

Jak wyeksportować i zaimportować swój szablon w e-Sklepie?

Comarch e-Sklep daje możliwość dostosowania wyglądu do preferencji sprzedawcy oraz potrzeb Klientów. Jeśli utworzyłeś już swój autorski projekt, to masz możliwość jego zapisania. Plik będzie potrzebny przy chęci modyfikacji wyglądu. Zapisana wersja szablonu może również stanowić kopię bezpieczeństwa. Warto jest więc wyeksportować szablon do pliku.

Jak wyeksportować swój szablon z Comarch e-Sklep?

Krok 1. W panelu administracyjnym przejdź do sekcji Wygląd Sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane/ zakładka Eksport szablonu.

Krok 2. W tym miejscu możesz opcjonalnie (przed eksportem) określić autora szablonu, podać adres e-mail, telefon oraz adres WWW swojego e-Sklepu.

Krok 3. Jeżeli chcesz wyeksportować szablon do pliku użyj przycisku Eksportuj szablon.

Gotowe! Szablon został wyeksportowany do pliku na Twoim urządzeniu.

Wskazówka
Z tego miejsca możesz także wyeksportować posiadane w e-Sklepie bannery, korzystając z przycisku Eksportuj bannery.

Jak wgrać własny szablon do Comarch e-Sklep?

Własny szablon. Jak go wgrać?

Po skomponowaniu swojego własnego szablonu możesz wgrać go do e-Sklepu. Postępuj zgodnie z poniższymi krokami.

Krok 1. W panelu administracyjnym przejdź do sekcji Wygląd Sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane/ zakładka Import szablonu.

Krok 2. Określ, czy wgrywany szablon ma podmienić istniejące bannery. Gdy parametr zostanie zaznaczony, wówczas wszystkie bannery zapisane na danym slocie zostaną usunięte i zastąpione bannerami z importowanego szablonu.

Krok 3. Wybierz plik XML swojego szablonu i naciśnij Importuj szablon.

Uwaga
Import szablonu jest operacją nieodwracalną i spowoduje nadpisanie dotychczasowego szablonu. W przypadku, gdy szablon był modyfikowany (dokonywano zmian w kodzie HTML) jego aktualizacja spowoduje, iż zmiany nie zostaną przeniesione. Warto wykonać eksport posiadanego szablonu do pliku w celu zapisania oraz posiadania wglądu to wprowadzanych modyfikacji. Jeżeli istnieje taka konieczność należy ponownie dokonać samodzielnej edycji szablonu

Wskazówka
W zakładce Szablony możesz określić, czy wgrywany szablon ma być domyślny i aktywny w e-Sklepie.

Krok 4. Teraz możesz podejrzeć zmiany, jakie zaszły w wyglądzie Twojego e-Sklepu. W tym celu możesz podejrzeć zmiany w czasie rzeczywistym lub przejść w tryb incognito. Pamiętaj, że wszelkie zmiany zostaną opublikowane po pełnej synchronizacji, która wciągu 10 minut zgodnie z wyświetlanym komunikatem.

Gotowe! Twój szablon został zaimportowany do e-Sklepu.

Jak wstawić dodatkową Wtyczkę (Widget) w szablonie Topaz?

Dodatkowy widget np. Ceneo Zaufane Opinie, Facebook Messenger lub inne można samodzielnie zaimplementować w kodzie szablonu. Wystarczy kilka prostych kroków, dzięki którym będzie można wyświetlić swoim Klientom dodatkowy widget na każdej stronie w e-Sklepie. Wszystkie wtyczki posiadają indywidualny skrypt, który należy wkleić w odpowiednim miejscu w kodzie szablonu. Obsługa w szablonie Topaz: Krok 1. W panelu administracyjnym e-Sklepu należy przejść do sekcji Wygląd sklepu/Ustawienia/(opcja trzy kropki w górnym prawym rogu) Edytuj ustawienia zaawansowane/ (ponownie opcja trzy kropki w górnym prawym rogu) Edytuj HTML. Krok 2. Odnaleźć plik base_layout.html i przejść do jego edycji. Krok 3. Skopiować skrypt danego widgetu, a następnie wkleić go w odpowiedniej sekcji pod koniec pliku. Poniżej wklejonego skryptu mają zostać tylko linijki zawierające zamknięcie tagu html, zamknięcie tagu body oraz zamknięcie( {% endif -%} ) jednego warunku. Powyżej wklejonego kodu powinno być zamknięcie ( {% endif -%} ) warunku {% if config.External.SalesManago -%}. Krok 4. Zapisać i opublikować zmiany.
Uwaga
Powyższa instrukcja dotyczy szablonu Topaz. Należy także pamiętać, iż różnego rodzaju wtyczki mogą wymagać odrębnej implementacji w różnych plikach szablonu. Zawsze należy zapoznać się z dokumentacją oraz wymaganiami dostawcy wtyczki. Jeżeli powyższa instrukcja nie jest wystarczająca dla wyświetlenia dodatkowej wtyczki w szablonie należy skontaktować się z Partnerem Comarch, w celu uzyskania dodatkowej pomocy.
Wskazówka
Chcesz dodać do e-Sklepu wtyczkę Facebook Messenger Chat? Skorzystaj z odrębnie przygotowanej instrukcji dostępnej w artykule Obsługa wtyczki Czatu Facebooka w szablonach.

Dlaczego na szczegółach towaru w szablonie Topaz w wersji 2021 nie wyświetlają się zdjęcia ?

Od wersji 2021 w Comarch e-Sklep dostępy jest filtr img2, który standardowo został obsłużony w szablonie Topaz w wersji 2021. W przypadku najnowszej wersji szablonu wgranej do sklepu w wersji 2020.4 lub starszej mogą nieprawidłowo wyświetlać się zdjęcia na szczegółach towaru (z uwagi na zastosowany filtr img2, który nie jest obsługiwany we wcześniejszych wersjach e-Sklepu). Jeśli posiadasz Comarch e-Sklep w wersji 2020.4 lub starszej niezbędne jest wygenerowanie szablonu Topaz w wersji 2020. Na stronie Kreatora wyglądu , wybierz jedną z opcji:
  • stwórz nowy projekt,
  • edytuj gotowy szablon,
  • dokończ poprzedni szablon.
Na środku strony dostępne jest pole: Wybierz wersję, w którym należy wybrać z listy wersję: 2020 i kliknąć w przycisk – Rozpocznij. Zostaniesz wówczas przekierowany na stronę Kreatora wyglądu w wersji 2020.4, gdzie będziesz mógł wygenerować szablon w wersji (2020.4), zgodnej z wersją e-Sklepu. Po wygenerowaniu szablonu w wersji 2020.4, zaimportuj szablon do panelu administracyjnego e-Sklepu. Możesz to zrobić w menu Wygląd sklepu/ Ustawienia/ Więcej / Edytuj ustawienia zaawansowane/ Import szablonu.  

Dostosowanie wyglądu e-Sklepu

Jak skonfigurować mapę strony (sitemap)?

Wstęp

Mapa strony (sitemap) to spis wszystkich zakładek i podstron dostępnych na stronie internetowej. Dobrze zaplanowana ułatwia nawigację i sprawia, że odwiedzający szybciej znajdują to, czego szukają. Czy warto dostosować mapę strony do swoich potrzeb? Tak! Powinna ona pasować do typu strony i jej użytkowników. Przykładem może być wyróżnienie kategorii produktów, a w przypadku bloga – tematycznych artykułów. Dzięki dobrze zorganizowanej mapie strony, Google może szybciej zrozumieć strukturę strony, co zwiększa jej szanse na lepszą pozycję w wynikach wyszukiwania. W Comarch e-Sklep możesz w prosty sposób stworzyć mapę strony, dopasowaną do potrzeb Twoich Klientów. Opcja ta dostępna jest w każdym z gotowych szablonów B2B oraz B2C: Rubin, Szafir, Topaz, One Page Shop i Dla Gastronomii. Domyślnie, dla nowych sklepów, odnośnik do mapy strony znajduje się w stopce.

Jak skonfigurować mapę strony?

Wskazówka
W pierwszej kolejności, zaktualizuj swój szablon. Musi on być w wersji nie starszej niż 2025.4.1. Dokładną instrukcję aktualizacji znajdziesz w artykule: Jak zaktualizować szablon do najnowszej wersji? 
Po aktualizacji możesz przejść do panelu administracyjnego Comarch e-Sklep, a następnie do sekcji: Wygląd sklepu > Ustawienia. Wybierz zakładkę "Mapa strony". Przy pierwszym przejściu do obszaru, mapa strony będzie częściowo skonfigurowana.
Widok panelu administracyjnego
Widok konfiguracji mapy strony z poziomu panelu administracyjnego
Domyślnie w grupie "Strony". znajdują się wszystkie strony statyczne czyli te, które dostępne są w Twoim e-Sklepie. Nie są w nich uwzględnione np. kategorie produktów. Grupę tę możesz edytować. Najedź myszką na kafel, a następnie edytuj go: Podczas edycji w panelu administracyjnym wyświetli się obszar, w którym możliwe jest dokonanie zmian. Możesz zdecydować, czy do grupy stron dodasz już istniejącą stronę ze sklepu, czy stronę zewnętrzną. Jeśli posiadasz w niej już strony, to możesz je również usunąć. Możesz również dodać własną Grupę stron. Aby to zrobić, należy wybrać sekcję „ Dodaj grupę stron " : Na początku należy ustalić nazwę dla grupy stron: Podczas edycji w panelu administracyjnym wyświetli się obszar, w którym możliwe jest dodanie strony zewnętrznej lub istniejącej strony ze sklepu. Po określeniu, jakie strony powinny się wyświetlać, zmiany należy zapisać i opublikować.
Przykład mapy strony w szablonach B2C
   

Posiadam gotowy szablon Comarch. Jak mogę go dostosować do kryteriów WCAG 2.1/2.2?

Wstęp

Z dniem 28 czerwca 2025 roku w życie wejdą przepisy związane z implementacją ustawy z dnia 26 kwietnia 2024 r. o zapewnianiu spełniania wymagań dostępności niektórych produktów i usług. Wdraża ona do polskiego prawa tzw. Europejski Akt o Dostępności (EAA) – unijną dyrektywę 2019/882. Celem ustawy jest zapewnienie, że kluczowe produkty i usługi będą dostępne dla wszystkich użytkowników, w tym osób z niepełnosprawnościami. Przedsiębiorcy mają czas do 28 czerwca 2025 roku, aby dostosować swoje produkty i usługi do nowych wymogów.
Wskazówka
Chcesz dowiedzieć się więcej o tych przepisach? Sprawdź artykuł w naszym Centrum Pomocy: Europejski Akt o Dostępności (EAA) i zapoznaj się ze szczegółami
W niniejszym artykule wskazujemy, jakie czynności należy wykonać, jeśli posiadasz jeden ze standardowych szablonów Comarch, czyli: Rubin, Szafir, Topaz, One Page Shop lub Dla Gastronomii.   

Sprawdź, jaki szablon posiadasz

Nie wiesz, który szablon posiadasz? Możesz to sprawdzić w panelu administracyjnym Comarch e-Sklep. Aby to zrobić, z poziomu panelu administracyjnego przejdź do zakładki Wygląd sklepu/ Ustawienia a następnie, pod przyciskiem "Więcej" wybierz Edytuj ustawienia zaawansowane. W obszarze, który został wyświetlony, pojawi się kilka zakładek, a wśród nich zakładka "Szablon". Wybierz ją, po czym sprawdź szablon:   Jeśli Twój szablon to Rubin, Szafir, Topaz, One Page Shop lub Dla Gastronomii, to możesz przejść do kolejnej części artykułu. Jeśli posiadasz własny szablon z indywidualnymi modyfikacjami, to przejdź do artykułu: Posiadam własny szablon, jak mogę go dostosować do kryteriów WCAG 2.1/2.2?  Jeśli posiadasz szablon Bursztyn, Agat lub Opal, to przejdź do artykułu: Posiadam szablon Bursztyn, Opal lub Agat, jak mogę go dostosować do kryteriów WCAG 2.1/2.2?  

Co zrobić jako właściciel e-Sklepu lub Partner, jeśli używam gotowych szablonów Comarch?

Jako właściciel e-Sklepu lub Partner Comarch zadbaj, aby zadbać o dostosowanie swojej witryny do obowiązujących przepisów. Nowe wymogi to wspólna odpowiedzialność:
  • Comarch e-Sklep – zajmiemy się kwestiami technicznymi w przypadku Gotowych Szablonów Comarch, do których należą m.in. zmiany w kodzie,
  • Właściciel, administrator lub Partner sklepu – musisz zadbać o treści i elementy, które dodajesz samodzielnie. Chodzi tu głównie opis produktów, zdjęcia i grafiki czy identyfikację wizualną. 
 

Jak zacząć?

Jeśli korzystasz z gotowych szablonów, takich jak Rubin, Szafir, Topaz, One Page Shop lub Dla Gastronomii, nie musisz przejmować się samodzielnym edytowaniem ich kodu. Wszystkie usprawnienia zostaną udostępnione wraz z aktualizacją, która pojawi się w czerwcu 2025 roku.

Aktualizacja szablonu

Wskazówka
Aktualizację szablonu wykonaj wtedy, kiedy będzie ona dostępna. Realizacja wersji 2025.4 przewidywana jest przed 28 czerwca 2025 roku, poinformujemy o niej w aktualnościach. Będzie ona zawierała zmiany związane z omawianymi tutaj przepisami.

Jak zaktualizować szablon?

Aby zaktualizować szablon i przejść na Topaz, One Page Shop, Dla Gastronomii, Rubin lub Szafir, należy skorzystać z aktualnej wersji Kreatora Wyglądu. Pamiętaj, że szablony Rubin i Szafir przeznaczone są tylko dla sklepów Enterprise i B2B. Odnośnik znajduje się również w panelu administracyjnym e-Sklepu w sekcji Wygląd sklepu > Kreator wyglądu.  Istnieją trzy możliwości aktualizacji tych szablonów:
  • Wygenerowanie zupełnie nowego szablonu w Kreatorze Wyglądu oraz wgranie go do e-Sklepu,
  • Wybór i edycja jednego z gotowych układów i jego modyfikacja,
  • Import posiadanego szablonu do Kreatora Wyglądu oraz ponowne wygenerowanie go w najnowszej wersji.
Wygenerowany z Kreatora Wyglądu szablon należy wgrać do e-Sklepu. W panelu administracyjnym e-Sklepu, w sekcji Wygląd sklepu znajduje się bezpośredni odnośnik do importu szablonu z Kreatora wyglądu. Szczegółowa instrukcja dostępna jest w artykule Jak wyeksportować i zaimportować swój szablon w e-Sklepie?
Pamiętaj o zapisaniu szablonu oraz opublikowaniu go w e-Sklepie. Zmiany wprowadzone w ustawieniach zostaną zsynchronizowane do sklepu po 10 minutach.
Wskazówka
Informacje na temat aktualizacji znajdują się w Centrum Pomocy: Jak zaktualizować szablon do najnowszej wersji?  
Więcej informacji na temat Kreatora Wyglądu B2C oraz B2B znajduje się w Centrum Pomocy:

Odpowiedni kontrast kolorów w e-Sklepie – wymóg WCAG na poziomie AA

Jednym z głównych wymogów WCAG jest stosowanie odpowiednich kontrastów na stronach internetowych. Jeśli w wybranym szablonie graficznym wykorzystujesz któryś ze standardowych motywów kolorystycznych dostępnych w kreatorach, to zostaną one dostosowane do wymagań wynikających z przepisów. Jeśli natomiast masz przygotowany własny motyw kolorystyczny lub chcesz zmienić część kolorów zastosowanych w szablonie, to pamiętaj, że muszą one posiadać odpowiednie kontrasty. Wszelkich zmian kolorystycznych możesz dokonać w Kreatorze Wyglądu.  Odpowiedni kontrast między tekstem a tłem jest kluczowy dla osób z dysfunkcjami wzroku. WCAG 2.1 określa minimalny współczynnik kontrastu (4.5:1 dla tekstu zwykłego i 3:1 dla tekstu dużego). Ważne jest również unikanie łączenia kolorów, które mogą być trudne do rozróżnienia, takich jak czerwony i zielony. Kontrasty po modyfikacji kolorów możesz sprawdzić np. narzędziem WAVE. WAVE to popularny, dostępny dla wszystkich zestaw narzędzi do oceny dostępności stron internetowych. Rozszerzenia WAVE dla Chrome, Firefox i Edge, umożliwiają testowanie bezpośrednio w tych przeglądarkach, bez przesyłania danych na serwer WAVE. WAVE znajdziesz pod linkiem: WAVE Web Accessibility Evaluation Tools.  

Jak sprawdzić kontrast?

Przejdź na stronę swojego e-Sklepu. Włącz wtyczkę WAVE. Po prawej stronie ekranu wyświetli się panel boczny, na pierwszej zakładce widać podsumowanie całej strony: Już na tym etapie możesz przejść do szczegółów, klikając "View details". Możesz w tym miejscu przejść także do zakładki "Contrast".   Czerwone kwadraty oznaczają obszar do poprawy. Przejdź przez stronę, aby zobaczyć szczegóły każdego z nich. Po kliknięciu na jeden z kwadratów pokaże się komunikat dotyczący kontrastu: W panelu bocznym pojawi się dokładna informacja na temat koloru. W tym miejscu, korzystając z suwaków możesz od razu dostosować kolor tak, aby był odpowiedni i sprawdzić, czy spełnia wymagania WCAG.  

Gdzie dostosować kolory?

Kolory w szablonie możesz zmienić korzystając z Kreatora Wyglądu. Po imporcie szablonu, edycji lub stworzeniu nowego projektu, przejdź do zakładki "Style" i edytuj motyw kolorystyczny:   Następnie możesz zmieniać swobodnie kolor na wybranych elementach:   Zmian możesz dokonać także z poziomu panelu administracyjnego, przechodząc do zakładki Wygląd Sklepu > Ustawienia.

Pozostałe zmiany

Poza zmianami w szablonie graficznym sklepu należy uzupełnić szereg danych. Znaczącą część tych elementów możesz wykonać już teraz, nie czekając na aktualizację Comarch e-Sklep. Poniżej znajduje się lista zmian, które należy wdrożyć w swoim e-Sklepie.

Teksty alternatywne ("Alt", alty) w Comarch e-Sklep

Twój szablon musi obsługiwać parametr "alt" w obrazkach. Jeśli wykorzystasz aktualny szablon standardowy od Comarch to obsługę zapewnia Comarch e-Sklep, jeśli zdecydowałeś się na indywidualny szablon lub samodzielną aktualizację starszej wersji to upewnij się, że w szablonie są obsługiwane parametry "alt" we wskazanych elementach. Teksty alternatywne („alt”) to krótkie opisy obrazków, które pozwalają osobom korzystającym z czytników ekranu zrozumieć, co znajduje się na zdjęciu. Atrybut „alt” jest szczególnie ważny dla zdjęć produktów, ponieważ umożliwia przekazanie najważniejszych informacji o produktach.  Dlaczego tekst alternatywny jest taki ważny? 
  • Pomaga osobom korzystającym z czytników ekranu, które odczytują tekst alternatywny na głos,
  • Poprawia dostępność stron internetowych, czyniąc je bardziej przyjaznymi dla wszystkich użytkowników,
  • Wpływa na pozycjonowanie w wyszukiwarkach, ponieważ dobrze opisane obrazy są lepiej interpretowane przez algorytmy Google.   
Dobrze sformułowany opis powinien być zwięzły, ale wystarczająco informacyjny. Poniżej prezentujemy przykłady dobrego i złego zastosowania opisów alternatywnych:
Przyklad
Poprawne :
  • Czerwona sukienka maxi z rozcięciem, modelka na tle miejskiego pejzażu.
  • Białe sneakersy z grubą podeszwą, ustawione na drewnianej podłodze.
  • Nowoczesna sofa w kolorze szarym, z drewnianymi nogami, ustawiona w minimalistycznym salonie.
  • Słuchawki bezprzewodowe z aktywną redukcją szumów, na białym tle.
Niepoprawne:
  • Sukienka.
  • Buty sportowe.
  • Fajna kanapa.
  • Najlepszy sprzęt w dobrej cenie!

Gdzie należy uzupełnić teksty alternatywne (alt)?

1. Dla zdjęć towarów w systemach Comarch ERP

Korzystam z Comarch ERP Optima
Po uruchomieniu Comarch ERP Optima przejdź na pozycję cennika, a następnie edytuj wybrany towar. Następnie przejdź na zakładkę "Atrybuty", a następnie do sekcji "Zdjęcia i załączniki". W tym miejscu zobaczysz kolumnę "Atrybut Alt".
Po dwukrotnym kliknięciu możliwe jest uzupełnienie opisu alternatywnego: Po dokonaniu zmian należy je zapisać. Po wykonaniu wszystkich modyfikacji należy wykonać synchronizację.

Korzystam z Comarch ERP XL

Po uruchomieniu ERP XL przejdź do Sprzedaż > Towary , a następnie na zakładkę "Załączniki". Opis alternatywny dla towaru stanowi Kod:    
Korzystam z Comarch ERP XT
Przejdź na kartę produktu, a następnie do zakładki "Zdjęcia". Wśród pól do uzupełnienia znajdziesz "Opis alternatywny (Alt)".   W tym miejscu wpisz odpowiednią treść, a następnie zapisz wprowadzone zmiany.  

2. Dla zdjęć w bannerach – w panelu administracyjnym Comarch e-Sklep

Pamiętaj, alby alty (opisy alternatywne) były uzupełnione także w przypadku bannerów. Aby to zrobić, przejdź z poziomu panelu administracyjnego do Wygląd sklepu > Ustawienia > Bannery  do edycji swoich bannerów. Klikając na odpowiedni kafelek pojawią się opcje z uzupełnieniem Alt:

3. Dla zdjęć stosowanych na stronach z treściami formalnymi – w panelu administracyjnym Comarch e-Sklep

Obrazki możesz dodawać także do treści, które udostępniasz na specjalnych stronach, takich jak np. Regulamin sklepu, Polityka prywatności, Wysyłka itp. W obszarze do edycji, który jest dostępny z poziomu panelu administracyjnego w sekcji Ustawienia > Treści formalne edytuj interesującą Cię treść, a dodając obrazek uzupełnij alt:    

4. Dla zdjęć wprowadzonych w opisie towaru i opisie kategorii

Dodając opisy produktów i kategorii, warto upewnić się, że linkowane zdjęcia zawierają poprawnie uzupełniony atrybut "alt". To kluczowe dla osób korzystających z czytników ekranu. Dbałość o ten detal poprawia dostępność strony i zwiększa jej widoczność w sieci. Opis towaru i kategorii możesz dodać w systemach Comarch ERP.  Opis kategorii możesz ustawić również z poziomu panelu administracyjnego, bez konieczności korzystania z systemu ERP. Szczegółowe informacje znajdują się w artykule: Jak edytować kategorię w Comarch e-Sklep? 

5. Dla zdjęć w Blogu

Obrazki, które dodawane są dla wpisów blogowych od wersji 2025.4 będą posiadały atrybuty ALT oraz Title. Ich uzupełnienie będzie możliwe przy przejściu z poziomu panelu administracyjnego Comarch e-Sklep do sekcji Marketing > Blog przy dodawaniu wpisu:

6. Dla zdjęć w plikach użytkownika w sekcji "Twoje pliki"

Pliki użytkownika w e-Sklepie to dedykowana przestrzeń do przechowywania własnych materiałów, które mogą zostać wykorzystane w sklepie internetowym. Pliki można przesyłać za pośrednictwem panelu administracyjnego, w sekcji Ustawienia > Twoje pliki. Maksymalny rozmiar pojedynczego pliku: 3 MB. Pliki, które dodawane są we wspomnianym obszarze, od wersji 2025.4 będą posiadały atrybuty ALT oraz Title. Ich uzupełnienie będzie możliwe przy przejściu z poziomu panelu administracyjnego do sekcji Ustawienia > Twoje pliki przy edycji pliku lub jego dodaniu.
Wskazówka
Jeśli posiadasz sklep wielojęzyczny, to we wszystkich tych wymienionych powyżej obszarach, znajdują się również obrazki dla danego języka. Pamiętaj, alby atrybut ALT zdefiniować dla każdego z nich!
 

Atrybut title - obowiązkowy czy nie?

Atrybut title jest przydatny do przekazywania dodatkowych informacji o elementach HTML, widocznych jako podpowiedź po najechaniu kursorem. Może być używany w ikonach bez podpisu, formularzach czy linkach, aby dostarczyć kontekst. Nie jest jednak obowiązkowy według WCAG, ponieważ czytniki ekranu często go ignorują, a osoby nawigujące klawiaturą mogą nie mieć do niego dostępu.  

Zalecenia dla udostępnianych treści - ogranicz migające elementy

Jako właściciel sklepu musisz sam zadbać o to, jakie treści umieszczasz na swojej stronie. Migające elementy, takie jak animacje czy reklamy, mogą wywoływać problemy u osób z padaczką fotogenną. Według kryteriów WCAG 2.1 zalecane jest ograniczenie migających treści do maksymalnie trzech błysków na sekundę lub ich całkowite usunięcie. Jako właściciel sklepu musisz dbać o statyczne elementy lub spokojne animacje. Również treści zawarte w różnego typu prospektach, gazetkach czy folderach informacyjnych w formie dokumentów powinny być zgodne z wytycznymi WCAG.

1.Obrazki i bannery

W szablonach graficznych takie elementy mogą pojawić się na przykład w bannerach i elementach tekstowych ze zdjęciem. Upewnij się, że grafiki tam zamieszczone są odpowiednie, czyli bez intensywnych animacji i nieodpowiednich kolorów. Szczególną uwagę zwróć na pliki w formacie GIF. Sprawdź, w jaki sposób możesz skonfigurować bannery oraz elementy tekstowe ze zdjęciem.  

2.Materiały audio i viedo

Aby sklep internetowy był w pełni dostępny zgodnie z WCAG, właściciele muszą zadbać o dodanie audiodeskrypcji i transkrypcji do materiałów multimedialnych (filmy, nagrania dźwiękowe). Choć oba rozwiązania służą poprawie dostępności, mają różne funkcje.
  • Audiodeskrypcja to dodatkowy opis dźwiękowy, który przedstawia istotne elementy wizualne nagrania osobom niewidzącym,
  • Transkrypcja to zapis tekstowy całej treści audio, umożliwiający odbiór treści osobom niesłyszącym, może to być w formie napisów dla audiodeskrypcji.
Dodanie tych elementów leży po stronie właścicieli sklepów. Do filmów, które udostępniasz, dodaj zatem widoczne napisy, a także dobrej jakości opis dźwiękowy. Ich brak może wykluczyć część użytkowników i wpłynąć na komfort korzystania ze strony. Dobre praktyki dostępności to nie tylko wymóg, ale też inwestycja w lepsze doświadczenie klientów.

Dostosuj komunikację mailową - aktualizacja lub zmiana treści e-mail

Dostosowanie treści e-mail zgodnie z wytycznymi WCAG to kluczowy krok w budowaniu dostępnej i klarownej komunikacji. W tej części artykułu przedstawiamy rozwiązania zarówno dla domyślnych wiadomości, jak i tych modyfikowanych, aby zapewnić ich lepszą czytelność i dostępność dla wszystkich odbiorców.

1.Treści mailowe są domyślne, nie zostały sformatowane

Jeśli treści nie zostały przez Ciebie zmienione i stanowią domyślne treści, które są dostępne w Comarch e-Sklep, to wystarczy, że zaktualizujesz je. Aby to zrobić, należy przejść w panelu administracyjnym do zakładki Ustawienia > Treści formalne, a następnie wybrać „Wysyłka e-mail i SMS”. Zakładka ta zawiera treści wiadomości wysyłane do klientów po wykonaniu określonych akcji, np. po zakupie czy rejestracji. W Comarch e-Sklep istnieje możliwość przywrócenia standardowej treści pojedynczej wiadomości e-mail lub wszystkich jednocześnie. Opcja ta stanowi również aktualizację treści e-mail. "Przywróć domyślną treść" dostępna jest w panelu administracyjnym e-Sklepu w menu Ustawienia/ Treści formalne/ Wysyłka e-mail i SMS na szczegółach każdej wiadomości, po kliknięciu w przycisk Więcej:  

2.Treści mailowe są modyfikowane, zostały przeze mnie zmienione

Jeśli posiadasz własne, dostosowane do Twojej komunikacji marketingowej treści e-mail, to sprawdź, czy są one odpowiednio napisane i sformatowane. Zastosuj się do poniższych wskazówek. W jaki sposób poprawnie napisać i sformatować treści?
  • Struktura Stosuj nagłówki (<h1>, <h2> itd.) dla przejrzystości. Używaj krótkich akapitów i list punktowanych.
  • Tekst i formatowanie Zapewnij wysoki kontrast między tekstem a tłem. Wybieraj czytelne czcionki (sans-serif, min. 12-14 px). Nie używaj wyłącznie koloru do przekazywania informacji.
  • Obrazy i multimedia Dodawaj tekst alternatywny (alt text) do obrazów. Unikaj tekstu osadzonego w grafikach, jeśli można go przesłać jako tekst.
  • Linki i przyciski Stosuj opisowe teksty linków zamiast „Kliknij tutaj”. Upewnij się, że są łatwe do kliknięcia na ekranach dotykowych.
  • Język i czytelność Używaj prostego i zrozumiałego języka. Unikaj skrótów i branżowego żargonu, jeśli odbiorca może ich nie znać.
  • Testowanie Sprawdź wiadomość na różnych urządzeniach i czytnikach ekranu. Zweryfikuj zgodność ze standardami WCAG.
Szczegółowe informacje na temat edycji treści e-mail znajdują się a artykule: E-mail i SMS  

3.Załączniki (m.in. instrukcje, katalogi)

Należy zadbać o to, aby wszystkie udostępniane w sklepie załączniki, takie jak instrukcje czy katalogi, były zgodne z wytycznymi WCAG, zapewniając tym samym ich pełną dostępność dla wszystkich użytkowników.  

Dodatkowe narzędzia pomocne przy wdrażaniu WCAG

Przystosowanie e-Sklepu do wymogów nie musi wiązać się z dużymi wydatkami na zmiany w kodzie. Kluczowe aspekty dostępności można wdrożyć samodzielnie, wykorzystując opcje dostępne w systemach Comarch ERP, a także Kreatorze Wyglądu czy Panelu Administracyjnym. Warto pamiętać, że poprawa dostępności to nie tylko obowiązek wynikający z przepisów, ale także realna szansa na zwiększenie grona klientów oraz podniesienie komfortu ich zakupów. Istnieje kilka ogólnodostępnych narzędzi, które pomogą Ci dostosować sklep do wymogów. Obszerna lista narzędzi do oceny dostępności stron internetowych, zgodnych z WCAG znajduje się na stronie: Web Accessibility Evaluation Tools List .  

Podsumowanie

Dostępność cyfrowa to nie jednorazowe przedsięwzięcie, lecz ciągły rozwój i udoskonalanie. Regularne sprawdzanie funkcjonalności, optymalizacja elementów wizualnych i dostosowywanie sposobów interakcji pozwalają na stałe podnoszenie jakości doświadczeń użytkowników. Dążenie do pełnej zgodności ze standardami WCAG 2.1/2.2 oraz wymogami Europejskiego Aktu o Dostępności (EAA) nie tylko ułatwia nawigację wszystkim odwiedzającym, ale także buduje pozytywny wizerunek i wzmacnia pozycję na rynku. Wdrażanie kolejnych usprawnień to inwestycja w przyszłość, która przynosi korzyści zarówno właścicielom, jak i ich klientom.

Bannery

Wskazówka
Od 1 czerwca 2025 roku zakończyliśmy aktualizację oraz wydawanie nowych wersji szablonów Bursztyn, Agat i Opal, a tym samym ich wsparcie, aby skupić się na nowoczesnych rozwiązaniach, które jeszcze lepiej odpowiadają na potrzeby dynamicznie rozwijającego się rynku e-commerce. Zachęcamy Was do przejścia na nasze nowe, udoskonalone szablony. Dla sklepów B2C polecamy szablony Topaz, One Page Shop oraz Dla Gastronomii, natomiast dla platform B2B idealnym wyborem będą Rubin i Szafir.

Banner jest jednym z nośników treści reklamowych. Wystarczy, że przygotujesz obrazek, który przyciągnie wzrok klienta i dobrać do niego odpowiedni tekst promocyjny, a Twój sklep stanie się bardziej atrakcyjny dla klientów.

Edycja bannerów

Modyfikacja domyślnych bannerów dostępnych w szablonach Comarch dostępna jest w Panelu administracyjnym w obszarze Wygląd sklepu/ Ustawienia/ Bannery.

Wybierz banner, który chcesz edytować i kliknij w niego.

Przykładowa lista bannerów w szablonie Topaz

Wyświetlone zostanie okno, w którym możesz uzupełnić nazwę, opis oraz dodać lub zmienić zdjęcia. Edycja kolejności zdjęć w bannerze zarówno w widoku podstawowym i zaawansowanym jest możliwa przy użyciu metody "przeciągnij i upuść".

ban1

Aby móc uzupełnić więcej szczegółów dotyczących bannerów, rozwiń opcję Widok zaawansowany. Pojawi się wtedy panel, w którym można zmienić np. tekst na bannerze, nagłówek, czas jego wyświetlania, link do którego kieruje dany obrazek, a także tooltip i tekst alternatywny. Pole Tekst oraz Link pojawi się po dodaniu obrazka i rozwinięciu widoku zaawansowanego. Pamiętaj, aby zapisać zmiany ikoną dyskietki. Wszystkie zmiany w bannerach należy zatwierdzić opcją Publikuj dostępną w menu rozwijanym Więcej na liście bannerów.

hy

Wskazówka

Rekomendowane rozmiary obrazków w bannerach dla szablonów Comarch:

  • szablon Szafir: Bannery – przy tworzeniu wyglądu szablonu Szafirz w Kreatorze wybieramy ułożenie bannerów spośród sześciu opcji: Wygląd Sklepu/Ustawienia/Bannery/kafelki homepage
    • Banner 1: rekomendowana proporcja obrazków 3:1 (1500 px x 500 px). W celu zachowania dobrej jakości zdjęć na ekranach o wysokiej rozdzielczości ekranu, zalecamy dodawanie obrazków w jednakowej wielkości. Bannery umieszczone nad stopką powinny być tej samej skali, np. 100×100 i 200×200 lub 400×200 i 800×400 itd
    • Banner 2: 1255px x780px, 2x 620px x 380px
    • Banner 3: 2x 635px x 290px, 2x 840px x 290px
    • Banner 4: 1270px x 580px, 2x 635px x 290px,
    • Banner 5: 2x 735px x 390px,
    • Banner 6: 3x 480px x 385px;

  • szablon Topaz: Bannery – przy tworzeniu wyglądu szablonu Topaz w Kreatorze wybieramy ułożenie bannerów spośród sześciu opcji: Wygląd Sklepu/Ustawienia/Bannery/kafelki homepage
    • Banner 1: 1255px x 780px, 2x 620px x 380px,
    • Banner 2: 1920px x 680px,
    • Banner 3: 2x 635px x 290px, 2x 840px x 290px
    • Banner 4: 1270px x 580px, 2x 635px x 290px,
    • Banner 5: 2x 735px x 390px,
    • Banner 6: 3x 480px x 385px;

Dodatkowo możliwa jest konfiguracja obrazków w obrębie różnych urządzeń - dodatkowa konfiguracja grafik dla ekranów tabletu i telefonu jest możliwa po kliknięciu w obrazek w ramach edycji konkretnego banneru.

 

Za pomocą ikony plusa jest możliwe dodanie dopasowanych zdjęć względem ekranów różnych urządzeń: W przypadku jeżeli nie ma dodanych wskazanych obrazków dla tabletu czy telefonu, na urządzeniach mobilnych wyświetla się obrazek dodany dla ekranów komputera.

Zalecane rozmiary dla wskazanych bannerów według tego ustawienia prezentują się następująco:

Banner Ekran komputera Ekran tabletu Ekran telefonu
Banner 1 1255px x 780px, 2x 620px x 380px 840px x 520px, 2 x 420px x 255px 3x 770px x 475px
Banner 2 1920px x 680px 1280px x 455px 3x 770px x 275px
Banner 3 635px x 290px, 2x 840px x 290px 545px x 255px, 2x 720px x 255px 770px x 360px, 2x 770px x 275px
Banner 4 1270px x 580px, 2x 635px x 290px 845px x 385px, 2x 425px x 195px 3x 770px x 230px
Banner 5 2x 735px x 390px 2 x 630px x 365px 3x 375px x 200px
Banner 6 3x 480px x 385px 3x 415px x 330px 3x 770px x 615px

    • Rekomendowany rozmiar banneru, który pokazuje się po rozwinięciu kategorii (menuBanner) wynosi
              • header1: 220×295 px,
              • header2: 220×295 px
              • header3: 1118 x 534 px

konfiguracji można dokonać z poziomu: Wygląd Sklepu/ Ustawienia /Bannery/ menuBanner,

    • Rekomendowany rozmiar banneru, który pokazuje się na stronie Kontakt wynosi: 610px x 605px - Wygląd Sklepu/Ustawienia/Bannery/contactBanner,
    • Rekomendowane rozmiary bannerów, które pokazują się na stronie Lookbook wynoszą: 2x 560px x 630px, 700px x 850px, 1260px x 540px, 630px x 950px - Wygląd Sklepu/Ustawienia/Bannery/lookbook,
    • Rekomendowany rozmiar banneru, który pokazuje się na zakładce Promocje, po otworzeniu sekcji Profil klienta wynosi: 1920px x 680px -  Wygląd Sklepu/Ustawienia/Bannery/ CustomerProfileBanner,
    • Rekomendowany rozmiar zdjęć towaru wynosi: 660px x 630px;
  • szablon Bursztyn: 1920 px x 608 px
  • szablon Opal:  banner główny: 1840 px x 578 px, mniejsze zdjęcia pod bannerem głównym: 904 px x 487 px
  • szablon Agat: rozmiar obrazka dowolny z zachowaniem proporcji 2:1 np. 1200 px x 600 px. W celu zachowania dobrej jakości zdjęcia na ekranach o wysokiej rozdzielczości ekranu, rekomendujemy zdjęcia o rozdzielczości nie mniejszej niż 1140 px x 570 px

Typy bannerów dla szablonów Topaz i Szafir (B2B)

W panelu administracyjnym dodany jest nowy banner o nazwie top, a jego treść brana jest z pola Tekst. Banner pojawia się jako wąski pasek na górze strony. Gdy dodasz adres strony, produktu, promocji lub innego przekierowania w polu Link, po kliknięciu na banner zostanie otworzona odpowiednia strona przypisana do tego banneru. Pamiętaj, aby wprowadzone zmiany zapisać oraz opublikować. W panelu administracyjnym w zakładce Wygląd sklepu/ Ustawienia/ Motyw kolorystyczny znajdują się trzy pola, w których możemy w łatwy sposób zmienić kolory naszego banneru. Pola nazywają się:

  • Kolor tła w bannerze 'Top’,
  • Kolor czcionki w bannerze 'Top’,
  • Kolor czcionki w bannerze 'Top’ po najechaniu.
Wskazówka
Top banner jest widoczny w e-Sklepie dopiero po dodaniu obrazka. Kolor oraz rodzaj pliku nie ma wpływu na kolor lub wygląd banneru.

Dodatkowo w szablonie Szafir został dodany kolejny banner wyświetlany na stronie głównej. Jeśli jest włączona opcja dostępu do sklepu dla zalogowanych kontrahentów to wówczas ukazuje się tylko ten banner. Jeżeli nie został on skonfigurowany, to wówczas widoczny jest domyślnie standardowy banner główny.

Dodawanie bannerów

Nowy banner możesz dodać z poziomu listy bannerów klikając w kafelek z ikoną plusa w widoku kafelkowym lub klikając w przycisk Dodaj w widoku listy. W pojawiającym się oknie uzupełnij nazwę oraz opis banneru, a także zdjęcia, które będą widoczne w sklepie.

gf

Po dodaniu zdjęcia pojawi się możliwość włączenia widoku zaawansowanego, w którym możesz uzupełnić szczegółowe dane. Długość linku dodawanego do slajdu w bannerze może wynosić maksymalnie 500 znaków.

c

Wskazówka
Po uzupełnieniu komórki link, dla banneru w szablonie Topaz (w widoku zaawansowanym) – cały baner staje się „klikalny”, to znaczy, że w przypadku kliknięcia na baner zostanie wykonane przekierowanie do określonego wcześniej linku. W przypadku uzupełnienia komórki: link oraz tekst – na bannerze zostanie wyświetlony przycisk Sprawdź.

Banner, który ma się wyświetlać na stronie głównej powinien zostać nazwany homepage. Po uzupełnieniu wszystkich potrzebnych informacji, należy je zatwierdzić przyciskiem Dodaj. Tak przygotowany banner należy następnie zaimplementować w kodzie szablonu. Nowo dodane bannery nie zaimplementowane w kodzie szablonu nie będą widoczne w e-Sklepie, ponieważ w kodzie szablonu istnieją odniesienia do domyślnych bannerów takich jak np. homepage czy promotionalbanners.

Import i eksport bannerów

W e-Sklepie istnieje możliwość importu i eksportu bannerów bez sprawdzania limitu danych. Dzięki temu możesz przenosić ich dużą ilość bez nadmiernego obciążania szablonu.

Aby zaimportować szablon przejdź do panelu administracyjnego, a następnie do sekcji Wygląd sklepu/ Ustawienia/ Więcej (trzy kropki w prawym górnym rogu), po czym przejdź do Edytuj ustawienia zaawansowane/ Import z pliku XML.

Szablon zaimportujesz klikając przycisk Wybierz plik XML. Aby zmienić bannery zaznacz podmień istniejące bannery. Opcja ta zastępuje dotychczasowe bannery widniejące na stronie e-sklepu. Zmiany zatwierdzić opcją Publikuj, dostępną w menu rozwijanym Więcej. Zaimportowane bannery możesz zobaczyć w panelu administracyjnym, przechodząc do Wygląd sklepu/ Ustawienia/ Bannery. 

Eksport bannerów dokonuje się w Panelu Administracyjnym w Wygląd sklepu/ Ustawienia/ Więcej (trzy kropki w prawym górnym rogu)/ Edytuj ustawienia zaawansowane/ Eksport do pliku XML. Tak należy kliknąć w Eksportuj bannery i zostanie pobrany plik XML.

Wskazówka
Dodatkowe informacje na temat wyświetlających się bannerów znajdują się w artykułach:

Jak zarządzać elementami na liście towarów z panelu administracyjnego?

Wstęp

Dzięki nowej funkcjonalności, użytkownicy Panelu Administracyjnego będą mogli edytować i aktualizować elementy listy towarów bez potrzeby korzystania z Kreatora Wyglądu. To rozwiązanie zaprojektowano z myślą o szablonie Topaz, współpracującego z każdą wersją Comarch e-Sklepu. Nowa funkcjonalność nie tylko zwiększy wygodę użytkowania, ale także przyczyni się do optymalizacji czasu pracy. W niniejszym artykule przybliżymy szczegóły tego rozwiązania.

Zarządzanie elementami na liście towarów

W wersji 2024.6.1 Comarch e-Sklepu dla szablonu Topaz dodano funkcjonalność zarządzania elementami na liście towarów wprost z Panelu Administracyjnego Comarch e-Sklepu. Aby to zrobić, należy w Panelu Administracyjnym przejść do obszaru Wygląd sklepu (1) > Ustawienia (2) następnie kliknij w kartę Zarządzanie elementami na liście towarów (3) znajdującą się nad kaflami motywów kolorystycznych szablonu:

Jakie obszary są możliwe do zmiany?

  • Domyślny sposób wyświetlania towarów na liście – możesz zdecydować w jaki sposób zaprezentowane będą towary w Twoim e-Sklepie, domyślny widok to Kafelki;
  • Wyświetlaj zdjęcia 360° na liście towarów – domyślna wrtość: Tak;
  • Układ zdjęć kategorii na stronie „Produkty” – możesz wybrać układ zdjęć na stronie „Produkty”, domyślny jest układ listy;
  • Elementy w panelu filtrów (Kategorie, Cena, Producent, Marka, Dostępność, Ocena, Zdjęcia, Atrybuty, Atrybuty czasowe) – możesz wskazać, które będą widoczne w panelu filtrów;
  • Udostępnij zdjęcia podkategorii – możesz zdecydować o udostępnianiu zdjęć do podkategorii, domyślna wartość:Tak;
  • Lista elementów na stronie z listą towarów – w tym obszarze istnieje możliwość zmiany kolejności wyświetlania poszczególnych elementów na stronie głównej sklepu oraz ukrycia wybranych. Zmiany kolejności dokonasz poprzez kliknięcie strzałek w kolumnie „Kolejność„. Aby ukryć element wystarczy, że odznaczysz checkbox w kolumnie Dostępne. Możesz także w szybki sposób przejść do edycji poszczególnych elementów, wybierając opcję „Przejdź do edycji…„, a także edytować etykietę tłumaczenia.
 

Jak edytować nagłówek w szablonie B2C?

Wstęp

Nagłówek w e-Sklepie to stały element, umieszczony na górze ekranu lub na dole w wersji mobilnej. Jego głównym celem jest umożliwienie użytkownikom szybkiego dostępu do różnych sekcji witryny, takich jak: “Strona główna”, “O nas” czy “Kontakt”. Dzięki opcji edycji nagłówka możesz prosto i szybko:
  • dodawać, edytować, wyróżniać i usuwać strony lub grupy stron,
  • dodać, edytować lub usuwać odnośniki do mediów społecznościowych,
  • w jednym miejscu zmienić logotyp i favicon.
Możliwość edycji nagłówka dostępna jest dla szablonów B2C: Topaz, One Page Shop oraz Dla Gastronomii. Aby edytować zawartość nagłówka sklepu, należy przejść w panelu administracyjnym do obszaru: Wygląd sklepu  > Ustawienia > Nagłówek: W tym miejscu masz możliwość:
  • ustawienia logotypu i faviconu,
  • ustalenia, które media społecznościowe powinny wyświetlać się w nagłówku,
  • dodania stron lub grupy stron,
  • przejścia do konfiguracji menu kategorii.

Jak dodać logotyp i favicon?

Aby dodać logotyp i favicon, wybierz przycisk „Wyślij plik”, a następnie wybierz plik z odpowiedniego miejsca na Twoim komputerze.
Wskazówka
Pamiętaj, że w przypadku logotypu, maksymalny rozmiar obrazka wynosi 30 KB, a wymiary to 200 x 200px. Rekomendowane formaty: PNG, JPG, JPEG, SVG. W przypadku faviconu maksymalny rozmiar obrazka wynosi 10 KB, a rekomendowane formaty to: PNG, JPG, JPEG, SVG.

 

Jak edytować odnośniki do mediów społecznościowych?

Wskazówka
Miniatury z odnośnikami do mediów społecznościowych są widoczne w drugim i trzecim typie nagłówka (header-2 oraz header-3) w szablonie Topaz.
Aby edytować istniejący odnośnik do mediów społecznościowych, przejdź do szczegółów logotypu wybranego serwisu, który chcesz podłączyć do e-Sklepu. W miejscu "# " w kodzie wklej link do swojego portalu. Dzięki temu możliwe będzie przekierowanie użytkownika do konkretnego medium społecznościowego. Następnie zapisz zmiany. Aby dodać nowy odnośnik do mediów społecznościowych wystarczy, że naciśniesz ikonę plusa. Wyświetli się wówczas edytor, do którego należy wkleić analogiczny kod, jak w przykładzie prezentowanym powyżej. Fragment kodu należy skopiować z poziomu panelu administracyjnego. W miejscu "#"w kodzie wklej link do swojego portalu. Jeśli chcesz zmienić obrazek, to we fragmencie kodu w miejscu linku wklej swój odnośnik do wybranego zdjęcia. Może to być odnośnik skopiowany z pliku, który znajduje się w Plikach użytkownika.
Wskazówka
W nagłówku wyświetli się pięć pierwszych ikon mediów społecznościowych, które zostały dodane w panelu administracyjnym.
 

Jak dodać strony lub grupy stron?

Z poziomu obszaru Wygląd sklepu > Ustawienia > Nagłówek możesz dodać Stronę lub Grupę stron. Aby to zrobić, należy wybrać sekcję "Dodaj stronę lub grupę stron". Po wybraniu tej opcji wyświetli się następujący popup: Z poziomu popupu należy zaznaczyć parametr: Stronę lub Grupę stron i uzupełnić obowiązkowe pole "Nazwa". Następnie, aby dodać odnośnik do strony, należy edytować dodaną stronę lub grupę.  Podczas edycji w panelu administracyjnym wyświetli się obszar, w którym możliwe jest dokonanie zmian. Możesz zdecydować, czy do strony lub grupy stron dodasz już istniejącą stronę ze sklepu, czy stronę zewnętrzną: Po wyborze opcji "Dodaj stronę ze sklepu" pokaże się popup z listą stron, które można wybrać i dodać do sekcji. Możesz także dodać stronę zewnętrzną, uzupełniając pola na formularzu: Przy dodanym odnośniku możesz zdecydować, czy chcesz go wyróżnić, otworzyć w nowej karcie, czy usunąć.   Wprowadzone zmiany należy zapisać i opublikować. Poniżej prezentujemy efekt wprowadzonych konfiguracji (dodanie mediów społecznościowych, grupy stron oraz wyróżnienia):
Topaz header-2
Topaz header-2
 
Topaz header-3
Topaz header-3
   

Jak automatycznie ustawić język sklepu w oparciu o język przeglądarki?

W tym artykule dowiesz się jak włączyć funkcję, aby po wejściu do sklepu ustawiał się język ustawiony przez Klienta w przeglądarce. Funkcja ta działa tylko dla sklepów wielojęzycznych.
Wskazówka
Sklep wielojęzyczny to taki, w którym oprócz języka domyślnego, aktywny jest przynajmniej jeden dodatkowy język w zakładce Ustawienia > Ustawienia sklepu > Dane sklepu > Języki
Odtworzenie języka z poprzedniej sesji będzie miało priorytet nad domyślnymi ustawieniami przeglądarki. Oznacza, to że język wybrany podczas ostatniej wizyty użytkownika zostanie zachowany przy kolejnej wizycie, niezależnie od domyślnych ustawień językowych przeglądarki. Funkcja dostępna dla najnowszej wersji szablonów z Kreatora wyglądu. Aby skorzystać z tej funkcji, przejdź w panelu administracyjnym do sekcji Wygląd Sklepu > Ustawienia > Ogólne            

Logotyp oraz favicon w Comarch e-Sklep

Logotyp e-Sklepu stanowi jeden z elementów identyfikacji wizualnej i jednocześnie jest jej najważniejszą częścią. Dzięki logo firma lub produkt są łatwiejsze do zidentyfikowania przez odbiorcę.

Logo i favicon. Jak je zmienić?

Jak wgrać własny logotyp w e-Sklepie?

Krok 1. W panelu administracyjnym przejdź do sekcji Ustawienia/Ustawienia sklepu/Dane sklepu/. Krok 2. Wybierz plik i zapisz zmiany.  
Uwaga
Maksymalny rozmiar obrazka wynosi 30 KB, wielkość to 200 x 200 px oraz musi być on w formacie *.PNG, *.JPG, *.JPEG, *.SVG.

Jak wgrać favicon?

Logo sklepu można również umieścić w ikonie strony internetowej, która prezentuje się w nagłówku przeglądarki,w wynikach wyszukiwania przy tytule strony, na pasku ulubionych zakładek tzw. favicon. Krok 1. Przejdź do sekcji Wygląd sklepu/zakładka Nagłówek/Stopka. Krok 2. Wgraj własny favicon dla swojego e-Sklepu i zapisz zmiany.
Uwaga
Uwaga! Maksymalny rozmiar obrazka to 10 KB.
 

Tworzenie filtrów na liście kategorii w e-Sklepie

Wstęp

Dobrze skonfigurowane filtry w znacznym stopniu uproszczą i skrócą proces wyszukiwania poszczególnych produktów , co z pewnością przełoży się na pozytywny odbiór i częstsze zakupy w Twoim e-Sklepie. Dodanie nowego filtra odbywa się poprzez utworzenie nowego atrybutu w systemie ERP, a następnie odpowiednie przyporządkowanie go grupy towarowej.

Comarch Betterfly

Poniżej znajdziesz kroki, które w łatwy i szybki sposób pomogą Ci utworzyć nowe filtry kategorii w Twoim e-Sklepie.

Krok 1. Na początku musimy utworzyć Atrybuty, które mają być widoczne na Twojej liście filtrów. Logujemy się do panelu administracyjnego Twojego systemu Comarch Betterfly. Rozwijamy zakładkę Więcej funkcji i klikamy w Comarch e-Sklep.  W nowym widoku wchodzimy w Atrybuty w Comarch e-Sklep,

a następnie w górnym prawym roku ikonę Dodaj.

 Krok 2. W sekcji Nazwa uzupełnij nazwę atrybuty dla każdego języka osobno, a następnie wciśnij przycisk Zapisz zmiany.

Krok 3. Teraz musisz przyporządkować powstałe atrybuty do konkretnej grupy, żeby posłużyły Ci jako filtry kategorii na liście towarowej. W zakładce Więcej funkcji/ Comarch e-Sklep/  Grupy w Comarch w e-Sklep,

a następnie kliknij lewym przyciskiem myszki w grupę na, której mają się wyświetlać dodatkowe filtry.

Krok 4. W sekcji Atrybuty kliknij w pole nazwa atrybutu. Wyskoczy Ci lista wszystkich dodanych atrybutów. Wybierz tylko te, które chcesz mieć widoczne na swojej liście towarowej.

  Krok 5. Kolejne zmiany będą dokonywane już na karcie towaru. Produkty będą widoczne w twoich filtrach dopiero po dodaniu ich w sekcji: Atrybuty zwykłe. Atrybuty muszą zostać wybrane takie same jak w kroku 4. W tym artykule znajdziesz więcej informacji odnośnie konfiguracji produktów z twoim e-Sklepie: Skonfiguruj swój pierwszy produkt i wyślij go do e-Sklepu 
Przyklad
Jak dodamy atrybuty zgodnie z poniższym zdjęciem to produkt będzie widoczny we wszystkich trzech filtrach. Widok z e-Sklepu po synchronizacji i wybraniu odpowiednich filtrów:
Krok 6. Po wykonaniu powyższych kroków wykonaj synchronizację danych i sprawdź, jak wyglądają nowe filtry w Twoim e-Sklepie.

Comarch ERP Optima

Jak utworzyć filtr?

Poniżej znajdziesz kroki, które w łatwy i szybki sposób pomogą Ci utworzyć nowe filtry kategorii w Twoim e-Sklepie.

Krok 1. Na początku musimy utworzyć Atrybuty, które mają być widoczne na Twojej liście filtrów. Z poziomu ERP Optima W zakładce Ogólne/ Atrybuty otwórz Listę atrybutów i ikoną plusa dodaj nowy atrybut.

Krok 2. W zakładce Ogólne uzupełnij formularz wpisując Kod i Nazwę atrybutu, wybierz format: Lista oraz udostępnij atrybut w e-Sklepie/e-Sale.

Krok 3. Uzupełnij zakładkę Pozycje listy podając wartości dla atrybutu, a następnie zapisz zmiany dyskietką :

Krok 4. Teraz musimy przyporządkować powstałe atrybuty do konkretnej grupy, żeby posłużyły nam jako filtry kategorii na liście towarowej W zakładce Ogólne/ Cennik otwórz Grupę towarową (klikając dwa razy w wybraną grupę).

Krok 5. W sekcji Atrybuty używając plusa   dodaj nowy atrybut do grupy towarowej.

Krok 6. Dodaj atrybut wpisując jego nazwę lub wybierając atrybut z listy (klikając na parametr Atrybut). Po dodaniu atrybutu zapisz zmiany klikając w dyskietkę.

Wskazówka
Nie przypisuj wartości do atrybutu na grupie towarowej - wartość atrybutu jest pobierana z karty towarowej. W tym celu należy dodać ten sam atrybut z wartością na danym towarze.

Jak dodać atrybut do towaru?

Krok 1. Kolejne zmiany będą dokonywane już na karcie towaru. Na wybranym towarze przejdź na zakładkę Atrybuty, dodaj nowy atrybut i zapisz zmiany

Krok 2. Wybierz wartość dla wybranego atrybutu i zaznacz parametr "udostępnij w Comarch e-Sklep/e-Sale". Po wykonanych czynnościach zapisz zmiany

Krok 3. Wykonaj synchronizację do e-Sklepu z poziomu Comarch ERP Optima. Teraz możesz wejść do swojego e-Sklepu i zobaczyć swoje nowo dodane filtry.

Comarch ERP XL

Jak utworzyć filtr?

Krok 1. Na początku musimy utworzyć Atrybuty, które mają być widoczne na Twojej liście filtrów. Z poziomu ERP XL w sekcji Administrator, w zakładce Narzędzia/ Atrybuty otwórz Atrybuty i ikoną folderu z zielonym plusem dodaj nową klasę atrybutów.

Krok 2. W zakładce Ogólne uzupełnij formularz wpisując Nazwę atrybutu, wybierz Typ: Lista oraz udostępnij atrybut parametrem e-Sklep.

A, w zakładce Obiekty dodaj do obiektów klasy towarowe.

Krok 3. Uzupełnij formularz Definicje atrybutów podając wartości dla atrybutu, a następnie zapisz zmiany .

Krok 4. Teraz musimy przyporządkować powstałe atrybuty do konkretnej grupy towarowej, aby posłużyły nam jako filtry kategorii na liście towarów. W menu głównym ERP XL otwórz sekcję Sprzedaż, a następnie w zakładce Ogólne/ Towary otwórz Grupę towarową (klikając dwa razy w wybraną pozycję).

Krok 5. W formularzu Wzorca towaru (grupa Bakalie) w zakładce Atrybuty używając plusa dodaj nowy atrybut do grupy towarowej.

Krok 6. Dodaj klasę atrybutu wybierając go z listy i zatwierdź go zaznaczoną ikoną.

Wskazówka
Nie przypisuj wartości do atrybutu na grupie towarowej – wartość atrybutu jest pobierana z karty towarowej. W tym celu należy dodać ten sam atrybut z wartością na danym towarze.

Krok 7. Nie zapomnij w zakładce Aplikacje zaznaczyć parametr e-Sklep.

Jak dodać atrybut do towaru?

Krok 1. Kolejne zmiany będą dokonywane już na karcie towaru. Na wybranym towarze przejdź na zakładkę Atrybuty, dodaj nowy atrybut i zapisz zmiany.

Krok 2. Wybierz wartość dla wybranego atrybutu i zapisz zmiany.

Krok 3.Wykonaj synchronizację do e-Sklepu z poziomu Comarch ERP XL. Teraz możesz wejść do swojego e-Sklepu i zobaczyć swoje nowo dodane filtry.

Comarch ERP Altum

Jak utworzyć filtr?

Krok 1. Zaczynamy od utworzenia nowego atrybutu, który będzie widoczny na Twojej liście filtrów. Z poziomu ERP Altum w sekcji Konfiguracja, w zakładce Atrybuty i klikamy w plus, żeby dodać nową klasę atrybutu.

Krok 2. Wpisujemy Nazwę atrybutu, następnie wybieramy Typ: Lista oraz udostępniamy atrybut parametrem e-Sklep/Podgląd. Dodatkowo trzeba pamiętać, że parametr Aktywny musi być włączony.

Krok 3. Zdefiniujemy teraz nowe wartości dla atrybutu, który dodaliśmy. Należy zaznaczyć go na liście atrybutów, a następnie w sekcji Lista wartości atrybutu wybrać przycisk [Dodaj].

Krok 4. Przejdź teraz do zakładki Lista oddziałów i wybierz obiekt Grupa artykułów. Na dole pojawi Ci się nowo dodany atrybut. Kliknij w niego a następnie Powiąż i zapisz zmiany

Krok 5. Następnie przyporządkuj powstałe atrybuty do konkretnej grupy towarowej, aby posłużyły nam jako filtry kategorii na liście towarów. W menu głównym ERP Altum wybieramy sekcje Artykuły, a następnie wybieramy kategorie, do której mamy dodać wcześniej dodane atrybuty (klikając dwa razy w wybraną pozycję).

Krok 5. W oknie, które się otworzy, przejdź do zakładki Atrybuty i używając plusa dodaj nowy atrybut do grupy towarowej. Po dodaniu zapisujemy zmiany

Krok 6. Przechodzimy teraz do zakładki Oddziały i wykonujemy synchronizację. Jeśli chcemy, żeby nowe atrybuty były widoczne w e-Sklepie to musimy wybrać obiekt Artykuł.

Jak dodać atrybut do towaru?

Krok 1. Kolejne zmiany będą dokonywane już na karcie towaru. Na wybranym towarze przejdź na zakładkę Atrybuty, dodaj nowy atrybut, wybieramy właściwy z listy i klikamy wybierz.

Krok 2. Wybierz wartość dla wybranego atrybutu i zapisz zmiany.

Krok 3. Wykonujemy teraz synchronizację e-Sklepu z Comarch ERP Altum. Teraz możesz wejść do swojego e-Sklepu i zobaczyć swoje nowo dodane filtry.

Jak skonfigurować Lookbook w Comarch e-Sklep?

Wskazówka
Od 1 czerwca 2025 roku zakończyliśmy aktualizację oraz wydawanie nowych wersji szablonów Bursztyn, Agat i Opal, a tym samym ich wsparcie, aby skupić się na nowoczesnych rozwiązaniach, które jeszcze lepiej odpowiadają na potrzeby dynamicznie rozwijającego się rynku e-commerce. Zachęcamy Was do przejścia na nasze nowe, udoskonalone szablony. Dla sklepów B2C polecamy szablony Topaz, One Page Shop oraz Dla Gastronomii, natomiast dla platform B2B idealnym wyborem będą Rubin i Szafir.

Lookbook - czym jest i jak do wykorzystać?

Chociaż lookbook został stworzony głównie z myślą o świecie mody, to można w nim prezentować towary z dowolnych kategorii. Może to być zarówno seria zdjęć z kolekcją ubrań, jak i zdjęcie ścianki warsztatowej, na której zaznaczono dostępne w sklepie narzędzia. Dodatkowo, na zamieszczonych fotografiach możliwe jest dodanie odnośników kierujących do konkretnych produktów sprzedawanych w e-Sklepie. W przypadku e-Sklepu lookbookiem można nazwać zbiór fotografii przedstawiających konkretną kategorię produktową. Towary prezentowane na zdjęciach powinny być odpowiednio wyeksponowane. Żeby produkt skutecznie przyciągał uwagę zaleca się, aby zdjęcia były wykonywane na neutralnym tle, które będzie odpowiednio komponowało się ze stroną sklepu. Dzięki lookbookowi możesz przedstawić Klientowi np. odpowiednie zastosowanie swoich produkt i tym samym inspirować ich. Dodatkowo funkcja ta pozwala na promowanie wielu towarów w bardzo atrakcyjnej formie.

Konfiguracja lookbooka w panelu administracyjnym

Niektóre szablony, takie jak Opal czy Topaz, domyślnie posiadają skonfigurowany banner jako lookbook. Oznacza to, że nie musisz tworzyć specjalnie dodatkowej sekcji.

W przypadku innych szablonów lookbook może wiązać się z dodaniem nowego banneru. Aby dodać lookbook do swojej strony należy zalogować się do panelu administracyjnego i postępuj zgodnie z poniższą instrukcją: Krok 1. Przejdź do sekcji Wygląd sklepu/ Ustawienia/ Bannery. Jeżeli nie masz sekcji bannerowej o nazwie lookbook naciśnij przycisk plusa, aby dodać nowy banner.

Jeżeli masz taką sekcję przejdź do jej edycji.

Krok 2. Wprowadź nazwę dla nowego lookbooka. Następnie naciśnij dodaj.

Krok 3. Po wpisaniu nazwy nowego banneru wyświetla się nowy formularz. W tym miejscu masz możliwość dodania opisu dla administratora oraz obrazków do katalogu.

Uzupełnij wszystkie pola i zaznacz opcję lookbook.

  • Nazwa – wprowadź tu nagłówek dla swojego Lookbooka,
  • Link – wprowadź przyjazną treść w linku dla lookbooka – wyświetli się ona, gdy dodasz w swoim sklepie więcej niż jeden lookbook.

Jeżeli powyższe kroki zostały wykonane, to możesz przejść do dodawania obrazków. Po dodaniu obrazków istnieje również możliwość uzupełnienia szczegółów dotyczących konkretnego zdjęcia. Aby dokonać modyfikacji w tym obszarze przejdź w Widok zaawansowany.

Po kliknięciu w odnośnik pojawi się panel, w którym można zmienić np. tekst na bannerze, nagłówek, czas jego wyświetlania, link do którego kieruje dany obrazek, a także tooltip i tekst alternatywny.

Jak oznaczyć towary na zdjęciu w lookbooku?

Krok 1. Dodaj zdjęcie dla swojego lookbooka. Krok 2. Przejdź do jego szczegółów. Krok 3. Kliknij na zdjęciu w miejsce, dla którego chcesz oznaczyć towar. Otworzy Ci się nowy popup, w którym wybierzesz towar ze swojej bazy. Gotowe! Dla wybranej grafiki zostały oznaczone towary. Przechodząc do lookbooka w szablonie Topaz, kiedy klikniesz w ikonę "plusa" znajdującą się na danym towarze, masz możliwość dodania tego towaru do koszyka, a ikoną serduszka dodasz towar do ulubionych.

Lookbook w sklepie demonstracyjnym https://demo-topaz.comarchesklep.pl/

Wskazówka
Konfiguracja lookbooka jest taka sama dla wszystkich szablonów Comarch. Każdy z nich posiada jednak odmienny widok i sposób oznaczenia towarów. Niżej możesz zobaczyć, jak wyglądają lookbooki w poszczególnych szablonach Comarch.

Lookbook w Szablonie Topaz

Szablon Topaz dedykowany sprzedaży detalicznej posiada dwa widoki lookbooka do wyboru: mozaikę lub listę. Aby zdecydować jaki widok jest dla Ciebie odpowiedni przejdź do zakładki Wygląd Sklepu/ Ustawienia i w sekcji Ustawienia lookbooka wybierz jeden z dostępnych widoków:
  • Widok typu Lista
Widok ten charakteryzuje się prezentacją zdjęć jedno pod drugim, w dwóch równoległych kolumnach. W tym widoku masz możliwość precyzyjnego oznaczenia towarów na bannerze i umożliwić dzięki temu ich zakup bezpośrednio z sekcji lookbook. Służą do tego znaczniki, które dodasz w dowolnym miejscu na obrazku podczas konfiguracji. Dodatkowo Twoi Klienci będą mogli swobodnie dodawać oznaczone towary do ulubionych w swoim profilu.
Wskazówka
Rekomendowany rozmiar bannerów do loobooka w widoku lista wynoszą: 620px x 620px. Pamiętaj, że każdy obrazek powinien mieć nie więcej niż 500 KB. Ilość znaczników jaką możesz dodać zależna jest od pola Lookbook json, które może zmieścić maksymalnie 3000 znaków. 
Widok typu Lista – Lookbook w szablonie Topaz

Po kliknięciu w znacznik pokaże się kafel ze zdjęciem i ceną towaru.

Jeśli towar jest fantomem, to po kliknięciu w przycisk „Kup teraz” pojawi się popup z atrybutami do wyboru.

Widok lookbooka w formie listy możesz zobaczyć w naszym sklepie demonstracyjnym.
  • Widok typu mozaika
Widok typu mozaika charakteryzuje się różnorodnym rozmieszczeniem grafik w odmiennych rozmiarach – tworząc tytułową mozaikę. Na każdej grafice możesz oznaczyć towary, które są dostępne do kupienia w Twoim e-Sklepie. Z tego poziomu Klient będzie mógł w szybki sposób przejść do szczegółów towaru i poznać szczegóły na jego temat.
Wskazówka
Rekomendowany rozmiar bannerów w lookbooku dla widoku mozaika to kolejno: 560px x 630px, 700px x 850px, 1260px x 540px, 630px x 950px, 560px x 630 px. Pamiętaj, że każdy obrazek powinien mieć nie więcej niż 500 KB.
Widok typu Mozaika - Lookbook w szablonie Topaz
Oznaczone towary w lookbooku z widokiem mozaika - szablon Topaz
Widok lookbooka w formie mozaiki możesz zobaczyć w naszym sklepie demonstracyjnym. Jeżeli chcesz posiadać kilka stron Lookbook wybieranych z listy w Twoim nagłówku, to w sekcji z bannerami dodaj kolejny Lookbook a następnie włącz odpowiednie ustawienie w Wygląd sklepu/ Ustawienia/ Ustawienia szablonu/ Ogólne:
Wskazówka
Wskazana funkcjonalność nie jest dostępna w nagłówku header-5, ponieważ tam nie występuje zakładka Lookbook w nagłówku
Dzięki niemu zyskasz rozbudowaną zakładkę z Lookbookiem w swoim sklepie internetowym, który będzie prezentował się następująco: Jeśli chcesz, żeby Twoi Klienci mogli dodać wszystkie towary z Lookbooka do koszyka, to w zakładce Wygląd sklepu/ Ustawienia/ Ustawienia szablonu/ Ogólne zezwól na dodawanie towarów do koszyka. 
Wskazówka
Ikona koszyka pojawi się w Lookbooku jeśli wszystkie towary do niego dodane, będę proste i dostępne w sklepie. Towar prosty po dodaniu go w zakładce Wygląd sklepu/ Ustawienia/ Bannery/ Lookbook będzie miał parametr hasAttributes: false
 

Lookbook w Szablonie Szafir

Aby sekcja lookbook mogła być widoczna na głównej stronie Twojego e-Sklepu to musisz w pierwszej kolejności aktywować go w pasku nawigacji. W tym celu przejdź do zakładki Wygląd sklepu/ Ustawienia/ Strona główna  i zaznacz sekcję lookbook.
Lista kilku lookbooków w szablonie Szafir
Jak wygląda lookbook w szablonie Szafir możesz zobaczyć w naszym sklepie demonstracyjnym

Lookbook w Szablonie Opal

Widok lookbooka w szablonie Opal charakteryzuje się rozmieszczeniem zdjęć w formie mozaiki. Na grafikach można precyzyjnie oznaczyć towary, które z poziomu lookbooka można dodać bezpośrednio do koszyka. Jak wygląda lookbook w szablonie Opal możesz zobaczyć w naszym sklepie demonstracyjnym.

Lookbook w Szablonie Bursztyn

Widok lookbooka w szablonie Bursztyn charakteryzuje się prezentacją zdjęć jedno obok drugiego. Na bannerach można precyzyjnie oznaczyć towary i ilości, które z poziomu lookbooka można dodać bezpośrednio do koszyka.  

Oznaczone towary w lookbooku - szablon Bursztyn

Jak wykonać kopię bezpieczeństwa mojego szablonu?

Jak wykonać kopię bezpieczeństwa mojego szablonu?

Oprawa wizualna sklepu jest bardzo ważnym elementem podczas prowadzenia sprzedaży w sieci. Narzędzie Kreator Wyglądu Comarch e-Sklep umożliwia stworzenie własnych, niepowtarzalnych szablonów wedle preferencji i potrzeb użytkowników. W intuicyjnym narzędziu jakim jest Kreator, będziesz w stanie zaprojektować wszelkie niezbędne funkcje, takie jak stronę główną, listę towarów, szczegóły towaru oraz koszyk. Jeśli Twój projekt szablonu został zaimportowany do e-Sklepu oraz skonfigurowany wedle Twoich preferencji (dodanie grafik do bannerów, modyfikacje kolorystyczne) masz możliwość jego zapisania, co będzie stanowić kopię bezpieczeństwa. Kopia bezpieczeństwa to dane, które w każdej chwili można odtworzyć w przypadku ich utracenia (np. poprzez przypadkowe usunięcie) lub częstego wprowadzania zmian. Dane, jakie może zawierać kopia bezpieczeństwa to szablon, który wcześniej został przez nas wygenerowany wraz z bannerami. Zaleca się wykonywanie kopii zapasowych oraz zabezpieczenie ich hasłem. Każda wykonana kopia zapasowa powinna zostać zapisana w bezpiecznym i dogodnym dla Użytkownika miejscu.

Jak wykonać kopię bezpieczeństwa?

W Panelu Administracyjnym przejdź do sekcji Wygląd sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane, a następnie przejdź do zakładki Eksport szablonu. W pustych polach znajdujących się w zakładce Eksport szablonu, opcjonalnie przed eksportem możesz uzupełnić powyższe dane, tj. Autora szablonu, e-mail, telefon i stronę WWW sklepu. Aby wyeksportować szablon, kliknij Eksportuj szablon. Wyeksportowany plik jest w formacie XML, a jego nazwa zawiera szablon oraz wersję, co znacznie ułatwia zarządzanie kopiami bezpieczeństwa w przypadku wykonywania ich regularnie.

Jak wyeksportować bannery?

Bannery, które znajdują się w Twoim sklepie możesz również wyeksportować tworząc kopię bezpieczeństwa. W tym celu także musisz przejść do Wygląd sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane, a następnie do zakładki Eksport szablonu. Obok przycisku Eksportuj szablon, znajduje się przycisk Eksportuj bannery, który musisz kliknąć aby bannery, które posiadasz w e-Sklepie zostały weksportowane. Kopia bezpieczeństwa jest również zapisywana w formacie XML, a nazwa pliku wskazuje na szablon, wersję i zawartość bannerów.

Jak zabezpieczyć hasłem swój szablon?

Jeśli chcesz, aby Twój szablon został zabezpieczony hasłem, a znajomość hasła była niezbędna podczas zaimportowania tego szablonu do e-Sklepu, musisz w tym celu przejść w Panelu Administracyjnym do sekcji Wygląd sklepu/ Ustawienia/ Ustawienia zaawansowane, następnie do zakładki Szablon. W tym miejscu nadasz hasło dla swojego szablonu. Zgodnie z Polityką bezpieczeństwa haseł, hasło powinno:
  • Składać się z minimum 8 znaków,
  • Zawierać dużą literę,
  • Zawierać małą literę,
  • Zawierać cyfrę 0-9,
  • Zawierać znak specjalny – ‘!.+?;^]=-(&_)#=
Gotowe! Teraz Twój szablon został zabezpieczony hasłem. Jeśli wyeksportujesz szablon, który zabezpieczyłeś hasłem – podczas importu tego szablonu, będziesz musiał podać nadane wcześniej hasło. Jego brak uniemożliwi import szablonu, a podanie błędnego hasła spowoduje nieprawidłowe działanie szablonu po imporcie. Więcej informacji znajdziesz:

Jak dodać zdjęcia 360° dla moich towarów w Comarch e-Sklep?

Zdjęcia obrotowe 360° umożliwiają zaprezentowanie produktu z każdej strony. Dzięki nim klient może dokładniej obejrzeć produkt i tym samym dostrzec więcej detali. Fotografia obrotowa świetnie sprawdza się przy towarach, które posiadają wiele elementów lub oryginalną budowę. Aby dla swoich towarów zaprezentować zdjęcia w formie 360° musisz:
  • posiadać aktualną wersję (min. 2023.1.4) szablonu Topaz (B2C) lub Szafir (B2B),
  • posiadać odpowiednio przygotowane katalogi ze zdjęciami na zewnętrznym hostingu.
Domyślnie zdjęcia 360° widoczne są na liście towarowej i na szczegółach towaru. Jeśli chcesz ograniczyć wyświetlanie zdjęć przejdź do panelu administracyjnego do zakładki Wygląd sklepu/ Ustawienia/ Ogólne i znajdź parametr Wyświetlaj zdjęcia 360° na liście towarów, a następnie zmień parametr na Nie. Pamiętaj, aby po zmianie parametru zapisać i opublikować zmiany.  

Jak przygotować zdjęcia 360°, aby móc udostępnić je dla moich towarów?

Krok 1. Sfotografuj swój towar z różnych stron obracając się wokół jego osi - tworząc odpowiednią ilość zdjęć prezentującą towar z różnych stron. Krok 2. Zatytułuj kolejno przygotowane zdjęcia podając numer klatki: 1, 2, 3, 4, itd. Numeracja zdjęć będzie odpowiadać za kolejność prezentowanej klatki. Krok 3. Utwórz folder, w którym umieścisz przygotowane zdjęcia i udostępnij je na zewnętrznym serwerze, w celu uzyskania linku do katalogu. Tak przygotowany katalog udostępnisz następnie w formie atrybutu na towarze w swoim systemie Comarch ERP.

Jak dodać zdjęcie 360° dla mojego towaru w Comarch e-Sklep?

Krok 1. Przejdź do swojego systemu Comarch ERP i dodaj nowy atrybut o nazwie 360photo i typie tekst. Krok 2. Przejdź do edycji wybranego towaru i dodaj w odpowiednim miejscu nowy atrybut o nazwie 360photo. Jako wartość atrybutu wprowadź adres URL do zewnętrznego hostingu, na którym znajduje się katalog z przygotowanym zdjęciem w formacie 360°. Krok 3. Zapisz zmiany i wykonaj synchronizację danych. Gotowe! W Twoim e-Sklepie pojawiły się właśnie zdjęcia w formie 360°. Od teraz Twoi Klienci zobaczą sprzedawane towary z różnych stron.
Wskazówka
Do prawidłowego wyświetlania się zdjęcia 360° należy dodać wskazany wyżej atrybut na towarze nadrzędnym, tak żeby ścieżka do niego alfabetycznie była na pierwszym miejscu. Wskazane zdjęcie będzie widoczne na liście towarowej na ojcu oraz w galerii towaru. Jeśli towary podrzędne nie będą posiadały zdjęć 360°, to będą widoczne z towaru nadrzędnego. Dla każdego języka można dodać tylko jedno zdjęcie 360°.
Oznaczenie dostępności zdjęcia 360° na szczegółach towaru w szablonie Topaz
Oznaczenie dostępności zdjęcia 360° na szczegółach towaru w szablonie Topaz
Podgląd zdjęcia 360° na szczegółach towaru w szablonie Topaz
Zobacz jak prezentuje się zdjęcie w formacie 360° w jednym z naszych sklepów demonstracyjnych.

Rozbudowana stopka w szablonach Topaz i Szafir - jak ją skonfigurować?

Wstęp

Stopka to jeden z podstawowych elementów każdego sklepu internetowego. Oprócz wymaganych informacji, które muszą się w niej znaleźć, może zawierać zbiór innych odniesień do konkretnych sekcji w Twoim e-Sklepie, do Twojego bloga lub profili w social mediach. Odnośniki mogą pozytywnie wpływać na wizerunek Twojego sklepu, przyczyniając się do wsparcia sprzedaży i generując większy ruch na stronie. W Kreatorze wyglądu obok standardowych widoków znajduje się dodatkowy, który jest bardziej rozbudowany. W przypadku szablonu Topaz jest to trzeci widok (footer-3), zaś w przypadku Szafira - drugi widok (footer-2). Dzięki modyfikacji obszaru możesz jeszcze bardziej spersonalizować swój sklep poprzez uzupełnienie stopki w więcej przydatnych informacji.

Konfiguracja rozbudowanej stopki

Jak przystąpić do edycji stopki?

Po zaimportowaniu z Kreatora wyglądu stopka będzie wyświetlać się w ograniczonym zakresie. Niezmiennie jej edycji dokonasz z perspektywy zakładek: Wygląd Sklepu/Ustawienia a następnie sekcji Nagłówek/Stopka. To tutaj zdecydujesz o ilości grup stron, konkretnych elementach w ich obrębie a następnie o kolejności w jakiej będą prezentować się w e-Sklepie. Również z tego poziomu dodasz odwołania do Twoich profili na portalach społecznościowych oraz ustawisz favicon dla swojego sklepu internetowego.

Więcej możliwości edycji stopki

Rozbudowana stopka w szablonie Topaz oraz Szafir umożliwia dodanie większej ilości grup stron niż dotychczas. Dzięki temu z łatwością zamieścisz w niej wszystko czego potrzebujesz. Dodatkowo sekcję uzupełniono o grafiki partnerów logistycznych oraz obsługiwanych operatorów płatności.

Przykładowy wygląd rozbudowanej stopki w szablonie Topaz

Przykładowy wygląd rozbudowanej stopki w szablonie Szafir

Jak skonfigurować poszczególne elementy?

    • Elementy 1-5: dodawanie kolejnych grup stron oraz zmiana ich kolejności dokonywana jest poprzez sekcję Nagłówek/Stopka w Ustawieniach w obrębie zakładki Wygląd Sklepu. W obrębie danej grupy możesz dodawać konkretne strony poprzez kliknięcie przycisku Dodaj stronę ze sklepu.
Wskazówka
Zmiany kolejności poszczególnych grup odnośników lub zmiany danych odnośników w obrębie danej grupy dokonuje się metodą Przeciągnij i upuść.
    • Element 6: odpowiada za wyświetlanie następujących informacji: e-mail, numer telefonu, telefon2 (jeśli nie istnieje, to zastępowany jest przez telefon komórkowy) fax lub skype. W celu edycji danych kontaktowych należy przejść w panelu e-Sklepu do zakładki Ustawienia/Ustawienia sklepu. Informacje o adresie e-mail pobierane są automatycznie z zakładki Ogólne z sekcji Konto e-mail sklepu. Aby dodać lub zmodyfikować numer telefonu konieczne jest wybranie zakładki Dane sprzedawcy, następnie Infolinia i zweryfikowanie pola Telefon.
      Wskazówka
      W elemencie wyświetlone zostaną maksymalnie 3 informacje (e-mail, telefon i jedno z wybranych pól np. telefon2, telefon komórkowy lub fax.
    • Element 7: odwołania do portali społecznościowych dodajemy bez zmian. Więcej o tym znajdziesz tutaj.
    • Elementy 8-9: aby dodać informację o operatorach płatności oraz partnerach logistycznych należy wybrać zakładkę Wygląd Sklepu/Ustawienia/Bannery. Edycji dokonasz z perspektywy kafelków: Logistics Partners oraz Payment Operators poprzez dodanie właściwych grafik operatorów i partnerów. Aby zmienić nazwę „Operator płatności” i/lub „Partnerzy logistyczni” wybierz zamiast zakładki Bannery, zakładkę Tłumaczenia. Wyszukaj po parametrze „ID” LogisticsPartnersBannerTitle oraz PaymentOperatorsBannerTitle i zmodyfikuj pole „Tekst” według własnych preferencji. Zmiany zapisz i opublikuj. W przypadku chęci usunięcia któregoś z elementów, zaznacz go i naciśnij przycisk „Usuń”.
Wskazówka
Zalecane parametry grafik dla operatorów płatności i partnerów logistycznych: szerokość maksymalna 64 px, rozszerzenie PNG.
    • Element 10: dane dotyczące firmy pobierane są z zakładki Ustawienia/Ustawienia sklepu/Dane sprzedawcy/Dane identyfikacyjne, a także z obszaru: Ustawienia/ Ustawienia sklepu/ Informacja o działalności gospodarczej/ Numer KRS lub CEIDG, Organ rejestrujący oraz Ustawienia/ Ustawienia sklepu/ Adres pocztowy, gdzie uwzględnione zostaną wszystkie pola za wyjątkiem Szerokości i długości geograficznej.

Udostępnij towar w mediach społecznościowych - konfiguracja dla szablonów Topaz i Szafir

Wstęp

Dzięki funkcji udostępniania towarów klienci mają możliwość udostępnienia wybranego asortymentu w mediach społecznościowych lub za pomocą komunikatorów internetowych. Jest to jedna z częściej używanych opcji w sklepach internetowych. W Comarch e-Sklep możesz udostępniać produkty na następujących platformach:
  • Facebook
  • Twitter
  • Linkedin
  • WhatsApp
  • Printerest
  • Gmail
  • E-mail
Aby skorzystać z przygotowanego przez nas mechanizmu udostępniania towaru musisz posiadać:
  • aktualną wersję szablonu Topaz (min. 2023.0) – sprawdzić wersję szablonu,
  • oraz aktualną wersję e-Sklepu (min. 2023.0),
  • certyfikat SSL.

Konfiguracja udostępniania towarów w szablonie Topaz

Aby skonfigurować udostępnianie towarów w szablonie postępuj zgodnie z poniższą instrukcją. Krok 1. Zaloguj się do panelu administracyjnego, a następnie przejdź do sekcji Wygląd sklepu/ Ustawienia. Krok 2. W zakładce Dodatkowe odszukaj sekcję o nazwie Udostępnianie towarów. Krok 3. Spośród dostępnych platform wybierz te, na których Klient będzie mógł udostępniać Twoje towary. Krok 4. Po dokonaniu modyfikacji zapisz i opublikuj zmiany.
Wskazówka
Jeżeli nie pozwolisz na udostępnianie towarów, to widok na szczegółach towaru nie ulegnie zmianie. Produkt będzie można udostępnić klikając przycisk Poleć towar
Na szczegółach towaru ikona i napis "Poleć towar" zmienia się na "Udostępnij na". Po kliknięciu w ikonę Klient będzie mógł wybrać opcje, które zostały wybrane w panelu administracyjnym. W wersji mobilnej Klient będzie mógł udostępnić towar w aplikacjach, które posiada zainstalowane w swoim smartfonie. Lista aplikacji otworzy się po kliknięciu w przycisku Dostępne aplikacje.   

Konfiguracja udostępniania towarów w szablonie Szafir

Aby skonfigurować udostępnianie towarów w szablonie postępuj zgodnie z poniższą instrukcją. Krok 1. Zaloguj się do panelu administracyjnego, a następnie przejdź do sekcji Wygląd sklepu/ Ustawienia. Krok 2. W zakładce Ogólne odszukaj sekcję o nazwie Udostępnianie towarów. Krok 3. Spośród dostępnych platform wybierz te, na których Klient będzie mógł udostępniać Twoje towary. Krok 4. Po dokonaniu modyfikacji zapisz i opublikuj zmiany.
Wskazówka
Jeżeli nie pozwolisz na udostępnianie towarów, to widok na szczegółach towaru nie ulegnie zmianie. Produkt będzie można udostępnić klikając przycisk Poleć towar
Na szczegółach towaru ikona i napis "Poleć towar" zmienia się na "Udostępnij na". Po kliknięciu w ikonę Klient będzie mógł wybrać opcje, które zostały wybrane w panelu administracyjnym. W wersji mobilnej Klient będzie mógł udostępnić towar w aplikacjach, które posiada zainstalowane w swoim smartfonie. Lista aplikacji otworzy się po kliknięciu w przycisku Dostępne aplikacje. 

Dodawanie nowej strony do szablonu (z zachowaniem stylów)

Wskazówka
Od 1 czerwca 2025 roku zakończyliśmy aktualizację oraz wydawanie nowych wersji szablonów Bursztyn, Agat i Opal, a tym samym ich wsparcie, aby skupić się na nowoczesnych rozwiązaniach, które jeszcze lepiej odpowiadają na potrzeby dynamicznie rozwijającego się rynku e-commerce. Zachęcamy Was do przejścia na nasze nowe, udoskonalone szablony. Dla sklepów B2C polecamy szablony Topaz, One Page Shop oraz Dla Gastronomii, natomiast dla platform B2B idealnym wyborem będą Rubin i Szafir.

W e-Sklepie możesz dodawać nowe strony do swojego szablonu. Dzięki dodatkowemu odnośnikowi Klient może przenieść się do przeznaczonej dla niego treści. W celu dodania nowej strony w e-Sklepie z zachowaniem obecnego wyglądu stron, wystarczy wykonać kilka prostych kroków.

Wskazówka
Instrukcja dotyczy szablonów Topaz oraz Szafir od wersji 2021.5. W przypadku szablonów Bursztyn, Opal, Agat od wersji 2022.  W  przypadku wszystkich szablonów w wersji poniżej  2021.5 obowiązuje instrukcja "Jak wyświetlać własną Treść na nowo dodanej Stronie użytkownika"  

Krok 1. Tworzenie nowej strony

a) W panelu administracyjnym przejdź do zakładki Wygląd sklepu > Strony. Na dole strony znajduje się sekcja Użytkownika. Skorzystaj z przycisku plusa, aby dodać nową stronę. b) W oknie pop-up uzupełnij pole Nazwa i Tytuł strony (meta title). Pole Link uzupełni się automatycznie. Następnie zatwierdź przyciskiem DODAJ.
Uwaga
Należy zapamiętać Identyfikator strony - numer znajdujący się na końcu wygenerowanego linka URL strony. Przykład: http://demo.comarch-esklep.pl/testowy/nowa_strona/27
Wskazówka
Pole link uzupełni się automatycznie na podstawie wprowadzonej nazwy. Możesz także wprowadzić swój własny tekst.
Nowa strona zostaje dodana jako nieaktywna. W celu jej aktywacji, trzeba zmienić wartość przełącznika Aktywna na "Tak". c) Po wykonaniu powyższych operacji mamy gotową pustą stronę. W celu jej publikacji, użyj na szczegółach strony przycisku Więcej > Publikuj, znajdującego się w prawym górnym rogu strony. Publikuj

Krok 2. Przyporządkowanie nowej strony do odpowiedniego pliku (obiektu) w szablonie

Aby nowa strona mogła zostać prawidłowo wyświetlona w e-Sklepie, należy przyporządkować ją do odpowiedniego pliku w posiadanym szablonie. Postępuj zgodnie z poniższymi krokami i powiąż wcześniej dodaną stronę z plikiem user-page.html . a) W panelu administracyjnym przejdź do sekcji Wygląd sklepu > Ustawienia > Edytuj ustawienia zaawansowane (z rozwijanej listy w prawym górnym rogu ekranu). b) W zakładce Strony nowo dodana strona powinna pojawić się na końcu listy. Wprowadź w pustym polu w kolumnie Plik wartość user-page.html. c) Wprowadzone zmiany zapisz oraz opublikuj (przyciski w prawym górnym rogu). Zapisz i publikuj  

Krok 3. Utworzenie własnej treści dla nowej strony

Na nowo dodanej stronie możliwe jest w łatwy i szybki sposób wprowadzenie własnych treści. Treść użytkownika dodajemy zgodnie z poniższymi informacjami: a) W panelu administracyjnym przejdź do sekcji Ustawienia > Treści formalne, po czym przejdź do zakładki Regulamin i inne. b) Dodaj nową treść użytkownika, klikając w przycisk Dodaj regulamin. c) Wprowadź nazwę nowej strony oraz dowolną treść, jaką chcesz wyświetlić. W tym miejscu możesz także wgrać własne załączniki. W dodatkowym elemencie na pasku nowej strony pojawią się odnośniki do załączonych plików, do których Klient będzie miał swobodny dostęp. Zapisz przyciskiem Dodaj bez publikacji lub Dodaj i publikuj. Treść dla nowej strony d) Następnie wejdź ponownie w szczegóły zapisanej treści i wprowadź Identyfikator*.
Uwaga
W polu Identyfikator wprowadź identyfikator cyfrowy strony utworzonej w kroku 1. Pamiętaj! Musi to być to przypisany numer z zakładki Wygląd sklepu > Ustawienia, Więcej > Edytuj ustawienia zaawansowane > Strony, inaczej powiązanie treści użytkownika z nowo dodaną stroną się nie powiedzie.
e) Zapisz i publikuj. Po wykonaniu powyższych kroków pod adresem URL z punktu 1. powinna być widoczna treść wprowadzona w sekcji Regulamin i inne.

Krok 4. Dodanie strony do sekcji

W ostatnim kroku, należy przejść do zakładki Wygląd sklepu > Ustawienia > Nagłówek lub Stopka, następnie kliknąć w odpowiednią sekcję i z tego miejsca dodać nową stronę, wybierając opcję Dodaj stronę ze sklepu. Dodaj stronę ze sklepu
Uwaga
Pamiętaj o publikacji szablonu po wprowadzeniu powyższych zmian!
Wykonanie powyższych kroków pozwala na utworzenie własnej strony, a następnie powiązanie ją z treścią użytkownika. Nowa strona będzie widoczna w stopce szablonu, a po przejściu do niej wyświetli się utworzona wcześniej treść.

Ustawienia Wyglądu Sklepu

Ustawienia

Obszar Wygląd sklepu/ Ustawienia zawiera szereg ustawień odnośnie wyglądu Twojego sklepu pogrupowanych w zakładki:
  • Ustawienia szablonu,
  • Bannery,
  • Tłumaczenia,
  • Nagłówek / Stopka,
  • Dokumentacja.

Ustawienia szablonu

W ustawieniach szablonu możesz:
  • konfigurować kolorystykę swojego szablonu,
  • korzystać z parametrów określających sposób animacji banneru głównego,
  • wybrać akcję po dodaniu do koszyka,
  • dodać klucz aplikacji Google Maps API, aby korzystać z map Google.
Wskazówka
Ilość parametrów zależna jest od wykorzystywanego szablonu, a także od własnych ustawień dodanych w zakładce Ustawienia (JSON) w ustawieniach zaawansowanych, a następnie wprowadzonych w pliku __settings.liquid
Więcej o konfiguracji kolorów Twojego sklepu przeczytasz w artykule Zmiana kolorystyki

Bannery

W tej zakładce możesz modyfikować istniejące bannery lub dodawać nowe zgodnie z artykułem Bannery

Tłumaczenia

W obszarze Tłumaczenia znajduje się lista fraz wykorzystywanych w szablonie oraz ich tłumaczeń. Możesz dodawać, usuwać, a także edytować istniejące frazy, aby dostosować szablon do swoich potrzeb. Listę fraz wraz z tłumaczeniami można wyeksportować do pliku XML oraz zaimportować z wcześniej przygotowanego pliku XML.
Wskazówka
Fraz systemowych nie można usuwać, ale można je edytować.

Nagłówek / Stopka

W zakładce Nagłówek / Stopka możliwe jest dodanie favicon.ico, czyli grafiki, która jest widoczna na zakładce w przeglądarce. Aby dodać zdjęcie, należy kliknąć przycisk Wyślij plik, po czym wybrać odpowiednią grafikę o rozmiarze nie większym niż 10 KB. W tym obszarze możesz również edytować elementy wyświetlające się w stopce. W sekcji Dołącz do nas możesz edytować i usuwać istniejące linki do portali społecznościowych lub dodawać nowe, a także wykorzystać obszar do innych odniesień zewnętrznych przydatnych w Twoim sklepie.
Wskazówka
Od wersji 2019.5 dodane zostały nowe odnośniki do najczęściej wykorzystywanych social mediów, które wyświetlane są w stopce szablonu. Mogą teraz Państwo kierować swoich użytkowników dodatkowo do serwisu Instagram, YouTube oraz Snapchat.

W sekcji Strony możesz edytować i dodawać grupy stron wyświetlających się w stopce. Po przejściu w edycję danej grupy możesz edytować nazwę w wielu językach, modyfikować listę stron poprzez usunięcie istniejących lub dodanie nowych stron ze sklepu, bądź stron zewnętrznych. Usunąć grupę możesz z poziomu menu więcej w prawym górnym rogu.

Dokumentacja

W tej zakładce znajdziesz link do Centrum Pomocy gdzie znajduje się aktualna dokumentacja odnośnie silnika Liquid

Ustawienia zaawansowane

Obszar Wygląd sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane (menu 'więcej' w prawym górnym rogu) zawiera bardziej zaawansowane ustawienia pogrupowane w zakładki:
  • Ustawienia (JSON),
  • Szablon,
  • Obiekty,
  • Testy A/B,
  • Strony,
  • Import z pliku XML,
  • Eksport do pliku XML.
Wskazówka
Szczegółowe informacje dla webmasterów odnośnie poniższych ustawień znajdziesz w artykule Szablony w sklepie

Ustawienia (JSON)

W tej zakładce dostępne są ustawienia analogiczne z zakładką Ustawienia szablonu, którą znajdziesz w sekcji Wygląd sklepu/ Ustawienia, ale przedstawione w formacie JSON. W tym miejscu możesz dodać własne ustawienia dla szablonów.

Szablon

W tej zakładce możesz ustawić szablon jako domyślny i/lub aktywny oraz podstawowe informacje o szablonie: nazwę, wersję, datę utworzenia oraz dane autora. Poprzez opcję Zmień hasło masz możliwość nadania hasła szablonowi i zablokowania nim obszarów, w których dokonuje się edycji szablonu oraz dostępu do szablonu poprzez aplikację Liquid Sync.
Uwaga
Zablokowanie hasłem dostępu do szablonu przez Liquid Sync spowoduje całkowity brak dostępu, mimo podania poprawnego hasła w aplikacji Liquid Sync.
 

Obiekty

W zakładce Obiekty znajduje się lista konfigurowalnych obiektów lokalnych - więcej o tych obiektach przeczytasz w artykule Obiekty lokalne. Na liście masz możliwość prostej konfiguracji istniejących obiektów po kliknięciu w wiersz z obiektem lub konfiguracji w formacie JSON po kliknięciu w adekwatną opcję oraz możliwość dodania kolejnych obiektów, które później mogą zostać wykorzystane w szablonie sklepu.

Testy A/B

Testy A/B pozwalają na wyświetlenie strony sklepu w dwóch różnych odsłonach celem zbadania i porównania ogólnej jakości i funkcjonalności szablonów, zaznaczonych w zakładce Szablon jako aktywne. W praktyce przy ustawieniu dwóch szablonów A i B jako aktywnych, sklep będzie się wyświetlał klientom raz w wersji A raz w wersji B (po równo). Jest to metoda badawcza, która w połączeniu z Google Analytics daje materiał do analizy współczynników konwersji, czyli procentowej wielkości określającej stosunek użytkowników strony, którzy wykonali pożądaną akcję (np. zakup) do wszystkich użytkowników danej strony. Okres trwania testów A/B możesz ustawić w panelu na 1 do 365 dni.

Strony

Zakładka zawiera listę stron w sklepie wraz z obiektami oraz plikami html które są przypisane do danej strony. W kolumnach Plik i Include możesz przypisać odpowiedni pliki html do wybranej strony. Po kliknięciu w wiersz z nazwą strony masz możliwość wybrania obiektów dostępnych na danej stronie.

Import z pliku XML

Import z pliku XML pozwala wczytać w sklepie wcześniej przygotowany i wyeksportowany szablon po kliknięciu w opcję Wybierz plik XML a następnie przycisk Importuj szablon znajdujący się poniżej. Jeżeli nadpisujesz istniejący szablon i chcesz zrobić pełny import, pamiętaj o zaznaczeniu opcji Podmień istniejące bannery, aby nadpisać bannery z szablonu wybranego na liście rozwijalnej w lewym górnym rogu.
Uwaga
Pamiętaj! Przed importem sprawdź, czy w liście rozwijalnej w lewym górnym rogu masz wybrany odpowiedni wolny slot lub szablon, który chcesz nadpisać nowym.

Eksport do pliku XML

Eksport przygotowanego szablonu do pliku XML następuje po kliknięciu w przycisk Eksportuj szablon. Dodatkowo istnieje możliwość eksportu tylko bannerów do pliku XML poprzez wybranie przycisku Eksportuj bannery. Przed eksportem możesz uzupełnić dane autora szablonu takie jak Autor, E-mail, Telefon, Adres WWW.

Edytuj HTML

Z obszaru Edytuj ustawienia zaawansowane poprzez menu Więcej widoczne w prawym górnym rogu masz dostęp do obszaru Edytuj HTML. 
Uwaga
Uwaga. Ustawienia zaawansowane przeznaczone są dla webmasterów. Ustawienia wpływają w sposób bezpośredni na zachowanie strony w przeglądarce internetowej. Niepoprawnie wprowadzone dane mogą spowodować:
  • błąd wyświetlania strony,
  • nieprawidłowe funkcjonowanie strony,
  • nieprawidłowe wyświetlanie strony,
  • nieprawidłowe formatowanie strony.
Z tego obszaru masz możliwość edycji kodu szablonu dzięki dostępowi do plików html, css, js, co daje praktycznie nieograniczone możliwości personalizacji wyglądu oraz tworzenia własnych szablonów. Możesz również tworzyć oddzielne szablony dla sklepu na Facebooku lub wersji mobilnej poprzez listę rozwijalną obok listy z aktywnym szablonem. Na liście plików możesz wejść w edycję plików istniejących lub dodać nowe pliki. Po wejściu w edycję pliku masz możliwość jego edycji lub usunięcia, a także blokady poprzez wcześniej zdefiniowane hasło w ustawieniach zaawansowanych na zakładce Szablon. Pliki podniesione do edycji widoczne są w formie zakładek w lewym górnym rogu. Od wersji 2020 dla szablonu Topaz została dodana informacja na temat godziny wygenerowania szablonu w kreatorze. Taka informacja znajduje się w pliku _layout.html nad oknem edycji. Jeżeli plik nie był modyfikowany, wówczas godzina odpowiada godzinie wygenerowania szablonu w kreatorze. Jeżeli plik został zmodyfikowany to prezentowana godzina jest godziną ostatniej modyfikacji pliku.
Wskazówka
Więcej o plikach szablonu przeczytasz w artykule Pliki szablonu oraz Szablony w sklepie.

Produkty polecane

W szablonach Comarch e-Sklep wyświetlane są produkty prezentowane jako polecane w Twoim sklepie. Produkty które wyświetlają się w tym obszarze oznacza się odpowiednim parametrem na kartach towarowych w systemie ERP. Więcej na temat dodawania atrybutów czasowych do produktów można przeczytać w poniższych artykułach: Domyślnie w sekcji polecane wyświetlają się towary oznaczone w ERP atrybutem 'rekomendacja sprzedawcy' Jednak rodzaj wyświetlanych produktów możesz zmodyfikować dopasowując je do własnych upodobań. Dzięki temu na stronie głównej można zaprezentować nie tylko towary polecane, ale np. nowości, promocje, produkt z gazetki czy też wyprzedaż. Zmianę rodzaju wyświetlanych produktów wykonuje się w Panelu administracyjnym. W tym celu należy edytować obiekt, który domyślnie wyświetla nowości zdefiniowane w systemie ERP. Zaloguj się do Panelu administracyjnego i przejdź do obszaru Wygląd sklepu/ Ustawienia. Następnie użyj przycisku ‘Więcej’ i Edytuj Ustawienia zaawansowane. Przejdź do zakładki 'Obiekty' i edytuj obiekt 'productrecommended'. W edycji obiektu 'productrecommended' możesz zmienić typ wyświetlanych produktów wybierając je z listy rozwijanej. Po zmianie zapisz swój wybór i opublikuj szablon, aby nowe produkty pojawiły się na stronie, w sekcji polecane.

Strony w e-Sklepie

Obszar do zarządzania stronami znajdujący się w Panelu administracyjnym w obszarze Wygląd sklepu/Strony, zawiera listę wszystkich stron obsługiwanych przez e-Sklep zaprezentowaną w formie kafelków, podzielonych na dwie kategorie, strony standardowe oraz użytkownika. Z poziomu listy stron możesz edytować jedną z nich poprzez kliknięcie w kafelek lub dodać nową stronę w obszarze stron użytkownika za pomocą kafelka z plusem. Po przejściu do edycji strony masz możliwość usunięcia strony oraz zmiany ustawień takich jak:
  • Aktywność
  • Nazwa
  • Język
  • Adres Url/ Link
  • Tytuł strony (meta title)
  • Opis strony (meta description)
  • Słowa kluczowe (meta keywords)
  • Tooltip dla URL
  • Klucz
Uwaga
Możliwość usuwania stron dostępna jest jedynie dla stron użytkownika w menu więcej po przejściu w edycję wybranej strony
Wskazówka
Dezaktywować możesz wszystkie strony użytkownika oraz następujące strony standardowe:
  • Porównywarka towarów
  • Wyszukiwanie zaawansowane
  • Kontakt
  • Regulamin sklepu
  • Polityka prywatności
  • Prawo do odstąpienia od umowy
  • Informacje o sklepie
  • Wysyłka
  • Płatność
  • Reklamacje i zwroty
  • Program lojalnościowy
  • Blog
  • Blog szczegóły wpisu
  • HTTP 404
Więcej o stronach przeczytasz w artykule Dodawanie nowej strony do szablonu (z zachowaniem styli).

Jak dodać nową treść i stronę?

Wstęp

W Comarch e-Sklep użytkownik ma możliwość tworzenia własnych stron oraz treści. Te drugie stanowią m.in. wiadomości E-mail i SMS, zgody formalne, czy dodatkowe treści użytkownika, np. regulamin sklepu. W panelu administracyjnym znajdują się standardowe treści oraz strony, które są odpowiednio ze sobą zmapowane  w określony sposób, w wybranych miejscach wyświetlane.

Dodawanie nowej treści

Tworzenie treści

Aby utworzyć w e-Sklepie nową treść należy w panelu administracyjnym przejść do sekcji: Ustawienia/Treści formalne/zakładka Regulamin i Inne, po czym dodać nową treść: Po kliknięciu przycisku Dodaj regulamin należy uzupełnić nazwę oraz treść lub wgrać treści z pdf. Możliwe jest także dodanie załączników. Zmiany należy dodać i opublikować. Można również je zapisać bez publikacji. Po zapisaniu zmian, przechodząc do szczegółów nowo dodanej treści, nad polem nazwa pojawi się identyfikator, który będzie niezbędny w dalszej konfiguracji,
Wskazówka
Wartość identyfikatora będzie potrzebna podczas dalszej konfiguracji.

Dodawanie nowej strony

Dodanie strony

Nową stronę tworzymy w panelu administracyjnym w obszarze: Wygląd sklepu/Strony. W sekcji Użytkownika skorzystaj z przycisku Dodaj. Wypełnij pola z nazwą, linkiem i tytułem strony i zatwierdź przyciskiem Dodaj. Nowa strona zostaje dodana jako nieaktywna. W celu jej aktywowania wystarczy kliknąć na jej kafelek i zmienić przełącznik opcji Aktywna na TAK  W celu publikacji strony użyj przycisku Więcej/Publikuj. Po dodaniu nowej strony należy zapamiętać jej numer, który znajduje się na końcu adresu URL.
Wskazówka
Numer strony widnieje w nawiasie przy jej nazwie. Możesz to sprawdzić przechodząc kolejno do sekcji: Wygląd sklepu/Ustawienia/Edytuj ustawienia zaawansowane/Strony.

Przypisanie obiektu do strony

Przejdź do obszaru Wygląd sklepu/Ustawienia, następnie użyj przycisku Więcej i wybierz Edytuj ustawienia zaawansowane. Przejdź na zakładkę "Strony". Dla nowo dodanej strony w kolumnie Plik należy wpisać nazwę pliku user-page.html. Wprowadzone zmiany zachowaj za pomocą przycisku Zapisz.

Umieszczenie strony w stopce e-sklepu

W zakładce Wygląd sklepu/Ustawienia/Nagłówek/Stopka należy wybrać odpowiednią sekcję i dodać nową stronę.

Zmiana kolorystyki

Wskazówka
Od 1 czerwca 2025 roku zakończyliśmy aktualizację oraz wydawanie nowych wersji szablonów Bursztyn, Agat i Opal, a tym samym ich wsparcie, aby skupić się na nowoczesnych rozwiązaniach, które jeszcze lepiej odpowiadają na potrzeby dynamicznie rozwijającego się rynku e-commerce. Zachęcamy Was do przejścia na nasze nowe, udoskonalone szablony. Dla sklepów B2C polecamy szablony Topaz, One Page Shop oraz Dla Gastronomii, natomiast dla platform B2B idealnym wyborem będą Rubin i Szafir.
W e-Sklepie istnieje możliwość modyfikacji kolorów w każdym szablonie. Możesz wybrać Gotowe Szablony Comarch lub stworzyć swój własny w Kreatorze wyglądu, a następnie edytować niektóre ustawienia. Aby zmienić kolorystykę należy przejść do sekcji Wygląd Sklepu/Ustawienia, po czym wybrać zakładkę Ustawienia szablonu. Szablony Bursztyn i Opal posiadają trzy predefiniowane schematy kolorów:
  • Pomarańszowy
  • Niebieski
  • Szary
Szablon Agat, podobnie jak wyżej wymienione, posiada również trzy schematy kolorów:
  • Złoty
  • Zielony
  • Lodowy
Szablon Szafir posiada następujące schematy kolorów:
  • Granatowy
  • Niebieski
  • Pomarańczowy
Z poziomu Panelu Administracyjnego możesz również modyfikować szablon Topaz. Podobnie jak podczas projektowania w Kreatorze Wyglądu możesz wybrać jeden z pięciu motywów kolorystycznych:
  • Domyślny
  • Bordowy
  • Beżowy
  • Granatowy
  • Błękitny
Każdy motyw można dodatkowo samodzielnie skonfigurować, na przykład zmienić kolory poszczególnych elementów szablonu. Po dokonaniu wszelkich modyfikacji pamiętaj o ich zapisaniu oraz opublikowaniu. W tym celu naciśnij symbol dyskietki znajdujący się w prawym górnym rogu, a następnie wybierz więcej i wybierz Publikuj.
Uwaga
Pamiętaj o ustawieniu szablonu jako Domyślny i Aktywny!
 

Jak wyeksportować i zaimportować swój szablon w e-Sklepie?

Comarch e-Sklep daje możliwość dostosowania wyglądu do preferencji sprzedawcy oraz potrzeb Klientów. Jeśli utworzyłeś już swój autorski projekt, to masz możliwość jego zapisania. Plik będzie potrzebny przy chęci modyfikacji wyglądu. Zapisana wersja szablonu może również stanowić kopię bezpieczeństwa. Warto jest więc wyeksportować szablon do pliku.

Jak wyeksportować swój szablon z Comarch e-Sklep?

Krok 1. W panelu administracyjnym przejdź do sekcji Wygląd Sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane/ zakładka Eksport szablonu.

Krok 2. W tym miejscu możesz opcjonalnie (przed eksportem) określić autora szablonu, podać adres e-mail, telefon oraz adres WWW swojego e-Sklepu.

Krok 3. Jeżeli chcesz wyeksportować szablon do pliku użyj przycisku Eksportuj szablon.

Gotowe! Szablon został wyeksportowany do pliku na Twoim urządzeniu.

Wskazówka
Z tego miejsca możesz także wyeksportować posiadane w e-Sklepie bannery, korzystając z przycisku Eksportuj bannery.

Jak wgrać własny szablon do Comarch e-Sklep?

Własny szablon. Jak go wgrać?

Po skomponowaniu swojego własnego szablonu możesz wgrać go do e-Sklepu. Postępuj zgodnie z poniższymi krokami.

Krok 1. W panelu administracyjnym przejdź do sekcji Wygląd Sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane/ zakładka Import szablonu.

Krok 2. Określ, czy wgrywany szablon ma podmienić istniejące bannery. Gdy parametr zostanie zaznaczony, wówczas wszystkie bannery zapisane na danym slocie zostaną usunięte i zastąpione bannerami z importowanego szablonu.

Krok 3. Wybierz plik XML swojego szablonu i naciśnij Importuj szablon.

Uwaga
Import szablonu jest operacją nieodwracalną i spowoduje nadpisanie dotychczasowego szablonu. W przypadku, gdy szablon był modyfikowany (dokonywano zmian w kodzie HTML) jego aktualizacja spowoduje, iż zmiany nie zostaną przeniesione. Warto wykonać eksport posiadanego szablonu do pliku w celu zapisania oraz posiadania wglądu to wprowadzanych modyfikacji. Jeżeli istnieje taka konieczność należy ponownie dokonać samodzielnej edycji szablonu

Wskazówka
W zakładce Szablony możesz określić, czy wgrywany szablon ma być domyślny i aktywny w e-Sklepie.

Krok 4. Teraz możesz podejrzeć zmiany, jakie zaszły w wyglądzie Twojego e-Sklepu. W tym celu możesz podejrzeć zmiany w czasie rzeczywistym lub przejść w tryb incognito. Pamiętaj, że wszelkie zmiany zostaną opublikowane po pełnej synchronizacji, która wciągu 10 minut zgodnie z wyświetlanym komunikatem.

Gotowe! Twój szablon został zaimportowany do e-Sklepu.

Prezentacja własnych punktów odbioru osobistego w formie mapy

Wskazówka
Od 1 czerwca 2025 roku zakończyliśmy aktualizację oraz wydawanie nowych wersji szablonów Bursztyn, Agat i Opal, a tym samym ich wsparcie, aby skupić się na nowoczesnych rozwiązaniach, które jeszcze lepiej odpowiadają na potrzeby dynamicznie rozwijającego się rynku e-commerce. Zachęcamy Was do przejścia na nasze nowe, udoskonalone szablony. Dla sklepów B2C polecamy szablony Topaz, One Page Shop oraz Dla Gastronomii, natomiast dla platform B2B idealnym wyborem będą Rubin i Szafir.

Ustawienia ogólne

Niezbędne ustawienia do włączenia widoku własnych punktów odbioru na mapie: 1. Dodanie w panelu sklepu klucza aplikacji do Google Maps API (Wygląd Sklepu > Ustawienia) google maps api input 2. Zaznaczenie opcji wyświetlania punktów odbioru osobistego na mapie (Wygląd Sklepu > Ustawienia) change to map view 3. Dodanie własnych punktów odbioru (Ustawienia > Płatności i dostawy > Odbiór osobisty) add delivery points add point
Wskazówka
Wypełniając formularz nowego punktu, trzeba pamiętać o polach „Szerokość/długość geograficzna”
add point form 4. Włączyć opcję odbioru osobistego w panelu (Ustawienia > Płatności i dostawy > Odbiór osobisty) enable delivery points 5. Dodać dostawę za pomocą własnych punktów odbioru do sposobów dostawy deliveries add delivery method 6. Dodać dostawę do macierzy dostaw oraz określić metody płatności za ten rodzaj dostawy add delivery method payments methods 7. Dokonać niezbędnych modyfikacji w kodzie szablonu wg poniższych instrukcji.  

Szablon Szafir

Wskazówka
Pliki niezbędne do prezentacji własnych punktów odbioru osobistego w formie mapy: Pobierz pliki
  1. Umieść pliki „collection-points-scripts.html” i „collection-points-styles.html” w głównym folderze szablonu.
  2. Umieść plik „collection-points.js” w folderze „js”.
  3. Umieść plik “collection-points.css” w folderze “css”.
  4. Podmień plik “collection-points.html”, który znajduje się w folderze „order/delivery-partials”.
  5. W pliku „__layout.html”, na końcu sekcji „<head>” dodaj poniższą linijkę:
    {% include 'collection-points-styles.html' %}
  6. W pliku „__layout.html”, na końcu sekcji „<body>” dodaj poniższą linijkę:
    {% include 'collection-points-scripts.html' %}
 

Szablon Agat

Wskazówka
Pliki niezbędne do prezentacji własnych punktów odbioru osobistego w formie mapy: Pobierz pliki
  1. Umieść plik “collection-points.css” w folderze “css”.
  2. Umieść plik “collection-points.js” w folderze “js”.
  3. Podmień plik “order.js”, który znajduje się w folderze “js”.
  4. Podmień plik “delivery-adress.html”, który znajduje się w folderze “partials/cart”.
  5. Podmień plik “init.js”, który znajduje się w folderze “js”.
  6. W pliku “_layout.html”, na końcu sekcji “<head>” dodaj poniży kod:
    {% if page.PageId == config.DefinedPages.Order.Id -%} 
       <link rel="stylesheet" type="text/css" href="css/collection-points.css"> 
    {% endif -%}
     

Szablon Opal

Wskazówka
Pliki niezbędne do prezentacji własnych punktów odbioru osobistego w formie mapy: Pobierz pliki
  1. Umieść plik “collection-points.js” w folderze “js”.
  2. Umieść plik “collection-points.css” w folderze “css”.
  3. Podmień plik “order.js”, który znajduje się w folderze “js”.
  4. Podmień plik “data-form.html”, który znajduje się w folderze “order/cst-data”.
  5. Podmień plik “cart.html”, który znajduje się w folderze “order”.
  6. W pliku “_layout.html”, na końcu sekcji “<head>” dodaj poniży kod:
    {% if page.PageId == config.DefinedPages.Order.Id -%} 
       <link rel="stylesheet" type="text/css" href="css/collection-points.css"> 
    {% endif -%}
  7. Do pliku “order-cart.html”, wklej poniższy kod:
    {% extends '_layout.html' -%}
    
    {% block PageContent -%}
        <script src="{{ cart.CollectionPointMapUrl }}"></script>
        <script>var _CollectionPointMapUrl = '{{ cart.CollectionPointMapUrl }}';</script>
        <script src="js/collection-points.js?v={{ lqTS }}"></script>
        {% include 'order-cart-container.html'%}
    {% endblock -%}
    
    {% block PageBodyEnd -%}
        <script>__ResxCartEmpty = '{{ translations.Crt_CartIsEmpty | H }}';</script>
        <script src="js/order.js?v={{ lqTS }}" charset="utf-8" type="text/javascript"></script>
    {% endblock -%}

Szablon Bursztyn

Wskazówka
Pliki niezbędne do prezentacji własnych punktów odbioru osobistego w formie mapy: Pobierz pliki
  1. Umieść plik “collectionpoints.js” w folderze “js”.
  2. Umieść plik “collectionpoints.css” w folderze “css”.
  3. Podmień plik “order.js”, który znajduje się w folderze “js”.
  4. Podmień plik “cart.html”, który znajduje się w folderze “order”.
  5. Podmień plik “order-short-info.html”, który znajduje się w folderze “order”.
  6. Podmień plik “cart-products-partial.html”, który znajduje się w folderze “order”.
  7. W pliku “_layout.html”, na końcu sekcji “<head>” dodaj poniży kod:
    {% if page.PageId == config.DefinedPages.Order.Id -%}
        <link rel="stylesheet" type="text/css" href="css/collectionpoints.css">
    {% endif -%}
    
  8. Do pliku “order-cart.html”, wklej poniższy kod:
    {% extends '_layout.html' -%}
    
    {% block PageContent -%}
        <script src="{{ cart.CollectionPointMapUrl }}"></script>
        <script>var _CollectionPointMapUrl = '{{ cart.CollectionPointMapUrl }}';</script>
        <script src="js/collectionpoints.js?v={{ lqTS }}"></script>
        {% include 'order-cart-container.html'%}
    {% endblock -%}
    
    {% block PageBodyEnd %}
        <script type="text/javascript">__ResxCartEmpty = '{{ translations.Crt_CartIsEmpty | H }}';</script>
        <script src="js/order.js?v={{ lqTS }}"></script>
    {% endblock %}
     

Powiększanie zdjęć w szczegółach towaru w szablonie Topaz

Powiększanie zdjęć w szczegółach towaru w szablonie Topaz

W tym artykule dowiesz się jak dodać możliwość wyświetlania drugiego zdjęcia na liście towarów.

Wskazówka
W tym artykule trzeba będzie wprowadzać zmiany w plikach js i css. Z tego artykułu dowiesz się jak je minifikować i kompilować

Uwaga
Zapis nazwa_folderu/nazwa_pliku.rozszerzenie oznacza, że aby znaleźć dany plik należy udać się do folderu o nazwie podanej przed ukośnikiem. Przykładowo: order/thx.html oznacza plik thx.html w folderze order

Na początku w pliku elements\product-details-1.html lub elements\product-details-2.html (w zależności od typu wyglądu), za pomocą narzędzia wyszukiwania, znajdź linijkę: <img alt="{{image.Alt | H}}" src="css/img/alo.gif" data-lazy="img/grande/{{image.Id}}/{{image.Link}}.jpg"> W miejsce tej linijki wklej następujacy kod: <img class="open-gallery" alt="{{image.Alt | H}}" src="css/img/alo.gif" data-lazy="img/{{image.Id}}/{{image.Link}}.jpg"> Następnie w tym samym pliku, za pomocą narzędzia wyszukiwania, znajdź linijkę: <img alt="{{product.Images[0].Alt | H}}" src="css/img/alo.gif" data-lazy="img/grande/{{product.Images[0].Id}}/{{product.Images[0].Link}}.jpg"> W jej miejsce wklej następujący kod: <img class="open-gallery" alt="{{product.Images[0].Alt | H}}" src="css/img/alo.gif" data-lazy="img/{{product.Images[0].Id}}/{{product.Images[0].Link}}.jpg">   Kolejnym krokiem jest przejście do pliku js\layout1.js. W pliku tym, za pomocą narzędzia wyszukiwania, znajdujemy frazę var productDetailsFunctions = {, a następnie bezpośrednio pod nią wklejamy następujący kod: openGallery: function (e) { var t = $(".product-details__image").slick("slickCurrentSlide"); var i = $(e.currentTarget).parents(".product-details__images"); i.addClass("opened-gallery"); i.append('<svg class="svgIcon close-gallery-button"><use xlink:href="css/img/icons-sprite.svg#times-light"></use></svg>'); $("body").addClass("modal-opened"); $(".open-gallery:not(.opened-gallery-switch)").addClass("opened-gallery-switch"); $(".product-details__image-list").addClass("slider-hidden"); $(".product-details__image").addClass("opened-gallery"); $(".product-details__image").slick("unslick"); this.setGallerySlider(t); $(".draggable").css("top", "25%"); }, closeGallery: function (e) { $(".product-details__images").removeClass("opened-gallery"); $(".product-details__image").removeClass("opened-gallery"); $(".open-gallery.opened-gallery-switch").removeClass("opened-gallery-switch"); $(e.currentTarget).remove(); $(".product-details__image-list").removeClass("slider-hidden"); $("body").removeClass("modal-opened"); $(".product-details__image").slick("unslick"); $(".draggable").css("top", "0"); this.setSlider(); }, setGallerySlider: function (t) { $(".product-details__image").slick ({ infinite: true, slidesToShow: 1, slidesToScroll: 1, autoplay: false, nextArrow: '<button type="button" aria-label="nextArrow" class="slick-next"><svg class="svgIcon svgIcon--arrowRight"><use xlink:href="css/img/icons-sprite.svg#angle-right-light"></use></svg></button>', prevArrow: '<button type="button" aria-label="prevArrow" class="slick-next"><svg class="svgIcon svgIcon--arrowLeft"><use xlink:href="css/img/icons-sprite.svg#angle-right-light"></use></svg></button>', accessibility: false, dots: false, }); $(".product-details__image").slick("slickGoTo", t, true); }, W tym samym pliku za pomocą narzędzia wyszukiwania znajdź frazę var body = $('body'); a bezpośrednio pod nią wklej następujacy kod: body.on("click", ".open-gallery:not(.opened-gallery-switch)", function(e) { productDetailsFunctions.openGallery(e); }), $("body").on("click", ".close-gallery-button", function(e) { productDetailsFunctions.closeGallery(e); }),   Przejdź do pliku css\elements\product-deatils-1-g.css lub css\elements\product-deatils-2-g.css (w zależności od typu wyglądu). Na koncu pliku wklej następujący kod: .close-gallery-button { position: fixed; right: 0; top: 0; background: transparent; color: #656565; z-index: 20; border: 0; font-size: 20px; width: 50px; height: 50px; cursor: pointer; } .slider-hidden { display: none; } .opened-gallery { position: fixed; display: flex; z-index: 20; top: 0; right: 0; bottom: 0; left: 0; background: #ffffff; width: 100%; .slick-next:last-child { right: 20px; } .slick-next:first-child { left: 20px; } .slick-next { height: 35px; width: 35px; } img { max-height: none; } } Ostatnim krokiem jest przeście do pliku css\base_layout-g.css. Znajdź  frazę body { i bezpośrednio pod wyszukaną linijką wklej następujacy kod: &.modal-opened { overflow: hidden; }                          

Integracja z edrone - dostosowanie szablonu

Wskazówka
Od 1 czerwca 2025 roku zakończyliśmy aktualizację oraz wydawanie nowych wersji szablonów Bursztyn, Agat i Opal, a tym samym ich wsparcie, aby skupić się na nowoczesnych rozwiązaniach, które jeszcze lepiej odpowiadają na potrzeby dynamicznie rozwijającego się rynku e-commerce. Zachęcamy Was do przejścia na nasze nowe, udoskonalone szablony. Dla sklepów B2C polecamy szablony Topaz, One Page Shop oraz Dla Gastronomii, natomiast dla platform B2B idealnym wyborem będą Rubin i Szafir.
Darmowe szablony Comarch od wersji 2018.1 posiadają wbudowaną integrację z zaawansowanym systemem do zarządzania relacjami z klientami edrone. Jeżeli korzystasz z innych szablonów, to ten artykuł może być dla Ciebie pomocny. Poniżej znajduje się lista kroków, które należy wykonać w celu integracji z edrone.
  1. Ustawiamy swój App ID z edrone w panelu administracyjnym (Ustawienia/Ustawienia Sklepu/Ogólne/Integracja z edrone)
  2. W głównym folderze szablonu tworzymy folder edrone, w którym umieszczamy pliki, których zawartość znajduje się w kolejnych punktach
  3. W pliku html, na końcu sekcji head includujemy plik edrone/head.html (dodajemy {% include ‘edrone/head.html’ -%} ) {% if config.External.Edrone.AppId != '' -%} <script type="text/javascript"> (function (srcjs) { window._edrone = window._edrone || {}; _edrone.app_id = '{{ config.External.Edrone.AppId }}'; _edrone.version = '1.0.0'; _edrone.platform_version = '{{ config.Version }}'; _edrone.platform = 'comarch'; _edrone.shop_lang = '{{ page.Language }}';{% if page.PageId != config.DefinedPages.Order.Id -%} _edrone.action_type = 'other'; {% if usr.Authenticated -%} {% if customer.Address.Name != '' -%} {% assign FullName = customer.Address.Name -%} {% if FullName contains ' ' -%} {% assign HalfName = FullName | Split:' ' -%} {% endif %} _edrone.first_name = '{% if HalfName[0] -%}{{ HalfName[0] }}{% else %}{{ FullName }}{% endif %}'; {% if HalfName[1] -%} _edrone.last_name = '{{ HalfName[1] }}'; {% endif %} {% endif -%} {% if customer.Address.Country != '' -%} _edrone.country = '{{ customer.Address.Country }}'; {% endif -%} {% if customer.Address.City != '' -%} _edrone.city = '{{ customer.Address.City }}'; {% endif -%} {% if customer.Address.Phone != '' -%} _edrone.phone = '{{ customer.Address.PhoneNo }}'; {% endif -%} _edrone.email = '{{ customer.Email }}'; {% endif -%} {% endif -%}var doc = document.createElement('script'); doc.type = 'text/javascript'; doc.async = true; doc.src = ('https:' == document.location.protocol ? 'https:' : 'http:') + srcjs; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(doc, s); })("//d3bo67muzbfgtl.cloudfront.net/edrone_2_0.js"); </script> {% endif -%}
  4. W pliku html, na końcu sekcji body includujemy pliki edrone/product-presentation.html oraz edrone/subscribe.html
    • product-presentation.html
    {% if page.PageId == config.DefinedPages.ProductDetails.Id and config.External.Edrone.AppId != '' -%} <script type="text/javascript"> {% if productdetails -%} {% assign product-presentation = productdetails -%} {% elseif product-details -%} {% assign product-presentation = product-details -%} {% endif -%} window._edrone = window._edrone || {}; _edrone.action_type = 'product_view'; _edrone.product_ids = '{{ product-presentation.Product.Id }}'; _edrone.product_titles = '{{ product-presentation.Product.Name }}'; {% if product-presentation.Product.ImageId > 0 -%} _edrone.product_images = 'http:{{ page.BaseHref }}img/large/{{ product-presentation.Product.ImageId }}/{% if product-presentation.Product.Images[0].Name != "" -%}{{ product-presentation.Product.Images[0].Name }}{% else %}.jpg{% endif %}'; {% endif -%} {% if product-presentation.Product.Code != '' -%} _edrone.product_skus = '{{ product-presentation.Product.Code }}'; {% endif -%} _edrone.product_urls = '{{ page.CanonicalLink }}'; _edrone.product_category_ids = '{{ page.GroupId }}'; _edrone.product_category_names = '{{ page.CurrentSiteNode.Name }}'; </script> {% endif %}
    Wskazówka
    Jeżeli w swoim szablonie obiekt ze szczegółami produktu ma inną nazwę, to należy zmodyfikować warunek.
    • subscribe.html
    {% if config.External.Edrone.AppId != '' -%} {% if page.PageId == config.DefinedPages.Home.Id or page.PageId == config.DefinedPages.CustomerProfile.Id -%} <script type="text/javascript"> $(document).ajaxSuccess(function(a,b,c,d) { if(d && d.action && (d.action.Action == 'Newsletter/Subscribe' || d.action.Action == 'newsletter/subscribe') && d.action.Result){ var queryString = c.data.split('&'); for(i=0; i<queryString.length; i++){ if(queryString[i].indexOf('email') != -1){ var email = queryString[i].split('=')[1].replace('%40','@'); } } _edrone.customer_tags = 'From Newsletter Subscribe'; _edrone.email = email; _edrone.subscriber_status = '1'; _edrone.action_type = 'subscribe'; _edrone.init(); } }); </script> {% endif %} {% if page.PageId == config.DefinedPages.CustomerProfile.Id -%} <script type="text/javascript"> $(document).ajaxSuccess(function(a,b,c,d) { if(d && d.action && (d.action.Action == 'Newsletter/Unsubscribe' || d.action.Action == 'newsletter/unsubscribe') && d.action.Result){ var queryString = c.data.split('&'); for(i=0; i<queryString.length; i++){ if(queryString[i].indexOf('email') != -1){ var email = queryString[i].split('=')[1].replace('%40','@'); } } _edrone.customer_tags = 'From Newsletter Subscribe'; _edrone.email = email; _edrone.subscriber_status = '0'; _edrone.action_type = 'subscribe'; _edrone.init(); } }); </script> {% endif %} {% endif %}
    Wskazówka
    Jeżeli w swoim szablonie umożliwiasz zapis do newslettera z innych stron niż strona główna i profil klienta oraz pozwalasz na wypisanie poza profilem klienta, to należy zmodyfikować powyższy plik.
    Uwaga
    W wersji 2018.7 z domyślnych szablonów Comarch usunięto akcję dotyczącą zapisu i wypisu z newslettera, ponieważ dane przekazywane są przez Comarch e-Sklep w tle.
  5. W szablonach Agat, Bursztyn i Opal, w tym samym miejscu includujemy również plik edrone/add-to-cart.html {% if page.PageId == config.DefinedPages.ProductDetails.Id and config.External.Edrone.AppId != '' -%} <script type="text/javascript"> $(document).ajaxSuccess(function(a,b,c,d) { if(d && d.action && (d.action.Action == 'Cart/Add' || d.action.Action == 'cart/add') && d.action.Result ){ _edrone.action_type = 'add_to_cart'; _edrone.init(); } }); </script> {% endif %}
    Wskazówka
    Plik należy dodać do wszystkich szablonów, które nie są oparte o najnowszą wersję szablonu Szafir (w tym szablonie dodawanie do koszyka w edrone obsłużone jest bezpośrednio w funkcjach szablonu – spowodowane jest to możliwością dodawania kilku towarów jednocześnie czego inne szablony nie posiadają).
  6. W szablonie Bursztyn, w tym samym miejscu includujemy również plik edrone/add-to-cart-with-data.html {% if config.External.Edrone.AppId != '' -%} {% if page.PageId == config.DefinedPages.Home.Id or page.PageId == config.DefinedPages.ProductList.Id -%} <script type="text/javascript"> $(document).ajaxSuccess(function(a,b,c,d) { if(d && d.action && (d.action.Action == 'Cart/Add' || d.action.Action == 'cart/add') && d.action.Result ){ window._edrone = window._edrone || {};var products = d.collection["customer.Cart"].Products; var size = products.length; var product = products[size-1];_edrone.product_ids = product.Id; _edrone.product_titles = product.NameNoHtml; if(product.ImageId > 0){ _edrone.product_images = 'http:{{ page.BaseHref }}img/large/'+product.ImageId+'/.jpg'; } if(product.Code != ''){ _edrone.product_skus = product.Code; } _edrone.product_urls = 'http:{{ page.BaseHref }}'+product.Url; _edrone.product_category_ids = product.DefaultGroup; _edrone.action_type = 'add_to_cart'; _edrone.init(); } }); </script> {% endif %} {% endif %}
    Wskazówka
    Kod działa dla dodawania do koszyka ze strony głównej i listy towarów. Jeżeli pozwalasz na dodawanie do koszyka z innych stron, należy go zmodyfikować.
  7. W pliku z podziękowaniami za zakup (Agat – partials/cart/summary.html, Bursztyn i Opal – order/thank-you.html, Szafir – order/thx.html), na końcu pliku (tuż pod includem rich-snippetów), includujemy plik edrone/order.html {% if config.External.Edrone.AppId != '' -%} <script type="text/javascript"> _edrone.action_type = 'order';{% if cart -%} {% assign order = cart -%} {% endif -%}{% assign FullName = order.Customer.DeliveryAddress.Name -%} {% if FullName contains ' ' -%} {% assign HalfName = FullName | Split:' ' -%} {% endif %} _edrone.first_name = '{% if HalfName[0] -%}{{ HalfName[0] }}{% else %}{{ FullName }}{% endif %}'; {% if HalfName[1] -%} _edrone.last_name = '{{ HalfName[1] }}'; {% endif %} _edrone.country = '{{ order.Customer.DeliveryAddress.Country }}'; {% if order.Customer.DeliveryAddress.City != '' -%} _edrone.city = '{{ order.Customer.DeliveryAddress.City }}'; {% endif %} {% if order.Customer.DeliveryAddress.PhoneNo != '' -%} _edrone.phone = '{{ order.Customer.DeliveryAddress.PhoneNo }}'; {% endif %} _edrone.email = '{{ order.Customer.Email }}'; {% assign size = order.PlacedOrder.Products | Size -%} var ids = ''; var titles = ''; var images = ''; var skus = ''; var urls = ''; var categoryIds = ''; var counts = ''; {% for product in order.PlacedOrder.Products -%} ids += '{{ product.Id }}{% if forloop.index != size -%}|{% endif -%}'; titles += '{{ product.NameNoHtml }}{% if forloop.index != size -%}|{% endif -%}'; images += '{% if product.ImageId > 0 -%}http:{{ page.BaseHref }}img/large/{{ product.ImageId }}/.jpg{% endif -%}{% if forloop.index != size -%}|{% endif -%}'; skus += '{{ product.Code }}{% if forloop.index != size -%}|{% endif -%}'; urls += 'http:{{ page.BaseHref }}{{ product.Url }}{% if forloop.index != size -%}|{% endif -%}'; categoryIds += '{{ product.DefaultGroup }}{% if forloop.index != size -%}|{% endif -%}'; counts += '{{ product.Quantity | Normalize }}{% if forloop.index != size -%}|{% endif -%}'; {% endfor -%} _edrone.product_ids = ids; _edrone.product_titles = titles; _edrone.product_images = images; _edrone.product_skus = skus; _edrone.product_urls = urls; _edrone.product_category_ids = categoryIds; _edrone.product_counts = counts; _edrone.order_id = '{{ order.PlacedOrder.Id }}'; _edrone.base_currency = '{{ order.Currency }}'; _edrone.order_currency = '{{ order.Currency }}'; _edrone.base_payment_value = '{{ order.OrderTotalValue | ToString | Replace:",","." }}'; _edrone.order_payment_value = '{{ order.OrderTotalValue | ToString | Replace:",","." }}'; _edrone.init(); </script> {% endif -%}
    Wskazówka
    Jeżeli w swoim szablonie używasz dla koszyka innej nazwy obiektu niż cart lub order, to powyższy kod należy zmodyfikować.
  Edrone i dodawanie towarów w szablonie Szafir:
  1. Plik js/init-ui1.js
  • Funkcja serialAddingToCart
Na samym początku funkcji znajduje się pętla “each”, a w niej instrukcja warunkowa „if (quantity > 0)”. Na końcu tej instrukcji warunkowej wklejamy poniższy kod: if(typeof _edrone !== 'undefined') { var product = form.parents('.product-item-lq'); var base = $('[data-base]').data('base'); if (first) { _edrone.product_ids = productId; _edrone.product_titles = product.find('.product-name-lq').text(); _edrone.product_images = base + product.find('img').data('src'); _edrone.product_skus = product.find('.product-code-lq').text(); _edrone.product_urls = base + product.find('a').attr('href'); _edrone.product_category_ids = $('[data-group-id]').data('group-id'); _edrone.product_category_names = $('[data-group-name]').data('group-name'); first = false; } else { _edrone.product_ids += '|' + productId; _edrone.product_titles += '|' + product.find('.product-name-lq').text(); _edrone.product_images += '|' + base + product.find('img').data('src'); _edrone.product_skus += '|' + product.find('.product-code-lq').text(); _edrone.product_urls += '|' + base + product.find('a').attr('href'); _edrone.product_category_ids += '|' + $('[data-group-id]').data('group-id'); _edrone.product_category_names += '|' + $('[data-group-name]').data('group-name'); } } Kilkanaście linijek niżej (w tej samej funkcji) jest instrukcja warunkowa “if (resGuardian)”. Na początku tej instrukcji warunkowej wklejamy poniższy kod: if(typeof _edrone !== 'undefined') { _edrone.action_type = 'add_to_cart'; _edrone.init(); }
  • Funkcja addManyProducts
Na samym początku funkcji znajduje się pętla “for(var i=0; i<products.length; i++)” iterująca po produktach. Tuż przed nią należy dodać poniższą linijkę: var first = true; Następnie, w tej pętli znajduje się instrukcja warunkowa „if(products[i].askForPriceChild == false && products[i].quantity > 0)”. Na samym jej końcu należy dodać poniższy kod: if(parameters && !validationError && products[i].supply != undefined && typeof _edrone !== 'undefined'){ if(first){ _edrone.product_ids = products[i].supply; _edrone.product_images = products[i].img; _edrone.product_skus = products[i].code; var name = _edrone.product_titles; var url = _edrone.product_urls; var categoryId = _edrone.product_category_ids; var categoryName = _edrone.product_category_names; first = false; } else { _edrone.product_ids += '|' + products[i].supply; _edrone.product_images += '|' + products[i].img; _edrone.product_skus += '|' + products[i].code; _edrone.product_titles += '|' + name; _edrone.product_urls += '|' + url; _edrone.product_category_ids += '|' + categoryId; _edrone.product_category_names += '|' + categoryName; } } Kilkanaście linijek niżej (w tej samej funkcji) jest “$.post”. Na samym jego początku należy dodać poniższy kod: if(typeof _edrone !== 'undefined') { _edrone.action_type = 'add_to_cart'; _edrone.init(); }
  • Dodanie funkcji simpleAddToCartSuccess
Na końcu pliku js/init-ui1.js należy dodać poniższy kod: function simpleAddToCartSuccess(e){ updateClientArea(); if(typeof _edrone !== 'undefined') { if ($('.add-from-presentation-lq').index() == -1) { var product = $(e.currentTarget).parents('.product-item-lq'); var base = product.parents('[data-base]').data('base'); _edrone.product_ids = product.data('product-id'); _edrone.product_titles = product.find('.product-name-lq').text(); _edrone.product_images = base + product.find('img').attr('src'); _edrone.product_skus = product.find('.product-code-lq').text(); _edrone.product_urls = base + product.find('a').attr('href'); _edrone.product_category_ids = product.parents('[data-group-id]').data('group-id'); _edrone.product_category_names = product.parents('[data-group-name]').data('group-name'); } _edrone.action_type = 'add_to_cart'; _edrone.init(); } } Następnie należy zmodyfikować “event”, który jest wywoływany przy kliknięciu w element z klasą “add-to-cart-update-client-area-lq”. Zmieniamy zawartość tego eventa na: app.post(e, simpleAddToCartSuccess, e); Cały event powinien wyglądać następująco: $('body').on('click', '.add-to-cart-update-client-area-lq', function(e) { app.post(e, simpleAddToCartSuccess, e); });
  1. Plik js/init-ui2.js
  • Funkcja serialAddingFromWishlist
Na samym początku funkcji znajduje się pętla “each”. Tuż przed nią należy dodać poniższą linijkę: var first = true; Następnie, w tej pętli znajduje się instrukcja warunkowa „if (quantity > 0)”. Na samym jej końcu należy dodać poniższy kod: if(typeof _edrone !== 'undefined') { if (first) { _edrone.product_ids = productId; _edrone.product_titles = productContainer.find('.product-name-lq').text(); _edrone.product_images = base + productContainer.find('img').attr('src'); _edrone.product_skus = productContainer.find('.product-code-lq').text(); _edrone.product_urls = base + productContainer.find('a').attr('href'); _edrone.product_category_ids = categoryId; first = false; } else { _edrone.product_ids += '|' + productId; _edrone.product_titles += '|' + productContainer.find('.product-name-lq').text(); _edrone.product_images += '|' + base + productContainer.find('img').attr('src'); _edrone.product_skus += '|' + productContainer.find('.product-code-lq').text(); _edrone.product_urls += '|' + base + productContainer.find('a').attr('href'); _edrone.product_category_ids += '|' + categoryId; } } Kilkanaście linijek niżej (w tej samej funkcji) jest instrukcja warunkowa “if (resGuardian)”. Na początku tej instrukcji warunkowej wklejamy poniższy kod: if(typeof _edrone !== 'undefined') { _edrone.action_type = 'add_to_cart'; _edrone.init(); }

Nowości i promocje w szablonie

Na stronie głównej sklepu wyświetlane są produkty prezentowane jako promocje w Twoim sklepie. Nowości i promocje w szablonie: 1 - strona główna Produkty które wyświetlają się w tym obszarze oznacza się odpowiednim parametrem na kartach towarowych w systemie ERP. Więcej na temat dodawania atrybutów czasowych do produktów można przeczytać w poniższych artykułach:   Jednak rodzaj wyświetlanych produktów możesz zmodyfikować dopasowując je do własnych upodobań. Dzięki temu na stronie głównej można zaprezentować nie tylko promocje, ale np. nowości, rekomendacje sprzedawcy, produkt z gazetki czy też wyprzedaż. Zmianę rodzaju wyświetlanych produktów wykonuje się w Panelu administracyjnym. W tym celu należy edytować obiekt, który domyślnie wyświetla nowości zdefiniowane w systemie ERP. Zaloguj się do Panelu administracyjnego i przejdź do obszaru Wygląd sklepu/ Ustawienia. Następnie użyj przycisku ‘Więcej’ i Edytuj Ustawienia zaawansowane. Przejdź do zakładki 'Obiekty' i edytuj obiekt 'productnew'. Nowości i promocje w szablonie: 2 - lista obiektów W edycji obiektu 'productnew' możesz zmienić typ wyświetlanych produktów wybierając je z listy rozwijanej. Nowości i promocje w szablonie: 3 - nowości i promocje Po zmianie zapisz swój wybór i opublikuj szablon, aby nowe produkty pojawiły się na stronie.

Szablony dla zaawansowanych

Spełnij kryteria WCAG 2.1/2.2. Przewodnik dla programistów oraz Partnerów Comarch.

Wstęp

Z dniem 28 czerwca 2025 roku w życie wejdą przepisy związane z implementacją ustawy z dnia 26 kwietnia 2024 r. o zapewnianiu spełniania wymagań dostępności niektórych produktów i usług. Wdraża ona do polskiego prawa tzw. Europejski Akt o Dostępności (EAA) – unijną dyrektywę 2019/882. Celem ustawy jest zapewnienie, że kluczowe produkty i usługi będą dostępne dla wszystkich użytkowników, w tym osób z niepełnosprawnościami. Przedsiębiorcy mają czas do 28 czerwca 2025 roku, aby dostosować swoje produkty i usługi do nowych wymogów.
Wskazówka
Chcesz dowiedzieć się więcej o tych przepisach? Sprawdź artykuł w naszym Centrum Pomocy: Europejski Akt o Dostępności (EAA) i zapoznaj się ze szczegółami
Niniejszy artykuł przedstawia fundamentalne zasady i techniczne wytyczne, których wdrożenie przyczyni się do zwiększenia dostępności witryny internetowej. Ma on na celu ma na celu pomóc programistom Liquid w tworzeniu dostępnych cyfrowo aplikacji i stron internetowych.  

Najlepsze praktyki dostępności

Dostępność stron internetowych jest obecnie kluczowym aspektem ich projektowania, mającym na celu zapewnienie równego dostępu do treści dla wszystkich użytkowników, niezależnie od ich indywidualnych potrzeb czy ograniczeń. Przestrzeganie najlepszych praktyk w zakresie dostępności nie tylko wspiera osoby korzystające z technologii asystujących, ale również poprawia ogólną użyteczność i funkcjonalność serwisu. W tym artykule przedstawiamy najlepsze praktyki dotyczące dostępności, które powinny być stosowane w kodzie HTML i CSS. Każdy z tych elementów odgrywa istotną rolę w budowaniu przyjaznego i dostępnego środowiska cyfrowego. Omówione zagadnienia obejmują:
  • Stosowanie semantycznych znaczników HTML,
  • Zapewnienie odpowiedniego kontrastu kolorystycznego,
  • Właściwe oznaczanie grafik poprzez teksty alternatywne,
  • Dostosowanie mechanizmów nawigacyjnych dla użytkowników korzystających z klawiatury.
 
Wskazówka
Ten artykuł przeznaczony jest dla osób z zaawansowaną wiedzą dotyczącą modyfikacji kodu szablonu. Jeśli nie jesteś programistą i nie dokonujesz zmian w kodzie, to przejdź do artykułów ogólnych:
 

Zasady ogólne

  • Semantyczne znaczniki HTML Używaj odpowiednich znaczników HTML, takich jak <header>, <nav>, <main>, <footer>, aby struktura strony była logiczna i zrozumiała. Jeśli w szablonie znajdują się niestandardowe struktury lub elementy, upewnij się, że są one odpowiednio oznaczone i dostępne dla czytników ekranu, np. za pomocą landmarków ARIA Landmarks.
  • Kolory i kontrast Zapewnij odpowiedni kontrast między tekstem, a tłem. Używaj narzędzi do sprawdzania kontrastu, aby upewnić się, że spełniasz standardy WCAG. Wykorzystaj devtools do sprawdzania kontrastu kolorów, takie jak np. WebAIM Contrast Checker, lub skorzystaj z narzędzia WAVE dostępnego jako rozszerzenie do przeglądarki.
  • Tekst alternatywny Zawsze dodawaj tekst alternatywny do obrazów, aby osoby korzystające z czytników ekranu mogły zrozumieć ich zawartość. W większości przypadków wykorzystanie filtra Liquid Img automatycznie zapewni odpowiednie atrybuty alt, natomiast jeśli używasz niestandardowych obrazów, upewnij się, że dodajesz alt lub aria-label do elementu <img>.
  • Nawigacja klawiaturą Zagwarantuj opcję poruszania się po stronie przy użyciu klawiatury, jednocześnie dbając o dostępność wszystkich interaktywnych elementów. Pamiętaj o zdefiniowaniu stylu swojego :focus oraz :focus-visible, aby użytkownicy mogli łatwo zidentyfikować, który element jest aktualnie aktywny. Niektóre znaczniki HTML5 są domyślnie dostępne dla nawigacji klawiaturą, takie jak <button>, <a>, <input>, ale jeśli używasz niestandardowych elementów, takich jak <div> lub <span>, upewnij się, że dodajesz tabindex=”0″ i odpowiednie role ARIA.
  • Czytelność Używaj prostego i zrozumiałego języka. Unikaj skomplikowanych zdań i terminologii, która może być trudna do zrozumienia dla niektórych użytkowników.
 

Elementy interaktywne

  • Formularze Używaj odpowiednich znaczników formularzy, takich jak <input>, <select>, <textarea>. Zapewnij, że są one poprawnie oznaczone. Używaj aria-label lub aria-labelledby, jeśli etykiety nie są widoczne. Jeśli natomiast w szablonie wykorzystywane są customowe pola formularzy, np. przy użyciu wykorzystania elementów <div> lub <span> to upewnij się, że są one dostępne dla czytników ekranu i użytkowników korzystających z klawiatury, np. poprzez dodanie role=”checkbox” lub role=”button” oraz odpowiednich atrybutów ARIA.
  • Przyciski Używaj <button> zamiast <div> lub <span> do tworzenia przycisków. Jeśli używasz ikon jako przycisków, dodaj aria-label lub title, aby opisać ich funkcję. Ikony, które nie mają znaczenia informacyjnego, powinny mieć aria-hidden=”true” lub role=”presentation”, aby nie były odczytywane przez czytniki ekranu.
  • Linki Używaj <a> do tworzenia linków. Tekst linku powinien jasno opisywać jego cel. Unikaj używania ogólnych fraz, takich jak „kliknij tutaj”. Jeśli chcesz dostarczyć dodatkowe informacje, użyj aria-label np. w przypadku linków do pobrania plików, np. <a href=”plik.pdf” aria-label=”Pobierz plik PDF”>Pobierz</a>.
  • Role ARIA Używaj ról ARIA, aby poprawić dostępność elementów, które nie mają semantycznego znaczenia w HTML. Na przykład, jeśli używasz <div> jako przycisku, dodaj role=”button” i zapewnij odpowiednie atrybuty ARIA, takie jak aria-pressed dla przycisków przełączających. Dodaj tłumaczenia do szablonu, aby zapewnić tłumaczenie tekstów używanych w atrybutach ARIA, takich jak aria-label, aria-labelledby i aria-describedby, aby były dostępne w różnych językach. np. aria-label=”{{translations.DownloadFile}}”.
 

Struktura treści

  • Nagłówki Używaj nagłówków od <h1> do <h6> w logicznej hierarchii. Nagłówek <h1> powinien być używany tylko raz na stronie, a kolejne nagłówki powinny być używane zgodnie z hierarchią.
  • Listy Używaj <ul> dla list nieuporządkowanych i <ol> dla list uporządkowanych. Unikaj używania <div> lub <span> do tworzenia list.
  • Tabele Używaj tabel do prezentacji danych. Dodaj <caption> opisujący tabelę i używaj nagłówków <th> z atrybutem scope=”col” lub scope=”row” dla kolumn i wierszy, aby poprawić dostępność.
  • Animacje i ruch Unikaj automatycznych animacji, które mogą być dezorientujące dla użytkowników. Jeśli musisz użyć animacji, zapewnij możliwość ich wyłączenia lub ograniczenia. Używaj prefers-reduced-motion w CSS, aby dostosować animacje do preferencji użytkownika.
  • Wideo i audio Zapewnij napisy i transkrypcje dla materiałów wideo i audio. Używaj znaczników <video> i <audio> z odpowiednimi atrybutami, takimi jak controls, aby umożliwić użytkownikom interakcję z multimediami.
  • Dynamiczne treści Jeśli używasz JavaScript do dynamicznego aktualizowania treści, upewnij się, że zmiany są ogłaszane dla czytników ekranu. Używaj aria-live i aria-atomic, aby kontrolować, jak zmiany są komunikowane użytkownikom korzystającym z technologii asystujących.
  • Testowanie dostępności Regularnie testuj swoją stronę pod kątem dostępności, używając narzędzi, takich jak Lighthouse, Axe lub WAVE. Te narzędzia pomogą zidentyfikować problemy z dostępnością i zasugerują poprawki. Ręczne testowanie dostępności jest również ważne. Używaj czytników ekranu, takich jak NVDA lub VoiceOver, aby sprawdzić, jak Twoja strona jest odczytywana przez użytkowników korzystających z technologii asystujących. Testuj na różnych urządzeniach i przeglądarkach, aby upewnić się, że dostępność jest zachowana we wszystkich warunkach. Testuj również z użytkownikami korzystającymi z technologii asystujących, aby uzyskać rzeczywiste opinie na temat dostępności Twojej strony.
 
Wskazówka
Szczegółowy zakres wymagań związanych z przepisami, znajdziesz w:
 

Podsumowanie

Dostępność jest kluczowym aspektem tworzenia stron internetowych i aplikacji. Stosowanie się do najlepszych praktyk dostępności pomoże zapewnić, że Twoje treści są dostępne dla wszystkich użytkowników, niezależnie od ich zdolności. Pamiętaj, że dostępność to proces ciągły, a regularne testowanie i aktualizowanie treści jest niezbędne, aby utrzymać wysokie standardy dostępności.

Jak skonfigurować dodatek Comarch Liquid Sync?

Jak działa Comarch Liquid Sync?

Liquid Sync synchronizuje pliki umieszczone na komputerze użytkownika z plikami szablonu Liquid. Pilnuje zgodności danych wykrywając modyfikacje w plikach lokalnych lub w plikach szablonu Liquid, a następnie podmienia nieaktualny plik na jego nowszą wersje. Dzięki aplikacji Liquid Sync nie trzeba używać edytorów kodu dostępnych w panelu administracyjnym e-Sklep. Każdy użytkownik może korzystać z dowolnego środowiska programistycznego, a Liquid Sync zadba o zgodność utworzonego lokalnie projektu z plikami w panelu administracyjnym.

Jak uruchomić Comarch Liquid Sync?

Aplikacja dostępna dla sklepów Comarch.
Liquid Sync można pobrać ze strony Liquid Sync. Rozpakowany folder będzie zawierać między innymi:
  • Katalog pl – zawiera XML z ustawieniami. Nie należy go usuwać.
  • Katalog logs – zawiera logi operacji.
  • COMARCHeShopLiquidSync – aplikacja Liquid Sync.
Aplikację należy uruchomić z prawami administratora. Po uruchomieniu zostaną otwarte dwa okna: okno konsolowe oraz okno przeglądarki z interfejsem aplikacji. Obydwa okna powinny pozostać włączone.

Jak skonfigurować Comarch Liquid Sync?

Liquid Sync potrzebuje danych logowania do sklepu. Przy pierwszym uruchomieniu widoczny będzie formularz, w którym należy wpisać:
  • Nazwę sklepu – dowolna nazwa, po której będzie można rozpoznać sklep na liście sklepów
  • Url – adres url istniejącego sklepu
  • Login – login użytkownika, na którego aplikacja ma się zalogować do panelu e-Sklepu. Należy wykorzystać login webmaster, którego konfiguracja dostępna jest w panelu administracyjnym**.
  • Hasło – hasło wskazanego użytkownika
Wskazówka
Comarch e-Sklep Liquid Sync do połączenia wymaga SSL
konfiguracja liquid sync
Wskazówka
**Zaloguj się do panelu administracyjnego e-Sklepu przejdź do zakładki Integracje > Dodaj integrację. Na filtrze Typ wybierz Dodatki. Następnie wybierz dodatek Comarch Liquid Sync, naciśnij Dodaj, a w kolejnym kroku Konfiguruj.
Po kliknięciu Zaloguj się sklep zostanie dodany do listy po lewej stronie. W prawym oknie pojawi się lista dostępnych szablonów. Szablony w sklepie połączonym z Liquid Sync Od teraz będzie to ekran startowy aplikacji. Aby dodać kolejny sklep trzeba będzie nacisnąć przycisk Dodaj sklep. Po zalogowaniu w rozpakowanym katalogu COMARCHeShopLiquidSync zostanie utworzony katalog o podanej w formularzu nazwie. Lokalny katalog sklepu utworzony przez LiquidSync Katalog będzie zawierał:
  • Katalog logs – zawiera logi operacji danego e-Sklepu
  • Katalog sync – zawiera plik z ustawieniami
  • Katalog templates – w tym miejscu będą tworzyć się podkatalogi z plikami dla dostępnych szablonów
Katalogi z plikami szablonu nie mogą zostać przeniesione.

Synchronizacja

Praca z plikami

Aby wybrać, który z szablonów aplikacja powinna synchronizować, wystarczy wybrać odpowiednią pozycję na liście dostępnych szablonów. Jeżeli synchronizacja dotyczy szablonu, który jest zabezpieczony hasłem, Liquid Sync również będzie potrzebował hasła. Hasło szablonu w Liquid Sync Po wybraniu szablonu otworzy się okno synchronizacji. Lewa kolumna o nazwie Log będzie zawierać logi synchronizacji, natomiast prawa o nazwie Pliki będzie informować o konfliktach do rozwiązania. Szynchronizacja szablonu za pomocą Liquid Sync Przy pierwszej synchronizacji szablonu, wewnątrz katalogu templates, zostanie utworzony odpowiadający mu katalog. Nazwami katalogów są id szablonów. Folder lokalny szablonu w aplikacji Liquid Sync Jeżeli w panelu administracyjnym e-Sklep nie zostały wcześniej dodane żadne pliki dla danego szablonu, to wewnątrz powyższego folderu należy samodzielnie utworzyć katalog o nazwie 0 (zero). W katalogu 0 należy umieszczać wszystkie pliki wymagające synchronizacji. Jeżeli szablon zawierał już jakiekolwiek pliki, katalog utworzy się automatycznie, a wewnątrz niego znajdować się będą pliki pobrane z panelu. Każdy nowy plik umieszczony w katalogu 0 automatycznie pojawi się w plikach szablonu Liquid w panelu administracyjnym e-Sklep. Plik lokalny synchronizowany z szablonem Liquid pliki liquid syncAplikacja Liquid Sync wyświetli również odpowiedni log. Log nowego pliku w Liquid Sync Plik lokalny zostanie również wysłany do sklepu po każdym zapisie, a jego usunięcie spowoduje usunięcie odpowiadającego pliku z szablonu Liquid.

Rozwiązywanie konfliktów

Zdarza się, że pliki lokalne nie są zgodne z plikami szablonu Liquid. W takiej sytuacji, w kolumnie Pliki, Liquid Sync wyświetli odpowiedni komunikat. Komunikat zapyta użytkownika, w jaki sposób aplikacja powinna rozwiązać konflikt. Poniżej opisane zostaną przyczyny konfliktów oraz sposoby ich rozwiązania.

Jak zmodyfikować plik w panelu administracyjnym e-Sklep?

Modyfikacja plików po stronie panelu administracyjnego, w przeciwieństwie do modyfikacji plików lokalnych, jest traktowana jako konflikt. Komunikat konfliktu, w przypadku modyfikacji istniejących plików, będzie proponował dwa rozwiązania: pobrać plik szablonu do projektu lokalnego lub wysłać lokalny plik do panelu administracyjnego. Konflikt: Pliki nie są zgodne Jeżeli zmiana zostanie wykonana w podczas aktywnej synchronizacji, należy kliknąć przycisk Odśwież, aby zobaczyć komunikat. Usunięcie pliku po stronie panelu administracyjnego będzie wymagało podjęcia decyzji: usunąć plik z lokalnego systemu plików, czy wysłać istniejący lokalnie plik do panelu administracyjnego e-Sklep. Konflikt: Brak pliku na zdalnym systemie Dodanie nowego pliku w panelu administracyjnym również wyświetli stosowny komunikat. Liquid Sync zaproponuje wtedy pobranie nowego pliku z panelu do projektu lokalnego lub usunięcie nowego pliku z szablonu Liquid. Konflikt: Brak pliku na lokalnym systemie

Jak zmodyfikować plik lokalny, kiedy aplikacja Comarch Liquid Sync była wyłączona?

Liquid Sync nie miał okazji zaktualizować pliku lokalnego po jego modyfikacji, więc wystąpiła niezgodność. W przypadku istniejących plików aplikacja wyświetli komunikat z rozwiązaniami: pobrać plik szablonu do projektu lokalnego lub wysłać plik lokalny do sklepu. Konflikt: Pliki nie są zgodne Jeżeli plik lokalny zostanie usunięty, komunikat będzie zawierał opcję pobrania odpowiadającego pliku ze sklepu lub jego usunięcie. Konflikt: Brak pliku na lokalnym systemie Gdy nowy plik zostanie dodany, rozwiązać konflikt można poprzez wysłanie nowego pliku do sklepu lub usunięcie go. Konflikt: Brak pliku na zdalnym systemie.
Wskazówka
Należy pamiętać, aby w panelu administracyjnym włączyć podgląd zmian w czasie rzeczywistym.

Co to jest Liquid?

Liquid to silnik szablonów graficznych wykorzystywany w Comarch e-Sklep. Szablony graficzne w technologii Liquid umożliwiają swobodną modyfikację wyglądu sklepu. Modyfikacji można dokonywać samodzielnie w ustawianiach szablonu, tym samym łatwo wgrywać nowe bannery, czy dostosować kolorystykę. Posiadając większą wiedzę z zakresu HTML, JS, CSS i Liquid, można głębiej ingerować w wygląd sklepu. W przypadku nie posiadania dostatecznej wiedzy, można zlecić wykonanie szablonu Partnerowi bądź firmie wdrażającej.

Dostępne filtry

Tablice

W skład tych filtrów wchodzą:
First Randomize
Last Join
Skip Map
Take Size
Sort Uniq
Reverse
 

Tekstowe

W skład tych filtrów wchodzą:
Format Size
Append Slice
Prepend Split
Capitalize StripHtml
Downcase StripNewlines
Upcase NewlineToBr
Remove Truncate
RemoveFirst TruncateWords
Replace Times
ReplaceFirst
 

Liczbowe, Matematyczne

W skład tych filtrów wchodzą:
Plus Normalize
Minus Floor
Times Ceil
DividedBy Abs
Modulo Round
 

Data i czas

W skład tych filtrów wchodzą:
Date
 

Cena

W skład tych filtrów wchodzą:
ToPrice
 

HTML

Filtry, które po zastosowaniu zwracają gotowe fragmenty kodów HTML do wykorzystania na stronie. W skład tych filtrów wchodzą:
A Img2
Img
 

Pozostałe

W skład tych filtrów wchodzą:
H ToInt
Escape ToNum
EscapeUri ToTimeSpan
UnEscapeUri DEBUG
ToString
 

 

Opis dostępnych filtrów:

 
First
Pobiera pierwszy element z tablicy. Zwracany typ: zależny co przechowuje tablica. {{ product-details.Product.Images |First |Img }}

 
Last
Pobiera ostatni element z tablicy. Zwracany typ: zależny co przechowuje tablica. {{ product-details.Product.Images |Last |Img }}

 
Skip
Zwraca tablicę, która nie zawiera początkowych elementów z tablicy wejściowej. Omija określoną liczbę elementów. Liczba elementów do ominięcia jest przekazywana w parametrze. Parametry: int. Zwracany typ: tablica elementów typu zdefiniowanego w tablicy wejściowej. {% assign koloryTekst = 'biały, czarny, zielony, czerwony, niebieski, żółty' %} {% assign kolory = koloryTekst |Split: ',' %}Wszystkie elementy {% for kolor in kolory -%} {{ kolor }} {% endfor -%} Pomiń 3 pierwsze elementy {% assign kolory = kolory |Skip: 3 %} {% for kolor in kolory -%} {{ kolor }} {% endfor -%} Powyższy przykład zwróci: Wszystkie elementy biały czarny zielony czerwony niebieski żółtyPomiń 3 pierwsze elementy czerwony niebieski żółty

 
Take
Zwraca tablicę, która zawiera tylko określoną liczbę początkowych elementów z tablicy wejściowej. Parametry: int. Zwracany typ: tablica elementów typu zdefiniowanego w tablicy wejściowej. {% assign koloryTekst = 'biały, czarny, zielony, czerwony, niebieski, żółty' %} {% assign kolory = koloryTekst |Split: ',' %}Wszystkie elementy {% for kolor in kolory -%} {{ kolor }} {% endfor -%} Pobierz tylko 3 pierwsze elementy {% assign kolory = kolory |Take: 3 %} {% for kolor in kolory -%} {{ kolor }} {% endfor -%} Powyższy przykład zwróci: Wszystkie elementy biały czarny zielony czerwony niebieski żółtyPobierz tylko 3 pierwsze elementy biały czarny zielony

 
Sort
Sortuje elementy w tablicy według przekazanego argumentu. Argument powinien być właściwością kolekcji elementów tablicy wejściowej. Parametry: string. Zwracany typ: tablica elementów typu zdefiniowanego w tablicy wejściowej. {% assign sortedFlags = product-details.Product.Flags |Sort: 'Text' %} {% for flag in sortedFlags -%} Nazwa: {{ flag.Text}} {% endfor -%}

 
Reverse
Odwraca kolejność elementów w tablicy. Zwracany typ: tablica elementów typu zdefiniowanego w tablicy wejściowej. {% assign koloryTekst = 'biały, czarny, zielony, czerwony, niebieski, żółty' %} {% assign kolory = koloryTekst |Split: ', ' %} {% assign kolory = kolory |Reverse %} Wszystkie elementy w odwróconej kolejności {% for kolor in kolory -%} {{ kolor }} {% endfor -%} Powyższy przykład zwróci: Wszystkie elementy w odwróconej kolejności żółty niebieski czerwony zielony czarny biały

 
Randomize
Zwraca tablicę, w której kolejność elementów jest ustawiona w sposób losowy. Zwracany typ: tablica elementów typu zdefiniowanego w tablicy wejściowej. {% assign koloryTekst = 'biały, czarny, zielony, czerwony, niebieski, żółty' %} {% assign kolory = koloryTekst |Split: ', ' %} {% assign kolory = kolory |Randomize %} Wszystkie elementy w losowej kolejności {% for kolor in kolory -%} {{ kolor }} {% endfor -%} Powyższy przykład może zwrócić: czerwony niebieski biały żółty czarny zielony Kolejny przykład {% assign losowyObrazek = productdetails.Product.Images |Randomize %} Pierwszy losowy obrazek na towarze {{losowyObrazek |First |Img }}

 
Join
Łączy elementy tablicy w ciąg znaków wstawiając pomiędzy elementy przekazany parametr. Parametry: string. Zwracany typ: string. {% assign koloryTekst = 'biały, czarny, zielony, czerwony, niebieski, żółty' %} {% assign tablicaKolorow = koloryTekst |Split: ', ' %} {{tablicaKolorow |Join: '. ' }} Powyższy przykład zwróci: biały. czarny. zielony. czerwony. niebieski. żółty

 
Map
Zwraca tablicę składającą się z wartości elementów kolekcji wejściowej dla wskazanej właściwości przez przekazany argument. Parametry: string. Zwracany typ: tablica elementów typu wskazanej właściwości. {% assign typyFlag = product-details.Product.Flags |Map: 'Text' %} {% for typFlagi in typyFlag -%} {{typFlagi}} {% endfor -%} Powyższy przykład może zwrócić: Promocja Najlepiej oceniany Kolejny przykład {{ config.Languages |Map: 'Name' |Join: ', ' }} Powyższy przykład może zwrócić: polski, Deutsch, français

 
Size
Zwraca liczbę elementów w tablicy. Zwracany typ: int. Liczba obrazków dla towaru {{ product-details.Product.Images |Size }}

 
Uniq
Zwraca tablicę unikatowych elementów. Tablica ta nie zawiera duplikatów. Zwracany typ: tablica elementów typu zdefiniowanego w tablicy wejściowej. {% assign kolory = "czarny,biały,niebieski,czarny,niebieski" | Split: ',' -%} {% assign unikatoweKolory = kolory | Uniq -%} {% for kolor in unikatoweKolory -%} {{kolor}} {% endfor -%} Powyższy przykład zwróci: czarny biały niebieski

 
Format
Formatuje tekst zgodnie z wartościami przekazanymi w poszczególnych parametrach. Parametry: object p1, object p2 = null, object p3 = null, object p4 = null, object p5 = null, object p6 = null, object p7 = null, object p8 = null, object p9 = null, object p10 = null. Zwracany typ: string. {% assign cenaWaluta = 'Cena: {0}, waluta {1}' -%} {{ cenaWaluta | Format:'25.00', 'PLN' }} Powyższy przykład zwróci: Cena: 25.00, waluta PLN

 
Append
Dodaje tekst przekazany przez argument na koniec tekstu wejściowego. Jeżeli tekst wejściowy == null to filtr zwróci null. Parametry: string. Zwracany typ: string. {% assign tekst1 = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' %} {% assign tekst2 = 'Litwo! Ojczyzno moja! Ty jesteś jak zdrowie.' %} {{ tekst1 |Append: tekst2 }} Powyższy przykład zwróci: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Litwo! Ojczyzno moja! Ty jesteś jak zdrowie.

 
Prepend
Dodaje tekst przekazany przez argument na początek tekstu wejściowego. Jeżeli tekst wejściowy == null to filtr zwróci null. Parametry: string. Zwracany typ: string. {% assign tekst1 = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' %} {% assign tekst2 = 'Litwo! Ojczyzno moja! Ty jesteś jak zdrowie. ' %} {{ tekst1 |Prepend: tekst2 }} Powyższy przykład zwróci: Litwo! Ojczyzno moja! Ty jesteś jak zdrowie. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

 
Capitalize
Konwertuje tekst tak, aby każde słowo w tekście zaczynało się z dużej litery.Zwracany typ: string. {% assign tekst1 = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' %} {{ tekst1 |Capitalize }}

 
Downcase
Konwertuje tekst tak, aby cały tekst (każda litera) był napisany małymi literami. Zwracany typ: string. {% assign tekst1 = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' %} {{ tekst1 | Downcase }}

 
Upcase
Konwertuje tekst tak, aby cały tekst (każda litera) był napisany wielkimi literami.Zwracany typ: string. {% assign tekst1 = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' %} {{ tekst1 |Upcase}}

 
Remove
Usuwa z tekstu wejściowego fragment tekstu przekazanego przez parametr. Parametry: string. Zwracany typ: string. {% assign tekst1 = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' %} {{ tekst1 |Remove: 'ip' }}

 
RemoveFirst
Usuwa z tekstu wejściowego pierwsze wystąpienie fragmentu tekstu przekazanego przez parametr. Parametry: string. Zwracany typ: string. {% assign tekst1 = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' %} {{ tekst1 |RemoveFirst: 'ip' }}

 
Replace
Zamienia w tekście wejściowym szukany fragment tekstu innym tekstem (tekst zamienny). Szukany fragment tekstu oraz tekst zamienny przekazywane są przez parametry. Parametry przyjmują wyrażenia regularne. Jeśli chcemy wyszukać znak specjalny i użyć go jak znaku, a nie części wyrażenia regularnego, należy go poprzedzić ukośnikiem \.Parametry: string, string = "". Zwracany typ: string. {% assign tekst2 = 'Litwo! Ojczyzno moja! Ty jesteś jak zdrowie.' %} {{ tekst2 |Replace:'!','.' }} {% assign waga = '31.53kg' %} {{ waga |Replace:'\.',',' }} {% assign spacje = ' Litwo! Ojczyzno moja! Ty jesteś jak zdrowie. ' %} {{ spacje |Replace:'^\s+|\s+$','' }}

 
ReplaceFirst
Zamienia w tekście wejściowym pierwsze wystąpienie szukanego fragmentu tekstu innym tekstem (tekst zamienny). Szukany fragment tekstu oraz tekst zamienny przekazywane są przez parametry. Parametry przyjmują wyrażenia regularne. Jeśli chcemy wyszukać znak specjalny i użyć go jak znaku, a nie części wyrażenia regularnego, należy go poprzedzić ukośnikiem \.Parametry: string, string = "". Zwracany typ: string. {% assign tekst2 = 'Litwo! Ojczyzno moja! Ty jesteś jak zdrowie.' %} {{ tekst2 |ReplaceFirst:'!','.' }}

 
Size
Zwraca długość tekstu - liczba znaków w tekście. Zwracany typ: int. Długość opisu towaru {{ productdetails.Product.Description |Size }} Kolejny przykład Liczba znaków w cenie towaru {{ productdetails.Product.Price |ToString |Size }}

 
Slice
Zwraca fragment z tekstu wejściowego dla podanej pozycji początkowej oraz długości. Pozycja początkowa oraz długość przekazywane są przez parametry. W przypadku, gdy parametr z pozycją początkową jest ujemny to pozycja początkowa liczona jest od od końca tekstu.
Uwaga
Znaki w tekście numerowane są od 0. Należy uwzględnić to przy określaniu pozycji początkowej.
Parametry: int, int = 1. Zwracany typ: string. {% assign tekst2 = 'Litwo! Ojczyzno moja! Ty jesteś jak zdrowie.' %} {{ tekst2 |Slice:0 }} {{ tekst2 |Slice:1 }} {{ tekst2 |Slice:0,20 }} {{ tekst2 |Slice: - 1 }} {{ tekst2 |Slice: - 20,10 }} Powyższy przykład zwróci: L i Litwo! Ojczyzno moja . jesteś jak

 
Split
Tworzy z tekstu wejściowego tablicę, w której każdy element stanowi fragment tekstu rozdzielony przez podany wzorzec. Wzorzec przekazany przez parametr. Parametry: string. Zwracany typ: string[]. {% assign koloryTekst = 'biały, czarny, zielony, czerwony, niebieski, żółty' %} {% assign kolory = koloryTekst |Split: ', ' %}Pierwszy element {{ kolory[0] }} Wszystkie elementy {% for kolor in kolory - %} {{ kolor }} {% endfor - %} Powyższy przykład zwróci: Pierwszy element białyWszystkie elementy biały czarny zielony czerwony niebieski żółty

 
StripHtml
Usuwa wszystkie tagi HTML z tekstu wejściowego. Zwracany typ: string. {{ productdetails.Product.Description |StripHtml }}

 
StripNewlines
Usuwa wszystkie znaki nowej linii (podziały wiersza) z tekstu wejściowego. Zwracany typ: string. {{ productdetails.Product.Description |StripNewlines }}

 
NewlineToBr
Wstawia tag HTML przed każdym znakiem nowej linii w tekście wejściowym. Zwracany typ: string. {{ productdetails.Product.Description |NewlineToBr }}

 
Truncate
Obcina tekst wejściowy do podanej liczby znaków dodając na końcu tekst obcinający. Liczba znaków oraz tekst obcinający przekazywane są przez parametry. Tekst obcinający wliczony jest w liczbę znaków. Parametry: int = 50, string = "...". Zwracany typ: string. {% assign tekst1 = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' %} {% assign tekst2 = 'Litwo! Ojczyzno moja! Ty jesteś jak zdrowie.' %} {{ tekst1 |Truncate }} {{ tekst2 |Truncate: 25, '(...)' }} Powyższy przykład zwróci: Lorem ipsum dolor sit amet, consectetur adipisc... Litwo! Ojczyzno moja(...)

 
TruncateWords
Obcina tekst wejściowy do podanej liczby wyrazów dodając na końcu tekst obcinający. Liczba wyrazów oraz tekst obcinający przekazywane są przez parametry. Parametry: int 15, string = "..." Zwracany typ: string. {% assign tekst1 = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' %} {% assign tekst2 = 'Litwo! Ojczyzno moja! Ty jesteś jak zdrowie.' %} {{ tekst1 |TruncateWords }} {{ tekst2 |TruncateWords: 3,'(...)' }} Powyższy przykład zwróci: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Litwo! Ojczyzno moja!(...)

 
Times
Powtarza tekst wielokrotnie. Liczba powtórzeń przekazywana przez parametr. Parametry: int. Zwracany typ: string. {% assign kropka = '.' %} {% assign liczbaPowtorzen = 3 %} Przykładowy tekst zakończony kropkami{{ kropka|Times: liczbaPowtorzen }}

 
Plus
Dodawanie. Parametry: int/decimal. Zwracany typ: taki sam jak element wejściowy, na którym wywołany jest filtr. {% assign liczba1 = 9 %} {% assign liczba2 = 2 %} Wynik: {{ liczba1 | Plus: liczba2 }}
Uwaga
Jeśli filtr Plus wywołany zostanie na elemencie wejściowym typu string to działanie będzie podobne do użycia filtru Append.
 

 
Minus
Odejmowanie. Parametry: int/decimal. Zwracany typ: taki sam jak element wejściowy, na którym wywołany jest filtr. {% assign liczba1 = 9 %} {% assign liczba2 = 3 %} Wynik: {{ liczba1 |Minus: liczba2 }}

 
Times
Mnożenie. Parametry: int/decimal. Zwracany typ: taki sam jak element wejściowy, na którym wywołany jest filtr. {% assign liczba1 = 9.01 %} {% assign liczba2 = 2 %} Wynik: {{ liczba1 |Times: liczba2 }}

 
DividedBy
Dzielenie. Parametry: int/decimal. Zwracany typ: taki sam jak element wejściowy, na którym wywołany jest filtr. {% assign liczba1 = 9 %} {% assign liczba2 = 3 %} Wynik:{{ liczba1 |DividedBy: liczba2 }}

 
Modulo
Reszta z dzielenia. Parametry: int/decimal. Zwracany typ: taki sam jak element wejściowy, na którym wywołany jest filtr. {% assign liczba1 = 9.01 %} {% assign liczba2 = 2 %} Wynik:{{ liczba1 |Modulo: liczba2 }}

 
Normalize
Formatuje liczbę wejściową usuwając jej „zbędne” zera w części ułamkowej. Typ liczby wejściowej: decimal. Zwracany typ: decimal. Cena: {{ productdetails.Product.Price }} Cena: {{ productdetails.Product.Price |Normalize }} Powyższy przykład może zwrócić: Cena: 10,00 Cena: 10

 
Floor
Zwraca największą liczbę całkowitą, która jest mniejsza lub równa wejściowej. Typ liczby wejściowej: decimal. Zwracany typ: int. {% assign liczba = 6.05 %} Wynik:{{ liczba |Floor }} Powyższy przykład zwróci: Wynik:6

 
Ceil
Zwraca najmniejszą liczbę całkowitą, która jest większa lub równa wejściowej.Typ liczby wejściowej: decimal. Zwracany typ: int. {% assign liczba = 6.05 %} Wynik:{{ liczba |Ceil }} Powyższy przykład zwróci: Wynik:7

 
Abs
Zwraca wartość bezwzględną z liczby. {% assign liczba = -6.05 %} Wynik:{{ liczba |Abs }} Powyższy przykład może zwrócić: Wynik:6.05

 
Round
Zaokrągla liczbę wejściową do określonej ilości miejsc po przecinku. Zwracany typ: taki sam jak element wejściowy, na którym wywołany jest filtr. {% assign liczba = 6.05687 %} Wynik:{{ liczba |Round: 4 }} Powyższy przykład zwróci: Wynik:6.0569

 
Date
Formatuje datę i czas. Zwraca datę i czas zgodnie z formatem przekazanym w parametrze.
Wskazówka
Filtr Date w sklepie korzysta z domyślnych ustawień dla DotLiquid. Należy korzystać z formatu daty zgodnego z konwencją .NET dostępnym pod linkiem: https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.100).aspx
Parametry: string. Zwracany typ: string. Data i czas "teraz" {{ config.Now }} Data {{ config.Now |Date:'yyyy-MM-dd' }} Czas {{ config.Now |Date:'HH:mm:ss' }} Powyższy przykład może zwrócić: Data i czas "teraz" 13.10.2022 10:32:39 Data 2022-10-13 Czas 10:32:39

 
ToPrice
Formatuje cenę do formatu wyświetlania zgodnego z kulturą dla ustawionej lokalizacji sklepu (grupowanie tysięcy, kropka czy przecinek, itd.). Lokalizacja sklepu określa, czy sklep został zainstalowany domyślnie na rynek polski, niemiecki, itd. Zwracany typ: string. Cena: {{ product-details.Product.Price }} Cena: {{ product-details.Product.Price |ToPrice }} Powyższy przykład może zwrócić: Cena: 2348,68 Cena: 2 348,68 (lokalizacja na rynek polski)

 
A
Tworzy tag <a>wraz z atrybutami. Wartości dla atrybutów tagu pobierane są z elementu wejściowego. Typ elementu wejściowego: obiekt Liquid. Zwracany typ: string. Filtr ma zastosowanie dla obiektów:
  • Strona
  • Grupa towarowa
  • Towar
  • Blog
  • Tagi
Przykład użycia filtra A dla obiektów: Strona Strony {{ config.DefinedPages.Home |A |H }} {{ config.Pages['6'] |A |H }} {% comment %} Strona o id = 6 {% endcomment %} {{ page.CurrentSiteNode |A |H }} {{ page.GroupNodes[0] |A |H }} {{ page.Breadcrumbs[0] |A |H }} Powyższy przykład może zwrócić: Strony <a href="./">Strona główna</a> <a href="profil-klienta,6">Profil klienta</a> <a href="produkty/owoce-1/banany-555,2,1024703">Banany</a> <a href="produkty/owoce-1,2,76">Owoce</a> <a href="./">Strona główna</a> Przykład użycia filtra A dla obiektów: Towar Towary {{ product-new.Products[0] |A |H }} {{ product-list.Products[1] |A |H }} {{ product-details.Product |A |H }} Powyższy przykład może zwrócić: Towary <a href="banany,3,1024703,81">Banany</a> <a href="minibanany-odrobina-wystarczy,3,1024703,82">Minibanany odrobina wystarczy</a> <a href="minibanany-odrobina-wystarczy,3,1024703,82">Minibanany odrobina wystarczy</a> Przykład użycia filtra A dla obiektów: Blog, Tags Blog {{ blog.PostList.Posts[0] |A |H }} {{ blog.PostDetails |A |H }} Tags {{ config.Tags.Blog[0] |A |H }} Powyższy przykład może zwrócić: Blog <a href="blog-wpis-podstawowy,24,1">Blog wpis podstawowy</a> <a href="blog-wpis-podstawowy,24,1">Blog wpis podstawowy</a> Tags <a rel="tag" href="blog,23?seaBlog=Informacje">Informacje</a>

 
Img
Tworzy tag <img>wraz z atrybutami. Wartości dla atrybutów tagu pobierane są z elementu wejściowego lub mogą być przekazywane przez parametry.
Uwaga
Tag <img> domyślnie ustawiony ma link do obrazka w atrybucie data-src. Należy zastosować funkcję skryptową, która przepisze wartość z atrybutu data-src do atrybutu src (lazy load).
Typ elementu wejściowego: obiekt Liquid, string. Parametry: string size = "small", string alt = null, string title = null. Zwracany typ: string. Dostępne wartości dla parametru size:
Parametr size Rozmiar zdjęcia (dłuższa krawędź) w px
img 0
pico 16
icon 32
thumb 50
small 100
compact 160
medium 240
large 480
grande 600
master 1920
Filtr ma zastosowanie dla obiektów:
  • Towar
  • Zdjęcia towaru (na szczegółach towaru)
  • Producent
  • Marka
  • Blog (w obiekcie blog pomijany jest parametr size. Obrazki zwracane są zawsze w rozmiarze rzeczywistym).
Przykład użycia filtra Img dla obiektów: Towar, Zdjęcia towaru Lista towarów {{ product-list.Products[1] |Img |H }} {{ produc-tlist.Products[1] |Img: 'medium','Świeże banany, Kraków' |H }} Towar (szczegóły) {{ product-details.Product |Img:'large' |H }} {{ product-details.Product.StockLevel.ImageUrl |Img |H }} { % comment % } Tekst z linkiem {% endcomment %} {{ product-details.Product.Images[0] |Img |H }} Powyższy przykład może zwrócić: Lista towarów <img alt="Minibanany odrobina wystarczy" src="usr/alo.gif" data-src="img/small/59/minibanany.jpg"/> <img alt="Świeże banany, Kraków" src="usr/alo.gif" data-src="img/medium/59/minibanany.jpg"/> Towar (szczegóły) <img alt="Minibanany odrobina wystarczy" src="usr/alo.gif" data-src="img/large/59/minibanany.jpg"/> <img src="usr/alo.gif" data-src="Ima.ashx?t=wrs&Id=1"/> <img alt="" src="usr/alo.gif" data-src="img/small/59/.jpg"/> Przykład użycia filtra Img dla obiektów: Producent, Marka Producent, Marka {{ manufacturers-brands.Manufacturers[2] |Img |H }} {{ manufacturers-brands.Manufacturers[2] |Img: 'thumb','Comarch globalny dostawca IT.' |H }} {{ manufacturers-brands.Brands[3] |Img |H }} Powyższy przykład może zwrócić: Producent, Marka <img alt="Comarch" src="usr/alo.gif" data-src="img/small/160/Comarch.jpg"/> <img alt="Comarch globalny dostawca IT." src="usr/alo.gif" data-src="img/thumb/160/Comarch.jpg"/> <img alt="Comarch ALTUM" src="usr/alo.gif" data-src="img/small/92/Comarch%20ALTUM.jpg"/> Przykład użycia filtra Img dla obiektów: Blog Blog {{ blog.LatestPosts[0] |Img |H }} {{ blog.PostList.Posts[0] |Img: 'compact','Blog dla Partnera','Informacje dla Partnerów na blogu sklepu' |H }} {{ blog.PostDetails |Img |H }} Powyższy przykład może zwrócić: Blog <img alt="Blog wpis podstawowy" src="usr/alo.gif" data-src="Ima.ashx?t=blg&id=1"/> <img alt="Blog dla Partnera" title="Blog dla Partnera,'Informacje dla Partnerów na blogu sklepu" src="usr/alo.gif" data-src="Ima.ashx?t=blg&id=1"/> <img alt="Blog wpis podstawowy" src="usr/alo.gif" data-src="Ima.ashx?t=blg&id=1"/> Przykład użycia filtra Img dla tekstu z linkiem do obrazka Tekst z linkiem do obrazka {{ productdetails.Product.StockLevel.ImageUrl |Img |H }} { % comment % } Tekst z linkiem {% endcomment %} {{ 'https://www.domena.pl/file/banner.jpg' |Img:'','atrybut alt','atrybut title' |H }} Powyższy przykład może zwrócić Tekst z linkiem do obrazka <img src="usr/alo.gif" data-src="Ima.ashx?t=wrs&Id=1"/> <img alt="atrybut alt" title="atrybut title"src="usr/alo.gif" data-src="https://www.domena.pl/file/banner.jpg"/>

 
Img2
Filtr Img2 zachowuje się w podobny sposób jak wyżej opisany filtr Img. Różnicą jest to, że utworzony tag <img> ma link do obrazka nie w atrybucie data-src, lecz w atrybucie data-lazy. Dodatkowo filtr Img2 pozwala na dodanie czwartego parametru raw, w którym można wpisać wszystko, np. class="example_class" i znajdzie się to wewnątrz tagu <img>.Typ elementu wejściowego: obiekt Liquid, string. Parametry: string size = "small", string raw = null, string alt = null, string title = null. Zwracany typ: string.Przykład użycia filtra Img2 na szczegółach towaru: {{product.Images[0] |Img2 :'large', '', 'pasek', 'obrazek' }} {{product.Images[0] |Img2: 'large', 'class="open-gallery"', 'pasek', 'obrazek' }} Powyższy przykład może zwrócić: <img src="img/large/27/.jpg" alt="pasek" title="obrazek" style="opacity: 1;"> <img src="img/large/27/.jpg" alt="pasek" title="obrazek" class="open-gallery" style="opacity: 1;">

 
H
Zamienia znaki specjalne na encje HTML (HTMLEncode).Zwracany typ: string. {% assign tekst2HTML = '<p>Litwo! <b>Ojczyzno moja!</b> Ty jesteś jak zdrowie.</p>' %} Tekst z encjami HTML {{ tekst2HTML |H }} Powyższy przykład zwróci: Tekst z encjami HTML <p>Litwo! <b>Ojczyzno moja!</b> Ty jesteś jak zdrowie.</p>

 
Escape
Alias dla filtra H.

 
EscapeUri
Zamienia znaki spoza zakresu ASCII na format zgodny z ASCII. Zwracany typ: string. {% assign tekst2 = 'Litwo! Ojczyzno moja! Ty jesteś jak zdrowie.' %} Link użytkownika {{ '<'|H }}a href="/?tekst={{ tekst2 | EscapeUri }}" (...) Powyższy przykład zwróci: Link użytkownika <a href="/?tekst=Litwo!%20Ojczyzno%20moja!%20Ty%20jeste%C5%9B%20jak%20zdrowie." (...)

 
UnEscapeUri
Filtr przeciwstawny do filtra EscapeUri. Zwracany typ: string.

 
ToString
Konwertuje element wejściowy do typu string. Zwracany typ: string. {% assign tekst2 = ' Litwo! Ojczyzno moja! Ty jesteś jak zdrowie.' %} {% assign liczba = 3 %} Liczba i tekst: {{ liczba |ToString |Append: tekst2 }} Powyższy przykład zwróci: Liczba i tekst: 3 Litwo! Ojczyzno moja! Ty jesteś jak zdrowie.

 
ToInt
Konwertuje element wejściowy do typu int. Zwracany typ: int. {% assign tekstLiczba1 = '9' %} {% assign liczba1 = tekstLiczba1 |ToInt %} ToInt: {{ liczba1 }} | {{ liczba1 |Minus: 4 }} Powyższy przykład zwróci: ToInt: 9 | 5

 
ToNum
Konwertuje element wejściowy zgodnie z formatem dla kultury Invariant (zapewnia zawsze taki sam format). Liczby oraz daty wyświetlane są zgodnie z kulturą dla lokalizacji sklepu. Zwracany typ: string. liczba: {{ 1239,01 }} liczba (Invariant) : {{ 1239,01 |ToNum }} data: {{config.Now }} data (Invariant) {{config.Now |ToNum }} Powyższy przykład może zwrócić: liczba: 1239,01 liczba (Invariant) : 1239.01 data: 29.04.2016 14:45:24 data (Invariant) 04/29/2016 14:45:24

 
ToTimeSpan
Konwertuje tekst do typu TimeSpan zgodnie z formatem dla kultury Invariant. Zwracany typ: TimeSpan. TimeSpan: {{ '509.07:01:01' |ToTimeSpan }}

 
DEBUG
Wyświetla obiekty globalne i lokalne wraz z jego właściwościami oraz odpowiadającymi im wartościami. Przykład wyświetlenia obiektu customer z filtrem DEBUG <fieldset> <legend>DEBUG customer</legend> <code>{{ customer | DEBUG }}</code> </fieldset> </fieldset> Powyższy przykład może zwrócić: { "NewsletterSubscriber" : false, "Authenticated" : false, "CustomerDetailsEditable" : true, "Currency" : "PLN", "CurrencyExt" : { "Code" : "PLN", "Symbol" : "zł" },(...)
Uwaga
Tryb debug dla obiektów dostępny jest tylko, gdy włączony jest parametr Podgląd stron w czasie rzeczywistym
 

Obiekty lokalne

Niniejszy artykuł przedstawia wykaz obiektów lokalnych dostępnych w sklepie. Obiekty mogą być wykorzystywane w szablonach graficznych sklepu. Odwołanie do obiektu w szablonie następuje poprzez jego nazwę zmiennej nadaną w momencie dodania obiektu do szablonu. Dla każgdego obiektu opisano:
  • opcje konfiguracyjne
  • strony, na których może być użyty
  • właściwości obiektu
Wskazówka
Obiekty lokalne domyślnie nie są dostępne w sklepie. Obiekt należy dodać, oraz aktywować na wybranych stronach. Obiekty lokalne są importowane wraz z szablonem. Obiekt udostępnia informacje o aktualnej stronie.

Nowości i promocje

Obiekt zwraca listę towarów wg właściwości, np. nowości, promocje, itd.
Konfiguracja

Konfiguracja

Dostępne opcje konfiguracyjne:
  • Pokaż towary tylko ze zdjęciem
  • Zawężaj do wybranej grupy
  • Ilość
  • Typ
Pokaż towary tylko ze zdjęciem – Towary tylko ze zdjęciem. Wartość domyślna: true. Zawężaj do wybranej grupy – Zawęża wyświetlane towary wg wybranego typu tylko do tych towarów, które należą do tej samej grupy co przeglądany towar na stronie szczegóły towaru. Wartość domyślna: true. Ilość – Liczba towarów. Wartość minimalna: 1. Wartość maksymalna: 50. Wartość domyślna: 12. Typ – Towary wg właściwości. Wartość domyślna: 1 – Promocja. Dostępne wartości:
  1. Promocja
  2. Nowość
  3. Najczęściej oglądane
  4. Najczęściej kupowane
  5. Cross-Selling
  6. Towar z gazetki
  7. Towar polecany
  8. Wyprzedaż
  9. Superjakość
  10. Supercena
  11. Najlepiej oceniany
  12. Rekomendacja sprzedawcy
  13. Dostępność–Zapowiedź
  14. Towary sugerowane (sugerowane do sprzedaży z ERP)
  15. Nagroda

Dostępny na stronach

Obiekt może być dodany na wszystkich dostępnych stronach w sklepie. Obiekt może być dodany wielokrotnie na stronie.
Obiekt posiada właściwość productnew.Products, czyli tablicę z listą towarów.
Wskazówka
Nazwa obiektu jest przykładowa.
Tablica productnew.Products posiada z kolei następujące właściwości:
productnew.Products.AskForPrice productnew.Products.Manufacturer
productnew.Products.Availability productnew.Products.MinPrice
productnew.Products.BasicUnitMinQuantity productnew.Products.Name
productnew.Products.Brand productnew.Products.NameNoHtml
productnew.Products.Code productnew.Products.NoDiscount
productnew.Products.DecimalPlacesPrice productnew.Products.PreviousPrice
productnew.Products.DecimalUnit productnew.Products.Price
productnew.Products.DefaultGroup productnew.Products.Rating
productnew.Products.Flags productnew.Products.RatingCount
productnew.Products.GIDNumber productnew.Products.RegularPrice
productnew.Products.HasAttributes productnew.Products.SaleUnit
productnew.Products.HasOtherUnits productnew.Products.Type
productnew.Products.Id productnew.Products.UPC
productnew.Products.Image productnew.Products.UnitPriceRatio
productnew.Products.ImageId productnew.Products.UnitPriceUnit
productnew.Products.Images productnew.Products.Url
productnew.Products.Link productnew.Products.Weight
 

Siatka towarów

Obiekt zwraca listę towarów wg wybranego kryterium źródła danych.
Konfiguracja

Konfiguracja

Dostępne opcje konfiguracyjne:
  • Pokaż towary tylko ze zdjęciem
  • Ilość
  • Typ
  • Wartość
Pokaż towary tylko ze zdjęciem – Towary tylko ze zdjęciem. Wartość domyślna: true. Ilość – Liczba towarów. Wartość minimalna: 1. Wartość maksymalna: 50. Wartość domyślna: 12. Typ – Towary wg źródła. Wartość domyślna: 1 – Wybór ręczny. Dostępne wartości:
  1. Ręczny
  2. Grupa towarowa
  3. Producent
  4. Marka
  5. Ostatnio oglądane
Wartość – W zależności od wartości parametru Typ przyjmuje wartości:
  1. Id towarów oddzielone przecinkiem
  2. Id grupy
  3. Id producenta
  4. Id marki
Wartość domyślna: Pusty ciąg znaków.

Dostępny na stronach

Obiekt może być dodany na wszystkich dostępnych stronach w sklepie. Obiekt może być dodany wielokrotnie na stronie.
Obiekt posiada właściwość Products.
Wskazówka
Nazwa obiektu jest przykładowa.
W jej skład wchodzą następujące właściwości:
productlastviewed.Products.AskForPrice productlastviewed.Products.Manufacturer
productlastviewed.Products.Availability productlastviewed.Products.MinPrice
productlastviewed.Products.BasicUnitMinQuantity productlastviewed.Products.Name
productlastviewed.Products.Brand productlastviewed.Products.NameNoHtml
productlastviewed.Products.Code productlastviewed.Products.NoDiscount
productlastviewed.Products.DecimalPlacesPrice productlastviewed.Products.PreviousPrice
productlastviewed.Products.DecimalUnit productlastviewed.Products.Price
productlastviewed.Products.DefaultGroup productlastviewed.Products.Rating
productlastviewed.Products.Flags productlastviewed.Products.RatingCount
productlastviewed.Products.GIDNumber productlastviewed.Products.RegularPrice
productlastviewed.Products.HasAttributes productlastviewed.Products.SaleUnit
productlastviewed.Products.HasOtherUnits productlastviewed.Products.Type
productlastviewed.Products.Id productlastviewed.Products.UPC
productlastviewed.Products.Image productlastviewed.Products.UnitPriceRatio
productlastviewed.Products.ImageId productlastviewed.Products.UnitPriceUnit
productlastviewed.Products.Images productlastviewed.Products.Url
productlastviewed.Products.Link productlastviewed.Products.Weight
 

Lista towarów

Obiekt zwraca listę towarów dla wybranej kategorii lub kryterium wyszukiwania.
Konfiguracja

Konfiguracja

Dostępne opcje konfiguracyjne:
  • Ilość
  • Sortuj według
  • pageId
  • sort
Ilość – Liczba towarów. Wartość minimalna: 1. Wartość maksymalna: 50. Wartość domyślna: 12. Sortuj według – Domyślne sortowanie listy towarów. Wartość domyślna: Nazwa (A-Z). Dostępne wartości:
  1. Najczęściej kupowane
  2. Najczęściej oglądane
  3. Nazwa (A-Z)
  4. Nazwa (Z-A)
  5. Cena rosnąco
  6. Cena malejąco
  7. Producent (A-Z)
  8. Kod towaru (A-Z)
  9. Kod towaru (Z-A)
  10. Najlepiej ocenianie
  11. Domyślnie
  12. Ostatnio dodane
  13. Ostatnio zmodyfikowane
pageId – Nazwa parametru w query string odpowiedzialna za wyświetlaną stronę (paginacja). Wartość domyślna: pageId. sort – Nazwa parametru w query string odpowiedzialna za sortowanie. Wartość domyślna: sort.

Dostępny na stronach

Obiekt może być dodany tylko na stronach
  • która pełni funkcję strony z listą towarów
  • która pełni funkcję strony ze szczegółami towaru.
Obiekt może być dodany tylko jednokrotnie na stronie.
Obiekt posiada następujące właściwości:
Wskazówka
Nazwa obiektu jest przykładowa.
productlist.FilteringOptions productlist.Search
productlist.HeaderData productlist.SelectedSorting
productlist.ItemsPerPage productlist.SortingOptions
productlist.PageCount productlist.SortingQueryGET
productlist.PageNo productlist.Supervisor
productlist.PageQueryGET productlist.TotalItems
productlist.Products.[nr produktu]
 

Prezentacja towaru

Obiekt zwraca szczegółowe informacje o wybranym towarze.
Konfiguracja

Konfiguracja

Dostępne opcje konfiguracyjne:
  • Zawężaj do wybranej grupy
Zawężaj do wybranej grupy – Zawęża wyświetlane towary wybranego producenta oraz wybranej marki tylko do tych towarów, które należą do tej samej grupy co przeglądany towar na stronie szczegóły towaru. Wartość domyślna: true.

Dostępny na stronach

Obiekt może być dodany tylko na stronie, która pełni funkcję strony ze szczegółami towaru. Obiekt może być dodany tylko jednokrotnie na stronie.
Obiekt posiada właściwość Product w której skład wchodzą następujące właściwości:
Wskazówka
Nazwa obiektu jest przykładowa.
productdetails.Product.Accessories productdetails.Product.MetaTitle
productdetails.Product.AddedDate productdetails.Product.ModifiedDate
productdetails.Product.Archival productdetails.Product.MoreInfoUrl
productdetails.Product.AskForPrice productdetails.Product.Name
productdetails.Product.Attachments productdetails.Product.Name1
productdetails.Product.Attributes productdetails.Product.NameNoHtml
productdetails.Product.AttributesEditable productdetails.Product.NetWeight
productdetails.Product.AttributesList productdetails.Product.NoDiscount
productdetails.Product.AttributesPolyvalent productdetails.Product.OrdersCount
productdetails.Product.Availability productdetails.Product.ParentId
productdetails.Product.BasicUnit productdetails.Product.Points
productdetails.Product.BasicUnitMinQuantity productdetails.Product.PointsPrice
productdetails.Product.BasicUnitRatio productdetails.Product.PreviousPrice
productdetails.Product.Batch productdetails.Product.Price
productdetails.Product.Brand productdetails.Product.Rating
productdetails.Product.BrandProducts productdetails.Product.RatingCount
productdetails.Product.CN productdetails.Product.RegularPrice
productdetails.Product.Clip productdetails.Product.Related
productdetails.Product.Code productdetails.Product.RelatedProducts
productdetails.Product.ControlStock productdetails.Product.SaleUnit
productdetails.Product.DecimalPlacesPrice productdetails.Product.Sets
productdetails.Product.DecimalUnit productdetails.Product.ShortDescription
productdetails.Product.DefaultGroup productdetails.Product.Sold
productdetails.Product.DeliveryCostType productdetails.Product
productdetails.Product.Dimensions productdetails.Product.StockLevel
productdetails.Product.Flags productdetails.Product.SubtotalMinPrice
productdetails.Product.GIDNumber productdetails.Product.SubtotalPreviousPrice
productdetails.Product.HasAttributes productdetails.Product.SubtotalPrice
productdetails.Product.HasDefaultUnit productdetails.Product.SubtotalRegularPrice
productdetails.Product.HasOtherUnits productdetails.Product.Supervisor
productdetails.Product.Hits productdetails.Product.Supplies
productdetails.Product.Id productdetails.Product.Symbol
productdetails.Product.Image productdetails.Product.TotalMinPrice
productdetails.Product.ImageId productdetails.Product.TotalPreviousPrice
productdetails.Product.Images productdetails.Product.TotalPrice
productdetails.Product.Link productdetails.Product.TotalRegularPrice
productdetails.Product.Manufacturer productdetails.Product.Type
productdetails.Product.ManufacturerCode productdetails.Product.UPC
productdetails.Product.ManufacturerProducts productdetails.Product.UnitPriceRatio
productdetails.Product.MinPrice productdetails.Product.UnitPriceUnit
productdetails.Product.MetaDescription productdetails.Product.Units
productdetails.Product.MetaKeywords productdetails.Product.Url
productdetails.Product.VAT productdetails.Product.WasteMgmtCost
productdetails.Product.Weight productdetails.Product.YouTubeVideos
 

Nagłówek

Obiekt zwraca menu kategorii i stron.
Konfiguracja

Konfiguracja

Dostępne opcje konfiguracyjne:
  • Poziom rozwinięcia
  • Ilość poziomów
  • Typ
Poziom rozwinięcia – Głębokość do jakiej maksymalnie może rozwinąć się menu. Wartość minimalna: 0 Wartość maksymalna: 10 Wartość domyślna: 0. Ilość poziomów – ilość poziomów na temat których obiekt przetrzymuje dane. Typ – Grupy wg wyboru. Wartość domyślna: Grupy najwyższego poziomu. Dostępne wartości:
  1. Grupy najwyższego poziomu
  2. Podgrupy począwszy od
  3. Wybrane
  4. Zawężaj menu do wybranej grupy

Dostępny na stronach

Obiekt może być dodany na wszystkich dostępnych stronach w sklepie. Obiekt może być dodany tylko jednokrotnie na stronie.
Obiekt posiada właściwość Nodes w której skład wchodzą następujące właściwości:
Wskazówka
Nazwa obiektu jest przykładowa.
header.Nodes.Count header.Nodes.ImageId
header.Nodes.Groups header.Nodes.Name
header.Nodes.Heading header.Nodes.Product
header.Nodes.Id header.Nodes.Url
header.Nodes.Image
 

Menu producentów i marek

Obiekt zwraca listę producentów oraz marek.
Konfiguracja

Konfiguracja

Obiekt nie posiada opcji konfiguracyjnych.

Dostępny na stronach

Obiekt może być dodany na wszystkich dostępnych stronach w sklepie. Obiekt może być dodany tylko jednokrotnie na stronie.
Obiekt posiada następujące właściwości:
Wskazówka
Nazwa obiektu jest przykładowa.
manufacturersbrands.Brands manufacturersbrands.Manufacturers
 

Tekst

Obiekt zwraca tekst wpisany w panelu administracyjnym.
Konfiguracja

Konfiguracja

Dostępne opcje konfiguracyjne:
  • Język
  • Treść
Język – Dla jakiego języka będzie wyświetlany wpisany poniżej tekst. Treść – Treść wyświetlana przez obiekt dla danego języka.

Dostępny na stronach

Obiekt może być dodany na wszystkich dostępnych stronach w sklepie. Obiekt może być dodany wielokrotnie na stronie.
Obiekt posiada tylko jedną właściwość:
Wskazówka
Nazwa obiektu jest przykładowa.
text.Content
 

Opinie

Obiekt zwraca oceny, opinie dla wybranego towaru.
Konfiguracja

Konfiguracja

Dostępne opcje konfiguracyjne:
  • pageId
pageId – Nazwa parametru w query string odpowiedzialna za wyświetlaną stronę(paginacja). Wartość domyślna: rvPageId.

Dostępny na stronach

Obiekt może być dodany tylko na stronie, która pełni funkcję strony ze szczegółami towaru. Obiekt może być dodany tylko jednokrotnie na stronie.
Obiekt posiada następujące właściwości:
Wskazówka
Nazwa obiektu jest przykładowa.
productuserreviews.ItemsPerPage productuserreviews.PageQueryGET
productuserreviews.PageCount productuserreviews.Reviews
productuserreviews.PageNo productuserreviews.TotalItems
 

Porównywarka towarów

Obiekt zwraca listę towarów dodanych do porównania.
Konfiguracja

Konfiguracja

Obiekt nie posiada opcji konfiguracyjnych.

Dostępny na stronach

Obiekt może być dodany tylko na stronie, która pełni funkcję strony z porównywarką towarów. Obiekt może być dodany tylko jednokrotnie na stronie.
Obiekt ten przetrzymuje informacje na temat porównywanych produktów.
Wskazówka
Nazwa obiektu (comparison-tool) jest przykładowa.
comparison-tool.Attributes comparison-tool.Products
 

Profil klienta

Obiekt zwraca szczegółowe informacje o zalogowanym kliencie.
Konfiguracja

Konfiguracja

Dostępne opcje konfiguracyjne:
  • orderPageId
  • orderId
  • reviewPageId
  • reviewAwaitingPageId
  • historyPageId
  • complaintsPageId
  • complaintId
  • loyaltyPageId
orderPageId – Nazwa parametru w query string odpowiedzialna za wyświetlaną stronę (paginacja). Wartość domyślna: ordPageId. orderId – Nazwa parametru w query string odpowiedzialna za wyświetlanie szczegółów zamówienia. Wartość domyślna: orderId. reviewPageId – Nazwa parametru w query string odpowiedzialna za wyświetlaną stronę (paginacja). Wartość domyślna: rvPageId. reviewAwaitingPageId – Nazwa parametru w query string odpowiedzialna za wyświetlaną stronę (paginacja). Wartość domyślna: rvAwPageId. historyPageId – Nazwa parametru w query string odpowiedzialna za wyświetlaną stronę (paginacja). Wartość domyślna: hsPageId. complaintsPageId – Nazwa parametru w query string odpowiedzialna za wyświetlaną stronę (paginacja). Wartość domyślna:complaintsPageId. complaintId – Nazwa parametru w query string odpowiedzialna za wyświetlaną stronę. Wartość domyślna: complaintId. loyaltyPageId – Nazwa parametru w query string odpowiedzialna za wyświetlaną stronę (paginacja). Wartość domyślna: ltyPageId.

Dostępny na stronach

Obiekt może być dodany tylko na stronie, która pełni funkcję strony z profilem klienta. Obiekt może być dodany tylko jednokrotnie na stronie.
Obiekt ten przetrzymuje następujące właściwości:
Wskazówka
Nazwa obiektu jest przykładowa.
customerprofile.Complaint customerprofile.LoyaltyHistory
customerprofile.ComplaintQueryGET customerprofile.Newsletter
customerprofile.ComplaintsActive customerprofile.Offer
customerprofile.ComplaintsExecuted customerprofile.OfferDetPageQueryGET
customerprofile.Consents customerprofile.OfferQueryGET
customerprofile.DiscountDetPageQueryGET customerprofile.Offers
customerprofile.DiscountERPDetails customerprofile.OffersPageQueryGet
customerprofile.DiscountQueryGET customerprofile.Order
customerprofile.Discounts customerprofile.OrderDetPageQueryGET
customerprofile.DiscountsERP customerprofile.OrderQueryGET
customerprofile.DiscountsEshop customerprofile.Orders
customerprofile.DiscountsPageQueryGet customerprofile.OrdersActive
customerprofile.Employees customerprofile.OrdersExecuted
customerprofile.History customerprofile.ProductsToRate
customerprofile.Inquiries customerprofile.Reviews
customerprofile.InquiriesPageQueryGet customerprofile.WishList
customerprofile.LinkedAccounts
 

Blog

Obiekt zwraca wpisy z bloga.
Konfiguracja

Konfiguracja

Dostępne opcje konfiguracyjne:
  • pageId
pageId – Nazwa parametru w query string odpowiedzialna za wyświetlaną stronę (paginacja). Wartość domyślna: pageId.

Dostępny na stronach

Obiekt może być dodany na wszystkich dostępnych stronach w sklepie. Obiekt może być dodany tylko jednokrotnie na stronie.
Obiekt posiada następujące właściwości:
Wskazówka
Nazwa obiektu jest przykładowa.
blog.LatestPosts blog.PostList
blog.PostDetails
Uwaga
Obiekt zwraca właściwość LatestPosts zawsze. Aby móc skorzystać z tej właściwości, należy ją obsłużyć w ramach własnej modyfikacji szablonu. Właściwość PostList aktywuje się na stronie, która pełni funkcję listy wpisów na blogu, na pozostałych stronach właściwość zwraca null. Właściwość PostDetails aktywuje się na stronie, która pełni funkcję szczegółów wpisu na blogu, na pozostałych stronach właściwość zwraca null.
 

Zamówienie

Obiekt zwraca dane o zamówieniu oraz informacje niezbędne do złożenia zamówienia (np. sposoby dostawy i płatności).
Konfiguracja

Konfiguracja

Obiekt nie posiada opcji konfiguracyjnych.

Dostępny na stronach

Obiekt może być dodany tylko na stronie, która pełni funkcję strony gdzie składa się zamówienie. Obiekt może być dodany tylko jednokrotnie na stronie.
Obiekt ten przetrzymuje następujące właściwości:
Wskazówka
Nazwa obiektu jest przykładowa.
cart.Attachments cart.PlacedOrder
cart.Attributes cart.Points
cart.AuthenticationRequired cart.PointsForValue
cart.CartEmpty cart.PointsPaid
cart.Changes cart.PointsPrice
cart.CollectionPointMapUrl cart.PointsPriceTotalValue
cart.CompanyOnly cart.PreOrder
cart.Coupon cart.Products
cart.Currency cart.ProductsMinimumTotalValue
cart.CurrencyExt cart.ProductsSubtotalValue
cart.Customer cart.ProductsSubtotalValueBeforeDiscount
cart.DeliveryMethods cart.ProductsTotalValue
cart.Demo cart.ProductsTotalValueBeforeDiscount
cart.Discount cart.ProductsValue
cart.EditedOrderId cart.ProductsValueBeforeDiscount
cart.GratisItems cart.SelectedDelivery
cart.NotDeterminedDeliveryCost cart.SelectedDeliveryPaymentChannelKey
cart.NotDeterminedProductsDeliveryCost cart.SelectedDeliveryPaymentId
cart.Note cart.SplitPayment
cart.OSS cart.SubtotalPrices
cart.OrderStep cart.ThirdPartyHTML
cart.OrderTotalValue cart.ThirdPartyScripts
cart.OrderValueDiscounts cart.VATValue
 

Dodatkowe właściwości dla wersji Enterprise

Właściwości obiektów dostępne tylko w sklepach w wersji Enterprise.  

Towary

Właściwości:
  • Batch
  • TotalPreviousPrice
  • SubtotalPreviousPrice
  • TotalPrice
  • SubtotalPrice
  • TotalRegularPrice
  • SubtotalRegularPrice
 

Zamówienie, koszyk

Właściwości:
  • ProductsSubtotalValue
  • ProductsTotalValueBeforeDiscount
  • ProductsSubtotalValueBeforeDiscount
  • SubtotalPrices
  • ProductsTotalValue
 

Reklamacje, zwroty

Właściwości:
  • SubtotalPrice
  • TotalPrice
  • SubtotalPrices
  • TotalValue
  • SubtotalValue
 

Kontrahenci

Właściwości:
  • VATEU
 

Config

Właściwości:
  • VATEU
 

Config.Currencies

Dla wersji Enterpise zwraca listę walut przesłanych z systemu ERP. Dla pozostałych wersji zwraca domyślną walutę. Obiekt zwraca szczegółowe informacje o wybranym towarze.  

 

Opis używanych obiektów lokalnych:

 
productnew.Products.AskForPrice
Zawiera informacje czy włączono opcję zapytaj o cenę.
 
 
productnew.Products.Availability
Zawiera informacje na temat dostępności.Właściwości:
  • Date – służy do wyświetlenia informacji na temat ustawionej daty dla danego towaru (np. przy zapowiedzi produktu),
  • ImageUrl – url obrazu,
  • Status – Id statusu dostępności,
  • Text – opis tekstowy dla danego statusu,
  • Type – wyświetla typ dostępności,
 
 
productnew.Products.BasicUnitMinQuantity
Informacja o minimalnej ilości zakupu w jednostce podstawowej towaru.
 
 
productnew.Products.Brand
Informacje na temat marki.Właściwości:
  • Heading – tytuł,
  • Id – numer Id,
  • Image - informacja o obrazie, zawiera:
    • ExternalUrl - link zewnętrzny do obrazu,
    • Id - numer id obrazu,
    • Link - link do obrazu,
  • ImageId – id obrazu,
  • Name – nazwa,
  • Url – adres Url,
  • UrlWithManufacturer – adres do produktów danego producenta,
 
 
productnew.Products.Code
Zawiera informacje o kodzie produktu.
 
 
productnew.Products.DecimalPlacesPrice
Liczba miejsc po przecinku do wyświetlania ceny.
 
 
productnew.Products.DecimalUnit
Informacja czy jednostki mogą być liczbami niecałkowitymi.
 
 
productnew.Products.DefaultGroup
Informacja o grupie domyślnej.
 
 
productnew.Products.Flags
Zwraca informacje o flagach (np. nowość, wyprzedaż).
 
 
productnew.Products.GIDNumber
Numer Id produktu z bazy systemu ERP.
 
 
productnew.Products.HasAttributes
Informacja czy produkt posiada atrybuty.
 
 
productnew.Products.HasOtherUnits
Informacja czy przedmiot ma inne jednostki sprzedażowe (np. para, pojedynczy produkt).
 
 
productnew.Products.Id
Numer Id produktu.
 
 
productnew.Products.Image
Informacja o zdjęciu produktu.Właściwości:
  • ExternalUrl - link zewnętrzny do zdjęcia,
  • Id - numer Id zdjęcia,
  • Link - link do zdjęcia,
 
 
productnew.Products.ImageId
Numer Id obrazu produktu.
 
 
productnew.Products.Images
Informacje o zdjęciach produktu. Dla każdego ze zdjęć posiada te same pola, co właściwość productnew.Products.Image.
 
 
productnew.Products.Link
Link do produktu.
 
 
productnew.Products.Manufacturer
W skład tej właściwości wchodzą Name, Id, Heading, Image, ImageId, Url, Website.
 
 
productnew.Products.MinPrice
Cena minimalna z ostatnich 30 dni.
 
 
productnew.Products.Name
Nazwa produktu.
 
 
productnew.Products.NameNoHtml
Nazwa produktu bez znaczników HTML.
 
 
productnew.Products.NoDiscount
Informacja czy produkt może być objęty zniżką.
 
 
productnew.Products.PreviousPrice
Poprzednia cena produktu.
 
 
productnew.Products.Price
Cena produktu.
 
 
productnew.Products.Rating
Średnia ocena produktu.
 
 
productnew.Products.RatingCount
Ilość ocen produktu.
 
 
productnew.Products.RegularPrice
Cena normalna produktu.
 
 
productnew.Products.SaleUnit
Jednostka sprzedażowa (np. para).
 
 
productnew.Products.Type
Typ towaru.
 
 
productnew.Products.UPC
Kod EAN z ERP.
 
 
productnew.Products.UnitPriceRatio
Przelicznik ceny za jednostkę miary.
 
 
productnew.Products.UnitPriceUnit
Możliwa jednostka przeliczeniowa (np. litry na mililitry, gramy na kilogramy itd.). Jeżeli wartość jest nullem nie wyświetlamy ceny jednostkowej.
 
 
productnew.Products.Url
Adres URL produktu.
 
 
productnew.Products.Weight
Waga produktu.
 
 
productlastviewed.Products.AskForPrice
Informacja czy włączono opcję zapytaj o cenę.
 
 
productlastviewed.Products.Availability
Informacje na temat dostępności.Właściwości:
  • Date - zwraca datę kiedy produkt będzie dostępny (np. jeżeli produkt jest zapowiedzią),
  • ImageUrl - adres url dla obrazka,
  • Status - status,
  • Text - wartość tekstowa (np. "od ręki"),
  • Type - typ,
 
 
productlastviewed.Products.BasicUnitMinQuantity
Informacja o minimalnej ilości zakupu w jednostce podstawowej towaru.
 
 
productlastviewed.Products.Brand
Informacje o marce produktu.Właściwości:
  • Heading - tytuł,
  • Id - numer Id,
  • Image - informacja o obrazie, zawiera:
    • ExternalUrl - link zewnętrzny do obrazu,
    • Id - numer id obrazu,
    • Link - link do obrazu,
  • ImageId - id obrazu,
  • Name - nazwa,
  • Url - adres url,
  • UrlWithManufacturer - adres URL do strony producenta,
 
 
productlastviewed.Products.Code
Zwraca kod produktu.
 
 
productlastviewed.Products.DecimalPlacesPrice
Liczba miejsc po przecinku do wyświetlania ceny.
 
 
productlastviewed.Products.DecimalUnit
Informacja czy jednostki mogą być liczbami niecałkowitymi.
 
 
productlastviewed.Products.DefaultGroup
Informacja o domyślnej grupie.
 
 
productlastviewed.Products.Flags
Zwraca flagi dla produktów (np. promocja, nowość itd.).
 
 
productlastviewed.Products.GIDNumber
Numer Id produktu z bazy systemu ERP.
 
 
productlastviewed.Products.HasAttributes
Informacja czy produkt posiada atrybuty.
 
 
productlastviewed.Products.HasOtherUnits
Informacja czy przedmiot ma inne jednostki sprzedażowe (np. para, pojedynczy produkt).
 
 
productlastviewed.Products.Id
Id produktu.
 
 
productlastviewed.Products.Image
Informacja o zdjęciu produktu.Właściwości:
  • ExternalUrl - link zewnętrzny do zdjęcia,
  • Id - numer Id zdjęcia,
  • Link - link do zdjęcia,
 
 
productlastviewed.Products.ImageId
Zwraca Id obrazka.
 
 
productlastviewed.Products.Images
Informacje o zdjęciach produktu. Dla każdego ze zdjęć posiada te same pola, co właściwość productlastviewed.Products.Image.
 
 
productlastviewed.Products.Link
Link do strony produktu.
 
 
productlastviewed.Products.Manufacturer
Informacje na temat producenta.Właściwości:
  • Heading - tytuł,
  • Id - id,
  • Image - informacja o obrazie, zawiera:
    • ExternalUrl - link zewnętrzny do obrazu,
    • Id - numer id obrazu,
    • Link - link do obrazu,
  • ImageId - id obrazu,
  • Name - nazwa,
  • Url - adres url,
  • Website - adres strony
 
 
productlastviewed.Products.MinPrice
Cena minimalna produktu z ostatnich 30 dni.
 
 
productlastviewed.Products.Name
Nazwa produktu.
 
 
productlastviewed.Products.NameNoHtml
Nazwa produktu (pozbawiona znaczników HTML).
 
 
productlastviewed.Products.NoDiscount
Informacja czy produkt może być objęty zniżką.
 
 
productlastviewed.Products.PreviousPrice
Poprzednia cena produktu.
 
 
productlastviewed.Products.Price
Cena produktu.
 
 
productlastviewed.Products.Rating
Średnia ocena produktu.
 
 
productlastviewed.Products.RatingCount
Liczba wszystkich ocen produktu.
 
 
productlastviewed.Products.RegularPrice
Cena normalna produktu.
 
 
productlastviewed.Products.SaleUnit
Jednostka sprzedażowa (np. para).
 
 
productlastviewed.Products.Type
Typ towaru.
 
 
productlastviewed.Products.UPC
Kod EAN z ERP.
 
 
productlastviewed.Products.UnitPriceRatio
Przelicznik ceny za jednostke miary.
 
 
productlastviewed.Products.UnitPriceUnit
Możliwa jednostka przeliczeniowa (np. litry na mililitry, gramy na kilogramy itd.). Jeżeli wartość jest nullem nie wyświetlamy ceny jednostkowej.
 
 
productlastviewed.Products.Url
Adres strony produktu (dokładniejszy niż w przypadku Link).
 
 
productlastviewed.Products.Weight
Waga produktu.
 
 
productlist.FilteringOptions
Właściwość odpowiada za opcje filtracji przedmiotów.Właściwości:
  • Filters - odpowiada za opcje filtracji, zawiera:
    • Field - nazwa dla danego filtru,
    • Heading - tytuł danego filtru (np. Producent),
    • Values - wartości dla konkretnych filtrów, zawiera:
      • Count - liczba przedmiotów spełniających dany warunek,
      • Field - nazwa (zazwyczaj tożsama z polem field elementu nadrzędnego),
      • Selected - czy opcja została wybrana,
      • Text - nazwa danego pola,
      • TotalCount - całkowita liczba przedmiotów tego typu na liście,
      • Value - wartość pola,
      Wskazówka
      Aby dostać się do powyższych właściwości productlist.FilteringOptions.Filters.[numer].Nazwa należy użyć nr produktu w tablicy. Przykładowo, aby dostać się do pierwszego przedmiotu w nawiasie kwadratowym należy wpisać właściwą cyfrę. Należy pamiętać, że tablice numerowane są od 0.
  • Groups - odpowiada za opcje filtracji po kategoriach, zawiera:
    • Group - opis kategorii, zawiera:
      • Heading - alternatywna nazwa kategorii,
      • Id - id kategorii,
      • Image - informacje o obrazie (zawiera ExternalUrl, Id, Link),
      • ImageId - id obrazka,
      • Name - nazwa kategorii,
      • Url - url kategorii,
    • Nodes - lista podkategorii, zawiera:
      • Count - ilość towarów,
      • Group - opis kategorii (zawiera Heading, Id, Image, ImageId, Name, Url),
    • Parent - opis kategorii nadrzędnej (zawiera Heading, Id, Image, ImageId, Name, Url),
    Wskazówka
    Aby dostać się do powyższych właściwości productlist.FilteringOptions.Groups.[numer].Nazwa należy użyć nr produktu w tablicy. Przykładowo, aby dostać się do pierwszego przedmiotu w nawiasie kwadratowym należy wpisać właściwą cyfrę. Należy pamiętać, że tablice numerowane są od 0.
  • MaxPrice - najwyższa cena produktów z danej listy,
  • MinPrice - najniższa cena produktów z danej listy,
  • PriceFrom - cena od (wpisana przez użytkownika),
  • PriceTo - cena do (wpisana przez użytkownika),
  • Results - czy są wyniki filtrowania, czy zwykła lista,
  • SearchGroups - grupy na podstawie filtrowania,
 
 
productlist.HeaderData
Informacje na temat nagłówka danej kategorii (np. jej tytuł, opis).Właściwości:
  • Description - opis,
  • Heading - tytuł,
  • Image - informacja o obrazie, zawiera:
    • ExternalUrl - link zewnętrzny do obrazu,
    • Id - numer Id obrazu,
    • Link - link do obrazu,
  • ImageId - id obrazu,
  • MetaDescription - opis meta,
  • MetaKeywords - meta słowa kluczowe,
  • MetaTitle - tytuł meta,
  • ShortDescription - krótki opis,
 
 
productlist.ItemsPerPage
Określa liczbę produktów na stronie.
 
 
productlist.PageCount
Liczba stron.
 
 
productlist.PageNo
Numer strony.
 
 
productlist.PageQueryGET
Zwraca string PageQueryGET ustawiony z poziomu Panelu administratora (np. PageId).
 
 
productlist.Products.[nr produktu]
Informacje o produkcie.Właściwości:
  • AskForPrice - czy włączono opcję zapytaj o cenę,
  • AttributesList - lista atrybutów, zawiera:
    • Attributes - atrbuty, zawiera:
      • Id - numer id,
      • Format - liczbę określającą format,
      • Name - nazwa,
      • Values - wartości, zawiera:
        • Object - obiekt,
        • Value - wartość,
        • ValueId - numer id wartości,
    • AttributesEditable - atrybuty edytowalne,
    • AttributesPolyvalent - atrybuty wielowartościowe,
    • Clip - informuje, czy towar jest fantomem,
  • Availability – dostępność, zawiera:
    • Date - służy do wyświetlenia informacji na temat ustawionej daty dla danego towaru (np. przy zapowiedzi produktu),
    • ImageUrl - adres obrazu
    • Status - Id statusu dostępności,
    • Text - opis tekstowy dla danego statusu,
    • Type - wyświetla typ dostępności,
  • BasicUnitMinQuantity - informacja o minimalnej ilości zakupu w jednostce podstawowej towaru,
  • Brand - informacje na temat marki, zawiera:
    • Heading - tytuł,
    • Id - numer Id,
    • Image - informacje o obrazie (zawiera ExternalUrl, Id, Link),
    • ImageId - id obrazu,
    • Name - nazwa,
    • Url - adres Url,
    • UrlWithManufacturer - adres do produktów danego producenta,
  • Code - kod,
  • DecimalPlacesPrice - liczba miejsc po przecinku do wyświetlania ceny,
  • DecimalUnit - czy jednostki mogą być liczbami niecałkowitymi,
  • DefaultGroup - domyślna grupa,
  • Flags - zwraca flagi dla produktu (np. promocja, nowość itd.),
  • GIDNumber - numer Id produktu z bazy systemu ERP,
  • HasAttributes - czy posiada atrybuty,
  • HasOtherUnits - czy przedmiot ma inne jednostki sprzedażowe (np. para, pojedynczy produkt),
  • Id - id,
  • ImageId - id obrazu,
  • Image - informacje o obrazie, zawiera:
    • ExternalUrl - link zewnętrzny,
    • Id - id obrazu,
    • Link - link do obrazu,
  • Images - informacje o obrazach, zawiera:
    • ExternalUrl - link zewnętrzny,
    • Id - id obrazu,
    • Link - link do obrazu,
  • Link - link,
  • Manufacturer – informacje na temat producenta, zawiera:
    • Heading - tytuł,
    • Id - numer Id,
    • Image - informacje o obrazie (zawiera ExternalUrl, Id, Link),
    • ImageId - id obrazu,
    • Name - nazwa,
    • Url - adres url,
    • Website - adres strony,
  • MinPrice - cena minimalna z ostatnich 30 dni,
  • Name - nazwa,
  • NameNoHtml - nazwa bez znacznikow HTML,
  • NoDiscount - informacja czy produkt może być objęty zniżką,
  • PreviousPrice - poprzednia cena,
  • Price - cena,
  • Rating - średnia ocena,
  • RatingCount - liczba wszystkich ocen,
  • RegularPrice - cena normalna,
  • SaleUnit - jednostka sprzedażowa (np. para),
  • ShortDescription - krótki opis,
  • StockLevel - informacja o stanie magazynowym, zawiera:
    • Control - informuje czy kontrola jest włączona,
    • ImageUrl - adres grafiki obrazującej stan,
    • QuantityControl - informuje czy kontrola ilości jest włączona,
    • Text - tekst informujący o stanie magazynowym,
    • Type - wyświetla typ dostepności stanu magazynowego,
    • Value - dostępna ilość produktu,
  • Type - typ towaru,
  • UPC - kod EAN z ERP,
  • UnitPriceRatio - przelicznik ceny za jednostkę miary,
  • UnitPriceUnit - możliwa jednostka przeliczeniowa (np. litry na mililitry, gramy na kilogramy itd.). Jeżeli wartość jest nullem nie wyświetlamy ceny jednostkowej,
  • Url - adres Url,
  • Weight - waga
Wskazówka
Aby dostać się do powyższych właściwości productlist.Products[nr produktu].Nazwa należy użyć nr produktu w tablicy. Przykładowo, aby dostać się do pierwszego przedmiotu w nawiasie kwadratowym należy wpisać właściwą cyfrę. Należy pamiętać, że tablice numerowane są od 0.
 
 
productlist.Search
Zwraca informacje na temat wyniku wyszukiwania.Właściwości:
  • Brand - marka,
  • Group - zwraca string z nazwą kategorii,
  • GroupId - Id grupy,
  • Manufacturer - producent,
  • PriceFrom - cena od,
  • PriceTo - cena do,
  • Search - wartość pola wpisanego w wyszukiwarkę,
  • SearchAll - wartość pola wpisanego w wyszukiwarkę,
  • SearchAny - wyszukiwanie którejkolwiek z fraz,
  • SearchId - numer id wyszukiwania,
  • SearchWild - wyszukiwanie losowe (odpowiednik ,,szczęśliwego trafu"),
  • TotalItems - liczba przedmiotów spełniająca podane kryterium,
  • Url - adres Url,
 
 
productlist.SelectedSorting
Wybrany sposób sortowania.
 
 
productlist.SortingOptions
Opcje sortowania.Właściwości:
  • Text - wartość tekstowa danej właściwości wyszukiwania,
  • Value - wartość,
 
 
productlist.SortingQueryGET
Podobnie jak w przypadku SortingQueryGET zwraca string ustawiony z poziomu Panelu administratora (np. PageId).
 
 
productlist.Supervisor
Opiekun towaru.
 
 
productlist.TotalItems
Łączna liczba przedmiotów.
 
 
productdetails.Product.Accessories
Akcesoria produktu.
 
 
productdetails.Product.AddedDate
Data dodania produktu.
 
 
productdetails.Product.Archival
Informacja, czy produkt jest produktem archiwalnym.
 
 
productdetails.Product.AskForPrice
Informacja czy włączono opcję zapytaj o cenę.
 
 
productdetails.Product.Attachments
Lista załączników dodanych do produktu.
 
 
productdetails.Product.Attributes
Atrybuty produktu.Właściwości:
  • Format - format atrybutu: tekst, liczba, data itp.,
  • Id - Id danej właściwości,
  • Name - nazwa właściwości (np. materiał),
  • Object - właściwy obiekt dla atrbutu, zgodnie z Format,
  • Value - wartość danej właściwości (np. tworzywo sztuczne)
 
 
productdetails.Product.AttributesEditable
Pole edytowalne (przykładowo treść graweru na biżuterii).
 
 
productdetails.Product.AttributesList
Lista atrybutów produktu.
 
 
productdetails.Product.AttributesPolyvalent
W skład tej właściwości wchodzą: Format, Id, Name oraz Values (Values może posiadać Object, ValueId oraz Value).
 
 
productdetails.Product.Availability
Informacja o dostępności produktu.Właściwości:
  • Date - ustawienie daty kiedy towar będzie dostępny,
  • ImageUrl - adres URL obrazu,
  • Status - status,
  • Text - opis tekstowy,
  • Type - typ,
 
 
productdetails.Product.BasicUnit
Domyślna jednostka sprzedaży (np. sztuka).
 
 
productdetails.Product.BasicUnitMinQuantity
Minimalna ilość towaru do zakupu w jednostce podstawowej.
 
 
productdetails.Product.BasicUnitRatio
Przelicznik jednostki produktu.
 
 
productdetails.Product.Batch
Cechy towaru, (zwraca true jeżeli towar posiada konfigurację jednak nie jest ona odrębnym towarem).
 
 
productdetails.Product.Brand
Marka produktu.Właściwości:
  • Heading - nazwa,
  • Id - numer Id,
  • Image - informacje o obrazie (zawiera ExternalUrl, Id, Link),
  • ImageId - id obrazu,
  • Name - nazwa,
  • Url - adres Url,
  • UrlWithManufacturer - adres url Producenta,
 
 
productdetails.Product.BrandProducts
Towary danej marki.Właściwości:
  • AskForPrice - czy włączono opcję zapytaj o cenę,
  • Availability - dostępność. W skład tej właściwości wchodzą: Text, Type, Status, Date, ImageUrl
  • BasicUnitMinQuantity - minimalna ilość towaru do zakupu w jednostce podstawowej,
  • Brand - marka. W skład tej właściwości wchodzą: Name, Id, Heading, Image, ImageId, Url, UrlWithManufacturer
  • Code - kod produktu,
  • DecimalPlacesPrice - liczba miejsc po przecinku do wyświetlania ceny,
  • DecimalUnit - określa, czy jednostki mogą być liczbami niecałkowitymi,
  • DefaultGroup - grupa domyślna,
  • Flags - zwraca flagi (np. nowość, wyprzedaż),
  • GIDNumber - numer Id produktu z bazy systemu ERP,
  • HasAttributes - czy posiada atrybuty,
  • HasOtherUnits - czy przedmiot ma inne jednostki sprzedażowe (np. para, pojedynczy produkt),
  • Id - numer Id,
  • Image - zawiera informacje o obrazie. W skład tej właściwości wchodzą:
    • ExternalUrl - link zewnętrzny,
    • Id - id obrazu,
    • Link - link do obrazu,
  • ImageId - id obrazu,
  • Images - zawiera informacje o zdjęciach. W skład tej właściwości wchodzą:
    • ExternalUrl - link zewnętrzny,
    • Id - id zdjęcia,
    • Link - link do zdjęcia,
  • Link - link,
  • Manufacturer - producent. W skład tej właściwości wchodzą Name, Id, Heading, Image, ImageId, Url, Website,
  • MinPrice - cena minimalna z ostatnich 30 dni,
  • Name - nazwa,
  • NameNoHtml - nazwa bez znaczników HTML,
  • NoDiscount - informacja czy produkt może być objęty zniżką,
  • PreviousPrice - poprzednia cena,
  • Price - cena,
  • Rating - średnia ocen,
  • RatingCount - liczba ocen,
  • RegularPrice - cena normalna,
  • SaleUnit - jednostka sprzedażowa,
  • Type - typ,
  • UPC - kod EAN z ERP,
  • UnitPriceRatio - przelicznik ceny za jednostkę miary,
  • UnitPriceUnit - możliwa jednostka przeliczeniowa (np. litry na mililitry, gramy na kilogramy itd.). Jeżeli wartość jest nullem nie wyświetlamy ceny jednostkowej,
  • Url - adres URL,
  • Weight - waga,
 
 
productdetails.Product.CN
 
 
productdetails.Product.Clip
Właściwość informująca, czy jest to fantom.
 
 
productdetails.Product.Code
Kod produktu.
 
 
productdetails.Product.ControlStock
Pokazuje czy stany magazynowe zostały włączone.
 
 
productdetails.Product.DecimalPlacesPrice
Liczba miejsc po przecinku do wyświetlania ceny.
 
 
productdetails.Product.DecimalUnit
Informacja czy jednostki mogą być liczbami niecałkowitymi.
 
 
productdetails.Product.DefaultGroup
Informacja czy produkt posiada grupę domyślną.
 
 
productdetails.Product.DeliveryCostType
Typ kosztu dostawy (np. gdy towar jest bardzo duży).
 
 
productdetails.Product.Dimensions
Informuje o wymiarach, zawiera właściwości: Length (długość), Width (szerokość) i Height (wysokość).
 
 
productdetails.Product.Flags
Wyświetla informacje o flagach dla danego produktu (np. promocja, nowość) - zawiera pole text (nazwa, np. Nagroda) oraz type (typ, np. Reward).
 
 
productdetails.Product.GIDNumber
Numer Id produktu z bazy systemu ERP.
 
 
productdetails.Product.HasAttributes
Informacja czy produkt posiada atrybuty.
 
 
productdetails.Product.HasDefaultUnit
Informacja czy produkt posiada domyślną jednostkę.
 
 
productdetails.Product.HasOtherUnits
Informacja czy przedmiot ma inne jednostki sprzedażowe (np. para, pojedynczy produkt).
 
 
productdetails.Product.Hits
Ilość wyświetleń danego towaru.
 
 
productdetails.Product.Id
Numer Id produktu.
 
 
productdetails.Product.Image
Informacje o obrazie produktu.Właściwości:
  • ExternalUrl - zewnetrzny link,
  • Id - id obrazu,
  • Link - link do obrazu,
 
 
productdetails.Product.ImageId
Id obrazu produktu.
 
 
productdetails.Product.Images
Informacje na temat obrazków dołączonych do produktu.Właściwości:
  • Alt - alternatywny tekst, który wyświetli się zamiast obrazka,
  • ExternalUrl - zewnętrzny link,
  • Id - id obrazu,
  • Link - link obrazu,
  • Name - nazwa,
  • NoFollow - czy wykorzystywany jest atrybut nofollow,
  • Title - tytuł,
Wskazówka
Aby dostać się do powyższych właściwości productdetails.Product.Images[numer].Nazwa należy użyć nr zdjęcia w tablicy. Przykładowo, aby dostać się do pierwszego przedmiotu w nawiasie kwadratowym należy wpisać właściwą cyfrę. Należy pamiętać, że tablice numerowane są od 0.
 
 
productdetails.Product.Link
Link do produktu.
 
 
productdetails.Product.Manufacturer
Producent. W skład tej właściwości wchodzą Heading, Id, Image, ImageId, Name, Url, Website.
 
 
productdetails.Product.ManufacturerCode
Kod Producenta.
 
 
productdetails.Product.ManufacturerProducts
Towary danego producenta. Cechy tej właściwości są tożsame z w.w. właściwością BrandProducts.
 
 
productdetails.Product.MinPrice
Najniższa cena towaru lub usługi, jaka obowiązywała w okresie 30 dni przed wprowadzeniem obniżki.
 
 
productdetails.Product.MetaDescription
Opis Meta.
 
 
productdetails.Product.MetaKeywords
Słowa kluczowe Meta.
 
 
productdetails.Product.MetaTitle
Tytuł Meta.
 
 
productdetails.Product.ModifiedDate
Data ostatniej modyfikacji produktu.
 
 
productdetails.Product.MoreInfoUrl
Adres Url z większą ilością informacji.
 
 
productdetails.Product.Name
Nazwa produktu.
 
 
productdetails.Product.Name1
Nazwa produktu.
 
 
productdetails.Product.NameNoHtml
Nazwa produktu bez znaczników HTML.
 
 
productdetails.Product.NetWeight
Waga netto produktu.
 
 
productdetails.Product.NoDiscount
Informacja czy produkt może być objęty zniżką.
 
 
productdetails.Product.OrdersCount
Ilość osób (unikalnych klientów), które zakupiły dany produkt.
 
 
productdetails.Product.ParentId
Numer Id rodzica produktu.
 
 
productdetails.Product.Points
Liczba punktów lojalnościowych, które klient otrzyma za zakup tego towaru.
 
 
productdetails.Product.PointsPrice
Koszt towaru podany w punktach lojalnościowych.
 
 
productdetails.Product.PreviousPrice
Poprzednia cena produktu.
 
 
productdetails.Product.Price
Cena produktu.
 
 
productdetails.Product.Rating
Średnia ocen produktu.
 
 
productdetails.Product.RatingCount
Ilość ocen produktu.
 
 
productdetails.Product.RegularPrice
Cena standardowa produktu.
 
 
productdetails.Product.Related
Wyświetla produkty powiązane z obecnie oglądanym.Właściwości:
  • AskForPrice - czy włączono opcję zapytaj o cenę,
  • Availability - w skład tej właściwości wchodzą: Text, Type, Status, Date, ImageUrl
  • BasicUnitMinQuantity - minimalna ilość towaru do zakupu w jednostce podstawowej,
  • Brand - marka, w skład tej właściwości wchodzą: Name, Id, Heading, ImageId, Url, UrlWithManufacturer
  • Code - kod produktu,
  • DecimalPlacesPrice - liczba miejsc po przecinku do wyświetlania ceny,
  • DecimalUnit - czy jednostki mogą być liczbami niecałkowitymi,
  • DefaultGroup - grupa domyślna,
  • Flags - zwraca flagi (np. nowość, wyprzedaż),
  • GIDNumber - numer Id produktu z bazy systemu ERP,
  • HasAttributes - czy posiada atrybuty,
  • HasOtherUnits - czy przedmiot ma inne jednostki sprzedażowe (np. para, pojedynczy produkt),
  • Id - numer Id,
  • Image - informacje o obrazie, zawiera:
    • ExternalUrl - zewnetrzny link,
    • Id - id obrazu,
    • Link - link do obrazu,
  • ImageId - id obrazu,
  • Images - obrazy, zawiera właściwości ExternalUrl, Id oraz Link,
  • Link - link,
  • Manufacturer - w skład tej właściwości wchodzą Name, Id, Heading, ImageId, Url, Website,
  • MinPrice - cena minimalna z ostatnich 30 dni,
  • Name - nazwa,
  • NameNoHtml - nazwa bez znaczników HTML,
  • NoDiscount - informacja czy produkt może być objęty zniżką,
  • PreviousPrice - poprzednia cena,
  • Price - cena,
  • Rating - średnia ocen,
  • RatingCount - liczba ocen,
  • RegularPrice - cena normalna,
  • SaleUnit - jednostka sprzedażowa,
  • Type - typ,
  • UPC - kod EAN z ERP,
  • UnitPriceRatio - przelicznik ceny za jednostkę miary,
  • UnitPriceUnit - możliwa jednostka przeliczeniowa (np. litry na mililitry, gramy na kilogramy itd.). Jeżeli wartość jest nullem nie wyświetlamy ceny jednostkowej,
  • Url - adres Url,
  • Weight - waga
 
 
productdetails.Product.RelatedProducts
Wyświetla inne produkty powiązane z obecnie oglądanym (np. akcesoria do danego produktu).Właściwości:
  • AIProductsRecommendations - towary podobne do przeglądanego, rekomendowane przez dodatek Sztucznej inteligencji (AI),
  • Accessories - akcesoria do danego produktu,
  • Crossselling - produkty powiązane z przeglądanym,
  • Custom - dodatkowy typ ustawiany w systemie ERP,
  • Substitutes - produkty zastępcze do przeglądanego produktu,
  • Suggested - produkty sugerowane.
Wskazówka
Wyżej wymienione właściwości posiadają:
  • AskForPrice - czy włączono opcję zapytaj o cenę,
  • Availability - w skład tej właściwości wchodzą: Text, Type, Status, Date, ImageUrl
  • BasicUnitMinQuantity - minimalna ilość towaru do zakupu w jednostce podstawowej,
  • Brand - marka, w skład tej właściwości wchodzą: Name, Id, Heading, ImageId, Url, UrlWithManufacturer
  • Code - kod produktu,
  • DecimalPlacesPrice - liczba miejsc po przecinku do wyświetlania ceny,
  • DecimalUnit - czy jednostki mogą być liczbami niecałkowitymi,
  • DefaultGroup - grupa domyślna,
  • Flags - zwraca flagi (np. nowość, wyprzedaż),
  • GIDNumber - numer Id produktu z bazy systemu ERP,
  • HasAttributes - czy posiada atrybuty,
  • HasOtherUnits - czy przedmiot ma inne jednostki sprzedażowe (np. para, pojedynczy produkt),
  • Id - numer Id,
  • Image - informacje o obrazie, zawiera:
    • ExternalUrl - zewnetrzny link,
    • Id - id obrazu,
    • Link - link do obrazu,
  • ImageId - id obrazu,
  • Images - obrazy, zawiera właściwości ExternalUrl, Id oraz Link,
  • Link - link,
  • Manufacturer - w skład tej właściwości wchodzą Name, Id, Heading, ImageId, Url, Website,
  • MinPrice - cena minimalna z ostatnich 30 dni,
  • Name - nazwa,
  • NameNoHtml - nazwa bez znaczników HTML,
  • NoDiscount - informacja czy produkt może być objęty zniżką,
  • PreviousPrice - poprzednia cena,
  • Price - cena,
  • Rating - średnia ocen,
  • RatingCount - liczba ocen,
  • RegularPrice - cena normalna,
  • SaleUnit - jednostka sprzedażowa,
  • Type - typ,
  • UPC - kod EAN z ERP,
  • UnitPriceRatio - przelicznik ceny za jednostkę miary,
  • UnitPriceUnit - możliwa jednostka przeliczeniowa (np. litry na mililitry, gramy na kilogramy itd.). Jeżeli wartość jest nullem nie wyświetlamy ceny jednostkowej,
  • Url - adres Url,
  • Weight - waga
 
 
productdetails.Product.SaleUnit
Jednostka sprzedażowa produktu.
 
 
productdetails.Product.Sets
Informacje o zestawach.Właściwości:
  • PreviousPrice - wcześniejsza cena,
  • Price - cena,
  • Products - lista produktów wchodzących w skład zestawu,
  • SetId - id zestawu,
  • SetName - nazwa zestawu,
 
 
productdetails.Product.ShortDescription
Krótki opis produktu.
 
 
productdetails.Product.Sold
Ilość sprzedanych sztuk towaru.
 
 
productdetails.Product.SplitPayment
Podział płatności.
 
 
productdetails.Product.StockLevel
Stany magazynowe produktu.Właściwości:
  • Control - czy włączone są stany magazynowe,
  • ImageUrl - adres URL obrazu,
  • QuantityControl - kontrola ilości towaru,
  • Text - opis dla stanu,
  • Type - typ,
  • Value - wartość,
 
 
productdetails.Product.SubtotalMinPrice
Najniższa cena netto towaru lub usługi, jaka obowiązywała w okresie 30 dni przed wprowadzeniem obniżki (dotyczy sklepów Enterprise i B2B).
 
 
productdetails.Product.SubtotalPreviousPrice
Cena bez VAT produktu przed obniżką.
 
 
productdetails.Product.SubtotalPrice
Cena produktu bez VAT.
 
 
productdetails.Product.SubtotalRegularPrice
Cena produktu netto.
 
 
productdetails.Product.Supervisor
Opiekun produktu.
 
 
productdetails.Product.Supplies
Właściwości fantoma.Właściwości:
  • AttributeNames - zawiera nazwy poszczególnych fantomów (tj. opcji danego towaru, takich jak np. kolor), w skład tej właściwości wchodzi Id oraz Name (nazwa danej opcji)
  • Key - lista Id kolejnych właściwości prowadząca do opcji która jest nadrzędna
  • Supplies - informacje na temat opcji, zawiera:
    • Format - format atrybutu: tekst, liczba data itp.,
    • Object - obiekt właściwy dla atrbutu, zgodny z Format,
    • Supplies - właściwości fantoma - analogicznie właściwości jak w obecnie opisywanej właściwości Supplies,
    • Value - wartość danej właściwości towaru (np. rozmiar "M"/"L"),
    • ValueId - Id wartości,
 
 
productdetails.Product.Symbol
Symbol (w formie stringa).
 
 
productdetails.Product.TotalMinPrice
Najniższa cena brutto towaru lub usługi, jaka obowiązywała w okresie 30 dni przed wprowadzeniem obniżki (dotyczy sklepów Enterprise i B2B).
 
 
productdetails.Product.TotalPreviousPrice
Poprzednia cena towaru brutto.
 
 
productdetails.Product.TotalPrice
Cena z podatkiem VAT.
 
 
productdetails.Product.TotalRegularPrice
Cena produktu brutto.
 
 
productdetails.Product.Type
Typ towaru.
 
 
productdetails.Product.UPC
Zwraca kod EAN z ERP.
 
 
productdetails.Product.UnitPriceRatio
Przelicznik ceny za jednostkę miary.
 
 
productdetails.Product.UnitPriceUnit
Możliwa jednostka przeliczeniowa (np. litry na mililitry, gramy na kilogramy itd.). Jeżeli wartość to null, to nie wyświetlamy ceny jednostkowej.
 
 
productdetails.Product.Units
Jednostka sprzedażowa produktu.Właściwości:
  • Default - czy jest to wartość domyślna,
  • Dimensions - wymiary, zawiera Length (długość), Width (szerokość), Height (wysokość),
  • Id - Id danej jednostki,
  • Name - nazwa jednostki (np. para),
  • Ratio - przelicznik ceny przy zmianie jednostki,
 
 
productdetails.Product.Url
Adres Url produktu.
 
 
productdetails.Product.VAT
Stawka VAT.
 
 
productdetails.Product.WasteMgmtCost
Koszt gospodarowania odpadami.
 
 
productdetails.Product.Weight
Waga produktu.
 
 
productdetails.Product.YouTubeVideos
Załączone pliki video Youtube.
 
 
header.Nodes.Count
Liczba przedmiotów dostępna w danej kategorii menu.
 
 
header.Nodes.Groups
Jeżeli zawiera podmenu, to wyświetla pola wymienione w tym punkcie (Count, Heading, Id, Image, ImageId, Name, Nodes, Url oraz dodatkowe pole HasChildren)
 
 
header.Nodes.Heading
Nazwa dostępna po najechaniu kursorem.
 
 
header.Nodes.Id
Numer Id.
 
 
header.Nodes.Image
Informacje o obrazie.Właściwości:
  • ExternalUrl - zewnetrzny link,
  • Id - id obrazu,
  • Link - link do obrazu,
 
 
header.Nodes.ImageId
Id obrazu.
 
 
header.Nodes.Name
Wyświetlana nazwa.
 
 
header.Nodes.Product
Wyświetla informacje dotyczące produktów (productdetails).
 
 
header.Nodes.Url
Adres Url.
 
 
manufacturersbrands.Brands
Marka.Właściwości:
  • Heading - tytuł,
  • Id - Id,
  • Image - informacje o obrazie, zawiera:
    • ExternalUrl - zewnetrzny link,
    • Id - id obrazu,
    • Link - link do obrazu,
  • ImageId - id obrazka,
  • Name - nazwa,
  • Url - adres Url,
  • UrlWithManufacturer - adres Url,
 
 
manufacturersbrands.Manufacturers
Producenci.Właściwości:
  • Brands - tablica z markami danego producenta,
  • Heading - tytuł,
  • Id - Id,
  • Image - informacje o obrazie, zawiera:
    • ExternalUrl - zewnetrzny link,
    • Id - id obrazu,
    • Link - link do obrazu,
  • ImageId - id obrazka,
  • Name - nazwa,
  • Url - adres Url,
  • Website - adres Url,
 
 
text.Content
Treść wpisana w panelu administracyjnym
 
 
productuserreviews.ItemsPerPage
Dopuszczalna liczba opinii na każdej stronie.
 
 
productuserreviews.PageCount
Liczba stron.
 
 
productuserreviews.PageNo
Numer strony na której obecnie się znajdujemy.
 
 
productuserreviews.PageQueryGET
Zwraca string PageQueryGET ustawiony z poziomu Panelu administratora (np. PageId).
 
 
productuserreviews.Reviews
Przetrzymuje recenzje danego produktu.Właściwości:
  • CreatedDate - kiedy recenzja została napisana,
  • Rating - ocena (w formie graficznej gwiazdek),
  • Author - autor recenzji,
  • Comment - komentarz/opis oceny,
  • RegisteredAuthor - czy autor recenzji był zalogowany
 
 
productuserreviews.TotalItems
Łączna liczba opinii.
 
 
comparison-tool.Attributes
Lista atrybutów.
 
 
comparison-tool.Products
Obiekt z produktami do porównania.Właściwości:
  • AddedDate - data dodania produktu,
  • AskForPrice - zapytaj o cenę,
  • Attributes - atrybuty,
  • AttributesList - listę atrybutów,
  • Availability - dostępność, zawiera:
    • Date - data,
    • ImageUrl - adres URL zdjęcia,
    • Status - status,
    • Text - opis słowny,
    • Type - numer oznaczający dostępność,
  • BasicUnit - domyślna jednostka sprzedaży (np. sztuka),
  • BasicUnitMinQuantity - minimalna ilość towaru do zakupu w jednostce podstawowej,
  • BasicUnitRatio - przelicznik jednostki,
  • Brand - marka, zawiera:
    • Heading - tytuł,
    • Id - numer id,
    • Image - informacje o obrazie, zawiera:
      • ExternalUrl - zewnetrzny link,
      • Id - id obrazu,
      • Link - link do obrazu,
    • ImageId - id obrazu,
    • Name - nazwa,
    • Url - adres URL,
    • UrlWithManufacturer - adres url producenta,
  • Code - kod produktu,
  • ControlStock - pokazuje, czy stany magazynowe zostały włączone,
  • DecimalPlacesPrice - liczba miejsc po przecinku do wyświetlania ceny,
  • DecimalUnit - czy jednostki moga być liczbami niecałkowitymi,
  • DefaultGroup - czy posiada grupę domyślną,
  • Flags - wyświetla informacje o flagach dla danego produktu, np. promocja, nowość. zawiera pole text - nazwa oraz typ,
  • GIDNumber - numer Id produktu z bazy systemu ERP,
  • HasAttributes - czy posiada atrybuty,
  • HasDefaultUnit - czy posiada domyślną jednostkę,
  • HasOtherUnits - czy posiada inne jednostki sprzedażowe,
  • Hits - ilość wyświetleń danego towaru,
  • Id - numer id,
  • Image - informacje o obrazie, zawiera:
    • ExternalUrl - zewnetrzny link,
    • Id - id obrazu,
    • Link - link do obrazu,
  • ImageId - id obrazu,
  • Images - zdjęcia produktu, dla każdego z nich posiada:
    • ExternalUrl - zewnętrzny link,
    • Id - id zdjęcia,
    • Link - link do zdjęcia,
  • Link - link,
  • Manufacturer - producent, zawiera:
    • Heading - nazwa,
    • Id - numer id,
    • Image - informacje o obrazie, zawiera:
      • ExternalUrl - zewnetrzny link,
      • Id - id obrazu,
      • Link - link do obrazu,
    • ImageId - id obrazu,
    • Name - nazwa,
    • Url - adres URL,
    • Website - adres URL,
  • ManufacturerCode - kod producenta,
  • MetaDescription - opis (metadane),
  • MetaKeywords - słowa kluczowe (metadane),
  • MetaTitle - tytuł (metadane),
  • MinPrice - cena minimalna z ostatnich 30 dni,
  • ModifiedDate - data modyfikacji,
  • MoreInfoUrl - adres URL z większą ilością informacji,
  • Name - nazwa,
  • Name1 - nazwa,
  • NameNoHtml - nazwe bez znaczników HTML,
  • NetWeight - waga netto,
  • NoDiscount - informacja czy produkt może być objęty zniżką,
  • OrdersCount - ilość osób (unikalnych klientów), które zakupiły dany produkt,
  • ParentId - numer id rodzica,
  • Points - liczba punktów lojalnościowych przyznawana za zakup tego towaru,
  • PointsPrice - koszt towaru podany w punktach lojalnościowych,
  • PreviousPrice - cena poprzednia,
  • Price - cena,
  • Rating - średnia ocen,
  • RatingCount - ilość ocen,
  • RegularPrice - cena standardowa,
  • SaleUnit - jednostka sprzedażowa,
  • ShortDescription - krótki opis,
  • Sold - informacja o liczbie sprzedanych sztuk danego towaru,
  • StockLevel - stany magazynowe,
  • SubtotalMinPrice - cena minimalna netto z ostatnich 30 dni od daty wprowadzenia promocji,
  • SubtotalPreviousPrice - cena poprzednia bez VAT,
  • SubtotalPrice - cena bez VAT,
  • SubtotalRegularPrice - cena netto,
  • Symbol - symbol (w formie stringa),
  • TotalMinPrice - cena minimalna brutto z ostatnich 30 dni od daty wprowadzenia promocji,
  • TotalPreviousPrice - cena poprzednia brutto,
  • TotalPrice - cena z podatkiem VAT,
  • TotalRegularPrice - cena produktu brutto,
  • Type - typ towaru,
  • UPC - zwraca kod EAN z ERP,
  • UnitPriceRatio - przelicznik ceny za jednostkę miary,
  • UnitPriceUnit - możliwa jednostka przeliczeniowa (np. litry na mililitry, gramy na kilogramy itp.). Jeżeli wartość wynosi null, to nie wyświetlamy ceny jednostkowej,
  • Url - adres URL produktu,
  • VAT - stawka VAT,
  • WasteMgmtCost - koszt gospodarowania odpadami,
  • Weight - waga,
 
 
customerprofile.Complaint
Przetrzymuje szczegóły na temat reklamacji.
 
 
customerprofile.ComplaintQueryGET
Zwraca string ComplaintQueryGET ustawiony z poziomu Panelu administratora (np.PageId).
 
 
customerprofile.ComplaintsActive
Lista z trwającymi właśnie reklamacjami i zwrotami.Właściwości:
  • Complaints - zawiera informacje o reklamacjach i zwrotach. W jego skład wchodzą właściwości:
    • ComplaintId - id reklamacji/zwrotu,
    • CreatedDate - data utworzenia reklamacji/zwrotu,
    • Currency - waluta,
    • Informacje o walucie. Zawiera:
      • Code - waluta przesłana z systemu ERP,
      • Symbol - symbol wprowadzony w panelu administracyjnym,
    • DecimalPlacesPrice - liczba miejsc po przecinku do wyświetlania ceny,
    • DefaultGroup - grupa domyślna produktu,
    • Description - opis reklamacji/zwrotu,
    • Id - id produktu,
    • Image - informacje o obrazie, zawiera:
      • ExternalUrl - zewnetrzny link,
      • Id - id obrazu,
      • Link - link do obrazu,
    • ImageId - id zdjęcia produktu,
    • Link - link do produktu,
    • NameNoHtml - nazwa produktu,
    • OrderId - numer zamówienia,
    • Price - cena,
    • Quantity - ilość,
    • Status - numer określający aktualny status reklamacji/zwrotu,
    • StatusText - tekst określający aktualny status reklamacji/zwrotu,
    • SubtotalPrice - cena netto,
    • SubtotalPrices - czy wyświetlane ceny są cenami netto,
    • SubtotalValue - wartość netto,
    • TotalPrice - cena brutto,
    • TotalValue - wartość brutto,
    • Type - numer określający typ (reklamacja czy zwrot),
    • TypeText - tekst określający typ (reklamacja czy zwrot),
    • Unit - jednostka,
    • Url - adres strony z produktem,
    • Value - wartość,
  • ItemsPerPage - ilość przedmiotów które mają być wyświetlane na stronie,
  • PageCount - ilość stron,
  • PageNo - numer strony,
  • PageQueryGET - zwraca string PageQueryGET ustawiony z poziomu Panelu administratora (np. PageId),
  • TotalItems - łącznie przedmiotów
 
 
customerprofile.ComplaintsExecuted
Informacje na temat rozstrzygniętych reklamacji i zwrotów, zawiera pola analogicznie jak ComplaintsActive.
 
 
customerprofile.Consents
Informacje o zgodach Klienta.Właściwości:
  • Channels - kanały,
  • Checked - czy zgoda została zaakceptowana,
  • Contents - treści regulaminów przypisane do konkretnej zgody,
  • Date - data wyrażenia zgody,
  • Id - numer id zgody,
  • PublishedDate - data publikacji zgody,
  • Required - czy zgoda jest wymagana,
  • Statement - czy jest to forma oświadczenia,
  • Text - treść zgody,
  • Type - numer oznaczający typ zgody,
  • Updated - kiedy była aktualizacja tresci,
 
 
customerprofile.DiscountDetPageQueryGET
Zwraca string DiscountDetPageQueryGet ustawiony z poziomu Panelu Administratora.
 
 
customerprofile.DiscountERPDetails
Informacje nt. zniżki z systemu ERP.
 
 
customerprofile.DiscountQueryGET
Zwraca string DiscountQueryGET ustawiony z poziomu Panelu Administratora.
 
 
customerprofile.Discounts
Informacje na temat zniżek przysługujących Klientowi.Właściwości:
  • CustomerGroups - ulubione kategorie danego Klienta,
  • CustomerProducts - ulubione produkty danego Klienta,
  • FirstOrder - jeśli zwraca true to jest to pierwsze zamówienie Klienta zaś w Panelu Administracyjnym znajduje się obniżka dla pierwszych zamówień,
  • Groups - zniżka grupowa (dotyczy danej grupy produktów, np. obuwia damskiego). Zawiera Currency, DateTill, Discount, DiscountType, Treshold oraz Group, które zawiera Count, HasChildren, Heading, Id, Image, ImageId, Name oraz Url,
  • OrderValue - wartość zamówienia (po przeliczeniu zniżki),
  • Products - produkty, na które klient ma zniżkę,
  • Regular - standardowa obniżka (jeżeli została taka przypisana w Panelu Administracyjnym),
 
 
customerprofile.DiscountsERP
Informacje na temat zniżek z systemu ERP.Właściwości:
  • Discounts - lista produktów ze zniżkami, zawiera:
    • Code - kod,
    • DateFrom - data, początek ważności zniżki,
    • DateTill - data, koniec ważności zniżki,
    • Description - opis,
    • Id - numer id,
    • Name - nazwa produktu ze zniżką,
    • Type - typ zniżki,
  • ItemsPerPage- ilość produktów na stronie,
  • PageCount - ilość stron,
  • PageNo - numer strony,
  • PageQueryGET - zwraca string PageQueryGET ustawiony z poziomu Panelu Administratora,
  • TotalItems - łączna ilość towarów ze zniżkami (odpowiada ilości produktów w tym obiekcie we właściwości Discounts,
 
 
customerprofile.DiscountsEshop
Zniżki z e-Sklepu.Właściwości:
  • FirstOrder - jeśli zwraca true to jest to pierwsze zamówienie Klienta zaś w Panelu Administracyjnym znajduje się obniżka dla pierwszych zamówień,
  • OrderValue - rabat od wartości zamówienia,
  • Regular - rabat dla stałego klienta,
 
 
customerprofile.DiscountsPageQueryGet
Zwraca string DiscountsPageQueryGet ustawiony z poziomu Panelu Administratora.
 
 
customerprofile.Employees
Lista pracowników jakich posiada sklep, wraz z ich danymi.Właściwości:
  • Active - czy pracownik ma status aktywnego,
  • Email - adres email pracownika,
  • ExportedToERP - czy pracownik został wyeksportowany do systemu ERP,
  • Id - id pracownika,
  • LanguageId - id języka,
  • Name - nazwa pracownika,
  • Name2 - nazwa pracownika,
  • Owner - czy jest właścicielem,
  • PhoneNo - numer telefonu pracownika,
 
 
customerprofile.History
Zawiera informacje na temat działań na koncie, np. logowań (i nieudanych prób logowania) czy zmiany danych.Właściwości:
  • Items - zawiera następujące informacje:
    • Category - rodzaj wykonanej akcji (np. Logowanie),
    • Date - data wykonania akcji,
    • Event - opis akcji (np. Logowanie poprawne),
    • User - kto wykonał akcję,
    • UserType - typ użytkownika, który wykonał akcję
  • ItemsPerPage - ilość akcji wyświetlanych na jednej stronie,
  • PageCount - ilość stron,
  • PageNo - numer strony,
  • PageQueryGet - zwraca string PageQueryGET ustawiony z poziomu Panelu administratora (np. PageId),
  • TotalItems - łączna liczba akcji,
 
 
customerprofile.Inquiries
Zawiera informacje odnośnie zapytań ofertowych.Właściwości:
  • ItemsPerPage - maksymalna ilość zapytań wyświetlana na jednej stronie,
  • List - lista zapytań, zawiera:
    • Date - data złożenia zapytania,
    • Id - id zapytania,
    • Status - numer określający status zapytania,
    • StatusText - tekst opisujący status zapytania,
  • PageCount - ilość stron,
  • PageNo - numer strony,
  • PageQueryGET - zwraca string PageQueryGET ustawiony z poziomu Panelu administratora (np. PageId),
  • TotalItems - ilość zapytań ofertowych,
 
 
customerprofile.InquiriesPageQueryGet
Zwraca string InquiriesPageQueryGet ustawiony z poziomu Panelu administratora.
 
 
customerprofile.LinkedAccounts
Powiązane konta.
 
 
customerprofile.LoyaltyHistory
Historia wydawanych i zdobywanych punktów lojalnościowych.Właściwości:
  • Items - informacje odnośnie płatności punktami lojalnościowymi, zawiera:
    • Date - data,
    • Event - numer oznaczający zdarzenie,
    • EventText - tekst opisujący zdarzenie,
    • Id - numer id,
    • Points - ilość punktów,
    • User - typ użytkownika (słownie),
    • UserType - numer określający typ użytkownika,
  • ItemsPerPage - ilość akcji wyświetlanych na jednej stronie,
  • PageCount - ilość stron,
  • PageNo - numer strony,
  • PageQueryGET - zwraca string PageQueryGET ustawiony z poziomu Panelu administratora (np. PageId),
  • TotalItems - łączna liczba akcji,
 
 
customerprofile.Newsletter
Informacje o subskrypcji newslettera oraz Id języka.Właściwości:
  • LanguageId - id języka, w jakim newsletter ma się wyświetlać,
  • Subscriber - czy użytkownik jest subskrybentem newslettera,
 
 
customerprofile.Offer
 
 
customerprofile.OfferDetPageQueryGET
Zwraca string OfferDetPageQueryGET ustawiony z poziomu Panelu administratora.
 
 
customerprofile.OfferQueryGET
Zwraca string OfferQueryGET ustawiony z poziomu Panelu administratora.
 
 
customerprofile.Offers
Lista ofert.Właściwości:
  • ItemsPerPage - ilość ofert na stronie,
  • List - lista ofert, zawiera:
    • Date - data utworzenia oferty,
    • Id - numer id oferty,
    • Status - numer określający status oferty,
    • StatusText - tekst opisujący aktualny status oferty,
  • PageCount - ilość stron,
  • PageNo - aktualna strona,
  • PageQueryGET - zwraca string PageQueryGET ustawiony z poziomu Panelu administratora,
  • TotalItems - ilość ofert,
 
 
customerprofile.OffersPageQueryGet
Zwraca string OffersPageQueryGet ustawiony z poziomu Panelu administratora.
 
 
customerprofile.Order
Zawiera informacje na temat złożonego zamówienia.Właściwości:
  • Attachments - załączniki,
  • Attributes – atrybuty nagłówkowe zamówienia,
  • CanAccept - czy zamówienie może być zaakceptowane,
  • CanCancel - czy zamówienie może być anulowane,
  • CanCopy - czy zamówienie może zostać skopiowane,
  • CanEdit – czy zamówienie można edytować,
  • CanRestorePayment - jeżeli wartość true, to umożliwia to umożliwia ponowne opłacenie towaru (np. w przypadku awarii Banku, nieudanej płatności itp.),
  • Currency - zwraca walutę,
  • Customer- zwraca informacje dotyczące Klienta:
    • Buyer - trzecie dane klienta,
    • Company - czy Klient jest firmą,
    • DeliveryAddress- zwraca informacje na temat adresu dostawy:
      • City - miasto,
      • Country - kraj,
      • Name - dane kupującego,
      • Name2 - dane kupującego,
      • Name3 - dane kupującego,
      • PhoneNo - numer telefonu,
      • State - województwo,
      • Street - ulica,
      • StreetNo - numer domu,
      • UnitNo - numer mieszkania,
      • ZipCode - kod pocztowy,
    • Email - zwraca adres mailowy,
    • Employee- zwraca informacje na temat pracownika, zawiera:
      • Email - adres mailowy,
      • LanguageId - id języka,
      • Name - nazwa,
      • Name2 - dodatkowe pole nazwa,
      • PhoneNo - numer telefonu
    • Invoice - czy wybrano fakturę,
    • InvoiceAddress - zawiera dane adresowe na jakie ma być wystawiona faktura. Zawiera te same pola co DeliveryAddress oraz dodatkowo pole Email wskazujące na adres mailowy,
    • RegisteredUser - czy użytkownik jest zarejestrowany,
    • SSN - numer PESEL,
    • TIN - numer NIP,
    • VATEU - zwraca kraj właściwy dla VAT,
  • Date - data złożenia zamówienia,
  • Delivery - wybrany sposób dostawy, zawiera:
    • CollectionPoint - punkt odbioru,
    • CollectionPointAddress - dane adresowe punktu odbioru,
    • CollectionPointId - numer id punktu odbioru,
    • CollectionPointTypeId - numer id oznaczający typ punktu odbioru,
    • DateText - data,
    • Description - opis,
    • MethodId - numer id sposobu dostawy,
    • Name - nazwa sposobu dostawy,
    • PackageCount - ilość paczek,
    • Status - status dostawy (numer),
    • StatusText - status dostawy (tekst),
    • SubtotalValue - wartość bez podatku VAT,
    • TotalValue - wartość zamówienia,
    • Waybill - list przewozowy,
    • Waybills - informacje o listach przewozowych,
  • DeliveryDate - zawiera liczbę (zazwyczaj dni) w ciągu których towar zostanie dostarczony,
  • Discount - zniżka,
  • Documents - załączone dokumenty/pliki,
  • ERPOrderNumber – numer zamówienia z ERPa,
  • EditingAllowed – jeśli true to zamówienie jest w trakcie edycji,
  • ExpectedDate - dzień dostarczenia towaru ,
  • ExpirationDate - dzień do którego towar zostanie dostarczony,
  • Hash - unikalny numer oznaczający zamówienie,
  • Id - numer Id,
  • IsEdited – jeśli true to zamówienie zostało wyedytowane,
  • ItemsPerPage – ilość towarów na stronie na szczegółach zamówienia,
  • LanguageId - Id języka,
  • NotDeterminedDeliveryCost - wyświetla informacje czy koszt dostawy został zdefiniowany,
  • Note - dodatkowe informacje,
  • OrderTotalValue - łączna wartość zamowienia,
  • PageCount – ilość stron z towarami na szczegółach zamówienia,
  • PageNo – numer strony z towarami na szczegółach zamówienia,
  • Payment - informacje odnośnie płatności, zawiera:
    • Description - opis,
    • DueDateText - określa termin/moment płatności,
    • MethodId - Id danej metody,
    • MethodIdText - opis danego Id,
    • MethodType - typ metody,
    • Name - nazwa,
    • OnlineNumber - Id transakcji z platności online,
    • Status - status płatności (numer),
    • StatusText - status płatności (tekst),
    • SubtotalValue - koszt płatności bez podatku VAT,
    • TotalValue - łączny koszt płatności,
  • Points – punkty lojalnościowe otrzymane za złożenie zamówienia,
  • PointsPaid – punkty lojalnościowe wydane w tym zamówieniu,
  • ProcessedDate - data wysłania,
  • Products - informacje o produktach w zamówieniu, zawiera:
    • Attributes – atrybuty elementu zamówienia,
    • CanComplain - czy można złożyć reklamację,
    • CanReturn - czy można zwrócić towar,
    • Code - kod produktu,,
    • DefaultGroup - grupa domyślna produktu,
    • Description - pole opis (np. rozmiar buta),
    • Id - numer Id,
    • Image - obraz,
    • ImageId - Id obrazu,
    • IsDeleted – czy usunięty,
    • IsEdited – czy wyedytowany,
    • IsModified – czy modyfikowany,
    • IsSetElement - czy jest częścią zestawu,
    • IsSetParent - czy przedmiot jest przedmiotem głównym,
    • Link - link,
    • NameNoHtml - nazwa bez tagów HTML,
    • No - numer,
    • Price - cena,
    • Quantity - ilość zakupionego towaru,
    • ReturnedQuantity - ilość zwróconego towaru,
    • SetName - nazwa zestawu,
    • SubtotalPrice - cena bez VAT,
    • SubtotalValue - cena całkowita (cena * ilość) bez VAT,
    • TotalPrice - cena z podatkiem VAT,
    • TotalValue - całkowita wartość zamówienia,
    • UPC - zwraca kod EAN z ERP,
    • Unit - jednostka sprzedażowa (np. para),
    • Url - adres URL,
    • VAT - wartość podatku VAT,
    • Value - wartość brutto towaru,
    • WasteMgmtCost - koszty gospodarowania odpadami,
  • ProductsSubtotalValue - cena towarów bez podatku VAT,
  • ProductsTotalValue - łączna cena towarów w koszyku,
  • ProductsValue - wartość towarów,
  • ProductsValueBeforeDiscount – wartość towarów przed zniżką,
  • ProductsVatValue - wartość podatku VAT (w złotówkach),
  • RecalculationRequired – czy wymagane przeliczenie zamówienia,
  • RelatedOffers - powiązane oferty sprzedaży,
  • RelatedOrders - powiązane zamówienia,
  • ReportUrl - wygenerowany link do raportu,
  • SelectedDeliveryDate – wybrana przez klienta data dostawy,
  • Source - źródło,
  • SplitPayment - podział płatności,
  • Status - status,
  • StatusText - opis tekstowy statusu,
  • SubtotalPrices - czy wyświetlane ceny są cenami netto,
  • TotalItems – ilość wszystkich towarów z zamówienia,
  • Url - adres URL do zamówienia, zawiera hash,
  • Weight - waga,
 
 
customerprofile.OrderDetPageQueryGET
Zwraca string OrderDetPageQueryGET ustawiony w panelu administracyjnym.
 
 
customerprofile.OrderQueryGET
Zwraca string OrderQueryGET ustawiony z poziomu Panelu administratora (np.PageId).
 
 
customerprofile.Orders
Połączenie danych z customerprofile.Active i customerprofile.Executed.Właściwości:
  • ItemsPerPage - maksymalna ilość na jednej stronie,
  • Orders - zawiera informacje o zamówieniach, posiada właściwości:
    • Currency - waluta,
    • CurrencyExt - informacje o walucie. Zawiera Code i Symbol,
    • Date - data złożenia zamówienia,
    • DeliveryStatus - status zamówienia (numer),
    • DeliveryStatusText - status zamówienia (tekst),
    • Email - adres email,
    • OrderId - numer id zamówienia,
    • PaymentStatus - status płatności (numer),
    • PaymentStatusText - status płatności (tekst),
    • Status - status zamówienia (numer),
    • StatusText - status zamówienia (tekst),
    • SubtotalValue - wartość zamówienia bez podatku VAT,
    • TotalValue - wartość zamówienia z podatkiem VAT,
    • Value - wartość zamówienia,
  • PageCount - ilość stron,
  • PageNo - aktualny numer strony,
  • PageQueryGET - zwraca string PageQueryGET ustawiony z poziomu Panelu administratora,
  • TotalItems - łączna ilość zamówień,
 
 
customerprofile.OrdersActive
Informacje na temat aktywnych zamówień.Właściwości:
  • ItemsPerPage - ilość przedmiotów wyświetlanych na jednej stronie,
  • Orders - lista aktywnych zamówień zawiera następujące informacje:
    • Currency - waluta,
    • CurrencyExt - informacje o walucie. Zawiera Code i Symbol,
    • Date - data złożenia zamówienia,
    • DeliveryStatus - status zamówienia (numer),
    • DeliveryStatusText - status zamówienia (tekst),
    • Email - adres email,
    • OrderId - numer id zamówienia,
    • PaymentStatus - status płatności (numer),
    • PaymentStatusText - status płatności (tekst),
    • Status - status zamówienia (numer),
    • StatusText - status zamówienia (tekst),
    • SubtotalValue - wartość zamówienia bez podatku VAT,
    • TotalValue - wartość zamówienia z podatkiem VAT,
    • Value - wartość zamówienia,
  • PageCount - ilość stron,
  • PageNo - numer strony,
  • PageQueryGet - zwraca string PageQueryGET ustawiony z poziomu Panelu administratora (np. PageId),
  • TotalItems - łączna liczba aktywnych zamówień,
 
 
customerprofile.OrdersExecuted
Zamówienia zrealizowane.Właściwości:
  • ItemsPerPage - ilość przedmiotów wyświetlanych na jednej stronie,
  • Orders - lista aktywnych zamówień zawiera następujące informacje:
    • Currency - waluta,
    • CurrencyExt - informacje o walucie. Zawiera Code i Symbol,
    • Date - data złożenia zamówienia,
    • DeliveryStatus - status zamówienia (numer),
    • DeliveryStatusText - status zamówienia (tekst),
    • Email - adres email,
    • OrderId - numer id zamówienia,
    • PaymentStatus - status płatności (numer),
    • PaymentStatusText - status płatności (tekst),
    • Status - status zamówienia (numer),
    • StatusText - status zamówienia (tekst),
    • SubtotalValue - wartość zamówienia bez podatku VAT,
    • TotalValue - wartość zamówienia z podatkiem VAT,
    • Value - wartość zamówienia,
  • PageCount - ilość stron,
  • PageNo - numer strony,
  • PageQueryGet - zwraca string PageQueryGET ustawiony z poziomu Panelu administratora (np. PageId),
  • TotalItems - łączna liczba zrealizowanych zamówień,
 
 
customerprofile.ProductsToRate
Produkty zakupione ale jeszcze nie ocenione.Właściwości:
  • ItemsPerPage - maksymalna ilość przedmiotów na stronie,
  • PageCount - ilość stron,
  • PageNo - numer strony,
  • PageQueryGet - zwraca string PageQueryGET ustawiony z poziomu Panelu administratora,
  • Products - informacje o produktach, zawiera:
    • OrderDate - data złożenia zamówienia,
    • OrderId - id zamówienia,
    • Product - informacja o produkcie, zawiera:
      • DefaultGroup - domyślna grupa,
      • Id - id produktu,
      • Image - informacje o obrazie, zawiera:
        • ExternalUrl - zewnetrzny link,
        • Id - id obrazu,
        • Link - link do obrazu,
      • ImageId - id zdjęcia,
      • Link - link do produktu,
      • NameNoHtml - nazwa produktu bez znaczników HTML,
      • Url - adres URL produktu,
  • TotalItems - łączna ilość produktów do oceny,
 
 
customerprofile.Reviews
Zawiera informacje na temat opinii napisanych przez użytkownika.Właściwości:
  • AverageRating - średnia ocen,
  • ItemsPerPage - ilość przedmiotów na stronie,
  • PageCount - ilość stron,
  • PageNo - numer strony,
  • PageQueryGET - zwraca string PageQueryGET ustawiony z poziomu Panelu administratora,
  • Reviews - opinie. Zawiera:
    • Active - czy opinia jest aktywna,
    • Comment - treść opinii,
    • CreatedDate - data utworzenia,
    • OrderId - id zamówienia,
    • Product - informacje o produkcie. Zawiera:
      • DefaultGroup - domyślna grupa,
      • Id - id produktu,
      • Image - informacje o obrazie, zawiera:
        • ExternalUrl - zewnetrzny link,
        • Id - id obrazu,
        • Link - link do obrazu,
      • ImageId - id obrazka,
      • Link - link,
      • NameNoHtml - nazwa (bez znaczników html),
      • Url - adres strony produktu,
    • Rating - ocena,
  • TotalItems - łączna ilość opinii,
 
 
customerprofile.WishList
Lista towarów znajdujących się na liście życzeń/przechowalni.Właściwości:
  • Note - uwagi,
  • Notify - powiadomienie,
  • NofifyDate - data powiadomienia,
  • Product - informacje o produkcie, zawiera:
    • AskForPrice - zapytaj o cenę,
    • Availability - dostępność, zawiera:
      • Date - data,
      • ImageUrl - adres URL zdjęcia,
      • Status - status dostępności (numer),
      • Text - status dostępności (tekst),
      • Type - typ,
    • BasicUnitMinQuantity - informacja o minimalnej ilości zakupu w jednostce podstawowej towaru,
    • Brand - marka, zawiera:
      • Heading - tytuł,
      • Id - id marki,
      • Image - informacje o obrazie, zawiera:
        • ExternalUrl - zewnetrzny link,
        • Id - id obrazu,
        • Link - link do obrazu,
      • ImageId - numer id obrazu,
      • Name - nazwa marki,
      • Url - adres url marki,
      • UrlWithManufacturer - adres do produktów danego producenta,
    • Code - kod,
    • DecimalPlacesPrice - liczba miejsc po przecinku do wyświetlania ceny,
    • DecimalUnit - czy jednostki mogą być liczbami niecałkowitymi,
    • DefaultGroup - domyślna grupa,
    • Flags - flagi (np. nowość, wyprzedaż),
    • GIDNumber - numer Id produktu z bazy systemu ERP,
    • HasAttributes - czy posiada atrybuty,
    • HasOtherUnits - czy posiada inne jednostki sprzedażowe,
    • Id - numer id,
    • Image - zdjęcie, zawiera:
      • ExternalUrl - zewnętrzny link,
      • Id - numer id obrazu,
      • Link - link do obrazu,
    • ImageId - id obrazu,
    • Images - zdjęcia, zawiera:
      • ExternalUrl - zewnętrzny link,
      • Id - numer id obrazu,
      • Link - link do obrazu,
    • Link - link do produktu,
    • Manufacturer - producent, zawiera:
      • Heading - tytuł,
      • Id - numer id producenta,
      • Image - zdjęcie, zawiera:
        • ExternalUrl - zewnętrzny link,
        • Id - numer id obrazu,
        • Link - link do obrazu,
      • ImageId - id obrazu,
      • Name - nazwa,
      • Url - adres URL,
      • Website - strona WWW producenta,
    • MinPrice – cena minimalna z ostatnich 30 dni,
    • Name - nazwa produktu,
    • NameNoHtml - nazwa produktu bez znaczników HTML,
    • NoDiscount - informacja, czy produkt może być objęty zniżką,
    • PreviousPrice - cena poprzednia,
    • Price - cena,
    • Rating - średnia ocena,
    • RatingCount - ilość ocen,
    • RegularPrice - cena normalna,
    • SaleUnit - jednostka sprzedażowa (np. para),
    • Type - typ,
    • UPC – kod EAN z ERP,
    • UnitPriceRatio - przelicznik ceny za jednostkę miary,
    • UnitPriceUnit - możliwa jednostka przeliczniowa (np. litry na mililitry, gramy na kilogramy itd.),
    • Url - adres url,
    • Weigth - waga,
  • Quantity - ilość,
 
 
blog.LatestPosts
Zwraca informacje na temat ostatnich postów.Właściwości:
  • Content - zawartość wpisu (jego treść),
  • Heading - tytuł,
  • Id - numer Id,
  • ImageUrl - URL obrazu,
  • PublishedDate - data publikacji,
  • Url - adres URL,
  • Tags - tagi, zawiera właściwości:
    • Text - tekst,
    • Url - adres URL,
    • Weight - waga,
 
 
blog.PostDetails
Informacje o szczegółach posta.Właściwości:
  • Content - treść,
  • Heading - nagłówek,
  • Id - id,
  • ImageUrl - url obrazka,
  • MetaDescription - meta opis,
  • MetaKeywords - meta słowa kluczowe,
  • MetaTitle - meta tytuł,
  • Next - informacje o następnym poście, zawiera:
    • Heading - nagłówek,
    • Id - id,
    • PublishedDate - data publikacji,
    • Url - url,
  • Previous - informacje o poprzednim poście (analogicznie do Next),
  • PublishedDate - data publikacji,
  • Tags - informacje o tagach, zawiera:
    • Text - nazwa taga,
    • Url - url do listy postów z danym tagiem,
    • Weight - waga,
  • Url - url,
 
 
blog.PostList
Informacje o liście postów.Właściwości:
  • ItemsPerPage - ilość wpisów wyświetlanych na jednej stronie,
  • PageCount - ilość stron,
  • PageNo - numer strony,
  • PageQueryGET - zwraca string PageQueryGET ustawiony z poziomu Panelu administratora (np. PageId),
  • TotalItems - łączna liczba postów ,
  • Posts - zawiera informacje na temat wpisów na stronie. Właściwość ta zawiera dokładnie te same elementy co LatestPosts,
  • Search - informacje o wyszukaniu. Zawiera element Url,
 
 
cart.Attachments
Załączniki dodane do zamówienia.
 
 
cart.Attributes
Atrybuty nagłówkowe zamówienia.
 
 
cart.AuthenticationRequired
Informacja czy wymagane jest aby użytkownik był zalogowany.
 
 
cart.CartEmpty
Informacja czy koszyk jest pusty.
 
 
cart.Changes
Zwraca true jeśli dokonano zmiany w koszyku (np. dodanie produktu jako użytkownik zalogowany, wylogowanie i ponowne dodanie produktu jako zalogowany użytkownik).
 
 
cart.CollectionPointMapUrl
Link do mapy z punktami odbioru.
 
 
cart.CompanyOnly
Jeśli true to zamówienie można złożyć tylko jako firma.
 
 
cart.Coupon
Zwraca użyty kod rabatowy.
 
 
cart.Currency
Waluta w koszyku.
 
 
cart.CurrencyExt
Informacje o walucie w koszyku. Zawiera Code i Symbol).
 
 
cart.Customer
Informacje na temat Klienta.Właściwości:
  • Buyer - trzecie dane klienta,
  • Company - czy Klient jest firmą,
  • CustomerDetailsEditable - czy można edytować dane,
  • DeliveryAddress- właściwość odpowiada za możliwość zmiany adresu dostawy, składa się z:
    • City - miasto,
    • Country - kraj,
    • Name - dane odbiorcy,
    • Name2 - dane odbiorcy,
    • Name3 - dane odbiorcy,
    • PhoneNo - numer telefonu,
    • State - województwo,
    • Street - ulica,
    • StreetNo - numer domu,
    • UnitNo - numer mieszkania,
    • ZipCode - kod pocztowy,
  • Email - adres e-mail,
  • Id - numer Id,
  • Invoice - czy Klient chce aby wystawiona została faktura,
  • InvoiceAddress - właściwość odpowiada za możliwość wybrania danych do faktury, takich jak:
    • City - miasto,
    • Country - kraj,
    • Name - dane odbiorcy faktury,
    • Name2 - dane odbiorcy faktury,
    • Name3 - dane odbiorcy faktury,
    • PhoneNo - numer telefonu,
    • State - województwo,
    • Street - ulica,
    • StreetNo - numer domu,
    • UnitNo - numer mieszkania,
    • ZipCode - kod pocztowy,
  • SSN - numer PESEL,
  • TIN - numer NIP,
  • VATEU - numer VATEU,
 
 
cart.DeliveryMethods
Informacje na temat sposobów dostawy.Właściwości:
  • CalculationId - id kalkulacji,
  • CollectionPointTypeId - numer id oznaczający typ punktu odbioru,
  • DateText - opis sposobu dostawy,
  • Description - opis,
  • FastDelivery - czy obsługuje opcję szybkiej dostawy,
  • FreeDeliveryFrom - opcja darmowej dostawy od określonej kwoty,
  • ImageUrl - url do obrazu,
  • Name - nazwa,
  • NotDeterminedDeliveryCost - zwraca true jeżeli koszt dostawy zostanie ustalony przez obsługę sklepu,
  • Payments - informacje na temat sposobu płatności dostępnego dla wybranego sposobu dostawy. Zawiera:
    • AdditionalDataHTML - dodatkowo przekazany HTML,
    • COD - płatność za pobraniem,
    • Channels - kanały płatności,
    • Description - opis,
    • DueDateText - określa termin płatności,
    • FreePaymentFrom - darmowa płatność od (kwota),
    • Id - numer Id,
    • ImageUrl - adres URL obrazu,
    • MethodId - numer id metody płatności,
    • Name - Nazwa,
    • TotalValue - kwota,
  • TotalValue - wartość sposobu dostawy (cena),
 
 
cart.Demo
Gdy true, nie można składać zamówień.
 
 
cart.Discount
Wartość rabatu wyrażona w procentach.
 
 
cart.EditedOrderId
Id wyedytowanego zamówienia.
 
 
cart.GratisItems
Informuje o przysługujących produktach promocyjnych. Właściwości:
  • Attributes - atrybuty produktu, zawiera:
    • Format – format atrybutu: tekst, liczba, data itp.,
    • Id – Id danej właściwości,
    • Name – nazwa właściwości (np. materiał),
    • Object – właściwy obiekt dla atrbutu, zgodnie z Format,
    • Value – wartość danej właściwości (np. tworzywo sztuczne)
  • AttributesEditable - pole z atrybutami edytowalnymi (przykładowo treść graweru na biżuterii),
  • AttributesPolyvalent - lista atrybutów produktu,
  • DiscountId - numer Id rabatu,
  • DiscountType - typ przyznanego rabatu,
  • DiscountValue - wartość przyznanego rabatu,
  • ElementId - numer Id produktu promocyjnego,
  • HasAttributes - informacja czy produkt posiada atrybuty,
  • Image - informacje o obrazie produktu, zawiera:
    • ExternalUrl - zewnętrzny link,
    • Id - numer id obrazu,
    • Link - link do obrazu,
  • IsNetPrice - informacja czy cena jest wartością netto,
  • Name - nazwa rabatu,
  • NameNoHtml - nazwa produktu,
  • ProductGroupId - numer Id grupy rabatowej do której należy produkt,
  • ProductId - numer Id produktu,
  • Quantity - ilość danego przedmiotu na którą naliczany jest towar po cenie promocyjnej,
  • SaleUnit - jednostka sprzedażowa,
  • Url - adres URL,
  • Value - wartość produktu promocyjnego,
 
 
cart.NotDeterminedDeliveryCost
Zwraca true jeżeli koszt dostawy zostanie ustalony przez obsługę sklepu.
 
 
cart.NotDeterminedProductsDeliveryCost
 
 
cart.Note
Informacje/uwagi dodatkowe wpisane przez Klienta.
 
 
cart.OSS
Informacja o obsłudze szczególnej procedury rozliczania VAT dla e-Commerce.
 
 
cart.OrderStep
Nazwa kroku w zamówieniu.
 
 
cart.OrderTotalValue
Łączna wartość do zapłaty.
 
 
cart.OrderValueDiscounts
Łączna wartość zniżek.
 
 
cart.PlacedOrder
Wszystkie dane odnośnie danego zamówienia.
 
 
cart.Points
Punkty lojalnościowe, które klient otrzyma za złożenie tego zamówienia.
 
 
cart.PointsForValue
Ilość punktów lojalnościowych za wartość zamówienia.
 
 
cart.PointsPaid
Punkty lojalnościowe wydane przy składaniu tego zamówienia.
 
 
cart.PointsPrice
Cena zamówienia (netto lub brutto w zależności od rodzaju klienta – prywatny lub firma) przy użyciu punktów lojalnościowych.
 
 
cart.PointsPriceTotalValue
Cena brutto zamówienia przy użyciu punktów lojalnościowych.
 
 
cart.PreOrder
Informacja czy produkt jest zapowiedzią (nie jest jeszcze dostępny).
 
 
cart.Products
Informacje o produkcie/produktach w koszyku.Właściwości:
  • AskForPrice - czy włączono opcję zapytaj o cenę,
  • AskForPriceId - numer id zapytania o cenę,
  • Attributes - atrybuty,
  • BasicUnit - podstawowa jednostka,
  • BasicUnitRatio - przelicznik jednostki,
  • CanChangeQuantity - czy można zmienić ilość,
  • CanDelete - czy można usunąć,
  • Changed - jeśli wartość zwraca true należy dokonać ponownego przeliczenia koszyka,
  • Code - kod produktu,
  • DecimalPlacesPrice - liczba miejsc po przecinku do wyświetlania ceny,
  • DecimalUnit - czy jednostka może być liczbą niecałkowitą,
  • DefaultGroup - do jakiej grupy domyślnej przedmiot należy,
  • Description - opis przedmiotu (np. rozmiar buta),
  • Discount - zniżka,
  • GIDNumber - numer Id produktu z bazy systemu ERP,
  • Id - numer Id,
  • Image - zdjęcie, zawiera:
    • ExternalUrl - zewnętrzny link,
    • Id - numer id obrazu,
    • Link - link do obrazu,
  • ImageId - id obrazu,
  • IsSetElement - czy należy do zestawu,
  • IsSetParent - czy przedmiot jest główną częścią np. zestawu,
  • Link - link,
  • NameNoHtml - nazwa bez znaczników HTML,
  • No - numer przedmiotu w koszyku,
  • NoDiscount - czy nie ma zniżki,
  • Points - punkty,
  • PointsForValue - ilość punktów lojalnościowych za wartość produktu,
  • PointsPrice – cena towaru po użyciu punktów lojalnościowych,
  • Price - cena,
  • Quanity - ilość danego przedmiotu w koszyku,
  • SaleUnit - jednostka sprzedażowa,
  • SetName - nazwa zestawu,
  • SplitPayment - podział płatności,
  • Status- zawiera:
    • Date - jeżeli produkt jest zapowiedzią, to w tym miejscu znajduje się data kiedy stanie się on dostępny,
    • ImageUrl - adres URL obrazu,
    • Status - status,
    • Text - opis tekstowy,
    • Type - typ,
  • SubtotalPrice - cena bez VAT,
  • SubtotalValue - wartość bez VAT (produkt * ilość),
  • SubtotalValueBeforeDiscount - wartość bez VAT (produkt * ilość) przed obniżką,
  • TotalPrice - cena z podatkiem VAT,
  • TotalValue - cena za towary (cena * ilość),
  • TotalValueBeforeDiscount - cena za towary przed obniżką,
  • UPC - kod EAN towaru,
  • UnitPriceRatio - przelicznik ceny za jednostkę miary,
  • UnitPriceUnit - możliwa jednostka przeliczeniowa (np. litry na mililitry, gramy na kilogramy itd.). Jeżeli wartość jest nullem nie wyświetlamy ceny jednostkowej,
  • Url - adres URL,
  • VAT - stawka VAT,
  • Value - suma zamówienia brutto,
  • ValueBeforeDiscount - wartość przed rabatem,
  • WasteMgmCost -koszty gospodarowania odpadami,
  • Weight - waga,
 
 
cart.ProductsMinimumTotalValue
Minimalna cena zamówienia.
 
 
cart.ProductsSubtotalValue
Cena towarów (produkt * ilość) bez podatku VAT.
 
 
cart.ProductsSubtotalValueBeforeDiscount
Cena towarów (produkt * ilość) bez podatku VAT przed rabatem.
 
 
cart.ProductsTotalValue
Łączna cena towarów w koszyku.
 
 
cart.ProductsTotalValueBeforeDiscount
Łączna cena towarów bez rabatu.
 
 
cart.ProductsValue
Wartość towarów.
 
 
cart.ProductsValueBeforeDiscount
Cena towarów przed rabatem.
 
 
cart.SelectedDelivery
Wybrany sposób dostawy.Właściwości:
  • CalculationId - id kalkulacji,
  • CollectionPoint – dane wybranego punktu odbioru wprowadzone w panelu administracyjnym (np. adres, nazwa, godziny otwarcia),
  • CollectionPointId – numer Id punktu dostawy,
  • CollectionPointMapData - informacje o punktach dostawy,
  • CollectionPointMapUrl - adres do mapy punktów dostawy,
  • CollectionPointTypeId – numer Id typu punktu dostawy,
  • CollectionPointTypeText – opis tekstowy typu punktu odbioru (np. "Personal"),
  • DateText – opis,
  • Description – opis danej metody dostawy (jeżeli opis został uzupełniony w Panelu Administratora),
  • FastDelivery - czy obsługuje opcję szybkiej dostawy,
  • FreeDeliveryFrom – darmowa dostawa (od określonej kwoty),
  • ImageUrl - adres URL zdjęcia,
  • MethodId – numer Id metody dostawy,
  • Name - nazwa sposobu dostawy,
  • NotDeterminedDeliveryCost - brak ustalonych kosztów dostawy,
  • Payment - informacje odnośnie płatności, zawiera:
    • AdditionalDataHTML – dodatkowo przekazany HTML,
    • COD - płatność za pobraniem,
    • Channel,
    • Description – opis danej metody płatności (jeżeli opis został uzupełniony w Panelu Administratora),
    • DueDateText – opis (np. w formie tekstu lub liczby) terminu płatności,
    • Id – numer Id,
    • ImageUrl – url obrazka,
    • MethodId – Id danej metody,
    • MethodIdText - nazwa dla danego ID,
    • MethodType – typ metody dostawy,
    • Name – nazwa,
    • SubtotalValue – całkowity koszt netto płatności,
    • TotalValue – koszt całkowity płatności (np. dodatkowa opłata związana z przedpłatą),
    • VAT - stawka podatku VAT,
  • PhoneRequired – czy wymagane jest podanie numeru telefonu,
  • SelectedDate – data dostawy wybrana przez klienta,
  • SubtotalValue – całkowita cena netto kosztu dostawy,
  • Time – ilość dni, którą należy dodać do dzisiejszej daty, aby uzyskać najwcześniejszą możliwą do wyboru datę dostawy,
  • TotalValue – cen całkowita kosztu dostawy,
  • VAT - stawka podatku VAT,
 
 
cart.SelectedDeliveryPaymentChannelKey
Wybrany kanał płatności.
 
 
cart.SelectedDeliveryPaymentId
Id wybranej metody płatności.
 
 
cart.SplitPayment
Podział płatności.
 
 
cart.SubtotalPrices
Informacja czy ceny w koszyku pokazywane są z podatkiem VAT.
 
 
cart.ThirdPartyHTML
Zawiera kod wywoływanego skryptu, jeśli została wprowadzona odpowiednia konfiguracja w Panelu administracyjnym związana z obsługą Wiarygodne Opinie - Opineo.pl, Zaufane Opinie, Program Ochrony Kupujących - Ceneo.pl, lub Wiarygodne Opinie - Okazje.info.
 
 
cart.ThirdPartyScripts
Zawiera kod wywoływanego skryptu, jeśli została wprowadzona odpowiednia konfiguracja w Panelu administracyjnym związana z obsługą Wiarygodne Opinie - Opineo.pl, Zaufane Opinie, Program Ochrony Kupujących - Ceneo.pl, lub Wiarygodne Opinie - Okazje.info.
 
 
cart.VATValue
Wartość podatku VAT w koszyku.
 
 

Jak wykonać kopię bezpieczeństwa mojego szablonu?

Jak wykonać kopię bezpieczeństwa mojego szablonu?

Oprawa wizualna sklepu jest bardzo ważnym elementem podczas prowadzenia sprzedaży w sieci. Narzędzie Kreator Wyglądu Comarch e-Sklep umożliwia stworzenie własnych, niepowtarzalnych szablonów wedle preferencji i potrzeb użytkowników. W intuicyjnym narzędziu jakim jest Kreator, będziesz w stanie zaprojektować wszelkie niezbędne funkcje, takie jak stronę główną, listę towarów, szczegóły towaru oraz koszyk. Jeśli Twój projekt szablonu został zaimportowany do e-Sklepu oraz skonfigurowany wedle Twoich preferencji (dodanie grafik do bannerów, modyfikacje kolorystyczne) masz możliwość jego zapisania, co będzie stanowić kopię bezpieczeństwa. Kopia bezpieczeństwa to dane, które w każdej chwili można odtworzyć w przypadku ich utracenia (np. poprzez przypadkowe usunięcie) lub częstego wprowadzania zmian. Dane, jakie może zawierać kopia bezpieczeństwa to szablon, który wcześniej został przez nas wygenerowany wraz z bannerami. Zaleca się wykonywanie kopii zapasowych oraz zabezpieczenie ich hasłem. Każda wykonana kopia zapasowa powinna zostać zapisana w bezpiecznym i dogodnym dla Użytkownika miejscu.

Jak wykonać kopię bezpieczeństwa?

W Panelu Administracyjnym przejdź do sekcji Wygląd sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane, a następnie przejdź do zakładki Eksport szablonu. W pustych polach znajdujących się w zakładce Eksport szablonu, opcjonalnie przed eksportem możesz uzupełnić powyższe dane, tj. Autora szablonu, e-mail, telefon i stronę WWW sklepu. Aby wyeksportować szablon, kliknij Eksportuj szablon. Wyeksportowany plik jest w formacie XML, a jego nazwa zawiera szablon oraz wersję, co znacznie ułatwia zarządzanie kopiami bezpieczeństwa w przypadku wykonywania ich regularnie.

Jak wyeksportować bannery?

Bannery, które znajdują się w Twoim sklepie możesz również wyeksportować tworząc kopię bezpieczeństwa. W tym celu także musisz przejść do Wygląd sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane, a następnie do zakładki Eksport szablonu. Obok przycisku Eksportuj szablon, znajduje się przycisk Eksportuj bannery, który musisz kliknąć aby bannery, które posiadasz w e-Sklepie zostały weksportowane. Kopia bezpieczeństwa jest również zapisywana w formacie XML, a nazwa pliku wskazuje na szablon, wersję i zawartość bannerów.

Jak zabezpieczyć hasłem swój szablon?

Jeśli chcesz, aby Twój szablon został zabezpieczony hasłem, a znajomość hasła była niezbędna podczas zaimportowania tego szablonu do e-Sklepu, musisz w tym celu przejść w Panelu Administracyjnym do sekcji Wygląd sklepu/ Ustawienia/ Ustawienia zaawansowane, następnie do zakładki Szablon. W tym miejscu nadasz hasło dla swojego szablonu. Zgodnie z Polityką bezpieczeństwa haseł, hasło powinno:
  • Składać się z minimum 8 znaków,
  • Zawierać dużą literę,
  • Zawierać małą literę,
  • Zawierać cyfrę 0-9,
  • Zawierać znak specjalny – ‘!.+?;^]=-(&_)#=
Gotowe! Teraz Twój szablon został zabezpieczony hasłem. Jeśli wyeksportujesz szablon, który zabezpieczyłeś hasłem – podczas importu tego szablonu, będziesz musiał podać nadane wcześniej hasło. Jego brak uniemożliwi import szablonu, a podanie błędnego hasła spowoduje nieprawidłowe działanie szablonu po imporcie. Więcej informacji znajdziesz:

Dodanie konfigurowalności strony głównej w szablonie Szafir

Dodanie konfigurowalności strony głównej w szablonie Szafir

W tym artykule dowiesz się jak zmodyfikować szablon Szafir, aby strona główna była konfigurowalna.
Wskazówka
Instrukcja przeznaczona jest dla sklepów od wersji 2022.4, które posiadają starsze szablony. Artykuł przeprowadzi Cię przez proces modyfikacji plików js oraz scss. Dodatkowe informacje o kompilacji i minifikacji znajdziesz w centrum pomocy.

Krok 1.

W panelu administracyjnym przejdź do sekcji Wygląd sklepu/Ustawienia. Następnie, mając wybrany szablon Szafir, w prawym górnym rogu wybierz więcej, po czym przejdź do Edytuj ustawienia zaawansowane/więcej/edytuj HTML.

Krok 2.

Odnajdź plik __settings.liquid. Następnie w drugiej linijce dodaj poniższy kod: {% assign homepage = "Strona główna" -%} {% assign elementsAtHomepage = "Lista elementów na stronie głównej sklepu" -%} {% assign name = "Nazwa" -%} {% assign parameters = "Parametry" -%} {% assign mainBanner = "Baner główny" -%} {% assign mainBannerLink = "Przejdź do edycji tego bannera" -%} {% assign newsSection = "Sekcja Nowości" -%} {% assign newsSectionLink = "Przejdź do edycji zawartości tej sekcji" -%} {% assign newsletter = "Newsletter" -%} {% assign manufacturersSlider = "Slider Producenci" -%} {% assign news = "Aktualności" -%} {% assign newsLink = "Przejdź do listy artykułów bloga" -%} {% assign infographicBanner = "Banner infografika" -%} {% assign infographicBannerLink = "Przejdź do edycji tego bannera" -%} {% assign animationOnHover = "Animacja na hoverze" -%} {% assign brandsSlider = "Slider Marki" -%} Następnie wyszukaj linijkę border-bottom: 1px solid #ddd; i pod nią dodaj display: flex;. Parę linijek niżej znajduje się kod: #lg-settings-content .row::after { display: block; clear: both; content: ''; } #lg-settings-content .cell { border-left: 1px solid #ddd; display: inline-block; vertical-align: middle; width: calc((100% - 308px)/4); min-height: 20px; padding: 10px; float: left; } Usuń go, a następnie wklej następujący kod: #lg-settings-content .cell { border-left: 1px solid #ddd; width: calc((100% - 308px)/4); padding: 10px; } #lg-settings-content .elements-at-homepage .cell.name{ width: 130px; } #lg-settings-content .elements-at-homepage .cell.translation{ width: 160px; } #lg-settings-content .elements-at-homepage .cell.parameters{ width: calc(100% - 515px); } #lg-settings-content .elements-at-homepage .cell.goto{ width: 100%; } Wyszukaj frazę {{navigationBarSettings}} i zamień ją na {{homepage}}. Następnie odszukaj frazę {{newsletter}} i usuń całą sekcję fieldset w której się ona znajduje. To samo zrób w przypadku fraz {{homepageBannerTranslation}}, {{blogOnHomepage}} oraz {{categoryMenu}}. Kilka linijek niżej znajdziesz id="tab1Content". Pod tą linijką dodaj poniższy fragment:

{{navigationBarSettings}}

Następnie znajdź frazę id="tab2Content" i dwie linijki wyżej wklej następujący kod:
{{categoryMenu}}

{{categoryMenuInfo}}

{{elementsAtHomepage}}
{{available}}
{{number}}
{{name}}
{{translationId}}
{{parameters}}
{{mainBanner}}

{{animationTypeTranslation}}

{{newsSection}}

{{animationOnHover}}

{{newsletter}}
{{manufacturersSlider}}

{{animationOnHover}}

{{brandsSlider}}

{{animationOnHover}}

{{news}}

{{blogPresentationOnHomepage}}

{{animationOnHover}}

{{infographicBanner}}

{{animationOnHover}}

Teraz wyszukaj funkcję __SaveLiquidSettings i linijkę wyżej wklej poniższy kod: $('.pa-translation-link').each(function(){ var id = $(this).text(); var url = $(this).attr('href').replaceAll('__ID__', id); $(this).attr('href', url); }); $('.pa-link').each(function(){ var id = $(this).data('id'); var url = $(this).attr('href').replaceAll('__ID__', id); $(this).attr('href', url); });

Krok 3.

Następnie w pliku home.html w pierwszych linijkach znajdziesz taki fragment kodu: {% include 'common/banner.html' -%}

{{translations.NewProducts}}

{% if customer.HidePrices -%} {% include 'product/hidden-prices-msg.html' -%} {% endif -%} {% include 'product/minibox-grid.html' -%}
{% unless customer.NewsletterSubscriber or settings.newsletter == 'no' -%}

Przykładowe modyfikacje

Wyszukiwarka zaawansowana w szablonie Topaz

Wyszukiwarka zaawansowana w szablonie Topaz

W tym artykule dowiesz się jak zmodyfikować swój szablon Topaz, aby obsługiwał wyszukiwarkę zaawansowaną.
Wskazówka
Niniejsza instrukcja przeznaczona jest dla sklepów w wersji 2020.2 lub nowszej!
Wskazówka
Kopiowanie fraz, które należy wyszukać w kodzie, może powodować problemy. Frazy do wyszukania najlepiej przepisać ręcznie, lub skopiować, ale po skopiowaniu podmienić znaki typu - _ ' " itp. W przeciwnym wypadku, fraza może nie zostać odnaleziona w kodzie!
Wskazówka
W tym artykule trzeba będzie wprowadzać zmiany w plikach js i css. Z tego artykułu dowiesz się jak je minifikować
Pierwszym krokiem jest dodanie obiektu wykorzystywanego w wyszukiwarce. Aby to zrobić, otwórz Panel Administracyjny, a następnie zakładkę Wygląd sklepu -> Ustawienia. Kliknij w prawym górnym rogu na ikonkę z trzema kwadratami i z rozwiniętego menu wybierz opcję Edytuj ustawienia zaawansowane. Przejdź do zakładki Obiekty. Kliknij przycisk Dodaj. W polu Typ wybierz Menu producentów i marek a w polu Nazwa podaj manufacturer-brand, po czym kliknij Dodaj. W ten sposób utworzony został obiekt, dzięki któremu wyszukiwarka będzie mogła wybierać spośród producentów i marek. Następnie należy przypisać obiekt do wyszukiwarki. Podobnie jak przed chwilą, otwórz Panel Administracyjny, a następnie zakładkę Wygląd sklepu -> Ustawienia -> Edytuj ustawienia zaawansowane. Wybierz zakładkę Strony. Znajdź stronę Wyszukiwanie zaawansowane (18). W tym samym wierszu, w kolumnie z nazwą pliku, wpisz advanced-search.html, a następnie zapisz. Kliknij na pole z napisem Wyszukiwanie zaawansowane (18). Pojawi się lista dostępnych obiektów. Kliknij kwadrat przy utworzonym wcześniej obiekcie manufacturer-brand, by pokazał się znak wyboru (tzw. "ptaszek"). A następnie zapisz. Kolejnym krokiem jest utworzenie nowego pliku o nazwie advanced-search.html w głównym katalogu z plikami Twojego szablonu Topaz. Treść tego pliku powinna wyglądać następująco: {% extends '_layout.html' -%} {% block pageContent -%} {% include 'elements/advanced-search/advanced-search.html' -%} {% endblock -%} Następnie, przejdź do katalogu elements. Utwórz w nim nowy katalog pod nazwą advanced-search. Przejdź do nowo utworzonego katalogu, a następnie utwórz w nim plik o nazwie advanced-search.html. Do nowo utworzonego pliku wklej poniższy kod: {% include 'partials/common/breadcrumbs.html' -%} {% assign filters = products.FilteringOptions.Filters %}
 
 
 
 
   
 
{{translations.SearchIn}}
 

{{translations.Pro_ProductDescription}}

{{translations.Pro_ProductSymbol}}

{{translations.EanCode}}

{{translations.Man_ManufacturerCode}}

{{translations.Pro_productAttributes}}

{{translations.Pro_ProductCode}}
 
 
 
{{translations.Pro_productAttributes}}
 
{% if customer.HidePrices != true -%}
{{translations.PriceFrom}}
{{translations.PriceTo}}
 

{{translations.PricesDifference}}

 
{% endif -%}

{{translations.WithPhoto}}

{{translations.NewProduct}}

{{translations.Prize}}

{{translations.ExtraQuality}}

{{translations.ExtraPrice}}

{{translations.ProductFromNewsletter}}

{{translations.Promotion}}

{{translations.RecommendedProduct}}

{{translations.SellerRecomendation}}

{{translations.Sale}}

{{translations.BestReviewed}}
 
 
{% if manufacturer-brand.Manufacturer != 0 -%}
 
{{translations.Manufacturer}}
 
{% assign i = 1 -%} {% for manufacturer in manufacturer-brand.Manufacturers -%}

{{manufacturer.Name}} {% assign i = i | Plus: 1 -%} {% endfor -%}
 
{% endif -%} {% if manufacturer-brand.Brand != 0 -%}
 
{{translations.Brand}}
 
{% assign i = 1 -%} {% for brand in manufacturer-brand.Brands -%}

{{brand.Name}} {% assign i = i | Plus: 1 -%} {% endfor -%}
 
{% endif -%}
{% include 'partials/newsletter-global.html' -%}
Wskazówka
W przypadku problemów z narzędziem Liquid Sync, pliki należy dodać bezpośrednio przez Panel Administracyjny, w zakładce Wygląd sklepu -> Ustawienia -> Edytuj ustawienia zaawansowane -> Edytuj HTML.
Kolejny krok to dodanie odpowiedniej treści do plików .css, odpowiedzialnych za wygląd zaawansowanej wyszukiwarki towarów. W tym celu wróć do głównego katalogu z plikami Topaza, a następnie otwórz katalog css. Do znajdującego się w nim pliku layout.css Wklej na samym dole następujący, już zminifikowany kod: *{line-height:1.5em}.advancedSearch{max-width:1100px;height:auto;margin:40px auto;user-select:none}.advancedSearch select{-webkit-appearance:none;-moz-appearance:none;text-indent:1px;text-overflow:""}.advancedSearch input[type="checkbox"]{visibility:hidden;width:0;height:0}.advancedSearch .form__invalid-input{visibility:hidden}.advancedSearch .title{font-size:17px;font-weight:600;color:{{settings.primaryFontColor}};margin-bottom:20px;text-transform:uppercase}.advancedSearch .search{width:100%;height:40px;display:flex}.advancedSearch .search .searchInput{width:50%;height:42px;padding-left:20px;font-size:14px;color:{{settings.secondaryFontColor}};border:1px solid {{settings.inputLabelColor}};border-right:none}.advancedSearch .search .searchCategory{width:30%;height:42px;font-size:14px;color:{{settings.secondaryFontColor}};border:1px solid {{settings.inputLabelColor}};border-right:none;padding:0 10px;background-color:{{settings.primaryPageBgColor}};-webkit-appearance:none;-moz-appearance:none;appearance:none;text-indent:5px;background-position-x:97%;transition:200ms}.advancedSearch .search .searchCategory option:checked{color:#000000 !important}.advancedSearch .search .searchCategory:hover{background-image:url("https://static.comarchesklep.pl/files/fonts/fontawesome-pro-5.6.3-web/svgs/solid/caret-up.svg") !important}.advancedSearch .search .searchButton{width:20%;height:22px;background-color:{{settings.primaryBtnBgColor}};color:{{settings.primaryBtnFontColor}};border:1px solid {{settings.primaryBtnBorderColor}};text-align:center;text-decoration:none;text-transform:uppercase;padding:11px 0 7px;font-size:14px;cursor:pointer;transition:200ms}.advancedSearch .search .searchButton:hover{background-color:{{settings.primaryBtnHoverBgColor}};color:{{settings.primaryBtnHoverFontColor}};border:1px solid {{settings.primaryBtnHoverBorderColor}};transition:200ms}.advancedSearch .searchType{padding:30px 0 30px 15px;border-bottom:1px solid {{settings.borderColor}};display:block;flex-direction:row;width:calc(100% - 15px);list-style:none}.advancedSearch .searchType li{display:inline}.advancedSearch .searchType li>*{cursor:pointer}.advancedSearch .searchType li input{visibility:hidden;display:none}.advancedSearch .searchType li .option{font-size:14px;color:{{settings.primaryFontColor}};border-radius:50%;background-color:{{settings.primaryPageBgColor}};border:80% solid {{settings.primaryFontColor}}}.advancedSearch .searchType li label{margin:0 30px 0 5px;font-size:14px}.advancedSearch .searchType li label:before{height:15px;width:16px;margin-right:10px;border-radius:50%;border:1px solid #0000005e;content:"";display:inline-block}.advancedSearch .searchType li.selected label:before{border-color:#000000;-webkit-box-shadow:inset 0 0 0 5px #000000;-moz-box-shadow:inset 0 0 0 5px #000000;box-shadow:inset 0 0 0 5px #000000}.advancedSearch .propertyContainer{width:100%;padding:30px 0;border-bottom:1px solid {{settings.borderColor}}}.advancedSearch .propertyContainer .checkboxContainer{width:100%;display:flex;flex-direction:row;justify-content:space-between;flex-wrap:wrap}.advancedSearch .propertyContainer .checkboxContainer span{flex:0 1 25%;margin:10px 0;font-size:14px;color:{{settings.primaryFontColor}}}.advancedSearch .propertyContainer .checkboxContainer span .checkIcon{position:relative;top:-14px;left:-25px;fill:{{settings.checkColor}}}.advancedSearch .propertyContainer .checkboxContainer span .checkIcon svg{width:12px;height:12px}.advancedSearch .propertyContainer .checkboxContainer span label{margin-left:10px;display:inline-flex;height:20px}.advancedSearch .propertyContainer .checkboxContainer span input:checked+label:before{text-align:center;background-color:{{settings.checkActiveBgColor}};overflow:hidden;border:solid 1px {{settings.checkActiveBgColor}}}.advancedSearch .propertyContainer .checkboxContainer span input+label:before{content:" ";display:inline-block;cursor:pointer;position:relative;width:15px;height:15px;border-radius:4px;background-color:transparent;color:{{settings.borderColor}};border:1px solid {{settings.borderColor}};transition:all 200ms ease;margin-right:10px}.advancedSearch .propertyContainer .checkboxContainer span:hover,.advancedSearch .propertyContainer .checkboxContainer input:hover,.advancedSearch .propertyContainer .checkboxContainer label:hover{cursor:pointer}.advancedSearch .propertyContainer .checkboxContainer:after{content:"";flex:1 0 25%}.advancedSearch .propertyContainer .productFeaturesContainer{display:flex;width:100%;flex-direction:row;flex-wrap:wrap}.advancedSearch .propertyContainer .productFeaturesContainer .priceContainer{width:25%}.advancedSearch .propertyContainer .productFeaturesContainer .priceContainer span{display:block}.advancedSearch .propertyContainer .productFeaturesContainer .priceContainer span .price{width:100%;font-size:14px;margin-bottom:10px;color:{{settings.primaryFontColor}};display:block}.advancedSearch .propertyContainer .productFeaturesContainer .priceContainer span input[type="number"]{height:40px;width:60%;font-size:14px;color:{{settings.secondaryFontColor}};border:1px solid {{settings.inputLabelColor}};margin-bottom:20px;text-align:right;padding-right:42px;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.advancedSearch .propertyContainer .productFeaturesContainer .priceContainer span .currency{position:relative;top:0;left:-40px;width:fit-content;margin:0;color:{{settings.secondaryFontColor}};font-size:14px}.advancedSearch .propertyContainer .productFeaturesContainer .productFeatures{width:75%;margin-top:15px}.advancedSearch .propertyContainer .productFeaturesContainer .productFeatures span{flex:0 1 33%;margin:10px 0;font-size:14px;color:{{settings.primaryFontColor}}}.advancedSearch .propertyContainer .productFeaturesContainer .productFeatures span label{margin-left:10px}.advancedSearch .propertyContainer .productFeaturesContainer .productFeatures:after{content:"";flex:0 1 33%}.advancedSearch .propertyContainer .productFeaturesContainer .hidePricesFeatures{width:100%}.advancedSearch .lastProperty{border:none} Do pliku layout-m.css wklej poniższy kod: @media only screen and (max-width: 768px){.advancedSearch{width:calc(100% - 40px);margin:0 auto}.advancedSearch input[type="checkbox"]{position:fixed}.advancedSearch .search{margin-top:20px;display:block;width:100%}.advancedSearch .search .searchInput{width:100%;display:block;border-right:1px solid {{settings.inputLabelColor}};margin-bottom:20px}.advancedSearch .search .searchCategory{width:100%;display:block;border-right:1px solid {{settings.inputLabelColor}};margin-bottom:20px}.advancedSearch .search .searchButton{display:block;width:100%}.advancedSearch .search .scrollingButton{display:block;width:100%;position:fixed;top:0;left:0;z-index:1}.advancedSearch .searchType{margin-top:110px;padding-left:0;display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between}.advancedSearch .searchType li{display:inline-block;flex:50%;margin-bottom:10px}.advancedSearch .searchType li>label{margin:0}.advancedSearch .propertyContainer{margin:10px 0}.advancedSearch .propertyContainer .checkboxContainer span{flex:0 1 100%}.advancedSearch .propertyContainer .productFeaturesContainer .priceContainer{width:100%;display:flex;flex-direction:row;justify-content:space-between;flex-wrap:wrap}.advancedSearch .propertyContainer .productFeaturesContainer .priceContainer span{flex:1 0 50%}.advancedSearch .propertyContainer .productFeaturesContainer .priceContainer span input[type="number"]{width:75%}.advancedSearch .propertyContainer .productFeaturesContainer .productFeatures{width:100%;display:flex;flex-direction:row;justify-content:space-between}.advancedSearch .propertyContainer .productFeaturesContainer .productFeatures span{flex:0 1 100%}} Do pliku layout-d.css wklej poniższy kod: @media only screen and (min-width: 768px) and (max-width: 1150px){.advancedSearch{width:calc(100% - 40px);margin:0 auto}.advancedSearch .search{margin-top:20px}}@media only screen and (min-width: 768px) and (max-width: 1000px){.advancedSearch .propertyContainer .productFeaturesContainer .productFeatures span{flex:0 1 43%}} W ten sposób w Topazie znalazł się kod odpowiedzialny za wygląd wyszukiwarki zaawansowanej. Kolejny krok to dodanie tłumaczeń. W tym celu należy w Panelu Administratora wejść w Wygląd sklepu -> Ustawienia i wybrać zakładkę Tłumaczenia. Przycisk Dodaj pozwala na dodanie nowego tłumaczenia. Aby tłumaczenie zostało dodane, należy wprowadzić odpowiednie Id oraz frazę (Tekst). Lista Id oraz fraz do wprowadzenia: 1. AllCategories - Wszystkie kategorie 2. SearchElement - Szukaj towaru... 3. WithSequence - Wyrażenie 4. WithAllWords- Wszystkie słowa 5. WithAnyWord - Dowolne ze słów 6. WithPartOfWord - Część słowa 7. SearchIn - Szukaj w 8. EanCode - Kod EAN 9. PriceFrom - Cena od 10. PriceTo - Cena do 11. PricesDifference - Cena maksymalna musi być większa od ceny minimalnej 12. WithPhoto - Tylko ze zdjęciem 13. NewProduct - Nowość 14. Prize - Nagroda 15. ExtraQuality - Superjakość 16. ExtraPrice - Supercena 17. ProductFromNewsletter - Towar z gazetki 18. Promotion - Promocja 19. RecommendedProduct - Towar polecany 20. SellerRecomendation - Rekomendacja sprzedawcy 21. Sale - Wyprzedaż 22. BestReviewed - Najlepiej oceniany 23. Manufacturer - Producent 24. Brand - Marka
Wskazówka
<strong.Uwaga! Kopiując Id z powyższej instrukcji do Panelu Administracyjnego, upewnij się, że po danym Id nie została skopiowana żadna spacja.
Następnie należy dodać odpowiedni kod do plików js. W tym celu, w plikach Topaza, otwórz folder js a następnie plik layout0.js. Odszukaj linijkę z frazą productListFunctions.init();. Pod znalezioną linijką znajduje się linia ze znakiem }. Pod nią wklej następujący kod: if($('body').find('.advancedSearch').index() >= 0) { advancedSearchFunctions.init(); } Następnie otwórz plik layout1.js znajdujący się w tym samym katalogu. Poniższy kod możesz wkleić na samym początku pliku: var advancedSearchFunctions = { init: function () { this.events(); }, events: function () { $('body').on('click', '.js-search-item', function (e) { $(e.currentTarget).closest('.searchType').children('.selected').removeClass('selected'); $(e.currentTarget).parent().addClass('selected'); }); $('body').on('click', '.checkboxContainer > span', function (e) { var input = $(this).children('input'); if(input.prop("checked") == true) { input.prop( "checked", false); } else { input.prop("checked", true); } }); $('body').on('click','.search-radio', function(e) { if ($('.search-radio[value=searchAll]').is(":checked")) { $('.advanced-search-input').attr('name', 'searchAll'); } else if ($('.search-radio[value=searchWild]').is(":checked")) { $('.advanced-search-input').attr('name', 'searchWild'); } else if ($('.search-radio[value=searchAny]').is(":checked")) { $('.advanced-search-input').attr('name', 'searchAny'); } else { $('.advanced-search-input').attr('name', 'name'); } }); $('body').on('change', '#priceTo, #priceFrom', function(e) { var priceTo = Number($('#priceTo').val()); var priceFrom = Number($('#priceFrom').val()); if(priceTo != '') { $('#priceTo').val(parseInt(priceTo)); } if(priceFrom != '') { $('#priceFrom').val(parseInt(priceFrom)); } if(priceFrom > priceTo) { $('.form__invalid-input').css('visibility', 'visible'); $('.searchButton').prop('disabled', true); } else { $('.form__invalid-input').css('visibility', 'hidden'); $('.searchButton').prop('disabled', false); } }); $(window).scroll(function(){ let scrollBottom = $(document).height() - $(window).height() - $(window).scrollTop(); if($('.newsletter1-wrapper')[0]) { if ($(this).scrollTop() > 300 && scrollBottom > 20 ) { $('.searchButton').addClass('scrollingButton'); } else { $('.searchButton').removeClass('scrollingButton'); } } else { if ($(this).scrollTop() > 300 ) { $('.searchButton').addClass('scrollingButton'); } else { $('.searchButton').removeClass('scrollingButton'); } } }); $(function(){ $('body').on('click', '.searchButton', function(e) { var t=$(this).parents('.advancedSearch'),hasValue=false,arr=$('#SearchAdvancedForm input[type!=hidden],#SearchAdvancedForm select').serializeArray(),i, data = t.find('input:not([disabled]), select:not([disabled]), textarea:not([disabled])').serializeArray(); var tab = []; for(i in arr) if(arr[i].value) {hasValue=true;break;} data.push({name: "__csrf", value: __CSRF}); $.post(null, data, function (d) { if (d.action.Redirect302) location.href = d.action.Redirect302; }); }); }); } } Ostatnim krokiem jest dodanie możliwości otwarcia wyszukiwarki zaawansowanej przy pomocy linku umieszczonego w stopce sklepu. Aby to zrobić, przejdź do pliku elements -> footer -> footer-1.html (jeśli w Kreatorze wybrałeś drugi rodzaj stopki, plik będzie nazywał się footer-2.html). Następnie wyszukaj linijkę z frazą advanced-search-link. W linijce tej znajduje się fragment href="#". Zamień znak # na {{config.DefinedPages.AdvancedSearch.Url}}. W ten sposób z poziomu stopki będzie można w prosty sposób otworzyć zaawansowane wyszukiwanie.

Ustawienia paska nawigacji w szablonie Szafir

Ustawienia paska nawigacji w szablonie Szafir

W tym artykule dowiesz się jak ustawić pasek nawigacji w swoim szablonie. Zmiany te pozwolą na dodanie m.in. przycisku importu koszyka i przycisku do pobrania przykładowego pliku CSV.
Wskazówka
W tym artykule trzeba będzie wprowadzać zmiany w plikach js i css. Z tego artykułu dowiesz się jak je minifikować

Uwaga
Zapis nazwa_folderu/nazwa_pliku.rozszerzenie oznacza, że aby znaleźć dany plik należy udać się do folderu o nazwie podanej przed ukośnikiem. Przykładowo: order/thx.html oznacza plik thx.html w folderze order

Pierwszym krokiem będzie zamiana treści w pliku common/navigation-bars/main-navigation-bar-partial.html. Ze względu na znaczną rozbudowę nie można wskazać konkretnych zmian, zatem udostępniamy cały kod, którym należy zastąpić kod obecny: {% if config.DefinedPages.WithdrawalRight.Id != page.PageId and config.DefinedPages.Payment.Id != page.PageId and config.DefinedPages.Shipping.Id != page.PageId and config.DefinedPages.Complaints.Id != page.PageId and config.DefinedPages.Loyalty.Id != page.PageId and config.DefinedPages.Registration.Id != page.PageId and config.DefinedPages.Login.Id != page.PageId and config.DefinedPages.Terms.Id != page.PageId and config.DefinedPages.Contact.Id != page.PageId and config.DefinedPages.Privacy.Id != page.PageId and config.DefinedPages.Blog.Id != page.PageId and config.DefinedPages.BlogDetails.Id != page.PageId and config.DefinedPages.PasswordReminder.Id != page.PageId and config.DefinedPages.CustomerProfile.Id != page.PageId and config.DefinedPages.About.Id != page.PageId and config.DefinedPages.SocialMedia.Id != page.PageId -%} {% assign togglingClass = '' -%} {% if page.PageId == config.DefinedPages.ProductDetails.Id -%} {% assign togglingClass = 'toggle-categories-lq' -%} {% endif -%} <nav class="header-categories-ui main-navigation-bar-ui"> <ul class="manufacturer-container-ui"> <li class="{% if config.DefinedPages.ProductList.Id == page.PageId or config.DefinedPages.Home.Id == page.PageId or config.DefinedPages.Manufacturers.Id == page.PageId -%} categories-opened-ui {% endif -%} {% if config.DefinedPages.AdvancedSearch.Id == page.PageId -%} login-back-ui {% endif -%} categories-option-ui categories-option-lq" > <a class="categories-label-ui category-links-ui categories-link-lq {{togglingClass}}" aria-label="categories-label" href="{{ config.DefinedPages.ProductList.Url }}" title="{{ translations.Contact }}"> <i class="va-mid-ui header-categories-icon-ui ti-menu"></i> <span class="va-mid-ui line-height-1-ui">{{translations.Categories}}</span> </a> </li> <li class="main-navigation-bar-links-ui"> <ul> {% assign manufacturersSize = manufacturer-brand.Manufacturers | Size -%} {% if usr.Authenticated == true -%} {% if settings.discountsPresentationInCustomerProfileInPromotionsTab == 'yes' and settings.promotions -%} <li class="no-on-mobile-ui" style="order: {{settings.promotionsNo}};"> <a href="{{settings.promotionsLink}}"> {% if settings.promotionsIcon != '' -%} <i class="va-mid-ui {{settings.promotionsIcon}} header-manufacturers-icon-ui header-categories-icon-ui"></i> {% endif -%} <span class="va-mid-ui line-height-1-ui documents-ui"> {% if settings.promotionsTranslation != '' -%} {{ translations[settings.promotionsTranslation] }} {% else -%} {{ settings.promotionsLabel }} {% endif -%} </span> </a> </li> {% endif -%} {% if settings.documents -%} <li class="no-on-mobile-ui" style="order: {{settings.documentsNo}};"> <a href="{{settings.documentsLink}}"> {% if settings.documentsIcon != '' -%} <i class="va-mid-ui {{settings.documentsIcon}} header-manufacturers-icon-ui header-categories-icon-ui"></i> {% endif -%} <span class="va-mid-ui line-height-1-ui documents-ui"> {% if settings.documentsTranslation != '' -%} {{ translations[settings.documentsTranslation] }} {% else -%} {{ settings.documentsLabel }} {% endif -%} </span> </a> </li> {% endif -%} {% assign manufacturers = settings.authenticatedManufacturers -%} {% assign manufacturersNo = settings.authenticatedManufacturersNo -%} {% assign manufacturersIcon = settings.authenticatedManufacturersIcon -%} {% assign manufacturersLabel = settings.authenticatedManufacturersLabel -%} {% assign manufacturersTranslation = settings.authenticatedManufacturersTranslation -%} {% assign manufacturersLink = settings.authenticatedManufacturersLink -%} {% assign searchAdvanced = settings.authenticatedSearchAdvanced -%} {% assign searchAdvancedNo = settings.authenticatedSearchAdvancedNo -%} {% assign searchAdvancedIcon = settings.authenticatedSearchAdvancedIcon -%} {% assign searchAdvancedLabel = settings.authenticatedSearchAdvancedLabel -%} {% assign searchAdvancedTranslation = settings.authenticatedSearchAdvancedTranslation -%} {% assign searchAdvancedLink = settings.authenticatedSearchAdvancedLink -%} {% assign cartImport = settings.authenticatedCartImport -%} {% assign cartImportNo = settings.authenticatedCartImportNo -%} {% assign cartImportIcon = settings.authenticatedCartImportIcon -%} {% assign cartImportLabel = settings.authenticatedCartImportLabel -%} {% assign cartImportTranslation = settings.authenticatedCartImportTranslation -%} {% assign cartImportLink = settings.authenticatedCartImportLink -%} {% assign downloadCSV = settings.authenticatedDownloadCSV -%} {% assign downloadCSVNo = settings.authenticatedDownloadCSVNo -%} {% assign downloadCSVIcon = settings.authenticatedDownloadCSVIcon -%} {% assign downloadCSVLabel = settings.authenticatedDownloadCSVLabel -%} {% assign downloadCSVTranslation = settings.authenticatedDownloadCSVTranslation -%} {% assign downloadCSVLink = settings.authenticatedDownloadCSVLink -%} {% assign customerLinks = settings.authenticatedCustomerLinks -%} {% else -%} {% assign manufacturers = settings.notAuthenticatedManufacturers -%} {% assign manufacturersNo = settings.notAuthenticatedManufacturersNo -%} {% assign manufacturersIcon = settings.notAuthenticatedManufacturersIcon -%} {% assign manufacturersLabel = settings.notAuthenticatedManufacturersLabel -%} {% assign manufacturersTranslation = settings.notAuthenticatedManufacturersTranslation -%} {% assign manufacturersLink = settings.notAuthenticatedManufacturersLink -%} {% assign searchAdvanced = settings.notAuthenticatedSearchAdvanced -%} {% assign searchAdvancedNo = settings.notAuthenticatedSearchAdvancedNo -%} {% assign searchAdvancedIcon = settings.notAuthenticatedSearchAdvancedIcon -%} {% assign searchAdvancedLabel = settings.notAuthenticatedSearchAdvancedLabel -%} {% assign searchAdvancedTranslation = settings.notAuthenticatedSearchAdvancedTranslation -%} {% assign searchAdvancedLink = settings.notAuthenticatedSearchAdvancedLink -%} {% assign cartImport = settings.notAuthenticatedCartImport -%} {% assign cartImportNo = settings.notAuthenticatedCartImportNo -%} {% assign cartImportIcon = settings.notAuthenticatedCartImportIcon -%} {% assign cartImportLabel = settings.notAuthenticatedCartImportLabel -%} {% assign cartImportTranslation = settings.notAuthenticatedCartImportTranslation -%} {% assign downloadCSV = settings.notAuthenticatedDownloadCSV -%} {% assign downloadCSVNo = settings.notAuthenticatedDownloadCSVNo -%} {% assign downloadCSVIcon = settings.notAuthenticatedDownloadCSVIcon -%} {% assign downloadCSVLabel = settings.notAuthenticatedDownloadCSVLabel -%} {% assign downloadCSVTranslation = settings.notAuthenticatedDownloadCSVTranslation -%} {% assign customerLinks = settings.notAuthenticatedCustomerLinks -%} {% endif -%} {% assign manufacturersSize = manufacturer-brand.Manufacturers | Size -%} {% if manufacturers and manufacturersSize > 0 -%} <li class="{% if page.PageId == config.DefinedPages.Manufacturers.Id -%} active-bar-ui {% else -%} no-on-mobile-ui {% endif -%}" style="order: {{manufacturersNo}};"> {% if page.PageId == config.DefinedPages.Manufacturers.Id -%} <span class="block-ui page-label-ui"> {% else -%} <a href="{{manufacturersLink}}"> {% endif -%} {% if manufacturersIcon != '' -%} <i class="va-mid-ui {{manufacturersIcon}} header-manufacturers-icon-ui"></i> {% endif -%} <span class="va-mid-ui line-height-1-ui"> {% if manufacturersTranslation != '' -%} {{ translations[manufacturersTranslation] }} {% else -%} {{ manufacturersLabel }} {% endif -%} </span> {% if page.PageId != 20 -%} </a> {% else -%} </span> {% endif -%} </li> {% endif -%} {% if searchAdvanced -%} <li class="{% if config.DefinedPages.AdvancedSearch.Id == page.PageId -%} active-bar-ui {% else -%} no-on-mobile-ui {% endif -%}" style="order: {{searchAdvancedNo}};"> {% if config.DefinedPages.AdvancedSearch.Id == page.PageId -%} <span class="block-ui page-label-ui"> {% else -%} <a href="{{searchAdvancedLink}}"> {% endif -%} {% if searchAdvancedIcon != '' -%} <i class="va-mid-ui {{searchAdvancedIcon}} header-manufacturers-icon-ui"></i> {% endif -%} <span class="va-mid-ui line-height-1-ui"> {% if searchAdvancedTranslation != '' -%} {{ translations[searchAdvancedTranslation] }} {% else -%} {{ searchAdvancedLabel }} {% endif -%} </span> {% if config.DefinedPages.AdvancedSearch.Id != page.PageId -%} </a> {% else -%} </span> {% endif -%} </li> {% endif -%} {% if cartImport -%} <li class="no-on-mobile-ui" style="order: {{cartImportNo}};"> <label for="file" class="import-cart-lq import-cart-ui block-ui page-label-ui"> {% if cartImportIcon != '' -%} <i class="{{cartImportIcon}} header-manufacturers-icon-ui"></i> {% endif -%} {% if cartImportTranslation != '' -%} {{ translations[cartImportTranslation] }} {% else -%} {{ cartImportLabel }} {% endif -%} </label> <input class="import-cart-input-lq" id="file" type="file" name="file" accept=".csv" {% if settings.afterAddingToCart == 1 -%} data-redirect-url="{{ page.BaseHref }}{{ config.DefinedPages.Order.Url }}" {% endif -%} /> {% if settings.afterAddingToCart == 3 -%} <div class="message-popup-background-ui after-importing-cart-popup-lq container-to-hide-lq hide-container-lq hidden-lq"> {% include 'product/after-adding-to-cart.html' -%} </div> {% endif -%} <div class="importing-cart-succeed-lq message-popup-background-ui hidden-lq hide-lq container-to-hide-lq" data-url="{{ page.BaseHref }}{{ config.DefinedPages.Order.Url }}"> <div class="message-popup-ui box-ui after-adding-to-cart-popup-ui after-importing-popup-container-lq"> <div class="box-ui product-added-to-cart-ui"> <i class="va-mid-ui ti-check"></i> <span class="va-mid-ui line-height-1-ui"> {% if customer.Cart.EditedOrderId -%} {{ translations.AddedToOrder }} {% else -%} {{ translations.AddedToCart }} {% endif -%} </span> </div> </div> </div> <div class="during-ajax-modal-lq during-ajax-modal-ui hidden-lq"> <div class="loader-ui big-ui"></div> </div> </li> {% endif -%} {% if downloadCSV -%} <li class="no-on-mobile-ui" style="order: {{downloadCSVNo}};"> <a href="usr/cart_importcsv_file.csv"> {% if downloadCSVIcon != '' -%} <i class="{{downloadCSVIcon}} header-manufacturers-icon-ui"></i> {% endif -%} {% if downloadCSVTranslation != '' -%} {{ translations[downloadCSVTranslation] }} {% else -%} {{ downloadCSVLabel }} {% endif -%} </a> </li> {% endif -%} {% for customerLink in customerLinks -%} {% if customerLink.available -%} <li class="no-on-mobile-ui" style="order: {{customerLink.no}};"> <a href="{{customerLink.link}}"> {% if customerLink.icon != '' -%} <i class="{{customerLink.icon}} header-manufacturers-icon-ui"></i> {% endif -%} {% if customerLink.translation != '' -%} {{ translations[customerLink.translation] }} {% else -%} {{ customerLink.label }} {% endif -%} </a> </li> {% endif -%} {% endfor -%} </ul> </li> </ul> </nav> {% endif -%} Następnie dodamy ustawienia do szablonu. W tym celu należy użyć narzędzia wyszukiwania w pliku _settings.liquid i wyszukać pierwsze wystąpienie frazy {% else %}, a następnie wkleić następujący kod linijkę wyżej: {% assign general = "Ogólne" -%} {% assign navigationBarSettings = "Ustawienia paska nawigacji na stronie głównej" -%} {% assign notAuthenticatedInfo = "Lista elementów zawartych w pasku nawigacji dla klientów niezalogowanych" -%} {% assign authenticatedInfo = "Lista elementów zawartych w pasku nawigacji dla klientów zalogowanych" -%} {% assign available = "Dostępne" -%} {% assign number = "Lp" -%} {% assign icon = "Ikona" -%} {% assign polishLabel = "Etykieta PL" -%} {% assign translationId = "Id tłumaczenia" -%} {% assign linkAction = "link/akcja" -%} {% assign cartImport = "Import koszyka" -%} {% assign cartImportInfo = "Opcja importu koszyka z pliku CSV" -%} {% assign downloadCSV = "Pobierz przykładowy plik CSV" -%} {% assign downloadCSVInfo = "Przykładowy plik CSV do importu koszyka" -%} {% assign searchAdvanced = "Wyszukiwarka zaawansowana" -%} {% assign promotions = "Promocje" -%} {% assign documents = "Dokumenty" -%} {% assign addLink = "Dodaj link" -%} {% assign delete = "Usuń" -%} W tym sam pliku szukamy pierwszego wystąpienia frazy {% endcase %} i wklejamy następujący kod linijkę wyżej: {% assign general = "General" -%} {% assign navigationBarSettings = "Homepage navigation bar settings" -%} {% assign notAuthenticatedInfo = "List of elements in navigation bar for not authenticated customers" -%} {% assign authenticatedInfo = "List of elements in navigation bar for authenticated customers" -%} {% assign available = "Available" -%} {% assign number = "No" -%} {% assign icon = "Icon" -%} {% assign polishLabel = "Label PL" -%} {% assign translationId = "Translation Id" -%} {% assign linkAction = "link/action" -%} {% assign cartImport = "Cart import" -%} {% assign cartImportInfo = "Cart import option from CSV file" -%} {% assign downloadCSV = "Download sample CSV file" -%} {% assign downloadCSVInfo = "Sample CSV file for cart import" -%} {% assign searchAdvanced = "Search advanced" -%} {% assign promotions = "Promotions" -%} {% assign documents = "Documents" -%} {% assign addLink = "Add link" -%} {% assign delete = "Delete" -%}

Kolejnym krokiem jest wyszukanie frazy <script> oraz wklejenie bezpośrednio nad nią następującego kodu:

<div id="tab1Content"> <fieldset> <legend>{{notAuthenticatedInfo}}</legend> <div> <div class="row"> <div class="cell available">{{available}}</div> <div class="cell no">{{number}}</div> <div class="cell">{{icon}}</div> <div class="cell">{{polishLabel}}</div> <div class="cell">{{translationId}}</div> <div class="cell">{{linkAction}}</div> <div class="cell delete">{{delete}}</div> </div> <div class="row"> <div class="cell available"><input type="checkbox" name="notAuthenticatedCartImport" {% if settings.notAuthenticatedCartImport -%} checked {% endif -%} /></div> <div class="cell no"><input type="number" name="notAuthenticatedCartImportNo" value="{{ settings.notAuthenticatedCartImportNo }}" /></div> <div class="cell"><input type="text" name="notAuthenticatedCartImportIcon" value="{{ settings.notAuthenticatedCartImportIcon }}" /></div> <div class="cell"><input type="text" name="notAuthenticatedCartImportLabel" value="{{ settings.notAuthenticatedCartImportLabel }}" /></div> <div class="cell"><input type="text" name="notAuthenticatedCartImportTranslation" value="{{ settings.notAuthenticatedCartImportTranslation }}" /></div> <div class="cell">{{cartImportInfo}}</div> <div class="cell delete"></div> </div> <div class="row"> <div class="cell available"><input type="checkbox" name="notAuthenticatedDownloadCSV" {% if settings.notAuthenticatedDownloadCSV -%} checked {% endif -%} /></div> <div class="cell no"><input type="number" name="notAuthenticatedDownloadCSVNo" value="{{ settings.notAuthenticatedDownloadCSVNo }}" /></div> <div class="cell"><input type="text" name="notAuthenticatedDownloadCSVIcon" value="{{ settings.notAuthenticatedDownloadCSVIcon }}" /></div> <div class="cell"><input type="text" name="notAuthenticatedDownloadCSVLabel" value="{{ settings.notAuthenticatedDownloadCSVLabel }}" /></div> <div class="cell"><input type="text" name="notAuthenticatedDownloadCSVTranslation" value="{{ settings.notAuthenticatedDownloadCSVTranslation }}" /></div> <div class="cell">{{downloadCSVInfo}}</div> <div class="cell delete"></div> </div> <div class="row"> <div class="cell available"><input type="checkbox" name="notAuthenticatedSearchAdvanced" {% if settings.notAuthenticatedSearchAdvanced -%} checked {% endif -%} /></div> <div class="cell no"><input type="number" name="notAuthenticatedSearchAdvancedNo" value="{{ settings.notAuthenticatedSearchAdvancedNo }}" /></div> <div class="cell"><input type="text" name="notAuthenticatedSearchAdvancedIcon" value="{{ settings.notAuthenticatedSearchAdvancedIcon }}" /></div> <div class="cell"><input type="text" name="notAuthenticatedSearchAdvancedLabel" value="{{ settings.notAuthenticatedSearchAdvancedLabel }}" /></div> <div class="cell"><input type="text" name="notAuthenticatedSearchAdvancedTranslation" value="{{ settings.notAuthenticatedSearchAdvancedTranslation }}" /></div> <div class="cell"><input type="text" name="notAuthenticatedSearchAdvancedLink" value="{{ settings.notAuthenticatedSearchAdvancedLink }}" /></div> <div class="cell delete"></div> </div> {% for customerLink in settings.notAuthenticatedCustomerLinks -%} <div class="row notAuthenticatedCustomerLink" data-index="{{forloop.index0}}"> <div class="cell available"><input type="checkbox" name="notAuthenticatedCustomerLink{{forloop.index0}}" {% if customerLink.available -%} checked {% endif -%} /></div> <div class="cell no"><input type="number" name="notAuthenticatedCustomerLinkNo{{forloop.index0}}" value="{{ customerLink.no }}" /></div> <div class="cell"><input type="text" name="notAuthenticatedCustomerLinkIcon{{forloop.index0}}" value="{{ customerLink.icon }}" /></div> <div class="cell"><input type="text" name="notAuthenticatedCustomerLinkLabel{{forloop.index0}}" value="{{ customerLink.label }}" /></div> <div class="cell"><input type="text" name="notAuthenticatedCustomerLinkTranslation{{forloop.index0}}" value="{{ customerLink.translation }}" /></div> <div class="cell"><input type="text" name="notAuthenticatedCustomerLinkLink{{forloop.index0}}" value="{{ customerLink.link }}" /></div> <div class="cell delete"><div class="fa fa-trash"></div></div> </div> {% endfor -%} </div> <button class="add-link">{{addLink}}</button> <input name="customer-links" type="hidden" value="{{settings.notAuthenticatedCustomerLinks | Size }}" /> </fieldset> <fieldset> <legend>{{authenticatedInfo}}</legend> <div> <div class="row"> <div class="cell available">{{available}}</div> <div class="cell no">{{number}}</div> <div class="cell">{{icon}}</div> <div class="cell">{{polishLabel}}</div> <div class="cell">{{translationId}}</div> <div class="cell">{{linkAction}}</div> <div class="cell delete">{{delete}}</div> </div> <div class="row"> <div class="cell available"><input type="checkbox" name="authenticatedCartImport" {% if settings.authenticatedCartImport -%} checked {% endif -%} /></div> <div class="cell no"><input type="number" name="authenticatedCartImportNo" value="{{ settings.authenticatedCartImportNo }}" /></div> <div class="cell"><input type="text" name="authenticatedCartImportIcon" value="{{ settings.authenticatedCartImportIcon }}" /></div> <div class="cell"><input type="text" name="authenticatedCartImportLabel" value="{{ settings.authenticatedCartImportLabel }}" /></div> <div class="cell"><input type="text" name="authenticatedCartImportTranslation" value="{{ settings.authenticatedCartImportTranslation }}" /></div> <div class="cell">{{cartImportInfo}}</div> <div class="cell delete"></div> </div> <div class="row"> <div class="cell available"><input type="checkbox" name="authenticatedDownloadCSV" {% if settings.authenticatedDownloadCSV -%} checked {% endif -%} /></div> <div class="cell no"><input type="number" name="authenticatedDownloadCSVNo" value="{{ settings.authenticatedDownloadCSVNo }}" /></div> <div class="cell"><input type="text" name="authenticatedDownloadCSVIcon" value="{{ settings.authenticatedDownloadCSVIcon }}" /></div> <div class="cell"><input type="text" name="authenticatedDownloadCSVLabel" value="{{ settings.authenticatedDownloadCSVLabel }}" /></div> <div class="cell"><input type="text" name="authenticatedDownloadCSVTranslation" value="{{ settings.authenticatedDownloadCSVTranslation }}" /></div> <div class="cell">{{downloadCSVInfo}}</div> <div class="cell delete"></div> </div> <div class="row"> <div class="cell available"><input type="checkbox" name="promotions" {% if settings.promotions -%} checked {% endif -%} /></div> <div class="cell no"><input type="number" name="promotionsNo" value="{{ settings.promotionsNo }}" /></div> <div class="cell"><input type="text" name="promotionsIcon" value="{{ settings.promotionsIcon }}" /></div> <div class="cell"><input type="text" name="promotionsLabel" value="{{ settings.promotionsLabel }}" /></div> <div class="cell"><input type="text" name="promotionsTranslation" value="{{ settings.promotionsTranslation }}" /></div> <div class="cell"><input type="text" name="promotionsLink" value="{{ settings.promotionsLink }}" /></div> <div class="cell delete"></div> </div> <div class="row"> <div class="cell available"><input type="checkbox" name="documents" {% if settings.documents -%} checked {% endif -%} /></div> <div class="cell no"><input type="number" name="documentsNo" value="{{ settings.documentsNo }}" /></div> <div class="cell"><input type="text" name="documentsIcon" value="{{ settings.documentsIcon }}" /></div> <div class="cell"><input type="text" name="documentsLabel" value="{{ settings.documentsLabel }}" /></div> <div class="cell"><input type="text" name="documentsTranslation" value="{{ settings.documentsTranslation }}" /></div> <div class="cell"><input type="text" name="documentsLink" value="{{ settings.documentsLink }}" /></div> <div class="cell delete"></div> </div> <div class="row"> <div class="cell available"><input type="checkbox" name="authenticatedSearchAdvanced" {% if settings.authenticatedSearchAdvanced -%} checked {% endif -%} /></div> <div class="cell no"><input type="number" name="authenticatedSearchAdvancedNo" value="{{ settings.authenticatedSearchAdvancedNo }}" /></div> <div class="cell"><input type="text" name="authenticatedSearchAdvancedIcon" value="{{ settings.authenticatedSearchAdvancedIcon }}" /></div> <div class="cell"><input type="text" name="authenticatedSearchAdvancedLabel" value="{{ settings.authenticatedSearchAdvancedLabel }}" /></div> <div class="cell"><input type="text" name="authenticatedSearchAdvancedTranslation" value="{{ settings.authenticatedSearchAdvancedTranslation }}" /></div> <div class="cell"><input type="text" name="authenticatedSearchAdvancedLink" value="{{ settings.authenticatedSearchAdvancedLink }}" /></div> <div class="cell delete"></div> </div> {% for customerLink in settings.authenticatedCustomerLinks -%} <div class="row authenticatedCustomerLink" data-index="{{forloop.index0}}"> <div class="cell available"><input type="checkbox" name="authenticatedCustomerLink{{forloop.index0}}" {% if customerLink.available -%} checked {% endif -%} /></div> <div class="cell no"><input type="number" name="authenticatedCustomerLinkNo{{forloop.index0}}" value="{{ customerLink.no }}" /></div> <div class="cell"><input type="text" name="authenticatedCustomerLinkIcon{{forloop.index0}}" value="{{ customerLink.icon }}" /></div> <div class="cell"><input type="text" name="authenticatedCustomerLinkLabel{{forloop.index0}}" value="{{ customerLink.label }}" /></div> <div class="cell"><input type="text" name="authenticatedCustomerLinkTranslation{{forloop.index0}}" value="{{ customerLink.translation }}" /></div> <div class="cell"><input type="text" name="authenticatedCustomerLinkLink{{forloop.index0}}" value="{{ customerLink.link }}" /></div> <div class="cell delete"><div class="fa fa-trash"></div></div> </div> {% endfor -%} </div> <button class="add-link authenticated">{{addLink}}</button> <input name="customer-links" type="hidden" value="{{settings.authenticatedCustomerLinks | Size }}" /> </fieldset> </div> </div>

Po wykonaniu powyższych instrukcji należy wyszukać frazy </style> i wkleić następujący kod bezpośrednio nad wyszukaną linijką:

#lg-settings-content #tab1Content fieldset { width: calc(100% - 50px); } #lg-settings-content .row { border-bottom: 1px solid #ddd; } #lg-settings-content .row:first-child { border-top: 1px solid #ddd; border-bottom: 2px solid #ddd; font-weight: 700; } #lg-settings-content .row::after { display: block; clear: both; content: ''; } #lg-settings-content .cell { border-left: 1px solid #ddd; display: inline-block; vertical-align: middle; width: calc((100% - 308px)/4); min-height: 20px; padding: 10px; float: left; } #lg-settings-content .cell:last-child { border-right: 1px solid #ddd; } #lg-settings-content .cell input { width: 100%; height: 20px; } #lg-settings-content .cell.available { width: 70px; } #lg-settings-content .cell.available input { display: block; margin: 0; cursor: pointer; } #lg-settings-content .cell.no { width: 50px; } #lg-settings-content .cell.no input { width: 40px; height: 14px; } #lg-settings-content .cell.delete { width: 40px; text-align: center; } #lg-settings-content .cell.delete .fa { cursor: pointer; } #lg-settings-content .yellow-box { padding: 20px; border: 1px solid #fec42f; font-size: 14px; font-weight: 400 !important; position: relative; } #lg-settings-content .yellow-box:after { content: ''; width: 30px; height: 30px; position: absolute; top: 10px; right: 15px; background: url(../../Content/Images/all/important.png) no-repeat; } Ostatnią zmianą w pliku będzie dodanie kodu bezpośrednio nad wyszukaną frazą } </script>: $('#lg-settings-content').on('click', '.fa-trash', function(e){ $(e.currentTarget).parents('.row').remove(); }); function addCustomerLinksArr(name, o){ var customerLinks = []; $('#lg-settings-content .'+name).each(function(i,el) { var index = $(this).data('index'); var available = $(this).find('[name='+name+index+']').prop('checked'); var no = $(this).find('[name='+name+'No'+index+']').val(); var icon = $(this).find('[name='+name+'Icon'+index+']').val(); var label = $(this).find('[name='+name+'Label'+index+']').val(); var translation = $(this).find('[name='+name+'Translation'+index+']').val(); var link = $(this).find('[name='+name+'Link'+index+']').val(); if(no && (label || translation) && link){ var obj = {available: available, no: no, icon: icon, label: label, translation: translation, link: link}; customerLinks.push(obj); } }); if(customerLinks.length > 0){ o[name+'s'] = customerLinks; } } function __SaveLiquidSettings(){ var o = {}; $('#lg-settings-content input[name]').each(function(i,el) { if($(el).attr('type') == 'radio' || $(el).attr('type') == 'checkbox') { if($(el).is(':checked')) { o[el.name] = el.value; } } else { o[el.name] = el.value; } }); addCustomerLinksArr('authenticatedCustomerLink', o); addCustomerLinksArr('notAuthenticatedCustomerLink', o); return o; } Następnie przechodzimy do pliku scss/desktop2.scss i na jego końcu wklejamy kod: .main-navigation-bar-ui{ background: $bgColor; .manufacturer-container-ui{ border-top: none; border-bottom: none; li{ margin-right: -1px; border-bottom: 1px solid $lightBorderColor; } .categories-opened-ui{ vertical-align: bottom; float: none; display: inline-block; margin-right: -5px; border-top: 1px solid $lightBorderColor; margin-bottom: 0px; height: 68px; } .main-navigation-bar-links-ui{ width: calc(100% - 320px); vertical-align: bottom; background: $menuBackgroundColor; float: none; display: inline-block; border-left: 1px solid $lightBorderColor; border-top: 1px solid $lightBorderColor; border-bottom: none; border-right: none; ul{ display: flex; flex-wrap: wrap; } } } } Teraz przejdź do Panelu Administratora. Wybierz Wygląd Sklepu/ Ustawienia i przejdź w zakładkę Tłumaczenia. Po kliknięciu w przycisk Dodaj należy wpisać Id tłumaczenia oraz Tekst, który będzie się wyświetlał w e-Sklepie. Zmiany należy zatwierdzić przyciskiem Dodaj.
  • Id: ShowProducts -- Tekst: Pokaż produkty
  • Id: ShowMore -- Tekst: Pokaż więcej
Ostatnim krokiem jest dodanie nowego elementu do nawigacji. W tym celu przejdź w zakładkę Szablon, a następnie Ustawienia paska nawigacji na stronie głównej, gdzie należy uzupełnić pola według własnych upodobań.
  • Etykieta PL - nazwa etykiety (na przykład: ti-import)
  • Id tłumaczenia - nazwa jaka będzie widoczna na elemencie
  • Link/Akcja - link do strony

Aktualizacja filtrów i wyszukiwarki w szablonach

Wskazówka
Od 1 czerwca 2025 roku zakończyliśmy aktualizację oraz wydawanie nowych wersji szablonów Bursztyn, Agat i Opal, a tym samym ich wsparcie, aby skupić się na nowoczesnych rozwiązaniach, które jeszcze lepiej odpowiadają na potrzeby dynamicznie rozwijającego się rynku e-commerce. Zachęcamy Was do przejścia na nasze nowe, udoskonalone szablony. Dla sklepów B2C polecamy szablony Topaz, One Page Shop oraz Dla Gastronomii, natomiast dla platform B2B idealnym wyborem będą Rubin i Szafir.

Aktualizacja filtrów i wyszukiwarki w szablonach

W tym artykule dowiesz się jak zmodyfikować swój szablon, aby w lepszy sposób obsługiwał filtry i wyszukiwarkę.
Wskazówka
W tym artykule trzeba będzie wprowadzać zmiany w plikach js. Z tego artykułu dowiesz się jak je minifikować.

Szafir

W pliku common/pagination.html wyszukaj frazę {% if products.Search -%}. W tym warunku znajduje się tylko jedna linijka. Podmień ją na {% capture url -%}{{products.Search.Url}}{% endcapture -%} Następnie w pliku js/init.js, wyszukaj funkcję filter, a w niej $.get. Zastąp go wraz z całą jego zawartością poniższym kodem: $.get('', param, function (result) { app.serverMessage(result, form, e); if (result.action.Result) { if(result.action.Redirect302 != null){ app.replace(result.action.Redirect302); } else { app.replace(window.location.pathname); } } });

Agat

W pliku partials/blog/list-pagination.html wyszukaj frazę {% if products.Search -%}. W tym warunku znajduje się tylko jedna linijka. Podmień ją na {% capture url -%}{{products.Search.Url}}{% endcapture -%} Następnie na początku pliku js/init2.js, wyszukaj funkcję oznaczoną komentarzem // filters, a w niej warunek if (d.length == 2 && !d[0].value && !d[1].value) {. Usuń ten warunek wraz z jego zawartością. Kilka linijek niżej jest $.get. Zastąp go wraz z całą jego zawartością poniższym kodem: $.get('', p, function (d) { if (d.action.Result) { if (d.action.Redirect302 != null) { LoadList(d.action.Redirect302); } } });

Bursztyn lub Opal

W pliku product/listpagination.html wyszukaj frazę {% if products.Search -%}. W tym warunku znajduje się tylko jedna linijka. Podmień ją na {% capture url -%}{{products.Search.Url}}{% endcapture -%} Następnie w pliku js/list.js, wyszukaj funkcję oznaczoną komentarzem // filters, a w niej warunek if (d.length == 2 && !d[0].value && !d[1].value) {. Usuń ten warunek wraz z jego zawartością. Kilka linijek niżej jest $.get. Zastąp go wraz z całą jego zawartością poniższym kodem: $.get('', p, function (d) { if (d.action.Result) { if (d.action.Redirect302 != null) { LoadList(d.action.Redirect302+'#products'); } } });

Topaz

W pliku partials/list-pagination.html wyszukaj frazę {% if products.Search -%}. W tym warunku znajduje się tylko jedna linijka. Podmień ją na {% capture url -%}{{products.Search.Url}}{% endcapture -%} Następnie w pliku js/layout.js, wyszukaj funkcję getSearchFilters, a w niej warunek if (d.length == 2 && !d[0].value && !d[1].value) {. Usuń ten warunek wraz z jego zawartością. Kilka linijek niżej jest $.get. Zastąp go wraz z całą jego zawartością poniższym kodem: $.get('', p, function (d) { if (d.action.Result) { if (d.action.Redirect302 != null) { location.href = d.action.Redirect302; } } });

Dodanie nowego widoku filtrów

Dodanie nowego widoku filtrów

Szablon Szafir umożliwia dodanie w nim nowego widoku filtrów oraz modyfikowację ustawienia szablonu, aby był bardziej czytelny. Zmiany wyglądu dotyczą opisu danej kategorii i graficznych odnośników do podkategorii.
Wskazówka
W tym artykule dowiesz się jak wprowadzać zmiany w plikach js i scss. Dodatkowe informacje o kompilacji i minifikacji znajdziesz w centrum pomocy.

Szafir

W pliku __settings.liquid dodaj poniżesze tłumaczenia: {% assign productsList = "Lista towarów" -%} {% assign filterPanel = "Panel filtra" -%} {% assign filterPanelView = "Widok panelu filtra" -%} {% assign filterPanelViewOption1 = "Po lewej pod menu kategorii" -%} {% assign filterPanelViewOption2 = "U góry nad listą towarów" -%} {% assign defaultSection = "Sekcja domyślnie" -%} {% assign closed = "Zwinięta" -%} {% assign opened = "Rozwinięta" -%} {% assign graphMenu = "Graficzne menu" -%} {% assign graphMenuInfo = "Dodatkowe, graficzne menu nawigacji do podgrup" -%} {% assign category = "Kategoria" -%} {% assign nameGraphDescCategory = "Nazwa, grafika i opis kategorii" -%} {% assign overProductsList = "Nad listą towarów" -%} {% assign underProductsList = "Pod listą towarów" -%} {% assign graphFormOfNameDescImgCategory = "Forma graficzna prezentowania nazwy, opisu i zdjęcia kategorii" -%} {% assign backgroundImage = "Zdjęcie w tle" -%} {% assign leftImage = "Zdjęcie po lewej" -%} W tym samym pliku wyszukaj frazę id="tab1" i linijkę niżej wklej: {{productsList}} Teraz wyszukaj frazę: {% endif -%}
{% endblock -%}
products/product-filters.html
{% if settings.filterPanelView == "left" -%}

{{translations.Filters}}

{% endif -%}
    {% assign fo = products.FilteringOptions -%} {% unless customer.HidePrices -%}
  • {{ translations.Price }}
    {{translations.RangeFrom | Downcase }} {{translations.RangeTo | Downcase }} {{ currencyExt }}
  • {% endunless -%} {% if settings.graphicColorFilter == 'yes' and color-filter.Content and color-filter.Content != '' %} {% assign colorFilterArr = color-filter.Content | StripNewlines | Split: '|||' -%} {% assign colorFilterName = colorFilterArr[0] -%} {% assign colorFilterValues = colorFilterArr[1] | Split: '||' -%} {% endif -%} {% for filter in fo.Filters -%} {% unless filter.Field == 'MARK' and config.Reviews.Enabled == false -%} {% assign isSthSelected = false -%} {% assign allSelected = false -%} {% assign selectedQuantity = 0 -%} {% for value in filter.Values -%} {% if value.Selected -%} {% if isSthSelected == false and settings.toggleFilters == 2 -%} {% assign isSthSelected = true -%} {% endif -%} {% capture stringToAdd -%}{{value.Field}}|{{filter.Heading}}|{{value.Value}}|{{value.Text}}||{% endcapture -%} {% assign activeFiltersKeysString = activeFiltersKeysString | Append: stringToAdd -%} {% assign activeFiltersQuantity = activeFiltersKeysString | Split:'||' | Size -%} {% assign selectedQuantity = selectedQuantity | Plus: 1 -%} {% assign filtersQuantity = filter.Values | Size -%} {% if selectedQuantity == filtersQuantity -%} {% assign allSelected = true -%} {% endif -%} {% endif -%} {% endfor -%}
  • {% if settings.filterPanelView == "left" -%} {% else -%} {% endif -%}
    {% assign filterValuesLength = filter.Values | Size -%} {% if filter.Field == colorFilterName or isSthSelected or settings.filterPanelView == "up" -%} {% assign limit = filterValuesLength | ToInt -%} {% else -%} {% assign limit = settings.maxfilter | ToInt -%} {% endif -%}
    {% for value in filter.Values limit: limit -%} {% endfor -%}
    {% if filterValuesLength > limit and filter.Field != colorFilterName and settings.filterPanelView == "left" -%} {% endif -%}
  • {% endunless -%} {% endfor -%} {% if settings.filterPanelView == "up" -%}
  • {% endif -%}
{% if settings.filterPanelView == "left" -%} {% endif -%}
W pliku common/categories-navigation/categories-navigation-partial.html na samym dole znajdź warunek {% if areFilteringOptionsClass == 'with-filters-ui' -%} i zamień go na {% if areFilteringOptionsClass == 'with-filters-ui' and settings.filterPanelView == "left" -%} Następnie w pliku js/init.js znajdź frazę events: function() i linijkę niżej wklej poniższy kod: $('body').on('change', '.all-values-checkbox-lq', function(e) { var isChecked = $(e.currentTarget).prop('checked'); $(e.currentTarget).parents('.filter-item-lq').find('[type=checkbox]').prop('checked', isChecked); }); $('body').on('change', '.filters-up-lq .product-filters-lq input', function(e) { app.filter(e); }); Kontynuując zmiany w tym samym pliku, wyszukaj frazę form.find('[type="number"]').val(''); i zmień tam number na tel. Na końcu funkcji w której znajduje się ta fraza dopisz app.filter(e);. Przejdź do pliku js/init-ui1.js i na samym końcu wklej poniższy kod: $('body').on('click', '.toggle-filters-button-lq', function () { $('.filters-label-lq').toggleClass('hidden-lq'); }); W tym momencie masz już dodany filtr, w następnych krokach będziesz edytował styl. W pliku scss/globals/_globals-m.scss znajdź frazę .products-page-lq{ i usuń z tej klasy margin-top: 114px;. Kilka linijek niżej znajdziesz: .category-description-ui{ display: none; } Usuń ten fragment. Jeszcze niżej znajdziesz .category-img-ui{. Usuń w nim height: auto !important;. Znajdz i usuń poniższy fragment: .view-options-mobile-ui{ width: 21px; margin-right: 20px; } Linijkę niżej jest kod .sorting-options-ui{. Zmień w nim linijkę width: calc(100vw - 80px - 21px - 60px); na width: calc(100vw - 192px); i usuń oba wpisy związane z wysokością height: 26px;. Następnie w obrębie @media only screen and (max-width: 1279px) { (np w 2 linijce pliku) wklej poniższy kod: .products-navigation-ui.filters-up-ui .sorting-views-container-ui .sorting-options-ui{ .dropdown-trigger-ui{ padding: 10px; } .toggle-filters-button-ui{ padding-bottom: 0; & + .active-sorting-option-ui{ display: block; } } } .filters-up-main-container-ui{ margin: 0; } .filters-up-ui{ position: static; margin: 0; width: 100%; background-color: $bgColor; .sorting-views-container-ui{ padding: 20px 20px 0 20px; } .product-filters-ui{ position: static; padding: 0; background: $bgColor; & > ul{ margin: 20px; li{ width: calc(50% - 10px); &:first-child{ width: 100%; } &:nth-child(5n){ margin-right: 20px; } &:nth-child(2n+1){ margin-right: 0; } } } } } .undercategory-links-ui{ padding: 0 20px; a{ width: calc(50% - 10px); &:nth-child(5n){ margin-right: 20px; } &:nth-child(2n){ margin-right: 0; } } } Przejdz do pliku scss/globals/_globals1.scss na samym dole wklej poniższy kod: .undercategory-links-ui{ display: flex; flex-wrap: wrap; a{ width: calc(20% - 16px); border: 1px solid $lightBorderColor; margin: 0 20px 20px 0; padding: 20px; text-align: center; &:nth-child(5n){ margin-right: 0; } } .category-name-ui{ font-weight: 700; margin-bottom: 20px; color: $primaryColorFont; } img{ max-width: 100%; max-height: 200px; } } .graph-desc-category-down-ui{ display: flex; flex-flow: column; .category-section-ui{ order: 1; } } .category-section-ui{ button{ display: flex; width: 100%; align-items: center; justify-content: space-between; border: 1px solid $lightBorderColor; padding: 20px; background: transparent; color: $primaryColorFont; } h1{ font-size: 20px; color: $primaryColorFont; } &.left-ui{ .category-img-ui .category-container-ui .category-container-bg-ui{ max-width: none; } .category-img-lq{ display: flex; border: 1px solid $lightBorderColor; height: auto !important; } .img-container-ui{ min-width: 150px; max-width: 150px; padding: 20px; } img{ max-height: 100%; } .category-container-ui{ position: static; } .category-description-ui{ height: auto !important; } } } .filters-up-ui{ flex-wrap: wrap; .toggle-filters-button-ui + .active-sorting-option-ui{ transition: all ease 300ms; } .sorting-options-ui .toggle-filters-button-ui{ padding-bottom: 10px; &.with-quantity-ui{ padding-bottom: 0; } &.expanded-lq{ background-color: $btnSolidBgColor; color: $btnSolidTextColor; & + .active-sorting-option-ui{ background-color: $btnSolidBgColor; color: $btnSolidTextColor; } } } .product-filters-ui > ul{ display: flex; flex-wrap: wrap; li{ width: calc(20% - 16px); border: 1px solid $lightBorderColor; margin: 0 20px 20px 0; &:nth-child(5n){ margin-right: 0; } } .price-filter-ui{ padding: 20px; } .reset-filters-ui{ border: none; } .filter-drop-ui{ padding: 10px 20px; border-bottom: 1px solid $lightBorderColor; } .filter-value-list-ui{ padding: 10px 20px; overflow: auto; &::-webkit-scrollbar { width: 4px; border-radius: 50%; } &::-webkit-scrollbar-track { -webkit-box-shadow: inset 0 0 4px transparent; } &::-webkit-scrollbar-thumb { background-color: rgba(#8E8E8E, 0.5); outline: none; border-radius: 2px; &:hover{ background-color: #8E8E8E; } } &.three-ui{ max-height: 140px; } &.five-ui{ max-height: 220px; } &.eight-ui{ max-height: 340px; } } } } Ostatnim krokiem będzie znalezienie w scss/partials/_product-list.scss frazy .change-view-ui i podmień margin-right na margin-left Jedyne zmiany w panelu administracyjnym wymagają dodania dwóch tłumaczeń. Wygląd sklepu -> Ustawienia -> Tłumaczenia: - CloseFilters: Zwiń filtry - ClearAllFilters: Wyczyść wszystkie filtry

Zmiana nagłówka sekcji polecanych towarów na przykładzie szablonu Topaz

Wstęp

W standardowym szablonie Topaz sekcja polecanych towarów domyślnie wyświetla się z nazwą "Towary polecane". W tym artykule dowiesz się w jaki sposób dostosować tą nazwę do swojego e-Sklepu.  

Dodanie tłumaczenia

Tytuł sekcji Towary polecane można zmienić dodając odpowiednie tłumaczenie do szablonu oraz edytując kod HTML szablonu. W pierwszej kolejności należy dodać tłumaczenie w sekcji Wygląd sklepu/ Ustawienia/ Tłumaczenia po kliknięciu w przycisk Dodaj należy wpisać Id tłumaczenia oraz Tekst, który będzie się wyświetlał w e-Sklepie. Zmiany należy zatwierdzić przyciskiem Dodaj.

Edycja kodu HTML

Następnie w panelu administracyjnym w sekcji: Wygląd sklepu/ Ustawienia/ Więcej (trzy kropki) / Edytuj ustawienia zaawansowane, a następnie Więcej/ Edytuj HTML należy przejść do katalogu elements/ recommended gdzie znajdują się pliki HTML z sekcjami Towary polecane. Tytuł sekcji znajduje się w linijce: <span class="recommended-products-title">{{ translations.Recommended }}</span> gdzie fragment Recommended jest Id tłumaczenia wprowadzanego w panelu administracyjnym. Aby zmienić nagłówek sekcji Towary polecane należy w miejsce Recommended wprowadzić Id wcześniej dodanego tłumaczenia. Po wprowadzonych zmianach w szablonie należy zapisać i opublikować zmiany.
Przyklad
Jeżeli w panelu administracyjnym dodałeś tłumaczenie o Id: PolecanaSekcja wówczas fragment kodu HTML powinien wyglądać następująco: <span class="recommended-products-title">{{ translations.PolecanaSekcja }}</span>
 
Wskazówka
Nadmierna ilość sekcji polecanych i wyświetlanych w niej towarów może obciążyć wyświetlanie strony w wyniku czego strona może się gorzej ładować i indeksować.

Zmiana nagłówka w pozostałych szablonach

W pozostałych standardowych szablonach Comarch zmiana nagłówka sekcji polecanych towarów odbywa się podobnie natomiast należy dokonać edycji następujących plików HTML:
  • szablon Agat – home-page.html
  • szablon Bursztyn – homepage.html
  • szablon Szafir – home.html

Szablon i treści wiadomości e-mail

Wstęp

Zmiana szablonu i treści wiadomości e-mail to jedna z tych rzeczy, która może wyróżnić nas na tle konkurencji. Mail, który przyciąga uwagę potrafi sprawić, że w przyszłości Klient szybciej skojarzy naszą firmę. Dodatkowo zmiana kolorystyki wyrazów w mailu może pomóc odbiorcy zwrócić uwagę na istotne informacje. W tym artykule dowiesz się, jak zarządzać powiadomieniami e-mail w Comarch e-Sklep, a także w jaki sposób możesz zarządzać szablonem domyślnym.
Uwaga
Dodatkowe modyfikacje stopki w szablonie wiadomości e-mail nie są wskazane dla osób, które nie posiadają wiedzy na temat kodowania w HTML.
Wskazówka
Po przeczytaniu całej instrukcji warto skorzystać z naszych przykładów, które utrwalą Twoją wiedzę i ułatwią kolejne modyfikacje szablonu wiadomości e-mail.

Gdzie zarządzać treściami powiadomień e-mail w Comarch e-Sklep?

Dostęp do treści związanych z komunikacją pomiędzy kontrahentem, a Comarch e-Sklep znajduje się w panelu administracyjnym w sekcji Ustawienia/Treści formalne. W tym obszarze znajdują się następujące treści:
  • Zgody,
  • Wysyłka e-mail i SMS,
  • Wydruki,
  • Komunikaty,
  • Regulamin i inne.
Wszystkie treści wiadomości możemy edytować wchodząc w jej szczegóły. W środku możemy określić ich widoczność oraz zmienić lub modyfikować takie dane jak:
  • Zmiana nadawcy wiadomości,
  • Dodać lub usunąć odbiorcę,
  • Ustawić, żeby potwierdzenie wiadomości zostało wysłane również do opiekuna,
  • Temat,
  • Język,
  • Treść.
Pierwsze dwa pola związane są z odbiorcą i nadawcą, zmieniamy je klikając w zaznaczony obszar:   Po zakończeniu zmian klikamy w przycisk zapisz. Warto dla sprawdzenia poprawności treści wysłać wiadomość próbną. Opcja dostępna jest na szczegółach każdego powiadomienia - w prawym górnym rogu. Dla wszystkich treści wysyłanych testowo z obszaru Ustawienia/ Treści formalne/ Wysyłka e-mail i SMS obejmuje walidacja wprowadzonych danych.
Wskazówka
Zachęcamy do przeczytania naszego artykułu odnośnie Dezaktywacji wybranych powiadomień e-mail

Gdzie edytować szablon wiadomości e-mail?

Szablon wiadomości e-mail znajduje się w panelu administracyjnym Comarch e-Sklep. Aby zmienić domyślny szablon wiadomości postępuj zgodnie z poniższymi krokami. Krok 1. W panelu przejdź do sekcji Ustawienia/ Treści formalne/Wysyłka e-mail i SMS. Krok 2. Z listy dostępnych treści wybierz okienko Szablon i przejdź do jego szczegółów. Krok 3. W nowym oknie rozpocznij edycję szablonu wiadomości e-mail. Każda linijka kodu, która jest z komentarzem odpowiada za wygląd naszego maila.
Przyklad
Wskazówka
Komentarze pomocnicze wyróżnione są kolorem brązowym i zawierają się w ramkach /**/. Nie usuwaj ich, ponieważ służą tylko do opisywania linijki kodu i mogą być przydatne podczas kolejnych modyfikacji.
Uwaga
Zmień tylko miejsca, które są opisane w instrukcji. Usunięcie nawet jednego symbolu może spowodować zniekształcenie całego szablonu. Jeżeli jednak usunąłeś za dużo elementów możesz przywrócić ustawienia domyślne. Pomocny artykuł: Jak przywrócić standardową treść wiadomości e-mail?

Edycja kolorów w szablonie wiadomości

Przed zabraniem się za zmianę kolorów warto sprawdzić szatę graficzną naszego e-Sklepu. Informację odnośnie kodów kolorów użytych w naszym szablonie możemy znaleźć w dwóch miejscach:
  • W panelu administracyjnym w zakładce Wygląd sklepu/ Ustawienia/ Ustawienia szablonu widzimy jaki kolor jest przyporządkowany do konkretnego miejsca w naszym szablonie. Kod używanego koloru znajduje się po prawej stronie. Można go skopiować oraz dowolnie modyfikować.
  • W konsoli przeglądarki (wciskając F12) możliwa jest weryfikacja poszczególnych kolorów użytych w wybranych elementach szablonu. Wybierając ikonę umożliwiamy sobie weryfikację obiektu oraz jego szczegółów po najechaniu na niego kursorem.
Po przygotowaniu kolorów możemy się zabrać za ich edycję w naszym szablonie wiadomości e-mail. W kodzie HTML szablonu szukamy w komentarzach miejsca, które chcemy podmienić. Po znalezieniu odpowiedniej linijki zmieniamy symbol koloru, który jest po symbolu „#” (UWAGA! Nie usuwamy tego symbolu). Po wprowadzeniu modyfikacji zapisz zmiany.
Wskazówka
W dowolnym momencie dokonywania zmian po ich wcześniejszym zapisaniu możesz je zobaczyć wysyłając wiadomość próbną. Wybieramy dowolną wiadomość z miejsca Ustawienia/ Treści formalne/Wysyłka e-mail i SMS a następnie klikamy w prawym górnym roku w Więcej i Wyślij próbnie. Pojawi nam się okno: Wpisujemy maila na, którego ma dojść wiadomość i klikamy w przycisk Wyślij próbnie. 

Motywy kolorystyczne dla szablonów wiadomości e-mail

Szablon wiadomości e-mail możesz w każdej chwili dowolnie modyfikować. Niżej prezentujemy przykładowe motywy kolorystyczne stworzone na bazie dostępnych motywów w Kreatorze Wyglądu Comarch oraz tabelę z odpowiednimi wartościami kolorów dla poszczególnych elementów w szablonie wiadomości.  
Szablon domyślny
Szablon domyślny
Topaz - motyw bordowy
Topaz - motyw bordowy
Topaz - motyw granatowy
Topaz - motyw granatowy
Topaz - motyw błękitny
Topaz - motyw błękitny
Topaz - motyw beżowy
Topaz - motyw beżowy
 
Motyw kolorystyczny szablonu Topaz: Domyślny Granatowy Bordowy Błękitny Beżowy
Nazwa:
a CB6724 151B72 BE2745 FF9181 BCAA9C
bgcolor1 ffffff ffffff ffffff ffffff ffffff
bgcolor2 F0A88D 9597AD CD6B7F BAD4F0 E6CAA6
shopName CB6724 151B72 BE2745 FF9181 BCAA9C
footerTitle 191616 000000 000000 17191A 3B3B3B
footerText 191616 000000 000000 17191A 3B3B3B
title1 4eb6f1 4eb6f1 4eb6f1 4eb6f1 4eb6f1
title2 ff7670 ff7670 ff7670 ff7670 ff7670
title3 53ccbd 53ccbd 53ccbd 53ccbd 53ccbd
text 191616 000000 000000 17191A 3B3B3B
orderColumnName a8a9a9 9597ad a8a9a9 9597ad 909090
orderDetails 3b3a3a 000000 000000 17191A 3B3B3B
orderPaymentName a8a9a9 9597ad a8a9a9 9597ad 909090
orderPaymentValue 191616 3B3B3B 000000 17191A 3B3B3B
orderPaymentTotal CB6724 151B72 BE2745 FF9181 BCAA9C
tableName CB6724 151B72 BE2745 FF9181 BCAA9C
rowName 191616 000000 000000 17191A 3B3B3B
rowContent a8a9a9 9597ad a8a9a9 9597ad 909090
feedbackButton (background-color) CB6724 C85555 CD6B7F FF9181 3B3B3B
feedbackButton (color) ffffff ffffff ffffff ffffff ffffff
feedbackButton (border) CB6724 C85555 CD6B7F FF9181 3B3B3B
feedbackButton-2 (background-color) 191616 151B72 000000 17191A  BCAA9C
feedbackButton-2 (color) ffffff ffffff ffffff ffffff ffffff
feedbackButton-2 (border) 191616 151B72 000000 17191A  BCAA9C
finishPaymentButton (background-color) CB6724 C85555 CD6B7F FF9181 3B3B3B
finishPaymentButton (color) ffffff ffffff ffffff ffffff ffffff
finishPaymentButton (border) CB6724 C85555 CD6B7F FF9181 3B3B3B
 

Jak zmienić kształt przycisków w powiadomieniach e-mail?

Obecnie w szablonie wiadomości możemy mieć dwa rodzaje przycisków:
  • Kwadratowe,
  • Zaokrąglone.
Zmiany ich wyglądu dokonujemy w zakładce Ustawienia/ Treści/ E-mail i SMS. W kodzie HTML szukamy przycisku który chcemy podmienić.
Wskazówka
W komentarzach zawarte są szczegółowe informację odnośnie każdej linijki kodu. Dzięki temu możemy łatwo znaleźć odpowiedni przycisk i  tym samy wiemy, która linijka służy np. do zmiany koloru przycisku lub koloru tekstu. Każdy przycisk jest opisany w następujący sposób: W miejscu zaznaczonym na czerwono wpisujemy odpowiednią wartość, która wpływa na kształt przycisków w wiadomości:
  • 0, gdy chcemy, aby przyciski były prostokątne,
  • 50px, gdy chcemy, aby przyciski były zaokrąglone.
Warto, żebyśmy wybrali formę i kolorystykę zbliżoną do wyglądu naszego e-Sklepu.

Jak dodać logo w szablonie wiadomości e-mail?

W wiadomościach, które wysyłamy do naszego klienta za pośrednictwem panelu administracyjnego zamieszczone jest logo naszego e-Sklepu. Domyślnie logo pobierane jest z konfiguracji, czyli z sekcji Ustawienia/ Ustawienia sklepu/ Dane sprzedawcy/ Logotyp. Więcej informacji odnośnie logotypu znajdziesz w artykule: Logotyp oraz favicon w Comarch e-Sklep (Logotyp oraz favicon w Comarch e-Sklep – Centrum Pomocy Comarch e-Sklep). Jeżeli chcesz zamieścić w szablonie wiadomości e-mail inne logo, niż domyślnie ustawione w konfiguracji konieczna jest jego modyfikacja. Jak jej dokonać? Postępuj zgodnie z poniższymi krokami. Krok 1. Wgraj plik z docelowym logiem na swój serwer. Krok 2. W panelu administracyjnym przejdź do sekcji Ustawienia/ Treści/ E-mail i SMS i rozpocznij edycję szablonu. Krok 3. Odszukaj w szablonie frazy src="{{config.Url}}logo.png". Krok 4. W każdej odnalezionej frazie (będzie ich 4) wstaw ścieżkę z serwera, na którym został udostępniony plik z logiem. Krok 5. Zapisz wprowadzone zmiany.

Jak edytować stopkę wiadomości e-mail?

Wszystkie dane kontaktowe, które są w stopce wiadomości e-mail pobierane są ustawień w panelu administracyjnym. Wszystkie frazy, które są zaznaczone na czerwono można w łatwy sposób zmienić w naszej stopce. Krok 1. W panelu administracyjnym przejdź do sekcji Ustawienia/ Treści formalne/Wysyłka e-mail i SMS i edycję szablonu. Krok 2. Odszukaj w szablonie frazy i je podmień. Krok 3. Zapisz wprowadzone zmiany.
Wskazówka
Informacje odnośnie dodawania ikon social mediów w szablonie znajdziesz w artykule: Ustawienia Wyglądu Sklepu w zakładce Nagłówek / Stopka

Obsługa wtyczki Czatu Facebooka w szablonach

Wskazówka
Od 1 czerwca 2025 roku zakończyliśmy aktualizację oraz wydawanie nowych wersji szablonów Bursztyn, Agat i Opal, a tym samym ich wsparcie, aby skupić się na nowoczesnych rozwiązaniach, które jeszcze lepiej odpowiadają na potrzeby dynamicznie rozwijającego się rynku e-commerce. Zachęcamy Was do przejścia na nasze nowe, udoskonalone szablony. Dla sklepów B2C polecamy szablony Topaz, One Page Shop oraz Dla Gastronomii, natomiast dla platform B2B idealnym wyborem będą Rubin i Szafir.
Uwaga
Z dniem 9 maja 2024 roku wtyczka została oficjalnie wycofana. Więcej informacji można znaleźć w Centrum Pomocy Meta.
W niniejszym artykule dowiesz się w jaki sposób Twój szablon może obsługiwać wtyczkę Czatu Facebooka. Na początku omówiona zostanie ogólna instrukcja ustawienia wtyczki oraz opisane zostaną ustawienia w konfiguracji Facebooka, na które warto zwrócić uwagę. W dalszych punktach zostaną omówione wymagane zmiany w kodzie poszczególnych szablonów.
Uwaga
Instrukcja dotyczy dodania wtyczki dla standardowych szablonów Comarch od wersji 2021.2.

Instrukcja ogólna

1. W przeglądarce internetowej otwieramy stronę https://business.facebook.com. Logujemy się swoimi danymi. 2. Wybieramy opcję Skrzynka odbiorcza. Z menu po prawej stronie  wybieramy opcję Ustawienia. 3. Z listy po lewej wybieramy opcję Wtyczka czatu. Po załadowaniu się ustawień, znajduje się opcja Skonfiguruj wtyczkę czatu Klikamy przycisk Skonfiguruj. 4. Pokaże się małe okienko do konfiguracji. 5. Na początku mamy do wyboru metodę konfiguracji. Wybieramy opcję Standardowa. 6. W kroku pierwszym ustawiamy język, w jakim nasza wtyczka będzie pracować. 7. Krok drugi to dodanie naszej domeny. Zwróć uwagę na to, czy podana przez Ciebie domena posiada protokół http czy https. Podany w niniejszej konfiguracji musi się zgadzać z faktycznymi ustawieniami. Jeśli korzystasz z szablonu Topaz, One Page Shop lub Szafir, możesz pominąć kroki 8 oraz 9. W wygenerowanym przez Meta kodzie do wklejenia, znajdź tylko page_id i znajdujący się tam numer (identyfikator) skopiuj - będzie potrzebny w ustawieniach szablonu. 8. (Dla szablonu Bursztyn, Opal, Agat) Krok trzeci to kod potrzebny do dodania wtyczki do szablonu. Należy go skopiować przy użyciu przycisku Skopiuj kod. 9. (Dla szablonu Bursztyn, Opal, Agat) Wklej skopiowany przed chwilą kod w odpowiednie miejsce w Twoim szablonie. Instrukcja gdzie należy wkleić ten kod, znajduje się poniżej, dla każdego ze standardowych szablonów z osobna.

Opcjonalnie:

10. Przejdź do sekcji Dostosuj wtyczkę Wtyczka czatu gdzie można ustawić m.in. wyrównanie wtyczki do lewej lub prawej strony, jej motyw kolorystyczny a także odległość od dołu strony dla komputerów i urządzeń mobilnych. W tej sekcji możesz także dodatkowo ustawić automatyczne rozwijanie okna czatu oraz włączyć lub wyłączyć czat dla osób niezalogowanych do Facebooka bądź Messengera. 11. Przejdź do sekcji Rozpocznij konwersację gdzie można ustawić wiadomość powitalną a także włączyć/wyłączyć funkcję najczęściej zadawanych pytań. Pytania wraz z odpowiedziami na nie konfigurujemy w tej sekcji dowolnie.

Zwróć uwagę na te ustawienia:

Po procesie konfiguracji mogą wystąpić pewne problemy lub błędy. Część z nich może być spowodowana nieprawidłowymi ustawieniami Twojej strony na Facebooku. Na głównej stronie na rozwijanym menu po lewej stronie kliknij Wszystkie narzędzia, potem Ustawienia strony a następnie wybierz sekcję Ogólne. Ustawienia, które mogą powodować problemy to m.in. Widoczność strony, gdy mamy ustawioną opcję "Cofnięto publikację strony". Kolejnymi ustawieniami do sprawdzenia są Ograniczenia dotyczące kraju oraz Ograniczenia wiekowe. Ewentualne narzucenie ograniczeń może powodować błędy wyświetlane w konsoli w narzędziach developerskich, gdy otworzysz swój sklep. Sprawdź też sekcję Wszystkie narzędzia -> Ustawienia strony -> Zaawansowane ustawienia wiadomości, a tam ustawienie Domeny dodane do białej listy. Upewnij się, że Twój sklep znajduje się na tej liście. Z perspektywy Klienta, w przypadku ewentualnych błędów związanych z wyświetlaniem lub działaniem wtyczki, pomocne może okazać się wyczyszczenie pamięci podręcznej (cache).

Obsługa w szablonie Topaz, One Page Shop i Szafir

1. W przygotowanym przez Meta kodzie do wklejenia, odszukaj page_id i skopiuj podany tam numer (identyfikator). 2. Skopiowany identyfikator wklej w Panelu Administracyjnym Comarch e-Sklep, przechodząc do zakładki: Topaz/One Page Shop: Wygląd Sklepu/ Ustawienia/ Dodatkowe/ Wyświetlaj Facebook czat, Szafir: Wygląd sklepu/ Ustawienia/ Ogólne/ Wyświetlaj Facebook czat i zaznaczając parametr na Tak:

Obsługa w szablonie Bursztyn

W szablonie Bursztyn, skopiowany kod należy wkleić do pliku _layout.html znajdującego się w głównym katalogu z Twoim szablonem. Kod wklejamy pod koniec tego pliku. Poniżej niego mają zostać tylko linijki zawierające zamknięcie tagu html oraz zamknięcie tagu body. Istnieje możliwość zmiany położenia wtyczki. Przy pomocy konfiguratora wtyczki czatu możemy ustalić, czy ma być ona wyrównana do lewej czy do prawej strony, zmienić motyw kolorystyczny dopasowując go do wyglądu sklepu, a także ustalić w jakiej odległości od dołu ekranu ma pojawiać się wtyczka (dla wyrównania do prawej, sugerowana odległość na komputery w szablonie Bursztyn to 120px). Można także własnoręcznie edytować style naszej wtyczki. W plikach .scss wystarczy dodać odpowiednio klasę .fb_customer_chat_bounce_in_v2 - okno czatu oraz .fb_customer_chat_icon - ikona wtyczki a następnie przy użyciu gulp'a przekonwertować pliki .scss na .css. Zmiany możemy dokonać na końcu pliku main.scss.

Obsługa w szablonie Opal

W szablonie Opal, skopiowany kod należy wkleić do pliku _layout.html znajdującego się w głównym katalogu z Twoim szablonem. Kod wklejamy pod koniec tego pliku. Poniżej niego mają zostać tylko linijki zawierające zamknięcie tagu html oraz zamknięcie tagu body. Istnieje możliwość zmiany położenia wtyczki. Przy pomocy konfiguratora wtyczki czatu możemy ustalić, czy ma być ona wyrównana do lewej czy do prawej strony, zmienić motyw kolorystyczny dopasowując go do wyglądu sklepu, a także ustalić w jakiej odległości od dołu ekranu ma pojawiać się wtyczka (dla wyrównania do prawej, sugerowana odległość na komputery w szablonie Opal to 110px). Można także własnoręcznie edytować style naszej wtyczki. W plikach .scss wystarczy dodać odpowiednio klasę .fb_customer_chat_bounce_in_v2 - okno czatu oraz .fb_customer_chat_icon - ikona wtyczki a następnie przy użyciu gulp'a przekonwertować pliki .scss na .css. Zmiany możemy dokonać na końcu pliku main.scss.

Obsługa w szablonie Agat

W szablonie Agat, skopiowany kod należy wkleić do pliku _layout.html znajdującego się w głównym katalogu z Twoim szablonem. Kod wklejamy pod koniec tego pliku. Poniżej niego mają zostać tylko linijki zawierające zamknięcie tagu html oraz zamknięcie tagu body. Istnieje możliwość zmiany położenia wtyczki. Przy pomocy konfiguratora wtyczki czatu możemy ustalić, czy ma być ona wyrównana do lewej czy do prawej strony, zmienić motyw kolorystyczny dopasowując go do wyglądu sklepu, a także ustalić w jakiej odległości od dołu ekranu ma pojawiać się wtyczka (dla wyrównania do prawej, sugerowana odległość na komputery w szablonie Agat to 120px). Można także własnoręcznie edytować style naszej wtyczki. W plikach .scss wystarczy dodać odpowiednio klasę .fb_customer_chat_bounce_in_v2 - okno czatu oraz .fb_customer_chat_icon - ikona wtyczki a następnie przy użyciu gulp'a przekonwertować pliki .scss na .css. Zmiany możemy dokonać na końcu pliku main.scss.

Przykładowy kod do modyfikacji wyglądu wtyczki - wersja na komputery

Poniżej znajduje się przykładowy kod służący modyfikacji położenia i wysokości zarówno okna czatu, jak i ikonki czatu. Zakładamy, że w ustawieniach wtyczki opisanych wcześniej, mamy wyrównanie do prawej i 120px odległości od dołu w wersji na komputery. Kod w wersji .scss (Po jego wklejeniu do odpowiedniego pliku w danym szablonie, należy przekonwertować pliki .scss na pliki .css i dokonać ich minifikacji. Jak tego dokonać dowiesz się z tego artykułu. @media screen and (min-width: 769px) { .fb_customer_chat_bounce_in_v2 { bottom:185px !important; right:3% !important; height:600px !important } .fb_customer_chat_icon { bottom:125px !important; right:2.3% !important } }
Wskazówka
Przedstawiony kod jest tylko przykładem, jak możemy edytować wygląd naszej wtyczki. Należy pamiętać także o utworzeniu styli dla wersji mobilnej przy użyciu @media.
Wskazówka
W przykładzie została użyta instrukcja !important Jest to o tyle istotne, że bez jej użycia możemy nie nadpisać domyślnego wyglądu wtyczki przygotowanego przez Facebooka.

Trusted Shops – jak dodać logo do sklepu?

Wskazówka
Od 1 czerwca 2025 roku zakończyliśmy aktualizację oraz wydawanie nowych wersji szablonów Bursztyn, Agat i Opal, a tym samym ich wsparcie, aby skupić się na nowoczesnych rozwiązaniach, które jeszcze lepiej odpowiadają na potrzeby dynamicznie rozwijającego się rynku e-commerce. Zachęcamy Was do przejścia na nasze nowe, udoskonalone szablony. Dla sklepów B2C polecamy szablony Topaz, One Page Shop oraz Dla Gastronomii, natomiast dla platform B2B idealnym wyborem będą Rubin i Szafir.
Spis treści

Wstęp

Trusted Shops to znak jakości z ochroną kupującego, przyznawany sklepom internetowym. Aby rozpocząć jego integrację  z Comarch e-Sklep, najpierw musimy zarejestrować się na stronie TrustedShops. Po przejściu procesu rejestracji i otrzymaniu certyfikatu otrzymamy jego identyfikator, który jest potrzebny do połączenia go z naszym e-Sklepem.

Wprowadzenie identyfikatora Trusted Shops

W panelu administracyjnym należy wprowadzić identyfikator od Trusted Shops. Aby to zrobić, proszę przejść w Ustawienia/ Ustawiania sklepu/ Trusted Shops wpisać identyfikator i kliknąć przycisk Przyłącz. Następnie proszę podążać za poniższymi wskazówkami dotyczącymi właściwego szablonu.

Dodawanie loga Trusted Shops do e-Sklepu

Kolejnym krokiem w integracji platformy Trusted Shops jest dodanie loga platformy. Dokonuje się tego poprzez edycję kodu HTML szablonu naszego sklepu i wgranie odpowiednich poprawek wymaganych przez platformę. Kod ten posiada kilka parametrów konfiguracyjnych, które zostaną opisane w rozdziale poniżej. Natomiast dalsza część instrukcji zostanie poświęcona implementacji loga zależnie od używanego szablonu w Comarch e-Sklep.

Parametry konfiguracyjne

  • Fragment kodu ’yOffset’: ’60’, /* offset from page bottom */ określa wysokość, na jakiej ma się znajdować logo Trusted Shops. Często domyślnie jest to wartość 60. Zmiana tej wartości pozwala na dopasowanie elementu do wyglądu posiadanego szablonu.
  • Parametr ’variant’ odpowiada za wariant wyświetlania Trustbadge. Pozwala określić, które logo Trusted Shops będzie widoczne w naszym sklepie. Domyślnie wybrany wariant to 'reviews’, natomiast pozostałe warianty to 'default’, 'custom_reviews’ oraz 'custom’. Aby je zmienić, wystarczy wpisać nazwę wybranego wariantu w linijce kodu  ’variant’:’reviews’,  zastępując domyślnie wybrany wariant reviews.
Uwaga
Jeśli chcesz użyć wariantu „custom” lub „custom_reviews”, konieczne będą dodatkowe modyfikacje kodu Trustbadge i używanego szablonu. Więcej na ten temat przeczytasz na stronie TrustedShops
Wybrane warianty prezentują się następująco:

Agat

Etap I - skrypt główny

Krok 1. W panelu administracyjnym przejdź do sekcji Wygląd sklepu/ Ustawienia/  Więcej  / Edytuj ustawienia zaawansowane ponownie Więcej  / Edytuj HTML Krok 2. Przejdź do edycji pliku _layout.html, a następnie za pomocą narzędzia wyszukiwania odnajdź frazę </head>. Krok 3. Powyżej znalezionego fragmentu wklej poniższy skrypt, w którym wartość XXXXXXXXXXXXX należy zastąpić identyfikatorem od Trusted Shops:        

Etap II - wstawienie dodatkowego skryptu w szablonie

Krok 1. Pozostając w powyższym obszarze z plikami szablonu należy przejść do edycji partials/ cart/ lastpagesscripts.html i podmienić kod pliku na poniższy skrypt: <div id="trustedShopsCheckout" style="display: none;"> <span id="tsCheckoutOrderNr">{{cart.PlacedOrder.Id}}</span> <span id="tsCheckoutBuyerEmail">{{cart.Customer.Email}}</span> <span id="tsCheckoutBuyerId">-</span> <span id="tsCheckoutOrderAmount">{{cart.OrderTotalValue}}</span> <span id="tsCheckoutOrderCurrency">{{currency}}</span> <span id="tsCheckoutOrderPaymentType">OTHER</span> </div> <script> (function(){try{trustbadge.reInitialize();}catch(err){}})(); </script> Krok 2. Następnie należy zapisać i opublikować szablon (  Zapisz i opublikuj )

Opal i Bursztyn

Etap I - skrypt główny

Krok 1. W panelu administracyjnym przejdź do sekcji Wygląd sklepu/ Ustawienia/  Więcej  / Edytuj ustawienia zaawansowane ponownie Więcej  / Edytuj HTML Krok 2. Przejdź do edycji pliku _layout.html, a następnie za pomocą narzędzia wyszukiwania odnajdź frazę </head>. Krok 3. Powyżej znalezionego fragmentu wklej poniższy skrypt, w którym wartość XXXXXXXXXXXXX należy zastąpić identyfikatorem od Trusted Shops:        

Etap II - wstawienie dodatkowego skryptu w szablonie

Krok 1. Pozostając w powyższym obszarze z plikami szablonu należy przejść do edycji partials/ cart/ lastpagesscripts.html i podmienić kod pliku na poniższy skrypt: <div id="trustedShopsCheckout" style="display: none;"> <span id="tsCheckoutOrderNr">{{cart.PlacedOrder.Id}}</span> <span id="tsCheckoutBuyerEmail">{{cart.Customer.Email}}</span> <span id="tsCheckoutBuyerId">-</span> <span id="tsCheckoutOrderAmount">{{cart.OrderTotalValue}}</span> <span id="tsCheckoutOrderCurrency">{{currency}}</span> <span id="tsCheckoutOrderPaymentType">OTHER</span> </div> <script> (function(){try{trustbadge.reInitialize();}catch(err){}})(); </script> Krok 2. Następnie należy zapisać i opublikować szablon (  Zapisz i opublikuj )
Wskazówka
Instrukcja dotycząca dodawania logo Trusted Shops w szablonach Topaz, Szafir, One Page Shop znajduje się w artykule Trusted Shops.

Implementacja Google Analytics 4 w szablonach

Comarch e-Sklep jest zintegrowany z Google Analytics 4 dzięki prostej konfiguracji polegającej na dodaniu skryptu śledzącego w panelu administracyjnym. Dzięki zaimplementowanej w e-Sklepie warstwie danych (Data Layer) oraz obsłużonych domyślnie w darmowych szablonach Comarch skryptom uzyskasz dostęp do wielu funkcji Google Analytics takich jak: podstawowe śledzenie ruchu na Twoim sklepie oraz śledzenie transakcji e-commerce. Posiadając zmodyfikowany szablon również możesz korzystać z Google Analytics 4. Poniżej podpowiadamy jakie pliki HTML należy zmodyfikować, aby statystyki naliczały się w prawidłowy sposób. Zmodyfikuj następujące pliki. Szafir: base_layout.html partials/customer-profile/discounts/discount-elements.html partials/order/cart.html partials/order/thx.html partials/order/products-partials/set-aggregator.html partials/product/cart-product.html partials/product/product-presentation-forms.html js/init.min.js js/init-ui1.min.js js/init-ui2.min.js js/js.min.js Topaz: base_layout.html elements/cart/cart-1.html (lub cart-2.html) elements/product/product-details-1.html (lub 2,3,4) partials/cart/cart-item.html (lub partials/cart/new-cart/cart-item.html) partials/common/notify-about-availability-popup.html partials/customer/discounts/discount-elements.html js/layout0.min.js js/layout1.min.js js/layout2.min.js
Wskazówka
W celu wyodrębnienia zmian z owych plików, należy porównać dany plik z naszego szablonu z jego odpowiednikiem z najnowszej wersji szablonu

Jak wykonać kopię bezpieczeństwa mojego szablonu?

Jak wykonać kopię bezpieczeństwa mojego szablonu?

Oprawa wizualna sklepu jest bardzo ważnym elementem podczas prowadzenia sprzedaży w sieci. Narzędzie Kreator Wyglądu Comarch e-Sklep umożliwia stworzenie własnych, niepowtarzalnych szablonów wedle preferencji i potrzeb użytkowników. W intuicyjnym narzędziu jakim jest Kreator, będziesz w stanie zaprojektować wszelkie niezbędne funkcje, takie jak stronę główną, listę towarów, szczegóły towaru oraz koszyk. Jeśli Twój projekt szablonu został zaimportowany do e-Sklepu oraz skonfigurowany wedle Twoich preferencji (dodanie grafik do bannerów, modyfikacje kolorystyczne) masz możliwość jego zapisania, co będzie stanowić kopię bezpieczeństwa. Kopia bezpieczeństwa to dane, które w każdej chwili można odtworzyć w przypadku ich utracenia (np. poprzez przypadkowe usunięcie) lub częstego wprowadzania zmian. Dane, jakie może zawierać kopia bezpieczeństwa to szablon, który wcześniej został przez nas wygenerowany wraz z bannerami. Zaleca się wykonywanie kopii zapasowych oraz zabezpieczenie ich hasłem. Każda wykonana kopia zapasowa powinna zostać zapisana w bezpiecznym i dogodnym dla Użytkownika miejscu.

Jak wykonać kopię bezpieczeństwa?

W Panelu Administracyjnym przejdź do sekcji Wygląd sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane, a następnie przejdź do zakładki Eksport szablonu. W pustych polach znajdujących się w zakładce Eksport szablonu, opcjonalnie przed eksportem możesz uzupełnić powyższe dane, tj. Autora szablonu, e-mail, telefon i stronę WWW sklepu. Aby wyeksportować szablon, kliknij Eksportuj szablon. Wyeksportowany plik jest w formacie XML, a jego nazwa zawiera szablon oraz wersję, co znacznie ułatwia zarządzanie kopiami bezpieczeństwa w przypadku wykonywania ich regularnie.

Jak wyeksportować bannery?

Bannery, które znajdują się w Twoim sklepie możesz również wyeksportować tworząc kopię bezpieczeństwa. W tym celu także musisz przejść do Wygląd sklepu/ Ustawienia/ Edytuj ustawienia zaawansowane, a następnie do zakładki Eksport szablonu. Obok przycisku Eksportuj szablon, znajduje się przycisk Eksportuj bannery, który musisz kliknąć aby bannery, które posiadasz w e-Sklepie zostały weksportowane. Kopia bezpieczeństwa jest również zapisywana w formacie XML, a nazwa pliku wskazuje na szablon, wersję i zawartość bannerów.

Jak zabezpieczyć hasłem swój szablon?

Jeśli chcesz, aby Twój szablon został zabezpieczony hasłem, a znajomość hasła była niezbędna podczas zaimportowania tego szablonu do e-Sklepu, musisz w tym celu przejść w Panelu Administracyjnym do sekcji Wygląd sklepu/ Ustawienia/ Ustawienia zaawansowane, następnie do zakładki Szablon. W tym miejscu nadasz hasło dla swojego szablonu. Zgodnie z Polityką bezpieczeństwa haseł, hasło powinno:
  • Składać się z minimum 8 znaków,
  • Zawierać dużą literę,
  • Zawierać małą literę,
  • Zawierać cyfrę 0-9,
  • Zawierać znak specjalny – ‘!.+?;^]=-(&_)#=
Gotowe! Teraz Twój szablon został zabezpieczony hasłem. Jeśli wyeksportujesz szablon, który zabezpieczyłeś hasłem – podczas importu tego szablonu, będziesz musiał podać nadane wcześniej hasło. Jego brak uniemożliwi import szablonu, a podanie błędnego hasła spowoduje nieprawidłowe działanie szablonu po imporcie. Więcej informacji znajdziesz:

Przekreślenie na atrybutach towaru zgrupowanego - szablon Topaz

Wstęp

W szablonie Topaz, przy włączonej kontroli stanów magazynowych, w przypadku braku produktu towaru zgrupowanego wyświetlany jest przycisk "Powiadom mnie o dostępności". Z tego artykułu dowiesz się jak zmodyfikować swój szablon, aby dodatkowo wyświetlać przekreślenie na niedostępnych atrybutach.
Wskazówka
W tym artykule dowiesz się jak wprowadzać zmiany w plikach js i css. Z tego artykułu dowiesz się jak je minifikować.

Zmiany w plikach szablonu

Przedstawione w artykule modyfikacje są kompatybilne ze wszystkimi czterema widokami szczegółów towaru w szablonie Topaz. Kod odpowiedzialny za przekreślenie na atrybutach, będzie prawie identyczny dla każdego z widoków. Minimalne różnice zostały odpowiednio opisane. Edycję szablonu rozpocznij od pliku js/layout2.js. Struktura części kodu, którą należy zmienić może się różnić, w zależności czy masz zaimplementowaną graficzną prezentację atrybutów. Dlatego przedstawione zostaną dwa przypadki edycji omawianego pliku. W przypadku braku implementacji graficznej prezentacji atrybutów, odnajdź fragment: function SetSuplFirst(drop, s, lvl, valId) { var form = drop.parent().parent().parent(); var fDrop = form.find('.attributes-select'); drop.empty(); for (var el in s) { drop.append($('' + s[el].Value + '').data('el', JSON.stringify(s[el]))); } Kod znajdujący się w pętli for zamień na: var isUnavailable = false; var unavailableClassName = ""; if (s[el].Product) { if (s[el].Product.StockLevel && s[el].Product.StockLevel.Value === 0) { isUnavailable = true; } if (s[el].StockLevel && s[el].StockLevel.Value === 0) { isUnavailable = true; } } else { var checkStockLevelLoopObj = s[el]; var checkSuppliesStockLevelLoopObj = s[el]; while (typeof checkStockLevelLoopObj.Product === 'undefined') { checkSuppliesStockLevelLoopObj = checkStockLevelLoopObj.Supplies; checkStockLevelLoopObj = checkStockLevelLoopObj.Supplies[0]; } if (checkSuppliesStockLevelLoopObj.length > 1) { for (var supply in checkSuppliesStockLevelLoopObj) { if (checkSuppliesStockLevelLoopObj[supply].Product && checkSuppliesStockLevelLoopObj[supply].Product.StockLevel && checkSuppliesStockLevelLoopObj[supply].Product.StockLevel !== 0) { break; } else { if (checkSuppliesStockLevelLoopObj[supply].Product && !checkSuppliesStockLevelLoopObj[supply].Product.StockLevel) { break; } else { isUnavailable = true; } } if (checkSuppliesStockLevelLoopObj[supply].StockLevel && checkSuppliesStockLevelLoopObj[supply].StockLevel.Value !== 0) { break; } else { if (!checkSuppliesStockLevelLoopObj[supply].StockLevel) { break; } else { isUnavailable = true; } } } } else { if (checkStockLevelLoopObj.Product && checkStockLevelLoopObj.Product.StockLevel && checkStockLevelLoopObj.Product.StockLevel === 0) { isUnavailable = true; } if (checkStockLevelLoopObj.StockLevel && checkStockLevelLoopObj.StockLevel.Value === 0) { isUnavailable = true; } } } if (isUnavailable) { unavailableClassName = " button-option-unavailable"; } drop.append($('' + s[el].Value + '').data('el', JSON.stringify(s[el]))); Następnie wyszukaj fragment: function SetSupl(drop, s) { var form = drop.closest('#AddToCartForm'); var fDrop = form.find('.attributes-select'); drop.empty(); for (var el in s) { drop.append($('' + s[el].Value + '').data('el', JSON.stringify(s[el]))); } I instrukcje w pętli for zastąp tym samym kodem co w przypadku przedstawionej wyżej modyfikacji funkcji SetSuplFirst. Dla przypadku zaimplementowanej graficznej prezentacji atrybutów, zlokalizuj fragment: function SetSuplFirst(drop, s, lvl, valId) { var form = drop.parent().parent().parent(); var fDrop = form.find('.attributes-select'); //pobieram wszystkie kontenery dla poziomów drop.empty(); var attributesColorsData = drop.data('variants-colors'); var pageLanguage = drop.data('page-language'); var attributesColors = []; if (attributesColorsData) { attributesColorsData = attributesColorsData.split('|||'); for (var i = 0; i < attributesColorsData.length; i++) { var attributesColor = attributesColorsData[i].split('||'); var attributeColorName = attributesColor[0].split('|'); switch (pageLanguage) { case 1: attributeColorName = attributeColorName[0]; break; case 2: attributeColorName = attributeColorName[1]; break; case 3: attributeColorName = attributeColorName[2]; break; case 5: attributeColorName = attributeColorName[3]; break; default: break; } attributesColors.push([attributeColorName,attributesColor[1]]); } } for (var el in s) { if (drop.data('variants-colors')) { if ((drop.data('colors-option') === 'Grouping_First' && drop.data('attribute-id') === drop.data('first-attribute-id')) || (drop.data('colors-option') === 'Grouping_Last' && drop.data('attribute-id') === drop.data('last-attribute-id')) || (drop.data('colors-option') === 'Grouping_All')) { Teraz w pętli for (var el in s), przed pierwszą instrukcją sterującą if wklej: var isUnavailable = false; var unavailableClassName = ""; if (s[el].Product) { if (s[el].Product.StockLevel && s[el].Product.StockLevel.Value === 0) { isUnavailable = true; } if (s[el].StockLevel && s[el].StockLevel.Value === 0) { isUnavailable = true; } } else { var checkStockLevelLoopObj = s[el]; var checkSuppliesStockLevelLoopObj = s[el]; while (typeof checkStockLevelLoopObj.Product === 'undefined') { checkSuppliesStockLevelLoopObj = checkStockLevelLoopObj.Supplies; checkStockLevelLoopObj = checkStockLevelLoopObj.Supplies[0]; } if (checkSuppliesStockLevelLoopObj.length > 1) { for (var supply in checkSuppliesStockLevelLoopObj) { if (checkSuppliesStockLevelLoopObj[supply].Product && checkSuppliesStockLevelLoopObj[supply].Product.StockLevel && checkSuppliesStockLevelLoopObj[supply].Product.StockLevel !== 0) { break; } else { if (checkSuppliesStockLevelLoopObj[supply].Product && !checkSuppliesStockLevelLoopObj[supply].Product.StockLevel) { break; } else { isUnavailable = true; } } if (checkSuppliesStockLevelLoopObj[supply].StockLevel && checkSuppliesStockLevelLoopObj[supply].StockLevel.Value !== 0) { break; } else { if (!checkSuppliesStockLevelLoopObj[supply].StockLevel) { break; } else { isUnavailable = true; } } } } else { if (checkStockLevelLoopObj.Product && checkStockLevelLoopObj.Product.StockLevel && checkStockLevelLoopObj.Product.StockLevel === 0) { isUnavailable = true; } if (checkStockLevelLoopObj.StockLevel && checkStockLevelLoopObj.StockLevel.Value === 0) { isUnavailable = true; } } } if (isUnavailable) { unavailableClassName = " button-option-unavailable"; } Następnie, w obrębie wspomnianej wyżej pętli for, wyszukaj wszystkie wystąpienia kodu zawierające fragment: drop.append($(' I dla wszystkich znalezionych przypadków, na końcu fragmentów takich jak przedstawiony powyżej, dodaj kod: ' + unavailableClassName + ' Na koniec zmian w pliku, odnajdź poniższe instrukcje: function SetSupl(drop, s) { var form = drop.closest('#AddToCartForm'); var fDrop = form.find('.attributes-select'); //pobieram wszystkie kontenery dla poziomów drop.empty(); var attributesColorsData = drop.data('variants-colors'); var pageLanguage = drop.data('page-language'); var attributesColors = []; if (attributesColorsData) { attributesColorsData = attributesColorsData.split('|||'); for (var i = 0; i < attributesColorsData.length; i++) { var attributesColor = attributesColorsData[i].split('||'); var attributeColorName = attributesColor[0].split('|'); switch (pageLanguage) { case 1: attributeColorName = attributeColorName[0]; break; case 2: attributeColorName = attributeColorName[1]; break; case 3: attributeColorName = attributeColorName[2]; break; case 5: attributeColorName = attributeColorName[3]; break; default: attributeColorName = attributeColorName[0]; break; } attributesColors.push([attributeColorName,attributesColor[1]]); } } for (var el in s) { if (drop.data('variants-colors')) { if ((drop.data('colors-option') === 'Grouping_First' && drop.data('attribute-id') === drop.data('first-attribute-id')) || (drop.data('colors-option') === 'Grouping_Last' && drop.data('attribute-id') === drop.data('last-attribute-id')) || (drop.data('colors-option') === 'Grouping_All')) { Teraz dokonaj analogicznych modyfikacji jak w obrębie funkcji SetSuplFirst. Pamiętaj, że tym razem, zmiany we wszystkich wystąpieniach kodu: drop.append($(' Musisz dokonać w obrębie funkcji SetSupl. Do dokończenia zmian w szablonie pozostało zmodyfikowanie pliku ze stylami. W zależności od wygenerowanego w kreatorze szablonu widoku szczegółów towaru, nazwa edytowanego pliku będzie się różnić. Zmiany stylistyki w szablonie są identyczne dla wszystkich widoków, lecz umieszczane w innych fragmentach plików. Najpierw przedstawiona zostanie modyfikacja przeznaczona dla pierwszego i drugiego widoku szczegółów towaru. Otwórz plik css/layout0.css i wyszukaj fragment: .product-details .input-group input[type='button'].active,.product-details .input-group .attributes-select .button-option.active,.product-details .set .button-option.active,.product-details .set .button-option-sets.active{border:2px solid {{settings.paginationActiveBorderColor}};background-color:transparent} Teraz tuż za ostatnim znakiem przedstawionego kodu wklej instrukcje: .product-details .button-option-unavailable{position:relative;color:{{settings.secondaryFontColor}};transition:300ms}.product-details .button-option-unavailable::before{content:"";position:absolute;top:0;left:0;height:100%;width:100%;transition:300ms;background-color:rgba(226,226,226,0.2)}.product-details .button-option-unavailable::after{content:"";display:block;position:absolute;top:0;left:0;height:100%;width:100%;transition:300ms;cursor:pointer}@keyframes change-gradient-to-inactive{from{background:linear-gradient(to right top, transparent, transparent 48%, {{settings.secondaryFontColor}} 50%, {{settings.secondaryFontColor}} 50%, transparent 52%, transparent)}to{background:linear-gradient(to right top, transparent, transparent 49%, {{settings.secondaryFontColor}} 50%, {{settings.secondaryFontColor}} 50%, transparent 51%, transparent)}}@keyframes change-gradient-to-active{from{background:linear-gradient(to right top, transparent, transparent 49%, {{settings.secondaryFontColor}} 50%, {{settings.secondaryFontColor}} 50%, transparent 51%, transparent)}to{background:linear-gradient(to right top, transparent, transparent 48%, {{settings.secondaryFontColor}} 50%, {{settings.secondaryFontColor}} 50%, transparent 52%, transparent)}}.product-details .button-option-unavailable:not(.active){border:1px solid {{settings.secondaryFontColor}} !important}.product-details .button-option-unavailable:not(.active)::after{background:linear-gradient(to right top, transparent, transparent 49%, {{settings.secondaryFontColor}} 50%, {{settings.secondaryFontColor}} 50%, transparent 51%, transparent);-webkit-animation:change-gradient-to-inactive 300ms;animation:change-gradient-to-inactive 300ms}.product-details .button-option-unavailable.active{border:2px solid {{settings.secondaryFontColor}} !important}.product-details .button-option-unavailable.active::after{background:linear-gradient(to right top, transparent, transparent 48%, {{settings.secondaryFontColor}} 50%, {{settings.secondaryFontColor}} 50%, transparent 52%, transparent);-webkit-animation:change-gradient-to-active 900ms;animation:change-gradient-to-active 900ms} Poniżej natomiast pokazane są zmiany przeznaczone dla trzeciego i czwartego widoku szczegółów towaru. Otwórz plik css/layout0.css i wyszukaj fragment: .productDetails-attributes .button-option:not(.dropdown):not(.units-container){display:flex;flex-direction:row;justify-content:flex-start;align-items:center;margin-bottom:10px;flex-wrap:wrap}.productDetails-attributes .button-option:not(.dropdown):not(.units-container).active{border:2px solid {{settings.linkFontColor}};display:inline-flex}.productDetails-attributes .button-option:not(.dropdown):not(.units-container) span{height:50px;padding-left:15px;padding-right:15px;font-size:14px;font-weight:normal;font-stretch:normal;font-style:normal;line-height:1.71;letter-spacing:1.2px;text-align:center;color:{{settings.primaryFontColor}};border:2px solid {{settings.primaryPageBgColor}};cursor:pointer;transition:300ms;margin-right:5px}.productDetails-attributes .button-option:not(.dropdown):not(.units-container) span:not(.active):hover{border-color:{{settings.secondaryFontColor}}} Następnie zaraz po ostatnim znaku powyższego fragmentu dodaj kod: .productDetails-attributes .button-option:not(.dropdown):not(.units-container) .button-option-unavailable{position:relative;color:{{settings.secondaryFontColor}};transition:300ms}.productDetails-attributes .button-option:not(.dropdown):not(.units-container) .button-option-unavailable::before{content:"";position:absolute;top:0;left:0;height:100%;width:100%;transition:300ms;background-color:rgba(226,226,226,0.2)}.productDetails-attributes .button-option:not(.dropdown):not(.units-container) .button-option-unavailable::after{content:"";display:block;position:absolute;top:0;left:0;height:100%;width:100%;transition:300ms;cursor:pointer}@keyframes change-gradient-to-inactive{from{background:linear-gradient(to right top, transparent, transparent 48%, {{settings.linkFontColor}} 50%, {{settings.linkFontColor}} 50%, transparent 52%, transparent)}to{background:linear-gradient(to right top, transparent, transparent 49%, {{settings.secondaryFontColor}} 50%, {{settings.secondaryFontColor}} 50%, transparent 51%, transparent)}}@keyframes change-gradient-to-active{from{background:linear-gradient(to right top, transparent, transparent 49%, {{settings.secondaryFontColor}} 50%, {{settings.secondaryFontColor}} 50%, transparent 51%, transparent)}to{background:linear-gradient(to right top, transparent, transparent 48%, {{settings.linkFontColor}} 50%, {{settings.linkFontColor}} 50%, transparent 52%, transparent)}}.productDetails-attributes .button-option:not(.dropdown):not(.units-container) .button-option-unavailable:not(.active){border:1px solid {{settings.secondaryFontColor}}}.productDetails-attributes .button-option:not(.dropdown):not(.units-container) .button-option-unavailable:not(.active)::after{background:linear-gradient(to right top, transparent, transparent 49%, {{settings.secondaryFontColor}} 50%, {{settings.secondaryFontColor}} 50%, transparent 51%, transparent);-webkit-animation:change-gradient-to-inactive 300ms;animation:change-gradient-to-inactive 300ms}.productDetails-attributes .button-option:not(.dropdown):not(.units-container) .button-option-unavailable.active{border:1px solid {{settings.linkFontColor}}}.productDetails-attributes .button-option:not(.dropdown):not(.units-container) .button-option-unavailable.active::after{background:linear-gradient(to right top, transparent, transparent 48%, {{settings.linkFontColor}} 50%, {{settings.linkFontColor}} 50%, transparent 52%, transparent);-webkit-animation:change-gradient-to-active 900ms;animation:change-gradient-to-active 900ms}

Migracja do nowszej biblioteki klienta Google

Wskazówka
Od 1 czerwca 2025 roku zakończyliśmy aktualizację oraz wydawanie nowych wersji szablonów Bursztyn, Agat i Opal, a tym samym ich wsparcie, aby skupić się na nowoczesnych rozwiązaniach, które jeszcze lepiej odpowiadają na potrzeby dynamicznie rozwijającego się rynku e-commerce. Zachęcamy Was do przejścia na nasze nowe, udoskonalone szablony. Dla sklepów B2C polecamy szablony Topaz, One Page Shop oraz Dla Gastronomii, natomiast dla platform B2B idealnym wyborem będą Rubin i Szafir.

Wstęp

W wersji 2022.4. dostosowaliśmy logowanie do e-Sklepu z pomocą nowszej biblioteki usług tożsamości Google we wszystkich standardowych szablonach Comarch. Proces jest zoptymalizowany i przyjazny dla użytkownika. Ujednolicone zostały także przyciski logowania we wszystkich szablonach Comarch. Poniżej znajdują się informację o tym w jaki sposób zaimplementować wspomnianą zmianę do wszystkich standardowych szablonów.
Wskazówka
W tym artykule dowiesz się jak wprowadzać zmiany w plikach js, html i scss. Dodatkowe informacje o kompilacji i minifikacji znajdziesz w centrum pomocy.
Instrukcje do szablonów:

Szafir

Implementacja dla szablonu Szafir ukazana jest w artykule Logowanie do sklepu za pomocą konta Google i Facebook - implementacja w szablonie Szafir, ponieważ w tym szablonie funkcja ta jest również dostępna od wersji 2022.4.

Topaz

Pliki html

  • Na początek w pliku base_layout.html wyszukaj fragment crossorigin="anonymous". Powinien wystąpić raz w całym pliku. Dokładnie w linijkę pod tym elementem wklej ten fragment kodu:

 
  • Następnie w pliku static-elements/login/login.html wyszukaj fragment:
{% if config.External.Facebook or config.External.Google  -%}
  Zamień znajdujący się pomiędzy tym fragmentem a odpowiadającym mu elementem "{% endif -%}" fragment kodu na :  
  • Kolejną czynnością w plikach html dla szablonu Topaz będzie zamiana w pliku partials/customer/account-data.html całego tego fragmentu:
{% if config.External.Facebook or config.External.Google  -%}
 
{{ translations.ExternalWebsites }} {% if customer-profile.LinkedAccounts[0] -%} {% assign fbConnect = 0 -%} {% assign googleConnect = 0 -%} {% for account in customer-profile.LinkedAccounts -%} {% if account.Service == 'Facebook' and config.External.Facebook and config.External.Facebook.AppID != '' %} {% assign fbConnect = 1 -%} {% elsif account.Service == 'Google' and config.External.Google and config.External.Google.ClientID != '' %} {% assign googleConnect = 1 -%} {% endif %} {% endfor %} {% if fbConnect == 0 and config.External.Facebook and config.External.Facebook.AppID != '' %} {% endif %} {% if googleConnect == 0 and config.External.Google and config.External.Google.ClientID != '' %} {% endif %} {% else %} {% if config.External.Facebook and config.External.Facebook.AppID != '' %} {% endif %} {% if config.External.Google and config.External.Google.ClientID != '' %} {% endif %} {% endif %}
 
{% endif -%} Na odpowiadający mu i poprawiony fragment:
{% if config.External.Facebook or config.External.Google  -%}
 
{{translations.ExternalWebsites}} {% if customer-profile.LinkedAccounts[0] -%} {% assign fbConnect = 0 -%} {% assign googleConnect = 0 -%} {% for account in customer-profile.LinkedAccounts -%} {% if account.Service == 'Facebook' and config.External.Facebook and config.External.Facebook.AppID != '' %} {% assign fbConnect = 1 -%} {% elsif account.Service == 'Google' and config.External.Google and config.External.Google.ClientID != '' %} {% assign googleConnect = 1 -%} {% endif %} {% endfor %} {% if fbConnect == 0 and config.External.Facebook and config.External.Facebook.AppID != '' %} {% endif %} {% if googleConnect == 0 and config.External.Google and config.External.Google.ClientID != '' %} {% endif %} {% else %} {% if config.External.Facebook and config.External.Facebook.AppID != '' %} {% endif %} {% if config.External.Google and config.External.Google.ClientID != '' %} {% endif %} {% endif %}
 
{% endif -%}
  • Następnie należy dokonać zmian w plikach koszyka. W zależności od wybranej wariancji w kreatorze pliki będą się róźnić numerkiem na końcu. Jednak zmiany w html są identyczne dla obydwóch wariancji. W pliku elements/cart/cart-1.html lub /cart-2.html wyszukaj fragment:
{% if config.External.Facebook or config.External.Google  -%}
{% endif -%} Następnie zamień ten fragment na wskazany poniżej:
{% if config.External.Facebook or config.External.Google  -%}
{% endif -%}

Pliki JavaScript

  • Zamień całą zawartość pliku js/google-login.js na ten kod:
function handleCredentialResponse(response) {
  setTimeout(function() {
    $.post(null,{ __action: 'External/GoogleLogin', __CSRF: __CSRF, id_token: response.credential },function(result){
        if (result.action.Result) {
            window.location.replace('');
        } else if (result.action.Code === 108) {
            var errMsg = document.querySelector('#google-signin').dataset.errorMsg;
            createMessage(errMsg);
        } else {
            createMessage(result);
        }
    });
  }, 1000);
}

window.onload = function () {
    google.accounts.id.initialize({client_id: __googleID, callback: handleCredentialResponse})
    google.accounts.id.renderButton(
      document.getElementById("google-signin"),
      { theme: "outline", size: "large", width: "250", logo_alignment: "center", text: "signin_with"}
    );

    $('body').on('click', '#linkGoogleAccount', function(){
      setTimeout(function() {
          $.post(null,{ __action: 'External/GoogleAccountLink', __CSRF: __CSRF, userID: __googleID },function(result){
              if (result.action.Result) {
                  location.reload();
              } else {
                  createMessage(result);
              }
          });
      }, 1000);
    });

    $('body').on('click', '#unlinkGoogleAccount', function(){
      $.post(null,{ __action: 'External/GoogleAccountUnlink', __CSRF: __CSRF },function(result){
          if (result.action.Result) {
              location.reload();
          } else {
              createMessage(result);
          }
      });
    });

    $('body').on('click', '.logout', function () {
        googleLogout();
    });
}

function googleLogout() {
  var auth2 = gapi.auth2.getAuthInstance();
  auth2.signOut();
}

function createMessage(obj) {
    if (obj.action.Code != 100) {
        app.showTemporaryPopup(obj.action.Message);
    }
}

  • W pliku js/layout3.js wyszukaj frazę clearInterval(intervalAddress);. Pod jej pierwszym wystąpieniem dodaj fragment location.reload();, w taki sposób jak jest to przedstawione w kodzie poniżej:
        clearInterval(intervalAddress);
    }
}, 1000);
location.reload();

Pliki css

  • W pliku css/layout0.css wyszukaj frazę login-container. Następnie zamień kod znajdujący się za tą frazą na odpowiadający mu fragment znajdujący się poniżej:
.login-container{`max-width:100%;width:30rem;padding:7rem 3rem;box-sizing:border-box;margin:0 auto}.login-container .form__input-wrapper{display:inline-block;position:relative;width:calc(100% - 30px);margin-left:30px;background-color:inherit;margin-bottom:23px}.login-container .form__icons:not(.form__preview){color:{{settings.primaryFontColor}};position:absolute;transform:translateY(-50%);top:20px;left:-30px}.login-container .form__icons.form__preview svg{fill:{{settings.linkFontColor}}}.login-container .form .form__icon_left,.login-container .form__icon_left{left:0}.login-container .form select{border-bottom:1px solid {{settings.primaryFontColor}}}.login-form__signIn{color:{{settings.primaryFontColor}};text-align:center;margin:0;font-weight:300;font-size:32px;display:block}.login-form__welcomeMsg{margin:0.6rem 0 4rem 0;color:{{settings.primaryFontColor}};opacity:0.65;text-align:center}.login-form__more-options{margin:0 0 18px;display:block;text-align:right}.login-form__registerLink{display:block;margin:20px auto 70px;text-align:center}.login-form__forget-password{font-size:12px;font-weight:300;color:{{settings.primaryFontColor}};text-decoration:none}.login-form__register{color:{{settings.linkFontColor}};font-weight:400;font-size:16px}.login-form__submit{margin:0 auto 2.5rem;width:100%;box-sizing:border-box;padding:.8rem 0;display:block;height:auto}.login-container .login-form__socialButtons{display:block;width:100%;font-size:14px;color:{{settings.primaryFontColor}};text-align:center}.login-container .login-form__socialButtons .login-form__socialButtons__buttons{display:flex;flex-direction:column}.login-container .login-form__socialButtons .login-form__socialButtons__buttons .Facebook_Login_Container{display:flex;justify-content:center;align-items:center}.login-container .login-form__socialButtons .login-form__socialButtons__buttons .Facebook_Login_Container .button__Social__facebook{display:flex;justify-content:center;align-items:center;border:1px solid #dadce0;width:248px;min-width:248px;height:38px;margin-top:35px;cursor:pointer;background-color:#FFF;color:#3c4043;margin-left:1px;border-radius:4px;font-weight:500;letter-spacing:0.3px}.login-container .login-form__socialButtons .login-form__socialButtons__buttons .Facebook_Login_Container .button__Social__facebook:hover{background-color:#f9faff;border:1px solid #dbe1ee}.login-container .login-form__socialButtons .login-form__socialButtons__buttons .button__Social__google{display:flex;justify-content:center;align-items:center;margin-top:35px;cursor:pointer;background-color:#FFF}.login-container .login-form__socialButtons .login-form__socialButtons__title{display:block;width:100%;text-align:center;margin:50px 0 15px}.login-container .login-form__socialButtons .GFbLoginIcon{width:30px;height:30px;margin-right:7px}.login-container .login-form__socialButtons .FBIcon{width:21px;height:21px}
  • Następnie w pliku css/layout2.css wyszukaj frazę login-form__socialButtons. Zamień kod znajdujący się za pierwszym wystąpieniem tej frazy (łącznie z tą frazą) na ten wskazany poniżej:
.login-form__socialButtons{display:block;width:100%;font-size:14px;color:{{settings.primaryFontColor}};text-align:center}.login-form__socialButtons .login-form__socialButtons__buttons{display:flex;flex-direction:column}.login-form__socialButtons .login-form__socialButtons__buttons .Facebook_Login_Container{display:flex;justify-content:center;align-items:center}.login-form__socialButtons .login-form__socialButtons__buttons .Facebook_Login_Container .button__Social__facebook{display:flex;justify-content:center;align-items:center;border:1px solid #dadce0;width:248px;min-width:248px;height:38px;margin-top:20px;cursor:pointer;background-color:#FFF;color:#3c4043;margin-left:1px;border-radius:4px;font-weight:500;letter-spacing:0.3px}.login-form__socialButtons .login-form__socialButtons__buttons .Facebook_Login_Container .button__Social__facebook:hover{background-color:#f9faff;border:1px solid #dbe1ee}.login-form__socialButtons .login-form__socialButtons__buttons .button__Social__google{display:flex;justify-content:center;align-items:center;margin-top:20px;cursor:pointer;background-color:#FFF}.login-form__socialButtons .login-form__socialButtons__title{display:block;width:100%;text-align:center;margin:20px 0 0 0;font-size:20px;letter-spacing:1.2px}.login-form__socialButtons .GFbLoginIcon{width:30px;height:30px;margin-right:7px}.login-form__socialButtons .FBIcon{width:21px;height:21px}.primary-action-button .angleRight{fill:{{settings.primaryBtnFontColor}};margin-bottom:-3px;width:16px !important;height:16px !important}.primary-action-button:hover .angleRight{fill:{{settings.primaryBtnHoverFontColor}}}.primary-action-button--disabled .angleRight{fill:{{settings.primaryBtnFontColor}};margin-bottom:-3px;width:16px !important;height:16px !important}.primary-action-button--disabled:hover .angleRight{fill:{{settings.primaryBtnHoverFontColor}}}.cartContainer .validation-info__container{margin-top:6px}
  • Przygotowanie tekstów

Ostatnim etapem implementacji będzie dodanie odpowiednich tekstów do swojego szablonu. Odbywa się to poprzez opcję Tłumaczenia , która znajduje się w Panelu administracyjnym sklepu. Dokładna jej lokalizacja ukazana jest poniżej. W celu dodania tekstu klikamy przycisk dodaj. Dodajemy teksty według poniższej tabeli.
Id Tekst
ConnectFb Połącz konto z Facebookiem
ConnectGoogle Połącz konto z Google
 

Bursztyn

Pliki html

  • Na początek w pliku _layout.html wyszukaj fragment crossorigin="anonymous". Powinien wystąpić raz w całym pliku. Dokładnie w linijkę pod tym elementem wklej ten fragment kodu:

 
  • W pliku customer/login/login-form.html wyszukaj fragment:
{% if usr.Authenticated == 'false' and config.External.Facebook and config.External.Facebook.AppID != '' %}
{% endif -%} {% if usr.Authenticated == 'false' and config.External.Google and config.External.Google.ClientID != '' -%} {% endif -%} Następnie zamień go na ten wskazany poniżej:
{% if usr.Authenticated == 'false' and config.External.Facebook and config.External.Facebook.AppID != '' %}
{% endif -%} {% if usr.Authenticated == 'false' and config.External.Google and config.External.Google.ClientID != '' -%} {% endif -%}  
  • W pliku customer/registation.html wyszukaj fragment :
{% if usr.Authenticated == 'false' and config.External.Facebook and config.External.Facebook.AppID != '' -%}
{% endif -%} {% if usr.Authenticated == 'false' and config.External.Google and config.External.Google.ClientID != '' -%} {% endif -%} Następnie zastąp go kodem ukazanym poniżej :
{% if usr.Authenticated == 'false' and config.External.Facebook and config.External.Facebook.AppID != '' -%}
{% endif -%} {% if usr.Authenticated == 'false' and config.External.Google and config.External.Google.ClientID != '' -%} {% endif -%}  
  • Następnie w pliku customer/profile-account.html wyszukaj fragment :
    {% if customerProfile.LinkedAccounts[0] -%}
        {% assign fbConnect = 0 -%}
        {% assign googleConnect = 0 -%}
        {% for account in customerProfile.LinkedAccounts -%}
            {% if account.Service == 'Facebook' and config.External.Facebook and config.External.Facebook.AppID != '' %}
                
                {% assign fbConnect = 1 -%}
            {% elseif account.Service == 'Google' and config.External.Google and config.External.Google.ClientID != '' %}
                
                {% assign googleConnect = 1 -%}
            {% endif %}
        {% endfor %}
        {% if fbConnect == 0 and config.External.Facebook and config.External.Facebook.AppID != '' %}
            
        {% endif %}
        {% if googleConnect == 0 and config.External.Google and config.External.Google.ClientID != '' %}
            
        {% endif %}
    {% else %}
        {% if config.External.Facebook.AppID != '' and config.External.Facebook %}
            
        {% endif %}
        {% if config.External.Google.ClientID != '' and config.External.Google %}
            
        {% endif %}
    {% endif %}
Następnie zastąp ten fragment tym wskazanym poniżej:
    {% if customerProfile.LinkedAccounts[0] -%}
        {% assign fbConnect = 0 -%}
        {% assign googleConnect = 0 -%}
        {% for account in customerProfile.LinkedAccounts -%}
            {% if account.Service == 'Facebook' and config.External.Facebook and config.External.Facebook.AppID != '' %}
                
                {% assign fbConnect = 1 -%}
            {% elseif account.Service == 'Google' and config.External.Google and config.External.Google.ClientID != '' %}
                
                {% assign googleConnect = 1 -%}
            {% endif %}
        {% endfor %}
        {% if fbConnect == 0 and config.External.Facebook and config.External.Facebook.AppID != '' %}
            
        {% endif %}
        {% if googleConnect == 0 and config.External.Google and config.External.Google.ClientID != '' %}
            
        {% endif %}
    {% else %}
        {% if config.External.Facebook.AppID != '' and config.External.Facebook %}
            
        {% endif %}
        {% if config.External.Google.ClientID != '' and config.External.Google %}
            
        {% endif %}
    {% endif %}

Pliki JavaScript

  • W pliku js/order.js wyszukaj elemnt :
sessionStorage.removeItem('parcelSelected');
Powinien on wystąpić w tym pliku raz. Dokładnie w tym obszarze dokonaj zmian według fragmentu poniżej:
CreateTooltip(d.action);
lazyCheck();
location.reload();
$('html, body').animate({ scrollTop: $('#order-form').offset().top });
$(document).trigger('stepChanged', [step]);
sessionStorage.removeItem('parcelSelected');
 
  • Następnie w plikujs/google-login.js zastąp cały kod tym wskazanym poniżej :
function handleCredentialResponse(response) {
    setTimeout(function() {
      $.post(null,{ __action: 'External/GoogleLogin', __CSRF: __CSRF, id_token: response.credential },function(result){
        if (result.action.Result) {
            window.location.replace('');
        } else if (result.action.Code === 108) {
            var errMsg = document.querySelector('#google-signin').dataset.errorMsg;
            CreateTooltip({Type: 'err', Message: errMsg});
        } else {
            CreateTooltip(result.action);
        }
      });
    }, 1000);
  }
  
  window.onload = function () {
      google.accounts.id.initialize({client_id: __googleID, callback: handleCredentialResponse})
      google.accounts.id.renderButton(
        document.getElementById("google-signin"),
        { theme: "outline", size: "large", width: "325", logo_alignment: "center", text: "signin_with"}
      );
  
      $('body').on('click', '#linkGoogleAccount', function(){
        setTimeout(function() {
            $.post(null,{ __action: 'External/GoogleAccountLink',_csrf: __CSRF, userID: __googleID},function(result){
                if (result.action.Result) {
                    location.reload();
                } else {
                    CreateTooltip(result.action);
                }
            });
        }, 6000);
      });
  
      $('body').on('click', '#unlinkGoogleAccount', function(){
        $.post(null,{ __action: 'External/GoogleAccountUnlink',  __csrf: __CSRF},function(result){
            if (result.action.Result) {
                location.reload();
            } else {
                CreateTooltip(result.action);
            }
        });
      });
}

Pliki scss

  • W pliku scss/main.scss wyszukaj fragment:
.social-button {
  cursor: pointer;
  background-color: #4267b2;
  color: #fff;
  margin: 15px auto;
  padding: 15px 15px 10px;
  text-align: center;
  position: relative;
  transition: 200ms;
  display: block;
  .fa {
    font-size: 26px;
    position: relative;
    top: 5px;
    line-height: 0;
    margin-right: 5px;
  }
}

.client-panel {
  .social-button {
    &.google-button {
      background-color: #ea4335;
    }
  }
}

.register.container {
  .google-social-btn {
    margin-top: -15px;
  }
}

.google-social-btn {
  background-color: #ea4335;
  font-size: inherit;
  border: none;
  border-radius: 0;
  margin-top: 5px;
  &:hover {
    background-color: #da4639;
  }
}

.login-social-button {
  display: block;
  padding: 12px 0 13px;
  float: left;
  width: 100%;
  .fa-facebook-official {
    margin-right: 10px;
  }
}
Następnie zamień ten fragment według tego wskazanego poniżej :
.social-button {
  cursor: pointer;
  background-color: #FFF;
  color: #606060;
  margin: 15px auto;
  padding: 15px 15px 10px;
  text-align: center;
  position: relative;
  transition: 200ms;
  display: block;
  box-shadow: 0px 1px 1px 1px lightgray;
  font-weight: 700;
  .GLoginIcon{
    width: 30px;
    margin-right: 5px;
  }
  .FbLoginIcon{
    width:33px;
    margin-right: 5px;
  }
}
.social-button:hover{
  background-color: #E9E9E5;
  transition: 0,5s;
}

.register.container {
  .google-social-btn {
    margin-top: -15px;
  }
}

.login-social-button {
  font-family: system-ui;
  border: 1px solid #dadce0;
  border-radius: 4px;
  display: flex;
  justify-content: center;
  align-items: center;
  float: left;
  width: 325px;
  height: 44px;
  font-weight: 500;
  margin: 15px auto;
  color: #3c4043;
  cursor: pointer;

  .FbLoginIcon{
    width:21px;
    margin-right: 5px;
  }
}
.login-social-button:hover{
  background-color: #f9faff;
  border: 1px solid #dbe1ee;
}
 
  • W pliku scss/main2.scss zamień podany fragment:
.fb-login-section {
  background-color: #fff;
  padding: 0 25px 25px;
  display: inline-block;
  margin-top: -30px;
}
Na fragment wskazany poniżej:
.fb-login-section {
  background-color: #fff;
  display: inline-block;
  margin-top: -30px;
  padding: 0 25px 25px;
}
.fb-register-section{
  background-color: #fff;
  display: inline-block;
  margin-top: -30px;
  padding: 0 25px 0px;
}
Wskazówka
Pamiętaj, że pliki scss należy zminifikować. O tym jak skompilować i zminifikować pliki scss i js dowiesz się z artykułu o kompilacji i minifikacji.

Agat

Pliki html

  • Na początek w pliku _layout.html wyszukaj fragment crossorigin="anonymous". Powinien wystąpić raz w całym pliku. Dokładnie w linijkę pod tym elementem wklej ten fragment kodu:

 
  • W pliku partials/common/login-form.html wyszukaj fragment:
{% if usr.Authenticated == 'false' and config.External.Facebook and config.External.Facebook.AppID != '' %}

{% endif -%}
{% if usr.Authenticated == 'false' and config.External.Google and config.External.Google.ClientID != '' -%}

{% endif -%}
Występuje on na końu kodu. Zamień wspomniany fragment na ten przedstawiony poniżej:
{% if usr.Authenticated == 'false' and config.External.Facebook and config.External.Facebook.AppID != '' %}
{% endif -%} {% if usr.Authenticated == 'false' and config.External.Google and config.External.Google.ClientID != '' -%}
{% endif -%}  
  • W pliku registration.html wyszukaj fragment:
{% if usr.Authenticated == 'false' and config.External.Facebook.AppID != '' and config.External.Facebook -%}

{% endif -%}
{% if usr.Authenticated == 'false' and config.External.Google.ClientID != '' and config.External.Google -%}

{% endif -%}
Następnie zastąp go fragmentem wsazanym poniżej:
{% if usr.Authenticated == 'false' and config.External.Facebook.AppID != '' and config.External.Facebook -%}
{% endif -%} {% if usr.Authenticated == 'false' and config.External.Google and config.External.Google.ClientID != '' -%}
{% endif -%}  
  • W pliku customer-profile.html wyszukaj fragment :
{% if customerProfile.LinkedAccounts[0] -%}
    {% assign fbConnect = 0 -%}
    {% assign googleConnect = 0 -%}
    {% for account in customerProfile.LinkedAccounts -%}
        {% if account.Service == 'Facebook' and config.External.Facebook and config.External.Facebook.AppID != '' %}
            
            {% assign fbConnect = 1 -%}
        {% elsif account.Service == 'Google' and config.External.Google and config.External.Google.ClientID != '' %}
            
            {% assign googleConnect = 1 -%}
        {% endif %}
    {% endfor %}
    {% if fbConnect == 0 and config.External.Facebook and config.External.Facebook.AppID != '' %}
        
    {% endif %}
    {% if googleConnect == 0 and config.External.Google and config.External.Google.ClientID != '' %}
        
    {% endif %}
{% else %}
    {% if config.External.Facebook and config.External.Facebook.AppID != '' %}
        
    {% endif %}
    {% if config.External.Google and config.External.Google.ClientID != '' %}
        
    {% endif %}
{% endif %}
Następnie podmień ten kod na:
{% if customerProfile.LinkedAccounts[0] -%}
	{% assign fbConnect = 0 -%}
	{% assign googleConnect = 0 -%}
	{% for account in customerProfile.LinkedAccounts -%}
		{% if account.Service == 'Facebook' and config.External.Facebook and config.External.Facebook.AppID != '' %}
			
			{% assign fbConnect = 1 -%}
		{% elsif account.Service == 'Google' and config.External.Google and config.External.Google.ClientID != '' %}
			
			{% assign googleConnect = 1 -%}
		{% endif %}
	{% endfor %}
	{% if fbConnect == 0 and config.External.Facebook and config.External.Facebook.AppID != '' %}
		
	{% endif %}
	{% if googleConnect == 0 and config.External.Google and config.External.Google.ClientID != '' %}
		
	{% endif %}
{% else %}
	{% if config.External.Facebook and config.External.Facebook.AppID != '' %}
		
	{% endif %}
	{% if config.External.Google and config.External.Google.ClientID != '' %}
		
	{% endif %}
{% endif %}
 
  • W pliku partials/cart-content.html wyszukaj fragment:
{% if usr.Authenticated == 'false' and config.External.Facebook and config.External.Facebook.AppID != '' %}
	
{% endif -%}
{% if usr.Authenticated == 'false' and config.External.Google and config.External.Google.ClientID != '' -%}
	
{% endif -%}
Zamień ten fragment tym wskzazanym poniżej:
{% if usr.Authenticated == 'false' and config.External.Facebook and config.External.Facebook.AppID != '' %}
{% endif -%} {% if usr.Authenticated == 'false' and config.External.Google and config.External.Google.ClientID != '' -%}
{% endif -%}

Pliki JavaScript

  • W pliku js/google-login.js zamień cały kod na ten wskazany poniżej:
function handleCredentialResponse(response) {
    setTimeout(function() {
      $.post(null,{ __action: 'External/GoogleLogin', __CSRF: __CSRF, id_token: response.credential },function(result){
          if (result.action.Result) {
              window.location.replace('');
          } else if (result.action.Code === 108) {
              var errMsg = document.querySelector('#google-signin').dataset.errorMsg;
              createMessage(errMsg);
          } else {
              createMessage(result);
          }
      });
    }, 1000);
  }
  
  window.onload = function () {
      google.accounts.id.initialize({client_id: __googleID, callback: handleCredentialResponse})
      google.accounts.id.renderButton(
        document.getElementById("google-signin"),
        { theme: "outline", size: "large", width: "355", logo_alignment: "center", text: "signin_with"}
      );
  
      $('body').on('click', '#linkGoogleAccount', function(){
        setTimeout(function() {
            $.post(null,{ __action: 'External/GoogleAccountLink', __CSRF: __CSRF, userID: __googleID },function(result){
                if (result.action.Result) {
                    location.reload();
                } else {
                    createMessage(result);
                }
            });
        }, 1000);
      });
  
      $('body').on('click', '#unlinkGoogleAccount', function(){
        $.post(null,{ __action: 'External/GoogleAccountUnlink', __CSRF: __CSRF },function(result){
            if (result.action.Result) {
                location.reload();
            } else {
                createMessage(result);
            }
        });
      });
  
      $('body').on('click', '.logout', function () {
          googleLogout();
      });
  }
  
  function googleLogout() {
    var auth2 = gapi.auth2.getAuthInstance();
    auth2.signOut();
  }
  
  function createMessage(obj) {
      if (obj.action.Code != 100) {
          application.createMessage(obj.action);
      }
  }

Pliki scss

  • W pliku scss/main.scss wyszukaj frazę span.social-button. Powinna występować raz w danym pliku. Następnie usuń z fragmentu pod tą linijką element width: 250px;, tak aby po edycji wyglądał w ten sposób:
span.social-button {
	margin: 5px;
}
 
  • W pliku scss/main2.scss wyszukaj fragment:
.login-social-button,
.client-profile .social-button {
  cursor: pointer;
  background-color: #4267b2;
  color: #fff;
  padding: 15px 15px 15px 50px;
  margin: 15px auto;
  position: relative;
  transition: 200ms;
  display: block;
  max-width: 400px;
  width: 100%;
}
.client-profile .social-button {
  display: inline-block;
}
.login-social-button i,
.client-profile .social-button i {
  font-size: 32px;
  position: absolute;
  left: 13px;
  top: 9px;
}
.login-social-button:hover,
.client-profile .social-button:hover {
  background-color: #365899;
  transition: 200ms;
}

.client-profile {
  .social-button {
    margin: 15px;
    &.google-button {
      background-color: #ea4335;
    }
  }
}

.google-social-btn {
  background-color: #ea4335;
  position: relative;
  display: block;
  margin: 0 auto;
  &:hover {
    background-color: #da4639;
  }
}
Następnie zamień go na ten przedstawiony poniżej:
.login-social-button,
.client-profile .social-button {
  cursor: pointer;
  background-color: #FFF;
  color: #7f7f7f;
  padding: 15px 0px 15px 0px;
  margin: 15px auto;
  position: relative;
  transition: 200ms;
  display: flex;
  max-width: 400px;
  width: 100%;
  justify-content: center;
  align-items: center;

}
.client-profile .social-button {
  display: inline-block;
}
.login-social-button,
.client-profile .social-button{
  font-size: 14px;
  display: flex;
  justify-content: center;
  align-items: center;
  top: 9px;
  border: 1px solid #dadce0;
  .GLoginIcon{
    width: 30px;
    margin-right: 10px;
  }
  .FbLoginIcon{
    width:33px;
    margin-right: 10px;
  }
}
.fblogin-button{
  font-family: system-ui;
  width: 351px;
  height: 38px;
  padding: 0px;
  border-radius: 4px;
  font-weight: 500;
  color: #3c4043;
  top: 0;
    .FbLoginIcon{
    width:21px;
    height: 21px;
    margin-right: 10px;
  }
}
.Googlelogin-button{
  display: flex;
  justify-content: center;
  align-items: center;
}
.login-social-button:hover,
.client-profile .social-button:hover {
  background-color: #f9faff;
  border: 1px solid #dbe1ee;
}
Wskazówka
Pamiętaj, że pliki scss należy zminifikować. O tym jak skompilować i zminifikować pliki scss i js dowiesz się z artykułu o kompilacji i minifikacji.

Opal

Pliki html

  • W pliku _layout.html wyszukaj frazę:

Dokładnie pod tym elementem wklej poniższy kod:

  • Następnie w plikach customer/login/login-form.html oraz customer/registration.html wyszukaj fragment:
{% if usr.Authenticated == 'false' and config.External.Facebook and config.External.Facebook.AppID != '' %}
    
{% endif -%}
{% if usr.Authenticated == 'false' and config.External.Google and config.External.Google.ClientID != '' -%}
    
{% endif -%}
Zamień wspomniany fragment na ten ukazany poniżej:
{% if usr.Authenticated == 'false' and config.External.Facebook and config.External.Facebook.AppID != '' %}
{% endif -%} {% if usr.Authenticated == 'false' and config.External.Google and config.External.Google.ClientID != '' -%}
{% endif -%}
  • W pliku customer/profile-account.html wyszukaj fragment kodu:
{% if customerProfile.LinkedAccounts[0] -%}
    {% assign fbConnect = 0 -%}
    {% assign googleConnect = 0 -%}
    {% for account in customerProfile.LinkedAccounts -%}
        {% if account.Service == 'Facebook' and config.External.Facebook and config.External.Facebook.AppID != '' %}
            
            {% assign fbConnect = 1 -%}
        {% elseif account.Service == 'Google' and config.External.Google and config.External.Google.ClientID != '' %}
            
            {% assign googleConnect = 1 -%}
        {% endif %}
    {% endfor %}
    {% if fbConnect == 0 and config.External.Facebook and config.External.Facebook.AppID != '' -%}
        
    {% endif %}
    {% if googleConnect == 0 and config.External.Google and config.External.Google.ClientID != '' -%}
        
    {% endif %}
{% else %}
    {% if config.External.Facebook and config.External.Facebook.AppID != '' %}
        
    {% endif %}
    {% if config.External.Google and config.External.Google.ClientID != '' %}
        
    {% endif %}
{% endif %}
Zamień ten fragment na ten wskazany poniżej:
{% if customerProfile.LinkedAccounts[0] -%}
    {% assign fbConnect = 0 -%}
    {% assign googleConnect = 0 -%}
    {% for account in customerProfile.LinkedAccounts -%}
        {% if account.Service == 'Facebook' and config.External.Facebook and config.External.Facebook.AppID != '' %}
            
            {% assign fbConnect = 1 -%}
        {% elseif account.Service == 'Google' and config.External.Google and config.External.Google.ClientID != '' %}
            
            {% assign googleConnect = 1 -%}
        {% endif %}
    {% endfor %}
    {% if fbConnect == 0 and config.External.Facebook and config.External.Facebook.AppID != '' -%}
        
    {% endif %}
    {% if googleConnect == 0 and config.External.Google and config.External.Google.ClientID != '' -%}
        
    {% endif %}
{% else %}
    {% if config.External.Facebook and config.External.Facebook.AppID != '' %}
        
    {% endif %}
    {% if config.External.Google and config.External.Google.ClientID != '' %}
        
    {% endif %}
{% endif %}

Pliki JavaScript

  • W pliku js/google-login.js zamień cały kod na ten wskazany poniżej:
function handleCredentialResponse(response) {
    setTimeout(function() {
      $.post(null,{ __action: 'External/GoogleLogin', __csrf: __CSRF, id_token: response.credential },function(result){
          if (result.action.Result) {
              window.location.replace('');
          } else if (result.action.Code === 108) {
              var errMsg = document.querySelector('#google-signin').dataset.errorMsg;
              CreateTooltip({Type: 'err', Message: errMsg});
          } else {
              CreateTooltip(result.action);
          }
      });
    }, 1000);
  }
  
  window.onload = function () {
      google.accounts.id.initialize({client_id: __googleID, callback: handleCredentialResponse})
      google.accounts.id.renderButton(
        document.getElementById("google-signin"),
        { theme: "outline", size: "large", width: "350", logo_alignment: "center", text: "signin_with"}
      );
  
      $('body').on('click', '#linkGoogleAccount', function(){
        setTimeout(function() {
            $.post(null,{ __action: 'External/GoogleAccountLink', __csrf: __CSRF, userID: __googleID },function(result){
                if (result.action.Result) {
                    location.reload();
                } else {
                    CreateTooltip(result.action);
                }
            });
        }, 1000);
      });
      
      $('body').on('click', '#unlinkGoogleAccount', function(){
        $.post(null,{ __action: 'External/GoogleAccountUnlink', __csrf: __CSRF },function(result){
            if (result.action.Result) {
                location.reload();
            } else {
                CreateTooltip(result.action);
            }
        });
    });
}
  • W pliku js/order.js wyszukaj fragment:
$('.order:not(.order-content)').replaceWith(d.template);
lazyCheck();
$('html, body').animate({scrollTop: $('#order-form').offset().top});
$(document).trigger('stepChanged', [step]);
Następnie zamień ten fragment na ten wskazany poniżej:
location.reload();
lazyCheck();
$('html, body').animate({ scrollTop: $('#order-form').offset().top });
$(document).trigger('stepChanged', [step]);

Pliki scss

  • W pliku scss/main2.scss wyszukaj fragment kodu:
.social-button {
  cursor: pointer;
  background-color: #4267b2;
  color: #fff;
  padding: 15px 15px 10px;
  text-align: center;
  margin: 15px auto;
  position: relative;
  transition: 200ms;
  max-width: 350px;
  display: block;
  .fa {
    font-size: 26px;
    position: relative;
    top: 4px;
    line-height: 0;
    margin-right: 5px;
  }
}

.client-panel {
  .social-button {
    &.google-button {
      background-color: #ea4335;
    }
  }
}

.google-social-btn {
  background-color: #ea4335;
  font-size: inherit;
  border: none;
  border-radius: 0;
  margin-top: 5px;
  &:hover {
    background-color: #da4639;
  }
}

.login-social-button {
  display: block;
  padding: 14px 10px 11px;
  width: 100%;
  .fa-facebook-official {
    margin-right: 10px;
  }
}
Następnie zamień ten fragment na kod wskazany poniżej:
.social-button {
  cursor: pointer;
  background-color: #FFF;
  color: #3c4043;
  padding: 15px 15px 10px;
  text-align: center;
  margin: 15px auto;
  position: relative;
  transition: 200ms;
  max-width: 350px;
  display: block;
  border: 1px solid #dadce0;
  border-radius: 4px;
  .GLoginIcon{
    width: 30px;
    margin-right: 5px;
  }
  .FbLoginIcon{
    width:33px;
    margin-right: 5px;
  }
}
.social-button:hover{
  background-color: #f9faff;
  border: 1px solid #dbe1ee;
}
.facebookLogin-button{
  font-family: system-ui;
  font-weight: 500;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 38px;
  padding: 0;
  .FbLoginIcon{
    width:21px;
    margin-right: 5px;
  }
}

.google-social-btn {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 38px;
}
Wskazówka
Pamiętaj, że pliki scss należy zminifikować. O tym jak skompilować i zminifikować pliki scss i js dowiesz się z artykułu o kompilacji i minifikacji.

Graficzna prezentacja atrybutów - szablon Topaz

Wstęp

W szablonie Topaz od wersji 2022.4 wprowadzono możliwość graficznej prezentacji atrybutów towaru. Funkcja umożliwia prezentację atrybutów, w formie kolorów dla towarów zgrupowanych (fantomów) i tych posiadających atrybuty oraz w formie miniatur dla towarów zgrupowanych. W tym artykule dowiesz się jak zmodyfikować swój szablon, aby obsługiwał graficzną prezentację atrybutów.
Wskazówka
W tym artykule dowiesz się jak wprowadzać zmiany w plikach js i css. Z tego artykułu dowiesz się jak je minifikować.

Zmiana ustawień w Panelu Administracyjnym

W Panelu Administracyjnym wybierz zakładkę Wygląd sklepu/Ustawienia szablonu, a następnie w prawym górnym rogu kliknij na ikonę z trzema kwadratami i wybierz opcję Edytuj ustawienia zaawansowane. Następnie w zakładce Ustawienia (JSON) w oknie JSON znajdź na końcu kodu znak "}" i wklej przed nim poniższą instrukcję, po czym zapisz zmiany.
,"grapicalVariantsPresentation":"Variants_No","variantsGroupingAttribute":"Grouping_First","grapicalVariantsPresentationColorsPL":"Błękitny||#99CCFF|||Czerwony||#FF3300|||Niebieski||#3366FF|||Brązowy||#964b00|||Czarny||#000000|||Biały||#FFFFFF|||Złoty||#ffd700|||Różowy||#ffc0cb|||Turkusowy||#76D7C4|||Pomarańczowy||#fc9303|||Zielony||#008000|||Beżowy||#c2b280|||Bordowy||#800000|||Ciemny szary||#909090|||Fioletowy||#87599d|||Granatowy||#000080|||Szary||#b4b4b4|||Zgniło zielony||#a5a542|||Żółty||#ffef00","grapicalVariantsPresentationColorsEN":"Azure||#99CCFF|||Red||#FF3300|||Blue||#3366FF|||Brown||#964b00|||Black||#000000|||White||#FFFFFF|||Gold||#ffd700|||Pink||#ffc0cb|||Turquoise||#76D7C4|||Orange||#fc9303|||Green||#008000|||Beige||#c2b280|||Burgundy||#800000|||Dark grey||#909090|||Purple||#87599d|||Navy blue||#000080|||Gray||#b4b4b4|||Rotten green||#a5a542|||Yellow||#ffef00","grapicalVariantsPresentationColorsDE":"Azurblau||#99CCFF|||Rot||#FF3300|||Blau||#3366FF|||Braun||#964b00|||Schwarz||#000000|||Weiß||#FFFFFF|||Gold||#ffd700|||Rosa||#ffc0cb|||Türkis||#76D7C4|||Orange||#fc9303|||Grün||#008000|||Beige||#c2b280|||Kastanienbraun||#800000|||Dunkelgraué||#909090|||Violett||#87599d|||Marineblau||#000080|||Grau||#b4b4b4|||Fauliges Grün||#a5a542|||Gelb||#ffef00","grapicalVariantsPresentationColorsFR":"Azur||#99CCFF|||Rouge||#FF3300|||Bleu||#3366FF|||Marron||#964b00|||Noir||#000000|||Blanc||#FFFFFF|||Or||#ffd700|||Rose||#ffc0cb|||Turquoise||#76D7C4|||Orange||#fc9303|||Vert||#008000|||Beige||#c2b280|||Bordeaux||#800000|||Gris foncé||#909090|||Violet||#87599d|||Bleu marine||#000080|||Gris||#b4b4b4|||Vert pourri||#a5a542|||Jaune||#ffef00"

Zmiany w plikach szablonu

W pliku __settings.liquid znajdź frazę:
{% when '1' -%}
Pod podaną treścią należy wkleić poniższy kod:
{% assign additionalSettings = "Dodatkowe" -%}
{% assign grapicalVariantsPresentation_Title = "Graficzna prezentacja wariantów towarów" -%}
{% assign grapicalVariantsPresentation_No = "Nie" -%}
{% assign grapicalVariantsPresentation_Colors = "Kolory" -%}
{% assign grapicalVariantsPresentation_Thumbnails = "Miniatury (tylko dla towarów zgrupowanych)" -%}
{% assign grapicalVariantsPresentationColorSettings_Title = "Dodaj własne wartości atrybutów i przypisane dla nich wartości do poniższej listy" -%}
{% assign multiVariantProducts = "Towary wielowariantowe" -%}
{% assign variantsGroupingAttributeColors_Title = "W formie graficznej prezentowany będzie atrybut" -%}
{% assign variantsGroupingAttribute_Title = "W formie graficznej prezentowany będzie atrybut grupujący" -%}
{% assign variantsGroupingAttribute_First = "Pierwszy" -%}
{% assign variantsGroupingAttribute_Last = "Ostatni" -%}
{% assign variantsGroupingAttribute_All = "Wszystkie" -%}
{% assign addColor = "Dodaj kolor" -%}
{% assign grapicalVariantsPresentationColorSettings_Color = "Kolor" -%}
{% assign grapicalVariantsPresentationColorSettings_Value = "Wartość" -%}
{% assign delete = "Usuń" -%}
Następnie wyszukaj najbliższą frazę:
{% else %}
I wklej pod nią następujący kod:
{% assign additionalSettings = "Additional" -%}
{% assign grapicalVariantsPresentation_Title = "Graphical presentation of product variants" -%}
{% assign grapicalVariantsPresentation_No = "No" -%}
{% assign grapicalVariantsPresentation_Colors = "Colors" -%}
{% assign grapicalVariantsPresentation_Thumbnails = "Miniatures (only for grouped goods)" -%}
{% assign grapicalVariantsPresentationColorSettings_Title = "Add customized attribute values and assign them to the list below" -%}
{% assign multiVariantProducts = "Multivariant products" -%}
{% assign variantsGroupingAttributeColors_Title = "The attribute will be presented graphically" -%}
{% assign variantsGroupingAttribute_Title = "Grouping attribute will be presented in graphical form" -%}
{% assign variantsGroupingAttribute_First = "First" -%}
{% assign variantsGroupingAttribute_Last = "Last" -%}
{% assign variantsGroupingAttribute_All = "All" -%}
{% assign addColor = "Add color" -%}
{% assign grapicalVariantsPresentationColorSettings_Color = "Color" -%}
{% assign grapicalVariantsPresentationColorSettings_Value = "Value" -%}
{% assign delete = "Delete" -%}
Teraz znajdź fragment kodu:
#lg-settings-content .mainHeader {
	font-size: 22px;
	margin: 45px auto 10px;
}
A następnie zmień wartości marginesów na:
margin: 10px auto;
Kolejno wyszukaj:
#lg-settings-content .themeSettings__inputs > section
Podany fragment zastąp:
#lg-settings-content .themeSettings__inputs > section, #lg-settings-content .additionalSettingsTab section
Teraz wyszukaj:
#lg-settings-content .themeSettings__inputs .section-title
I zmień kod na poniższy:
#lg-settings-content .themeSettings__inputs .section-title, #lg-settings-content .additionalSettingsTab .section-title
Kolejno odnajdź instrukcję:
#lg-settings-content .colorInput {
	position: relative;
	box-shadow: 2px 8px 10px 0 rgba(0, 0, 0, .25);
	cursor: pointer;
	width: 80px !important;
	min-width: 80px !important;
	height: 22px;
	border-radius: 5px;
	margin: 5px 0 -5px 5px;
}
A następnie zastąp ją podanym fragmentem:
#lg-settings-content .colorInput, #lg-settings-content .variantColorInput {
	position: relative;
	box-shadow: 2px 8px 10px 0 rgba(0, 0, 0, .25);
	cursor: pointer;
	width: 80px !important;
	min-width: 80px !important;
	height: 22px;
	border-radius: 5px;
	margin: 5px 0 -5px 5px;
} 

#lg-settings-content .variantColorInput {
	width: 110px !important;
	min-width: 110px !important;
}

#lg-settings-content .colors-row {
	display: flex;
	width: 290px;
	border-bottom: 1px solid #ddd;
	border-right: 1px solid #ddd;
}

#lg-settings-content .colors-row:first-child {
	border-top: 1px solid #ddd;
	border-bottom: 1px solid #ddd;
	font-weight: bold;
}

#lg-settings-content .colors-cell-title {
	display: flex;
	align-items: center;
}

#lg-settings-content .colors-cell-title p {
	padding: 0 5px;
}

#lg-settings-content .colors-cell {
	border-left: 1px solid #ddd;
	padding: 5px 0 10px;
}

#lg-settings-content .colors-cell-name {
	width: 120px;
}

#lg-settings-content .colors-cell-color {
	display: flex;
	width: 130px !important;
}

#lg-settings-content .colors-cell-delete {
	width: 40px;
	display: flex;
	justify-content: center;
	align-items: center;
}

#lg-settings-content .colors-cell-delete div {
	cursor: pointer;
	padding: 5px;
}

#lg-settings-content .add-variant-color {
	margin: 10px 0;
}
Kolejnym etapem jest zmiana wyświetlanej treści w ustawieniach Panelu Administracyjnego. Wyszukaj fragment:
{{saveChangesTranslation}}

I poniżej powyższego kodu wklej poniższe instrukcje:

 
 
Teraz odszukaj instrukcję:

A linijkę przed nią wklej:

 
 
  {{multiVariantProducts}} 

{{grapicalVariantsPresentation_Title}}

 
 
 
 
 
 
 
 
 

{{variantsGroupingAttribute_Title}}

 

{{variantsGroupingAttributeColors_Title}}

 
 
 
 
 
 
 
 
 

{{grapicalVariantsPresentationColorSettings_Title}}

{% assign colorVariantsPresentationLanguageTableText = 'PL,EN,DE,FR,UK,RU,CS,SK,BG,DA,EL,ES,FI,IT,NO,NL,PT,RO,HR,ET,BE,IS,SV,LT,LV,HU,SR,SL,MK,TR,JA,SQ,KA' -%} {% assign colorVariantsPresentationLanguageTable = colorVariantsPresentationLanguageTableText | Split: ',' -%} {{chooseColorVariantsPresentationLanguage}}: {% for language in colorVariantsPresentationLanguageTable -%} {% assign variableName = 'grapicalVariantsPresentationColors' | Append: language -%} {% if settings[variableName] -%} {% endif -%} {% endfor -%}
 
 
  {{SizeChartTitle}} 

{{SizeChartSectionOne}}

 
 
 
 
 
 
 
 
 

{{SizeChartSectionTwo}}

 
 
 
 
 
 
 
 
 
 
 

Ostatnim etapem zmian w pliku jest edycja kodu JavaScript. Znajdź fragment:
function __SaveLiquidSettings(){
        var o = {};
        $('#lg-settings-content input[name], #lg-settings-content div[data-name]').each(function(i,el) {
            if($(el).attr('type') == 'radio' || $(el).attr('type') == 'checkbox') {
                if($(el).is(':checked')) {
                    o[el.name] = el.value;
                }
            } else if ($(el).attr('type') == 'color') {
                o[el.dataset.name] = el.dataset.value;
				(el.dataset.value).length > 7 ? el.classList.add('transparent-js') : el.classList.remove('transparent-js');
            } else {
                o[el.name] = el.value;
			}
        });
        return o;
    }
A nastepnie podmień go na:
if($('#grapicalVariantsPresentation-Colors').prop('checked')){
	    $('.grapicalVariantsPresentationColorSettings').show();
		$('.grouping-attribute-thumbnails').hide();
		$('.grouping-attribute-colors').show();
    } else {
	    $('.grapicalVariantsPresentationColorSettings').hide();
    }

	if($('#grapicalVariantsPresentation-Thumbnails').prop('checked')){
		$('.grouping-attribute-thumbnails').show();
		$('.grouping-attribute-colors').hide();
    }

	if($('#grapicalVariantsPresentation-No').prop('checked')){
		$('.variantsGroupingAttributeSettings').hide();
		$('.grouping-attribute-thumbnails').hide();
		$('.grouping-attribute-colors').hide();
    } else {
	    $('.variantsGroupingAttributeSettings').show();
    }

	$('[name=grapicalVariantsPresentation]').on('change', function(){
	    if($('#grapicalVariantsPresentation-Colors').prop('checked')){
			$('.grapicalVariantsPresentationColorSettings').show();
			$('.variantsGroupingAttributeSettings').show();
			$('.grouping-attribute-thumbnails').hide();
			$('.grouping-attribute-colors').show();
		} else if($('#grapicalVariantsPresentation-Thumbnails').prop('checked')) {
			$('.variantsGroupingAttributeSettings').show();
			$('.grapicalVariantsPresentationColorSettings').hide();
			$('.grouping-attribute-thumbnails').show();
			$('.grouping-attribute-colors').hide();
		} else {
			$('.grapicalVariantsPresentationColorSettings').hide();
			$('.variantsGroupingAttributeSettings').hide();
			$('.grouping-attribute-thumbnails').hide();
			$('.grouping-attribute-colors').hide();
		}
    });

	$('#lg-settings-content .add-variant-color').on('click', function(e){
		var colorsTableClass = $(e.currentTarget).prev().prev().val();
		var colorsTable = $(e.currentTarget).parent().find('.' + colorsTableClass);
		var newColorNumber = colorsTable.find('.colors-row').length - 1;
		var colorsTableTitle = colorsTable.find('.colors-row-title');
		colorsTableTitle.after('
'+ '
'+ '
'+ '
'+ '
'+ '
'); var openPaletteBtns = document.querySelectorAll('.openPaletteBtn-js'); var colorInputs = document.querySelectorAll('.colorInput'); var oldColor; for (let i = 0; i < openPaletteBtns.length; i++) { openPaletteBtns[i].addEventListener('click', function() { var pickerColor = colorPicker.checkIfHex(this.dataset.value); oldColor = pickerColor; colorPicker.openPalette(this); colorPicker.setTransparencyGradient(pickerColor); colorPicker.setTransparencyPicker(this.dataset.value); }); } for (let i = 0; i < colorInputs.length;i++) { colorInputs[i].addEventListener('change', function() { var hex = $(this).val(); var alphaPickerPosition = (document.querySelector('.selectedAlpha-js').style.left).replace(/\D/g, ''); var alphaValue = (1 - (alphaPickerPosition / 300)).toFixed(2); var rgbaColor = "rgba(" + colorPicker.hexToRgb(hex).r + "," + colorPicker.hexToRgb(hex).g + "," + colorPicker.hexToRgb(hex).b + "," + alphaValue + ")"; colorPicker.clearCanvas(); colorPicker.drawElements(hex); colorPicker.setTransparencyGradient(hex); openPaletteBtns[i].style.backgroundColor = rgbaColor; openPaletteBtns[i].setAttribute("data-value",rgbaColor); this.setAttribute("data-value", hex); this.setAttribute("value", hex); }); } $('.colors-delete-js').on('click', function(e) { var colorToRemove = $(e.currentTarget).parent().parent(); colorToRemove.remove(); }); }); $('.colors-delete-js').on('click', function(e) { var colorToRemove = $(e.currentTarget).parent().parent(); colorToRemove.remove(); }); $('.grapicalVariantsPresentationColorSelectLng').on('change', function() { var colorsTables = $('.grapicalVariantsPresentationColorTable'); for(var i = 0; i < colorsTables.length; i++) { $(colorsTables[i]).hide(); } var languageToDisplay = $('.grapicalVariantsPresentationColorSelectLng').val(); var tableToDisplay = '.grapicalVariantsPresentationColorTable.' + languageToDisplay; if($(tableToDisplay).length > 0) { $(tableToDisplay).show(); } else { var colorsTablesSection = $('.grapicalVariantsPresentationColorSettings'); colorsTablesSection.append('
' + '
' + '
' + ' Kolor (' + languageToDisplay + ')
' + '
' + ' Wartość
' + '
' + ' Usuń
'); } }); function __SaveLiquidSettings(){ var o = {}; var colorsVariants = []; var tempColorsVariants = []; $('#lg-settings-content input[name], #lg-settings-content div[data-name]').each(function(i,el) { if($(el).attr('type') == 'radio' || $(el).attr('type') == 'checkbox') { if($(el).is(':checked')) { o[el.name] = el.value; } } else if ($(el).attr('type') == 'colorVariant') { var colorLanguage = $(el).closest('.grapicalVariantsPresentationColorTable')[0].classList[1]; var toAdd = true; var hexColorVariant = el.dataset.value; var colorRow = el.parentElement.parentElement; var colorName = colorRow.querySelector('.variantColorInputName').value.trim(); if(colorRow.querySelector('.variantColorInputName').value !== colorName) { colorRow.querySelector('.variantColorInputName').value = colorName; } var arrayIndex = 0; var hasLanguage = false; if(!tempColorsVariants) { tempColorsVariants[0][0] = colorLanguage; colorsVariants[0][0] = colorLanguage; } else { for(var i = 0; i < tempColorsVariants.length; i++) { if(tempColorsVariants[i][0] == colorLanguage) { arrayIndex = i; hasLanguage = true; break; } } if(!hasLanguage) { tempColorsVariants.push([colorLanguage]); colorsVariants.push([colorLanguage]); arrayIndex = tempColorsVariants.length - 1; } } for(var i=1; i < tempColorsVariants[arrayIndex].length; i++) { if (tempColorsVariants[arrayIndex][i].toLowerCase() === colorName.toLowerCase()) { toAdd = false; break; } } if (!colorName) { toAdd = false; } if (toAdd) { if (colorsVariants[arrayIndex][1] && hexColorVariant) { colorsVariants[arrayIndex][1] = colorsVariants[arrayIndex][1] + '|||'; } if (colorsVariants[arrayIndex].length < 2) { colorsVariants[arrayIndex].push(colorName + '||' + hexColorVariant); } else { colorsVariants[arrayIndex][1] = colorsVariants[arrayIndex][1] + colorName + '||' + hexColorVariant; } tempColorsVariants[arrayIndex].push(colorName); } else { var elementToRemove = colorRow.querySelector('.variantColorInputName').parentElement.parentElement; elementToRemove.remove(); } } else if ($(el).attr('type') == 'color') { o[el.dataset.name] = el.dataset.value; (el.dataset.value).length > 7 ? el.classList.add('transparent-js') : el.classList.remove('transparent-js'); } else { o[el.name] = el.value; } }); if (colorsVariants !== "") { for(var i = 0; i < colorsVariants.length; i++) { o['grapicalVariantsPresentationColors' + colorsVariants[i][0]] = colorsVariants[i][1]; } } $('.selectedTheme-js').attr('id') === "themecolorDark" ? o["defaultColor"] = "#ffffff" : o["defaultColor"] = "#000000"; return o; } Kolejne zmiany w plikach szablonu Topaz dotyczą plików widoku szczegółów towaru. Kreator szablonów umożliwia wygenerowanie czterech różnych widoków szczegółów towarów, dlatego zmiany dla każdego z nich mogą się różnić. Na początku wykonaj zmiany w pliku z kodem JavaScript. Są one identyczne dla wszystkich widoków i należy ich dokonać w pliku js/layout2.js. Wyszukaj w pliku fragment:
function SetSuplFirst(drop, s, lvl, valId) {
    var form = drop.parent().parent().parent();
    var fDrop = form.find('.attributes-select');
    drop.empty();
    for (var el in s) {
        drop.append($('' + s[el].Value + '').data('el', JSON.stringify(s[el])));
    }
Przedstawioną powyżej pętle for podmień na następujący kod:
var attributesColorsData = drop.data('variants-colors');
    var attributesColors = [];
    if (attributesColorsData) {
        attributesColorsData = attributesColorsData.split('|||');
        for (var i = 0; i < attributesColorsData.length; i++) {
            var attributesColor = attributesColorsData[i].split('||');
            attributesColors.push([attributesColor[0],attributesColor[1]]);
        }
    }
    for (var el in s) {
        if (drop.data('variants-colors')) {
            if ((drop.data('colors-option') === 'Grouping_First' && drop.data('attribute-id') === drop.data('first-attribute-id'))
                || (drop.data('colors-option') === 'Grouping_Last' && drop.data('attribute-id') === drop.data('last-attribute-id'))
                || (drop.data('colors-option') === 'Grouping_All')) {
                var bgVariantColor = null;
                var borderVariantColor = null
                for (var i = 0; i < attributesColors.length; i++) {
                    if (attributesColors[i][0].toLowerCase() === s[el].Value.toLowerCase()) {
                        bgVariantColor = attributesColors[i][1];
                        borderVariantColor = attributesColors[i][1];
                    }
                }
				if (!bgVariantColor) {
                    bgVariantColor = '#FFFFFF';
                }
                if (bgVariantColor === '#FFFFFF' || bgVariantColor === drop.data('page-bg')) {
                    borderVariantColor = null;
                }
                drop.append($('
' + s[el].Value + '
 
').data('el', JSON.stringify(s[el])));
            }
            else {
                drop.append($('' + s[el].Value + '').data('el', JSON.stringify(s[el])));
            }  
        }
        else if (drop.data('thumbnails')) {
            var bgVariantImage
            if (s[el].Product) {
                if (s[el].Product.ImagesExt[0].ExternalUrl) {
                    bgVariantImage = "url(" + s[el].Product.ImagesExt[0].ExternalUrl + ")";
                }
                else {
                    bgVariantImage = "url(img/" + s[el].Product.ImagesExt[0].Id + "/" + s[el].Product.ImagesExt[0].Link + ")";
                }
            } else {
                var chcekImagesLoopObj = s[el].Supplies[0]
                while (!chcekImagesLoopObj.Product) {
                    chcekImagesLoopObj = chcekImagesLoopObj.Supplies[0];
                }
                if (chcekImagesLoopObj.Product.ImagesExt[0].ExternalUrl) {
                    bgVariantImage = "url(" + chcekImagesLoopObj.Product.ImagesExt[0].ExternalUrl + ")";
                } else {
                    bgVariantImage = "url(img/" + chcekImagesLoopObj.Product.ImagesExt[0].Id + "/" +  chcekImagesLoopObj.Product.ImagesExt[0].Link + ")";
                }
            }
            if ((drop.data('thumbnails-option') === 'Grouping_First' && drop.data('attribute-id') === drop.data('first-attribute-id'))
                || (drop.data('thumbnails-option') === 'Grouping_Last' && drop.data('attribute-id') === drop.data('last-attribute-id'))
                || (drop.data('thumbnails-option') === 'Grouping_All')) {
                drop.append($('
' + s[el].Value + '
 
').data('el', JSON.stringify(s[el])));
            } else {
                drop.append($('' + s[el].Value + '').data('el', JSON.stringify(s[el])));
            }
        } else {
            drop.append($('' + s[el].Value + '').data('el', JSON.stringify(s[el])));
        }
    }
Analogiczną zmianę wykonaj w sekcji:
function SetSupl(drop, s) {
    var form = drop.closest('#AddToCartForm');
    var fDrop = form.find('.attributes-select');
    drop.empty();
    for (var el in s) {
        drop.append($('' + s[el].Value + '').data('el', JSON.stringify(s[el])));
    }
Instrukcję pętli for podmień na ten sam kod, co dla fragmentu znajdującego się w funkcji SetSuplFirst. Następne zmiany dotyczyć będą pliku html. Zmiany zostaną omówione na przykładzie pliku elements/product/product-details-3.html, lecz omawiany kod będzie identyczny dla innych widoków szczegółów towaru. Róźnić się będzie jedynie nazwa edytowanego pliku, a dokładniej cyfra znajdująca się w nazwie. Na początku wyszukaj fragment:
{% if product.Archival == false -%}
          {% if product.Clip or product.Batch -%}
          
          {% if product.Clip or product.Batch -%}
          
          {% endif -%}
{% for attribute in product.Supplies.AttributeNames -%} {{ attribute.Name | H }}
{% endfor -%}

Przedstawiony powyżej element div (linijka od 7 do 12) zamień na następujący kod:
{% assign pageLanguageShort = page.Language | Upcase -%}
{% assign settingsVariableName = 'grapicalVariantsPresentationColors' | Append: pageLanguageShort -%}
{% assign grapicalVariantsPresentationColorsData = settings[settingsVariableName] -%}
{% if settings.grapicalVariantsPresentation == 'Variants_Thumbnails' -%}
    {% assign attributesThumbnails = true -%}
{% endif -%}
{% if settings.grapicalVariantsPresentation == 'Variants_Colors' -%} {% assign firstAttribute = product.Supplies.AttributeNames|First -%} {% assign lastAttribute = product.Supplies.AttributeNames|Last -%} {% for attribute in product.Supplies.AttributeNames -%} {{ attribute.Name | H }}
{% endfor -%} {% elseif settings.grapicalVariantsPresentation == 'Variants_Thumbnails' -%} {% assign firstAttribute = product.Supplies.AttributeNames|First -%} {% assign lastAttribute = product.Supplies.AttributeNames|Last -%} {% for attribute in product.Supplies.AttributeNames -%} {{ attribute.Name | H }}
{% endfor -%} {% else -%} {% for attribute in product.Supplies.AttributeNames -%} {{ attribute.Name | H }}
{% endfor -%} {% endif -%}
  Teraz znajdź:
{% elseif product.AttributesPolyvalent != empty -%}
{% for attribute in product.AttributesPolyvalent -%}
{{ attribute.Name }}
{% assign i = 0 -%} {% for value in attribute.Values -%} {% assign i = i | Plus: 1 -%} {% endfor -%} {% if i >= 4 -%} {% assign diff = i | Minus: 4 -%}

{{translations.ReadMore}} +{{diff}}

{% endif -%}
I powyższy kod zamień na:
{% elseif product.AttributesPolyvalent != empty -%}
	{% assign loopAttributeFlag = false -%}
        {% assign attributeQuantity = product.AttributesPolyvalent | Size -%}
        {% assign loopIterationVariable = 0 -%}
        {% for attribute in product.AttributesPolyvalent -%}
{{ attribute.Name }}
{% assign i = 0 -%} {% assign loopIterationVariable = loopIterationVariable | Plus: 1 -%} {% if settings.variantsGroupingAttribute == 'Grouping_First' and loopIterationVariable == 1 -%} {% assign loopAttributeFlag = true -%} {% elseif settings.variantsGroupingAttribute == 'Grouping_Last' and loopIterationVariable == attributeQuantity -%} {% assign loopAttributeFlag = true -%} {% elseif settings.variantsGroupingAttribute == 'Grouping_All' -%} {% assign loopAttributeFlag = true -%} {% else -%} {% assign loopAttributeFlag = false -%} {% endif -%} {% if settings.grapicalVariantsPresentation == 'Variants_Colors' and grapicalVariantsPresentationColorsData and loopAttributeFlag -%} {% assign variantsColorArr = grapicalVariantsPresentationColorsData | Split: '|||' -%} {% for value in attribute.Values -%} {% assign bgColorValue = '' -%} {% assign borderColorValue = '' -%} {% for colorValue in variantsColorArr -%} {% assign colorValueArr = colorValue | Split: '||' -%} {% assign colorValueName = colorValueArr[0] | Downcase -%} {% assign colorValueHash = colorValueArr[1] -%} {% assign colorValueToCheck = value.Value | H | Downcase -%} {% if colorValueName == colorValueToCheck -%} {% assign bgColorValue = colorValueHash -%} {% endif -%} {% endfor -%} {% if bgColorValue == '' -%} {% assign bgColorValue = '#FFFFFF' -%} {% endif -%} {% if bgColorValue != '#FFFFFF' or bgColorValue != settings.primaryPageBgColor -%} {% assign borderColorValue = bgColorValue -%} {% endif -%}
 
 
{{ value.Value | H }}
 
{% assign i = i | Plus: 1 -%} {% endfor -%} {% if i >= 4 -%} {% assign diff = i | Minus: 4 -%}

{{translations.ReadMore}} +{{diff}}

{% endif -%} {% else -%} {% for value in attribute.Values -%} {% assign i = i | Plus: 1 -%} {% endfor -%} {% if i >= 4 -%} {% assign diff = i | Minus: 4 -%}

{{translations.ReadMore}} +{{diff}}

{% endif -%} {% endif -%}
W przypadku kiedy szablon Topaz umożliwia zakup z listy towarów, konieczne są zmiany w pliku partials/products-list/add-to-cart-popup.html. Jeśli Twój szablon nie posiada tej opcji, możesz pominąć ten krok. Na początku wyszukaj fragment:
{% if product.Archival == false -%}
{% if product.Clip or product.Batch -%}

{% if product.Clip or product.Batch -%}

{% endif -%}
{% for attribute in product.Supplies.AttributeNames -%} {{ attribute.Name | H }}
{% endfor -%}
{% elseif product.AttributesPolyvalent != empty -%} {% for attribute in product.AttributesPolyvalent -%}
{{ attribute.Name }}
{% for value in attribute.Values -%} {{ value.Value | H }} {% endfor -%}
A następnie zamień go na:
{% if product.Archival == false -%}
    {% assign pageLanguageShort = page.Language | Upcase -%}
    {% assign settingsVariableName = 'grapicalVariantsPresentationColors' | Append: pageLanguageShort -%}
    {% assign grapicalVariantsPresentationColorsData = settings[settingsVariableName] -%}
    {% if settings.grapicalVariantsPresentation == 'Variants_Thumbnails' -%}
        {% assign attributesThumbnails = true -%}
    {% endif -%}
    {% if product.Clip or product.Batch -%}
        
        {% if product.Clip or product.Batch -%}
             
        {% endif -%}
{% if settings.grapicalVariantsPresentation == 'Variants_Colors' -%} {% assign firstAttribute = product.Supplies.AttributeNames|First -%} {% assign lastAttribute = product.Supplies.AttributeNames|Last -%} {% for attribute in product.Supplies.AttributeNames -%} {{ attribute.Name | H }}
{% endfor -%} {% elseif settings.grapicalVariantsPresentation == 'Variants_Thumbnails' -%} {% assign firstAttribute = product.Supplies.AttributeNames|First -%} {% assign lastAttribute = product.Supplies.AttributeNames|Last -%} {% for attribute in product.Supplies.AttributeNames -%} {{ attribute.Name | H }}
{% endfor -%} {% else -%} {% for attribute in product.Supplies.AttributeNames -%} {{ attribute.Name | H }}
{% endfor -%} {% endif -%}
{% elseif product.AttributesPolyvalent != empty -%} {% assign loopAttributeFlag = false -%} {% assign attributeQuantity = product.AttributesPolyvalent | Size -%} {% assign loopIterationVariable = 0 -%} {% for attribute in product.AttributesPolyvalent -%}
{{ attribute.Name }}
{% assign loopIterationVariable = loopIterationVariable | Plus: 1 -%} {% if settings.variantsGroupingAttribute == 'Grouping_First' and loopIterationVariable == 1 -%} {% assign loopAttributeFlag = true -%} {% elseif settings.variantsGroupingAttribute == 'Grouping_Last' and loopIterationVariable == attributeQuantity -%} {% assign loopAttributeFlag = true -%} {% elseif settings.variantsGroupingAttribute == 'Grouping_All' -%} {% assign loopAttributeFlag = true -%} {% else -%} {% assign loopAttributeFlag = false -%} {% endif -%} {% if settings.grapicalVariantsPresentation == 'Variants_Colors' and grapicalVariantsPresentationColorsData and loopAttributeFlag -%} {% assign variantsColorArr = grapicalVariantsPresentationColorsData | Split: '|||' -%} {% for value in attribute.Values -%} {% assign bgColorValue = '' -%} {% assign borderColorValue = '' -%} {% for colorValue in variantsColorArr -%} {% assign colorValueArr = colorValue | Split: '||' -%} {% assign colorValueName = colorValueArr[0] | Downcase -%} {% assign colorValueHash = colorValueArr[1] -%} {% assign colorValueToCheck = value.Value | H | Downcase -%} {% if colorValueName == colorValueToCheck -%} {% assign bgColorValue = colorValueHash -%} {% endif -%} {% endfor -%} {% if bgColorValue == '' -%} {% assign bgColorValue = '#FFFFFF' -%} {% endif -%} {% if bgColorValue != '#FFFFFF' or bgColorValue != settings.primaryPageBgColor -%} {% assign borderColorValue = bgColorValue -%} {% endif -%}
 
 
{{ value.Value | H }}
 
{% endfor -%} {% else -%} {% for value in attribute.Values -%} {{ value.Value | H }} {% endfor -%} {% endif -%}
Na koniec znajdź jeszcze fragment:
{% if product.Archival == false -%} {% if product.Clip or product.Batch -%} {% if product.Clip or product.Batch -%} {% endif -%}
{% for attribute in product.Supplies.AttributeNames -%} {{ attribute.Name | H }}
{% endfor -%}
{% elseif product.AttributesPolyvalent != empty -%} {% for attribute in product.AttributesPolyvalent -%}
{{ attribute.Name }}
{% assign i = 0 -%} {% for value in attribute.Values -%} {% assign i = i | Plus: 1 -%} {% endfor -%} {% if i >= 4 -%} {% assign diff = i | Minus: 4 -%}

{{translations.ReadMore}} +{{diff}}

{% endif -%}
I zastąp go poniższym kodem:
{% if product.Archival == false -%} {% assign pageLanguageShort = page.Language | Upcase -%} {% assign settingsVariableName = 'grapicalVariantsPresentationColors' | Append: pageLanguageShort -%} {% assign grapicalVariantsPresentationColorsData = settings[settingsVariableName] -%} {% if settings.grapicalVariantsPresentation == 'Variants_Thumbnails' -%} {% assign attributesThumbnails = true -%} {% endif -%} {% if product.Clip or product.Batch -%} {% if product.Clip or product.Batch -%} {% endif -%}
{% if settings.grapicalVariantsPresentation == 'Variants_Colors' -%} {% assign firstAttribute = product.Supplies.AttributeNames|First -%} {% assign lastAttribute = product.Supplies.AttributeNames|Last -%} {% for attribute in product.Supplies.AttributeNames -%} {{ attribute.Name | H }}
{% endfor -%} {% elseif settings.grapicalVariantsPresentation == 'Variants_Thumbnails' -%} {% assign firstAttribute = product.Supplies.AttributeNames|First -%} {% assign lastAttribute = product.Supplies.AttributeNames|Last -%} {% for attribute in product.Supplies.AttributeNames -%} {{ attribute.Name | H }}
{% endfor -%} {% else -%} {% for attribute in product.Supplies.AttributeNames -%} {{ attribute.Name | H }}
{% endfor -%} {% endif -%}
{% elseif product.AttributesPolyvalent != empty -%} {% assign loopAttributeFlag = false -%} {% assign attributeQuantity = product.AttributesPolyvalent | Size -%} {% assign loopIterationVariable = 0 -%} {% for attribute in product.AttributesPolyvalent -%}
{{ attribute.Name }}
{% assign i = 0 -%} {% assign loopIterationVariable = loopIterationVariable | Plus: 1 -%} {% if settings.variantsGroupingAttribute == 'Grouping_First' and loopIterationVariable == 1 -%} {% assign loopAttributeFlag = true -%} {% elseif settings.variantsGroupingAttribute == 'Grouping_Last' and loopIterationVariable == attributeQuantity -%} {% assign loopAttributeFlag = true -%} {% elseif settings.variantsGroupingAttribute == 'Grouping_All' -%} {% assign loopAttributeFlag = true -%} {% else -%} {% assign loopAttributeFlag = false -%} {% endif -%} {% if settings.grapicalVariantsPresentation == 'Variants_Colors' and grapicalVariantsPresentationColorsData and loopAttributeFlag -%} {% assign variantsColorArr = grapicalVariantsPresentationColorsData | Split: '|||' -%} {% for value in attribute.Values -%} {% assign bgColorValue = '' -%} {% assign borderColorValue = '' -%} {% for colorValue in variantsColorArr -%} {% assign colorValueArr = colorValue | Split: '||' -%} {% assign colorValueName = colorValueArr[0] | Downcase -%} {% assign colorValueHash = colorValueArr[1] -%} {% assign colorValueToCheck = value.Value | H | Downcase -%} {% if colorValueName == colorValueToCheck -%} {% assign bgColorValue = colorValueHash -%} {% endif -%} {% endfor -%} {% if bgColorValue == '' -%} {% assign bgColorValue = '#FFFFFF' -%} {% endif -%} {% if bgColorValue != '#FFFFFF' or bgColorValue != settings.primaryPageBgColor -%} {% assign borderColorValue = bgColorValue -%} {% endif -%}
 
 
{{ value.Value | H }}
 
{% assign i = i | Plus: 1 -%} {% endfor -%} {% if i >= 4 -%} {% assign diff = i | Minus: 4 -%}

{{translations.ReadMore}} +{{diff}}

{% endif -%} {% else -%} {% for value in attribute.Values -%} {% assign i = i | Plus: 1 -%} {% endfor -%} {% if i >= 4 -%} {% assign diff = i | Minus: 4 -%}

{{translations.ReadMore}} +{{diff}}

{% endif -%} {% endif -%}
Ostatnim etapem zmian w szablonie Topaz w celu graficznej prezentacji atrybutów jest zmiana plików css w szablonie. Pliki ze stylami różnią się w zależności od wybranego szczegółu towaru. Poniższe zmiany dotyczą pierwszego i drugiego widoku szczegółów towaru. Zmiany dla pozostałych widoków przedstawione są w dalszej częsci artykułu. W pliku css/layout1.css zlokalizuj podany fragment:
.product-details .input-group .wrongInput{border-bottom:1px solid #ce283e !important}.product-details .input-group .wrongInput--info{font-size:11px;text-align:left;color:#ce283e;position:absolute;left:0%;margin-top:-10px}.product-details .input-group input[name="attributeEditable"]{margin:30px 0 15px;padding-bottom:10px}.product-details .input-group .attributes-select{display:inline-block}
A następnie zaraz po ostatnim znaku powyższego kodu wklej:
.product-details .input-group .button-option-variants{height:auto;font-size:13px;padding:0 8px}.product-details .input-group .button-option-variants .button-option-variants-content{display:flex;flex-direction:column;align-items:center;padding:5px 0;margin:0 auto}.product-details .input-group .button-option-variants .button-option-variants-content__color{width:50px;height:50px;border:1px solid {{settings.secondaryFontColor}};border-radius:50%;margin-bottom:5px;background-size:cover !important}.product-details .input-group .button-option-variants .button-option-variants-content__text{line-height:1em;width:70px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
Na koniec odnajdź fragment:
.product-details .dropdown .dropdown-content{display:none;position:absolute;background-color:{{settings.primaryPageBgColor}};box-shadow:0 8px 16px 0 rgba(0,0,0,0.2);z-index:1;overflow-y:auto;max-height:190px;min-width:220px;padding:10px 15px}
I zmień wartość maksymalnej wysokości:
max-height:180px;
Następne zmiany stylistyki szablonu Topaz dotyczą wyłącznie trzeciego i czwartego widoku szczegółów towaru. W przypadku pozostałych widoków, wszystkie zmiany zostały już przedstawione. W pliku css/layout2.css należy wyszukać w pliku fragment:
.productDetails-attributes .breakLine{display:block;width:100%;height:0;margin:0}
A następnie przed powyższym kodem dodaj:
.productDetails-attributes .button-option:not(.dropdown):not(.units-container) .button-option-variants{height:auto;font-size:13px;padding:0 6px}.productDetails-attributes .button-option:not(.dropdown):not(.units-container) .button-option-variants .button-option-variants-content{display:flex;flex-direction:column;align-items:center;padding:10px 0}.productDetails-attributes .button-option:not(.dropdown):not(.units-container) .button-option-variants .button-option-variants-content__color{width:50px;height:50px;border:1px solid {{settings.secondaryFontColor}};border-radius:50%;margin-bottom:5px;background-size:cover !important}.productDetails-attributes .button-option:not(.dropdown):not(.units-container) .button-option-variants .button-option-variants-content__text{line-height:1em;width:65px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
Teraz odnajdź w pliku instrukcje:
.choose-attribute-popup .attribute-name,.choose-attribute-popup .attr-ed-name{color:{{settings.primaryFontColor}};width:30%;font-size:14px;font-weight:bold;line-height:1.43;letter-spacing:normal;margin-bottom:10px}.choose-attribute-popup .attribute-name::first-letter,.choose-attribute-popup .attr-ed-name::first-letter{text-transform:capitalize}
I wklej przed podanym fragmentem takie instrukcje:
.choose-attribute-popup .attributes-select .button-option-variants{height:auto;font-size:13px;padding:0 6px;width:fit-content;margin:0 auto}.choose-attribute-popup .attributes-select .button-option-variants .button-option-variants-content{display:flex;flex-direction:column;align-items:center;padding:10px 0}.choose-attribute-popup .attributes-select .button-option-variants .button-option-variants-content__color{width:50px;height:50px;border:1px solid {{settings.secondaryFontColor}};border-radius:50%;margin-bottom:5px;background-size:cover !important}.choose-attribute-popup .attributes-select .button-option-variants .button-option-variants-content__text{line-height:1em;width:65px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
Następnie wyszukaj fragment:
@media screen and (min-width: 769px){.productDetails .popup-dialog .form-container{width:35rem !important;max-width:unset !important;padding:3rem 4rem 2rem}}
Aby podmienić go na poniższe wartości:
@media screen and (min-width: 769px){.productDetails .popup-dialog .form-container{width:55rem !important;max-width:unset !important;padding:3rem 4rem 2rem}}
Kolejno zlokalizuj instrukcje:
.choose-attribute-popup .form-container{padding:20px}.choose-attribute-popup .input-group{width:100%;display:flex;flex-direction:row;align-items:center;flex-wrap:wrap}.choose-attribute-popup .attributes-select{display:grid;width:100%;grid-template-columns:33% 33% 33%;grid-row-gap:10px;max-width:unset}
I zastąp je następującymi:
.choose-attribute-popup .form-container{padding:20px}.choose-attribute-popup .close-button{right:40px}.choose-attribute-popup .input-group{width:100%;display:flex;flex-direction:row;align-items:center;flex-wrap:wrap}.choose-attribute-popup .attributes-select{display:grid;width:100%;grid-template-columns:16% 16% 16% 16% 16% 16%;column-gap:6px;grid-row-gap:10px;max-width:unset}
Ostatnim etapem zmian w pliku jest aktualizacja podanego kodu:
.choose-attribute-popup .attr-popup-button{width:calc(100%-34px);height:16px;font-size:14px;font-weight:normal;font-stretch:normal;font-style:normal;line-height:16px;letter-spacing:1.2px;text-align:center}.choose-attribute-popup .button-option[data-selected="true"]{border:2px solid {{settings.linkFontColor}} !important}.choose-attribute-popup .attr-values{display:grid;grid-template-columns:33% 33% 33%;grid-row-gap:10px;width:100%;background-color:{{settings.primaryPageBgColor}} !important}
Na poniższy fragment:
.choose-attribute-popup .attr-popup-button{width:50%;margin:0 auto;height:16px;font-size:14px;font-weight:normal;font-stretch:normal;font-style:normal;line-height:16px;letter-spacing:1.2px;text-align:center}.choose-attribute-popup .button-option[data-selected="true"]{border:2px solid {{settings.linkFontColor}} !important}.choose-attribute-popup .attr-values{display:grid;grid-template-columns:16% 16% 16% 16% 16% 16%;column-gap:6px;grid-row-gap:10px;width:100%;background-color:{{settings.primaryPageBgColor}} !important}
W przypadku trzeciego i czwartego widoku szczegółów towaru, konieczne są jeszcze dodatkowe zmiany w pliku css/layout-m0.css. Na początku wyszukaj fragment:
.productDetails .popup-dialog .main-title{max-width:85%}.productDetails .popup-dialog .primary-action-button{line-height:11px}.productDetails .popup-dialog .form-container{width:95%;padding:2rem 1.5rem;overflow-y:scroll;max-height:90vh}
Teraz podmień go na poniższy kod:
.productDetails .popup-dialog .main-title{max-width:85%}.productDetails .popup-dialog .primary-action-button{line-height:11px}.productDetails .popup-dialog .form-container{width:95%;padding:2rem 1.2rem;overflow-y:scroll;overflow-x:hidden;max-height:90vh}
Na koniec odnajdź w pliku instrukcje:
@media screen and (max-width: 400px){.choose-attribute-popup .attributes-select,.choose-attribute-popup .attr-values{grid-template-columns:49% 49%}
I zastąp je następującym fragmentem:
@media screen and (max-width: 768px){.choose-attribute-popup .attributes-select,.choose-attribute-popup .attr-values{grid-template-columns:33% 33% 33%;column-gap:0}.choose-attribute-popup .button-option-variants{padding:0 4px;word-break:break-word}.close-button{right:8px !important}.attr-popup-button{width:calc(100% - 34px) !important}.button-option-variants-content{padding:8px 0}}

Logowanie do sklepu za pomocą konta Google i Facebook - implementacja w szablonie Szafir

Wstęp

Z tego artykułu dowiesz się jak zaimplementować opcję logowania do Twojego sklepu w szablonie Szafir za pomocą kont Google oraz Facebook. Od wersji 2022.4 w szablonie Szafir wprowadziliśmy możliwość logowania do sklepu za pomocą konta Google oraz Facebook. W celu zaimplementowania takiej możliwości w swoim sklepie należy wykonać trzy czynności dla każdej z tych platform :
  1. Konfiguracja logowania w Panelu Administracyjnym
  2. Zmiany w kodzie źródłowym sklepu
  3. Przygotowanie tekstów
Wskazówka
W tym artykule dowiesz się jak wprowadzać zmiany w plikach js, html i scss. Dodatkowe informacje o kompilacji i minifikacji znajdziesz w centrum pomocy.
Poniżej znajdują się instrukcje rozwijające wspomniane wyżej wątki.

1. Konfiguracja logowania w Panelu Administracyjnym

Informacje odnośnie tego etapu implementacji znajdują się w artykule o logowaniu do sklepu za pomocą konta Google i Facebook.

2. Zmiany w kodzie źródłowym sklepu

Poniżej znajdują się fragmenty kodu, które należy dodać w celu utworzenia nowych opcji logowania.

Pliki html

  • W pliku _layout.html wyszukaj frazę crossorigin="anonymous" dokładnie pod linijką z tym elementem wklej ten kod:

  • W pliku sign-in.html wyszukaj frazę loader-js. Fraza powinna wystąpić raz. Pod tą linijką w miejscu pomiędzy tymi dwoma elementami:
    
{% endif -%} Wstaw poniższy fragment kodu:
{% if config.External.Facebook or config.External.Google  -%}
    
{% if usr.Authenticated == 'false' and config.External.Facebook and config.External.Facebook.AppID %}
{{translations.LoginWithFb}}
{% endif -%} {% if usr.Authenticated == 'false' and config.External.Google and config.External.Google.ClientID -%}
{% endif -%}
{% endif -%}
  • W pliku customer-profile/your-account/your-account.html na samym końcu w przedostatniej linijce dodaj fragment :

{{ translations.ExternalWebsites }}

{% if config.External.Facebook or config.External.Google -%}
{% if customer-profile.LinkedAccounts[0] -%} {% assign fbConnect = 0 -%} {% assign googleConnect = 0 -%} {% for account in customer-profile.LinkedAccounts -%} {% if account.Service == 'Facebook' and config.External.Facebook and config.External.Facebook.AppID != '' %}
{{translations.Disconnect_Fb}}
{% assign fbConnect = 1 -%} {% elsif account.Service == 'Google' and config.External.Google and config.External.Google.ClientID != '' %}
{{translations.Disconnect_Google}}
{% assign googleConnect = 1 -%} {% endif %} {% endfor %} {% if fbConnect == 0 and config.External.Facebook and config.External.Facebook.AppID != '' %}
{{translations.ConnectFb}}
{% endif %} {% if googleConnect == 0 and config.External.Google and config.External.Google.ClientID != '' %}
{{translations.ConnectGoogle}}
{% endif %} {% else %} {% if config.External.Facebook and config.External.Facebook.AppID != '' %}
{{translations.ConnectFb}}
{% endif %} {% if config.External.Google and config.External.Google.ClientID != '' %}
{{translations.ConnectGoogle}}
{% endif %} {% endif %}
{% endif -%}

Pliki JavaScript

W katalogu js stwórz dwa pliki JavaScript nazwij je kolejno google-login.js oraz fb-login.js. Następnie wklej do nich poniższe kody:
  • Plik google-login.js :
function handleCredentialResponse(response) {
  setTimeout(function() {
    $.post(null,{ __action: 'External/GoogleLogin', __csrf: __CSRF, id_token: response.credential },function(result){
      if (result.action.Result) {
          window.location.replace('');
      } else if (result.action.Code === 108) {
          const popup = '
' + __translations.CantLoginWithGoogle + '
'; document.body.innerHTML += popup; setTimeout(function () { $('.unsuccessfull-post-message-js').remove(); }, 3000); } else { const popup = '
' + __translations.CantLoginWithGoogle + '
'; document.body.innerHTML += popup; setTimeout(function () { $('.unsuccessfull-post-message-js').remove(); }, 3000); } }); }, 1000); } window.onload = function () { google.accounts.id.initialize({client_id: __googleID, callback: handleCredentialResponse}) google.accounts.id.renderButton( document.getElementById("google-signin"), { theme: "outline", size: "large", width: "250", logo_alignment: "center", text: "signin_with", wight: "100"} ); $('body').on('click', '#linkGoogleAccount', function(){ setTimeout(function() { $.post(null,{ __action: 'External/GoogleAccountLink', __csrf: __CSRF, userID: __googleID },function(result){ if (result.action.Result) { location.reload(); } else { const popup = '
' + __translations.FailedConnectToGoogle + '
'; document.body.innerHTML += popup; setTimeout(function () { $('.unsuccessfull-post-message-js').remove(); }, 3000); } }); }, 1000); }); $('body').on('click', '#unlinkGoogleAccount', function(){ $.post(null,{ __action: 'External/GoogleAccountUnlink', __csrf: __CSRF },function(result){ if (result.action.Result) { location.reload(); } else { const popup = '
' + __translations.FailedDisconnectFromGoogle + '
'; document.body.innerHTML += popup; setTimeout(function () { $('.unsuccessfull-post-message-js').remove(); }, 3000); } }); }); $('body').on('click', '.logout', function () { googleLogout(); }); } function googleLogout() { var auth2 = gapi.auth2.getAuthInstance(); auth2.signOut(); }

  • Plik fb-login.js :

var fbLoginStatus;

// This is called with the results from from FB.getLoginStatus().
function statusChangeCallback(response) {
    fbLoginStatus = response;
}

function _login() {
    FB.login(function (response) {
        // handle the response
        if (response.status === 'connected') {
            connectToFb(response);
        }
    }, { scope: 'public_profile,email' });
}

window.fbAsyncInit = function () {
    FB.init({
        appId: __fbId, //Your APP ID
        cookie: true,  // enable cookies to allow the server to access the session
        xfbml: true,  // parse social plugins on this page
        version: 'v2.1', // use version 2.1
        status: true
    });

    // These three cases are handled in the callback function.
    FB.getLoginStatus(function (response) {
        statusChangeCallback(response);
    });

    FB.Event.subscribe('auth.authResponseChange', function (response) {
        fbLoginStatus = response;
    });

    $('body').on('click', '.logout', function () {
        fbLogout();
    });

    $('body').on('click', '#disconnect-fb', function () {
        disconnectFb();
    });

    $('body').on('click', '#connect-fb', function (e) {
        connectFb(e);
    });
};

// Load the SDK asynchronously
(function (d, s, id) {
    var js, fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s); js.id = id;
    js.src = "https://connect.facebook.net/en_US/sdk.js";
    fjs.parentNode.insertBefore(js, fjs);
} (document, 'script', 'facebook-jssdk'));

function connectToFb(response) {
    FB.api('/me', {
        fields: 'email,name'
    }, function (u) {
        response.user = u;
        $.post(null, {
            __CSRF: __CSRF,
            __action: 'external/fblogin',
            response: JSON.stringify(response)
        }, function (result) {
            if (result.action.Result) {
                window.location.replace('');
            } else if (result.action.Code != 100) {
                const popup = '
' + __translations.CantLoginWithFb + '
'; document.body.innerHTML += popup; setTimeout(function () { $('.unsuccessfull-post-message-js').remove(); }, 3000); } }); }); } function fbLogout() { FB.logout(function (response) { }); } function disconnectFb() { var data = { __csrf: __CSRF, __action: 'External/FbAccountUnlink' }; $.post(null, data, function (result) { if (result.action.Result) { location.reload(); } else { const popup = '
' + __translations.FailedDisconnectFromFb + '
'; document.body.innerHTML += popup; setTimeout(function () { $('.unsuccessfull-post-message-js').remove(); }, 3000); } }); } function connectFb(e) { if (fbLoginStatus.status === 'connected') { var userIdNum = fbLoginStatus.authResponse.userID; var data = { __csrf: __CSRF, __action: 'External/FbAccountLink', userID: userIdNum }; $.post(null, data, function (result) { if (result.action.Result) { location.reload(); } else { const popup = '
' + __translations.FailedConnectToFb + '
'; document.body.innerHTML += popup; setTimeout(function () { $('.unsuccessfull-post-message-js').remove(); }, 3000); } }); } else { const popup = '
' + __translations.NeedToConnectToFb + '
'; document.body.innerHTML += popup; setTimeout(function () { $('.unsuccessfull-post-message-js').remove(); }, 3000); } }

Pliki scss

  • W pliku scss/globals/_globals-m.scss na samym końcu dodaj poniższy fragment kodu:
@media only screen and (max-width: 1279px){
  .connectSocialsAccount-ui{
    width: 100%; 
    .CustomerContentSection-ui{
      .CustomerSocialButton-ui{
        width: 100%;
        min-width: auto;
      }
    }
  }
}
  • W pliku scss/globals/_globals1.scss znajdź fragment :
  }
  &-button-drop-ui span{
    margin-left: 13px;
  }
Dokładnie nad tym fragmentem wstaw poniższy kod:
    .loginForm-ui{
      width:100%; 
      font-size: 16px; 
      margin-bottom: 20px;
      .login-form__socialButtons__title-ui{
        display:inline-block;
        width: 100%;
        text-align: center;
      }
      .socialLoginButtons-ui{
        display: flex;
        width: 100%;
        align-content: center;
        flex-wrap: wrap;
        flex-direction: column;
        .FbLoginForm-ui {
          display: flex;
          background: #FFFFFF;
          color: #3c4043;
          width: 250px;
          height: 40px;
          border: 1px solid #dadce0;
          border-radius: 4px;
          justify-content: center;
          align-items: center;
          margin-top: 18px;
          cursor: pointer;
          .FbLoginIcon-ui {
            background: #FFFFFF;
            display: inline-block;
            vertical-align: middle;
            width: 21px;
            height: 21px;
          }
          .FbButtonText-ui {
            display: inline-block;
            vertical-align: middle;
            padding-left: 10px;
            font-size: 14px;
            font-family: 'Roboto', sans-serif;
            font-weight: 500;
          }
        }
        .FbLoginForm-ui:hover{
          background-color: #f9faff;
          border: 1px solid #dbe1ee;
          transition: 0,5s;
        }

        .GLoginForm-ui {
          display: flex;
          justify-content: center;
          align-items: center;
          margin-top: 18px;
        }
      }
    }
  • Następnie dalej w tym samym pliku (scss/globals/_globals1.scss) na samym końcu dodaj poniższy fragment kodu:
.connectSocialsAccount-ui{
  width: 93%; 
  margin: auto;
  margin-bottom:50px;
  .CustomerContentSection-ui{
    margin-top: 50px;
    display: flex;
    flex-direction: column;
    .CustomerSocialButton-ui{
      display: inline-flex !important;
      box-shadow: 0px 1px 1px 1px lightgray;
      justify-content: center;
      align-items: center;
      width: calc(33% - 11px);
      min-width: 420px;
      height: auto;
      color: #232323;
      font-size: 14px;
      text-transform: uppercase;
      font-weight: 400;
      display: block;
      margin-bottom: 20px;
      padding: 17px;
      text-align: center;
      cursor: pointer;
      letter-spacing: 1px;
    }
    .CustomerSocialButtonGoogle-ui {
      background-color: #FFFFFF;
    }
    .CustomerSocialButtonFacebook-ui {
      background-color: #FFFFFF;
    }
    .CustomerSocialButton-ui:hover{
      box-shadow:0 0 4px #4285F4;
      transition: 1s;
    }
    .GFbLinkIcon-ui{
      margin-right: 10px;
      width: 32px;
      height: 32px;
    }
  }
}
Wskazówka
Pamiętaj, że pliki scss należy zminifikować. O tym jak skompilować i zminifikować pliki scss i js dowiesz się z artykułu o kompilacji i minifikacji.

3. Przygotowanie tekstów

Ostatnim etapem implementacji będzie dodanie odpowiednich tekstów do swojego szablonu. Odbywa się to poprzez opcję Tłumaczenia , która znajduje się w Panelu administracyjnym sklepu. Dokładna jej lokalizacja ukazana jest poniżej. W celu dodania tekstu klikamy przycisk dodaj. Dodajemy teksty według poniższej tabeli.
Id Tekst
ExternalWebsites Serwisy zewnętrzne
NeedToConnectToFb Musisz być zalogowany do Facebooka, aby połączyć konto.
CantLoginWithFb Błąd podczas logowania do Facebooka.
FailedDisconnectFromFb Błąd podczas odłączania konta Facebook.
FailedConnectToFb Błąd podczas łączenia z kontem Facebook.
LoginWithFb Zaloguj się przez Facebook
Disconnect_Fb Odłącz konto od Facebooka
ConnectFb Połącz konto z Facebookiem
CantLoginWithGoogle Nie udało się zalogować, spróbuj jeszcze raz!
FailedDisconnectFromGoogle Błąd podczas odłączania konta Google.
FailedConnectToGoogle Błąd podczas łączenia z kontem Google.
LoginWithGoogle Zaloguj się przez Google
Disconnect_Google Odłącz konto od Google
ConnectGoogle Połącz konto z Google