added dark mode

This commit is contained in:
2026-02-15 23:11:33 -06:00
parent e97347ff65
commit d8fde5b516
18 changed files with 543 additions and 366 deletions

View File

@@ -214,7 +214,7 @@ export default function MedicationsPage() {
return (
<div className="p-4 space-y-6">
<div className="flex items-center justify-between">
<h1 className="text-2xl font-bold text-gray-900">Medications</h1>
<h1 className="text-2xl font-bold text-gray-900 dark:text-gray-100">Medications</h1>
<Link href="/dashboard/medications/new" className="bg-indigo-600 text-white p-2 rounded-full">
<PlusIcon size={24} />
</Link>
@@ -224,7 +224,7 @@ export default function MedicationsPage() {
<PushNotificationToggle />
{error && (
<div className="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-lg">
<div className="bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 text-red-700 dark:text-red-400 px-4 py-3 rounded-lg">
{error}
</div>
)}
@@ -232,38 +232,38 @@ export default function MedicationsPage() {
{/* Due Now Section */}
{dueEntries.length > 0 && (
<div>
<h2 className="text-lg font-semibold text-gray-900 mb-3">Due</h2>
<h2 className="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-3">Due</h2>
<div className="space-y-3">
{dueEntries.map((entry) => (
<div
key={`${entry.item.medication.id}-${entry.time}`}
className={`bg-white rounded-xl p-4 shadow-sm ${borderColor(entry.status)}`}
className={`bg-white dark:bg-gray-800 rounded-xl p-4 shadow-sm ${borderColor(entry.status)}`}
>
<div className="flex items-center justify-between mb-2">
<div>
<div className="flex items-center gap-2">
<h3 className="font-semibold text-gray-900">{entry.item.medication.name}</h3>
<h3 className="font-semibold text-gray-900 dark:text-gray-100">{entry.item.medication.name}</h3>
{entry.item.is_previous_day && (
<span className="text-xs bg-purple-100 text-purple-700 px-2 py-0.5 rounded">Yesterday</span>
<span className="text-xs bg-purple-100 dark:bg-purple-900/30 text-purple-700 dark:text-purple-400 px-2 py-0.5 rounded">Yesterday</span>
)}
</div>
<p className="text-sm text-gray-500">{entry.item.medication.dosage} {entry.item.medication.unit}</p>
<p className="text-sm text-gray-500 dark:text-gray-400">{entry.item.medication.dosage} {entry.item.medication.unit}</p>
</div>
</div>
<div className="flex items-center justify-between bg-gray-50 rounded-lg p-3">
<div className="flex items-center justify-between bg-gray-50 dark:bg-gray-700 rounded-lg p-3">
<div className="flex items-center gap-2">
<ClockIcon size={16} className="text-gray-500" />
<span className="font-medium">{entry.time}</span>
<ClockIcon size={16} className="text-gray-500 dark:text-gray-400" />
<span className="font-medium text-gray-900 dark:text-gray-100">{entry.time}</span>
{entry.status === 'overdue' && (
<span className="text-xs text-red-600 font-medium">Overdue</span>
<span className="text-xs text-red-600 dark:text-red-400 font-medium">Overdue</span>
)}
</div>
{entry.status === 'taken' ? (
<span className="text-green-600 font-medium flex items-center gap-1">
<span className="text-green-600 dark:text-green-400 font-medium flex items-center gap-1">
<CheckIcon size={16} /> Taken
</span>
) : entry.status === 'skipped' ? (
<span className="text-gray-400 font-medium">Skipped</span>
<span className="text-gray-400 dark:text-gray-500 font-medium">Skipped</span>
) : (
<div className="flex gap-2">
<button
@@ -274,7 +274,7 @@ export default function MedicationsPage() {
</button>
<button
onClick={() => handleSkip(entry.item.medication.id, entry.time)}
className="text-gray-500 px-2 py-1"
className="text-gray-500 dark:text-gray-400 px-2 py-1"
>
Skip
</button>
@@ -290,18 +290,18 @@ export default function MedicationsPage() {
{/* PRN Section */}
{prnEntries.length > 0 && (
<div>
<h2 className="text-lg font-semibold text-gray-900 mb-3">As Needed</h2>
<h2 className="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-3">As Needed</h2>
<div className="space-y-3">
{prnEntries.map((item) => (
<div key={item.medication.id} className="bg-white rounded-xl p-4 shadow-sm">
<div key={item.medication.id} className="bg-white dark:bg-gray-800 rounded-xl p-4 shadow-sm">
<div className="flex items-center justify-between mb-2">
<div>
<h3 className="font-semibold text-gray-900">{item.medication.name}</h3>
<p className="text-sm text-gray-500">{item.medication.dosage} {item.medication.unit}</p>
<h3 className="font-semibold text-gray-900 dark:text-gray-100">{item.medication.name}</h3>
<p className="text-sm text-gray-500 dark:text-gray-400">{item.medication.dosage} {item.medication.unit}</p>
</div>
</div>
<div className="flex items-center justify-between bg-gray-50 rounded-lg p-3">
<span className="text-gray-500 text-sm">As needed</span>
<div className="flex items-center justify-between bg-gray-50 dark:bg-gray-700 rounded-lg p-3">
<span className="text-gray-500 dark:text-gray-400 text-sm">As needed</span>
<button
onClick={() => handleTake(item.medication.id)}
className="bg-green-600 text-white px-3 py-1 rounded-lg text-sm font-medium"
@@ -318,24 +318,24 @@ export default function MedicationsPage() {
{/* Upcoming Section */}
{upcomingEntries.length > 0 && (
<div>
<h2 className="text-lg font-semibold text-gray-500 mb-3">Upcoming</h2>
<h2 className="text-lg font-semibold text-gray-500 dark:text-gray-400 mb-3">Upcoming</h2>
<div className="space-y-3">
{upcomingEntries.map((entry) => (
<div
key={`${entry.item.medication.id}-${entry.time}`}
className="bg-gray-50 rounded-xl p-4 shadow-sm opacity-75"
className="bg-gray-50 dark:bg-gray-800 rounded-xl p-4 shadow-sm opacity-75"
>
<div className="flex items-center justify-between">
<div>
<div className="flex items-center gap-2">
<h3 className="font-medium text-gray-700">{entry.item.medication.name}</h3>
<h3 className="font-medium text-gray-700 dark:text-gray-300">{entry.item.medication.name}</h3>
{entry.item.is_next_day && (
<span className="text-xs bg-blue-100 text-blue-700 px-2 py-0.5 rounded">Tomorrow</span>
<span className="text-xs bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-400 px-2 py-0.5 rounded">Tomorrow</span>
)}
</div>
<p className="text-sm text-gray-400">{entry.item.medication.dosage} {entry.item.medication.unit}</p>
<p className="text-sm text-gray-400 dark:text-gray-500">{entry.item.medication.dosage} {entry.item.medication.unit}</p>
</div>
<div className="flex items-center gap-2 text-gray-400">
<div className="flex items-center gap-2 text-gray-400 dark:text-gray-500">
<ClockIcon size={16} />
<span className="font-medium">{entry.time}</span>
</div>
@@ -348,15 +348,15 @@ export default function MedicationsPage() {
{/* All Medications */}
<div>
<h2 className="text-lg font-semibold text-gray-900 mb-3">All Medications</h2>
<h2 className="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-3">All Medications</h2>
{medications.length === 0 ? (
<div className="bg-white rounded-xl p-8 shadow-sm text-center">
<div className="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-4">
<PillIcon className="text-gray-400" size={32} />
<div className="bg-white dark:bg-gray-800 rounded-xl p-8 shadow-sm text-center">
<div className="w-16 h-16 bg-gray-100 dark:bg-gray-700 rounded-full flex items-center justify-center mx-auto mb-4">
<PillIcon className="text-gray-400 dark:text-gray-500" size={32} />
</div>
<h3 className="font-semibold text-gray-900 mb-1">No medications yet</h3>
<p className="text-gray-500 text-sm mb-4">Add your medications to track them</p>
<h3 className="font-semibold text-gray-900 dark:text-gray-100 mb-1">No medications yet</h3>
<p className="text-gray-500 dark:text-gray-400 text-sm mb-4">Add your medications to track them</p>
<Link href="/dashboard/medications/new" className="inline-block bg-indigo-600 text-white px-4 py-2 rounded-lg font-medium">
Add Medication
</Link>
@@ -366,41 +366,41 @@ export default function MedicationsPage() {
{medications.map((med) => {
const { percent: adherencePercent, isPrn } = getAdherenceForMed(med.id);
return (
<div key={med.id} className="bg-white rounded-xl p-4 shadow-sm">
<div key={med.id} className="bg-white dark:bg-gray-800 rounded-xl p-4 shadow-sm">
<div className="flex items-start justify-between">
<div className="flex-1">
<div className="flex items-center gap-2">
<h3 className="font-semibold text-gray-900">{med.name}</h3>
<h3 className="font-semibold text-gray-900 dark:text-gray-100">{med.name}</h3>
{!med.active && (
<span className="text-xs bg-gray-100 text-gray-500 px-2 py-0.5 rounded">Inactive</span>
<span className="text-xs bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 px-2 py-0.5 rounded">Inactive</span>
)}
</div>
<p className="text-gray-500 text-sm">{med.dosage} {med.unit} &middot; {formatSchedule(med)}</p>
<p className="text-gray-500 dark:text-gray-400 text-sm">{med.dosage} {med.unit} &middot; {formatSchedule(med)}</p>
{med.times.length > 0 && (
<p className="text-gray-400 text-sm mt-1">Times: {med.times.join(', ')}</p>
<p className="text-gray-400 dark:text-gray-500 text-sm mt-1">Times: {med.times.join(', ')}</p>
)}
</div>
<button
onClick={() => handleDelete(med.id)}
className="text-red-500 p-2"
className="text-red-500 dark:text-red-400 p-2"
>
<TrashIcon size={18} />
</button>
</div>
{/* Adherence */}
<div className="mt-3 pt-3 border-t border-gray-100">
<div className="mt-3 pt-3 border-t border-gray-100 dark:border-gray-700">
{isPrn || adherencePercent === null ? (
<span className="text-sm text-gray-400">PRN &mdash; no adherence tracking</span>
<span className="text-sm text-gray-400 dark:text-gray-500">PRN &mdash; no adherence tracking</span>
) : (
<>
<div className="flex items-center justify-between mb-1">
<span className="text-sm text-gray-500">30-day adherence</span>
<span className={`font-semibold ${adherencePercent >= 80 ? 'text-green-600' : adherencePercent >= 50 ? 'text-yellow-600' : 'text-red-600'}`}>
<span className="text-sm text-gray-500 dark:text-gray-400">30-day adherence</span>
<span className={`font-semibold ${adherencePercent >= 80 ? 'text-green-600 dark:text-green-400' : adherencePercent >= 50 ? 'text-yellow-600 dark:text-yellow-400' : 'text-red-600 dark:text-red-400'}`}>
{adherencePercent}%
</span>
</div>
<div className="h-2 bg-gray-100 rounded-full overflow-hidden">
<div className="h-2 bg-gray-100 dark:bg-gray-700 rounded-full overflow-hidden">
<div
className={`h-full ${adherencePercent >= 80 ? 'bg-green-500' : adherencePercent >= 50 ? 'bg-yellow-500' : 'bg-red-500'}`}
style={{ width: `${adherencePercent}%` }}