Loading...

Animal Villa

animalvilla.org

{{ authError }}

Animal Villa

animalvilla.org

No animals currently boarding

Check in a pet to get started

🐶

{{ dog.dogName }}

Boarding {{ visitCountMap[getDogKey(dog.dogName, dog.ownerName)] || 1 }} visit{{ (visitCountMap[getDogKey(dog.dogName, dog.ownerName)] || 1) !== 1 ? 's' : '' }}

Owner: {{ dog.ownerName }}

Breed

{{ dog.breed }}

Age

{{ dog.age }}

Checked In

{{ formatDate(dog.checkInDate) }}

Expected Out

{{ formatDate(dog.expectedCheckOut) }}

$${{ dog.ratePerNight }}/night

$${{ getEstimatedTotal(dog.checkInDate, dog.expectedCheckOut, dog.ratePerNight).toFixed(2) }}

{{ getEstimatedTotal(dog.checkInDate, dog.expectedCheckOut, dog.ratePerNight) }} nights

Notes

{{ dog.notes }}

📱 {{ dog.ownerPhone }} 🕐 {{ formatRelative(dog.checkInDate) }}

Check In a New Pet

🐶

{{ dog.dogName }}

{{ dog.ownerName }} · {{ dog.breed }}

{{ dog.visitCount }} visit{{ dog.visitCount !== 1 ? 's' : '' }}
Dog photo

Add photo

×
Estimated Total ${{ calculatedTotal.toFixed(2) }}

{{ calculatedNights }} night{{ calculatedNights !== 1 ? 's' : '' }} × ${{ form.ratePerNight || 0 }}/night

{{ uploadedDocName }}

No conversations yet

Chat threads appear when you check in a dog

{{ chatVisits.length }} conversation{{ chatVisits.length !== 1 ? 's' : '' }}

🐶

{{ cv.visit.dogName }}

{{ cv.visit.ownerName }}

{{ formatMessageTime(cv.lastMessage.createdAt) }}

{{ cv.unreadCount }}

{{ cv.lastMessage.senderId === user.uid ? 'You' : cv.visit.ownerName }}: {{ cv.lastMessage.text }}

No messages yet — start the conversation

🐶

{{ selectedChatVisit.dogName }}

{{ selectedChatVisit.ownerName }}

No messages yet. Say hello!

{{ msg.text }}

{{ formatMessageTime(msg.createdAt) }}

No history yet

Completed visits will appear here

{{ history.length }} completed visit{{ history.length !== 1 ? 's' : '' }}

🐶

{{ visit.dogName }}

Completed {{ visitCountMap[getDogKey(visit.dogName, visit.ownerName)] || 1 }} visit{{ (visitCountMap[getDogKey(visit.dogName, visit.ownerName)] || 1) !== 1 ? 's' : '' }}

{{ visit.ownerName }}

{{ formatDate(visit.checkInDate) }} → {{ formatDate(visit.checkOutDate) }}

{{ getStayDuration(visit.checkInDate, visit.checkOutDate) }}

{{ visit.notes }}
{{ calendarImportResult }}

Calendar Sync Error

{{ calendarError }}

{{ calendarMonthName }} {{ calendarYear }}

{{ day }}
{{ cell.day }}
{{ visit.dogName }}

Google Calendar Sync

Last sync: {{ formatMessageTime(lastSyncTime) }}
Connect Google Calendar to sync boarding visits.
Google Calendar connected · {{ googleCalendars.length }} calendar{{ googleCalendars.length !== 1 ? 's' : '' }} available
{{ syncConfig.autoSync ? 'On' : 'Off' }}
Export mode: When you check in a pet, a calendar event will be created automatically. Check-outs will update the event.
Auto-sync is active — syncing every {{ syncConfig.intervalMinutes }} minute{{ syncConfig.intervalMinutes !== 1 ? 's' : '' }}
ICS File Import (alternative)

Export your calendar as an ICS file and upload it here. Events with title format PetName (OwnerName) will be detected.

{{ uploadedICSName }}
or paste ICS text

{{ filteredEvents.length }} of {{ calendarEvents.length }} Event{{ calendarEvents.length !== 1 ? 's' : '' }}

Filtered by "{{ calendarFilter }}"

{{ ev.petName }}

Owner: {{ ev.ownerName }}

📅 {{ ev.checkInDate }} {{ ev.checkInTime || '' }} 📆 {{ ev.checkOutDate }} {{ ev.checkOutTime || '' }} {{ ev.originalTitle }}

Check Out {{ selectedDog?.dogName }}

Confirm check-out details

Final Total ${{ calcCheckoutTotal().toFixed(2) }}

{{ calcCheckoutNights() }} night{{ calcCheckoutNights() !== 1 ? 's' : '' }} × ${{ selectedDog.ratePerNight }}/night

Edit Visit

Update details for {{ editForm.dogName || 'this visit' }}

Dog photo

Add photo

×
{{ editFormDocName }}
🐶

{{ selectedDogProfile.dogName }}

Owner: {{ selectedDogProfile.ownerName }}

{{ dogProfileVisits.length }} visit{{ dogProfileVisits.length !== 1 ? 's' : '' }} total

Breed{{ selectedDogProfile.breed }}
Age{{ selectedDogProfile.age }}
Phone{{ selectedDogProfile.ownerPhone }}
Rate${{ selectedDogProfile.ratePerNight }}/night

Notes

{{ selectedDogProfile.notes }}

Visit History

No visits found
{{ v.status === 'checked_in' ? 'Boarding' : 'Completed' }} ${{ v.ratePerNight }}/night

{{ formatDate(v.checkInDate) }} → {{ formatDate(v.checkOutDate) }}

{{ getStayDuration(v.checkInDate, v.checkOutDate || v.expectedCheckOut) }}

Delete Visit

Are you sure you want to delete the visit for {{ visitToDelete?.dogName }} ({{ visitToDelete?.ownerName }})? This action cannot be undone.

{{ viewerData.title }}

No preview available

{{ viewerData.title }}

Download

{{ formatDate(selectedDayDateStr) }}

No visits on this day
🐶

{{ visit.dogName }}

{{ visit.status === 'checked_in' ? 'Boarding' : 'Completed' }}

Owner: {{ visit.ownerName }}

{{ formatDate(visit.checkInDate) }} → {{ formatDate(visit.expectedCheckOut) }}

{{ visit.notes }}
{{ toast.message }}