Updated adoption report

This commit is contained in:
Corey Blais
2026-06-02 12:13:01 -04:00
parent 545fae59b2
commit 5f0fad3cbb
5 changed files with 50 additions and 15 deletions
+35 -15
View File
@@ -1,6 +1,7 @@
import { useEffect, useMemo, useState } from 'react';
import birdSilhouette from './assets/bird-silhouette.jpg';
import flockPalLandingArt from './assets/flockpal-landing-art.png';
import flockPalTextArt from './assets/flockpal-text.png';
import defaultBirdPhoto from './assets/yoda-default.png';
import { findParrotWeightReference, parrotSpeciesOptions, type ParrotWeightReference } from './parrotWeightReference';
import QRCode from 'qrcode';
@@ -4075,6 +4076,7 @@ function App() {
const toReportAssetUrl = (value: string) =>
value.startsWith('data:') || value.startsWith('http://') || value.startsWith('https://') ? value : new URL(value, window.location.origin).toString();
const reportLogoUrl = toReportAssetUrl(flockPalLandingArt);
const reportWordmarkUrl = toReportAssetUrl(flockPalTextArt);
const reportPhotoUrl = toReportAssetUrl(selectedBird.photoDataUrl || defaultBirdPhoto);
const profileRows = [
['Name', selectedBird.name],
@@ -4082,7 +4084,6 @@ function App() {
['Band/tag ID', selectedBird.tagId || 'Not recorded'],
['Sex', getBirdGenderLabel(selectedBird)],
['Hatch day', formatDate(selectedBird.dateOfBirth)],
['Gotcha day', formatDate(selectedBird.gotchaDay)],
['Favorite snack', selectedBird.favoriteSnack || 'Not recorded'],
['Latest weight', selectedBird.latestWeightGrams ? `${formatWeight(selectedBird.latestWeightGrams)}${selectedBird.latestRecordedOn ? ` on ${formatShortDate(selectedBird.latestRecordedOn)}` : ''}` : 'Pending'],
];
@@ -4199,7 +4200,7 @@ function App() {
box-shadow: 0 16px 34px rgba(86, 63, 34, 0.14);
display: grid;
gap: 22px;
grid-template-columns: 210px 1fr 172px;
grid-template-columns: 210px 1fr 320px;
min-height: 228px;
padding: 18px;
}
@@ -4238,9 +4239,36 @@ function App() {
object-fit: cover;
width: 132px;
}
.qr { align-self: center; justify-self: end; text-align: center; width: 170px; }
.qr { align-self: center; justify-self: end; text-align: center; width: 320px; }
.qr svg { background: #fff; border: 1px solid var(--border); border-radius: 12px; padding: 8px; width: 136px; }
.code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 14px; overflow-wrap: anywhere; }
.qr-join-label {
color: var(--green);
font-size: 12px;
font-weight: 800;
letter-spacing: 0.08em;
line-height: 1;
margin-bottom: -28px;
position: relative;
text-transform: uppercase;
z-index: 1;
}
.qr-wordmark {
display: block;
height: 150px;
margin: -28px auto -12px;
object-fit: contain;
width: 340px;
}
.qr-note {
color: var(--blue);
font-family: "Avenir Next", "Arial Rounded MT Bold", Arial, sans-serif;
font-size: 12px;
font-weight: 800;
letter-spacing: 0;
line-height: 1.28;
margin-top: 8px;
}
.grid { stroke: rgba(53, 129, 98, 0.16); }
.current { fill: none; stroke: ${escapeReportHtml(selectedBird.chartColor)}; stroke-linecap: round; stroke-width: 4; }
.historical { fill: none; opacity: .45; stroke: ${escapeReportHtml(selectedBird.chartColor)}; stroke-linecap: round; stroke-width: 3; }
@@ -4271,11 +4299,14 @@ function App() {
<p class="muted">Generated ${escapeReportHtml(formatDateTime(new Date().toISOString()))}</p>
</div>
<div class="qr">
<p class="qr-join-label">Join</p>
<img class="qr-wordmark" src="${escapeReportHtml(reportWordmarkUrl)}" alt="FlockPal">
<svg viewBox="0 0 ${qr.viewBoxSize} ${qr.viewBoxSize}" role="img" aria-label="Transfer code QR">
<rect width="${qr.viewBoxSize}" height="${qr.viewBoxSize}" fill="#fff"></rect>
<path d="${escapeReportHtml(qr.path)}" fill="#111418"></path>
</svg>
<p class="code">${escapeReportHtml(transferCode)}</p>
<p class="qr-note">Enter this code to keep ${escapeReportHtml(selectedBird.name)}'s care history flying forward.</p>
</div>
</header>
<main>
@@ -5986,9 +6017,7 @@ function App() {
aria-label="Reports"
title="Reports"
>
<svg className="report-tab-icon" viewBox="0 -960 960 960" aria-hidden="true" focusable="false">
<path d="M240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM320-240h320v-80H320v80Zm0-160h320v-80H320v80Zm-80-400v200-200 640-640Z" />
</svg>
<span className="material-symbols-outlined report-tab-icon" aria-hidden="true">analytics</span>
</button>
<button
className={`bird-detail-tab ${selectedBirdTab === 'audit' ? 'active' : ''}`}
@@ -6616,17 +6645,8 @@ function App() {
<span>Transfer code</span>
<strong>{selectedBirdAdoptionTransferCode || 'Not generated'}</strong>
</article>
<article className="detail-card">
<span>Included records</span>
<strong>
{weights.length} weights {vetVisits.length} vet visits {selectedBirdNotes.length} notes
</strong>
</article>
</div>
<div className="button-row">
<button className="secondary-button" onClick={handleCreateAdoptionTransferCode} type="button" disabled={creatingAdoptionReportCode}>
{creatingAdoptionReportCode ? 'Creating code...' : selectedBirdAdoptionTransferCode ? 'Code ready' : 'Create transfer code'}
</button>
<button className="primary-button" onClick={() => handleOpenAdoptionReport(false)} type="button" disabled={creatingAdoptionReportCode}>
{creatingAdoptionReportCode ? 'Preparing report...' : 'Open adoption report'}
</button>