CoolFace
Apppublic

ideleon24/tinytots-tracker-kiosk

sourceHugging Faceupdated 11mo agoView on Hugging Face
0likes
admin.html228 linesDownload Raw Back to root
1<!DOCTYPE html>2<html lang="en">3<head>4    <meta charset="UTF-8">5    <meta name="viewport" content="width=device-width, initial-scale=1.0">6    <title>Nachito's Admin Dashboard</title>7    <link rel="icon" type="image/x-icon" href="/static/favicon.ico">8    <script src="https://cdn.tailwindcss.com"></script>9    <script src="https://unpkg.com/feather-icons"></script>10</head>11<body class="bg-gray-100">12    <div class="flex h-screen">13        <!-- Sidebar -->14        <div class="bg-gray-800 text-white w-64 p-4">15            <div class="flex items-center space-x-2 mb-8 p-2">16                <img src="https://huggingface.co/spaces/ideleon24/tinytots-tracker-kiosk/resolve/main/images/Screen_Shot_2023-01-17_at_10.05.09_PM-removebg-preview.png" class="h-10 w-10">17<span class="font-bold text-lg">Admin Portal</span>18            </div>19            <nav>20                <a href="#" class="flex items-center space-x-2 p-2 bg-gray-700 rounded-lg">21                    <i data-feather="calendar" class="h-5 w-5"></i>22                    <span>Attendance</span>23                </a>24                <a href="#" class="flex items-center space-x-2 p-2 hover:bg-gray-700 rounded-lg mt-1">25                    <i data-feather="users" class="h-5 w-5"></i>26                    <span>Children</span>27                </a>28                <a href="#" class="flex items-center space-x-2 p-2 hover:bg-gray-700 rounded-lg mt-1">29                    <i data-feather="file-text" class="h-5 w-5"></i>30                    <span>Reports</span>31                </a>32            </nav>33        </div>34 35        <!-- Main Content -->36        <div class="flex-1 overflow-auto">37            <header class="bg-white shadow-sm p-4">38                <h1 class="text-2xl font-bold text-gray-800">39                    <i data-feather="calendar" class="inline mr-2"></i> 40                    Attendance Records41                </h1>42            </header>43 44            <main class="p-6">45                <div class="bg-white rounded-lg shadow overflow-hidden">46                    <div class="p-4 border-b flex justify-between items-center">47                        <div class="flex items-center space-x-4">48                            <input type="date" class="border rounded px-3 py-1">49                            <button class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-1 rounded">50Filter51                            </button>52                        </div>53                        <button class="bg-gray-100 hover:bg-gray-200 px-4 py-1 rounded flex items-center">54                            <i data-feather="download" class="mr-2 w-4 h-4"></i>55                            Export56                        </button>57                    </div>58 59                    <div class="overflow-x-auto">60                        <table class="min-w-full divide-y divide-gray-200">61                            <thead class="bg-gray-50">62                                <tr>63                                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Child</th>64                                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Time In</th>65                                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Time Out</th>66                                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Parent</th>67                                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Signature</th>68                                </tr>69                            </thead>70                            <tbody class="bg-white divide-y divide-gray-200">71                                <tr>72                                    <td class="px-6 py-4 whitespace-nowrap">Emma Johnson</td>73                                    <td class="px-6 py-4 whitespace-nowrap">08:15 AM</td>74                                    <td class="px-6 py-4 whitespace-nowrap">-</td>75                                    <td class="px-6 py-4 whitespace-nowrap">Sarah Johnson</td>76                                    <td class="px-6 py-4 whitespace-nowrap text-blue-500">View</td>77                                </tr>78                                <tr>79                                    <td class="px-6 py-4 whitespace-nowrap">Michael Chen</td>80                                    <td class="px-6 py-4 whitespace-nowrap">08:05 AM</td>81                                    <td class="px-6 py-4 whitespace-nowrap">04:30 PM</td>82                                    <td class="px-6 py-4 whitespace-nowrap">Lisa Chen</td>83                                    <td class="px-6 py-4 whitespace-nowrap text-blue-500">View</td>84                                </tr>85                            </tbody>86                        </table>87                    </div>88                </div>89            </main>90        </div>91    </div>92    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>93    <script>94        feather.replace();95        // Get records from API96        async function getAttendanceRecords() {97            try {98                const apiUrl = 'https://6613f7a153b0d5d80f66fc45.mockapi.io/api/v1/attendance';99                const response = await axios.get(apiUrl);100                return response.data;101            } catch (error) {102                console.error('API error:', error);103                return [];104            }105        }106// Display records in table107        function displayRecords(records) {108            const tbody = document.querySelector('tbody');109            tbody.innerHTML = '';110            111            if (records.length === 0) {112                const tr = document.createElement('tr');113                tr.innerHTML = `114                    <td colspan="5" class="px-6 py-4 text-center text-gray-500">115                        No attendance records found116                    </td>117                `;118                tbody.appendChild(tr);119                return;120            }121            122            records.forEach(record => {123                const tr = document.createElement('tr');124                tr.innerHTML = `125                    <td class="px-6 py-4 whitespace-nowrap">${record.childName}</td>126                    <td class="px-6 py-4 whitespace-nowrap">${record.timeIn}</td>127                    <td class="px-6 py-4 whitespace-nowrap">${record.timeOut || '-'}</td>128                    <td class="px-6 py-4 whitespace-nowrap">${record.parentName}</td>129                    <td class="px-6 py-4 whitespace-nowrap">130                        ${record.signature ? 131                            `<button onclick="showSignature('${record.childName}', '${record.signature}')" 132                             class="text-blue-500 hover:underline">View</button>` : 133                            'N/A'}134                    </td>135                `;136                tbody.appendChild(tr);137            });138        }139        140        // Show signature modal141        function showSignature(childName, signatureData) {142            const modal = document.createElement('div');143            modal.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50';144            modal.innerHTML = `145                <div class="bg-white rounded-lg p-6 max-w-md w-full">146                    <div class="flex justify-between items-center mb-4">147                        <h3 class="text-lg font-bold">${childName}'s Signature</h3>148                        <button onclick="this.parentNode.parentNode.parentNode.remove()" 149                            class="text-gray-500 hover:text-gray-700">150                            <i data-feather="x"></i>151                        </button>152                    </div>153                    <img src="${signatureData}" alt="Signature" class="w-full border rounded">154                    <div class="mt-4 text-right">155                        <button onclick="this.parentNode.parentNode.parentNode.remove()" 156                            class="px-4 py-2 bg-gray-100 hover:bg-gray-200 rounded">157                            Close158                        </button>159                    </div>160                </div>161            `;162            document.body.appendChild(modal);163            feather.replace();164        }165        // Filter records by date166        async function filterRecords() {167            const dateInput = document.querySelector('input[type="date"]');168            const selectedDate = dateInput.value;169            let records = await getAttendanceRecords();170            171            if (selectedDate) {172                records = records.filter(record => record.date === selectedDate);173            }174displayRecords(records);175        }176        // Export to CSV177        async function exportToCSV() {178            const records = await getAttendanceRecords();179if (records.length === 0) {180                alert('No records to export');181                return;182            }183            184            const headers = ['Child Name', 'Parent Name', 'Date', 'Time In', 'Time Out'];185            const csvRows = [];186            187            // Add header row188            csvRows.push(headers.join(','));189            190            // Add data rows191            records.forEach(record => {192                const values = [193                    `"${record.childName}"`,194                    `"${record.parentName}"`,195                    `"${record.date}"`,196                    `"${record.timeIn}"`,197                    `"${record.timeOut || ''}"`198                ];199                csvRows.push(values.join(','));200            });201            202            // Create CSV file203            const csvContent = csvRows.join('\n');204            const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });205            const url = URL.createObjectURL(blob);206            207            // Create download link208            const link = document.createElement('a');209            link.href = url;210            link.download = `attendance_${new Date().toISOString().split('T')[0]}.csv`;211            document.body.appendChild(link);212            link.click();213            document.body.removeChild(link);214        }215        // Initial load216        document.addEventListener('DOMContentLoaded', async () => {217            const today = new Date().toISOString().split('T')[0];218            document.querySelector('input[type="date"]').value = today;219            220            const records = await getAttendanceRecords();221            displayRecords(records);222            223            document.querySelector('button[class*="bg-blue"]').addEventListener('click', filterRecords);224            document.querySelector('button[class*="bg-gray"]').addEventListener('click', exportToCSV);225        });226</script>227</body>228</html>