Skip to main content

Overview

Nutritionist components provide interfaces for nutritionists to manage their profiles, view and manage patients, and collect patient data. These components are restricted to users with the nutricionista role.

NutricionistaProfile

Location: app/Livewire/Nutricionista/NutricionistaProfile.php:14 View: resources/views/livewire/nutricionista/nutricionista-profile.blade.php

Purpose

Manages nutritionist profile information including personal details, profile photo, consultation pricing, and password changes.

Traits

  • WithFileUploads - Enables file upload functionality for profile photos

Properties

PropertyTypeDefaultDescription
namestring-Nutritionist’s name
emailstring-Email address (read-only)
phonestring''Contact phone number
profile_photomixednullUploaded profile photo file
profile_photo_pathstring''Current photo path
consultation_pricefloat30.00Price per consultation
current_passwordstring''Current password for verification
passwordstring''New password
password_confirmationstring''Password confirmation
hasPersonalDataboolfalseWhether personal data exists
hasPasswordboolfalseWhether custom password is set

Validation Rules

Location: app/Livewire/Nutricionista/NutricionistaProfile.php:32
'name' => 'required|string|max:255'
'phone' => 'nullable|string|max:10'
'profile_photo' => 'nullable|image|max:2048'
'consultation_price' => 'required|numeric|min:0|max:999999.99'
'current_password' => 'required_with:password|string' // if hasPassword
'password' => 'nullable|string|min:8|confirmed'

Methods

mount(): void

Location: app/Livewire/Nutricionista/NutricionistaProfile.php:66 Initializes the component with the authenticated nutritionist’s data. Process:
  1. Verifies user has nutricionista role (aborts with 403 if not)
  2. Loads user name and email
  3. Checks if user has custom password (not default)
  4. Loads personal data if exists
  5. Loads consultation price from settings
if ($user->personalData) {
    $this->hasPersonalData = true;
    $this->phone = $user->personalData->phone ?? '';
    $this->profile_photo_path = $user->personalData->profile_photo ?? '';
}

saveProfile(): void

Location: app/Livewire/Nutricionista/NutricionistaProfile.php:93 Saves profile information including name, phone, photo, and consultation price. Process:
  1. Validates profile fields
  2. Updates user name
  3. Handles profile photo upload:
    • Deletes old photo if exists
    • Stores new photo in profile-photos directory
  4. Updates or creates PersonalData record
  5. Updates or creates NutricionistaSettings with consultation price
  6. Redirects with success message
Flash Messages:
  • success: “Tu perfil ha sido actualizado correctamente.”
  • error: “Error al actualizar el perfil:

updatePassword(): void

Location: app/Livewire/Nutricionista/NutricionistaProfile.php:148 Updates the nutritionist’s password with proper verification. Process:
  1. Validates current password (if user has custom password)
  2. Validates new password (min 8 chars, confirmed)
  3. Verifies current password matches
  4. Hashes and saves new password
  5. Sends PasswordChangedNotification to user
  6. Resets password fields
  7. Redirects with success message
Flash Messages:
  • password_success: “Tu contraseña ha sido actualizada correctamente.”
  • password_error: “La contraseña actual es incorrecta.” or “Error al actualizar la contraseña:

Usage Example

<livewire:nutricionista.nutricionista-profile />

PatientDataForm

Location: app/Livewire/Nutricionista/PatientDataForm.php:11 View: resources/views/livewire/nutricionista/patient-data-form.blade.php

Purpose

Allows nutritionists to create personal data records for patients who don’t have them yet. Used during the first appointment workflow.

Properties

PropertyTypeDefaultDescription
patientUser-Patient user model
appointmentId?intnullAssociated appointment ID
cedulastring''National ID number
phonestring''Phone number
addressstring''Physical address
birth_datestring''Date of birth
genderstring''Gender (male/female/other)
hasPersonalDataboolfalseWhether patient has data
isReadOnlyboolfalseForm is read-only

Validation Rules

Location: app/Livewire/Nutricionista/PatientDataForm.php:24
'gender' => 'required|in:male,female,other'
'birth_date' => 'required|date|before:today|after:{120 years ago}'
'cedula' => 'nullable|numeric|digits_between:6,20|unique:personal_data,cedula'
'phone' => 'nullable|numeric|digits:10'
'address' => 'nullable|string|max:255'

Methods

mount(User $patient, ?int $appointmentId = null): void

