Skip to main content

Overview

The Calendar component provides an interactive monthly calendar view that displays health measurements, exercises, and medical appointments. Users can navigate between months and select individual days to view detailed information.

Class Information

Namespace: App\Livewire\Dashboard Class: Calendar Traits: HasContext

Public Properties

PropertyTypeDescription
currentDateCarbonThe currently displayed month/year
selectedDateCarbon|nullThe selected date for viewing details
dayDetailsarrayContains detailed data for the selected day

Methods

mount()

Initializes the component with the current date.
public function mount()
{
    $this->currentDate = Carbon::now();
}

nextMonth()

Navigates to the next month in the calendar.
public function nextMonth()
{
    $this->currentDate->addMonth();
}
Usage:
<button wire:click="nextMonth">Next Month</button>

prevMonth()

Navigates to the previous month in the calendar.
public function prevMonth()
{
    $this->currentDate->subMonth();
}
Usage:
<button wire:click="prevMonth">Previous Month</button>

goToCurrentMonth()

Resets the calendar to the current month.
public function goToCurrentMonth()
{
    $this->currentDate = Carbon::now();
}
Usage:
<button wire:click="goToCurrentMonth">Today</button>

selectDay($dateString)

Selects a specific day and loads all related health data for that date. Parameters:
  • $dateString (string) - Date in parseable format (e.g., ‘Y-m-d’)
public function selectDay($dateString)
{
    $this->selectedDate = Carbon::parse($dateString);
    $userId = $this->getTargetUserId();

    $startOfDay = $this->selectedDate->copy()->startOfDay();
    $endOfDay = $this->selectedDate->copy()->endOfDay();
    $range = [$startOfDay, $endOfDay];

    $this->dayDetails = [
        'hearts' => MeasurementHeart::where('user_id', $userId)->whereBetween('date', $range)->latest('date')->get(),
        'weights' => MeasurementWeight::where('user_id', $userId)->whereBetween('date', $range)->latest('date')->get(),
        'exercises' => ActivityExercise::with('attachments')->where('user_id', $userId)->whereBetween('date', $range)->latest('date')->get(),
        'appointments' => MedicalAppointment::with('attachments')->where('user_id', $userId)->whereBetween('date', $range)->latest('date')->get(),
    ];

    $this->dispatch('open-modal', 'day-details');
}
Usage:
<div wire:click="selectDay('{{ $day['date']->format('Y-m-d') }}')">
    {{ $day['date']->format('d') }}
</div>
Day Details Structure:
  • hearts - Collection of MeasurementHeart records
  • weights - Collection of MeasurementWeight records
  • exercises - Collection of ActivityExercise records with attachments
  • appointments - Collection of MedicalAppointment records with attachments

refresh()

Refreshes the calendar component. Called via event listener.
#[On('refresh-calendar')]
public function refresh(){}

Event Listeners

EventMethodDescription
refresh-calendarrefresh()Refreshes the calendar display

Event Dispatchers

EventParametersDescription
open-modal'day-details'Opens the day details modal

Render Data

The render() method provides the following data to the view:
VariableTypeDescription
daysarrayArray of day objects with metadata
monthNamestringFormatted month and year (e.g., “January 2024”)
nextAppointmentMedicalAppointment|nullNext upcoming appointment
latestWeightMeasurementWeight|nullMost recent weight measurement
weightDifffloatDifference between latest and previous weight
weeklyMinutesintTotal exercise minutes in the last 7 days
weeklyActivitiesCountintNumber of activities this week

Day Object Structure

Each day in the days array contains:
[
    'date' => Carbon,           // The date object
    'isCurrentMonth' => bool,   // Whether day belongs to current month
    'isToday' => bool,          // Whether day is today
    'hasHeart' => bool,         // Has heart measurements
    'hasWeight' => bool,        // Has weight measurements
    'hasExercise' => bool,      // Has exercise activities
    'hasAppointment' => bool,   // Has medical appointments
]

Component Usage

Basic Implementation

<livewire:dashboard.calendar />

Blade Template Example

<div>
    <div class="calendar-header">
        <button wire:click="prevMonth">Previous</button>
        <h2>{{ $monthName }}</h2>
        <button wire:click="nextMonth">Next</button>
        <button wire:click="goToCurrentMonth">Today</button>
    </div>

    <div class="calendar-grid">
        @foreach($days as $day)
            <div 
                wire:click="selectDay('{{ $day['date']->format('Y-m-d') }}')"
                class="calendar-day 
                    {{ $day['isCurrentMonth'] ? 'current-month' : 'other-month' }}
                    {{ $day['isToday'] ? 'today' : '' }}"
            >
                <span>{{ $day['date']->format('d') }}</span>
                
                @if($day['hasHeart'])
                    <span class="indicator heart"></span>
                @endif
                
                @if($day['hasWeight'])
                    <span class="indicator weight"></span>
                @endif
                
                @if($day['hasExercise'])
                    <span class="indicator exercise">🏃</span>
                @endif
                
                @if($day['hasAppointment'])
                    <span class="indicator appointment">📅</span>
                @endif
            </div>
        @endforeach
    </div>

    <div class="stats">
        <p>Weekly Exercise: {{ $weeklyMinutes }} minutes</p>
        @if($nextAppointment)
            <p>Next Appointment: {{ $nextAppointment->date->format('M d, Y') }}</p>
        @endif
        @if($latestWeight)
            <p>Current Weight: {{ $latestWeight->weight }} kg 
                @if($weightDiff != 0)
                    ({{ $weightDiff > 0 ? '+' : '' }}{{ $weightDiff }} kg)
                @endif
            </p>
        @endif
    </div>
</div>

Dependencies

  • Carbon\Carbon - Date manipulation
  • App\Models\MeasurementHeart - Heart measurement model
  • App\Models\MeasurementWeight - Weight measurement model
  • App\Models\ActivityExercise - Exercise activity model
  • App\Models\MedicalAppointment - Medical appointment model
  • App\Traits\HasContext - Context trait for user targeting

Build docs developers (and LLMs) love