|
|
@@ -8,7 +8,7 @@
|
|
|
@using LotteryWebApp.Common;
|
|
|
|
|
|
@section Styles {
|
|
|
- <link rel="stylesheet" href="/Millions/css/buy-ticket.css" />
|
|
|
+ <link rel="stylesheet" href="/Millions/css/buy-ticket.css" asp-append-version="true" />
|
|
|
<style>
|
|
|
/* BuyTicket has its own bottom bar; avoid global navbar padding gap */
|
|
|
body.millions-bg { padding-bottom: 0 !important; }
|
|
|
@@ -39,7 +39,7 @@
|
|
|
<div class="flex items-center justify-between">
|
|
|
<div class="flex items-center gap-2 border border-[#E5E7EB] rounded-lg px-3 py-1.5 bg-gray-50">
|
|
|
<i class="fa-regular fa-calendar text-[[@themeColor]] text-sm" style="color: @themeColor"></i>
|
|
|
- <span class="text-[12px] font-bold text-gray-700">@DateTime.Now.ToString("dddd, MMM dd, yyyy", System.Globalization.CultureInfo.CurrentCulture)</span>
|
|
|
+ <span class="text-[12px] font-bold text-gray-700">@DateTime.Now.ToString("dddd, MMM dd, yyyy", new System.Globalization.CultureInfo("en-US"))</span>
|
|
|
</div>
|
|
|
<div class="flex items-center gap-1 ml-4 flex-1 justify-end">
|
|
|
<span class="text-[12px] font-bold text-gray-400">@Lang.millions_round</span>
|
|
|
@@ -61,7 +61,7 @@
|
|
|
var dateStr = "--";
|
|
|
DateTime dt;
|
|
|
if (DateTime.TryParse(term.date_random, out dt)) {
|
|
|
- dateStr = dt.ToString("MMM dd", System.Globalization.CultureInfo.CurrentCulture);
|
|
|
+ dateStr = dt.ToString("MMM dd", new System.Globalization.CultureInfo("en-US"));
|
|
|
}
|
|
|
|
|
|
var resKey = rawResult;
|
|
|
@@ -228,7 +228,7 @@ else
|
|
|
<div class="flex items-center justify-between">
|
|
|
<div class="flex items-center gap-2 border border-[#E5E7EB] rounded-lg px-3 py-1.5 bg-gray-50">
|
|
|
<i class="fa-regular fa-calendar text-[#0062FF] text-sm"></i>
|
|
|
- <span class="text-[12px] font-bold text-gray-700">@DateTime.Now.ToString("dddd, MMM dd, yyyy", System.Globalization.CultureInfo.CurrentCulture)</span>
|
|
|
+ <span class="text-[12px] font-bold text-gray-700">@DateTime.Now.ToString("dddd, MMM dd, yyyy", new System.Globalization.CultureInfo("en-US"))</span>
|
|
|
</div>
|
|
|
<div class="flex items-center gap-1 ml-4 flex-1 justify-end">
|
|
|
<span class="text-[12px] font-bold text-gray-400">@Lang.millions_round</span>
|
|
|
@@ -252,9 +252,10 @@ else
|
|
|
<div class="grid grid-cols-6 gap-y-2 gap-x-1 flex-1">
|
|
|
@for (int j = 0; j < (Model.termType == Constants.PIC10_BASIC_CODE ? 10 : (Model.termType == Constants.Millions_CODE ? 6 : 15)); j++)
|
|
|
{
|
|
|
+ var isMbBall = Model.termType == Constants.Millions_CODE && j == 5;
|
|
|
<div class="relative w-fit">
|
|
|
- <div class="ball-circle ball-empty"></div>
|
|
|
- @if (Model.termType == Constants.Millions_CODE && j == 5)
|
|
|
+ <div class="ball-circle ball-empty@(isMbBall ? " ball-mb-circle" : "")"></div>
|
|
|
+ @if (isMbBall)
|
|
|
{
|
|
|
<div class="absolute -bottom-[6px] -right-[4px] bg-[#FFD700] text-black text-[8.5px] font-black px-[2.5px] py-[1.5px] rounded-[3px] shadow-sm leading-none z-10 border border-[#EAA800]">MB</div>
|
|
|
}
|
|
|
@@ -348,7 +349,7 @@ else
|
|
|
<div class="space-y-1">
|
|
|
<span class="text-[11px] font-black text-[#0062FF] block text-center uppercase tracking-tight">@Lang.date_purchase</span>
|
|
|
<div class="bg-white border border-gray-100 rounded-xl py-2.5 px-2 text-center font-black text-[11px] text-gray-700 shadow-sm">
|
|
|
- @DateTime.Now.ToString("dddd MMM dd, yyyy", System.Globalization.CultureInfo.CurrentCulture)
|
|
|
+ @DateTime.Now.ToString("dddd MMM dd, yyyy", new System.Globalization.CultureInfo("en-US"))
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="space-y-1">
|
|
|
@@ -358,7 +359,7 @@ else
|
|
|
DateTime drawDate;
|
|
|
bool isValidDate = DateTime.TryParse(currentTerm?.date_end, out drawDate);
|
|
|
if (isValidDate) {
|
|
|
- @drawDate.ToString("dddd MMM dd, yyyy", System.Globalization.CultureInfo.CurrentCulture)
|
|
|
+ @drawDate.ToString("dddd MMM dd, yyyy", new System.Globalization.CultureInfo("en-US"))
|
|
|
} else {
|
|
|
@:N/A
|
|
|
}
|
|
|
@@ -608,9 +609,13 @@ else
|
|
|
updateSelectionCount();
|
|
|
liveUpdateTicket();
|
|
|
|
|
|
- // Focus card
|
|
|
+ // Focus card: append a tall spacer so even the last ticket can scroll up
|
|
|
+ // above the number-picker sheet (a flex column container does not honor
|
|
|
+ // padding-bottom as scrollable space), then bring the card to the top.
|
|
|
if (activeTicketCard && activeTicketCard.length) {
|
|
|
var container = $("#ticketContainer");
|
|
|
+ $("#editScrollSpacer").remove();
|
|
|
+ container.append('<div id="editScrollSpacer" aria-hidden="true" style="height:100vh;flex-shrink:0;"></div>');
|
|
|
var scrollPos = activeTicketCard.offset().top - container.offset().top + container.scrollTop();
|
|
|
container.stop().animate({ scrollTop: scrollPos - 15 }, 500);
|
|
|
}
|
|
|
@@ -886,6 +891,8 @@ else
|
|
|
modal.find('.modal-content').removeClass('animate__zoomIn').addClass('animate__zoomOut');
|
|
|
setTimeout(() => {
|
|
|
modal.removeClass('flex').addClass('hidden');
|
|
|
+ // Remove the temporary scroll spacer
|
|
|
+ $("#editScrollSpacer").remove();
|
|
|
// Reset state
|
|
|
activeBall = null;
|
|
|
activeTicketCard = null;
|
|
|
@@ -912,8 +919,9 @@ else
|
|
|
var ballsHtml = '';
|
|
|
var isMillions = @(Model.termType == Constants.Millions_CODE ? "true" : "false");
|
|
|
for (var i = 0; i < maxBalls; i++) {
|
|
|
- var mbIndicator = (isMillions && i === 5) ? '<div class="absolute -bottom-[6px] -right-[4px] bg-[#FFD700] text-black text-[8.5px] font-black px-[2.5px] py-[1.5px] rounded-[3px] shadow-sm leading-none z-10 border border-[#EAA800]">MB</div>' : '';
|
|
|
- ballsHtml += '<div class="relative w-fit"><div class="ball-circle ball-empty"></div>' + mbIndicator + '</div>';
|
|
|
+ var isMbBall = isMillions && i === 5;
|
|
|
+ var mbIndicator = isMbBall ? '<div class="absolute -bottom-[6px] -right-[4px] bg-[#FFD700] text-black text-[8.5px] font-black px-[2.5px] py-[1.5px] rounded-[3px] shadow-sm leading-none z-10 border border-[#EAA800]">MB</div>' : '';
|
|
|
+ ballsHtml += '<div class="relative w-fit"><div class="ball-circle ball-empty' + (isMbBall ? ' ball-mb-circle' : '') + '"></div>' + mbIndicator + '</div>';
|
|
|
}
|
|
|
|
|
|
var ticketHtml = `
|
|
|
@@ -1054,11 +1062,17 @@ else
|
|
|
let contentHtml = '';
|
|
|
|
|
|
if (numbers.length > 1) {
|
|
|
+ const isMillionsGame = "@Model.termType" === "@Constants.Millions_CODE";
|
|
|
let numbersBalls = '';
|
|
|
- numbers.forEach(n => {
|
|
|
- numbersBalls += `<div class="w-7 h-7 rounded-full flex items-center justify-center text-white text-[11px] font-black shadow-[0_4px_10px_rgba(186,15,33,0.3)]" style="background: linear-gradient(135deg, #FF3D63 0%, #E3132D 60%, #BA0F21 100%); border: 1px solid rgba(255, 255, 255, 0.3); text-shadow: 0px 1px 2px rgba(0,0,0,0.1); transition: transform 0.2s;">${n.trim()}</div>`;
|
|
|
+ numbers.forEach((n, ni) => {
|
|
|
+ var isMbBall = isMillionsGame && ni === numbers.length - 1;
|
|
|
+ var ballBg = isMbBall
|
|
|
+ ? 'background: radial-gradient(circle at 50% 50%, #0062ff 0%, #0062ff 60%, #0149f0 75%, #0231e0 85%, #0218d1 92%, #0300c2 100%); box-shadow: inset 0 0 6px 2px rgba(0,24,209,0.5), 0 4px 10px rgba(2,24,209,0.3);'
|
|
|
+ : 'background: linear-gradient(135deg, #FF3D63 0%, #E3132D 60%, #BA0F21 100%); box-shadow: 0 4px 10px rgba(186,15,33,0.3);';
|
|
|
+ numbersBalls += `<div class="w-7 h-7 rounded-full flex items-center justify-center text-white text-[11px] font-black" style="${ballBg} border: 1px solid rgba(255, 255, 255, 0.3); text-shadow: 0px 1px 2px rgba(0,0,0,0.1); transition: transform 0.2s;">${n.trim()}</div>`;
|
|
|
});
|
|
|
- contentHtml = `<div class="grid grid-cols-5 gap-y-2 relative z-10 px-2 justify-items-center">${numbersBalls}</div>`;
|
|
|
+ var summaryGridCols = isMillionsGame ? 'grid-cols-6' : 'grid-cols-5';
|
|
|
+ contentHtml = `<div class="grid ${summaryGridCols} gap-y-2 gap-x-1 relative z-10 px-1 justify-items-center">${numbersBalls}</div>`;
|
|
|
} else {
|
|
|
const isBS = @(Model.termType == Constants.PIC10_BIGSMALL_CODE ? "true" : "false");
|
|
|
const isFirstChoice = (numbers[0] === 'B' || numbers[0] === 'O');
|
|
|
@@ -1428,14 +1442,14 @@ else
|
|
|
<!-- Number Picker Modal (Refined Bottom Sheet) -->
|
|
|
<div id="numberPickerModal" class="fixed inset-0 bg-black/10 z-[200] hidden items-end justify-center p-0 transition-all">
|
|
|
<div class="modal-content bg-white w-full md:max-w-[414px] mx-auto shadow-2xl animate__animated animate__slideInUp animate__faster rounded-t-[20px] overflow-hidden">
|
|
|
- <div class="px-4 py-3 bg-[#0062FF] text-white flex justify-between items-center relative">
|
|
|
+ <div class="px-4 py-1.5 bg-[#0062FF] text-white flex justify-between items-center relative">
|
|
|
<div class="flex flex-col">
|
|
|
<h3 class="font-black text-[15px] uppercase tracking-wide" id="modalTitle">@Lang.Pick_Number</h3>
|
|
|
<div class="selection-count-area">
|
|
|
<span class="text-[10px] font-bold text-white/80 uppercase">Selected: <span id="selectionCount" class="text-white">0</span>/<span id="maxSelectionCount">10</span></span>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <button onclick="closeNumberPicker()" class="w-9 h-9 flex items-center justify-center rounded-full bg-white/10 hover:bg-white/20 transition-all">
|
|
|
+ <button onclick="closeNumberPicker()" class="w-8 h-8 flex items-center justify-center rounded-full bg-white/10 hover:bg-white/20 transition-all">
|
|
|
<i class="fa-solid fa-xmark text-lg"></i>
|
|
|
</button>
|
|
|
</div>
|