Created
April 30, 2025 16:44
-
-
Save fluxion9/2edf5070a95b530a4d98f6a780178062 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
?> | |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<title>Mediconnect 4.0 - User Details</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<script> | |
tailwind.config = { | |
theme: { | |
extend: { | |
colors: { | |
"primary-blue-light": "#a2aad9", | |
"primary-blue-dark": "#8990c9", | |
"primary-green": "#9bdcbc", | |
"top-gradient": "#9bdcbc", | |
"bottom-gradient": "#9293d4", | |
}, | |
fontFamily: { | |
poppins: ["Poppins", "sans-serif"], | |
}, | |
}, | |
}, | |
}; | |
</script> | |
<link | |
href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" | |
rel="stylesheet" | |
/> | |
<style> | |
body { | |
font-family: "Poppins", sans-serif; | |
} | |
/* Ensure focus states are visible */ | |
input:focus, | |
button:focus { | |
outline: 2px solid #a2aad9; | |
outline-offset: 2px; | |
} | |
</style> | |
</head> | |
<body | |
class="bg-gradient-to-b from-[#9bdcbc] to-[#9293d4] min-h-screen font-poppins text-[#010101]" | |
> | |
<header class="backdrop-blur-md shadow-sm sticky top-0 z-10"> | |
<div | |
class="container mx-auto px-4 py-4 flex items-center justify-between" | |
> | |
<div class="flex items-center gap-2"> | |
<div | |
class="h-8 w-8 rounded-full bg-gradient-to-r from-[#9bdcbc] to-[#9293d4] flex items-center justify-center" | |
> | |
<svg | |
xmlns="http://www.w3.org/2000/svg" | |
class="h-4 w-4 text-white" | |
fill="none" | |
viewBox="0 0 24 24" | |
stroke="currentColor" | |
> | |
<path | |
stroke-linecap="round" | |
stroke-linejoin="round" | |
stroke-width="2" | |
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" | |
/> | |
</svg> | |
</div> | |
<h1 class="text-xl font-bold tracking-tight text-gray-900"> | |
Mediconnect Registration Details | |
</h1> | |
</div> | |
<a | |
href="https://mymediconnect.co/4.0/events/nma2025/" | |
class="px-6 py-2 rounded-full bg-[#a2aad9] text-white hover:bg-[#8990c9] hover:shadow-lg transition-all duration-300 text-sm font-medium flex items-center gap-2" | |
> | |
<svg | |
xmlns="http://www.w3.org/2000/svg" | |
class="h-4 w-4" | |
fill="none" | |
viewBox="0 0 24 24" | |
stroke="currentColor" | |
> | |
<path | |
stroke-linecap="round" | |
stroke-linejoin="round" | |
stroke-width="2" | |
d="M10 19l-7-7m0 0l7-7m-7 7h18" | |
/> | |
</svg> | |
Back to Search | |
</a> | |
</div> | |
</header> | |
<main class="container mx-auto px-4 py-8"> | |
<!-- User Registration Details Section --> | |
<div class="max-w-3xl mx-auto"> | |
<!-- Loading State --> | |
<div | |
id="loadingState" | |
class="rounded-xl p-8 backdrop-blur-sm bg-white/20 shadow-lg border border-white/10 flex flex-col items-center justify-center" | |
> | |
<div | |
class="w-16 h-16 border-4 border-[#a2aad9] border-t-transparent rounded-full animate-spin mb-4" | |
></div> | |
<p class="font-medium text-lg"> | |
Loading your registration details... | |
</p> | |
</div> | |
<!-- Error State --> | |
<div | |
id="errorState" | |
class="hidden rounded-xl p-8 backdrop-blur-sm bg-white/20 shadow-lg border border-white/10" | |
> | |
<div class="flex flex-col items-center text-center"> | |
<div | |
class="w-20 h-20 bg-red-100 rounded-full flex items-center justify-center mb-6" | |
> | |
<svg | |
xmlns="http://www.w3.org/2000/svg" | |
class="h-10 w-10 text-red-600" | |
fill="none" | |
viewBox="0 0 24 24" | |
stroke="currentColor" | |
> | |
<path | |
stroke-linecap="round" | |
stroke-linejoin="round" | |
stroke-width="2" | |
d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" | |
/> | |
</svg> | |
</div> | |
<h2 class="text-2xl font-bold mb-2">No Registration Data Found</h2> | |
<p class="text-gray-600 mb-6"> | |
We couldn't find your registration details. Please return to the | |
search page to look up your registration. | |
</p> | |
<a | |
href="https://mymediconnect.co/4.0/events/nma2025/" | |
class="px-6 py-2 rounded-full bg-[#a2aad9] text-white hover:bg-[#8990c9] hover:shadow-lg transition-all duration-300 text-sm font-medium focus:ring-2 focus:ring-[#a2aad9] focus:ring-opacity-50" | |
> | |
Return to Search | |
</a> | |
</div> | |
</div> | |
<!-- User Data State --> | |
<div id="userDataState" class="hidden"> | |
<!-- Personal Information Card --> | |
<div | |
class="rounded-xl p-6 md:p-8 backdrop-blur-sm bg-white/20 shadow-lg hover:shadow-xl transition-shadow duration-300 border border-white/10 mb-6" | |
> | |
<div class="flex flex-col md:flex-row md:items-start gap-6"> | |
<div class="flex-shrink-0 flex flex-col items-center"> | |
<div | |
class="w-32 h-32 rounded-full bg-gradient-to-r from-[#9bdcbc] to-[#9293d4] flex items-center justify-center text-white text-3xl font-bold mb-4" | |
> | |
<span id="userInitials">N/A</span> | |
</div> | |
<!-- QR Code --> | |
<div class="mt-2 bg-white p-2 rounded-lg shadow-md"> | |
<img | |
id="qrCodeImage" | |
src="" | |
alt="QR Code" | |
class="w-24 h-24 object-contain" | |
/> | |
</div> | |
</div> | |
<div class="flex-grow"> | |
<div | |
class="flex flex-wrap items-start justify-between gap-4 mb-6" | |
> | |
<div> | |
<h2 class="text-3xl font-bold mb-1" id="userName"> | |
Loading... | |
</h2> | |
<p class="text-gray-600" id="userEmail"> | |
loading@example.com | |
</p> | |
</div> | |
<div | |
class="px-4 py-2 rounded-full bg-[#9bdcbc]/30 text-[#2d7d46] text-sm font-medium" | |
> | |
<span id="registrationStatus">Registered</span> | |
</div> | |
</div> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
<!-- Personal Information --> | |
<div> | |
<h3 | |
class="text-sm uppercase tracking-wider text-gray-500 mb-3 font-medium" | |
> | |
Personal Information | |
</h3> | |
<div class="space-y-4"> | |
<div> | |
<p class="text-xs text-gray-500">Phone Number</p> | |
<p class="font-medium" id="userPhone">N/A</p> | |
</div> | |
<div> | |
<p class="text-xs text-gray-500">Registration Number</p> | |
<p class="font-medium" id="userRegNo">N/A</p> | |
</div> | |
<div> | |
<p class="text-xs text-gray-500">Gender</p> | |
<p class="font-medium" id="userGender">N/A</p> | |
</div> | |
</div> | |
</div> | |
<!-- Professional Information --> | |
<div> | |
<h3 | |
class="text-sm uppercase tracking-wider text-gray-500 mb-3 font-medium" | |
> | |
Professional Information | |
</h3> | |
<div class="space-y-4"> | |
<div> | |
<p class="text-xs text-gray-500">Position</p> | |
<p class="font-medium" id="userCategory">N/A</p> | |
</div> | |
<div> | |
<p class="text-xs text-gray-500">Specialty</p> | |
<p class="font-medium" id="userHospital">N/A</p> | |
</div> | |
<div> | |
<p class="text-xs text-gray-500">State</p> | |
<p class="font-medium" id="userState">N/A</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Event Information Card --> | |
<div | |
class="rounded-xl p-6 md:p-8 backdrop-blur-sm bg-white/20 shadow-lg hover:shadow-xl transition-shadow duration-300 border border-white/10 mb-6" | |
> | |
<h3 class="text-xl font-bold mb-6 pb-3 border-b border-white/30"> | |
Event Details | |
</h3> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
<div> | |
<p class="text-xs text-gray-500 mb-1">Event Name</p> | |
<p class="font-medium text-lg" id="eventName"> | |
NMA ADM/AGC 2025 | |
</p> | |
<div class="mt-4"> | |
<p class="text-xs text-gray-500 mb-1">Registration Date</p> | |
<p class="font-medium" id="registrationDate">N/A</p> | |
</div> | |
<div class="mt-4"> | |
<p class="text-xs text-gray-500 mb-1">Registration Status</p> | |
<div class="flex items-center gap-2"> | |
<span class="w-3 h-3 rounded-full bg-green-500"></span> | |
<p class="font-medium" id="registrationStatusText"> | |
Confirmed | |
</p> | |
</div> | |
</div> | |
</div> | |
<div> | |
<p class="text-xs text-gray-500 mb-1">Pass Type</p> | |
<div | |
class="inline-flex items-center gap-2 bg-gradient-to-r from-[#9bdcbc]/30 to-[#9293d4]/30 px-4 py-2 rounded-lg" | |
> | |
<svg | |
xmlns="http://www.w3.org/2000/svg" | |
class="h-5 w-5 text-[#8990c9]" | |
fill="none" | |
viewBox="0 0 24 24" | |
stroke="currentColor" | |
> | |
<path | |
stroke-linecap="round" | |
stroke-linejoin="round" | |
stroke-width="2" | |
d="M15 5v2m0 4v2m0 4v2M5 5a2 2 0 00-2 2v3a2 2 0 110 4v3a2 2 0 002 2h14a2 2 0 002-2v-3a2 2 0 110-4V7a2 2 0 00-2-2H5z" | |
/> | |
</svg> | |
<span class="font-medium" id="passType">Standard Pass</span> | |
</div> | |
<div class="mt-4"> | |
<p class="text-xs text-gray-500 mb-1">Payment Status</p> | |
<p class="font-medium" id="paymentStatus">N/A</p> | |
</div> | |
<div class="mt-4"> | |
<p class="text-xs text-gray-500 mb-1">Payment Amount</p> | |
<p class="font-medium" id="paymentAmount">N/A</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Actions Card --> | |
<div | |
class="rounded-xl p-6 md:p-8 backdrop-blur-sm bg-white/20 shadow-lg hover:shadow-xl transition-shadow duration-300 border border-white/10" | |
> | |
<h3 class="text-xl font-bold mb-4">Actions</h3> | |
<div class="flex flex-wrap gap-4"> | |
<button | |
id="downloadPass" | |
class="px-6 py-3 rounded-full bg-[#a2aad9] text-white hover:bg-[#8990c9] hover:shadow-lg transition-all duration-300 text-sm font-medium flex items-center gap-2" | |
> | |
<svg | |
xmlns="http://www.w3.org/2000/svg" | |
class="h-5 w-5" | |
fill="none" | |
viewBox="0 0 24 24" | |
stroke="currentColor" | |
> | |
<path | |
stroke-linecap="round" | |
stroke-linejoin="round" | |
stroke-width="2" | |
d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" | |
/> | |
</svg> | |
Download Pass | |
</button> | |
<button | |
id="printPass" | |
class="px-6 py-3 rounded-full bg-white/30 text-gray-700 hover:bg-white/50 hover:shadow-lg transition-all duration-300 text-sm font-medium flex items-center gap-2" | |
> | |
<svg | |
xmlns="http://www.w3.org/2000/svg" | |
class="h-5 w-5" | |
fill="none" | |
viewBox="0 0 24 24" | |
stroke="currentColor" | |
> | |
<path | |
stroke-linecap="round" | |
stroke-linejoin="round" | |
stroke-width="2" | |
d="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z" | |
/> | |
</svg> | |
Print Pass | |
</button> | |
<a | |
href="https://mymediconnect.co/4.0/events/nma2025/" | |
class="px-6 py-3 rounded-full bg-white/30 text-gray-700 hover:bg-white/50 hover:shadow-lg transition-all duration-300 text-sm font-medium flex items-center gap-2" | |
> | |
<svg | |
xmlns="http://www.w3.org/2000/svg" | |
class="h-5 w-5" | |
fill="none" | |
viewBox="0 0 24 24" | |
stroke="currentColor" | |
> | |
<path | |
stroke-linecap="round" | |
stroke-linejoin="round" | |
stroke-width="2" | |
d="M10 19l-7-7m0 0l7-7m-7 7h18" | |
/> | |
</svg> | |
Back to Search | |
</a> | |
</div> | |
</div> | |
</div> | |
</div> | |
</main> | |
<footer | |
class="mt-12 py-6 bg-white/30 backdrop-blur-sm border-t border-white/20" | |
> | |
<div class="container mx-auto px-4 text-center text-sm text-gray-700"> | |
<p>© 2025 Mediconnect 4.0. All rights reserved.</p> | |
</div> | |
</footer> | |
<script> | |
document.addEventListener("DOMContentLoaded", () => { | |
// Get UI elements | |
const loadingState = document.getElementById("loadingState"); | |
const errorState = document.getElementById("errorState"); | |
const userDataState = document.getElementById("userDataState"); | |
const qrCodeImage = document.getElementById("qrCodeImage"); | |
// Elements for user data | |
const userInitials = document.getElementById("userInitials"); | |
const userName = document.getElementById("userName"); | |
const userEmail = document.getElementById("userEmail"); | |
const userPhone = document.getElementById("userPhone"); | |
const userRegNo = document.getElementById("userRegNo"); | |
const userGender = document.getElementById("userGender"); | |
const userCategory = document.getElementById("userCategory"); | |
const userHospital = document.getElementById("userHospital"); | |
const userState = document.getElementById("userState"); | |
const registrationDate = document.getElementById("registrationDate"); | |
const passType = document.getElementById("passType"); | |
const paymentStatus = document.getElementById("paymentStatus"); | |
const paymentAmount = document.getElementById("paymentAmount"); | |
// Status elements | |
const registrationStatus = document.getElementById("registrationStatus"); | |
const registrationStatusText = document.getElementById("registrationStatusText"); | |
// Get registration data from localStorage and URL parameters | |
// const urlParams = new URLSearchParams(window.location.search); | |
// const urlQrCode = urlParams.get('qr'); | |
const userRegistration = localStorage.getItem("userRegistration"); | |
// const qrCodeData = urlQrCode || localStorage.getItem("qrCodeData"); | |
// console.log(userRegistration); | |
// Function to format date nicely | |
function formatDate(dateString) { | |
if (!dateString) return "N/A"; | |
const options = { | |
year: "numeric", | |
month: "long", | |
day: "numeric", | |
hour: "2-digit", | |
minute: "2-digit", | |
}; | |
try { | |
return new Date(dateString).toLocaleDateString(undefined, options); | |
} catch (e) { | |
return dateString; // Return original if parsing fails | |
} | |
} | |
// Function to get initials from name | |
function getInitials(name) { | |
if (!name) return "NA"; | |
return name | |
.split(" ") | |
.map((part) => part.charAt(0)) | |
.join("") | |
.substring(0, 2) | |
.toUpperCase(); | |
} | |
// Map API field names to our display fields | |
function mapField(userData, possibleFields, defaultValue = "N/A") { | |
for (const field of possibleFields) { | |
if (userData.data && userData.data[field] && userData.data[field] !== "" && userData.data[field] !== "undefined") { | |
return userData.data[field]; | |
} | |
} | |
return defaultValue; | |
} | |
// Simulate loading for a smoother experience | |
setTimeout(() => { | |
// Check if we have registration data | |
if (userRegistration) { | |
try { | |
let userData = JSON.parse(userRegistration); | |
// Populate user data with flexible field mapping | |
userInitials.textContent = getInitials( | |
mapField(userData, ['name', 'fullname', 'user_name']) | |
); | |
userName.textContent = mapField( | |
userData, ['fullname', 'name', 'user_name'] | |
); | |
userEmail.textContent = mapField( | |
userData, ['email', 'mail', 'user_email'] | |
); | |
userPhone.textContent = mapField( | |
userData, ['phone', 'phone_number', 'mobile', 'tel'] | |
); | |
userGender.textContent = mapField( | |
userData, ['gender', 'sex'] | |
); | |
userCategory.textContent = mapField( | |
userData, ['category', 'position', 'designation', 'role'] | |
); | |
userHospital.textContent = userData.data.specialty === "" ? "N/A" : userData.data.specialty; | |
userState.textContent = mapField( | |
userData, ['state', 'location', 'region'] | |
); | |
qrCodeImage.src = 'tags/q/q' + userData.data.qr_code_url; | |
registrationDate.textContent = userData.data.date !== null ? formatDate(userData.data.date) : "N/A"; | |
// registrationDate.textContent = formatDate( | |
// mapField(userData, ['registration_date', 'registeration_date', 'date', 'created_at']) | |
// ); | |
// Set pass type based on available data | |
// const userPassType = mapField( | |
// userData, ['pass_type', 'ticket_type', 'category', 'position'] | |
// ); | |
// passType.textContent = userPassType; | |
// // Set registration status based on available data | |
// const userRegistrationStatus = mapField( | |
// userData, ['status', 'registration_status', 'active'], | |
// "Confirmed" | |
// ); | |
// registrationStatus.textContent = userRegistrationStatus; | |
// registrationStatusText.textContent = userRegistrationStatus; | |
// // Handle payment information | |
paymentStatus.textContent = "paid"; | |
// paymentStatus.textContent = mapField( | |
// userData, ['payment_status', 'paid', 'payment'] | |
// ); | |
paymentAmount.textContent = userData.data.amount | |
? `₦${userData.data.amount}` | |
: mapField(userData, ['amount', 'payment_amount', 'fee'], "N/A"); | |
// Show user data section | |
loadingState.classList.add("hidden"); | |
userDataState.classList.remove("hidden"); | |
} catch (error) { | |
console.error("Error parsing user data:", error); | |
loadingState.classList.add("hidden"); | |
errorState.classList.remove("hidden"); | |
} | |
} else { | |
// No registration data found, show error | |
loadingState.classList.add("hidden"); | |
errorState.classList.remove("hidden"); | |
} | |
}, 1000); // 1 second loading time for better UX | |
// Handle download pass button click | |
document.getElementById("downloadPass").addEventListener("click", () => { | |
if (!qrCodeImage.src || qrCodeImage.src.endsWith("#")) { | |
alert("QR code image not available for download"); | |
return; | |
} | |
try { | |
// Try to create a better filename | |
let fileName = "mediconnect-pass"; | |
// Add user name to filename if available | |
if (userName && userName.textContent && userName.textContent !== "N/A") { | |
fileName += `-${userName.textContent.toLowerCase().replace(/\s+/g, "-")}`; | |
} | |
fileName += ".png"; | |
// Create a virtual link to download the QR code | |
const link = document.createElement("a"); | |
link.download = fileName; | |
link.href = qrCodeImage.src; | |
document.body.appendChild(link); | |
link.click(); | |
document.body.removeChild(link); | |
} catch (error) { | |
console.error("Error downloading pass:", error); | |
alert("There was an error downloading your pass. Please try again."); | |
} | |
}); | |
// Handle print pass button click | |
document.getElementById("printPass").addEventListener("click", () => { | |
// Apply print-friendly styles before printing | |
const originalBodyBg = document.body.style.background; | |
document.body.style.background = "white"; | |
// Add a small delay to ensure styles are applied | |
setTimeout(() => { | |
window.print(); | |
// Restore original styles after printing | |
document.body.style.background = originalBodyBg; | |
}, 100); | |
}); | |
}); | |
</script> | |
</body> | |
</html> |
<!-- Attendance Check Card -->
<div
class="rounded-xl p-6 md:p-8 backdrop-blur-sm bg-white/20 shadow-lg hover:shadow-xl transition-shadow duration-300 border border-white/10 mb-6"
>
<h3 class="text-xl font-bold mb-6 pb-3 border-b border-white/30">
Attendance Check-In
</h3>
<div
class="flex flex-col md:flex-row md:items-center justify-between gap-4"
>
<div>
<p class="text-sm text-gray-600 mb-1">
Mark your attendance for today
</p>
<p class="text-xs text-gray-500" id="lastCheckInStatus">
Checking status...
</p>
</div>
<div class="flex-shrink-0">
<label class="relative inline-flex items-center cursor-pointer">
<input
type="checkbox"
id="attendanceToggle"
class="sr-only peer"
disabled
/>
<div
class="w-14 h-7 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-[#a2aad9]/30 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[4px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-6 after:w-6 after:transition-all peer-checked:bg-[#9bdcbc]"
></div>
<span
class="ml-3 text-sm font-medium text-gray-700"
id="toggleLabel"
>Loading...</span
>
</label>
</div>
</div>
<div
id="attendanceFeedback"
class="hidden mt-4 p-3 rounded-lg"
></div>
</div>
// Attendance Functionality
const attendanceToggle = document.getElementById("attendanceToggle");
const toggleLabel = document.getElementById("toggleLabel");
const lastCheckInStatus = document.getElementById("lastCheckInStatus");
const attendanceFeedback = document.getElementById("attendanceFeedback");
// Function to check attendance status
async function checkAttendanceStatus() {
try {
const userData = JSON.parse(localStorage.getItem("userRegistration"));
if (!userData || !userData.data || !userData.data.id) {
throw new Error("No user ID found");
}
const response = await fetch(
`https://mymediconnect.co/4.0/api/check-in-status.php?event=NMA ADM/AgC 2025&id=${userData.data.id}`
);
const data = await response.json();
if (data.status === "checked") {
attendanceToggle.checked = true;
toggleLabel.textContent = "Checked In";
lastCheckInStatus.textContent = "You have checked in for today";
lastCheckInStatus.classList.add("text-green-600");
lastCheckInStatus.classList.remove("text-gray-500");
} else {
attendanceToggle.checked = false;
toggleLabel.textContent = "Check In";
lastCheckInStatus.textContent = "Not checked in yet today";
lastCheckInStatus.classList.add("text-gray-500");
lastCheckInStatus.classList.remove("text-green-600");
}
attendanceToggle.disabled = false;
} catch (error) {
console.error("Error checking attendance status:", error);
lastCheckInStatus.textContent = "Unable to check status";
attendanceToggle.disabled = true;
}
}
// Function to handle attendance toggle
async function handleAttendanceToggle() {
const userData = JSON.parse(localStorage.getItem("userRegistration"));
if (!userData || !userData.data || !userData.data.id) {
showFeedback("User data not found", "error");
return;
}
attendanceToggle.disabled = true;
toggleLabel.textContent = "Processing...";
try {
const response = await fetch(
`https://mymediconnect.co/4.0/api/check-in.php?event=NMA ADM/AgC 2025&id=${userData.data.id}`
);
const data = await response.json();
if (data.status === "success") {
showFeedback("Attendance recorded successfully!", "success");
attendanceToggle.checked = true;
toggleLabel.textContent = "Checked In";
lastCheckInStatus.textContent = "You have checked in for today";
lastCheckInStatus.classList.add("text-green-600");
lastCheckInStatus.classList.remove("text-gray-500");
} else if (data.status === "exists") {
showFeedback("You have already checked in today", "info");
attendanceToggle.checked = true;
toggleLabel.textContent = "Checked In";
lastCheckInStatus.textContent = "You have checked in for today";
lastCheckInStatus.classList.add("text-green-600");
lastCheckInStatus.classList.remove("text-gray-500");
} else {
throw new Error(data.message || "Unknown error");
}
} catch (error) {
console.error("Error recording attendance:", error);
showFeedback(
"Failed to record attendance. Please try again.",
"error"
);
attendanceToggle.checked = false;
toggleLabel.textContent = "Check In";
} finally {
attendanceToggle.disabled = false;
}
}
// Function to show feedback messages
function showFeedback(message, type) {
attendanceFeedback.textContent = message;
attendanceFeedback.className = "mt-4 p-3 rounded-lg";
if (type === "success") {
attendanceFeedback.classList.add("bg-green-100", "text-green-700");
} else if (type === "error") {
attendanceFeedback.classList.add("bg-red-100", "text-red-700");
} else {
attendanceFeedback.classList.add("bg-blue-100", "text-blue-700");
}
attendanceFeedback.classList.remove("hidden");
// Hide feedback after 5 seconds
setTimeout(() => {
attendanceFeedback.classList.add("hidden");
}, 5000);
}
// Initialize attendance functionality
attendanceToggle.addEventListener("change", handleAttendanceToggle);
// Check attendance status when page loads
checkAttendanceStatus();
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Mediconnect Registration Details