Dmitriy | Инициализация.

This commit is contained in:
27 changed files with 1464 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
.price-updates-options {
position: relative;
font-size: 16px;
}
.price-updates-options input,
.price-updates-options label,
.price-updates-options button {
font-size: 16px;
}
.price-updates-options__input-wrapper {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 8px;
margin-bottom: 12px;
}
.price-updates-options__input-wrapper input[type="text"] {
width: 500px;
}
.price-updates-options__submit-wrapper {
display: flex;
gap: 12px;
}
.price-updates-options__submit {
width: 200px;
padding: 12px 16px;
text-align: center;
border-radius: 20px;
border: none;
color: #fff;
background: radial-gradient(278.91% 196.13% at 128.36% -48.29%, #ee6868 0%, #569ef0 57.69%);
cursor: pointer;
transition: filter 0.3s ease;
margin-top: 8px;
}
.price-updates-options__submit:hover {
filter: brightness(0.9);
}
.price-updates-options__success-message,
.price-updates-options__error-message {
width: max-content;
padding: 16px 20px;
border-radius: 8px;
}
.price-updates-options__success-message {
color: #fff;
background-color: #19a917;
}
.price-updates-options__error-message {
color: #fff;
background-color: #fa0505;
}

View File

@@ -0,0 +1,181 @@
.hidden {
display: none !important;
}
.price-updates-wrapper {
margin-right: 20px;
padding: 12px;
position: relative;
font-size: 16px;
}
.price-updates-wrapper input,
.price-updates-wrapper label,
.price-updates-wrapper button {
font-size: 16px;
}
.price-updates-variations {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 8px;
margin-bottom: 18px;
}
.price-updates-contents {
margin-bottom: 12px;
}
.price-updates-contents form {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 12px;
}
.price-updates-contents input {
height: 30px;
}
.price-updates-contents input[type="url"] {
width: 600px;
}
.price-updates-contents button {
width: 200px;
padding: 12px 16px;
text-align: center;
border-radius: 20px;
border: none;
color: #fff;
background: radial-gradient(278.91% 196.13% at 128.36% -48.29%, #ee6868 0%, #569ef0 57.69%);
cursor: pointer;
transition: filter 0.3s ease;
}
.price-updates-contents button:hover {
filter: brightness(0.9);
}
.price-updates-caption {
display: block;
margin-bottom: 12px;
font-size: 14px;
}
.price-updates-count {
display: flex;
gap: 12px;
margin-bottom: 12px;
}
.price-updates-count-success span {
color: #19a917;
}
.price-updates-count-error span {
color: #fa0505;
}
.price-updates-response {
width: 100%;
max-height: 800px;
overflow-y: auto;
margin-bottom: 12px;
}
.price-updates-response table {
width: 100%;
}
.price-updates-response thead th {
position: sticky;
top: 0;
padding-block: 12px;
background-color: #f0f0f1;
}
.price-updates-response tbody td {
text-align: center;
padding-block: 12px;
}
.price-updates-error {
width: max-content;
padding: 16px 20px;
border-radius: 8px;
color: #fff;
background-color: #fa0505;
}
.price-updates-loader-wrapper {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
position: absolute;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.25);
}
.price-updates-loader {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
max-width: 6rem;
margin-top: 3rem;
margin-bottom: 3rem;
}
.price-updates-loader:before,
.price-updates-loader:after {
content: "";
position: absolute;
border-radius: 50%;
animation: pulsOut 1.8s ease-in-out infinite;
filter: drop-shadow(0 0 1rem rgba(255, 255, 255, 0.75));
}
.price-updates-loader:before {
width: 100%;
padding-bottom: 100%;
box-shadow: inset 0 0 0 1rem #fff;
animation-name: pulsIn;
}
.price-updates-loader:after {
width: calc(100% - 2rem);
padding-bottom: calc(100% - 2rem);
box-shadow: 0 0 0 0 #fff;
}
@keyframes pulsIn {
0% {
box-shadow: inset 0 0 0 1rem #fff;
opacity: 1;
}
50%, 100% {
box-shadow: inset 0 0 0 0 #fff;
opacity: 0;
}
}
@keyframes pulsOut {
0%, 50% {
box-shadow: 0 0 0 0 #fff;
opacity: 0;
}
100% {
box-shadow: 0 0 0 1rem #fff;
opacity: 1;
}
}

69
assets/js/options-page.js Normal file
View File

@@ -0,0 +1,69 @@
jQuery(document).ready(function ($) {
const $form = $(".price-updates-options__form");
const $loaderWrapper = $(".price-updates-loader-wrapper");
const $success = $(".price-updates-options__success-message");
const $error = $(".price-updates-options__error-message");
function hideMessages() {
$success.addClass("hidden");
$error.addClass("hidden")
}
// [Событие] Сохранение настроек
$form.on("submit", function (e) {
e.preventDefault();
$loaderWrapper.removeClass("hidden");
$.ajax({
method: "POST",
url: priceUpdatesOptionsSettings.ajaxUrl + "/update",
data: $(this).serializeArray(),
success: function (response) {
hideMessages();
$success.removeClass("hidden");
$success.text("Настройки обновлены.");
},
error: function (error) {
console.error(error)
hideMessages();
$error.removeClass("hidden");
$error.text("Ошибка при обновлении настроек.");
},
complete: function () {
$loaderWrapper.addClass("hidden");
}
})
})
$loaderWrapper.removeClass("hidden");
// [Ajax] Подгружаем настройки
$.ajax({
method: "GET",
url: priceUpdatesOptionsSettings.ajaxUrl + "/get",
success: function (response) {
if (!response) return;
for (const [key, value] of Object.entries(response)) {
const $input = $form.find(`input[name="${key}"]`);
$input.val(JSON.stringify(value).slice(1, -1));
}
},
error: function (error) {
console.error(error);
hideMessages();
$error.removeClass("hidden");
$error.text("Ошибка при загрузке настроек.");
},
complete: function () {
$loaderWrapper.addClass("hidden");
}
})
});

View File

@@ -0,0 +1,205 @@
jQuery(document).ready(function ($) {
const $variantons = $('input[name="price-updates-variant"]');
const $contents = $("form[data-price-updates-variant]");
const $count = $(".price-updates-count");
const $countSuccess = $(".price-updates-count-success");
const $countError = $(".price-updates-count-error");
const $tableWrapper = $(".price-updates-response");
const $error = $(".price-updates-error");
const $loaderWrapper = $(".price-updates-loader-wrapper");
// [Событие] Смена варианита обновления цен
$variantons.on("change", function () {
const $varianton = $(this);
$tableWrapper.find("tbody").html("");
$tableWrapper.addClass("hidden");
updatePriceUpdatesCountSuccess(0);
updatePriceUpdatesCountError(0);
$count.addClass("hidden");
$countSuccess.addClass("hidden");
$countError.addClass("hidden");
$contents.each(function() {
const $content = $(this);
if ($varianton.val() != $content.data("price-updates-variant")) {
$content.addClass("hidden");
} else {
$content.removeClass("hidden");
}
});
});
// Инициализация вариантов обновления цен
$variantons.each(function() {
const $varianton = $(this);
$contents.each(function() {
const $content = $(this);
if (!$varianton.is(":checked") && $varianton.val() == $content.data("price-updates-variant")) {
$content.addClass("hidden");
} else {
$content.removeClass("hidden");
}
});
});
function getCount(response) {
if (!response?.length) {
return 0;
}
let success = 0;
let error = 0;
for (const item of response) {
if (!item?.isError) {
success += 1;
} else {
error += 1;
}
}
return { success, error };
}
function updatePriceUpdatesCountSuccess(count) {
if (typeof count !== "number") return;
$count.removeClass("hidden");
$countSuccess.removeClass("hidden");
$countSuccess.html(`Измененно элементов: <span>${count}</span>`);
}
function updatePriceUpdatesCountError(count) {
if (typeof count !== "number") return;
$count.removeClass("hidden");
$countError.removeClass("hidden");
$countError.html(`Неудалось изменить элементов: <span>${count}</span>`);
}
function getTableRow(data) {
const row = document.createElement("tr");
const tempData = { ...data };
delete tempData.url;
delete tempData.currency;
for (const [key, value] of Object.entries(tempData)) {
const ceil = document.createElement("td");
if (key === "sku") {
const link = document.createElement("a");
link.href = data.url;
link.textContent = value;
ceil.appendChild(link);
} else if (key === "regular" || key === "sale") {
ceil.textContent = value["old"] != value["new"] ? `${value["old"]} ${data.currency} -> ${value["new"]} ${data.currency}` : `${value["new"]} ${data.currency}`;
}
row.appendChild(ceil);
}
return $(row);
}
function getTableRowError(data) {
const row = document.createElement("tr");
const tempData = {
sku: data?.sku,
message: data?.message
};
for (const [key, value] of Object.entries(tempData)) {
const ceil = document.createElement("td");
ceil.textContent = value;
if (key === "message") {
ceil.colSpan = 2;
}
row.appendChild(ceil);
}
return $(row);
}
// [Событие] Отправка формы
$contents.on("submit", function(e) {
e.preventDefault();
$loaderWrapper.removeClass("hidden");
$.ajax({
method: "POST",
url: priceUpdatesSettings.ajaxUrl + "/update",
processData: false,
contentType: false,
data: new FormData(this),
success: function (response) {
$error.addClass("hidden");
$tableWrapper.find("tbody").html("");
if (!response?.length) {
$tableWrapper.addClass("hidden");
updatePriceUpdatesCountSuccess(0);
updatePriceUpdatesCountError(0);
return;
}
const count = getCount(response);
updatePriceUpdatesCountSuccess(count.success);
updatePriceUpdatesCountError(count.error);
$tableWrapper.removeClass("hidden");
for (const item of response) {
let $row = null;
if (!item?.isError) {
$row = getTableRow(item);
} else {
$row = getTableRowError(item);
}
$tableWrapper.find("tbody").append($row);
}
},
error: function (error) {
$tableWrapper.find("tbody").html("");
$tableWrapper.addClass("hidden");
updatePriceUpdatesCountSuccess(0);
updatePriceUpdatesCountError(0);
$count.addClass("hidden");
$countSuccess.addClass("hidden");
$countError.addClass("hidden");
$error.removeClass("hidden");
$error.text(error?.responseJSON?.message || "Неизвестная ошибка");
},
complete: function () {
$loaderWrapper.addClass("hidden");
}
})
})
});