No audit entries
+ ) : ( +{entry.detail}
+View portal as {CUSTOMER.name}
+Password changes are not available during staff impersonation.
+{pet.name}
+{pet.breed} ยท {pet.weight} lbs
+| Document | +Date Signed | ++ |
|---|---|---|
| {agr.name} | ++ {new Date(agr.dateSigned).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" })} + | ++ + | +
No upcoming appointments
+ )} +Duration
+{appt.duration} min
+Estimated Price
+${appt.price}
+Add-ons
+{appt.addOns.join(", ")}
+{appt.notes}
+ )} + {appt.status !== "completed" && appt.status !== "cancelled" && !readOnly && ( ++ {selectedPet?.name} with {selectedGroomer?.name || "First Available"} on {formatDate(selectedDate)} at {selectedTime} +
+ +Outstanding Balance
+${totalOutstanding.toFixed(2)}
+{outstanding.length} unpaid invoice{outstanding.length > 1 ? "s" : ""}
+| Date | +Items | +Amount | +Status | ++ |
|---|---|---|---|---|
| + {new Date(inv.date).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" })} + | +{inv.items.join(", ")} | +${inv.amount.toFixed(2)} | ++ + {inv.status} + + | ++ + | +
{pm.type} โขโขโขโข {pm.last4}
+Expires {pm.expiry}
+Autopay
+Automatically charge after each appointment
+{pkg.totalCredits - pkg.usedCredits}
+remaining of {pkg.totalCredits}
+Expires {new Date(pkg.expiresAt).toLocaleDateString()}
+{BUSINESS_NAME}
+Usually replies within a few hours
+{msg.text}
+| Category | + {channels.map(ch => ( +
+
+
+ |
+ ))}
+
|---|---|
|
+ {cat.label} +{cat.desc} + |
+ {channels.map(ch => (
+ + + | + ))} +
Here's what's happening at {BUSINESS_NAME}
++ {nextAppt.petName} with {nextAppt.groomerName} +
++ {nextAppt.services.join(", ")} + {nextAppt.addOns.length > 0 && ` + ${nextAppt.addOns.join(", ")}`} +
+{LOYALTY.points} pts
++ {LOYALTY.nextRewardAt - LOYALTY.points} pts to {LOYALTY.rewardName} +
+${outstanding.toFixed(2)}
+{pet.breed} ยท {pet.weight} lbs ยท {pet.sex === "male" ? "โ" : "โ"} {pet.spayedNeutered ? "(spayed/neutered)" : ""}
+Born {new Date(pet.dob).toLocaleDateString("en-US", { month: "long", day: "numeric", year: "numeric" })}
++ Changes to medical notes will be flagged for staff review. +
+ )} +| Vaccine | +Administered | +Expires | +Status | +Proof | +
|---|---|---|---|---|
| {vax.name} | +{new Date(vax.lastAdministered).toLocaleDateString()} | +{new Date(vax.expirationDate).toLocaleDateString()} | +
+
+ |
+ + {vax.documentUploaded ? ( + Uploaded + ) : !readOnly ? ( + + ) : ( + Missing + )} + | +
No history yet
+ ) : ( + petHistory.map(appt => ( +{appt.services.join(", ")}
+with {appt.groomerName} ยท ${appt.price}
+Grooming report cards from your recent visits
+ ++ {new Date(card.date).toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric", year: "numeric" })} ยท Groomer: {card.groomerName} +
+Before
+{card.beforeDescription}
+After
+{card.afterDescription}
+"{card.groomerNote}"
+Next recommended visit
++ {new Date(card.nextRecommendedDate).toLocaleDateString("en-US", { month: "long", day: "numeric", year: "numeric" })} +
+