web-next: migrar toda la UI al tema real nw-ryu
Reescritura completa del frontend Next.js del sistema visual Tailwind "simulado" al tema Django original (nw-ryu), para paridad pixel con la web actual antes del cutover. - Tema real: copia de static/nw-themes/nw-ryu + favicons a public/, el layout carga el novavow-style.css real de ultimo (gana la cascada sobre Tailwind) + Font Awesome. - Shell replicando los partials Django: SiteHeader, Video, Social, Footer, ServerClock; home con estructura real (main-page/middle-content/...). - Helpers reutilizables: PageShell (main-page > middle-content > body-content > title-content) y ServiceBox (title-box-content + back-to-account). - Paginas migradas a clases reales del tema (fieldset/tool-button/char-box/ item-box/info-box-light/max-center-table/alert-message/botones reales), eliminando el markup Tailwind (.nw-btn/.nw-card/.nw-input): auth (login/register/recover/reset/select-account/activate), cuenta + servicios de personaje (revive/unstuck/rename/customize/ change-race/change-faction/level-up/gold/transfer + pago Stripe), ajustes (change-password/change-email/security-token), comunidad (vote-points/recruit/battlepay), foro completo, y admin (indice + 7 secciones + los Admin*Manager). - Se conserva el bilingue (next-intl); claves nuevas en messages/es|en.json. Verificado: typecheck + build OK; rutas protegidas 307->login; sin MISSING_MESSAGE; cero Tailwind residual (solo .nw-tool-btn/.nw-page, clases propias en globals.css). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
$(document).ready(function(){$("#account-settings").click(function(){$("#account-settings-panel").slideToggle("slow");$(".fa-arrow-down-account").toggleClass('rotate');$(".fa-arrow-down-account").toggleClass('rotate2');});$("#character-settings").click(function(){$("#character-settings-panel").slideToggle("slow");$(".fa-arrow-down-character").toggleClass('rotate');$(".fa-arrow-down-character").toggleClass('rotate2');});$("#account-history").click(function(){$("#account-history-panel").slideToggle("slow");$(".fa-arrow-down-history").toggleClass('rotate');$(".fa-arrow-down-history").toggleClass('rotate2');});});
|
||||
@@ -0,0 +1,59 @@
|
||||
if (window.history.replaceState) {
|
||||
window.history.replaceState(null, null, window.location.href);
|
||||
};
|
||||
|
||||
$(function(){
|
||||
$('.promo-code').on("cut copy paste",function(e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
});
|
||||
|
||||
$(function(){
|
||||
$('.promo-code-button').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
$("#promo-code-response").empty();
|
||||
|
||||
var button = $(this);
|
||||
var buttonoriginal = button.html();
|
||||
var bValue = button.data('id');
|
||||
var data = {promocode: bValue};
|
||||
data = $("#uw-promo-code-form").serialize() + '&' + $.param(data);
|
||||
|
||||
changeButton(button, 'Canjeando código');
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '',
|
||||
data: data,
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
$("#promo-code-response").append(data.message).hide().slideDown();
|
||||
|
||||
if (data.success === true) {
|
||||
button.html("Código aceptado");
|
||||
button.css("color","#d79602");
|
||||
setTimeout(function() {
|
||||
$("#uw-promo-code-form")[0].reset();
|
||||
restoreButton(button, buttonoriginal);
|
||||
}, 5000);
|
||||
}
|
||||
else {
|
||||
setTimeout(function() {
|
||||
$("#promo-code-response").slideUp( function() {
|
||||
$("#promo-code-response").empty();
|
||||
restoreButton(button, buttonoriginal);
|
||||
grecaptcha.reset();
|
||||
});
|
||||
}, 5000);
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
setTimeout(function() {
|
||||
alert("Algo ha salido mal. Por favor intente más tarde");
|
||||
window.location.reload();
|
||||
}, 2000);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,62 @@
|
||||
$(function() {
|
||||
if (window.history.replaceState) {
|
||||
window.history.replaceState(null, null, window.location.href);
|
||||
}
|
||||
|
||||
$('.reward-form').on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
const form = $(this);
|
||||
const button = form.find('button[type="submit"]');
|
||||
const originalButtonText = button.html();
|
||||
const recruitResponse = $("#recruit-response");
|
||||
const rewardRow = form.closest('tr');
|
||||
const rewardsCounter = $("#claimed-rewards-counter");
|
||||
|
||||
// Serializar datos del formulario
|
||||
const data = form.serialize();
|
||||
|
||||
changeButton(button, 'Reclamando...');
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '',
|
||||
data: data,
|
||||
dataType: 'json',
|
||||
success: function(response) {
|
||||
recruitResponse.hide().empty();
|
||||
|
||||
if (response.success) {
|
||||
recruitResponse.html(`<span class="ok-form-response">${response.message}</span>`).slideDown();
|
||||
|
||||
// Actualizar la fila y deshabilitar el formulario
|
||||
rewardRow.find('.reward-action').html(`<span class="ok-form-response">${response.message}</span>`);
|
||||
|
||||
// Actualizar el contador de recompensas
|
||||
if (response.claimed_count !== undefined) {
|
||||
rewardsCounter.text(`${response.claimed_count}/6`);
|
||||
}
|
||||
} else {
|
||||
recruitResponse.html(`<span class="red-form-response">${response.message}</span>`).slideDown();
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
restoreButton(button, originalButtonText);
|
||||
}, 3000);
|
||||
},
|
||||
error: function() {
|
||||
recruitResponse.html('<span class="red-form-response">Error en el servidor. Inténtalo de nuevo más tarde.</span>').slideDown();
|
||||
restoreButton(button, originalButtonText);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function changeButton(button, text) {
|
||||
button.html(text);
|
||||
button.prop("disabled", true);
|
||||
}
|
||||
|
||||
function restoreButton(button, originalText) {
|
||||
button.html(originalText);
|
||||
button.prop("disabled", false);
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
if (window.history.replaceState) {
|
||||
window.history.replaceState(null, null, window.location.href);
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
// Mostrar mensaje de cancelación si está presente en el backend
|
||||
const cancelMessage = $("#rename-response").data("cancel-message");
|
||||
if (cancelMessage) {
|
||||
$("#rename-response").html(cancelMessage).hide().slideDown();
|
||||
}
|
||||
|
||||
// Manejar clics en el botón de renombrar
|
||||
$('.rename-button').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
$("#rename-response").empty();
|
||||
|
||||
const button = $(this);
|
||||
const originalText = button.html();
|
||||
const data = $("#nw-rename-form").serialize();
|
||||
|
||||
// Confirmar antes de proceder con el pago
|
||||
const conf = confirm("¿Estás seguro de renombrar al personaje seleccionado?");
|
||||
if (!conf) return;
|
||||
|
||||
// Cambiar texto del botón mientras procesa
|
||||
changeButton(button, 'Procesando pago...');
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '', // URL para manejar el POST
|
||||
data: data,
|
||||
dataType: 'json',
|
||||
success: function (response) {
|
||||
if (response.success) {
|
||||
// Verificar que Stripe está cargado
|
||||
if (typeof Stripe === 'undefined') {
|
||||
console.error("Stripe.js no está cargado.");
|
||||
$("#rename-response").append('<span class="red-form-response">Error al cargar Stripe. Intente nuevamente más tarde.</span>').hide().slideDown();
|
||||
restoreButton(button, originalText);
|
||||
return;
|
||||
}
|
||||
|
||||
// Redirigir a Stripe Checkout
|
||||
const stripe = Stripe(response.stripe_public_key);
|
||||
stripe.redirectToCheckout({ sessionId: response.session_id }).then(function (result) {
|
||||
if (result.error) {
|
||||
$("#rename-response").append('<span class="red-form-response">' + result.error.message + '</span>').hide().slideDown();
|
||||
restoreButton(button, originalText);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Mostrar mensaje de error del backend
|
||||
$("#rename-response").append(response.message).hide().slideDown();
|
||||
restoreButton(button, originalText);
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
$("#rename-response").append('<span class="red-form-response">Error inesperado. Por favor, intente más tarde.</span>').hide().slideDown();
|
||||
restoreButton(button, originalText);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Función para cambiar el texto del botón y desactivarlo
|
||||
function changeButton(button, text) {
|
||||
button.html(text);
|
||||
button.prop("disabled", true);
|
||||
}
|
||||
|
||||
// Función para restaurar el texto y habilitar el botón
|
||||
function restoreButton(button, originalText) {
|
||||
button.html(originalText);
|
||||
button.prop("disabled", false);
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
$(document).ready(function () {
|
||||
$("#comprar").on("click", async function (e) {
|
||||
e.preventDefault();
|
||||
$("#store-response").empty();
|
||||
|
||||
let button = $(this);
|
||||
let originalText = button.html();
|
||||
button.html("Procesando pago...");
|
||||
button.prop("disabled", true);
|
||||
|
||||
let personaje = $("#personaje").val();
|
||||
if (!personaje) {
|
||||
$("#store-response").append('<span class="red-form-response">Selecciona un personaje antes de comprar.</span>').hide().slideDown();
|
||||
button.html(originalText);
|
||||
button.prop("disabled", false);
|
||||
return;
|
||||
}
|
||||
|
||||
let carrito = [];
|
||||
$("#carrito li").each(function () {
|
||||
let itemData = $(this).data("item");
|
||||
carrito.push({
|
||||
item_id: itemData.item_id,
|
||||
name: itemData.name,
|
||||
price: itemData.price
|
||||
});
|
||||
});
|
||||
|
||||
if (carrito.length === 0) {
|
||||
$("#store-response").append('<span class="red-form-response">El carrito está vacío.</span>').hide().slideDown();
|
||||
button.html(originalText);
|
||||
button.prop("disabled", false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Realizar la solicitud para crear la sesión de pago en el backend
|
||||
try {
|
||||
const response = await fetch("{% url 'create_checkout_session' %}", {
|
||||
method: "POST",
|
||||
body: new URLSearchParams({
|
||||
personaje: personaje,
|
||||
carrito: JSON.stringify(carrito)
|
||||
})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
if (data.success) {
|
||||
window.location.href = data.stripe_url; // Redirigir a la página de pago de Stripe
|
||||
} else {
|
||||
$("#store-response").append(`<span class="red-form-response">${data.message}</span>`).hide().slideDown();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error al procesar el pago:", error);
|
||||
$("#store-response").append('<span class="red-form-response">Error al procesar el pago.</span>').hide().slideDown();
|
||||
}
|
||||
|
||||
button.html(originalText);
|
||||
button.prop("disabled", false);
|
||||
});
|
||||
});
|
||||
$("#categoria").on("change", function () {
|
||||
let categoriaSeleccionada = $(this).val();
|
||||
if (categoriaSeleccionada) {
|
||||
$.ajax({
|
||||
url: "{% url 'get_items_by_category' %}",
|
||||
method: "GET",
|
||||
data: { category: categoriaSeleccionada },
|
||||
success: function (data) {
|
||||
$("#items-container").empty();
|
||||
if (data.items.length > 0) {
|
||||
data.items.forEach(function (item) {
|
||||
let itemHtml = `
|
||||
<div class="item">
|
||||
<img src="${item.image_url}" alt="${item.name}" />
|
||||
<h4>${item.name}</h4>
|
||||
<p>Price: ${item.price} EUR</p>
|
||||
<button class="add-to-cart" data-item-id="${item.item_id}">Add to Cart</button>
|
||||
</div>
|
||||
`;
|
||||
$("#items-container").append(itemHtml);
|
||||
});
|
||||
} else {
|
||||
$("#items-container").append('<p>No items found in this category.</p>');
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
alert("Error loading items.");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
$(document).ready(function() {
|
||||
$('.add-to-cart').on('click', function() {
|
||||
var itemId = $(this).data('item-id');
|
||||
$.post('/store/add_to_cart/', {item_id: itemId}, function(response) {
|
||||
alert(response.message);
|
||||
location.reload();
|
||||
});
|
||||
});
|
||||
|
||||
$('.remove-from-cart').on('click', function() {
|
||||
var cartId = $(this).data('cart-id');
|
||||
$.post('/store/remove_from_cart/', {cart_id: cartId}, function(response) {
|
||||
alert(response.message);
|
||||
location.reload();
|
||||
});
|
||||
});
|
||||
|
||||
$('#checkout-button').on('click', function() {
|
||||
$.post('/store/checkout/', {}, function(response) {
|
||||
if (response.success) {
|
||||
var stripe = Stripe(response.stripe_public_key);
|
||||
stripe.redirectToCheckout({ sessionId: response.session_id });
|
||||
} else {
|
||||
alert(response.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
if(window.history.replaceState){window.history.replaceState(null,null,window.location.href);};$(function(){$('select').on('change',function(){var select=$(this);select.css('color',select.children('option:selected').css('color'));});});$(function(){$('#trade-sell-a').on('click',function(){$('#trade-sell-div').fadeIn('slow');$('#trade-buy-div').hide();});$('#trade-buy-a').on('click',function(){$('#trade-buy-div').fadeIn('slow');$('#trade-sell-div').hide();});});$(function(){$(".toggle-password").click(function(){$(this).toggleClass("fa-eye fa-eye-slash");var type=$(this).hasClass("fa-eye-slash")?"text":"password";$("#password-sell").attr("type",type);});});$(function(){$(".toggle-password").click(function(){$(this).toggleClass("fa-eye fa-eye-slash");var type=$(this).hasClass("fa-eye-slash")?"text":"password";$("#password-buy").attr("type",type);});});$(function(){$(".toggle-token").click(function(){$(this).toggleClass("fa-eye fa-eye-slash");var type=$(this).hasClass("fa-eye-slash")?"text":"password";$("#security-token-sell").attr("type",type);});});$(function(){$(".toggle-token").click(function(){$(this).toggleClass("fa-eye fa-eye-slash");var type=$(this).hasClass("fa-eye-slash")?"text":"password";$("#security-token-buy").attr("type",type);});});$(function(){$('.trade-points-sell-button').on('click',function(e){e.preventDefault();e.stopPropagation();$("#trade-points-sell-response").empty();var button=$(this);var buttonoriginal=button.html();var data={tradepointssell:button.data('id')};data=$("#nw-trade-points-sell-form").serialize()+'&'+$.param(data);changeButton(button,'CREANDO CÓDIGO');$.ajax({type:'POST',url:'',data:data,dataType:'json',success:function(data){$("#trade-points-sell-response").append(data.message).hide().slideDown();if(data.success===true){button.html("CÓDIGO CREADO");button.css("color","#d79602");setTimeout(function(){$("#nw-trade-points-sell-form")[0].reset();restoreButton(button,buttonoriginal);grecaptcha.reset(0);},5000);}
|
||||
else{setTimeout(function(){$("#trade-points-sell-response").slideUp(function(){$("#trade-points-sell-response").empty();restoreButton(button,buttonoriginal);grecaptcha.reset(0);});},5000);}},error:function(){setTimeout(function(){alert("Algo ha salido mal. Por favor intente más tarde");window.location.reload();},2000);}});});});$(function(){$('.trade-points-buy-button').on('click',function(e){e.preventDefault();e.stopPropagation();$("#trade-points-buy-response").empty();$(".trade-points-check-button").prop('disabled',true);var button=$(this);var buttonoriginal=button.html();var data={tradepointsbuy:button.data('id')};data=$("#nw-trade-points-buy-form").serialize()+'&'+$.param(data);changeButton(button,'CANJEANDO CÓDIGO');$.ajax({type:'POST',url:'',data:data,dataType:'json',success:function(data){$("#trade-points-buy-response").append(data.message).hide().slideDown();if(data.success===true){button.html("CÓDIGO CANJEADO");button.css("color","#d79602");setTimeout(function(){$("#nw-trade-points-buy-form")[0].reset();$(".trade-points-check-button").prop('disabled',false);restoreButton(button,buttonoriginal);grecaptcha.reset(1);},5000);}
|
||||
else{setTimeout(function(){$("#trade-points-buy-response").slideUp(function(){$("#trade-points-buy-response").empty();$(".trade-points-check-button").prop('disabled',false);restoreButton(button,buttonoriginal);grecaptcha.reset(1);});},5000);}},error:function(){setTimeout(function(){alert("Algo ha salido mal. Por favor intente más tarde");window.location.reload();},2000);}});});});$(function(){$('.trade-points-check-button').on('click',function(e){e.preventDefault();e.stopPropagation();$("#trade-points-buy-response").empty();$(".trade-points-buy-button").prop('disabled',true);var button=$(this);var buttonoriginal=button.html();var data={tradepointscheck:button.data('id')};data=$("#nw-trade-points-buy-form").serialize()+'&'+$.param(data);changeButton(button,'CHEQUEANDO CÓDIGO');$.ajax({type:'POST',url:'',data:data,dataType:'json',success:function(data){$("#trade-points-buy-response").append(data.message).hide().slideDown();if(data.success===true){button.html("INFO DEL CÓDIGO");button.css("color","#d79602");setTimeout(function(){$(".trade-points-buy-button").prop('disabled',false);restoreButton(button,buttonoriginal);grecaptcha.reset(1);},5000);}
|
||||
else{setTimeout(function(){$("#trade-points-buy-response").slideUp(function(){$("#trade-points-buy-response").empty();$(".trade-points-buy-button").prop('disabled',false);restoreButton(button,buttonoriginal);grecaptcha.reset(1);});},5000);}},error:function(){setTimeout(function(){alert("Algo ha salido mal. Por favor intente más tarde");window.location.reload();},2000);}});});});
|
||||
Reference in New Issue
Block a user