| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- @model LotteryWebApp.Models.TermResultHistoryModel
- @{
- ViewData["Title"] = "Millions - Results History";
- Layout = "~/Areas/Millions/Views/Shared/_Layout.cshtml";
- ViewData["ActiveTab"] = "Results";
- // Default to last 3 days if not specified
- if (string.IsNullOrEmpty(Model.fromDate)) {
- Model.fromDate = DateTime.Now.AddDays(-2).ToString("yyyy-MM-dd");
- }
- if (string.IsNullOrEmpty(Model.toDate)) {
- Model.toDate = DateTime.Now.ToString("yyyy-MM-dd");
- }
- }
- @using LotteryWebApp.Languages;
- @using LotteryWebApp.Common;
- @section Styles {
- <script src="https://cdn.tailwindcss.com"></script>
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
- <!-- Flatpickr for premium calendar -->
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
- <script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
- <link rel="stylesheet" href="/Millions/css/site.css" />
- <link rel="stylesheet" href="/Millions/css/results.css" />
- }
- <div class="main-container results-container animate__animated animate__fadeIn pb-40 relative mx-auto max-w-[414px] shadow-2xl min-h-screen bg-white">
- <!-- Header Group: Sticky at Top -->
- <div class="sticky top-0 w-full z-[100] bg-[#F3F4F6] pb-2 shadow-md">
- <!-- Header: Matches Figma (Right Image) -->
- <div class="results-top-header">
- <a href="javascript:history.back()" class="back-btn">
- <i class="fas fa-arrow-left"></i>
- </a>
- <h1 class="font-bricolage">@Lang.results</h1>
- </div>
- <!-- Selection Bar: Side-by-side dates and search -->
- <div class="selection-bar bg-white/50 backdrop-blur-sm px-4 pt-2 pb-2">
- <div class="flex gap-3">
- <div class="date-pick-input flex-1 cursor-pointer relative bg-white border border-gray-200 rounded-lg p-2 flex items-center gap-2">
- <img src="/Millions/img/icon_calendar.svg" class="w-5 h-5" />
- <input type="text" id="fromDate" value="@Model.fromDate" class="bg-transparent border-none outline-none font-bold text-[13px] w-full ml-1 cursor-pointer" readonly />
- <i class="fas fa-caret-down text-gray-400"></i>
- </div>
- <div class="date-pick-input flex-1 cursor-pointer relative bg-white border border-gray-200 rounded-lg p-2 flex items-center gap-2">
- <img src="/Millions/img/icon_calendar.svg" class="w-5 h-5" />
- <input type="text" id="toDate" value="@Model.toDate" class="bg-transparent border-none outline-none font-bold text-[13px] w-full ml-1 cursor-pointer" readonly />
- <i class="fas fa-caret-down text-gray-400"></i>
- </div>
- <button id="btnSearch" class="btn-search-red !w-12 !h-12 flex items-center justify-center bg-[#0062FF] text-white rounded-xl shadow-md" onclick="triggerSearch()">
- <i class="fas fa-search"></i>
- </button>
- </div>
- </div>
- <!-- Red Separator Line -->
- <div class="px-4 mt-1">
- <div class="h-[2px] bg-gradient-to-r from-transparent via-[#0062FF] to-transparent rounded-full opacity-40"></div>
- </div>
- </div>
- <!-- Result List Container -->
- <div id="results-list-container" class="results-items-list px-4 min-h-[300px]">
- <!-- Content will be loaded via JS for all 3 games -->
- <div class="flex flex-col items-center justify-center py-20 text-gray-400">
- <i class="fas fa-circle-notch fa-spin text-3xl mb-2"></i>
- <span>Loading results...</span>
- </div>
- </div>
- <!-- Bottom Promo Bar (Matches Bottom message with yellow text) -->
- <div class="fixed bottom-[82px] left-1/2 -translate-x-1/2 w-full min-[600px]:max-w-[414px] bg-[#0062FF] text-white py-2 text-center text-[12px] font-bold tracking-wide z-40 flex flex-col items-center justify-center overflow-hidden h-auto shadow-md">
- <div class="flex flex-col items-center w-full animate-slide-up">
- <div class="opacity-90">@Lang.have_chance_to_get</div>
- <div class="text-[18px] font-black text-[#FBF3A7] mt-0.5">@Lang.millions_jackpot_today_htg</div>
- </div>
- </div>
- <!-- Shared Bottom Navbar -->
- <div class="fixed bottom-0 left-0 w-full z-50">
- <div class="mx-auto max-w-[414px]">
- <partial name="_BottomNavbar" />
- </div>
- </div>
- <!-- Custom Notification Modal -->
- <div id="notificationModal" class="fixed inset-0 z-[300] flex items-center justify-center hidden px-6 font-bricolage" style="background: linear-gradient(135deg, rgba(26, 26, 46, 0.9) 0%, rgba(22, 33, 62, 0.9) 100%);">
- <div class="w-full max-w-[343px] min-h-[420px] bg-white rounded-[24px] overflow-hidden flex flex-col items-center p-8 animate__animated animate__zoomIn animate__faster shadow-2xl border border-white/50">
- <div class="w-full flex justify-center mb-8 mt-4">
- <img src="/Millions/img/modal/fail_icon.png" class="w-[160px] h-auto object-contain" alt="Notificaton icon" />
- </div>
- <div class="px-2 text-center mb-10 flex-1 flex items-center justify-center">
- <p id="notificationMessage" class="text-black font-[800] text-[20px] leading-snug"></p>
- </div>
- <div class="w-full">
- <button onclick="closeNotificationModal()" class="w-full bg-[#0062FF] text-white font-[800] text-[18px] py-[12px] rounded-[16px] shadow-lg active:scale-95 transition-all">
- @Lang.login
- </button>
- </div>
- </div>
- </div>
- </div>
- @section Scripts {
- <script>
- const gameConfigs = [
- { code: '@Constants.Millions_CODE', name: 'Millions', color: '#0062FF' }
- ];
- function initBrandedFlatpickr(selector, yearStart, yearEnd) {
- const inputEl = document.querySelector(selector);
- const wrapper = inputEl.closest('.date-pick-input');
-
- flatpickr(selector, {
- dateFormat: "Y-m-d",
- altInput: true,
- altFormat: "M d, Y",
- altInputClass: "bg-transparent border-none outline-none font-bold text-[13px] w-full ml-1 cursor-pointer",
- disableMobile: true,
- monthSelectorType: "dropdown",
- appendTo: wrapper,
- onReady: function (selectedDates, dateStr, instance) {
- instance.calendarContainer.style.zIndex = "9999";
- const yearInput = instance.calendarContainer.querySelector(".numInput.cur-year");
- if (yearInput) {
- const yearSelect = document.createElement("select");
- yearSelect.className = "flatpickr-monthDropdown-months cur-year-select";
- yearSelect.style.cssText = "appearance:none; font-weight:800; border:none; background:transparent; color:white; cursor:pointer; margin-left:4px; outline:none; font-family:inherit; font-size:inherit;";
- for (let y = yearEnd; y >= yearStart; y--) {
- const opt = document.createElement("option");
- opt.value = y;
- opt.text = y;
- opt.style.color = "#333";
- if (y === instance.currentYear) opt.selected = true;
- yearSelect.appendChild(opt);
- }
- yearSelect.addEventListener("change", function () {
- instance.changeYear(parseInt(this.value));
- });
- yearInput.style.display = "none";
- yearInput.parentNode.appendChild(yearSelect);
- }
- }
- });
- }
- document.addEventListener('DOMContentLoaded', function() {
- initBrandedFlatpickr("#fromDate", 2020, 2030);
- initBrandedFlatpickr("#toDate", 2020, 2030);
- triggerSearch(); // Initial load for all games
- });
- var systemUpgrading = false;
- function showNotification(message, code) {
- $("#notificationMessage").text(message);
- const $btn = $("#notificationModal button");
- if (code === "-2" || (message && message.includes("System is upgrading"))) {
- systemUpgrading = true;
- $btn.text("@Lang.login");
- } else {
- systemUpgrading = false;
- $btn.text("OK");
- }
- $("#notificationModal").removeClass("hidden").addClass("flex");
- }
- function closeNotificationModal() {
- $("#notificationModal").addClass("hidden").removeClass("flex");
- if (systemUpgrading) {
- window.location.href = subDomain + "/Account/Login";
- }
- }
- async function triggerSearch() {
- const fromDate = document.getElementById("fromDate").value;
- const toDate = document.getElementById("toDate").value;
- const btn = document.getElementById("btnSearch");
- const container = document.getElementById("results-list-container");
- btn.disabled = true;
- btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i>';
- container.style.opacity = "0.7";
- try {
- // Call the new grouped endpoint
- const response = await fetch(`${subDomain}/Millions/Home/TermResultHistoryGrouped?fromDate=${fromDate}&toDate=${toDate}`);
- if (!response.ok) throw new Error('Network response was not ok');
-
- const html = await response.text();
-
- try {
- const json = JSON.parse(html);
- if (json.responseCode === "-2" || (json.responseMessage && json.responseMessage.includes("System is upgrading"))) {
- showNotification(json.responseMessage || "System is upgrading", "-2");
- return;
- }
- } catch (e) {
- // Not JSON, likely HTML partial
- }
- if (html.trim() === "") {
- container.innerHTML = `
- <div class="w-full py-20 flex flex-col items-center justify-center text-gray-400 opacity-60">
- <i class="fas fa-search text-5xl mb-4"></i>
- <p class="font-bold">@Lang.no_results_found</p>
- </div>
- `;
- } else {
- container.innerHTML = html;
- }
- } catch (error) {
- console.error("Error loading grouped results:", error);
-
- // Check if the error response is JSON and has code -2
- if (error.message && (error.message.includes("System is upgrading") || error.message.includes("-2"))) {
- showNotification(error.message, "-2");
- } else {
- container.innerHTML = `<div class="text-center py-10 text-red-500 font-bold">Error loading results. Please try again.</div>`;
- }
- }
- container.style.opacity = "1";
- btn.disabled = false;
- btn.innerHTML = '<i class="fas fa-search"></i>';
- }
- </script>
- }
|