feat(water-log): surface irrigator name on log form + success screen
Deploy to route.crispygoat.com / deploy (push) Successful in 4m2s

Makes the currently-signed-in irrigator visible while data is being
entered and confirmed, so the operator can verify the reading is
attributed to them at a glance.

  - LogForm nav bar: title + initials avatar + name as a subtitle,
    sign-out button moves from the form footer into the nav bar
    (more discoverable, frees vertical space for the Submit button)
  - SuccessScreen recap: 'Logged by {name}' row with avatar below
    the timestamp, matches the log form styling
  - MobileWaterApp threads irrigatorName through to both screens

The headgate list still shows 'Signed in as {name}' as a small
caption — left untouched to avoid duplicate UI.

Validation:
  - tsc --noEmit clean
  - eslint clean on all modified files
This commit is contained in:
Tyler
2026-07-01 20:04:41 -06:00
parent ac88584b8b
commit ce62b17898
3 changed files with 79 additions and 24 deletions
+28 -1
View File
@@ -26,6 +26,9 @@ type Props = {
measurement: number;
unit: string;
timestamp: Date;
/** Name of the irrigator who logged the entry — shown in the recap
* so the operator can confirm the reading is attributed to them. */
irrigatorName?: string;
onLogAnother: () => void;
onBackToHeadgates: () => void;
};
@@ -35,6 +38,7 @@ export function MobileWaterSuccessScreen({
measurement,
unit,
timestamp,
irrigatorName,
onLogAnother,
onBackToHeadgates,
}: Props) {
@@ -197,6 +201,17 @@ export function MobileWaterSuccessScreen({
<div className="mt-2 border-t border-[rgba(60,60,67,0.10)] pt-2 text-[12px] text-[rgba(60,60,67,0.45)]">
{formatLongTimestamp(timestamp)}
</div>
{irrigatorName ? (
<div className="mt-1.5 flex items-center gap-1.5 text-[12px] text-[rgba(60,60,67,0.55)]">
<span
aria-hidden
className="inline-flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-[#14532d] text-[9px] font-bold uppercase text-white"
>
{initials(irrigatorName)}
</span>
<span>Logged by {irrigatorName}</span>
</div>
) : null}
</div>
{/* Action buttons */}
@@ -247,4 +262,16 @@ export function MobileWaterSuccessScreen({
);
}
export default MobileWaterSuccessScreen;
export default MobileWaterSuccessScreen;
/**
* Two-letter initials for the avatar chip in the recap.
* Mirrors the same helper used in the log form header so the avatar
* stays consistent across the two screens.
*/
function initials(name: string): string {
const parts = name.trim().split(/\s+/).filter(Boolean);
if (parts.length === 0) return "?";
if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();
return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
}