Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/app/admin/animal-adoptions/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useToast } from "@/hooks/use-toast";
import { useMutation } from "@/hooks/use-mutation";
import { useUnsavedChangesGuard } from "@/hooks/use-unsaved-changes";
import { LoadError } from "@/components/admin/load-error";
import { AdminLoading } from "@/components/admin/admin-loading";
import { logError } from "@/lib/logger";
import {
AnimalAdoptionsContent,
Expand Down Expand Up @@ -117,7 +118,7 @@ export default function AnimalAdoptionsAdminPage() {
};

if (loading) {
return <div>Loading...</div>;
return <AdminLoading label="adoptions content" />;
}

if (loadError) {
Expand All @@ -128,8 +129,8 @@ export default function AnimalAdoptionsAdminPage() {
<div className="max-w-4xl mx-auto space-y-6">
<div className="flex items-center justify-between">
<h1 className="text-3xl font-bold">Edit Animal Adoptions Page</h1>
<Button onClick={handleSave} disabled={saveMutation.pending}>
{saveMutation.pending ? "Saving..." : "Save Changes"}
<Button onClick={handleSave} loading={saveMutation.pending}>
Save Changes
</Button>
</div>

Expand Down Expand Up @@ -313,8 +314,8 @@ export default function AnimalAdoptionsAdminPage() {
</Card>

<div className="flex justify-end">
<Button onClick={handleSave} disabled={saveMutation.pending} size="lg">
{saveMutation.pending ? "Saving..." : "Save All Changes"}
<Button onClick={handleSave} loading={saveMutation.pending} size="lg">
Save All Changes
</Button>
</div>
</div>
Expand Down
11 changes: 6 additions & 5 deletions src/app/admin/animal-registration/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useToast } from "@/hooks/use-toast";
import { useMutation } from "@/hooks/use-mutation";
import { useUnsavedChangesGuard } from "@/hooks/use-unsaved-changes";
import { LoadError } from "@/components/admin/load-error";
import { AdminLoading } from "@/components/admin/admin-loading";
import { logError } from "@/lib/logger";
import {
AnimalRegistrationContent,
Expand Down Expand Up @@ -99,7 +100,7 @@ export default function AnimalRegistrationAdminPage() {
};

if (loading) {
return <div>Loading...</div>;
return <AdminLoading label="registration content" />;
}

if (loadError) {
Expand All @@ -117,8 +118,8 @@ export default function AnimalRegistrationAdminPage() {
here.
</p>
</div>
<Button onClick={handleSave} disabled={saveMutation.pending}>
{saveMutation.pending ? "Saving..." : "Save Changes"}
<Button onClick={handleSave} loading={saveMutation.pending}>
Save Changes
</Button>
</div>

Expand Down Expand Up @@ -229,8 +230,8 @@ export default function AnimalRegistrationAdminPage() {
</Card>

<div className="flex justify-end">
<Button onClick={handleSave} disabled={saveMutation.pending} size="lg">
{saveMutation.pending ? "Saving..." : "Save All Changes"}
<Button onClick={handleSave} loading={saveMutation.pending} size="lg">
Save All Changes
</Button>
</div>
</div>
Expand Down
6 changes: 4 additions & 2 deletions src/app/admin/animals/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ import {
import { ArrowLeft, Plus } from "lucide-react";
import { logError } from "@/lib/logger";
import { LoadError } from "@/components/admin/load-error";
import { AdminLoading } from "@/components/admin/admin-loading";

type DialogType =
| "encounter"
Expand Down Expand Up @@ -163,7 +164,7 @@ export default function AnimalMedicalPage() {
};

if (loading) {
return <div>Loading...</div>;
return <AdminLoading label="animal record" />;
}

if (loadError) {
Expand Down Expand Up @@ -825,10 +826,11 @@ export default function AnimalMedicalPage() {
</div>
<Button
className="w-full"
loading={savingLifecycle}
disabled={!lifecycleDialog.toStatus || savingLifecycle}
onClick={submitLifecycleTransition}
>
{savingLifecycle ? "Saving…" : "Apply transition"}
Apply transition
</Button>
</div>
)}
Expand Down
11 changes: 4 additions & 7 deletions src/app/admin/animals/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import { Plus, Pencil, Trash, Search } from "lucide-react";
import { logError } from "@/lib/logger";
import { ConfirmDialog } from "@/components/admin/confirm-dialog";
import { LoadError } from "@/components/admin/load-error";
import { AdminLoading } from "@/components/admin/admin-loading";

const STERILIZATION_LABELS: Record<string, string> = {
unknown: "Unknown",
Expand Down Expand Up @@ -469,12 +470,8 @@ export default function AnimalsManager() {
Enter a direct URL to the animal photo
</p>
</div>
<Button onClick={handleSubmit} className="w-full" disabled={mutation.pending}>
{mutation.pending
? "Saving…"
: editingAnimal
? "Update Animal"
: "Add Animal"}
<Button onClick={handleSubmit} className="w-full" loading={mutation.pending}>
{editingAnimal ? "Update Animal" : "Add Animal"}
</Button>
</div>
</DialogContent>
Expand Down Expand Up @@ -533,7 +530,7 @@ export default function AnimalsManager() {
</CardHeader>
<CardContent>
{loading ? (
<div>Loading...</div>
<AdminLoading label="animals" rows={4} />
) : loadError ? (
<LoadError label="animals" onRetry={loadAnimals} />
) : (
Expand Down
7 changes: 7 additions & 0 deletions src/app/admin/chip-lookup/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ function FoundScanForm({
const [outcome, setOutcome] = useState("");
const [notes, setNotes] = useState("");
const [busy, setBusy] = useState(false);
// Which open case is being resolved — busy locks every control, but
// the spinner belongs on the row the operator actually clicked.
const [busyCaseId, setBusyCaseId] = useState<string | null>(null);
const [resolving, setResolving] = useState<Record<string, string>>({});

const saveNew = async () => {
Expand Down Expand Up @@ -191,6 +194,7 @@ function FoundScanForm({
const chosen = resolving[openCase.id];
if (!chosen) return;
setBusy(true);
setBusyCaseId(openCase.id);
try {
const result = await resolveOpenCaseAction(
openCase.id,
Expand All @@ -216,6 +220,7 @@ function FoundScanForm({
});
} finally {
setBusy(false);
setBusyCaseId(null);
}
};

Expand Down Expand Up @@ -282,6 +287,7 @@ function FoundScanForm({
<Button
size="sm"
variant="outline"
loading={busyCaseId === r.id}
disabled={busy || !resolving[r.id]}
onClick={() => resolve(r)}
>
Expand Down Expand Up @@ -323,6 +329,7 @@ function FoundScanForm({
<Button
size="sm"
variant="outline"
loading={busy && busyCaseId === null}
disabled={busy}
onClick={saveNew}
>
Expand Down
14 changes: 9 additions & 5 deletions src/app/admin/communications/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
TableRow,
} from "@/components/ui/table";
import { LoadError } from "@/components/admin/load-error";
import { AdminLoading } from "@/components/admin/admin-loading";
import { useToast } from "@/hooks/use-toast";
import { useMutation } from "@/hooks/use-mutation";
import { logError } from "@/lib/logger";
Expand Down Expand Up @@ -148,7 +149,7 @@ function ExceptionActions({
variant: "destructive",
});
}
});
}, "requeue");

const setOptOut = (optedOut: boolean) =>
mutation.run(async () => {
Expand All @@ -173,7 +174,7 @@ function ExceptionActions({
variant: "destructive",
});
}
});
}, "optout");

return (
<div className="flex items-center justify-end gap-1">
Expand All @@ -182,6 +183,7 @@ function ExceptionActions({
variant="outline"
size="sm"
onClick={requeue}
loading={mutation.pendingKey === "requeue"}
disabled={mutation.pending}
aria-label={`Requeue ${label}`}
>
Expand All @@ -193,6 +195,7 @@ function ExceptionActions({
variant="ghost"
size="sm"
onClick={() => setOptOut(!comm.optedOut)}
loading={mutation.pendingKey === "optout"}
disabled={mutation.pending}
aria-label={
comm.optedOut
Expand Down Expand Up @@ -247,7 +250,7 @@ export default function CommunicationsPage() {
});

if (loading) {
return <div>Loading...</div>;
return <AdminLoading label="communications" />;
}
if (loadError || !overview) {
return <LoadError label="communications" onRetry={load} />;
Expand Down Expand Up @@ -280,10 +283,11 @@ export default function CommunicationsPage() {
<Button
variant="outline"
onClick={runPreview}
disabled={dryRun.pending}
loading={dryRun.pending}
loadingText="Evaluating…"
>
<FlaskConical className="h-4 w-4 mr-2" />
{dryRun.pending ? "Evaluating…" : "Preview next reminder run"}
Preview next reminder run
</Button>
{preview && (
<div className="mt-4 text-sm space-y-1" aria-live="polite">
Expand Down
5 changes: 3 additions & 2 deletions src/app/admin/data-quality/merge-household/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
} from "@/components/ui/select";
import { useToast } from "@/hooks/use-toast";
import { logError } from "@/lib/logger";
import { AdminLoading } from "@/components/admin/admin-loading";
import { CircleAlert, GitMerge, TriangleAlert } from "lucide-react";

function HouseholdCard({
Expand Down Expand Up @@ -195,7 +196,7 @@ function HouseholdMergeReview() {
</Card>
);
}
if (!pair) return <p>Loading…</p>;
if (!pair) return <AdminLoading label="candidate pair" rows={2} />;

return (
<div className="space-y-6">
Expand Down Expand Up @@ -383,7 +384,7 @@ export default function HouseholdMergePage() {
</Link>
</p>
</div>
<Suspense fallback={<p>Loading…</p>}>
<Suspense fallback={<AdminLoading label="candidate pair" rows={2} />}>
<HouseholdMergeReview />
</Suspense>
</div>
Expand Down
5 changes: 3 additions & 2 deletions src/app/admin/data-quality/merge-person/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
} from "@/components/ui/select";
import { useToast } from "@/hooks/use-toast";
import { logError } from "@/lib/logger";
import { AdminLoading } from "@/components/admin/admin-loading";
import { CircleAlert, GitMerge, KeyRound, TriangleAlert } from "lucide-react";

function PersonCard({
Expand Down Expand Up @@ -216,7 +217,7 @@ function PersonMergeReview() {
</Card>
);
}
if (!pair) return <p>Loading…</p>;
if (!pair) return <AdminLoading label="candidate pair" rows={2} />;

return (
<div className="space-y-6">
Expand Down Expand Up @@ -405,7 +406,7 @@ export default function PersonMergePage() {
</Link>
</p>
</div>
<Suspense fallback={<p>Loading…</p>}>
<Suspense fallback={<AdminLoading label="candidate pair" rows={2} />}>
<PersonMergeReview />
</Suspense>
</div>
Expand Down
5 changes: 3 additions & 2 deletions src/app/admin/data-quality/merge/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
} from "@/components/ui/select";
import { useToast } from "@/hooks/use-toast";
import { logError } from "@/lib/logger";
import { AdminLoading } from "@/components/admin/admin-loading";
import { CircleAlert, GitMerge, TriangleAlert } from "lucide-react";

function AnimalCard({
Expand Down Expand Up @@ -211,7 +212,7 @@ function MergeReview() {
</Card>
);
}
if (!pair) return <p>Loading…</p>;
if (!pair) return <AdminLoading label="candidate pair" rows={2} />;

return (
<div className="space-y-6">
Expand Down Expand Up @@ -417,7 +418,7 @@ export default function MergePage() {
</Link>
</p>
</div>
<Suspense fallback={<p>Loading…</p>}>
<Suspense fallback={<AdminLoading label="candidate pair" rows={2} />}>
<MergeReview />
</Suspense>
</div>
Expand Down
5 changes: 4 additions & 1 deletion src/app/admin/data-quality/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
} from "@/components/ui/select";
import { useToast } from "@/hooks/use-toast";
import { logError } from "@/lib/logger";
import { AdminLoading } from "@/components/admin/admin-loading";
import {
CheckCheck,
CircleAlert,
Expand Down Expand Up @@ -245,7 +246,9 @@ export default function DataQualityPage() {
</CardContent>
</Card>

{findings === null && !loadError && <p>Loading…</p>}
{findings === null && !loadError && (
<AdminLoading label="data-quality findings" rows={2} />
)}
{loadError && (
<Card>
<CardContent className="pt-6">
Expand Down
11 changes: 8 additions & 3 deletions src/app/admin/faq/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { Plus, Pencil, Trash, GripVertical } from "lucide-react";
import { logError } from "@/lib/logger";
import { ConfirmDialog } from "@/components/admin/confirm-dialog";
import { LoadError } from "@/components/admin/load-error";
import { AdminLoading } from "@/components/admin/admin-loading";

interface FAQ {
id: string;
Expand Down Expand Up @@ -210,7 +211,11 @@ export default function FAQManager() {
}, {} as Record<string, FAQ[]>);

if (loading) {
return <div className="p-8">Loading...</div>;
return (
<div className="p-8">
<AdminLoading label="FAQs" />
</div>
);
}

if (loadError) {
Expand Down Expand Up @@ -317,8 +322,8 @@ export default function FAQManager() {
</p>
)}
</div>
<Button onClick={handleSubmit} className="w-full" disabled={mutation.pending}>
{mutation.pending ? "Saving…" : editingFaq ? "Update FAQ" : "Add FAQ"}
<Button onClick={handleSubmit} className="w-full" loading={mutation.pending}>
{editingFaq ? "Update FAQ" : "Add FAQ"}
</Button>
</div>
</DialogContent>
Expand Down
Loading
Loading