Updated adoption report
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 242 KiB |
@@ -3,6 +3,12 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:FILL@0..1&icon_names=analytics&display=block"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
<link
|
<link
|
||||||
rel="icon"
|
rel="icon"
|
||||||
type="image/svg+xml"
|
type="image/svg+xml"
|
||||||
|
|||||||
+35
-15
@@ -1,6 +1,7 @@
|
|||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import birdSilhouette from './assets/bird-silhouette.jpg';
|
import birdSilhouette from './assets/bird-silhouette.jpg';
|
||||||
import flockPalLandingArt from './assets/flockpal-landing-art.png';
|
import flockPalLandingArt from './assets/flockpal-landing-art.png';
|
||||||
|
import flockPalTextArt from './assets/flockpal-text.png';
|
||||||
import defaultBirdPhoto from './assets/yoda-default.png';
|
import defaultBirdPhoto from './assets/yoda-default.png';
|
||||||
import { findParrotWeightReference, parrotSpeciesOptions, type ParrotWeightReference } from './parrotWeightReference';
|
import { findParrotWeightReference, parrotSpeciesOptions, type ParrotWeightReference } from './parrotWeightReference';
|
||||||
import QRCode from 'qrcode';
|
import QRCode from 'qrcode';
|
||||||
@@ -4389,6 +4390,7 @@ function App() {
|
|||||||
const toReportAssetUrl = (value: string) =>
|
const toReportAssetUrl = (value: string) =>
|
||||||
value.startsWith('data:') || value.startsWith('http://') || value.startsWith('https://') ? value : new URL(value, window.location.origin).toString();
|
value.startsWith('data:') || value.startsWith('http://') || value.startsWith('https://') ? value : new URL(value, window.location.origin).toString();
|
||||||
const reportLogoUrl = toReportAssetUrl(flockPalLandingArt);
|
const reportLogoUrl = toReportAssetUrl(flockPalLandingArt);
|
||||||
|
const reportWordmarkUrl = toReportAssetUrl(flockPalTextArt);
|
||||||
const reportPhotoUrl = toReportAssetUrl(selectedBird.photoDataUrl || defaultBirdPhoto);
|
const reportPhotoUrl = toReportAssetUrl(selectedBird.photoDataUrl || defaultBirdPhoto);
|
||||||
const profileRows = [
|
const profileRows = [
|
||||||
['Name', selectedBird.name],
|
['Name', selectedBird.name],
|
||||||
@@ -4396,7 +4398,6 @@ function App() {
|
|||||||
['Band/tag ID', selectedBird.tagId || 'Not recorded'],
|
['Band/tag ID', selectedBird.tagId || 'Not recorded'],
|
||||||
['Sex', getBirdGenderLabel(selectedBird)],
|
['Sex', getBirdGenderLabel(selectedBird)],
|
||||||
['Hatch day', formatDate(selectedBird.dateOfBirth)],
|
['Hatch day', formatDate(selectedBird.dateOfBirth)],
|
||||||
['Gotcha day', formatDate(selectedBird.gotchaDay)],
|
|
||||||
['Favorite snack', selectedBird.favoriteSnack || 'Not recorded'],
|
['Favorite snack', selectedBird.favoriteSnack || 'Not recorded'],
|
||||||
['Latest weight', selectedBird.latestWeightGrams ? `${formatWeight(selectedBird.latestWeightGrams)}${selectedBird.latestRecordedOn ? ` on ${formatShortDate(selectedBird.latestRecordedOn)}` : ''}` : 'Pending'],
|
['Latest weight', selectedBird.latestWeightGrams ? `${formatWeight(selectedBird.latestWeightGrams)}${selectedBird.latestRecordedOn ? ` on ${formatShortDate(selectedBird.latestRecordedOn)}` : ''}` : 'Pending'],
|
||||||
];
|
];
|
||||||
@@ -4513,7 +4514,7 @@ function App() {
|
|||||||
box-shadow: 0 16px 34px rgba(86, 63, 34, 0.14);
|
box-shadow: 0 16px 34px rgba(86, 63, 34, 0.14);
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 22px;
|
gap: 22px;
|
||||||
grid-template-columns: 210px 1fr 172px;
|
grid-template-columns: 210px 1fr 320px;
|
||||||
min-height: 228px;
|
min-height: 228px;
|
||||||
padding: 18px;
|
padding: 18px;
|
||||||
}
|
}
|
||||||
@@ -4552,9 +4553,36 @@ function App() {
|
|||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
width: 132px;
|
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; }
|
.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; }
|
.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); }
|
.grid { stroke: rgba(53, 129, 98, 0.16); }
|
||||||
.current { fill: none; stroke: ${escapeReportHtml(selectedBird.chartColor)}; stroke-linecap: round; stroke-width: 4; }
|
.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; }
|
.historical { fill: none; opacity: .45; stroke: ${escapeReportHtml(selectedBird.chartColor)}; stroke-linecap: round; stroke-width: 3; }
|
||||||
@@ -4585,11 +4613,14 @@ function App() {
|
|||||||
<p class="muted">Generated ${escapeReportHtml(formatDateTime(new Date().toISOString()))}</p>
|
<p class="muted">Generated ${escapeReportHtml(formatDateTime(new Date().toISOString()))}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="qr">
|
<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">
|
<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>
|
<rect width="${qr.viewBoxSize}" height="${qr.viewBoxSize}" fill="#fff"></rect>
|
||||||
<path d="${escapeReportHtml(qr.path)}" fill="#111418"></path>
|
<path d="${escapeReportHtml(qr.path)}" fill="#111418"></path>
|
||||||
</svg>
|
</svg>
|
||||||
<p class="code">${escapeReportHtml(transferCode)}</p>
|
<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>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
@@ -6530,9 +6561,7 @@ function App() {
|
|||||||
aria-label="Reports"
|
aria-label="Reports"
|
||||||
title="Reports"
|
title="Reports"
|
||||||
>
|
>
|
||||||
<svg className="report-tab-icon" viewBox="0 -960 960 960" aria-hidden="true" focusable="false">
|
<span className="material-symbols-outlined report-tab-icon" aria-hidden="true">analytics</span>
|
||||||
<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>
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className={`bird-detail-tab ${selectedBirdTab === 'audit' ? 'active' : ''}`}
|
className={`bird-detail-tab ${selectedBirdTab === 'audit' ? 'active' : ''}`}
|
||||||
@@ -7160,17 +7189,8 @@ function App() {
|
|||||||
<span>Transfer code</span>
|
<span>Transfer code</span>
|
||||||
<strong>{selectedBirdAdoptionTransferCode || 'Not generated'}</strong>
|
<strong>{selectedBirdAdoptionTransferCode || 'Not generated'}</strong>
|
||||||
</article>
|
</article>
|
||||||
<article className="detail-card">
|
|
||||||
<span>Included records</span>
|
|
||||||
<strong>
|
|
||||||
{weights.length} weights • {vetVisits.length} vet visits • {selectedBirdNotes.length} notes
|
|
||||||
</strong>
|
|
||||||
</article>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="button-row">
|
<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}>
|
<button className="primary-button" onClick={() => handleOpenAdoptionReport(false)} type="button" disabled={creatingAdoptionReportCode}>
|
||||||
{creatingAdoptionReportCode ? 'Preparing report...' : 'Open adoption report'}
|
{creatingAdoptionReportCode ? 'Preparing report...' : 'Open adoption report'}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 242 KiB |
@@ -1328,6 +1328,7 @@ textarea {
|
|||||||
|
|
||||||
.bird-detail-tab .info-tab-icon,
|
.bird-detail-tab .info-tab-icon,
|
||||||
.bird-detail-tab .note-tab-icon,
|
.bird-detail-tab .note-tab-icon,
|
||||||
|
.bird-detail-tab .report-tab-icon,
|
||||||
.bird-detail-tab .audit-tab-icon,
|
.bird-detail-tab .audit-tab-icon,
|
||||||
.bird-detail-tab .vet-tab-icon {
|
.bird-detail-tab .vet-tab-icon {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
@@ -1336,6 +1337,14 @@ textarea {
|
|||||||
stroke: none;
|
stroke: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bird-detail-tab .material-symbols-outlined {
|
||||||
|
display: block;
|
||||||
|
font-family: "Material Symbols Outlined";
|
||||||
|
font-size: 24px;
|
||||||
|
font-variation-settings: "FILL" 0, "wght" 400, "GRAD" 0, "opsz" 24;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.bird-detail-tab:hover {
|
.bird-detail-tab:hover {
|
||||||
border-color: rgba(35, 138, 90, 0.28);
|
border-color: rgba(35, 138, 90, 0.28);
|
||||||
color: var(--ink);
|
color: var(--ink);
|
||||||
|
|||||||
Reference in New Issue
Block a user