feat: initial setup, collections, caregiver frontend
This commit is contained in:
166
src/app/(app)/caregiver/dashboard/page.tsx
Normal file
166
src/app/(app)/caregiver/dashboard/page.tsx
Normal file
@@ -0,0 +1,166 @@
|
||||
'use client'
|
||||
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import Link from 'next/link'
|
||||
|
||||
interface User {
|
||||
id: number
|
||||
name?: string
|
||||
email: string
|
||||
tenants?: Array<{
|
||||
tenant: { id: number; name: string } | number
|
||||
roles?: string[]
|
||||
}>
|
||||
}
|
||||
|
||||
interface OrderStats {
|
||||
pending: number
|
||||
preparing: number
|
||||
prepared: number
|
||||
total: number
|
||||
}
|
||||
|
||||
export default function CaregiverDashboardPage() {
|
||||
const router = useRouter()
|
||||
const [user, setUser] = useState<User | null>(null)
|
||||
const [stats, setStats] = useState<OrderStats>({ pending: 0, preparing: 0, prepared: 0, total: 0 })
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
// Check auth
|
||||
const userRes = await fetch('/api/users/me', { credentials: 'include' })
|
||||
if (!userRes.ok) {
|
||||
router.push('/caregiver/login')
|
||||
return
|
||||
}
|
||||
const userData = await userRes.json()
|
||||
if (!userData.user) {
|
||||
router.push('/caregiver/login')
|
||||
return
|
||||
}
|
||||
setUser(userData.user)
|
||||
|
||||
// Fetch today's orders stats
|
||||
const today = new Date().toISOString().split('T')[0]
|
||||
const ordersRes = await fetch(`/api/meal-orders?where[date][equals]=${today}&limit=1000`, {
|
||||
credentials: 'include',
|
||||
})
|
||||
if (ordersRes.ok) {
|
||||
const ordersData = await ordersRes.json()
|
||||
const orders = ordersData.docs || []
|
||||
setStats({
|
||||
pending: orders.filter((o: { status: string }) => o.status === 'pending').length,
|
||||
preparing: orders.filter((o: { status: string }) => o.status === 'preparing').length,
|
||||
prepared: orders.filter((o: { status: string }) => o.status === 'prepared').length,
|
||||
total: orders.length,
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching data:', error)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
fetchData()
|
||||
}, [router])
|
||||
|
||||
const handleLogout = async () => {
|
||||
await fetch('/api/users/logout', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
})
|
||||
router.push('/caregiver/login')
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="login-page">
|
||||
<div className="spinner" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const tenantName =
|
||||
user?.tenants?.[0]?.tenant && typeof user.tenants[0].tenant === 'object'
|
||||
? user.tenants[0].tenant.name
|
||||
: 'Care Home'
|
||||
|
||||
return (
|
||||
<>
|
||||
<header className="header">
|
||||
<div className="header__content">
|
||||
<h1 className="header__title">{tenantName}</h1>
|
||||
<div className="header__user">
|
||||
<span className="header__user-name">{user?.name || user?.email}</span>
|
||||
<button onClick={handleLogout} className="btn btn--secondary">
|
||||
Logout
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main className="container">
|
||||
<div className="page-title">
|
||||
<h1>Dashboard</h1>
|
||||
<p>Today's overview</p>
|
||||
</div>
|
||||
|
||||
<div className="stats-grid">
|
||||
<div className="stat-card">
|
||||
<div className="stat-card__value">{stats.total}</div>
|
||||
<div className="stat-card__label">Total Orders Today</div>
|
||||
</div>
|
||||
<div className="stat-card">
|
||||
<div className="stat-card__value">{stats.pending}</div>
|
||||
<div className="stat-card__label">Pending</div>
|
||||
</div>
|
||||
<div className="stat-card">
|
||||
<div className="stat-card__value">{stats.preparing}</div>
|
||||
<div className="stat-card__label">Preparing</div>
|
||||
</div>
|
||||
<div className="stat-card">
|
||||
<div className="stat-card__value">{stats.prepared}</div>
|
||||
<div className="stat-card__label">Prepared</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h2>Quick Actions</h2>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<div className="quick-actions">
|
||||
<Link href="/caregiver/orders/new?mealType=breakfast" className="quick-action">
|
||||
<div className="quick-action__icon">🌅</div>
|
||||
<div className="quick-action__label">New Breakfast</div>
|
||||
</Link>
|
||||
<Link href="/caregiver/orders/new?mealType=lunch" className="quick-action">
|
||||
<div className="quick-action__icon">☀️</div>
|
||||
<div className="quick-action__label">New Lunch</div>
|
||||
</Link>
|
||||
<Link href="/caregiver/orders/new?mealType=dinner" className="quick-action">
|
||||
<div className="quick-action__icon">🌙</div>
|
||||
<div className="quick-action__label">New Dinner</div>
|
||||
</Link>
|
||||
<Link href="/caregiver/orders" className="quick-action">
|
||||
<div className="quick-action__icon">📋</div>
|
||||
<div className="quick-action__label">View Orders</div>
|
||||
</Link>
|
||||
<Link href="/caregiver/residents" className="quick-action">
|
||||
<div className="quick-action__icon">👥</div>
|
||||
<div className="quick-action__label">Residents</div>
|
||||
</Link>
|
||||
<Link href="/admin" className="quick-action">
|
||||
<div className="quick-action__icon">⚙️</div>
|
||||
<div className="quick-action__label">Admin Panel</div>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user