Location: app/Livewire/Nutricionista/PatientDataForm.php:50 Initializes the form for a specific patient. Process:
  1. Verifies authenticated user is a nutritionist (aborts with 403 if not)
  2. Verifies patient has paciente role (aborts with 404 if not)
  3. Checks if patient already has personal data
  4. If data exists, loads it and sets form to read-only
  5. Stores optional appointment ID for post-save redirect
if ($patient->personalData) {
    $this->hasPersonalData = true;
    $this->isReadOnly = true;
    // Load existing data...
}

save(): void

Location: app/Livewire/Nutricionista/PatientDataForm.php:80 Creates personal data record for the patient. Process:
  1. Prevents save if patient already has data
  2. Validates all input fields
  3. Creates PersonalData record
  4. Sends PersonalDataCreatedNotification to patient
  5. Redirects based on appointment ID:
    • If appointment ID exists: redirects to create attention record
    • Otherwise: redirects to patient list
Flash Messages:
  • error: “Este paciente ya tiene datos personales asignados.” or “Error al guardar los datos:

Usage Example

<livewire:nutricionista.patient-data-form :patient="$patient" :appointmentId="$appointmentId" />

PatientsTable

Location: app/Livewire/Nutricionista/PatientsTable.php:10 View: resources/views/livewire/nutricionista/patients-table.blade.php

Purpose

Provides a filterable, sortable table of all patients associated with the authenticated nutritionist.

Traits

  • WithPagination - Enables pagination support

Properties

PropertyTypeDefaultDescription
searchstring''Search term for name/email
estadostring''Filter by user state
proximas_citasstring''Filter patients with upcoming appointments
sortstring'name'Sort order (name/recent)

Query String Parameters

Location: app/Livewire/Nutricionista/PatientsTable.php:19
protected $queryString = [
    'search' => ['except' => ''],
    'estado' => ['except' => ''],
    'proximas_citas' => ['except' => ''],
    'sort' => ['except' => 'name'],
    'page' => ['except' => 1],
];

Methods

updatingSearch(): void

Location: app/Livewire/Nutricionista/PatientsTable.php:27 Resets pagination when search changes.

updatedEstado(): void

Location: app/Livewire/Nutricionista/PatientsTable.php:32 Resets pagination when state filter changes.

updatedProximasCitas(): void

Location: app/Livewire/Nutricionista/PatientsTable.php:37 Resets pagination when appointment filter changes.

clearFilters(): void

Location: app/Livewire/Nutricionista/PatientsTable.php:47 Resets all filters and sorting to defaults.

render()

Location: app/Livewire/Nutricionista/PatientsTable.php:56 Builds and executes the query to fetch filtered patients. Query Features:
  1. Filters to users with paciente role
  2. Eager loads relationships:
    • userState
    • personalData
    • appointmentsAsPaciente (only next pending appointment)
  3. Counts total appointments per patient
  4. Filters by search term (case-insensitive ILIKE)
  5. Filters by user state
  6. Filters by upcoming appointments if requested
  7. Sorts by name or most recent appointment
  8. Paginates with 12 patients per page
Sorting Options:
  • name: Alphabetical by patient name
  • recent: By most recent appointment date
Returns:
  • patients - Paginated patient collection
  • userStates - All available user states for filtering

Advanced Query Example

Location: app/Livewire/Nutricionista/PatientsTable.php:95 Filtering patients with upcoming appointments:
if ($this->proximas_citas === '1') {
    $query->whereHas('appointmentsAsPaciente', function($q) use ($nutricionista) {
        $q->where('nutricionista_id', $nutricionista->id)
          ->whereHas('appointmentState', fn($sq) => $sq->where('name', 'pendiente'))
          ->where('start_time', '>=', now());
    });
}

Usage Example

<livewire:nutricionista.patients-table />

Security Considerations

  • All components verify the authenticated user has the nutricionista role
  • PatientDataForm additionally verifies the target user has the paciente role
  • Patient data cannot be edited once created (read-only after initial save)
  • File uploads are restricted to images with 2MB max size
  • Cedula (national ID) uniqueness is enforced
  • Password changes require current password verification
  • All inputs are validated server-side
  • App\Models\User - User accounts
  • App\Models\PersonalData - Personal information
  • App\Models\NutricionistaSettings - Nutritionist-specific settings
  • App\Models\UserState - User account states
  • App\Models\Appointment - Appointments

Notifications

  • PasswordChangedNotification - Sent when password is updated
  • PersonalDataCreatedNotification - Sent to patient when their data is created

Build docs developers (and LLMs) love