bazar2/src/pages/Admin.js
2025-03-16 15:54:54 +05:30

586 lines
20 KiB
JavaScript

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">
&lt;
</button>
<div className="font-semibold">
{monthNames[calendarMonth]} {calendarYear}
</div>
<button onClick={handleNextMonth} className="p-1 rounded hover:bg-gray-100">
&gt;
</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;