Verified Hospital Request
`;
modal.classList.add('active');
}
// Respond to Request
function respondToRequest(id) {
const request = allRecords.find(r => r.__backendId === id);
if (!request) return;
// Show inline confirmation
const confirmDiv = document.createElement('div');
confirmDiv.className = 'fixed bottom-6 left-1/2 transform -translate-x-1/2 px-6 py-4 rounded-xl shadow-2xl text-center slide-up';
confirmDiv.style.backgroundColor = '#22c55e';
confirmDiv.innerHTML = `
✓ Thank you! Hospital has been notified.
They will contact you shortly.
`;
document.body.appendChild(confirmDiv);
setTimeout(() => {
confirmDiv.remove();
}, 3000);
closeAllModals();
}
// Share Alert
function shareAlert(id) {
document.getElementById('shareModal').classList.add('active');
}
// Share Badge
function shareBadge(badgeName) {
document.getElementById('shareModal').classList.add('active');
}
// Add Request Button
document.getElementById('addRequestBtn').addEventListener('click', () => {
document.getElementById('addRequestModal').classList.add('active');
});
// Add Request Form
document.getElementById('addRequestForm').addEventListener('submit', async (e) => {
e.preventDefault();
const submitBtn = document.getElementById('submitRequestBtn');
const originalText = submitBtn.innerHTML;
submitBtn.innerHTML = '
';
submitBtn.disabled = true;
const newRequest = {
id: `req-${Date.now()}`,
type: 'request',
hospital: document.getElementById('hospitalName').value,
bloodType: document.getElementById('bloodTypeNeeded').value,
urgency: document.getElementById('urgencyLevel').value,
location: document.getElementById('requestLocation').value,
description: document.getElementById('requestDescription').value,
distance: 'TBD',
status: 'Active',
timestamp: Date.now(),
userId: currentUser.id
};
if (allRecords.length >= 999) {
const warningDiv = document.createElement('div');
warningDiv.className = 'fixed bottom-6 left-1/2 transform -translate-x-1/2 px-6 py-4 rounded-xl shadow-2xl text-center';
warningDiv.style.backgroundColor = '#dc2626';
warningDiv.innerHTML = '
Maximum limit of 999 requests reached. Please delete some requests first.
';
document.body.appendChild(warningDiv);
setTimeout(() => warningDiv.remove(), 3000);
submitBtn.innerHTML = originalText;
submitBtn.disabled = false;
return;
}
const result = await window.dataSdk.create(newRequest);
submitBtn.innerHTML = originalText;
submitBtn.disabled = false;
if (result.isOk) {
document.getElementById('addRequestForm').reset();
closeAllModals();
const successDiv = document.createElement('div');
successDiv.className = 'fixed bottom-6 left-1/2 transform -translate-x-1/2 px-6 py-4 rounded-xl shadow-2xl text-center slide-up';
successDiv.style.backgroundColor = '#22c55e';
successDiv.innerHTML = '
✓ Request submitted successfully!
';
document.body.appendChild(successDiv);
setTimeout(() => successDiv.remove(), 3000);
} else {
const errorDiv = document.createElement('div');
errorDiv.className = 'fixed bottom-6 left-1/2 transform -translate-x-1/2 px-6 py-4 rounded-xl shadow-2xl text-center';
errorDiv.style.backgroundColor = '#dc2626';
errorDiv.innerHTML = '
Failed to submit request. Please try again.
';
document.body.appendChild(errorDiv);
setTimeout(() => errorDiv.remove(), 3000);
}
});
// Close Modals
function closeAllModals() {
document.querySelectorAll('.modal').forEach(modal => {
modal.classList.remove('active');
});
}
document.querySelectorAll('.close-modal').forEach(btn => {
btn.addEventListener('click', closeAllModals);
});
document.querySelectorAll('.modal').forEach(modal => {
modal.addEventListener('click', (e) => {
if (e.target === modal) {
closeAllModals();
}
});
});
// Helper Functions
function getTimeAgo(timestamp) {
const minutes = Math.floor((Date.now() - timestamp) / 60000);
if (minutes < 60) return `${minutes}m ago`;
const hours = Math.floor(minutes / 60);
if (hours < 24) return `${hours}h ago`;
return `${Math.floor(hours / 24)}d ago`;
}
// Element SDK Configuration
const defaultConfig = {
primary_color: "#dc2626",
secondary_color: "#22c55e",
background_color: "#f5f5f5",
surface_color: "#ffffff",
text_color: "#1f2937",
font_family: "system-ui, -apple-system, sans-serif",
font_size: 16,
app_title: "BloodNow",
tagline: "Save Lives Together",
welcome_message: "Welcome back, Hero!",
emergency_alert_title: "Urgent: Blood Needed",
donate_btn: "I Can Donate",
share_btn: "Share Alert"
};
async function onConfigChange(config) {
const customFont = config.font_family || defaultConfig.font_family;
const baseFontStack = 'system-ui, -apple-system, sans-serif';
const baseSize = config.font_size || defaultConfig.font_size;
document.body.style.fontFamily = `${customFont}, ${baseFontStack}`;
document.body.style.fontSize = `${baseSize}px`;
document.getElementById('app-title').textContent = config.app_title || defaultConfig.app_title;
document.getElementById('tagline').textContent = config.tagline || defaultConfig.tagline;
document.getElementById('welcome-message').textContent = config.welcome_message || defaultConfig.welcome_message;
}
function mapToCapabilities(config) {
return {
recolorables: [
{
get: () => config.primary_color || defaultConfig.primary_color,
set: (value) => {
config.primary_color = value;
window.elementSdk.setConfig({ primary_color: value });
}
},
{
get: () => config.secondary_color || defaultConfig.secondary_color,
set: (value) => {
config.secondary_color = value;
window.elementSdk.setConfig({ secondary_color: value });
}
},
{
get: () => config.background_color || defaultConfig.background_color,
set: (value) => {
config.background_color = value;
window.elementSdk.setConfig({ background_color: value });
}
},
{
get: () => config.surface_color || defaultConfig.surface_color,
set: (value) => {
config.surface_color = value;
window.elementSdk.setConfig({ surface_color: value });
}
},
{
get: () => config.text_color || defaultConfig.text_color,
set: (value) => {
config.text_color = value;
window.elementSdk.setConfig({ text_color: value });
}
}
],
borderables: [],
fontEditable: {
get: () => config.font_family || defaultConfig.font_family,
set: (value) => {
config.font_family = value;
window.elementSdk.setConfig({ font_family: value });
}
},
fontSizeable: {
get: () => config.font_size || defaultConfig.font_size,
set: (value) => {
config.font_size = value;
window.elementSdk.setConfig({ font_size: value });
}
}
};
}
function mapToEditPanelValues(config) {
return new Map([
["app_title", config.app_title || defaultConfig.app_title],
["tagline", config.tagline || defaultConfig.tagline],
["welcome_message", config.welcome_message || defaultConfig.welcome_message],
["emergency_alert_title", config.emergency_alert_title || defaultConfig.emergency_alert_title],
["donate_btn", config.donate_btn || defaultConfig.donate_btn],
["share_btn", config.share_btn || defaultConfig.share_btn]
]);
}
if (window.elementSdk) {
window.elementSdk.init({
defaultConfig,
onConfigChange,
mapToCapabilities,
mapToEditPanelValues
});
}