Skip to content

Instantly share code, notes, and snippets.

@fluxion9
Created April 30, 2025 16:44
Show Gist options
  • Save fluxion9/2edf5070a95b530a4d98f6a780178062 to your computer and use it in GitHub Desktop.
Save fluxion9/2edf5070a95b530a4d98f6a780178062 to your computer and use it in GitHub Desktop.
<?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>
@Petsamuel
Copy link

<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> <style> body { font-family: "Poppins", sans-serif; } /* Ensure focus states are visible */ input:focus, button:focus { outline: 2px solid #a2aad9; outline-offset: 2px; } </style>

Mediconnect Registration Details

Back to Search
<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>
      <!-- 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>

      <!-- 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);
    });
  });

  // 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();
</script>

@Petsamuel
Copy link

<!-- 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