updated code
This commit is contained in:
parent
1b8b39478d
commit
6c7af3ed4b
@ -25,7 +25,7 @@
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
<script type="text/javascript">
|
||||
<!-- <script type="text/javascript">
|
||||
function googleTranslateElementInit() {
|
||||
new google.translate.TranslateElement({
|
||||
pageLanguage: 'en',
|
||||
@ -33,7 +33,21 @@
|
||||
layout: google.translate.TranslateElement.InlineLayout.SIMPLE
|
||||
}, 'google_translate_element');
|
||||
}
|
||||
</script> -->
|
||||
|
||||
<script type="text/javascript">
|
||||
function googleTranslateElementInit() {
|
||||
new google.translate.TranslateElement(
|
||||
{ pageLanguage: 'en', includedLanguages: 'en,hi', layout: google.translate.TranslateElement.InlineLayout.SIMPLE },
|
||||
'google_translate_element'
|
||||
);
|
||||
}
|
||||
</script>
|
||||
<script src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
|
||||
|
||||
|
||||
<script src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
@ -48,7 +62,7 @@
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
<script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
|
||||
<!-- <script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script> -->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
57
src/App.css
57
src/App.css
@ -245,3 +245,60 @@
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* 1. Remove background, borders from the outer Google gadget */
|
||||
.goog-te-gadget {
|
||||
font-family: 'Poppins', sans-serif !important;
|
||||
font-size: 14px !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
/* 2. Customize the translate dropdown box */
|
||||
.goog-te-gadget-simple {
|
||||
background-color: #1f2937 !important; /* dark background */
|
||||
border: 1px solid #4b5563 !important; /* gray border */
|
||||
padding: 8px 12px !important;
|
||||
border-radius: 8px !important;
|
||||
cursor: pointer !important;
|
||||
display: inline-flex !important;
|
||||
align-items: center !important;
|
||||
}
|
||||
|
||||
/* 3. Customize the select language text inside */
|
||||
.goog-te-gadget-simple span {
|
||||
font-size: 14px !important;
|
||||
color: white !important;
|
||||
margin-right: 5px !important;
|
||||
}
|
||||
|
||||
/* 4. Customize hover effect */
|
||||
.goog-te-gadget-simple:hover {
|
||||
background-color: #374151 !important; /* slightly lighter on hover */
|
||||
}
|
||||
|
||||
/* 5. Hide the default Google icon if you want */
|
||||
.goog-te-gadget-icon {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* 6. Adjust the down arrow color */
|
||||
.goog-te-gadget-simple span[aria-hidden="true"] {
|
||||
color: #d1d5db !important; /* light gray arrow */
|
||||
margin-left: 4px !important;
|
||||
}
|
||||
|
||||
/* 7. Prevent weird border inside dropdown */
|
||||
.skiptranslate {
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
border: none !important;
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
/* 8. Remove unwanted clear dots or extra images */
|
||||
.goog-te-gadget img {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
1080
src/App.js
1080
src/App.js
File diff suppressed because it is too large
Load Diff
@ -1,67 +1,16 @@
|
||||
import { useState } from "react";
|
||||
import { Menu, X, Globe } from "lucide-react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
export default function Translate() {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [currentLanguage, setCurrentLanguage] = useState("English");
|
||||
|
||||
// Function to handle language change
|
||||
const changeLanguage = (language) => {
|
||||
setCurrentLanguage(language);
|
||||
|
||||
// This would integrate with Google Translate API
|
||||
// For actual implementation, you would need to use the Google Translate Element
|
||||
if (language === "English") {
|
||||
// Set to English
|
||||
if (window.googleTranslateElementInit) {
|
||||
const selectElement = document.querySelector('.goog-te-combo');
|
||||
if (selectElement) {
|
||||
selectElement.value = 'en';
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
}
|
||||
}
|
||||
} else if (language === "Hindi") {
|
||||
// Set to Hindi
|
||||
if (window.googleTranslateElementInit) {
|
||||
const selectElement = document.querySelector('.goog-te-combo');
|
||||
if (selectElement) {
|
||||
selectElement.value = 'hi';
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Translation Bar */}
|
||||
<div className="bg-gray-800 text-white py-1">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex justify-between items-center">
|
||||
<div className="flex items-center">
|
||||
<Globe size={18} className="mr-2" />
|
||||
<span className="text-sm">Translate:</span>
|
||||
</div>
|
||||
<div className="flex space-x-4">
|
||||
<button
|
||||
onClick={() => changeLanguage("English")}
|
||||
className={`text-sm px-2 py-1 rounded ${currentLanguage === "English" ? "bg-blue-600" : "hover:bg-gray-700"}`}
|
||||
>
|
||||
English
|
||||
</button>
|
||||
<button
|
||||
onClick={() => changeLanguage("Hindi")}
|
||||
className={`text-sm px-2 py-1 rounded ${currentLanguage === "Hindi" ? "bg-blue-600" : "hover:bg-gray-700"}`}
|
||||
>
|
||||
हिन्दी
|
||||
</button>
|
||||
{/* Hidden div for Google Translate Element */}
|
||||
<div id="google_translate_element" className="hidden"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-between items-center bg-gray-800 text-white px-2 mx-auto">
|
||||
{/* Left Side - Text */}
|
||||
<span className="text-sm font-medium">
|
||||
Translate:
|
||||
</span>
|
||||
|
||||
{/* Header */}
|
||||
</>
|
||||
{/* Right Side - Google Translate Original Widget */}
|
||||
<div id="google_translate_element" className="ml-4"></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -1,47 +0,0 @@
|
||||
import React from 'react';
|
||||
import { useState } from 'react';
|
||||
|
||||
const Faq = () => {
|
||||
const [openIndex, setOpenIndex] = useState(null);
|
||||
|
||||
const toggleFAQ = (index) => {
|
||||
setOpenIndex(openIndex === index ? null : index);
|
||||
};
|
||||
|
||||
const faqs = [
|
||||
{ question: "HOW TO PLAY", answer: "Details about how to play." },
|
||||
{ question: "WHERE TO PLAY", answer: "Information on where to play." },
|
||||
{ question: "WINNING NUMBERS EMAIL", answer: "Sign up for emails." },
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-full bg-white text-black ">
|
||||
{/* FAQ Section */}
|
||||
<div className="max-w-6xl p-12">
|
||||
{faqs.map((faq, index) => (
|
||||
<div key={index} className=" m-4">
|
||||
<button
|
||||
className=" bg-red-600 text-white text-lg font-semibold py-3 px-4 flex justify-between items-center rounded-md m-2"
|
||||
onClick={() => toggleFAQ(index)}
|
||||
>
|
||||
{faq.question}
|
||||
<span>{openIndex === index ? "▲" : "▼"}</span>
|
||||
</button>
|
||||
{openIndex === index && (
|
||||
<div className="p-4 bg-gray-100 border border-gray-300">
|
||||
{faq.answer}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Faq;
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
import React from 'react';
|
||||
import Faq from './Faq';
|
||||
const Footer = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-full bg-white text-black">
|
||||
{/* FAQ Section */}
|
||||
<Faq />
|
||||
|
||||
{/* Footer Section */}
|
||||
<footer className="bg-white border-t py-6 text-center">
|
||||
<div className="max-w-3xl mx-auto text-gray-600 text-sm">
|
||||
<p className="font-bold text-xl text-black flex items-center justify-center">
|
||||
MATKA <span className="text-red-600"> SATTA</span>
|
||||
</p>
|
||||
<h1 className="text-3xl md:text-4xl font-bold uppercase text-red-600">
|
||||
<img
|
||||
src="./logo.PNG"
|
||||
alt="Advertisement"
|
||||
className="w-28 h-30 m-auto"
|
||||
/>
|
||||
</h1>
|
||||
<p>
|
||||
At *Matka Satta Daily.com*, we provide accurate results, expert tips, and daily charts for all major Matka games. Whether you're looking for Desawar Matka results at 5:00 AM or Gali Matka results at 11:30 PM, we’ve got you covered. Stay ahead of the game with our live updates and expert strategies.
|
||||
|
||||
</p>
|
||||
<p className="mt-2">
|
||||
In the event of a discrepancy, the official drawing results shall
|
||||
prevail. All winning tickets must be redeemed in the
|
||||
state/jurisdiction in which they are sold.
|
||||
</p>
|
||||
<p className="mt-4 flex justify-center space-x-4 text-black font-semibold">
|
||||
<span>Media Center</span>
|
||||
<span>Legal</span>
|
||||
<span>Privacy</span>
|
||||
<span>español</span>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Footer;
|
||||
@ -1,49 +0,0 @@
|
||||
import { useState } from "react";
|
||||
import { Menu, X } from "lucide-react";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
export default function Header() {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Header */}
|
||||
<header className="bg-[#182633] text-white">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex justify-between items-center py-4">
|
||||
{/* Logo */}
|
||||
<Link to="/" className="text-2xl font-bold">
|
||||
<img
|
||||
src="./logo.PNG"
|
||||
alt="Advertisement"
|
||||
className="h-24 m-auto"
|
||||
/>
|
||||
</Link>
|
||||
|
||||
{/* Desktop Menu */}
|
||||
<nav className="hidden md:flex space-x-6">
|
||||
<Link to="/games" className="hover:text-gray-200 transition">Results</Link>
|
||||
<Link to="/" className="hover:text-gray-200 transition">FAQs</Link>
|
||||
</nav>
|
||||
|
||||
{/* Mobile Menu Button */}
|
||||
<button
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
className="md:hidden text-white focus:outline-none"
|
||||
>
|
||||
{isOpen ? <X size={28} /> : <Menu size={28} />}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Mobile Menu */}
|
||||
{isOpen && (
|
||||
<nav className="md:hidden flex flex-col space-y-4 pb-4">
|
||||
<Link to="#" className="hover:text-gray-200 transition">FAQs</Link>
|
||||
<Link to="/games" className="hover:text-gray-200 transition">Results</Link>
|
||||
</nav>
|
||||
)}
|
||||
</div>
|
||||
</header>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@ -1,293 +0,0 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { RefreshCw, Clock, ChevronRight, ChevronLeft } from 'lucide-react';
|
||||
import axios from 'axios';
|
||||
import TeamTime from './TeamTime';
|
||||
|
||||
const HeroSection = () => {
|
||||
const [todaysMatches, setTodaysMatches] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(null);
|
||||
const [currentDate, setCurrentDate] = useState('');
|
||||
const [activeTeamIndex, setActiveTeamIndex] = useState(0);
|
||||
|
||||
// API URL
|
||||
const API_URL = 'http://localhost:5500/api';
|
||||
|
||||
// Format time
|
||||
const formatTime = (timeString) => {
|
||||
try {
|
||||
const date = new Date(timeString);
|
||||
return date.toLocaleTimeString("en-US", { hour: '2-digit', minute: '2-digit', hour12: true });
|
||||
} catch (e) {
|
||||
return "XX:XX";
|
||||
}
|
||||
};
|
||||
|
||||
// Fetch today's matches
|
||||
useEffect(() => {
|
||||
const fetchTodaysMatches = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
// Get today's date for display
|
||||
const today = new Date();
|
||||
setCurrentDate(today.toLocaleDateString('en-US', {
|
||||
weekday: 'short',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
year: 'numeric'
|
||||
}));
|
||||
|
||||
// Get today's results
|
||||
const todayResultsResponse = await axios.get(`${API_URL}/today`);
|
||||
const todayResults = todayResultsResponse.data;
|
||||
|
||||
// Group by team
|
||||
const teamResults = {};
|
||||
|
||||
todayResults.forEach(result => {
|
||||
if (!teamResults[result.team]) {
|
||||
teamResults[result.team] = [];
|
||||
}
|
||||
teamResults[result.team].push({
|
||||
result: result.visible_result,
|
||||
time: formatTime(result.result_time),
|
||||
upcoming: new Date(result.result_time) > new Date()
|
||||
});
|
||||
});
|
||||
|
||||
// Convert to array for display
|
||||
const groupedResults = Object.entries(teamResults).map(([team, results]) => ({
|
||||
team,
|
||||
results: results.sort((a, b) => a.upcoming - b.upcoming)
|
||||
}));
|
||||
|
||||
setTodaysMatches(groupedResults);
|
||||
setLoading(false);
|
||||
} catch (err) {
|
||||
console.error("Error fetching today's matches:", err);
|
||||
setError("Failed to load today's match data. Please try again later.");
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchTodaysMatches();
|
||||
}, []);
|
||||
|
||||
// Navigation handlers
|
||||
const handleNext = () => {
|
||||
if (todaysMatches.length > 0) {
|
||||
setActiveTeamIndex((prevIndex) =>
|
||||
prevIndex === todaysMatches.length - 1 ? 0 : prevIndex + 1
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handlePrev = () => {
|
||||
if (todaysMatches.length > 0) {
|
||||
setActiveTeamIndex((prevIndex) =>
|
||||
prevIndex === 0 ? todaysMatches.length - 1 : prevIndex - 1
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// Refresh data
|
||||
const handleRefresh = () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const todayResultsResponse = await axios.get(`${API_URL}/today`);
|
||||
const todayResults = todayResultsResponse.data;
|
||||
|
||||
const teamResults = {};
|
||||
|
||||
todayResults.forEach(result => {
|
||||
if (!teamResults[result.team]) {
|
||||
teamResults[result.team] = [];
|
||||
}
|
||||
teamResults[result.team].push({
|
||||
result: result.visible_result,
|
||||
time: formatTime(result.result_time),
|
||||
upcoming: new Date(result.result_time) > new Date()
|
||||
});
|
||||
});
|
||||
|
||||
const groupedResults = Object.entries(teamResults).map(([team, results]) => ({
|
||||
team,
|
||||
results: results.sort((a, b) => a.upcoming - b.upcoming)
|
||||
}));
|
||||
|
||||
setTodaysMatches(groupedResults);
|
||||
setLoading(false);
|
||||
} catch (err) {
|
||||
setError("Failed to refresh match data. Please try again later.");
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// Render boxes similar to lottery design
|
||||
return (
|
||||
<div className="flex flex-col md:flex-row gap-4">
|
||||
{/* Today's Matches Box */}
|
||||
<div className="bg-gray-200 rounded-lg shadow-lg overflow-hidden w-full md:w-1/3">
|
||||
<div className="bg-white p-4 rounded-t-lg">
|
||||
<h2 className="text-center font-bold text-xl text-gray-800">Winning Numbers</h2>
|
||||
</div>
|
||||
<div className="p-4 text-center">
|
||||
<h3 className="font-medium text-lg mb-4">{currentDate}</h3>
|
||||
|
||||
{loading ? (
|
||||
<div className="flex justify-center p-6">
|
||||
<RefreshCw size={24} className="animate-spin text-red-600" />
|
||||
</div>
|
||||
) : error ? (
|
||||
<div className="bg-red-100 border border-red-400 text-red-700 p-3 rounded">
|
||||
<p>{error}</p>
|
||||
</div>
|
||||
) : todaysMatches.length > 0 ? (
|
||||
<div className="relative">
|
||||
{/* Navigation buttons */}
|
||||
<button
|
||||
onClick={handlePrev}
|
||||
className="absolute left-0 top-1/2 transform -translate-y-1/2 bg-gray-800 text-white rounded-full p-1 z-10"
|
||||
>
|
||||
<ChevronLeft size={20} />
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={handleNext}
|
||||
className="absolute right-0 top-1/2 transform -translate-y-1/2 bg-gray-800 text-white rounded-full p-1 z-10"
|
||||
>
|
||||
<ChevronRight size={20} />
|
||||
</button>
|
||||
|
||||
{/* Current team results */}
|
||||
<div className="py-2">
|
||||
<div className="bg-gray-800 text-white p-2 font-semibold rounded-t mb-2">
|
||||
{todaysMatches[activeTeamIndex]?.team || "No Team"}
|
||||
</div>
|
||||
|
||||
<div className="overflow-y-auto max-h-48">
|
||||
{todaysMatches[activeTeamIndex]?.results.map((result, idx) => (
|
||||
<div key={idx} className="flex justify-between items-center bg-white p-3 mb-2 rounded shadow">
|
||||
<div className="flex items-center gap-2">
|
||||
<Clock size={16} className="text-gray-500" />
|
||||
<span>{result.time}</span>
|
||||
</div>
|
||||
<div className={`text-xl font-bold ${result.upcoming ? 'text-gray-400' : 'text-red-600'}`}>
|
||||
{result.upcoming ? "Upcoming" : result.result}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Team indicators */}
|
||||
<div className="flex justify-center gap-1 mt-2">
|
||||
{todaysMatches.map((_, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className={`h-2 w-2 rounded-full ${idx === activeTeamIndex ? 'bg-red-600' : 'bg-gray-400'}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-center p-6 text-gray-500">
|
||||
No match results available for today.
|
||||
</div>
|
||||
)}
|
||||
|
||||
<button
|
||||
className="bg-red-600 text-white px-6 py-2 rounded-full font-bold mt-4 hover:bg-red-700 transition"
|
||||
onClick={handleRefresh}
|
||||
>
|
||||
PLay Now
|
||||
</button>
|
||||
|
||||
{/* <div className="mt-4 grid gap-2">
|
||||
<button className="bg-gray-800 text-white p-3 rounded font-medium">
|
||||
VIEW RESULTS
|
||||
</button>
|
||||
<button className="bg-gray-800 text-white p-3 rounded font-medium">
|
||||
CHECK YOUR NUMBERS
|
||||
</button>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Next Drawing Box */}
|
||||
<div className="bg-gray-200 rounded-lg shadow-lg overflow-hidden w-full md:w-1/3">
|
||||
<div className="bg-white p-4 rounded-t-lg">
|
||||
<h2 className="text-center font-bold text-xl text-gray-800">Next Drawing</h2>
|
||||
</div>
|
||||
<div className="p-4 text-center">
|
||||
<h3 className="font-medium text-lg mb-4">Sat, Mar 22, 2025</h3>
|
||||
|
||||
<div className="flex justify-center gap-2 my-4">
|
||||
<div className="bg-gray-800 text-white w-12 h-12 flex items-center justify-center rounded">
|
||||
<div className="text-xl font-bold">67</div>
|
||||
</div>
|
||||
<div className="bg-gray-800 text-white w-12 h-12 flex items-center justify-center rounded">
|
||||
<div className="text-xl font-bold">58</div>
|
||||
</div>
|
||||
<div className="bg-gray-800 text-white w-12 h-12 flex items-center justify-center rounded">
|
||||
<div className="text-xl font-bold">11</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center gap-2 text-xs text-gray-600 mb-4">
|
||||
<div className="text-center w-12">HOURS</div>
|
||||
<div className="text-center w-12">MINUTES</div>
|
||||
<div className="text-center w-12">SECONDS</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-gray-800 text-yellow-400 p-2 font-bold mb-2">
|
||||
ESTIMATED JACKPOT
|
||||
</div>
|
||||
|
||||
<div className="text-red-600 text-4xl font-bold mb-4">
|
||||
$444 Million
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Winners Box */}
|
||||
<div className="bg-gray-200 rounded-lg shadow-lg overflow-hidden w-full md:w-1/3">
|
||||
<div className="bg-white p-4 rounded-t-lg">
|
||||
<h2 className="text-center font-bold text-xl text-gray-800">Today's Timing </h2>
|
||||
</div>
|
||||
<div className="p-4">
|
||||
{/* <h3 className="font-medium text-lg mb-4">{currentDate}</h3> */}
|
||||
|
||||
{/* <div className="text-center mb-4">
|
||||
<div className="font-bold">Team Alpha</div>
|
||||
<div className="text-2xl font-bold">JACKPOT WINNERS</div>
|
||||
<div className="text-red-600 text-xl">None</div>
|
||||
</div>
|
||||
|
||||
<div className="text-center mb-4">
|
||||
<div className="font-bold">Team Beta</div>
|
||||
<div className="text-2xl font-bold">$2 MILLION WINNERS</div>
|
||||
<div className="text-red-600 text-xl">CO, TX</div>
|
||||
</div>
|
||||
|
||||
<div className="text-center">
|
||||
<div className="font-bold">MATCH 5</div>
|
||||
<div className="text-2xl font-bold">$1 MILLION WINNERS</div>
|
||||
<div className="text-red-600 text-xl">None</div>
|
||||
</div> */}
|
||||
<TeamTime/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default HeroSection;
|
||||
207
src/User/Home.js
207
src/User/Home.js
@ -1,207 +0,0 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { BarChart2, Calendar, RefreshCw, Clock, ChevronLeft, ChevronRight } from 'lucide-react';
|
||||
import axios from 'axios';
|
||||
import Footer from './Footer';
|
||||
import Header from './Header';
|
||||
import Translate from './Translate';
|
||||
import HeroSection from './Herosection';
|
||||
|
||||
const Home = () => {
|
||||
|
||||
const [teams, setTeams] = useState([]);
|
||||
const [dates, setDates] = useState([]);
|
||||
const [selectedTeam, setSelectedTeam] = useState(null);
|
||||
const [showChartView, setShowChartView] = useState(false);
|
||||
const [showCalendar, setShowCalendar] = useState(false);
|
||||
const [currentTime, setCurrentTime] = useState("");
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(null);
|
||||
const [calendarData, setCalendarData] = useState([]);
|
||||
const [currentMonth, setCurrentMonth] = useState(new Date());
|
||||
const [upcomingMatches, setUpcomingMatches] = useState([]);
|
||||
|
||||
|
||||
// API URL
|
||||
const API_URL = 'http://localhost:5500/api';
|
||||
|
||||
// Format time
|
||||
const formatTime = (timeString) => {
|
||||
try {
|
||||
const date = new Date(timeString);
|
||||
return date.toLocaleTimeString("en-US", { hour: '2-digit', minute: '2-digit', hour12: true });
|
||||
} catch (e) {
|
||||
return "XX:XX";
|
||||
}
|
||||
};
|
||||
|
||||
// Check if a match is upcoming
|
||||
const isUpcoming = (resultTime) => {
|
||||
try {
|
||||
const now = new Date();
|
||||
const matchTime = new Date(resultTime);
|
||||
return matchTime > now;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Fetch teams data
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
// Get all teams
|
||||
const teamsResponse = await axios.get(`${API_URL}/teams`);
|
||||
|
||||
// Get today's date and format it
|
||||
const today = new Date();
|
||||
const todayFormatted = today.toISOString().split('T')[0];
|
||||
|
||||
// Get yesterday's date and format it
|
||||
const yesterday = new Date();
|
||||
yesterday.setDate(yesterday.getDate() - 1);
|
||||
const yesterdayFormatted = yesterday.toISOString().split('T')[0];
|
||||
|
||||
// Set dates for display
|
||||
setDates([yesterdayFormatted, todayFormatted]);
|
||||
|
||||
// Get today's results
|
||||
const todayResultsResponse = await axios.get(`${API_URL}/results/daily?date=${todayFormatted}`);
|
||||
const todayResults = todayResultsResponse.data;
|
||||
|
||||
// Get yesterday's results
|
||||
const yesterdayResultsResponse = await axios.get(`${API_URL}/results/daily?date=${yesterdayFormatted}`);
|
||||
const yesterdayResults = yesterdayResultsResponse.data;
|
||||
|
||||
// Process upcoming matches
|
||||
const upcoming = todayResults.filter(result => isUpcoming(result.result_time));
|
||||
setUpcomingMatches(upcoming);
|
||||
|
||||
// Combine team data with results
|
||||
const teamsWithResults = teamsResponse.data.map(team => {
|
||||
// Get all results for this team
|
||||
const yesterdayTeamResults = yesterdayResults.filter(r => r.team === team.name);
|
||||
const todayTeamResults = todayResults.filter(r => r.team === team.name);
|
||||
|
||||
// Create result arrays for both days
|
||||
const yesterdayResultsArr = yesterdayTeamResults.map(r => ({
|
||||
result: r.visible_result,
|
||||
time: formatTime(r.result_time)
|
||||
}));
|
||||
|
||||
const todayResultsArr = todayTeamResults
|
||||
.filter(r => !isUpcoming(r.result_time))
|
||||
.map(r => ({
|
||||
result: r.visible_result,
|
||||
time: formatTime(r.result_time)
|
||||
}));
|
||||
|
||||
// Extract latest scheduled time
|
||||
let latestTime = "XX:XX";
|
||||
const latestTodayResult = todayTeamResults
|
||||
.sort((a, b) => new Date(b.result_time) - new Date(a.result_time))
|
||||
.find(r => r.result_time);
|
||||
|
||||
if (latestTodayResult) {
|
||||
latestTime = formatTime(latestTodayResult.result_time);
|
||||
}
|
||||
|
||||
return {
|
||||
id: team.id,
|
||||
name: team.name,
|
||||
time: latestTime,
|
||||
results: {
|
||||
[yesterdayFormatted]: yesterdayResultsArr,
|
||||
[todayFormatted]: todayResultsArr
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
setTeams(teamsWithResults);
|
||||
setLoading(false);
|
||||
} catch (err) {
|
||||
console.error("Error fetching data:", err);
|
||||
setError("Failed to load team data. Please try again later.");
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchData();
|
||||
|
||||
// Update current time every minute
|
||||
const interval = setInterval(() => {
|
||||
const now = new Date();
|
||||
const formattedTime = now.toLocaleString("en-IN", { timeZone: "Asia/Kolkata" });
|
||||
setCurrentTime(formattedTime);
|
||||
}, 60000);
|
||||
|
||||
// Set initial time
|
||||
const now = new Date();
|
||||
const formattedTime = now.toLocaleString("en-IN", { timeZone: "Asia/Kolkata" });
|
||||
setCurrentTime(formattedTime);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
|
||||
return (
|
||||
<div className="bg-gray-200 min-h-screen">
|
||||
<Translate/>
|
||||
<Header />
|
||||
<div className="w-full bg-white p-4 text-center text-white">
|
||||
{/* Header */}
|
||||
{/* <h1 className="text-3xl md:text-4xl font-bold uppercase text-red-600">
|
||||
<img
|
||||
src="./logo.PNG"
|
||||
alt="Advertisement"
|
||||
className="w-28 h-30 m-auto"
|
||||
/>
|
||||
</h1> */}
|
||||
|
||||
{/* Advertisement Banner */}
|
||||
{/* <div className="mt-4 flex justify-center items- border w-full lg:w-3/4 m-auto">
|
||||
<img
|
||||
src="./add.png"
|
||||
alt="Advertisement"
|
||||
className="w-auto max-w-4xl h-14"
|
||||
/>
|
||||
</div> */}
|
||||
{/* Disclaimer */}
|
||||
<p className="mt-4 text-black text-sm p-1 w-full lg:w-3/4 m-auto">
|
||||
Welcome to *Matka Satta Daily.com, your ultimate destination for accurate and timely Matka Satta results. We provide live updates, expert tips, and daily charts for all major Matka games, including **Desawar, **Delhi Bazar, **Shri Ganesh, **Faridabad, **Ghaziabad, and **Gali Matka*. Whether you're looking for results, guessing strategies, or historical data, we’ve got you covered.
|
||||
</p>
|
||||
|
||||
{/* Informational Text */}
|
||||
<p className="mt-2 text-red-400 text-sm font-medium bg-gray-900 p-2 rounded w-full lg:w-3/4 m-auto">
|
||||
Matka Satta Daily Results 2025: Desawar, Delhi Bazar, Shri Ganesh, Faridabad, Ghaziabad, and Gali Matka Live Updates
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
{/* Warning Message */}
|
||||
<p className="mt-2 text-white font-bold bg-red-700 p-2 rounded w-full lg:w-3/4 m-auto">
|
||||
Please note, do not give any money to anyone in the name of leaked game, neither before nor after - Thank you
|
||||
</p>
|
||||
|
||||
{/* Contact Link */}
|
||||
<p className="mt-2 text-white font-medium bg-gray-800 p-2 rounded w-full lg:w-3/4 m-auto">
|
||||
Click to contact us ➡ <a href="#" className="underline text-red-400 hover:text-red-300">Click Here</a>
|
||||
</p>
|
||||
|
||||
{/* Timestamp */}
|
||||
<p className="mt-2 text-red-400 text-lg text-bold">
|
||||
Updated: {currentTime} IST.
|
||||
</p>
|
||||
</div>
|
||||
<div className="max-w-6xl mx-auto p-4">
|
||||
|
||||
<HeroSection />
|
||||
</div>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Home;
|
||||
@ -1,36 +0,0 @@
|
||||
import { useState } from "react";
|
||||
|
||||
const TeamTime = () => {
|
||||
const [teams, setTeams] = useState([
|
||||
{ name: "GALI MATKA", time: "6:00 PM" },
|
||||
{ name: "GHAZIABAD MATKA", time: "4:00 PM" },
|
||||
{ name: "FARIDABAD MATKA", time: "12:30 PM" },
|
||||
{ name: "SHRI GANESH MATKA", time: "11:00 AM" },
|
||||
{ name: "DELHI BAZAR MATKA", time: "9:30 AM" },
|
||||
{ name: "DESAWAR MATKA", time: "5:00 AM" },
|
||||
]);
|
||||
|
||||
return (
|
||||
<div className="container mx-auto p-4">
|
||||
{/* <h2 className="text-2xl font-bold mb-4">Team Match Schedule</h2> */}
|
||||
<table className="table-auto w-full border border-gray-900">
|
||||
<thead>
|
||||
<tr className="bg-gray-300">
|
||||
<th className="border px-4 py-2">Team Name</th>
|
||||
<th className="border px-4 py-2">Timing</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{teams.map((team, index) => (
|
||||
<tr key={index} className="border">
|
||||
<td className="border px-4 py-2">{team.name}</td>
|
||||
<td className="border px-4 py-2">{team.time}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TeamTime;
|
||||
@ -1,64 +0,0 @@
|
||||
import { useState } from "react";
|
||||
import { Globe } from "lucide-react";
|
||||
|
||||
export default function Translate() {
|
||||
|
||||
const [currentLanguage, setCurrentLanguage] = useState("English");
|
||||
|
||||
// Function to handle language change
|
||||
const changeLanguage = (language) => {
|
||||
setCurrentLanguage(language);
|
||||
|
||||
// This would integrate with Google Translate API
|
||||
// For actual implementation, you would need to use the Google Translate Element
|
||||
if (language === "English") {
|
||||
// Set to English
|
||||
if (window.googleTranslateElementInit) {
|
||||
const selectElement = document.querySelector('.goog-te-combo');
|
||||
if (selectElement) {
|
||||
selectElement.value = 'en';
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
}
|
||||
}
|
||||
} else if (language === "Hindi") {
|
||||
// Set to Hindi
|
||||
if (window.googleTranslateElementInit) {
|
||||
const selectElement = document.querySelector('.goog-te-combo');
|
||||
if (selectElement) {
|
||||
selectElement.value = 'hi';
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Translation Bar */}
|
||||
<div className="bg-gray-800 text-white py-1">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex justify-between items-center">
|
||||
<div className="flex items-center">
|
||||
<Globe size={18} className="mr-2" />
|
||||
<span className="text-sm">Translate:</span>
|
||||
</div>
|
||||
<div className="flex space-x-4">
|
||||
<button
|
||||
onClick={() => changeLanguage("English")}
|
||||
className={`text-sm px-2 py-1 rounded ${currentLanguage === "English" ? "bg-blue-600" : "hover:bg-gray-700"}`}
|
||||
>
|
||||
English
|
||||
</button>
|
||||
<button
|
||||
onClick={() => changeLanguage("Hindi")}
|
||||
className={`text-sm px-2 py-1 rounded ${currentLanguage === "Hindi" ? "bg-blue-600" : "hover:bg-gray-700"}`}
|
||||
>
|
||||
हिन्दी
|
||||
</button>
|
||||
{/* Hidden div for Google Translate Element */}
|
||||
<div id="google_translate_element" className="hidden"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@ -1,586 +0,0 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { PlusCircle, Trash2, Edit, BarChart2, LogIn, Calendar as CalendarIcon } from 'lucide-react';
|
||||
|
||||
const Admin = () => {
|
||||
// Authentication state
|
||||
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
||||
const [authError, setAuthError] = useState('');
|
||||
const [loginData, setLoginData] = useState({ username: '', password: '' });
|
||||
|
||||
// Static credentials - in a real app, these would be stored securely
|
||||
const validCredentials = {
|
||||
username: 'admin',
|
||||
password: 'satta123'
|
||||
};
|
||||
|
||||
const [teams, setTeams] = useState([
|
||||
{ id: 1, name: 'BIKANER SUPER', time: '02:20 AM', results: { '2025-03-11': '04', '2025-03-12': '61' } },
|
||||
{ id: 2, name: 'DESAWAR', time: '05:00 AM', results: { '2025-03-11': '79', '2025-03-12': '55' } },
|
||||
{ id: 3, name: 'FARIDABAD', time: '06:00 PM', results: { '2025-03-11': '78', '2025-03-12': '98' } },
|
||||
{ id: 4, name: 'GHAZIABAD', time: '09:30 PM', results: { '2025-03-11': '19', '2025-03-12': '23' } },
|
||||
{ id: 5, name: 'GALI', time: '11:30 PM', results: { '2025-03-11': '72', '2025-03-12': 'XX' } },
|
||||
]);
|
||||
|
||||
const [selectedTeam, setSelectedTeam] = useState(null);
|
||||
const [showAddForm, setShowAddForm] = useState(false);
|
||||
const [showEditForm, setShowEditForm] = useState(false);
|
||||
const [showChartView, setShowChartView] = useState(false);
|
||||
const [showCalendar, setShowCalendar] = useState(false);
|
||||
const [formData, setFormData] = useState({ name: '', time: '', result: '' });
|
||||
const [dates, setDates] = useState(['2025-03-11', '2025-03-12']);
|
||||
const [currentDate, setCurrentDate] = useState('2025-03-12');
|
||||
|
||||
// Calendar state
|
||||
const [calendarYear, setCalendarYear] = useState(new Date().getFullYear());
|
||||
const [calendarMonth, setCalendarMonth] = useState(new Date().getMonth());
|
||||
|
||||
// Handle login input changes
|
||||
const handleLoginInputChange = (e) => {
|
||||
const { name, value } = e.target;
|
||||
setLoginData({ ...loginData, [name]: value });
|
||||
setAuthError('');
|
||||
};
|
||||
|
||||
// Handle login submission
|
||||
const handleLogin = (e) => {
|
||||
e.preventDefault();
|
||||
if (loginData.username === validCredentials.username &&
|
||||
loginData.password === validCredentials.password) {
|
||||
setIsAuthenticated(true);
|
||||
setAuthError('');
|
||||
} else {
|
||||
setAuthError('Invalid username or password');
|
||||
}
|
||||
};
|
||||
|
||||
// Handle logout
|
||||
const handleLogout = () => {
|
||||
setIsAuthenticated(false);
|
||||
setLoginData({ username: '', password: '' });
|
||||
};
|
||||
|
||||
// Handle input changes for team forms
|
||||
const handleInputChange = (e) => {
|
||||
const { name, value } = e.target;
|
||||
setFormData({ ...formData, [name]: value });
|
||||
};
|
||||
|
||||
// Add new team
|
||||
const handleAddTeam = () => {
|
||||
const newTeam = {
|
||||
id: teams.length + 1,
|
||||
name: formData.name,
|
||||
time: formData.time,
|
||||
results: {
|
||||
[dates[0]]: '',
|
||||
[dates[1]]: ''
|
||||
}
|
||||
};
|
||||
setTeams([...teams, newTeam]);
|
||||
setFormData({ name: '', time: '', result: '' });
|
||||
setShowAddForm(false);
|
||||
};
|
||||
|
||||
// Delete team
|
||||
const handleDeleteTeam = (id) => {
|
||||
setTeams(teams.filter(team => team.id !== id));
|
||||
};
|
||||
|
||||
// Select team for editing
|
||||
const handleSelectTeam = (team) => {
|
||||
setSelectedTeam(team);
|
||||
setFormData({
|
||||
name: team.name,
|
||||
time: team.time,
|
||||
result: team.results[currentDate] || ''
|
||||
});
|
||||
setShowEditForm(true);
|
||||
setShowChartView(false);
|
||||
};
|
||||
|
||||
// Update team
|
||||
const handleUpdateTeam = () => {
|
||||
const updatedTeams = teams.map(team => {
|
||||
if (team.id === selectedTeam.id) {
|
||||
const updatedResults = { ...team.results };
|
||||
updatedResults[currentDate] = formData.result;
|
||||
|
||||
return {
|
||||
...team,
|
||||
name: formData.name,
|
||||
time: formData.time,
|
||||
results: updatedResults
|
||||
};
|
||||
}
|
||||
return team;
|
||||
});
|
||||
|
||||
setTeams(updatedTeams);
|
||||
setShowEditForm(false);
|
||||
setSelectedTeam(null);
|
||||
setFormData({ name: '', time: '', result: '' });
|
||||
};
|
||||
|
||||
// Show chart for selected team
|
||||
const handleViewChart = (team) => {
|
||||
setSelectedTeam(team);
|
||||
setShowChartView(true);
|
||||
setShowEditForm(false);
|
||||
};
|
||||
|
||||
// Generate mock chart data for the selected team
|
||||
const generateChartData = () => {
|
||||
if (!selectedTeam) return [];
|
||||
|
||||
// Generate some random data for demonstration
|
||||
const mockData = [];
|
||||
const currentDate = new Date();
|
||||
|
||||
for (let i = 0; i < 30; i++) {
|
||||
const date = new Date(currentDate);
|
||||
date.setDate(date.getDate() - i);
|
||||
const dateStr = date.toISOString().split('T')[0];
|
||||
|
||||
mockData.unshift({
|
||||
date: dateStr,
|
||||
result: Math.floor(Math.random() * 100).toString().padStart(2, '0')
|
||||
});
|
||||
}
|
||||
|
||||
return mockData;
|
||||
};
|
||||
|
||||
// Calendar helpers
|
||||
const getDaysInMonth = (year, month) => {
|
||||
return new Date(year, month + 1, 0).getDate();
|
||||
};
|
||||
|
||||
const getFirstDayOfMonth = (year, month) => {
|
||||
return new Date(year, month, 1).getDay();
|
||||
};
|
||||
|
||||
const handlePrevMonth = () => {
|
||||
if (calendarMonth === 0) {
|
||||
setCalendarMonth(11);
|
||||
setCalendarYear(calendarYear - 1);
|
||||
} else {
|
||||
setCalendarMonth(calendarMonth - 1);
|
||||
}
|
||||
};
|
||||
|
||||
const handleNextMonth = () => {
|
||||
if (calendarMonth === 11) {
|
||||
setCalendarMonth(0);
|
||||
setCalendarYear(calendarYear + 1);
|
||||
} else {
|
||||
setCalendarMonth(calendarMonth + 1);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDateSelect = (day) => {
|
||||
const selectedDate = new Date(calendarYear, calendarMonth, day);
|
||||
const formattedDate = selectedDate.toISOString().split('T')[0];
|
||||
|
||||
// Check if the date is in the dates array
|
||||
if (!dates.includes(formattedDate)) {
|
||||
// Add the date to the dates array
|
||||
const newDates = [...dates, formattedDate].sort();
|
||||
setDates(newDates);
|
||||
|
||||
// Update teams with the new date
|
||||
const updatedTeams = teams.map(team => {
|
||||
const updatedResults = { ...team.results };
|
||||
if (!updatedResults[formattedDate]) {
|
||||
updatedResults[formattedDate] = '';
|
||||
}
|
||||
return { ...team, results: updatedResults };
|
||||
});
|
||||
|
||||
setTeams(updatedTeams);
|
||||
}
|
||||
|
||||
setCurrentDate(formattedDate);
|
||||
setShowCalendar(false);
|
||||
};
|
||||
|
||||
// Calendar component
|
||||
const CalendarComponent = () => {
|
||||
const monthNames = ["January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December"
|
||||
];
|
||||
|
||||
const daysInMonth = getDaysInMonth(calendarYear, calendarMonth);
|
||||
const firstDay = getFirstDayOfMonth(calendarYear, calendarMonth);
|
||||
|
||||
const renderCalendarDays = () => {
|
||||
const days = [];
|
||||
|
||||
// Add empty cells for days before the first day of the month
|
||||
for (let i = 0; i < firstDay; i++) {
|
||||
days.push(<div key={`empty-${i}`} className="h-8 w-8"></div>);
|
||||
}
|
||||
|
||||
// Add cells for each day of the month
|
||||
for (let day = 1; day <= daysInMonth; day++) {
|
||||
const date = new Date(calendarYear, calendarMonth, day).toISOString().split('T')[0];
|
||||
const isSelected = dates.includes(date);
|
||||
const isCurrentDate = date === currentDate;
|
||||
|
||||
days.push(
|
||||
<div
|
||||
key={day}
|
||||
className={`h-8 w-8 flex items-center justify-center rounded-full cursor-pointer ${
|
||||
isSelected ? 'bg-blue-100' : ''
|
||||
} ${
|
||||
isCurrentDate ? 'bg-blue-500 text-white' : ''
|
||||
} hover:bg-blue-200`}
|
||||
onClick={() => handleDateSelect(day)}
|
||||
>
|
||||
{day}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return days;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-white rounded shadow p-4 absolute top-full mt-1 right-0 z-10 w-[230px]">
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<button onClick={handlePrevMonth} className="p-1 rounded hover:bg-gray-100">
|
||||
<
|
||||
</button>
|
||||
<div className="font-semibold">
|
||||
{monthNames[calendarMonth]} {calendarYear}
|
||||
</div>
|
||||
<button onClick={handleNextMonth} className="p-1 rounded hover:bg-gray-100">
|
||||
>
|
||||
</button>
|
||||
</div>
|
||||
<div className="grid grid-cols-7 gap-1 mb-2">
|
||||
{['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'].map(day => (
|
||||
<div key={day} className="text-center text-xs font-medium text-gray-500">
|
||||
{day}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="grid grid-cols-7 gap-1">
|
||||
{renderCalendarDays()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Login Screen Component
|
||||
const LoginScreen = () => {
|
||||
return (
|
||||
<div className="flex items-center justify-center min-h-screen bg-gray-100">
|
||||
<div className="w-full max-w-md">
|
||||
<div className="bg-emerald-400 p-4 text-white text-center text-xl font-bold rounded-t-lg">
|
||||
Bikaner Super Satta Admin Login
|
||||
</div>
|
||||
<form
|
||||
className="bg-white shadow-md rounded-b-lg px-8 pt-6 pb-8 mb-4"
|
||||
onSubmit={handleLogin}
|
||||
>
|
||||
{authError && (
|
||||
<div className="mb-4 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded">
|
||||
{authError}
|
||||
</div>
|
||||
)}
|
||||
<div className="mb-4">
|
||||
<label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="username">
|
||||
Username
|
||||
</label>
|
||||
<input
|
||||
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
|
||||
id="username"
|
||||
type="text"
|
||||
name="username"
|
||||
placeholder="Username"
|
||||
value={loginData.username}
|
||||
onChange={handleLoginInputChange}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-6">
|
||||
<label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="password">
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 mb-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||
id="password"
|
||||
type="password"
|
||||
name="password"
|
||||
placeholder="******************"
|
||||
value={loginData.password}
|
||||
onChange={handleLoginInputChange}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-center">
|
||||
<button
|
||||
className="bg-emerald-500 hover:bg-emerald-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline flex items-center gap-2"
|
||||
type="submit"
|
||||
>
|
||||
<LogIn size={16} />
|
||||
Sign In
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Render login screen if not authenticated
|
||||
if (!isAuthenticated) {
|
||||
return <LoginScreen />;
|
||||
}
|
||||
|
||||
// Render admin panel if authenticated
|
||||
return (
|
||||
<div className="bg-gray-100 min-h-screen p-4">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<div className="bg-emerald-400 p-4 text-white flex justify-between items-center rounded-t-lg">
|
||||
<span className="text-xl font-bold">Bikaner Super Satta Result Admin Panel</span>
|
||||
<button
|
||||
className="bg-white text-emerald-700 px-3 py-1 rounded text-sm"
|
||||
onClick={handleLogout}
|
||||
>
|
||||
Logout
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Controls */}
|
||||
<div className="bg-white p-4 mb-4 flex justify-between items-center">
|
||||
<button
|
||||
className="bg-green-500 text-white px-4 py-2 rounded flex items-center gap-2"
|
||||
onClick={() => {
|
||||
setShowAddForm(true);
|
||||
setShowEditForm(false);
|
||||
setShowChartView(false);
|
||||
setFormData({ name: '', time: '', result: '' });
|
||||
}}
|
||||
>
|
||||
<PlusCircle size={16} />
|
||||
Add Team
|
||||
</button>
|
||||
|
||||
<div className="relative">
|
||||
<div className="flex items-center gap-2">
|
||||
<select
|
||||
className="border p-2 rounded"
|
||||
value={currentDate}
|
||||
onChange={(e) => setCurrentDate(e.target.value)}
|
||||
>
|
||||
{dates.map(date => (
|
||||
<option key={date} value={date}>
|
||||
{new Date(date).toLocaleDateString()}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<button
|
||||
className="bg-blue-500 text-white p-2 rounded flex items-center"
|
||||
onClick={() => setShowCalendar(!showCalendar)}
|
||||
>
|
||||
<CalendarIcon size={16} />
|
||||
</button>
|
||||
</div>
|
||||
{showCalendar && <CalendarComponent />}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Add Form */}
|
||||
{showAddForm && (
|
||||
<div className="bg-white p-4 mb-4 rounded shadow">
|
||||
<h2 className="text-lg font-semibold mb-4">Add New Team</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-1">Team Name</label>
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
value={formData.name}
|
||||
onChange={handleInputChange}
|
||||
className="w-full p-2 border rounded"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-1">Time</label>
|
||||
<input
|
||||
type="text"
|
||||
name="time"
|
||||
value={formData.time}
|
||||
onChange={handleInputChange}
|
||||
className="w-full p-2 border rounded"
|
||||
placeholder="e.g. 02:20 AM"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 flex justify-end gap-2">
|
||||
<button
|
||||
className="bg-gray-300 px-4 py-2 rounded"
|
||||
onClick={() => setShowAddForm(false)}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
className="bg-green-500 text-white px-4 py-2 rounded"
|
||||
onClick={handleAddTeam}
|
||||
>
|
||||
Add Team
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Edit Form */}
|
||||
{showEditForm && selectedTeam && (
|
||||
<div className="bg-white p-4 mb-4 rounded shadow">
|
||||
<h2 className="text-lg font-semibold mb-4">Edit Team: {selectedTeam.name}</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-1">Team Name</label>
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
value={formData.name}
|
||||
onChange={handleInputChange}
|
||||
className="w-full p-2 border rounded"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-1">Time</label>
|
||||
<input
|
||||
type="text"
|
||||
name="time"
|
||||
value={formData.time}
|
||||
onChange={handleInputChange}
|
||||
className="w-full p-2 border rounded"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-1">Result for {new Date(currentDate).toLocaleDateString()}</label>
|
||||
<input
|
||||
type="text"
|
||||
name="result"
|
||||
value={formData.result}
|
||||
onChange={handleInputChange}
|
||||
className="w-full p-2 border rounded"
|
||||
placeholder="e.g. 61"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 flex justify-end gap-2">
|
||||
<button
|
||||
className="bg-gray-300 px-4 py-2 rounded"
|
||||
onClick={() => setShowEditForm(false)}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
className="bg-blue-500 text-white px-4 py-2 rounded"
|
||||
onClick={handleUpdateTeam}
|
||||
>
|
||||
Update Team
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Chart View */}
|
||||
{showChartView && selectedTeam && (
|
||||
<div className="bg-white p-4 mb-4 rounded shadow">
|
||||
<h2 className="text-lg font-semibold mb-4">Monthly Chart: {selectedTeam.name}</h2>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full border-collapse">
|
||||
<thead>
|
||||
<tr className="bg-gray-100">
|
||||
<th className="border p-2 text-left">Date</th>
|
||||
<th className="border p-2 text-right">Result</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{generateChartData().map((item, index) => (
|
||||
<tr key={index} className={index % 2 === 0 ? 'bg-gray-50' : 'bg-white'}>
|
||||
<td className="border p-2">{new Date(item.date).toLocaleDateString()}</td>
|
||||
<td className="border p-2 text-right font-bold">{item.result}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div className="mt-4 flex justify-end">
|
||||
<button
|
||||
className="bg-gray-300 px-4 py-2 rounded"
|
||||
onClick={() => setShowChartView(false)}
|
||||
>
|
||||
Back to List
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Teams Table */}
|
||||
<div className="bg-white rounded-b-lg overflow-hidden">
|
||||
<table className="w-full border-collapse">
|
||||
<thead>
|
||||
<tr className="bg-gray-800 text-white">
|
||||
<th className="p-3 text-left">Games List</th>
|
||||
<th className="p-3 text-center md:block hidden">
|
||||
{new Date(dates[0]).toLocaleDateString()} <br/>
|
||||
{new Date(dates[0]).toLocaleDateString("en-US", {weekday: 'short'})}
|
||||
</th>
|
||||
<th className="p-3 text-center">
|
||||
{new Date(dates[1]).toLocaleDateString()} <br/>
|
||||
{new Date(dates[1]).toLocaleDateString("en-US", {weekday: 'short'})}
|
||||
</th>
|
||||
<th className="p-3 text-center">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{teams.map(team => (
|
||||
<tr key={team.id} className="border-b hover:bg-gray-50">
|
||||
<td className="p-3">
|
||||
<div className="font-semibold">{team.name}</div>
|
||||
<div className="text-sm text-gray-500">at {team.time}</div>
|
||||
</td>
|
||||
<td className="p-3 text-center text-2xl font-bold md:block hidden">{team.results[dates[0]] || 'XX'}</td>
|
||||
<td className="p-3 text-center text-2xl font-bold">{team.results[dates[1]] || 'XX'}</td>
|
||||
<td className="p-3">
|
||||
<div className="flex justify-center gap-2">
|
||||
<button
|
||||
className="p-2 bg-blue-100 text-blue-600 rounded"
|
||||
onClick={() => handleSelectTeam(team)}
|
||||
title="Edit Team"
|
||||
>
|
||||
<Edit size={16} />
|
||||
</button>
|
||||
<button
|
||||
className="p-2 bg-red-100 text-red-600 rounded"
|
||||
onClick={() => handleDeleteTeam(team.id)}
|
||||
title="Delete Team"
|
||||
>
|
||||
<Trash2 size={16} />
|
||||
</button>
|
||||
<button
|
||||
className="p-2 bg-green-100 text-green-600 rounded"
|
||||
onClick={() => handleViewChart(team)}
|
||||
title="View Monthly Chart"
|
||||
>
|
||||
<BarChart2 size={16} />
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Admin;
|
||||
@ -1,591 +0,0 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { BrowserRouter as Router, Route, Routes, Navigate, Link } from 'react-router-dom';
|
||||
import './App.css';
|
||||
import { useParams,useNavigate,useLocation } from 'react-router-dom';
|
||||
import Home from './pages/Home';
|
||||
import TeamResults from './pages/TeamResult';
|
||||
// Auth Context
|
||||
const AuthContext = React.createContext();
|
||||
|
||||
const AuthProvider = ({ children }) => {
|
||||
const [token, setToken] = useState(localStorage.getItem('token'));
|
||||
|
||||
const login = (newToken) => {
|
||||
localStorage.setItem('token', newToken);
|
||||
setToken(newToken);
|
||||
};
|
||||
|
||||
const logout = () => {
|
||||
localStorage.removeItem('token');
|
||||
setToken(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={{ token, login, logout, isAuthenticated: !!token }}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
// API Service
|
||||
const API_URL = 'http://localhost:5500';
|
||||
|
||||
const apiService = {
|
||||
login: async (accessKey, password) => {
|
||||
const response = await fetch(`${API_URL}/admin/login`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ accessKey, password })
|
||||
});
|
||||
console.log(accessKey);
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Login failed');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
},
|
||||
|
||||
getTeams: async (token) => {
|
||||
const response = await fetch(`${API_URL}/api/teams`, {
|
||||
headers: { 'Authorization': `Bearer ${token}` }
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch teams');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
},
|
||||
|
||||
createTeam: async (teamData, token) => {
|
||||
const response = await fetch(`${API_URL}/api/teams`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify(teamData)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to create team');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
},
|
||||
|
||||
updateTeam: async (id, teamData, token) => {
|
||||
const response = await fetch(`${API_URL}/api/teams/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify(teamData)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to update team');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
},
|
||||
|
||||
deleteTeam: async (id, token) => {
|
||||
const response = await fetch(`${API_URL}/api/teams/${id}`, {
|
||||
method: 'DELETE',
|
||||
headers: { 'Authorization': `Bearer ${token}` }
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to delete team');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
},
|
||||
|
||||
publishResult: async (resultData, token) => {
|
||||
const response = await fetch(`${API_URL}/admin/results`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify(resultData)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to publish result');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
},
|
||||
|
||||
getDailyResults: async (date, token) => {
|
||||
const response = await fetch(`${API_URL}/api/results/daily?date=${date}`, {
|
||||
headers: { 'Authorization': `Bearer ${token}` }
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch daily results');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
};
|
||||
|
||||
// Components
|
||||
const Login = () => {
|
||||
const [accessKey, setAccessKey] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [error, setError] = useState('');
|
||||
const { login } = React.useContext(AuthContext);
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
try {
|
||||
const data = await apiService.login(accessKey, password);
|
||||
login(data.token);
|
||||
// redirection
|
||||
|
||||
} catch (err) {
|
||||
setError('Invalid credentials');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="login-container">
|
||||
<h2>Admin Login</h2>
|
||||
{error && <div className="error">{error}</div>}
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="form-group">
|
||||
<label>Access Key</label>
|
||||
<input
|
||||
type="text"
|
||||
value={accessKey}
|
||||
onChange={(e) => setAccessKey(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label>Password</label>
|
||||
<input
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<button type="submit" className="btn-primary">Login</button>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const TeamList = () => {
|
||||
const [teams, setTeams] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState('');
|
||||
const { token } = React.useContext(AuthContext);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchTeams = async () => {
|
||||
try {
|
||||
const data = await apiService.getTeams(token);
|
||||
setTeams(data);
|
||||
setLoading(false);
|
||||
} catch (err) {
|
||||
setError('Failed to fetch teams');
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchTeams();
|
||||
}, [token]);
|
||||
|
||||
const handleDelete = async (id) => {
|
||||
if (window.confirm('Are you sure you want to delete this team?')) {
|
||||
try {
|
||||
await apiService.deleteTeam(id, token);
|
||||
setTeams(teams.filter(team => team.id !== id));
|
||||
} catch (err) {
|
||||
setError('Failed to delete team');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (loading) return <div>Loading...</div>;
|
||||
if (error) return <div className="error">{error}</div>;
|
||||
|
||||
return (
|
||||
<div className="team-list-container">
|
||||
<h2>Team Management</h2>
|
||||
<Link to="/teams/new" className="btn-primary">Add New Team</Link>
|
||||
<table className="team-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{teams.map(team => (
|
||||
<tr key={team.id}>
|
||||
<td>{team.id}</td>
|
||||
<td>{team.name}</td>
|
||||
<td>
|
||||
<Link to={`/teams/edit/${team.id}`} className="btn-secondary">Edit</Link>
|
||||
<button
|
||||
onClick={() => handleDelete(team.id)}
|
||||
className="btn-danger"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const TeamForm = ({ isEdit = false }) => {
|
||||
const [name, setName] = useState('');
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [error, setError] = useState('');
|
||||
const { token } = React.useContext(AuthContext);
|
||||
const { id } = useParams();
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
if (isEdit && id) {
|
||||
const fetchTeam = async () => {
|
||||
try {
|
||||
const teams = await apiService.getTeams(token);
|
||||
const team = teams.find(t => t.id === parseInt(id));
|
||||
if (team) {
|
||||
setName(team.name);
|
||||
}
|
||||
} catch (err) {
|
||||
setError('Failed to fetch team details');
|
||||
}
|
||||
};
|
||||
|
||||
fetchTeam();
|
||||
}
|
||||
}, [isEdit, id, token]);
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
setSubmitting(true);
|
||||
|
||||
try {
|
||||
if (isEdit) {
|
||||
await apiService.updateTeam(id, { name }, token);
|
||||
} else {
|
||||
await apiService.createTeam({ name }, token);
|
||||
}
|
||||
navigate('/teams');
|
||||
} catch (err) {
|
||||
setError(isEdit ? 'Failed to update team' : 'Failed to create team');
|
||||
setSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="team-form-container">
|
||||
<h2>{isEdit ? 'Edit Team' : 'Add New Team'}</h2>
|
||||
{error && <div className="error">{error}</div>}
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="form-group">
|
||||
<label>Team Name</label>
|
||||
<input
|
||||
type="text"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
className="btn-primary"
|
||||
disabled={submitting}
|
||||
>
|
||||
{submitting ? 'Saving...' : (isEdit ? 'Update Team' : 'Create Team')}
|
||||
</button>
|
||||
<Link to="/teams" className="btn-secondary">Cancel</Link>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const ResultCalendar = () => {
|
||||
const [date, setDate] = useState(new Date().toISOString().split('T')[0]);
|
||||
const [results, setResults] = useState([]);
|
||||
const [teams, setTeams] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState('');
|
||||
const { token } = React.useContext(AuthContext);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const [teamsData, resultsData] = await Promise.all([
|
||||
apiService.getTeams(token),
|
||||
apiService.getDailyResults(date, token)
|
||||
]);
|
||||
setTeams(teamsData);
|
||||
setResults(resultsData);
|
||||
setLoading(false);
|
||||
} catch (err) {
|
||||
setError('Failed to fetch data');
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, [date, token]);
|
||||
|
||||
const handleDateChange = (e) => {
|
||||
setDate(e.target.value);
|
||||
};
|
||||
|
||||
if (loading) return <div>Loading...</div>;
|
||||
if (error) return <div className="error">{error}</div>;
|
||||
|
||||
return (
|
||||
<div className="calendar-container">
|
||||
<h2>Results Calendar</h2>
|
||||
<div className="date-picker">
|
||||
<label>Select Date: </label>
|
||||
<input
|
||||
type="date"
|
||||
value={date}
|
||||
onChange={handleDateChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="results-container">
|
||||
<h3>Results for {date}</h3>
|
||||
<Link to={`/results/new?date=${date}`} className="btn-primary">Add New Result</Link>
|
||||
|
||||
{results.length === 0 ? (
|
||||
<p>No results for this date.</p>
|
||||
) : (
|
||||
<table className="results-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Team</th>
|
||||
<th>Result</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{results.map(result => (
|
||||
<tr key={result.id}>
|
||||
<td>{result.team}</td>
|
||||
<td>{result.visible_result}</td>
|
||||
<td>
|
||||
<Link to={`/results/edit/${result.id}?date=${date}`} className="btn-secondary">Edit</Link>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const ResultForm = ({ isEdit = false }) => {
|
||||
const [formData, setFormData] = useState({
|
||||
team: '',
|
||||
result: '',
|
||||
date: new Date().toISOString().split('T')[0]
|
||||
});
|
||||
const [teams, setTeams] = useState([]);
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [error, setError] = useState('');
|
||||
const { token } = React.useContext(AuthContext);
|
||||
const { id } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
const fetchTeams = async () => {
|
||||
try {
|
||||
const teamsData = await apiService.getTeams(token);
|
||||
setTeams(teamsData);
|
||||
|
||||
// Set date from query params if available
|
||||
const params = new URLSearchParams(location.search);
|
||||
const dateParam = params.get('date');
|
||||
if (dateParam) {
|
||||
setFormData(prev => ({ ...prev, date: dateParam }));
|
||||
}
|
||||
|
||||
// If editing, fetch the result details
|
||||
if (isEdit && id) {
|
||||
// This is a simplified approach. In a real app, you'd have an API endpoint to fetch a specific result
|
||||
const results = await apiService.getDailyResults(dateParam, token);
|
||||
const result = results.find(r => r.id === parseInt(id));
|
||||
console.log(result.team);
|
||||
if (result) {
|
||||
console.log(result)
|
||||
setFormData({
|
||||
team: result.team,
|
||||
result: result.visible_result,
|
||||
date: result.date
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
setError('Failed to fetch data');
|
||||
}
|
||||
};
|
||||
|
||||
fetchTeams();
|
||||
}, [isEdit, id, token, location.search]);
|
||||
|
||||
const handleChange = (e) => {
|
||||
const { name, value } = e.target;
|
||||
setFormData(prev => ({ ...prev, [name]: value }));
|
||||
};
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
setSubmitting(true);
|
||||
|
||||
try {
|
||||
await apiService.publishResult(formData, token);
|
||||
navigate(`/results?date=${formData.date}`);
|
||||
} catch (err) {
|
||||
setError('Failed to publish result');
|
||||
setSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="result-form-container">
|
||||
<h2>{isEdit ? 'Edit Result' : 'Add New Result'}</h2>
|
||||
{error && <div className="error">{error}</div>}
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="form-group">
|
||||
<label>Team</label>
|
||||
<select
|
||||
name="team"
|
||||
value={formData.team}
|
||||
onChange={handleChange}
|
||||
required
|
||||
>
|
||||
<option value="">Select a team</option>
|
||||
{teams.map(team => (
|
||||
<option key={team.id} value={team.id}>{team.name}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label>Result</label>
|
||||
<input
|
||||
type="text"
|
||||
name="result"
|
||||
value={formData.result}
|
||||
onChange={handleChange}
|
||||
placeholder="e.g., Win 3-2"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label>Date</label>
|
||||
<input
|
||||
type="date"
|
||||
name="date"
|
||||
value={formData.date}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
className="btn-primary"
|
||||
disabled={submitting}
|
||||
>
|
||||
{submitting ? 'Saving...' : (isEdit ? 'Update Result' : 'Publish Result')}
|
||||
</button>
|
||||
<Link to={`/results?date=${formData.date}`} className="btn-secondary">Cancel</Link>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const Dashboard = () => {
|
||||
const { logout } = React.useContext(AuthContext);
|
||||
|
||||
return (
|
||||
<div className="dashboard-container">
|
||||
<header className="dashboard-header">
|
||||
<h1>Admin Dashboard</h1>
|
||||
<button onClick={logout} className="btn-danger">Logout</button>
|
||||
</header>
|
||||
|
||||
<nav className="dashboard-nav">
|
||||
<Link to="/teams" className="nav-link">Teams</Link>
|
||||
<Link to="/results" className="nav-link">Results</Link>
|
||||
</nav>
|
||||
|
||||
<div className="dashboard-content">
|
||||
<Routes>
|
||||
<Route path="/teams" element={<TeamList />} />
|
||||
<Route path="/teams/new" element={<TeamForm />} />
|
||||
<Route path="/teams/edit/:id" element={<TeamForm isEdit={true} />} />
|
||||
<Route path="/results" element={<ResultCalendar />} />
|
||||
<Route path="/results/new" element={<ResultForm />} />
|
||||
<Route path="/results/edit/:id" element={<ResultForm isEdit={true} />} />
|
||||
<Route path="/" element={<Navigate to="/teams" />} />
|
||||
</Routes>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Protected Route
|
||||
const ProtectedRoute = ({ children }) => {
|
||||
const { isAuthenticated } = React.useContext(AuthContext);
|
||||
|
||||
if (!isAuthenticated) {
|
||||
return <Navigate to="/login" />;
|
||||
}
|
||||
|
||||
return children;
|
||||
};
|
||||
|
||||
// App
|
||||
const App = () => {
|
||||
return (
|
||||
<Router>
|
||||
<AuthProvider>
|
||||
<Routes>
|
||||
<Route path="/login" element={<Login />} />
|
||||
<Route
|
||||
path="/*"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Dashboard />
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route path="/" element={<Home />} />
|
||||
<Route path="/res" element={<TeamResults />} />
|
||||
</Routes>
|
||||
</AuthProvider>
|
||||
</Router>
|
||||
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
@ -9,14 +9,52 @@ import { useState } from 'react';
|
||||
};
|
||||
|
||||
const faqs = [
|
||||
{ question: "HOW TO PLAY", answer: "Details about how to play." },
|
||||
{ question: "WHERE TO PLAY", answer: "Information on where to play." },
|
||||
{ question: "WINNING NUMBERS EMAIL", answer: "Sign up for emails." },
|
||||
{
|
||||
question: "What is matkasatta.com?",
|
||||
answer: "matkasatta.com is an online platform where users can access information about satta games, strategies, and updates. We aim to provide the most recent and accurate information about the satta industry."
|
||||
},
|
||||
{
|
||||
question: "How do I register on the website?",
|
||||
answer: "To register, click on the 'Sign Up' or 'Register' button on our homepage. Fill in the required details and follow the on-screen instructions to complete the registration process."
|
||||
},
|
||||
{
|
||||
question: "Is it legal to use this website?",
|
||||
answer: "Online betting laws vary by jurisdiction. It is the responsibility of users to be aware of and comply with their local laws regarding online gambling. Please consult your local regulations before using our website."
|
||||
},
|
||||
{
|
||||
question: "How is my personal data protected?",
|
||||
answer: "We take user privacy very seriously. All personal data is stored securely, and we employ measures to protect against unauthorized access. For more details, please refer to our Privacy Policy."
|
||||
},
|
||||
{
|
||||
question: "Can I delete my account?",
|
||||
answer: "Yes, you can request account deletion by contacting our support team. Please note that some information might be retained for legal or operational reasons."
|
||||
},
|
||||
{
|
||||
question: "How do I deposit and withdraw money?",
|
||||
answer: "To deposit or withdraw money, go to the 'Wallet' or 'Account' section on our website. Supported payment methods include PhonePay, PayTM, Credit Card, and Debit Card. Follow the instructions provided and ensure you are familiar with our terms regarding deposits and withdrawals."
|
||||
},
|
||||
{
|
||||
question: "Is there a minimum deposit or withdrawal amount?",
|
||||
answer: "Yes, the minimum deposit is 100 RUPAY and the minimum withdrawal is 1000 RUPAY."
|
||||
},
|
||||
{
|
||||
question: "What should I do if I encounter a problem?",
|
||||
answer: "If you face any issues, please contact our support team at support@matkasatta.com or use the 'Contact Us' form on our website."
|
||||
},
|
||||
{
|
||||
question: "Do you promote responsible gambling?",
|
||||
answer: "Absolutely. We believe in promoting a responsible gambling environment. If you or someone you know has a gambling problem, please seek help and guidance immediately."
|
||||
},
|
||||
{
|
||||
question: "Are the games on matkasatta.com fair?",
|
||||
answer: "Yes, all games are operated with a fair system, and we ensure transparency in all our operations."
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-full bg-white text-black">
|
||||
<div className="w-full bg-white text-black" id="faq">
|
||||
{/* FAQ Section */}
|
||||
<div className="max-w-6xl mx-auto py-6">
|
||||
{faqs.map((faq, index) => (
|
||||
|
||||
17
src/pages/FaqPage.js
Normal file
17
src/pages/FaqPage.js
Normal file
@ -0,0 +1,17 @@
|
||||
import { useState } from "react";
|
||||
import Header from "./Header";
|
||||
import Faq from "./Faq";
|
||||
import Footer from "./Footer";
|
||||
|
||||
const FaqPage = () => {
|
||||
|
||||
return (
|
||||
<div className=" mx-auto ">
|
||||
<Header/>
|
||||
<Faq/>
|
||||
<Footer/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FaqPage;
|
||||
@ -1,13 +1,9 @@
|
||||
import React from 'react';
|
||||
import Faq from './Faq';
|
||||
const Footer = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-full bg-white text-black">
|
||||
{/* FAQ Section */}
|
||||
<Faq />
|
||||
|
||||
{/* Footer Section */}
|
||||
<footer className="bg-white border-t py-6 text-center">
|
||||
<div className="max-w-3xl mx-auto text-gray-600 text-sm">
|
||||
|
||||
@ -452,7 +452,10 @@ const GameList = () => {
|
||||
{item.result_time ? formatTime(item.result_time) : "N/A"}
|
||||
</td>
|
||||
<td className="border border-gray-300 p-2 text-right font-bold">
|
||||
{item.visible_result || item.result || "N/A"}
|
||||
{item.visible_result === '-1' || item.result === '-1'
|
||||
? "Yet to Announce"
|
||||
: (item.visible_result || item.result || "N/A")
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
))
|
||||
|
||||
@ -5,35 +5,9 @@ import { Link } from "react-router-dom";
|
||||
export default function Header() {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
// Add this effect to your App.js or index.js instead
|
||||
/*
|
||||
useEffect(() => {
|
||||
const script = document.createElement('script');
|
||||
script.src = "https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit";
|
||||
script.async = true;
|
||||
document.body.appendChild(script);
|
||||
|
||||
window.googleTranslateElementInit = () => {
|
||||
new window.google.translate.TranslateElement(
|
||||
{ pageLanguage: 'en', includedLanguages: 'en,hi' },
|
||||
'google_translate_element'
|
||||
);
|
||||
};
|
||||
|
||||
return () => {
|
||||
document.body.removeChild(script);
|
||||
};
|
||||
}, []);
|
||||
*/
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Translation Bar */}
|
||||
{/* <div className="bg-gray-800 text-white py-2">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex justify-between items-center">
|
||||
<div id="google_translate_element"></div>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
|
||||
{/* Header */}
|
||||
<header className="bg-[#182633] text-white">
|
||||
@ -51,7 +25,7 @@ export default function Header() {
|
||||
{/* Desktop Menu */}
|
||||
<nav className="hidden md:flex space-x-6">
|
||||
<Link to="/games" className="hover:text-gray-200 transition">Results</Link>
|
||||
<Link to="/" className="hover:text-gray-200 transition">FAQs</Link>
|
||||
<Link to="/faq" className="hover:text-gray-200 transition">FAQs</Link>
|
||||
</nav>
|
||||
|
||||
{/* Mobile Menu Button */}
|
||||
@ -66,7 +40,7 @@ export default function Header() {
|
||||
{/* Mobile Menu */}
|
||||
{isOpen && (
|
||||
<nav className="md:hidden flex flex-col space-y-4 pb-4">
|
||||
<Link to="#" className="hover:text-gray-200 transition">FAQs</Link>
|
||||
<Link to="/faq" className="hover:text-gray-200 transition">FAQs</Link>
|
||||
<Link to="/games" className="hover:text-gray-200 transition">Results</Link>
|
||||
</nav>
|
||||
)}
|
||||
|
||||
@ -4,7 +4,6 @@ import axios from 'axios';
|
||||
import TodaysMatch from './TodaysMatch';
|
||||
import Footer from './Footer';
|
||||
import Header from './Header';
|
||||
import Translate from '../Translate';
|
||||
|
||||
const Home2 = () => {
|
||||
const [teams, setTeams] = useState([]);
|
||||
@ -305,7 +304,7 @@ const Home2 = () => {
|
||||
|
||||
return (
|
||||
<div className="bg-gray-200 min-h-screen">
|
||||
<Translate/>
|
||||
|
||||
<Header />
|
||||
<div className="w-full bg-white p-4 text-center text-white">
|
||||
{/* Header */}
|
||||
|
||||
@ -1,684 +0,0 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { BarChart2, Calendar, RefreshCw, Clock, ChevronLeft, ChevronRight } from 'lucide-react';
|
||||
import axios from 'axios';
|
||||
import TodaysMatch from './TodaysMatch';
|
||||
|
||||
const Home2 = () => {
|
||||
const [teams, setTeams] = useState([]);
|
||||
const [dates, setDates] = useState([]);
|
||||
const [selectedTeam, setSelectedTeam] = useState(null);
|
||||
const [showChartView, setShowChartView] = useState(false);
|
||||
const [showCalendar, setShowCalendar] = useState(false);
|
||||
const [currentTime, setCurrentTime] = useState("");
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(null);
|
||||
const [calendarData, setCalendarData] = useState([]);
|
||||
const [currentMonth, setCurrentMonth] = useState(new Date());
|
||||
const [upcomingMatches, setUpcomingMatches] = useState([]);
|
||||
|
||||
// API URL
|
||||
const API_URL = 'http://localhost:5500/api';
|
||||
|
||||
// Format time
|
||||
const formatTime = (timeString) => {
|
||||
try {
|
||||
const date = new Date(timeString);
|
||||
return date.toLocaleTimeString("en-US", { hour: '2-digit', minute: '2-digit', hour12: true });
|
||||
} catch (e) {
|
||||
return "XX:XX";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Check if a match is upcoming
|
||||
const isUpcoming = (resultTime) => {
|
||||
try {
|
||||
const now = new Date();
|
||||
const matchTime = new Date(resultTime);
|
||||
return matchTime > now;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Fetch teams data
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
// Get all teams
|
||||
const teamsResponse = await axios.get(`${API_URL}/teams`);
|
||||
|
||||
// Get today's date and format it
|
||||
const today = new Date();
|
||||
const todayFormatted = today.toISOString().split('T')[0];
|
||||
|
||||
// Get yesterday's date and format it
|
||||
const yesterday = new Date();
|
||||
yesterday.setDate(yesterday.getDate() - 1);
|
||||
const yesterdayFormatted = yesterday.toISOString().split('T')[0];
|
||||
|
||||
// Set dates for display
|
||||
setDates([yesterdayFormatted, todayFormatted]);
|
||||
|
||||
// Get today's results
|
||||
const todayResultsResponse = await axios.get(`${API_URL}/results/daily?date=${todayFormatted}`);
|
||||
const todayResults = todayResultsResponse.data;
|
||||
|
||||
// Get yesterday's results
|
||||
const yesterdayResultsResponse = await axios.get(`${API_URL}/results/daily?date=${yesterdayFormatted}`);
|
||||
const yesterdayResults = yesterdayResultsResponse.data;
|
||||
|
||||
// Process upcoming matches
|
||||
const upcoming = todayResults.filter(result => isUpcoming(result.result_time));
|
||||
setUpcomingMatches(upcoming);
|
||||
|
||||
// Combine team data with results
|
||||
const teamsWithResults = teamsResponse.data.map(team => {
|
||||
// Get all results for this team
|
||||
const yesterdayTeamResults = yesterdayResults.filter(r => r.team === team.name);
|
||||
const todayTeamResults = todayResults.filter(r => r.team === team.name);
|
||||
|
||||
// Create result arrays for both days
|
||||
const yesterdayResultsArr = yesterdayTeamResults.map(r => ({
|
||||
result: r.visible_result,
|
||||
time: formatTime(r.result_time)
|
||||
}));
|
||||
|
||||
const todayResultsArr = todayTeamResults
|
||||
.filter(r => !isUpcoming(r.result_time))
|
||||
.map(r => ({
|
||||
result: r.visible_result,
|
||||
time: formatTime(r.result_time)
|
||||
}));
|
||||
|
||||
// Extract latest scheduled time
|
||||
let latestTime = "XX:XX";
|
||||
const latestTodayResult = todayTeamResults
|
||||
.sort((a, b) => new Date(b.result_time) - new Date(a.result_time))
|
||||
.find(r => r.result_time);
|
||||
|
||||
if (latestTodayResult) {
|
||||
latestTime = formatTime(latestTodayResult.result_time);
|
||||
}
|
||||
|
||||
return {
|
||||
id: team.id,
|
||||
name: team.name,
|
||||
time: latestTime,
|
||||
results: {
|
||||
[yesterdayFormatted]: yesterdayResultsArr,
|
||||
[todayFormatted]: todayResultsArr
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
setTeams(teamsWithResults);
|
||||
setLoading(false);
|
||||
} catch (err) {
|
||||
console.error("Error fetching data:", err);
|
||||
setError("Failed to load team data. Please try again later.");
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchData();
|
||||
|
||||
// Update current time every minute
|
||||
const interval = setInterval(() => {
|
||||
const now = new Date();
|
||||
const formattedTime = now.toLocaleString("en-IN", { timeZone: "Asia/Kolkata" });
|
||||
setCurrentTime(formattedTime);
|
||||
}, 60000);
|
||||
|
||||
// Set initial time
|
||||
const now = new Date();
|
||||
const formattedTime = now.toLocaleString("en-IN", { timeZone: "Asia/Kolkata" });
|
||||
setCurrentTime(formattedTime);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
// Show chart for selected team
|
||||
const handleViewChart = async (team) => {
|
||||
try {
|
||||
setLoading(true);
|
||||
// Get monthly results for the selected team
|
||||
const currentDate = new Date();
|
||||
const month = currentDate.getMonth() + 1;
|
||||
const year = currentDate.getFullYear();
|
||||
|
||||
const response = await axios.post(`${API_URL}/results/monthly`, {
|
||||
team: team.name,
|
||||
month: `${year}-${month.toString().padStart(2, '0')}`
|
||||
});
|
||||
|
||||
setSelectedTeam({
|
||||
...team,
|
||||
chartData: response.data
|
||||
});
|
||||
|
||||
setShowChartView(true);
|
||||
setShowCalendar(false);
|
||||
setLoading(false);
|
||||
} catch (err) {
|
||||
console.error("Error fetching chart data:", err);
|
||||
setError("Failed to load chart data. Please try again later.");
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Load calendar data
|
||||
const loadCalendarData = async (year, month) => {
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
// Calculate first and last day of month
|
||||
const firstDay = new Date(year, month, 1).toISOString().split('T')[0];
|
||||
const lastDay = new Date(year, month + 1, 0).toISOString().split('T')[0];
|
||||
|
||||
// Get results for each day in the month
|
||||
const dailyResultsPromises = [];
|
||||
const currentDate = new Date(year, month, 1);
|
||||
const lastDate = new Date(year, month + 1, 0);
|
||||
|
||||
while (currentDate <= lastDate) {
|
||||
const dateString = currentDate.toISOString().split('T')[0];
|
||||
dailyResultsPromises.push(
|
||||
axios.get(`${API_URL}/results/daily?date=${dateString}`)
|
||||
.then(response => ({
|
||||
date: dateString,
|
||||
results: response.data
|
||||
}))
|
||||
.catch(() => ({
|
||||
date: dateString,
|
||||
results: []
|
||||
}))
|
||||
);
|
||||
currentDate.setDate(currentDate.getDate() + 1);
|
||||
}
|
||||
|
||||
const allResults = await Promise.all(dailyResultsPromises);
|
||||
|
||||
// Format calendar data
|
||||
const calendarDays = [];
|
||||
const firstDayOfMonth = new Date(year, month, 1);
|
||||
const firstDayWeekday = firstDayOfMonth.getDay();
|
||||
|
||||
// Add empty cells for days before the first of the month
|
||||
for (let i = 0; i < firstDayWeekday; i++) {
|
||||
calendarDays.push(null);
|
||||
}
|
||||
|
||||
// Add days with results
|
||||
for (let i = 1; i <= lastDate.getDate(); i++) {
|
||||
const dateObj = new Date(year, month, i);
|
||||
const dateStr = dateObj.toISOString().split('T')[0];
|
||||
|
||||
const dayData = allResults.find(r => r.date === dateStr);
|
||||
let dayResults = [];
|
||||
|
||||
if (dayData && dayData.results.length > 0) {
|
||||
// Group by team
|
||||
const teamResults = {};
|
||||
|
||||
dayData.results.forEach(result => {
|
||||
if (!teamResults[result.team]) {
|
||||
teamResults[result.team] = [];
|
||||
}
|
||||
teamResults[result.team].push({
|
||||
result: result.visible_result,
|
||||
time: formatTime(result.result_time)
|
||||
});
|
||||
});
|
||||
|
||||
// Create an array for display
|
||||
dayResults = Object.entries(teamResults).map(([team, results]) => ({
|
||||
team,
|
||||
results
|
||||
}));
|
||||
}
|
||||
|
||||
calendarDays.push({
|
||||
day: i,
|
||||
date: dateStr,
|
||||
results: dayResults
|
||||
});
|
||||
}
|
||||
|
||||
setCalendarData(calendarDays);
|
||||
setLoading(false);
|
||||
} catch (err) {
|
||||
console.error("Error loading calendar data:", err);
|
||||
setError("Failed to load calendar data. Please try again later.");
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Handle calendar view button click
|
||||
const handleCalendarView = () => {
|
||||
const now = new Date();
|
||||
setCurrentMonth(now);
|
||||
loadCalendarData(now.getFullYear(), now.getMonth());
|
||||
setShowCalendar(true);
|
||||
setShowChartView(false);
|
||||
};
|
||||
|
||||
// Handle month change in calendar
|
||||
const handleMonthChange = (increment) => {
|
||||
const newMonth = new Date(currentMonth);
|
||||
newMonth.setMonth(newMonth.getMonth() + increment);
|
||||
setCurrentMonth(newMonth);
|
||||
loadCalendarData(newMonth.getFullYear(), newMonth.getMonth());
|
||||
};
|
||||
|
||||
// Refresh data
|
||||
const handleRefresh = () => {
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
// Format date for display
|
||||
const formatDate = (dateString) => {
|
||||
return new Date(dateString).toLocaleDateString('en-US', {
|
||||
weekday: 'short',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
year: 'numeric'
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
const [openIndex, setOpenIndex] = useState(null);
|
||||
|
||||
const toggleFAQ = (index) => {
|
||||
setOpenIndex(openIndex === index ? null : index);
|
||||
};
|
||||
|
||||
const faqs = [
|
||||
{ question: "HOW TO PLAY", answer: "Details about how to play." },
|
||||
{ question: "WHERE TO PLAY", answer: "Information on where to play." },
|
||||
{ question: "WINNING NUMBERS EMAIL", answer: "Sign up for emails." },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="bg-gray-200 min-h-screen">
|
||||
<div className="w-full bg-white p-4 text-center text-white">
|
||||
{/* Header */}
|
||||
<h1 className="text-3xl md:text-4xl font-bold uppercase text-red-600">
|
||||
<img
|
||||
src="./logo.PNG"
|
||||
alt="Advertisement"
|
||||
className="w-28 h-30 m-auto"
|
||||
/>
|
||||
</h1>
|
||||
|
||||
{/* Advertisement Banner */}
|
||||
<div className="mt-4 flex justify-center items- border">
|
||||
<img
|
||||
src="./add.png"
|
||||
alt="Advertisement"
|
||||
className="w-auto max-w-4xl h-14"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Informational Text */}
|
||||
<p className="mt-4 text-black text-sm p-1 w-full lg:w-3/4 m-auto">
|
||||
Delhi Diamond Satta Result And Monthly Satta Chart of March 2025 With Combined Chart of Gali, Desawar, Ghaziabad, Faridabad And Shri Ganesh from Matka Satta Fast, Matka Satta Result, Matka Satta Chart, Black Matka Satta and Matka Satta 786.
|
||||
</p>
|
||||
|
||||
{/* Disclaimer */}
|
||||
<p className="mt-2 text-red-400 text-sm font-medium bg-gray-900 p-2 rounded w-full lg:w-3/4 m-auto">
|
||||
Matka-Satta .com is the most popular gaming discussion forum for players to use freely and we are not in partnership with any gaming company.
|
||||
</p>
|
||||
|
||||
{/* Warning Message */}
|
||||
<p className="mt-2 text-white font-bold bg-red-700 p-2 rounded w-full lg:w-3/4 m-auto">
|
||||
कृपया ध्यान दें, लीक गेम के नाम पर किसी को कोई पैसा न दें, ना पहले ना बाद में - धन्यवाद
|
||||
</p>
|
||||
|
||||
{/* Contact Link */}
|
||||
<p className="mt-2 text-white font-medium bg-gray-800 p-2 rounded w-full lg:w-3/4 m-auto">
|
||||
हमसे संपर्क करने के लिए ➡ <a href="#" className="underline text-red-400 hover:text-red-300">यहाँ क्लिक करें</a>
|
||||
</p>
|
||||
|
||||
{/* Timestamp */}
|
||||
<p className="mt-2 text-red-400 text-lg text-bold">
|
||||
Updated: {currentTime} IST.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="max-w-6xl mx-auto p-4">
|
||||
{error && (
|
||||
<div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4">
|
||||
<p>{error}</p>
|
||||
</div>
|
||||
)}
|
||||
<TodaysMatch/>
|
||||
|
||||
<div className="bg-red-600 p-4 text-white text-center text-xl font-bold rounded-t-lg shadow-lg">
|
||||
Satta Result of {dates.length > 1 && formatDate(dates[1])} & {dates.length > 0 && formatDate(dates[0])}
|
||||
</div>
|
||||
|
||||
{/* Controls */}
|
||||
<div className="bg-white p-4 mb-4 flex flex-col md:flex-row justify-between items-center shadow-md">
|
||||
<div className="text-lg font-semibold text-gray-800 mb-2 md:mb-0">Latest Results</div>
|
||||
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
className="bg-black text-white px-4 py-2 rounded flex items-center gap-2 hover:bg-gray-800 transition"
|
||||
onClick={handleCalendarView}
|
||||
disabled={loading}
|
||||
>
|
||||
<Calendar size={16} />
|
||||
Calendar View
|
||||
</button>
|
||||
<button
|
||||
className="bg-red-600 text-white px-4 py-2 rounded flex items-center gap-2 hover:bg-red-700 transition"
|
||||
onClick={handleRefresh}
|
||||
disabled={loading}
|
||||
>
|
||||
<RefreshCw size={16} />
|
||||
Refresh
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Loading indicator */}
|
||||
{loading && (
|
||||
<div className="bg-white p-8 mb-4 rounded shadow flex justify-center items-center">
|
||||
<div className="flex items-center gap-2">
|
||||
<RefreshCw size={24} className="animate-spin text-red-600" />
|
||||
<span>Loading data...</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Upcoming Matches */}
|
||||
{!loading && upcomingMatches.length > 0 && !showChartView && !showCalendar && (
|
||||
<div className="bg-white p-4 mb-4 rounded shadow">
|
||||
<h2 className="text-lg font-semibold mb-4 flex items-center gap-2 text-red-600">
|
||||
<Clock size={20} />
|
||||
Upcoming Matches Today
|
||||
</h2>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full border-collapse">
|
||||
<thead>
|
||||
<tr className="bg-black text-white">
|
||||
<th className="border border-gray-300 p-2 text-left">Team</th>
|
||||
<th className="border border-gray-300 p-2 text-center">Scheduled Time</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{upcomingMatches.map((match, index) => (
|
||||
<tr key={index} className={index % 2 === 0 ? 'bg-gray-50' : 'bg-white'}>
|
||||
<td className="border border-gray-300 p-2 font-medium">{match.team}</td>
|
||||
<td className="border border-gray-300 p-2 text-center">{formatTime(match.result_time)}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Chart View */}
|
||||
{!loading && showChartView && selectedTeam && (
|
||||
<div className="bg-white p-4 mb-4 rounded shadow">
|
||||
<h2 className="text-lg font-semibold mb-4 text-red-600">Monthly Chart: {selectedTeam.name}</h2>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full border-collapse">
|
||||
<thead>
|
||||
<tr className="bg-black text-white">
|
||||
<th className="border border-gray-300 p-2 text-left">Date</th>
|
||||
<th className="border border-gray-300 p-2 text-center">Time</th>
|
||||
<th className="border border-gray-300 p-2 text-right">Result</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{selectedTeam.chartData && selectedTeam.chartData.map((item, index) => (
|
||||
<tr key={index} className={index % 2 === 0 ? 'bg-gray-50' : 'bg-white'}>
|
||||
<td className="border border-gray-300 p-2">{new Date(item.result_date).toLocaleDateString()}</td>
|
||||
<td className="border border-gray-300 p-2 text-center">{formatTime(item.result_time)}</td>
|
||||
<td className="border border-gray-300 p-2 text-right font-bold">{item.result}</td>
|
||||
</tr>
|
||||
))}
|
||||
{(!selectedTeam.chartData || selectedTeam.chartData.length === 0) && (
|
||||
<tr>
|
||||
<td colSpan="3" className="border border-gray-300 p-2 text-center">No chart data available</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div className="mt-4 flex justify-end">
|
||||
<button
|
||||
className="bg-black text-white px-4 py-2 rounded hover:bg-gray-800 transition"
|
||||
onClick={() => setShowChartView(false)}
|
||||
>
|
||||
Back to Results
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Calendar View - Improved Responsive Design */}
|
||||
{!loading && showCalendar && (
|
||||
<div className="bg-white p-4 mb-4 rounded shadow">
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<button
|
||||
className="bg-black text-white p-2 rounded flex items-center gap-1 hover:bg-gray-800 transition"
|
||||
onClick={() => handleMonthChange(-1)}
|
||||
>
|
||||
<ChevronLeft size={16} />
|
||||
<span className="hidden sm:inline">Previous</span>
|
||||
</button>
|
||||
|
||||
<h2 className="text-lg font-semibold text-red-600">
|
||||
{currentMonth.toLocaleDateString('en-US', { month: 'long', year: 'numeric' })}
|
||||
</h2>
|
||||
|
||||
<button
|
||||
className="bg-black text-white p-2 rounded flex items-center gap-1 hover:bg-gray-800 transition"
|
||||
onClick={() => handleMonthChange(1)}
|
||||
>
|
||||
<span className="hidden sm:inline">Next</span>
|
||||
<ChevronRight size={16} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-7 gap-1 mb-2">
|
||||
{['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'].map(day => (
|
||||
<div key={day} className="text-center font-semibold bg-gray-800 text-white p-1 text-xs sm:text-sm">{day}</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-7 gap-1">
|
||||
{calendarData.map((day, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`border rounded p-1 overflow-y-auto ${day ? 'bg-white' : 'bg-gray-100'
|
||||
}`}
|
||||
style={{
|
||||
height: "120px",
|
||||
maxHeight: "120px"
|
||||
}}
|
||||
>
|
||||
{day && (
|
||||
<>
|
||||
<div className={`text-right text-sm font-medium ${new Date().toISOString().split('T')[0] === day.date ?
|
||||
'bg-red-600 text-white p-1 rounded-full w-6 h-6 flex items-center justify-center ml-auto' :
|
||||
'text-gray-700'
|
||||
}`}>
|
||||
{day.day}
|
||||
</div>
|
||||
<div className="overflow-y-auto" style={{ maxHeight: "90px" }}>
|
||||
{day.results.length > 0 ? (
|
||||
day.results.map((teamResult, i) => (
|
||||
<div key={i} className="mt-1 border-t border-gray-200 pt-1">
|
||||
<div className="font-semibold text-xs text-red-600">{teamResult.team}</div>
|
||||
{teamResult.results.map((r, j) => (
|
||||
<div key={j} className="text-xs flex justify-between">
|
||||
<span className="text-gray-500">{r.time}</span>
|
||||
<span className="font-bold">{r.result}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<div className="text-xs text-gray-400 mt-2 text-center">No results</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-4 flex justify-end">
|
||||
<button
|
||||
className="bg-black text-white px-4 py-2 rounded hover:bg-gray-800 transition"
|
||||
onClick={() => setShowCalendar(false)}
|
||||
>
|
||||
Back to Results
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Teams Table with multiple results support */}
|
||||
{!loading && !showCalendar && !showChartView && (
|
||||
<div className="bg-white rounded-b-lg overflow-hidden shadow-lg">
|
||||
<table className="w-full border-collapse">
|
||||
<thead>
|
||||
<tr className="bg-black text-white">
|
||||
<th className="p-3 text-left">Games List</th>
|
||||
<th className="p-3 text-center">
|
||||
{dates.length > 0 && new Date(dates[0]).toLocaleDateString('en-US', { weekday: 'short' })} {dates.length > 0 && new Date(dates[0]).getDate()}th
|
||||
</th>
|
||||
<th className="p-3 text-center">
|
||||
{dates.length > 1 && new Date(dates[1]).toLocaleDateString('en-US', { weekday: 'short' })} {dates.length > 1 && new Date(dates[1]).getDate()}th
|
||||
</th>
|
||||
<th className="p-3 text-center">Chart</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{teams.map(team => (
|
||||
<tr key={team.id} className="border-b hover:bg-gray-50">
|
||||
<td className="p-3">
|
||||
<div className="font-semibold text-red-600">{team.name}</div>
|
||||
<div className="text-sm text-gray-500">at {team.time}</div>
|
||||
<div className="text-xs text-black underline mt-1 cursor-pointer hover:text-red-600" onClick={() => handleViewChart(team)}>Record Chart</div>
|
||||
</td>
|
||||
|
||||
<td className="p-3 text-center">
|
||||
{dates.length > 0 && team.results[dates[0]] && team.results[dates[0]].length > 0 ? (
|
||||
<div className="flex flex-col gap-1">
|
||||
{team.results[dates[0]].map((result, idx) => (
|
||||
<div key={idx} className="flex flex-col">
|
||||
<span className="text-2xl font-bold">{result.result}</span>
|
||||
<span className="text-xs text-gray-500">{result.time}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<span className="text-2xl font-bold text-gray-400">XX</span>
|
||||
)}
|
||||
</td>
|
||||
|
||||
<td className="p-3 text-center">
|
||||
{dates.length > 1 && team.results[dates[1]] && team.results[dates[1]].length > 0 ? (
|
||||
<div className="flex flex-col gap-1">
|
||||
{team.results[dates[1]].map((result, idx) => (
|
||||
<div key={idx} className="flex flex-col">
|
||||
<span className="text-2xl font-bold">{result.result}</span>
|
||||
<span className="text-xs text-gray-500">{result.time}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<span className="text-2xl font-bold text-gray-400">XX</span>
|
||||
)}
|
||||
</td>
|
||||
|
||||
<td className="p-3">
|
||||
<div className="flex justify-center">
|
||||
<button
|
||||
className="p-2 bg-red-100 text-red-600 rounded hover:bg-red-200 transition"
|
||||
onClick={() => handleViewChart(team)}
|
||||
title="View Monthly Chart"
|
||||
>
|
||||
<BarChart2 size={16} />
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
{teams.length === 0 && (
|
||||
<tr>
|
||||
<td colSpan="4" className="p-4 text-center">No teams found</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div className="bg-black text-white text-center p-3">
|
||||
<button className="hover:text-red-400 transition" onClick={handleCalendarView}>Click here for all games results.</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="w-full bg-white text-black">
|
||||
{/* FAQ Section */}
|
||||
<div className="max-w-6xl mx-auto py-6">
|
||||
{faqs.map((faq, index) => (
|
||||
<div key={index} className="mb-2">
|
||||
<button
|
||||
className="w-full bg-red-600 text-white text-lg font-semibold py-3 px-4 flex justify-between items-center rounded-md"
|
||||
onClick={() => toggleFAQ(index)}
|
||||
>
|
||||
{faq.question}
|
||||
<span>{openIndex === index ? "▲" : "▼"}</span>
|
||||
</button>
|
||||
{openIndex === index && (
|
||||
<div className="p-4 bg-gray-100 border border-gray-300">
|
||||
{faq.answer}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Footer Section */}
|
||||
<footer className="bg-white border-t py-6 text-center">
|
||||
<div className="max-w-3xl mx-auto text-gray-600 text-sm">
|
||||
<p className="font-bold text-xl text-black flex items-center justify-center">
|
||||
MATKA <span className="text-red-600"> SATTA</span>
|
||||
</p>
|
||||
<p className="mt-2">
|
||||
The Multi-State Lottery Association makes every effort to ensure the
|
||||
accuracy of winning numbers and other information. Official winning
|
||||
numbers are those selected in the respective drawings and recorded
|
||||
under the observation of an independent accounting firm.
|
||||
</p>
|
||||
<p className="mt-2">
|
||||
In the event of a discrepancy, the official drawing results shall
|
||||
prevail. All winning tickets must be redeemed in the
|
||||
state/jurisdiction in which they are sold.
|
||||
</p>
|
||||
<p className="mt-4 flex justify-center space-x-4 text-black font-semibold">
|
||||
<span>Media Center</span>
|
||||
<span>Legal</span>
|
||||
<span>Privacy</span>
|
||||
<span>español</span>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Home2;
|
||||
@ -2,11 +2,11 @@ import { useState } from "react";
|
||||
|
||||
const TeamMatchTable = () => {
|
||||
const [teams, setTeams] = useState([
|
||||
{ name: "GALI MATKA", time: "6:00 PM" },
|
||||
{ name: "GHAZIABAD MATKA", time: "4:00 PM" },
|
||||
{ name: "FARIDABAD MATKA", time: "12:30 PM" },
|
||||
{ name: "SHRI GANESH MATKA", time: "11:00 AM" },
|
||||
{ name: "DELHI BAZAR MATKA", time: "9:30 AM" },
|
||||
{ name: "GALI MATKA", time: "11:30 PM" },
|
||||
{ name: "GHAZIABAD MATKA", time: "9:30 PM" },
|
||||
{ name: "FARIDABAD MATKA", time: "6:00 PM" },
|
||||
{ name: "SHRI GANESH MATKA", time: "4:30 PM" },
|
||||
{ name: "DELHI BAZAR MATKA", time: "3:00 PM" },
|
||||
{ name: "DESAWAR MATKA", time: "5:00 AM" },
|
||||
]);
|
||||
|
||||
|
||||
@ -9,10 +9,8 @@ const MatkaResultsDashboard = () => {
|
||||
const [currentDate, setCurrentDate] = useState('');
|
||||
const [expandedTeams, setExpandedTeams] = useState({});
|
||||
|
||||
// API URL
|
||||
const API_URL = 'http://localhost:5500/api';
|
||||
|
||||
// Matka team descriptions and tips
|
||||
const matkaTeamInfo = {
|
||||
"Desawar Matka": {
|
||||
description: "Start your day with the latest Desawar Matka results at 5:00 AM. Our platform provides real-time updates and accurate results to help you stay ahead.",
|
||||
@ -40,17 +38,22 @@ const MatkaResultsDashboard = () => {
|
||||
}
|
||||
};
|
||||
|
||||
// Format time
|
||||
const normalizeTeamName = (teamName) => teamName.trim().toLowerCase();
|
||||
|
||||
const normalizedMatkaTeamInfo = Object.keys(matkaTeamInfo).reduce((acc, key) => {
|
||||
acc[key.trim().toLowerCase()] = matkaTeamInfo[key];
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const formatTime = (timeString) => {
|
||||
try {
|
||||
const date = new Date(timeString);
|
||||
return date.toLocaleTimeString("en-US", { hour: '2-digit', minute: '2-digit', hour12: true });
|
||||
} catch (e) {
|
||||
} catch {
|
||||
return "XX:XX";
|
||||
}
|
||||
};
|
||||
|
||||
// Toggle team expansion
|
||||
const toggleTeamExpansion = (team) => {
|
||||
setExpandedTeams(prev => ({
|
||||
...prev,
|
||||
@ -58,13 +61,10 @@ const MatkaResultsDashboard = () => {
|
||||
}));
|
||||
};
|
||||
|
||||
// Fetch today's results
|
||||
useEffect(() => {
|
||||
const fetchTodaysResults = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
// Get today's date for display
|
||||
setError(null);
|
||||
const today = new Date();
|
||||
setCurrentDate(today.toLocaleDateString('en-US', {
|
||||
weekday: 'short',
|
||||
@ -73,11 +73,9 @@ const MatkaResultsDashboard = () => {
|
||||
year: 'numeric'
|
||||
}));
|
||||
|
||||
// Get today's results from API
|
||||
const todayResultsResponse = await axios.get(`${API_URL}/today`);
|
||||
const todayResults = todayResultsResponse.data;
|
||||
const response = await axios.get(`${API_URL}/today`);
|
||||
const todayResults = response.data;
|
||||
|
||||
// Group by team
|
||||
const teamResults = {};
|
||||
|
||||
todayResults.forEach(result => {
|
||||
@ -88,18 +86,14 @@ const MatkaResultsDashboard = () => {
|
||||
result: result.visible_result,
|
||||
time: formatTime(result.result_time),
|
||||
timestamp: new Date(result.result_time),
|
||||
upcoming: new Date(result.result_time) > new Date(),
|
||||
description: matkaTeamInfo[result.team]?.description || "Stay updated with the latest results.",
|
||||
tip: matkaTeamInfo[result.team]?.tip || "Check regularly for updates and follow trends."
|
||||
upcoming: new Date(result.result_time) > new Date()
|
||||
});
|
||||
});
|
||||
|
||||
// Convert to array for display and initialize expanded state
|
||||
const groupedResults = Object.entries(teamResults).map(([team, results]) => {
|
||||
// Sort by time
|
||||
const sortedResults = results.sort((a, b) => a.timestamp - b.timestamp);
|
||||
const normalizedTeam = normalizeTeamName(team);
|
||||
|
||||
// Set all teams expanded by default
|
||||
setExpandedTeams(prev => ({
|
||||
...prev,
|
||||
[team]: true
|
||||
@ -107,6 +101,8 @@ const MatkaResultsDashboard = () => {
|
||||
|
||||
return {
|
||||
team,
|
||||
description: normalizedMatkaTeamInfo[normalizedTeam]?.description || "Stay updated with the latest results.",
|
||||
tip: normalizedMatkaTeamInfo[normalizedTeam]?.tip || "Check regularly for updates and follow trends.",
|
||||
results: sortedResults,
|
||||
upcomingCount: sortedResults.filter(r => r.upcoming).length,
|
||||
completedCount: sortedResults.filter(r => !r.upcoming).length
|
||||
@ -122,81 +118,24 @@ const MatkaResultsDashboard = () => {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchTodaysResults();
|
||||
}, []);
|
||||
|
||||
// Refresh data
|
||||
const handleRefresh = () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
// Get today's results from API
|
||||
const todayResultsResponse = await axios.get(`${API_URL}/today`);
|
||||
const todayResults = todayResultsResponse.data;
|
||||
|
||||
// Group by team
|
||||
const teamResults = {};
|
||||
|
||||
todayResults.forEach(result => {
|
||||
if (!teamResults[result.team]) {
|
||||
teamResults[result.team] = [];
|
||||
}
|
||||
teamResults[result.team].push({
|
||||
result: result.visible_result,
|
||||
time: formatTime(result.result_time),
|
||||
timestamp: new Date(result.result_time),
|
||||
upcoming: new Date(result.result_time) > new Date(),
|
||||
description: matkaTeamInfo[result.team]?.description || "Stay updated with the latest results.",
|
||||
tip: matkaTeamInfo[result.team]?.tip || "Check regularly for updates and follow trends."
|
||||
});
|
||||
});
|
||||
|
||||
// Convert to array for display
|
||||
const groupedResults = Object.entries(teamResults).map(([team, results]) => {
|
||||
// Sort by time
|
||||
const sortedResults = results.sort((a, b) => a.timestamp - b.timestamp);
|
||||
|
||||
return {
|
||||
team,
|
||||
results: sortedResults,
|
||||
upcomingCount: sortedResults.filter(r => r.upcoming).length,
|
||||
completedCount: sortedResults.filter(r => !r.upcoming).length
|
||||
};
|
||||
});
|
||||
|
||||
setTodaysResults(groupedResults);
|
||||
setLoading(false);
|
||||
} catch (err) {
|
||||
setError("Failed to refresh Matka data. Please try again later.");
|
||||
setLoading(false);
|
||||
}
|
||||
fetchTodaysResults();
|
||||
};
|
||||
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// Get status badge
|
||||
const getStatusBadge = (result) => {
|
||||
if (result.upcoming) {
|
||||
return (
|
||||
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
|
||||
Upcoming
|
||||
</span>
|
||||
const getStatusBadge = (result) => (
|
||||
result.upcoming ? (
|
||||
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">Upcoming</span>
|
||||
) : (
|
||||
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">Completed</span>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
|
||||
Completed
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-white rounded-lg shadow-lg overflow-hidden">
|
||||
{/* Header */}
|
||||
<div className="bg-gradient-to-r from-red-600 to-red-800 p-4 text-white">
|
||||
<div className="flex items-center justify-between">
|
||||
<h1 className="text-2xl font-bold">Today's Matka Results</h1>
|
||||
@ -207,12 +146,9 @@ const MatkaResultsDashboard = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Controls */}
|
||||
<div className="bg-gray-50 p-4 flex justify-between items-center border-b">
|
||||
<div className="text-sm font-medium text-gray-500">
|
||||
{todaysResults.length > 0 ?
|
||||
`${todaysResults.length} teams with results today` :
|
||||
"No results scheduled"}
|
||||
{todaysResults.length > 0 ? `${todaysResults.length} teams with results today` : "No results scheduled"}
|
||||
</div>
|
||||
<button
|
||||
className="bg-red-600 text-white px-4 py-2 rounded-md flex items-center gap-2 hover:bg-red-700 transition shadow-sm"
|
||||
@ -224,7 +160,6 @@ const MatkaResultsDashboard = () => {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Loading indicator */}
|
||||
{loading && (
|
||||
<div className="p-8 flex justify-center items-center">
|
||||
<div className="flex items-center gap-2">
|
||||
@ -234,13 +169,10 @@ const MatkaResultsDashboard = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Error message */}
|
||||
{error && (
|
||||
<div className="bg-red-50 border-l-4 border-red-500 p-4 m-4">
|
||||
<div className="flex">
|
||||
<div className="flex-shrink-0">
|
||||
<AlertTriangle className="h-5 w-5 text-red-400" />
|
||||
</div>
|
||||
<div className="ml-3">
|
||||
<p className="text-sm text-red-700">{error}</p>
|
||||
</div>
|
||||
@ -248,14 +180,12 @@ const MatkaResultsDashboard = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Results display */}
|
||||
{!loading && !error && (
|
||||
<div className="p-4">
|
||||
{todaysResults.length > 0 ? (
|
||||
<div className="space-y-4">
|
||||
{todaysResults.map((teamData, index) => (
|
||||
<div key={index} className="border border-gray-200 rounded-lg overflow-hidden shadow-sm">
|
||||
{/* Team header - clickable to expand/collapse */}
|
||||
<div
|
||||
className="bg-gradient-to-r from-gray-800 to-gray-700 text-white p-3 flex justify-between items-center cursor-pointer hover:from-gray-700 hover:to-gray-600 transition"
|
||||
onClick={() => toggleTeamExpansion(teamData.team)}
|
||||
@ -265,44 +195,29 @@ const MatkaResultsDashboard = () => {
|
||||
<div className="text-xs bg-opacity-20 bg-white px-2 py-1 rounded-full">
|
||||
<span className="font-medium">{teamData.upcomingCount}</span> upcoming • <span className="font-medium">{teamData.completedCount}</span> completed
|
||||
</div>
|
||||
{expandedTeams[teamData.team] ? (
|
||||
<ChevronUp size={20} />
|
||||
) : (
|
||||
<ChevronDown size={20} />
|
||||
)}
|
||||
{expandedTeams[teamData.team] ? <ChevronUp size={20} /> : <ChevronDown size={20} />}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Team results */}
|
||||
{expandedTeams[teamData.team] && (
|
||||
<div>
|
||||
<div className="px-4 py-3 bg-gray-50 border-t border-gray-100">
|
||||
<p className="text-sm text-gray-700">{teamData.description}</p>
|
||||
</div>
|
||||
<div className="px-4 py-3 bg-yellow-50 border-t border-yellow-100">
|
||||
<p className="text-sm text-yellow-800">
|
||||
<span className="font-bold">Pro Tip:</span> {teamData.tip}
|
||||
</p>
|
||||
</div>
|
||||
{teamData.results.map((result, idx) => (
|
||||
<div key={idx}>
|
||||
<div className={`p-4 flex justify-between items-center ${result.upcoming ? "bg-blue-50" : "bg-white"}`}>
|
||||
<div key={idx} className={`p-4 flex justify-between items-center ${result.upcoming ? "bg-blue-50" : "bg-white"}`}>
|
||||
<div className="flex items-center space-x-3">
|
||||
<Clock size={16} className="text-gray-400" />
|
||||
<span className="font-medium">{result.time}</span>
|
||||
{getStatusBadge(result)}
|
||||
</div>
|
||||
<div className="text-xl font-bold">
|
||||
{result.upcoming ? (
|
||||
<span className="text-gray-400">--</span>
|
||||
) : (
|
||||
<span className="text-gray-800">{result.result}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Description */}
|
||||
<div className="px-4 py-3 bg-gray-50 border-t border-gray-100">
|
||||
<p className="text-sm text-gray-700">{result.description}</p>
|
||||
</div>
|
||||
|
||||
{/* Pro Tip */}
|
||||
<div className="px-4 py-3 bg-yellow-50 border-t border-yellow-100">
|
||||
<p className="text-sm text-yellow-800">
|
||||
<span className="font-bold">Pro Tip:</span> {result.tip}
|
||||
</p>
|
||||
{result.upcoming ? <span className="text-gray-400">--</span> : <span className="text-gray-800">{result.result}</span>}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
@ -313,9 +228,7 @@ const MatkaResultsDashboard = () => {
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-center p-8">
|
||||
<div className="mx-auto h-12 w-12 text-gray-400">
|
||||
<Calendar className="h-12 w-12" />
|
||||
</div>
|
||||
<Calendar className="h-12 w-12 text-gray-400 mx-auto" />
|
||||
<h3 className="mt-2 text-sm font-medium text-gray-900">No results today</h3>
|
||||
<p className="mt-1 text-sm text-gray-500">There are no Matka results scheduled for today.</p>
|
||||
</div>
|
||||
|
||||
@ -1,35 +1,34 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { RefreshCw, Clock, ChevronRight, ChevronLeft } from 'lucide-react';
|
||||
import { RefreshCw, Clock } from 'lucide-react';
|
||||
import axios from 'axios';
|
||||
import TeamMatchTable from './Teams';
|
||||
|
||||
const TodaysMatch = () => {
|
||||
const [todaysMatches, setTodaysMatches] = useState([]);
|
||||
const [completedMatches, setCompletedMatches] = useState([]);
|
||||
const [upcomingMatches, setUpcomingMatches] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(null);
|
||||
const [currentDate, setCurrentDate] = useState('');
|
||||
const [activeTeamIndex, setActiveTeamIndex] = useState(0);
|
||||
|
||||
// API URL
|
||||
const API_URL = 'http://localhost:5500/api';
|
||||
// API URL (from environment variable)
|
||||
const API_URL = "http://localhost:5500/api";
|
||||
|
||||
// Format time
|
||||
// Format time function
|
||||
const formatTime = (timeString) => {
|
||||
try {
|
||||
const date = new Date(timeString);
|
||||
return date.toLocaleTimeString("en-US", { hour: '2-digit', minute: '2-digit', hour12: true });
|
||||
return date.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', hour12: true });
|
||||
} catch (e) {
|
||||
return "XX:XX";
|
||||
return 'XX:XX';
|
||||
}
|
||||
};
|
||||
|
||||
// Fetch today's matches
|
||||
useEffect(() => {
|
||||
const fetchTodaysMatches = async () => {
|
||||
// Fetch matches
|
||||
const fetchMatches = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
// Get today's date for display
|
||||
// Set today's date
|
||||
const today = new Date();
|
||||
setCurrentDate(today.toLocaleDateString('en-US', {
|
||||
weekday: 'short',
|
||||
@ -38,102 +37,52 @@ const TodaysMatch = () => {
|
||||
year: 'numeric'
|
||||
}));
|
||||
|
||||
// Get today's results
|
||||
const todayResultsResponse = await axios.get(`${API_URL}/today`);
|
||||
const todayResults = todayResultsResponse.data;
|
||||
const response = await axios.get(`${API_URL}/today`);
|
||||
const results = response.data;
|
||||
|
||||
// Group by team
|
||||
const teamResults = {};
|
||||
const completed = [];
|
||||
const upcoming = [];
|
||||
|
||||
todayResults.forEach(result => {
|
||||
if (!teamResults[result.team]) {
|
||||
teamResults[result.team] = [];
|
||||
}
|
||||
teamResults[result.team].push({
|
||||
results.forEach(result => {
|
||||
const isUpcoming = new Date(result.result_time) > new Date();
|
||||
|
||||
const matchInfo = {
|
||||
team: result.team,
|
||||
result: result.visible_result,
|
||||
time: formatTime(result.result_time),
|
||||
upcoming: new Date(result.result_time) > new Date()
|
||||
});
|
||||
};
|
||||
|
||||
if (isUpcoming) {
|
||||
upcoming.push(matchInfo);
|
||||
} else {
|
||||
completed.push(matchInfo);
|
||||
}
|
||||
});
|
||||
|
||||
// Convert to array for display
|
||||
const groupedResults = Object.entries(teamResults).map(([team, results]) => ({
|
||||
team,
|
||||
results: results.sort((a, b) => a.upcoming - b.upcoming)
|
||||
}));
|
||||
|
||||
setTodaysMatches(groupedResults);
|
||||
setCompletedMatches(completed);
|
||||
setUpcomingMatches(upcoming);
|
||||
setLoading(false);
|
||||
} catch (err) {
|
||||
console.error("Error fetching today's matches:", err);
|
||||
setError("Failed to load today's match data. Please try again later.");
|
||||
console.error("Error fetching matches:", err);
|
||||
setError("Failed to load match data. Please try again later.");
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchTodaysMatches();
|
||||
// On component mount
|
||||
useEffect(() => {
|
||||
fetchMatches();
|
||||
}, []);
|
||||
|
||||
// Navigation handlers
|
||||
const handleNext = () => {
|
||||
if (todaysMatches.length > 0) {
|
||||
setActiveTeamIndex((prevIndex) =>
|
||||
prevIndex === todaysMatches.length - 1 ? 0 : prevIndex + 1
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handlePrev = () => {
|
||||
if (todaysMatches.length > 0) {
|
||||
setActiveTeamIndex((prevIndex) =>
|
||||
prevIndex === 0 ? todaysMatches.length - 1 : prevIndex - 1
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// Refresh data
|
||||
// Refresh handler
|
||||
const handleRefresh = () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const todayResultsResponse = await axios.get(`${API_URL}/today`);
|
||||
const todayResults = todayResultsResponse.data;
|
||||
|
||||
const teamResults = {};
|
||||
|
||||
todayResults.forEach(result => {
|
||||
if (!teamResults[result.team]) {
|
||||
teamResults[result.team] = [];
|
||||
}
|
||||
teamResults[result.team].push({
|
||||
result: result.visible_result,
|
||||
time: formatTime(result.result_time),
|
||||
upcoming: new Date(result.result_time) > new Date()
|
||||
});
|
||||
});
|
||||
|
||||
const groupedResults = Object.entries(teamResults).map(([team, results]) => ({
|
||||
team,
|
||||
results: results.sort((a, b) => a.upcoming - b.upcoming)
|
||||
}));
|
||||
|
||||
setTodaysMatches(groupedResults);
|
||||
setLoading(false);
|
||||
} catch (err) {
|
||||
setError("Failed to refresh match data. Please try again later.");
|
||||
setLoading(false);
|
||||
}
|
||||
fetchMatches();
|
||||
};
|
||||
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// Render boxes similar to lottery design
|
||||
return (
|
||||
<div className="flex flex-col md:flex-row gap-4">
|
||||
{/* Today's Matches Box */}
|
||||
|
||||
{/* Matches Box */}
|
||||
<div className="bg-gray-200 rounded-lg shadow-lg overflow-hidden w-full md:w-1/3">
|
||||
<div className="bg-white p-4 rounded-t-lg">
|
||||
<h2 className="text-center font-bold text-xl text-gray-800">Winning Numbers</h2>
|
||||
@ -147,145 +96,95 @@ const TodaysMatch = () => {
|
||||
</div>
|
||||
) : error ? (
|
||||
<div className="bg-red-100 border border-red-400 text-red-700 p-3 rounded">
|
||||
<p>{error}</p>
|
||||
</div>
|
||||
) : todaysMatches.length > 0 ? (
|
||||
<div className="relative">
|
||||
{/* Navigation buttons */}
|
||||
<button
|
||||
onClick={handlePrev}
|
||||
className="absolute left-0 top-1/2 transform -translate-y-1/2 bg-gray-800 text-white rounded-full p-1 z-10"
|
||||
>
|
||||
<ChevronLeft size={20} />
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={handleNext}
|
||||
className="absolute right-0 top-1/2 transform -translate-y-1/2 bg-gray-800 text-white rounded-full p-1 z-10"
|
||||
>
|
||||
<ChevronRight size={20} />
|
||||
</button>
|
||||
|
||||
{/* Current team results */}
|
||||
<div className="py-2">
|
||||
<div className="bg-gray-800 text-white p-2 font-semibold rounded-t mb-2">
|
||||
{todaysMatches[activeTeamIndex]?.team || "No Team"}
|
||||
</div>
|
||||
|
||||
<div className="overflow-y-auto max-h-48">
|
||||
{todaysMatches[activeTeamIndex]?.results.map((result, idx) => (
|
||||
<div key={idx} className="flex justify-between items-center bg-white p-3 mb-2 rounded shadow">
|
||||
<div className="flex items-center gap-2">
|
||||
<Clock size={16} className="text-gray-500" />
|
||||
<span>{result.time}</span>
|
||||
</div>
|
||||
<div className={`text-xl font-bold ${result.upcoming ? 'text-gray-400' : 'text-red-600'}`}>
|
||||
{result.upcoming ? "Upcoming" : result.result}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Team indicators */}
|
||||
<div className="flex justify-center gap-1 mt-2">
|
||||
{todaysMatches.map((_, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className={`h-2 w-2 rounded-full ${idx === activeTeamIndex ? 'bg-red-600' : 'bg-gray-400'}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
{error}
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-center p-6 text-gray-500">
|
||||
No match results available for today.
|
||||
<div className="text-left">
|
||||
|
||||
{/* Completed Matches */}
|
||||
<div className="mb-6">
|
||||
<h4 className="font-bold text-lg mb-2 text-gray-700">Completed Matches</h4>
|
||||
{completedMatches.length > 0 ? (
|
||||
<div className="flex flex-col gap-2">
|
||||
{completedMatches.map((match, idx) => (
|
||||
<div key={idx} className="flex justify-between bg-white p-3 rounded shadow">
|
||||
<span className="font-medium">{match.team}</span>
|
||||
<span className="text-red-600 font-bold">{match.result}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-gray-500">No completed matches yet.</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Upcoming Matches */}
|
||||
<div>
|
||||
<h4 className="font-bold text-lg mb-2 text-gray-700">Upcoming Matches</h4>
|
||||
{upcomingMatches.length > 0 ? (
|
||||
<div className="flex flex-col gap-2">
|
||||
{upcomingMatches.map((match, idx) => (
|
||||
<div key={idx} className="flex justify-between bg-white p-3 rounded shadow">
|
||||
<span className="font-medium">{match.team}</span>
|
||||
<div className="flex items-center gap-1 text-gray-500">
|
||||
<Clock size={16} /> {match.time}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-gray-500">No upcoming matches scheduled.</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Refresh Button */}
|
||||
<button
|
||||
className="bg-red-600 text-white px-6 py-2 rounded-full font-bold mt-4 hover:bg-red-700 transition"
|
||||
onClick={handleRefresh}
|
||||
>
|
||||
PLay Now
|
||||
Refresh
|
||||
</button>
|
||||
|
||||
{/* <div className="mt-4 grid gap-2">
|
||||
<button className="bg-gray-800 text-white p-3 rounded font-medium">
|
||||
VIEW RESULTS
|
||||
</button>
|
||||
<button className="bg-gray-800 text-white p-3 rounded font-medium">
|
||||
CHECK YOUR NUMBERS
|
||||
</button>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Next Drawing Box */}
|
||||
{/* Other Boxes */}
|
||||
<div className="bg-gray-200 rounded-lg shadow-lg overflow-hidden w-full md:w-1/3">
|
||||
<div className="bg-white p-4 rounded-t-lg">
|
||||
<h2 className="text-center font-bold text-xl text-gray-800">Next Drawing</h2>
|
||||
<h2 className="text-center font-bold text-xl text-gray-800">Register To Play</h2>
|
||||
</div>
|
||||
<div className="p-4 text-center">
|
||||
<h3 className="font-medium text-lg mb-4">Sat, Mar 22, 2025</h3>
|
||||
|
||||
<div className="flex justify-center gap-2 my-4">
|
||||
<div className="bg-gray-800 text-white w-12 h-12 flex items-center justify-center rounded">
|
||||
<div className="text-xl font-bold">67</div>
|
||||
</div>
|
||||
<div className="bg-gray-800 text-white w-12 h-12 flex items-center justify-center rounded">
|
||||
<div className="text-xl font-bold">58</div>
|
||||
</div>
|
||||
<div className="bg-gray-800 text-white w-12 h-12 flex items-center justify-center rounded">
|
||||
<div className="text-xl font-bold">11</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center gap-2 text-xs text-gray-600 mb-4">
|
||||
<div className="text-center w-12">HOURS</div>
|
||||
<div className="text-center w-12">MINUTES</div>
|
||||
<div className="text-center w-12">SECONDS</div>
|
||||
</div>
|
||||
|
||||
<h3 className="font-medium text-lg mb-4">
|
||||
Delhi Bazaar, Shri Ganesh, De Delhi, Faridabad, Ghaziabad, Gali and Disawar Satta, now play from anywhere.
|
||||
</h3>
|
||||
<div className="bg-gray-800 text-yellow-400 p-2 font-bold mb-2">
|
||||
ESTIMATED JACKPOT
|
||||
No tension of payment, work of trust done with trust.
|
||||
</div>
|
||||
|
||||
<div className="text-red-600 text-4xl font-bold mb-4">
|
||||
$444 Million
|
||||
<div className="text-gray-800 text-sm mb-4 leading-relaxed">
|
||||
Play the game without any worry.
|
||||
<br />
|
||||
<span className="font-bold text-gray-900">((( HARRY )))</span><br />
|
||||
<span className="text-red-600 font-bold text-lg">📞 7830467644</span>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<a href="#" className="bg-green-600 text-white font-bold py-2 rounded hover:bg-green-700 transition">CALL NOW</a>
|
||||
<a href="#" className="bg-blue-600 text-white font-bold py-2 rounded hover:bg-blue-700 transition">WHATSAPP NOW</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Winners Box */}
|
||||
{/* Today's Timing Box */}
|
||||
<div className="bg-gray-200 rounded-lg shadow-lg overflow-hidden w-full md:w-1/3">
|
||||
<div className="bg-white p-4 rounded-t-lg">
|
||||
<h2 className="text-center font-bold text-xl text-gray-800">Today's Timing</h2>
|
||||
</div>
|
||||
<div className="p-4">
|
||||
{/* <h3 className="font-medium text-lg mb-4">{currentDate}</h3> */}
|
||||
|
||||
{/* <div className="text-center mb-4">
|
||||
<div className="font-bold">Team Alpha</div>
|
||||
<div className="text-2xl font-bold">JACKPOT WINNERS</div>
|
||||
<div className="text-red-600 text-xl">None</div>
|
||||
</div>
|
||||
|
||||
<div className="text-center mb-4">
|
||||
<div className="font-bold">Team Beta</div>
|
||||
<div className="text-2xl font-bold">$2 MILLION WINNERS</div>
|
||||
<div className="text-red-600 text-xl">CO, TX</div>
|
||||
</div>
|
||||
|
||||
<div className="text-center">
|
||||
<div className="font-bold">MATCH 5</div>
|
||||
<div className="text-2xl font-bold">$1 MILLION WINNERS</div>
|
||||
<div className="text-red-600 text-xl">None</div>
|
||||
</div> */}
|
||||
<TeamMatchTable />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user