feat: extend offline queueing to all quick-capture forms
Only Durchsicht had an offline fallback (queue to IndexedDB, sync on reconnect); Behandlung, Fütterung, Varroamessung, Schwarmkontrolle and Ernte just failed outright with no signal - exactly the situation a beekeeper is in at the actual hive. Generalizes lib/offline/db.ts and sync.ts to six queues (version-bumped IndexedDB schema, existing queued inspections preserved), wires the same "server rejected it vs. no network" fallback into all five remaining */new pages, and updates the sync badge to count/drain all six. Also: doc-hygiene pass (ARCHITECTURE.md/TASKS.md) to replace the stale pg_dump/CronJob backup plan with the in-app BackupModule that actually shipped earlier this session. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
1 parent
ac45514356
commit
1f67cd5548
11 files changed
+297
-46
No files matched your search
@@ -9,6 +9,8 @@ import { fetchColonies } from "@/lib/colonies/api";
|
||||
import { createFeeding } from "@/lib/feedings/api";
|
||||
import { FeedType } from "@/lib/feedings/types";
|
||||
import { FEED_TYPES, FEED_TYPE_LABELS } from "@/lib/feedings/labels";
|
||||
import { ApiError } from "@/lib/auth/api-client";
|
||||
import { queueFeeding } from "@/lib/offline/db";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
@@ -59,8 +61,15 @@ export default function NewFeedingPage() {
|
||||
toast.success("Fütterung gespeichert");
|
||||
router.push(`/colonies/${feeding.colonyId}`);
|
||||
},
|
||||
onError: () => {
|
||||
setError("Fütterung konnte nicht gespeichert werden.");
|
||||
onError: (mutationError, variables) => {
|
||||
if (mutationError instanceof ApiError) {
|
||||
setError("Fütterung konnte nicht gespeichert werden.");
|
||||
return;
|
||||
}
|
||||
void queueFeeding(variables).then(() => {
|
||||
toast.info("Kein Netzwerk – Fütterung wurde offline gespeichert und wird synchronisiert.");
|
||||
router.push(`/colonies/${variables.colonyId}`);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ import { Boxes } from "lucide-react";
|
||||
import { fetchApiaries } from "@/lib/apiaries/api";
|
||||
import { fetchColonies } from "@/lib/colonies/api";
|
||||
import { createHarvest } from "@/lib/harvests/api";
|
||||
import { ApiError } from "@/lib/auth/api-client";
|
||||
import { queueHarvest } from "@/lib/offline/db";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
@@ -53,8 +55,15 @@ export default function NewHarvestPage() {
|
||||
toast.success("Ernte gespeichert");
|
||||
router.push(`/harvests/${harvest.id}`);
|
||||
},
|
||||
onError: () => {
|
||||
setError("Ernte konnte nicht gespeichert werden.");
|
||||
onError: (mutationError, variables) => {
|
||||
if (mutationError instanceof ApiError) {
|
||||
setError("Ernte konnte nicht gespeichert werden.");
|
||||
return;
|
||||
}
|
||||
void queueHarvest(variables).then(() => {
|
||||
toast.info("Kein Netzwerk – Ernte wurde offline gespeichert und wird synchronisiert.");
|
||||
router.push("/harvests");
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ import { fetchColonies } from "@/lib/colonies/api";
|
||||
import { createSwarmControlCheck } from "@/lib/swarm-control/api";
|
||||
import { SWARM_ACTION_LABELS, SWARM_MOOD_LABELS } from "@/lib/swarm-control/labels";
|
||||
import { SwarmControlAction, SwarmMood } from "@/lib/swarm-control/types";
|
||||
import { ApiError } from "@/lib/auth/api-client";
|
||||
import { queueSwarmControlCheck } from "@/lib/offline/db";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
@@ -57,8 +59,15 @@ export default function NewSwarmControlCheckPage() {
|
||||
toast.success("Schwarmkontrolle gespeichert");
|
||||
router.push(`/colonies/${check.colonyId}`);
|
||||
},
|
||||
onError: () => {
|
||||
setError("Schwarmkontrolle konnte nicht gespeichert werden.");
|
||||
onError: (mutationError, variables) => {
|
||||
if (mutationError instanceof ApiError) {
|
||||
setError("Schwarmkontrolle konnte nicht gespeichert werden.");
|
||||
return;
|
||||
}
|
||||
void queueSwarmControlCheck(variables).then(() => {
|
||||
toast.info("Kein Netzwerk – Schwarmkontrolle wurde offline gespeichert und wird synchronisiert.");
|
||||
router.push(`/colonies/${variables.colonyId}`);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ import { toast } from "sonner";
|
||||
import { Syringe } from "lucide-react";
|
||||
import { fetchColonies } from "@/lib/colonies/api";
|
||||
import { createTreatment } from "@/lib/treatments/api";
|
||||
import { ApiError } from "@/lib/auth/api-client";
|
||||
import { queueTreatment } from "@/lib/offline/db";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
@@ -54,8 +56,15 @@ export default function NewTreatmentPage() {
|
||||
toast.success("Behandlung gespeichert");
|
||||
router.push(`/colonies/${treatment.colonyId}`);
|
||||
},
|
||||
onError: () => {
|
||||
setError("Behandlung konnte nicht gespeichert werden.");
|
||||
onError: (mutationError, variables) => {
|
||||
if (mutationError instanceof ApiError) {
|
||||
setError("Behandlung konnte nicht gespeichert werden.");
|
||||
return;
|
||||
}
|
||||
void queueTreatment(variables).then(() => {
|
||||
toast.info("Kein Netzwerk – Behandlung wurde offline gespeichert und wird synchronisiert.");
|
||||
router.push(`/colonies/${variables.colonyId}`);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ import { fetchColonies } from "@/lib/colonies/api";
|
||||
import { createVarroaMeasurement } from "@/lib/varroa/api";
|
||||
import { VarroaMethod } from "@/lib/varroa/types";
|
||||
import { VARROA_METHODS, VARROA_METHOD_LABELS } from "@/lib/varroa/labels";
|
||||
import { ApiError } from "@/lib/auth/api-client";
|
||||
import { queueVarroaMeasurement } from "@/lib/offline/db";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
@@ -56,8 +58,15 @@ export default function NewVarroaMeasurementPage() {
|
||||
toast.success("Varroamessung gespeichert");
|
||||
router.push(`/colonies/${measurement.colonyId}`);
|
||||
},
|
||||
onError: () => {
|
||||
setError("Varroamessung konnte nicht gespeichert werden.");
|
||||
onError: (mutationError, variables) => {
|
||||
if (mutationError instanceof ApiError) {
|
||||
setError("Varroamessung konnte nicht gespeichert werden.");
|
||||
return;
|
||||
}
|
||||
void queueVarroaMeasurement(variables).then(() => {
|
||||
toast.info("Kein Netzwerk – Varroamessung wurde offline gespeichert und wird synchronisiert.");
|
||||
router.push(`/colonies/${variables.colonyId}`);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user