dwaa2a / index.html
Youssef117's picture
اريد لكل مستخدم ان يكون يكون له حساب خاص به و مكان يضع بيه رقم الواتساب الذي يريد عليه الاشعار بتاع التطبيق و ايضا مكان واتساب لارسال للشخص المتابع و مكان لمشاؤكة قائمة الادوية من خلال الواتساب - Initial Deployment
ad8da2e verified
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>منبه الدواء - تذكير بمواعيد الأدوية</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
@import url('https://fonts.googleapis.com/css2?family=Tajawal:wght@400;500;700;900&display=swap');
body {
font-family: 'Tajawal', sans-serif;
}
.notification-badge {
position: absolute;
top: -5px;
right: -5px;
width: 20px;
height: 20px;
background-color: #EF4444;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
}
.medication-card {
transition: all 0.3s ease;
}
.medication-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
}
.notification {
animation: slideIn 0.5s forwards;
}
@keyframes slideIn {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.time-picker::-webkit-calendar-picker-indicator {
filter: invert(1);
}
</style>
</head>
<body class="bg-gray-100 text-gray-800">
<!-- Login/Signup Modal -->
<div id="authModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
<div class="bg-white rounded-lg w-full max-w-md">
<div class="bg-indigo-600 text-white px-6 py-4 rounded-t-lg">
<h3 class="text-lg font-bold">تسجيل الدخول / إنشاء حساب</h3>
</div>
<div class="p-6">
<form id="authForm">
<div class="mb-4">
<label for="username" class="block text-gray-700 mb-2">اسم المستخدم</label>
<input type="text" id="username" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" required>
</div>
<div class="mb-4">
<label for="password" class="block text-gray-700 mb-2">كلمة المرور</label>
<input type="password" id="password" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" required>
</div>
<div class="mb-6">
<label for="whatsappNumber" class="block text-gray-700 mb-2">رقم واتساب</label>
<input type="tel" id="whatsappNumber" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="مثال: 966501234567" required>
</div>
<div class="mb-6">
<label for="caretakerNumber" class="block text-gray-700 mb-2">رقم المتابع (اختياري)</label>
<input type="tel" id="caretakerNumber" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="مثال: 966501234567">
</div>
<div class="flex justify-between space-x-4 space-x-reverse">
<button type="button" id="loginBtn" class="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700">تسجيل الدخول</button>
<button type="button" id="signupBtn" class="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700">إنشاء حساب</button>
</div>
</form>
</div>
</div>
</div>
<div class="container mx-auto px-4 py-8 max-w-6xl">
<!-- Header -->
<header class="flex justify-between items-center mb-8">
<div>
<h1 class="text-3xl font-bold text-indigo-700">منبه الدواء</h1>
<p class="text-gray-600">تذكير بمواعيد الأدوية</p>
</div>
<div class="flex items-center space-x-4 space-x-reverse">
<div class="relative">
<button id="profileBtn" class="p-2 rounded-full bg-indigo-100 text-indigo-700 hover:bg-indigo-200">
<i class="fas fa-user"></i>
</button>
</div>
<div class="relative">
<button id="notificationBtn" class="p-2 rounded-full bg-indigo-100 text-indigo-700 hover:bg-indigo-200">
<i class="fas fa-bell"></i>
</button>
<span id="notificationCount" class="notification-badge hidden">0</span>
</div>
<button id="addMedBtn" class="bg-indigo-600 text-white px-4 py-2 rounded-lg hover:bg-indigo-700 flex items-center">
<i class="fas fa-plus ml-2"></i>
<span>إضافة دواء</span>
</button>
</div>
</header>
<!-- Notification Panel (Hidden by default) -->
<div id="notificationPanel" class="hidden fixed top-20 right-4 w-80 bg-white shadow-lg rounded-lg z-50 overflow-hidden">
<div class="bg-indigo-600 text-white px-4 py-3 flex justify-between items-center">
<h3 class="font-bold">الإشعارات</h3>
<button id="closeNotificationBtn" class="text-white hover:text-indigo-200">
<i class="fas fa-times"></i>
</button>
</div>
<div id="notificationList" class="max-h-96 overflow-y-auto">
<!-- Notifications will be added here dynamically -->
<div class="p-4 text-center text-gray-500">لا توجد إشعارات</div>
</div>
</div>
<!-- Stats Cards -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
<div class="bg-white p-6 rounded-lg shadow">
<div class="flex items-center">
<div class="p-3 rounded-full bg-green-100 text-green-600 mr-4">
<i class="fas fa-check-circle text-xl"></i>
</div>
<div>
<p class="text-gray-500">الجرعات المأخوذة</p>
<h3 class="text-2xl font-bold" id="takenCount">0</h3>
</div>
</div>
</div>
<div class="bg-white p-6 rounded-lg shadow">
<div class="flex items-center">
<div class="p-3 rounded-full bg-red-100 text-red-600 mr-4">
<i class="fas fa-times-circle text-xl"></i>
</div>
<div>
<p class="text-gray-500">الجرعات الفائتة</p>
<h3 class="text-2xl font-bold" id="missedCount">0</h3>
</div>
</div>
</div>
<div class="bg-white p-6 rounded-lg shadow">
<div class="flex items-center">
<div class="p-3 rounded-full bg-blue-100 text-blue-600 mr-4">
<i class="fas fa-pills text-xl"></i>
</div>
<div>
<p class="text-gray-500">إجمالي الأدوية</p>
<h3 class="text-2xl font-bold" id="totalMedsCount">0</h3>
</div>
</div>
</div>
</div>
<!-- Upcoming Medications -->
<div class="mb-8">
<h2 class="text-xl font-bold mb-4 flex items-center">
<i class="fas fa-clock text-indigo-600 ml-2"></i>
<span>الجرعات القادمة</span>
</h2>
<div id="upcomingMeds" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<!-- Upcoming meds will be added here dynamically -->
<div class="bg-white p-4 rounded-lg shadow text-center text-gray-500">
لا توجد جرعات قادمة
</div>
</div>
</div>
<!-- All Medications -->
<div>
<h2 class="text-xl font-bold mb-4 flex items-center">
<i class="fas fa-list-ul text-indigo-600 ml-2"></i>
<span>جميع الأدوية</span>
</h2>
<div id="allMedsList" class="space-y-4">
<!-- All meds will be added here dynamically -->
<div class="bg-white p-4 rounded-lg shadow text-center text-gray-500">
لا توجد أدوية مسجلة
</div>
</div>
</div>
<!-- Add Medication Modal -->
<div id="addMedModal" class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
<div class="bg-white rounded-lg w-full max-w-md">
<div class="bg-indigo-600 text-white px-6 py-4 rounded-t-lg flex justify-between items-center">
<h3 class="text-lg font-bold">إضافة دواء جديد</h3>
<button id="closeModalBtn" class="text-white hover:text-indigo-200">
<i class="fas fa-times"></i>
</button>
</div>
<div class="p-6">
<form id="medicationForm">
<div class="mb-4">
<label for="medName" class="block text-gray-700 mb-2">اسم الدواء</label>
<input type="text" id="medName" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" required>
</div>
<div class="mb-4">
<label for="medDosage" class="block text-gray-700 mb-2">الجرعة</label>
<input type="text" id="medDosage" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="مثال: حبة واحدة، ملعقة صغيرة" required>
</div>
<div class="mb-4">
<label for="medTime" class="block text-gray-700 mb-2">الوقت</label>
<input type="time" id="medTime" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 time-picker" required>
</div>
<div class="mb-4">
<label for="medFrequency" class="block text-gray-700 mb-2">التكرار</label>
<select id="medFrequency" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" required>
<option value="daily">يومي</option>
<option value="weekly">أسبوعي</option>
<option value="monthly">شهري</option>
<option value="custom">مخصص</option>
</select>
</div>
<div class="mb-4 hidden" id="customDaysContainer">
<label class="block text-gray-700 mb-2">أيام الأسبوع</label>
<div class="grid grid-cols-7 gap-2">
<label class="flex items-center justify-center p-2 border rounded-lg cursor-pointer">
<input type="checkbox" name="customDays" value="0" class="hidden">
<span>الأحد</span>
</label>
<label class="flex items-center justify-center p-2 border rounded-lg cursor-pointer">
<input type="checkbox" name="customDays" value="1" class="hidden">
<span>الاثنين</span>
</label>
<label class="flex items-center justify-center p-2 border rounded-lg cursor-pointer">
<input type="checkbox" name="customDays" value="2" class="hidden">
<span>الثلاثاء</span>
</label>
<label class="flex items-center justify-center p-2 border rounded-lg cursor-pointer">
<input type="checkbox" name="customDays" value="3" class="hidden">
<span>الأربعاء</span>
</label>
<label class="flex items-center justify-center p-2 border rounded-lg cursor-pointer">
<input type="checkbox" name="customDays" value="4" class="hidden">
<span>الخميس</span>
</label>
<label class="flex items-center justify-center p-2 border rounded-lg cursor-pointer">
<input type="checkbox" name="customDays" value="5" class="hidden">
<span>الجمعة</span>
</label>
<label class="flex items-center justify-center p-2 border rounded-lg cursor-pointer">
<input type="checkbox" name="customDays" value="6" class="hidden">
<span>السبت</span>
</label>
</div>
</div>
<div class="mb-4">
<label for="medNotes" class="block text-gray-700 mb-2">ملاحظات (اختياري)</label>
<textarea id="medNotes" rows="3" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500"></textarea>
</div>
<div class="mb-6">
<label class="flex items-center">
<input type="checkbox" id="enableWhatsApp" class="form-checkbox h-5 w-5 text-indigo-600">
<span class="mr-2 text-gray-700">إرسال تذكير عبر واتساب</span>
</label>
</div>
<div id="whatsappSection" class="hidden mb-6">
<div class="mb-4">
<label for="whatsappNumber" class="block text-gray-700 mb-2">رقم واتساب المريض</label>
<input type="tel" id="whatsappNumber" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="مثال: 966501234567">
</div>
<div class="mb-4">
<label for="secondaryContact" class="block text-gray-700 mb-2">رقم واتساب للشخص المساعد (اختياري)</label>
<input type="tel" id="secondaryContact" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="مثال: 966501234567">
</div>
</div>
<div class="flex justify-end space-x-4 space-x-reverse">
<button type="button" id="cancelMedBtn" class="px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-100">إلغاء</button>
<button type="submit" class="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700">حفظ الدواء</button>
</div>
</form>
</div>
</div>
</div>
<!-- Confirmation Modal -->
<div id="confirmModal" class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
<div class="bg-white rounded-lg w-full max-w-md">
<div class="bg-indigo-600 text-white px-6 py-4 rounded-t-lg">
<h3 class="text-lg font-bold">تأكيد أخذ الدواء</h3>
</div>
<div class="p-6">
<p id="confirmMessage" class="mb-6">هل أخذت دواء <span class="font-bold">[اسم الدواء]</span> في الوقت المحدد؟</p>
<div class="flex justify-end space-x-4 space-x-reverse">
<button id="missedBtn" class="px-4 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600">فوتتني الجرعة</button>
<button id="takenBtn" class="px-4 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600">نعم، أخذتها</button>
</div>
</div>
</div>
</div>
</div>
<script>
// Sample data for medications
let medications = JSON.parse(localStorage.getItem('medications')) || [];
let notifications = JSON.parse(localStorage.getItem('notifications')) || [];
let stats = JSON.parse(localStorage.getItem('stats')) || { taken: 0, missed: 0 };
// DOM Elements
const addMedBtn = document.getElementById('addMedBtn');
const addMedModal = document.getElementById('addMedModal');
const closeModalBtn = document.getElementById('closeModalBtn');
const cancelMedBtn = document.getElementById('cancelMedBtn');
const medicationForm = document.getElementById('medicationForm');
const medFrequency = document.getElementById('medFrequency');
const customDaysContainer = document.getElementById('customDaysContainer');
const enableWhatsApp = document.getElementById('enableWhatsApp');
const whatsappSection = document.getElementById('whatsappSection');
const notificationBtn = document.getElementById('notificationBtn');
const notificationPanel = document.getElementById('notificationPanel');
const closeNotificationBtn = document.getElementById('closeNotificationBtn');
const notificationList = document.getElementById('notificationList');
const notificationCount = document.getElementById('notificationCount');
const confirmModal = document.getElementById('confirmModal');
const confirmMessage = document.getElementById('confirmMessage');
const takenBtn = document.getElementById('takenBtn');
const missedBtn = document.getElementById('missedBtn');
const takenCount = document.getElementById('takenCount');
const missedCount = document.getElementById('missedCount');
const totalMedsCount = document.getElementById('totalMedsCount');
const upcomingMeds = document.getElementById('upcomingMeds');
const allMedsList = document.getElementById('allMedsList');
// Current medication being confirmed
let currentMedication = null;
// Event Listeners
addMedBtn.addEventListener('click', () => addMedModal.classList.remove('hidden'));
closeModalBtn.addEventListener('click', () => addMedModal.classList.add('hidden'));
cancelMedBtn.addEventListener('click', () => addMedModal.classList.add('hidden'));
medFrequency.addEventListener('change', function() {
if (this.value === 'custom') {
customDaysContainer.classList.remove('hidden');
} else {
customDaysContainer.classList.add('hidden');
}
});
enableWhatsApp.addEventListener('change', function() {
if (this.checked) {
whatsappSection.classList.remove('hidden');
} else {
whatsappSection.classList.add('hidden');
}
});
medicationForm.addEventListener('submit', addMedication);
notificationBtn.addEventListener('click', toggleNotificationPanel);
closeNotificationBtn.addEventListener('click', () => notificationPanel.classList.add('hidden'));
takenBtn.addEventListener('click', confirmTaken);
missedBtn.addEventListener('click', confirmMissed);
// Custom day checkboxes styling
document.querySelectorAll('[name="customDays"]').forEach(checkbox => {
const label = checkbox.parentElement;
checkbox.addEventListener('change', function() {
if (this.checked) {
label.classList.add('bg-indigo-100', 'border-indigo-500');
} else {
label.classList.remove('bg-indigo-100', 'border-indigo-500');
}
});
});
// Initialize the app
function init() {
updateStats();
renderMedications();
renderNotifications();
checkForDueMedications();
// Check for due medications every minute
setInterval(checkForDueMedications, 60000);
}
// Add new medication
function addMedication(e) {
e.preventDefault();
const name = document.getElementById('medName').value;
const dosage = document.getElementById('medDosage').value;
const time = document.getElementById('medTime').value;
const frequency = document.getElementById('medFrequency').value;
const notes = document.getElementById('medNotes').value;
const whatsappEnabled = document.getElementById('enableWhatsApp').checked;
const whatsappNumber = document.getElementById('whatsappNumber').value;
const secondaryContact = document.getElementById('secondaryContact').value;
let days = [];
if (frequency === 'custom') {
document.querySelectorAll('[name="customDays"]:checked').forEach(checkbox => {
days.push(parseInt(checkbox.value));
});
} else if (frequency === 'weekly') {
days = [new Date().getDay()]; // Current day of week (0-6)
} else if (frequency === 'monthly') {
days = [new Date().getDate()]; // Current day of month (1-31)
}
const medication = {
id: Date.now(),
name,
dosage,
time,
frequency,
days,
notes,
whatsappEnabled,
whatsappNumber,
secondaryContact,
createdAt: new Date().toISOString(),
active: true
};
medications.push(medication);
saveMedications();
// Reset form
medicationForm.reset();
addMedModal.classList.add('hidden');
// Update UI
updateStats();
renderMedications();
// Schedule notifications for this medication
scheduleMedicationNotifications(medication);
}
// Save medications to localStorage
function saveMedications() {
localStorage.setItem('medications', JSON.stringify(medications));
}
// Save notifications to localStorage
function saveNotifications() {
localStorage.setItem('notifications', JSON.stringify(notifications));
}
// Save stats to localStorage
function saveStats() {
localStorage.setItem('stats', JSON.stringify(stats));
}
// Update statistics
function updateStats() {
takenCount.textContent = stats.taken;
missedCount.textContent = stats.missed;
totalMedsCount.textContent = medications.length;
}
// Render medications list
function renderMedications() {
// Clear existing
allMedsList.innerHTML = '';
upcomingMeds.innerHTML = '';
if (medications.length === 0) {
allMedsList.innerHTML = '<div class="bg-white p-4 rounded-lg shadow text-center text-gray-500">لا توجد أدوية مسجلة</div>';
upcomingMeds.innerHTML = '<div class="bg-white p-4 rounded-lg shadow text-center text-gray-500">لا توجد جرعات قادمة</div>';
return;
}
// Sort medications by time
const sortedMeds = [...medications].sort((a, b) => {
return a.time.localeCompare(b.time);
});
// Filter active medications
const activeMeds = sortedMeds.filter(med => med.active);
// Render all medications
activeMeds.forEach(med => {
const medCard = createMedicationCard(med);
allMedsList.appendChild(medCard);
});
// Render upcoming medications (next 3)
const now = new Date();
const currentTime = now.getHours() * 60 + now.getMinutes();
const upcoming = activeMeds
.filter(med => {
const [hours, minutes] = med.time.split(':').map(Number);
const medTime = hours * 60 + minutes;
return medTime >= currentTime;
})
.slice(0, 3);
if (upcoming.length === 0) {
upcomingMeds.innerHTML = '<div class="bg-white p-4 rounded-lg shadow text-center text-gray-500">لا توجد جرعات قادمة</div>';
} else {
upcoming.forEach(med => {
const upcomingCard = createUpcomingCard(med);
upcomingMeds.appendChild(upcomingCard);
});
}
}
// Create medication card for all medications list
function createMedicationCard(med) {
const card = document.createElement('div');
card.className = 'bg-white p-4 rounded-lg shadow medication-card';
card.dataset.id = med.id;
const frequencyText = {
daily: 'يومي',
weekly: 'أسبوعي',
monthly: 'شهري',
custom: 'مخصص'
}[med.frequency];
let daysText = '';
if (med.frequency === 'custom' && med.days.length > 0) {
const dayNames = ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'];
daysText = med.days.map(day => dayNames[day]).join('، ');
}
card.innerHTML = `
<div class="flex justify-between items-start mb-2">
<h3 class="font-bold text-lg">${med.name}</h3>
<div class="flex space-x-2 space-x-reverse">
<button class="edit-btn p-1 text-indigo-600 hover:text-indigo-800" data-id="${med.id}">
<i class="fas fa-edit"></i>
</button>
<button class="delete-btn p-1 text-red-600 hover:text-red-800" data-id="${med.id}">
<i class="fas fa-trash-alt"></i>
</button>
</div>
</div>
<div class="flex items-center mb-2">
<i class="fas fa-bolt text-yellow-500 ml-2"></i>
<span>${med.dosage}</span>
</div>
<div class="flex items-center mb-2">
<i class="fas fa-clock text-blue-500 ml-2"></i>
<span>${med.time} - ${frequencyText}${daysText ? ' (' + daysText + ')' : ''}</span>
</div>
${med.notes ? `
<div class="flex items-start mb-2">
<i class="fas fa-sticky-note text-green-500 ml-2 mt-1"></i>
<span>${med.notes}</span>
</div>
` : ''}
${med.whatsappEnabled ? `
<div class="flex items-center">
<i class="fab fa-whatsapp text-green-600 ml-2"></i>
<span>يتم إرسال تذكير عبر واتساب</span>
</div>
` : ''}
`;
// Add event listeners to buttons
card.querySelector('.edit-btn').addEventListener('click', () => editMedication(med.id));
card.querySelector('.delete-btn').addEventListener('click', () => deleteMedication(med.id));
return card;
}
// Create upcoming medication card
function createUpcomingCard(med) {
const card = document.createElement('div');
card.className = 'bg-white p-4 rounded-lg shadow medication-card';
card.dataset.id = med.id;
card.innerHTML = `
<div class="flex justify-between items-start mb-2">
<h3 class="font-bold text-lg">${med.name}</h3>
<span class="bg-indigo-100 text-indigo-800 px-2 py-1 rounded text-sm">${med.time}</span>
</div>
<div class="flex items-center mb-2">
<i class="fas fa-bolt text-yellow-500 ml-2"></i>
<span>${med.dosage}</span>
</div>
<div class="flex items-center">
<i class="fas fa-clock text-blue-500 ml-2"></i>
<span>${med.frequency === 'daily' ? 'يومي' : med.frequency === 'weekly' ? 'أسبوعي' : 'شهري'}</span>
</div>
`;
return card;
}
// Edit medication
function editMedication(id) {
const med = medications.find(m => m.id === id);
if (!med) return;
// Fill the form with medication data
document.getElementById('medName').value = med.name;
document.getElementById('medDosage').value = med.dosage;
document.getElementById('medTime').value = med.time;
document.getElementById('medFrequency').value = med.frequency;
document.getElementById('medNotes').value = med.notes || '';
document.getElementById('enableWhatsApp').checked = med.whatsappEnabled;
if (med.frequency === 'custom') {
customDaysContainer.classList.remove('hidden');
// Check the appropriate day checkboxes
med.days.forEach(day => {
const checkbox = document.querySelector(`[name="customDays"][value="${day}"]`);
if (checkbox) {
checkbox.checked = true;
checkbox.dispatchEvent(new Event('change'));
}
});
}
if (med.whatsappEnabled) {
whatsappSection.classList.remove('hidden');
document.getElementById('whatsappNumber').value = med.whatsappNumber || '';
document.getElementById('secondaryContact').value = med.secondaryContact || '';
}
// Show the modal
addMedModal.classList.remove('hidden');
// Remove the medication (will be re-added when form is submitted)
medications = medications.filter(m => m.id !== id);
}
// Delete medication
function deleteMedication(id) {
if (confirm('هل أنت متأكد من حذف هذا الدواء؟')) {
medications = medications.filter(m => m.id !== id);
saveMedications();
renderMedications();
updateStats();
}
}
// Schedule notifications for a medication
function scheduleMedicationNotifications(med) {
// In a real app, we would use the browser's Notification API and set alarms
// For this demo, we'll just simulate it
}
// Check for due medications
function checkForDueMedications() {
const now = new Date();
const currentTime = now.getHours() * 60 + now.getMinutes();
medications.forEach(med => {
if (!med.active) return;
const [hours, minutes] = med.time.split(':').map(Number);
const medTime = hours * 60 + minutes;
// Check if medication is due now (with 1 minute tolerance)
if (Math.abs(currentTime - medTime) <= 1) {
// Check if we already notified for this medication today
const today = now.toDateString();
const alreadyNotified = notifications.some(n =>
n.medId === med.id && new Date(n.date).toDateString() === today
);
if (!alreadyNotified) {
// Create notification
const notification = {
id: Date.now(),
medId: med.id,
title: 'حان وقت الدواء',
message: `حان وقت أخذ ${med.name} (${med.dosage})`,
date: new Date().toISOString(),
read: false
};
notifications.push(notification);
saveNotifications();
// Show notification
showNotification(notification);
// Update UI
renderNotifications();
// If WhatsApp is enabled, send message (simulated)
if (med.whatsappEnabled) {
sendWhatsAppReminder(med);
}
// Show confirmation modal
currentMedication = med;
confirmMessage.innerHTML = `هل أخذت دواء <span class="font-bold">${med.name}</span> (${med.dosage}) في الوقت المحدد؟`;
confirmModal.classList.remove('hidden');
}
}
});
}
// Show notification
function showNotification(notification) {
// In a real app, we would use the browser's Notification API
// For this demo, we'll just add it to our notification list
// Play sound
const audio = new Audio('https://assets.mixkit.co/sfx/preview/mixkit-alarm-digital-clock-beep-989.mp3');
audio.play().catch(e => console.log('Audio play failed:', e));
}
// Send WhatsApp reminder using API
function sendWhatsAppReminder(med) {
const message = `تذكير: حان وقت أخذ ${med.name} (${med.dosage})`;
// Prepare API request data
const requestData = {
apiKey: 'EAAIoEPATD6QBPJc1eQOqVyrpmut0P2WUVUCfXNLlcSFl0KA5WuSeZCaV1SDaAuhZBGPZCz1B2Rc8szs3w0aqsVeMzZCrjBMHO67E2H2cPV6vxHlcI0gwdRuQOZCIKcGLYCWG9G0EAG8itMtpDzsDIiJFj6yHyZAtkKxL0KfJhyZBBDKNB1qhydFTZApZCchTAFHuovZAFCU0EQrBFKaLTib3GAZA9HzAEpz860PNsIYNjp7ZCUoX1u3S',
message: message
};
// Primary contact
if (med.whatsappNumber) {
requestData.phone = med.whatsappNumber;
fetch('https://api.whatsapp.com/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestData)
})
.catch(error => console.error('Error sending WhatsApp:', error));
}
// Secondary contact
if (med.secondaryContact) {
requestData.phone = med.secondaryContact;
fetch('https://api.whatsapp.com/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestData)
})
.catch(error => console.error('Error sending WhatsApp to secondary contact:', error));
}
}
// Toggle notification panel
function toggleNotificationPanel() {
notificationPanel.classList.toggle('hidden');
// Mark all notifications as read when panel is opened
if (!notificationPanel.classList.contains('hidden')) {
notifications.forEach(n => n.read = true);
saveNotifications();
renderNotifications();
}
}
// Render notifications
function renderNotifications() {
notificationList.innerHTML = '';
if (notifications.length === 0) {
notificationList.innerHTML = '<div class="p-4 text-center text-gray-500">لا توجد إشعارات</div>';
notificationCount.classList.add('hidden');
return;
}
// Sort by date (newest first)
const sortedNotifications = [...notifications].sort((a, b) => {
return new Date(b.date) - new Date(a.date);
});
// Show only the last 10 notifications
const recentNotifications = sortedNotifications.slice(0, 10);
recentNotifications.forEach(notif => {
const med = medications.find(m => m.id === notif.medId);
if (!med) return;
const notifElement = document.createElement('div');
notifElement.className = `p-4 border-b ${notif.read ? 'bg-white' : 'bg-blue-50'}`;
notifElement.innerHTML = `
<div class="flex justify-between items-start mb-1">
<h4 class="font-bold">${notif.title}</h4>
<span class="text-xs text-gray-500">${formatDate(notif.date)}</span>
</div>
<p class="text-gray-700">${notif.message}</p>
${med.notes ? `<p class="text-sm text-gray-600 mt-1">ملاحظة: ${med.notes}</p>` : ''}
`;
notificationList.appendChild(notifElement);
});
// Update notification badge
const unreadCount = notifications.filter(n => !n.read).length;
if (unreadCount > 0) {
notificationCount.textContent = unreadCount;
notificationCount.classList.remove('hidden');
} else {
notificationCount.classList.add('hidden');
}
}
// Format date for display
function formatDate(dateString) {
const date = new Date(dateString);
return date.toLocaleTimeString('ar-EG', { hour: '2-digit', minute: '2-digit' });
}
// Confirm medication was taken
function confirmTaken() {
if (!currentMedication) return;
stats.taken++;
saveStats();
updateStats();
confirmModal.classList.add('hidden');
currentMedication = null;
}
// Confirm medication was missed
function confirmMissed() {
if (!currentMedication) return;
stats.missed++;
saveStats();
updateStats();
// Add missed notification
const notification = {
id: Date.now(),
medId: currentMedication.id,
title: 'جرعة فائتة',
message: `فوتت جرعة ${currentMedication.name} (${currentMedication.dosage})`,
date: new Date().toISOString(),
read: false
};
notifications.push(notification);
saveNotifications();
renderNotifications();
confirmModal.classList.add('hidden');
currentMedication = null;
}
<!-- Profile Settings Modal -->
<div id="profileModal" class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
<div class="bg-white rounded-lg w-full max-w-md">
<div class="bg-indigo-600 text-white px-6 py-4 rounded-t-lg flex justify-between items-center">
<h3 class="text-lg font-bold">إعدادات الحساب</h3>
<button id="closeProfileBtn" class="text-white hover:text-indigo-200">
<i class="fas fa-times"></i>
</button>
</div>
<div class="p-6">
<div class="mb-4">
<label class="block text-gray-700 mb-2">اسم المستخدم</label>
<p id="profileUsername" class="font-bold"></p>
</div>
<div class="mb-4">
<label for="profileWhatsapp" class="block text-gray-700 mb-2">رقم واتساب</label>
<input type="tel" id="profileWhatsapp" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="مثال: 966501234567">
</div>
<div class="mb-4">
<label for="profileCaretaker" class="block text-gray-700 mb-2">رقم المتابع</label>
<input type="tel" id="profileCaretaker" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="مثال: 966501234567">
</div>
<div class="mb-4">
<label class="flex items-center">
<input type="checkbox" id="shareList" class="form-checkbox h-5 w-5 text-indigo-600">
<span class="mr-2 text-gray-700">مشاركة قائمة الأدوية مع المتابع</span>
</label>
</div>
<div class="flex justify-end space-x-4 space-x-reverse">
<button id="logoutBtn" class="px-4 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600">تسجيل الخروج</button>
<button id="saveProfileBtn" class="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700">حفظ التغييرات</button>
</div>
</div>
</div>
</div>
// Initialize the app
document.addEventListener('DOMContentLoaded', function() {
// Check if user is logged in
const currentUser = JSON.parse(localStorage.getItem('currentUser'));
if (!currentUser) {
document.getElementById('authModal').classList.remove('hidden');
} else {
init();
}
});
// User authentication functions
const users = JSON.parse(localStorage.getItem('users')) || [];
document.getElementById('signupBtn').addEventListener('click', function() {
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
const whatsapp = document.getElementById('whatsappNumber').value;
const caretaker = document.getElementById('caretakerNumber').value;
if (users.some(u => u.username === username)) {
alert('اسم المستخدم موجود بالفعل');
return;
}
const newUser = {
username,
password,
whatsapp,
caretaker,
shareList: false,
medications: []
};
users.push(newUser);
localStorage.setItem('users', JSON.stringify(users));
localStorage.setItem('currentUser', JSON.stringify(username));
document.getElementById('authModal').classList.add('hidden');
location.reload();
});
document.getElementById('loginBtn').addEventListener('click', function() {
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
const user = users.find(u => u.username === username && u.password === password);
if (!user) {
alert('اسم المستخدم أو كلمة المرور غير صحيحة');
return;
}
localStorage.setItem('currentUser', JSON.stringify(username));
document.getElementById('authModal').classList.add('hidden');
location.reload();
});
// Profile functions
document.getElementById('profileBtn').addEventListener('click', function() {
const currentUser = JSON.parse(localStorage.getItem('currentUser'));
const user = users.find(u => u.username === currentUser);
document.getElementById('profileUsername').textContent = user.username;
document.getElementById('profileWhatsapp').value = user.whatsapp;
document.getElementById('profileCaretaker').value = user.caretaker || '';
document.getElementById('shareList').checked = user.shareList || false;
document.getElementById('profileModal').classList.remove('hidden');
});
document.getElementById('closeProfileBtn').addEventListener('click', function() {
document.getElementById('profileModal').classList.add('hidden');
});
document.getElementById('saveProfileBtn').addEventListener('click', function() {
const currentUser = JSON.parse(localStorage.getItem('currentUser'));
const userIndex = users.findIndex(u => u.username === currentUser);
users[userIndex].whatsapp = document.getElementById('profileWhatsapp').value;
users[userIndex].caretaker = document.getElementById('profileCaretaker').value;
users[userIndex].shareList = document.getElementById('shareList').checked;
localStorage.setItem('users', JSON.stringify(users));
document.getElementById('profileModal').classList.add('hidden');
});
document.getElementById('logoutBtn').addEventListener('click', function() {
localStorage.removeItem('currentUser');
location.reload();
});
// Modify init function to load user-specific data
function init() {
const currentUser = JSON.parse(localStorage.getItem('currentUser'));
const user = users.find(u => u.username === currentUser);
// Load user's medications
medications = user.medications || [];
updateStats();
renderMedications();
renderNotifications();
checkForDueMedications();
setInterval(checkForDueMedications, 60000);
}
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Youssef117/dwaa2a" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>