Enhance person editing functionality and birthday reminders

- Added a modal for editing person details, including name, role, favorite color, birthday, and description.
- Implemented visibility toggling for PIN input based on role selection, ensuring security for Head of Household.
- Introduced birthday reminder functionality in the calendar, generating events for upcoming birthdays with appropriate notifications.
- Updated calendar and settings UI to accommodate new features, improving user experience and data management.
This commit is contained in:
2026-03-31 18:08:22 -05:00
parent 93ecc5910a
commit df06dcc0d7
6 changed files with 347 additions and 53 deletions
+1
View File
@@ -77,6 +77,7 @@ $iconByType = [
'grocery_due' => 'fa-cart-shopping',
'expense' => 'fa-coins',
'bill_day' => 'fa-file-invoice-dollar',
'birthday_reminder' => 'fa-cake-candles',
];
?>
+68
View File
@@ -354,6 +354,73 @@ $permanenceOptions = [
<div class="alert d-none" id="addPersonFeedback" role="status"></div>
</div>
</form>
<?php
$peopleEditPayload = [];
foreach ($people as $ep) {
$peopleEditPayload[] = [
'id' => (string) ($ep['id'] ?? ''),
'name' => (string) ($ep['name'] ?? ''),
'role' => (string) ($ep['role'] ?? ROLE_CHILD),
'favoriteColor' => (string) ($ep['favoriteColor'] ?? '#4a90e2'),
'birthday' => (string) ($ep['birthday'] ?? ''),
'description' => (string) ($ep['description'] ?? ''),
];
}
?>
<script type="application/json" id="settingsPeopleEditPayload"><?= json_encode($peopleEditPayload, JSON_HEX_TAG | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE) ?></script>
<div class="modal fade" id="editPersonModal" tabindex="-1" aria-labelledby="editPersonModalLabel" aria-hidden="true" data-bs-backdrop="false">
<div class="modal-dialog modal-dialog-scrollable">
<div class="modal-content">
<form id="editPersonForm">
<div class="modal-header">
<h3 class="modal-title h5" id="editPersonModalLabel">Edit person</h3>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body row g-3">
<input type="hidden" name="id" id="edit_person_id" value="">
<input type="hidden" id="edit_person_initial_role" value="">
<div class="col-12">
<label class="form-label" for="edit_name">Name</label>
<input class="form-control" id="edit_name" name="name" required maxlength="120" autocomplete="name">
</div>
<div class="col-md-6">
<label class="form-label" for="edit_role">Role</label>
<select class="form-select" id="edit_role" name="role">
<option value="<?= ROLE_CHILD ?>">Child</option>
<option value="<?= ROLE_ADULT ?>">Adult</option>
<option value="<?= ROLE_HEAD ?>">Head of household</option>
</select>
</div>
<div class="col-md-6">
<label class="form-label" for="edit_favoriteColor">Favorite color</label>
<input type="color" class="form-control form-control-color" id="edit_favoriteColor" name="favoriteColor" value="#4a90e2">
</div>
<div class="col-12" id="edit_pin_wrap">
<label class="form-label" for="edit_pin">PIN for new Head of household (4+ characters)</label>
<input type="password" class="form-control" id="edit_pin" minlength="4" autocomplete="new-password">
</div>
<div class="col-md-6">
<label class="form-label" for="edit_birthday">Birthday (optional)</label>
<input type="date" class="form-control" id="edit_birthday" name="birthday" autocomplete="bday">
</div>
<div class="col-12">
<label class="form-label" for="edit_description">Notes (optional)</label>
<textarea class="form-control" id="edit_description" name="description" rows="2" maxlength="500" placeholder="Short note visible in household tools"></textarea>
</div>
<div class="col-12">
<div class="alert d-none" id="editPersonFeedback" role="status"></div>
</div>
</div>
<div class="modal-footer flex-wrap gap-2 justify-content-between">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Save</button>
</div>
</form>
</div>
</div>
</div>
<?php else: ?>
<p class="text-muted">Only a verified Head of household can add or edit people.</p>
<?php endif; ?>
@@ -380,6 +447,7 @@ $permanenceOptions = [
<button type="button" class="btn btn-sm btn-outline-secondary btn-rotate-person-nfc-token" data-id="<?= htmlspecialchars($p['id'] ?? '', ENT_QUOTES, 'UTF-8') ?>" data-name="<?= htmlspecialchars((string) ($p['name'] ?? ''), ENT_QUOTES, 'UTF-8') ?>">Rotate token</button>
</td>
<td class="text-end text-nowrap">
<button type="button" class="btn btn-sm btn-outline-primary btn-edit-person" data-person-id="<?= htmlspecialchars($p['id'] ?? '', ENT_QUOTES, 'UTF-8') ?>">Edit</button>
<?php if (($p['role'] ?? '') === ROLE_HEAD): ?>
<button type="button" class="btn btn-sm btn-outline-secondary btn-reset-pin" data-id="<?= htmlspecialchars($p['id'] ?? '', ENT_QUOTES, 'UTF-8') ?>">Reset PIN</button>
<?php endif; ?>