Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/JReyna217/PharmaVault/llms.txt

Use this file to discover all available pages before exploring further.

The PharmaVault dashboard gives you an at-a-glance view of your entire medication inventory the moment you log in. It aggregates every item you own into four plain-English counters and renders a colour-coded pie chart so you can immediately spot whether stock is healthy, approaching expiry, or already past it — without digging through individual records.

Dashboard Stats

Every time the dashboard loads it calls IInventoryDao.GetDashboardStatsAsync(int userId) and populates a DashboardStatsDto object with four integer counters derived from the quantities stored in your inventory rows.
namespace PharmaVault.Core.Models;

public class DashboardStatsDto
{
    public int TotalStock { get; set; }
    public int ExpiredStock { get; set; }
    public int ExpiringSoonStock { get; set; }
    public int GoodStock { get; set; }
}

TotalStock

The sum of all quantity values across every inventory row that belongs to the authenticated user. This is the headline number shown at the top of the dashboard.

GoodStock

Units whose expiration date falls more than 30 days in the future. These are considered safe to use without any urgency.

ExpiringSoonStock

Units expiring on or before CURRENT_DATE + INTERVAL '30 days' but not yet past today’s date. The 30-day window gives you time to plan before stock becomes unusable.

ExpiredStock

Units whose expiration date is strictly before today (CURRENT_DATE). These should be reviewed and removed from active use.

How Expiration Thresholds Work

The four counters are calculated in a single PostgreSQL query using CASE expressions evaluated against CURRENT_DATE. No application-layer date math is involved — the database computes the buckets at query time.
SELECT
    COALESCE(SUM(quantity), 0) AS TotalStock,
    COALESCE(SUM(CASE WHEN expiration_date < CURRENT_DATE
                      THEN quantity ELSE 0 END), 0)                          AS ExpiredStock,
    COALESCE(SUM(CASE WHEN expiration_date >= CURRENT_DATE
                       AND expiration_date <= CURRENT_DATE + INTERVAL '30 days'
                      THEN quantity ELSE 0 END), 0)                          AS ExpiringSoonStock,
    COALESCE(SUM(CASE WHEN expiration_date > CURRENT_DATE + INTERVAL '30 days'
                      THEN quantity ELSE 0 END), 0)                          AS GoodStock
FROM inventory
WHERE user_id = @UserId;
COALESCE(..., 0) ensures that a user with no inventory rows receives zeroes instead of NULL for every counter.
The thresholds are:
CategoryCondition
Expiredexpiration_date < CURRENT_DATE
Expiring Soonexpiration_date >= CURRENT_DATE AND expiration_date <= CURRENT_DATE + 30 days
Goodexpiration_date > CURRENT_DATE + 30 days

ApexCharts Pie Chart

When TotalStock > 0, the dashboard renders an interactive pie chart powered by the ApexCharts Blazor library. The chart maps each stock category to a fixed colour:
SliceColourHex
Good ConditionGreen#198754
Expiring SoonAmber#ffc107
ExpiredRed#dc3545
The chart background is set to transparent so it blends with any page theme. When TotalStock equals zero the chart is hidden entirely to avoid rendering an empty or misleading graphic.

InventoryChartData Model

Each pie slice is backed by a lightweight data class that holds a human-readable label and a count:
public class InventoryChartData
{
    public string Status { get; set; } = string.Empty;
    public int Count { get; set; }
}
The three instances are constructed in Dashboard.razor.cs after stats are loaded:
_chartData = new List<InventoryChartData>
{
    new() { Status = "Good Condition",   Count = _stats.GoodStock },
    new() { Status = "Expiring Soon",    Count = _stats.ExpiringSoonStock },
    new() { Status = "Expired",          Count = _stats.ExpiredStock }
};

_chartOptions = new ApexChartOptions<InventoryChartData>
{
    Colors = new List<string> { "#198754", "#ffc107", "#dc3545" },
    Chart  = new Chart { Background = "transparent" }
};

Accessing the Dashboard

The dashboard is served at the /dashboard route and requires an authenticated session. Unauthenticated visitors are redirected to / (the login page) automatically by the cookie authentication middleware.
Once authenticated, the page header displays two pieces of contextual information resolved from the active ClaimsPrincipal:
  • User’s full name — read from ClaimTypes.Name, which is set to User.FullName at login.
  • Current date — formatted as "dddd, MMMM dd, yyyy" (e.g., Monday, July 14, 2025) using DateTime.Now.
UserName    = user.Identity.Name ?? "User";
CurrentDate = DateTime.Now.ToString("dddd, MMMM dd, yyyy");

Build docs developers (and LLMs) love