+
+ {/* DYNA chart */}
+
+
+ N-dynamiek
+
+ N-beschikbaarheid (bandbreedte en verwachting) versus
+ N-opname door het gewas
+
+
+
+
+
+
+
+ {/* Balance and advice side by side */}
+
)
}
@@ -127,33 +211,36 @@ interface DynaChartProps {
data: DynaDailyPoint[]
fertilizingRecommendations: DynaFertilizerAdvice | null
events?: DynaChartEvent[]
+ year?: number
}
export function DynaChart({
data,
fertilizingRecommendations,
events = [],
+ year = new Date().getFullYear(),
}: DynaChartProps) {
const monthTicks = getMonthTicks(data)
const today = new Date().toISOString().split("T")[0] ?? ""
+ const isCurrentYear = year === new Date().getFullYear()
const recDate = fertilizingRecommendations?.b_date_recommended
- // Count how many events share the same date, for stacking labels
- const dateCounts = new Map()
- const eventsWithStack = events.map((ev) => {
- const count = dateCounts.get(ev.date) ?? 0
- dateCounts.set(ev.date, count + 1)
- return { ...ev, stackIndex: count }
- })
+ // Group events by date and only include dates present in the data
+ const eventsByDate = groupEventsByDate(events)
+ const chartDates = new Set(data.map((d) => d.b_date_calculation))
+ const uniqueEventDates = Array.from(eventsByDate.entries()).filter(
+ ([date]) => chartDates.has(date),
+ )
- const chartData = data.map((d) => ({
+ const chartData: DynaChartPoint[] = data.map((d) => ({
date: d.b_date_calculation,
b_nw: d.b_nw,
b_nw_min: d.b_nw_min,
b_nw_max: d.b_nw_max,
b_nw_recommended: d.b_nw_recommended,
b_n_uptake: d.b_n_uptake,
+ _events: eventsByDate.get(d.b_date_calculation),
}))
return (
@@ -181,6 +268,24 @@ export function DynaChart({
stopOpacity={0.05}
/>
+
+
+
+
- {
- const raw = payload?.[0]?.payload?.date ?? label
- return formatDateLabel(raw)
- }}
- />
- }
- />
+ } />
} />
- {/* Min-max band */}
+ {/* Min-max band (render first so it's behind everything) */}
- {/* N availability line */}
-
- {/* N uptake line */}
+ {/* N uptake — dashed line for distinction */}
- {/* Today reference line */}
-
+ {/* Today reference line — only for current year */}
+ {isCurrentYear && (
+
+ )}
{/* Fertilizer recommendation date */}
{recDate && (
@@ -287,20 +387,18 @@ export function DynaChart({
/>
)}
- {/* Field events: sowing (Z), harvest (O), fertilizer (M)
- Labels are stacked vertically per date to avoid overlap */}
- {eventsWithStack.map((ev, idx) => (
+ {/* Field events — info dot at top of each vertical line.
+ Events grouped by date; tooltip shows all events for that day. */}
+ {uniqueEventDates.map(([date, evs]) => (
(
-
)}
/>
diff --git a/fdm-app/app/components/blocks/mineralisatie/mineralisatie-chart.tsx b/fdm-app/app/components/blocks/mineralisatie/mineralisatie-chart.tsx
index db38cacb0..22b16fa28 100644
--- a/fdm-app/app/components/blocks/mineralisatie/mineralisatie-chart.tsx
+++ b/fdm-app/app/components/blocks/mineralisatie/mineralisatie-chart.tsx
@@ -78,6 +78,7 @@ export function FarmMineralisatieChart({
year = new Date().getFullYear(),
}: FarmMineralisatieChartProps) {
const currentDoy = getCurrentDoy()
+ const isCurrentYear = year === new Date().getFullYear()
return (
@@ -146,18 +147,20 @@ export function FarmMineralisatieChart({
/>
}
/>
-
+ {isCurrentYear && (
+
+ )}
!s.error)
@@ -313,18 +317,20 @@ export function FieldMineralisatieChart({
/>
}
/>
-
+ {isCurrentYear && (
+
+ )}
{activeSeries.map((s) => {
const style = METHOD_STYLE[s.method]
return (
diff --git a/fdm-app/app/routes/farm.$b_id_farm.$calendar.mineralisatie.$b_id._index.tsx b/fdm-app/app/routes/farm.$b_id_farm.$calendar.mineralisatie.$b_id._index.tsx
index fb0c73f17..8c431c72a 100644
--- a/fdm-app/app/routes/farm.$b_id_farm.$calendar.mineralisatie.$b_id._index.tsx
+++ b/fdm-app/app/routes/farm.$b_id_farm.$calendar.mineralisatie.$b_id._index.tsx
@@ -1,5 +1,5 @@
import { getCurrentSoilData, getField } from "@nmi-agro/fdm-core"
-import { ArrowRight, Lightbulb, Slash } from "lucide-react"
+import { ArrowRight, FlaskConical, Lightbulb, Slash } from "lucide-react"
import { Suspense, use } from "react"
import {
data,
@@ -276,6 +276,37 @@ function MineralisatieFieldContent({
)}
+ {/* DYNA Call-to-Action — prominent banner */}
+
+
+
+
+
+
+
+
+ Dynamisch N-advies met DYNA
+
+
+ bèta
+
+
+
+ Gedetailleerd N-opname vs. beschikbaarheid advies op
+ dagbasis — inclusief uitspoelingsrisico.
+
+
+
+
+
+
Mineralisatiecurve
@@ -285,7 +316,10 @@ function MineralisatieFieldContent({
-
+
@@ -299,32 +333,6 @@ function MineralisatieFieldContent({
calendar={calendar}
/>
-
- {/* DYNA Call-to-Action */}
-
-
- Dynamisch N-advies beschikbaar (bèta)
-
-
- Bereken gedetailleerd N-opname vs. beschikbaarheid
- advies met het DYNA-model.
-
-
-
-
-
>
)
}
diff --git a/fdm-app/app/routes/farm.$b_id_farm.$calendar.mineralisatie.$b_id.dyna.tsx b/fdm-app/app/routes/farm.$b_id_farm.$calendar.mineralisatie.$b_id.dyna.tsx
index f45a88de9..de6816592 100644
--- a/fdm-app/app/routes/farm.$b_id_farm.$calendar.mineralisatie.$b_id.dyna.tsx
+++ b/fdm-app/app/routes/farm.$b_id_farm.$calendar.mineralisatie.$b_id.dyna.tsx
@@ -4,15 +4,17 @@ import {
getField,
getGrazingIntention,
getCultivations,
+ getHarvests,
type FertilizerApplication,
type Fertilizer,
} from "@nmi-agro/fdm-core"
-import { Slash } from "lucide-react"
+import { CalendarOff, Slash } from "lucide-react"
import { Suspense, use } from "react"
import {
data,
type LoaderFunctionArgs,
type MetaFunction,
+ NavLink,
useLoaderData,
} from "react-router"
import { DynaAdviceCard } from "~/components/blocks/mineralisatie/dyna-advice"
@@ -20,6 +22,7 @@ import { DynaBalanceCard } from "~/components/blocks/mineralisatie/dyna-balance"
import { DynaChart } from "~/components/blocks/mineralisatie/dyna-chart"
import { LeachingChart } from "~/components/blocks/mineralisatie/leaching-chart"
import { DynaFallback } from "~/components/blocks/mineralisatie/skeletons"
+import { Button } from "~/components/ui/button"
import {
Card,
CardContent,
@@ -116,6 +119,27 @@ export async function loader({ request, params }: LoaderFunctionArgs) {
getCultivations(fdm, session.principal_id, b_id, timeframe),
])
+ // Pre-flight check: any main crop without a harvest date will cause
+ // the DYNA API to return 400 "b_date_harvest is missing".
+ const ongoingMainCrops = cultivations.filter(
+ (c) =>
+ c.b_lu_end == null &&
+ c.b_lu_croprotation !== "catchcrop",
+ )
+ for (const crop of ongoingMainCrops) {
+ if (!crop.b_lu) continue
+ const harvests = await getHarvests(fdm, session.principal_id, crop.b_lu, timeframe)
+ if (harvests.length === 0) {
+ return {
+ missingHarvestDate: true as const,
+ field,
+ b_id,
+ b_id_farm,
+ calendar: params.calendar ?? "",
+ }
+ }
+ }
+
// Build a map from p_id → full fertilizer properties for quick lookup
const fertilizerMap = new Map(
fertilizers.map((f: Fertilizer) => [f.p_id, f]),
@@ -224,6 +248,29 @@ export default function DynaPage() {
)
}
+ if (loaderData.missingHarvestDate) {
+ return (
+
+
+
+
+
+ Oogstdatum ontbreekt
+
+ DYNA heeft een oogstdatum nodig om de berekening uit te
+ voeren. Voeg een oogstdatum toe aan het gewas op dit
+ perceel.
+
+
+
+
+
+
+ )
+ }
+
const { asyncData, chartEvents } = loaderData
return (
@@ -338,6 +385,7 @@ function DynaContent({
data={yearData}
fertilizingRecommendations={fertilizingRecommendations}
events={chartEvents}
+ year={year}
/>
diff --git a/fdm-app/app/routes/farm.$b_id_farm.$calendar.mineralisatie._index.tsx b/fdm-app/app/routes/farm.$b_id_farm.$calendar.mineralisatie._index.tsx
index 9b0f50dc5..b13c164c5 100644
--- a/fdm-app/app/routes/farm.$b_id_farm.$calendar.mineralisatie._index.tsx
+++ b/fdm-app/app/routes/farm.$b_id_farm.$calendar.mineralisatie._index.tsx
@@ -162,7 +162,10 @@ function MineralisatieFarmContent({
-
+
diff --git a/fdm-calculator/src/mineralisatie/builders.test.ts b/fdm-calculator/src/mineralisatie/builders.test.ts
index 8d9ccf144..5b407d62e 100644
--- a/fdm-calculator/src/mineralisatie/builders.test.ts
+++ b/fdm-calculator/src/mineralisatie/builders.test.ts
@@ -22,7 +22,7 @@ describe("buildDynaRequest – rotation building", () => {
},
]
const result = buildDynaRequest(baseField, soilData, cultivations, [], "arable", timeframe2025)
- const rotation = result.rotation as { year: number; b_lu: string }[]
+ const rotation = (result.field as Record).rotation as { year: number; b_lu: string }[]
expect(rotation).toHaveLength(1)
expect(rotation[0].year).toBe(2025)
expect(rotation[0].b_lu).toBe("bwt")
@@ -39,7 +39,7 @@ describe("buildDynaRequest – rotation building", () => {
},
]
const result = buildDynaRequest(baseField, soilData, cultivations, [], "dairy", timeframe2025)
- const rotation = result.rotation as { year: number; b_lu: string }[]
+ const rotation = (result.field as Record).rotation as { year: number; b_lu: string }[]
expect(rotation).toHaveLength(1)
expect(rotation[0].year).toBe(2025)
expect(rotation[0].b_lu).toBe("grs")
@@ -56,7 +56,7 @@ describe("buildDynaRequest – rotation building", () => {
},
]
const result = buildDynaRequest(baseField, soilData, cultivations, [], "dairy", timeframe2025)
- const rotation = result.rotation as { year: number; b_lu: string }[]
+ const rotation = (result.field as Record).rotation as { year: number; b_lu: string }[]
expect(rotation).toHaveLength(1)
expect(rotation[0].b_lu).toBe("grs")
})
@@ -72,7 +72,7 @@ describe("buildDynaRequest – rotation building", () => {
},
]
const result = buildDynaRequest(baseField, soilData, cultivations, [], "arable", timeframe2025)
- const rotation = result.rotation as unknown[]
+ const rotation = (result.field as Record).rotation as unknown[]
// Falls back to the empty fallback entry (no b_lu)
expect(rotation).toHaveLength(1)
expect((rotation[0] as Record).b_lu).toBeUndefined()
@@ -96,7 +96,7 @@ describe("buildDynaRequest – rotation building", () => {
},
]
const result = buildDynaRequest(baseField, soilData, cultivations, [], "arable", timeframe2025)
- const rotation = result.rotation as { year: number; b_lu: string }[]
+ const rotation = (result.field as Record).rotation as { year: number; b_lu: string }[]
// Only 2025 entry is produced — 2024 cultivation is excluded (ended before 2025)
expect(rotation).toHaveLength(1)
expect(rotation[0].year).toBe(2025)
@@ -125,7 +125,7 @@ describe("buildDynaRequest – rotation building", () => {
},
]
const result = buildDynaRequest(baseField, soilData, cultivations, [], "dairy", timeframe2025)
- const rotation = result.rotation as { year: number; b_lu: string; b_lu_green?: string }[]
+ const rotation = (result.field as Record).rotation as { year: number; b_lu: string; b_lu_green?: string }[]
expect(rotation).toHaveLength(1)
expect(rotation[0].b_lu).toBe("grs")
expect(rotation[0].b_lu_green).toBe("phc")
@@ -158,7 +158,7 @@ describe("buildDynaRequest – harvests", () => {
baseField, soilData, cultivations, [], "dairy", timeframe2025,
undefined, harvestsByBlu,
)
- const rotation = result.rotation as { harvests: { b_date_harvest: string; b_lu_yield: number }[] }[]
+ const rotation = (result.field as Record).rotation as { harvests: { b_date_harvest: string; b_lu_yield: number }[] }[]
expect(rotation).toHaveLength(1)
expect(rotation[0].harvests).toHaveLength(3)
expect(rotation[0].harvests[0].b_date_harvest).toBe("2025-05-10")
@@ -182,7 +182,7 @@ describe("buildDynaRequest – harvests", () => {
[{ b_lu_catalogue: "bwt", b_lu_yield: 1800 }],
new Map(),
)
- const rotation = result.rotation as { harvests: { b_date_harvest: string; b_lu_yield?: number }[] }[]
+ const rotation = (result.field as Record).rotation as { harvests: { b_date_harvest: string; b_lu_yield?: number }[] }[]
expect(rotation[0].harvests).toHaveLength(1)
expect(rotation[0].harvests[0].b_date_harvest).toBe("2025-08-15")
expect(rotation[0].harvests[0].b_lu_yield).toBe(1800)
@@ -210,7 +210,7 @@ describe("buildDynaRequest – harvests", () => {
[{ b_lu_catalogue: "grs", b_lu_yield: 1838 }],
harvestsByBlu,
)
- const rotation = result.rotation as { harvests: { b_date_harvest: string; b_lu_yield?: number }[] }[]
+ const rotation = (result.field as Record).rotation as { harvests: { b_date_harvest: string; b_lu_yield?: number }[] }[]
expect(rotation[0].harvests[0].b_lu_yield).toBe(1838)
})
@@ -226,7 +226,7 @@ describe("buildDynaRequest – harvests", () => {
},
]
const result = buildDynaRequest(baseField, soilData, cultivations, [], "dairy", timeframe2025)
- const rotation = result.rotation as { harvests: unknown[] }[]
+ const rotation = (result.field as Record).rotation as { harvests: unknown[] }[]
expect(rotation[0].harvests).toHaveLength(0)
})
})
From 23b7b63d807488f2227da39f49a9b737cbdc4904 Mon Sep 17 00:00:00 2001
From: SvenVw <37927107+SvenVw@users.noreply.github.com>
Date: Mon, 20 Apr 2026 14:23:14 +0200
Subject: [PATCH 06/22] refactor: renaming for consistency
---
.../{mineralisatie.tsx => mineralization.tsx} | 8 ++--
.../data-completeness.tsx | 2 +-
.../dyna-advice.tsx | 2 +-
.../dyna-balance.tsx | 4 +-
.../dyna-chart.tsx | 2 +-
.../field-list.tsx | 4 +-
.../leaching-chart.tsx | 2 +-
.../method-selector.tsx | 2 +-
.../mineralization-chart.tsx} | 14 +++----
.../nsupply-kpi.tsx | 2 +-
.../skeletons.tsx | 40 +++++++++----------
.../app/components/blocks/sidebar/farm.tsx | 4 +-
...tie.server.ts => mineralization.server.ts} | 2 +-
...$calendar.mineralization.$b_id._index.tsx} | 22 +++++-----
...m.$calendar.mineralization.$b_id.dyna.tsx} | 12 +++---
...d_farm.$calendar.mineralization.$b_id.tsx} | 2 +-
..._farm.$calendar.mineralization._index.tsx} | 26 ++++++------
...m.$b_id_farm.$calendar.mineralization.tsx} | 6 +--
18 files changed, 78 insertions(+), 78 deletions(-)
rename fdm-app/app/components/blocks/header/{mineralisatie.tsx => mineralization.tsx} (96%)
rename fdm-app/app/components/blocks/{mineralisatie => mineralization}/data-completeness.tsx (99%)
rename fdm-app/app/components/blocks/{mineralisatie => mineralization}/dyna-advice.tsx (99%)
rename fdm-app/app/components/blocks/{mineralisatie => mineralization}/dyna-balance.tsx (95%)
rename fdm-app/app/components/blocks/{mineralisatie => mineralization}/dyna-chart.tsx (99%)
rename fdm-app/app/components/blocks/{mineralisatie => mineralization}/field-list.tsx (96%)
rename fdm-app/app/components/blocks/{mineralisatie => mineralization}/leaching-chart.tsx (98%)
rename fdm-app/app/components/blocks/{mineralisatie => mineralization}/method-selector.tsx (96%)
rename fdm-app/app/components/blocks/{mineralisatie/mineralisatie-chart.tsx => mineralization/mineralization-chart.tsx} (97%)
rename fdm-app/app/components/blocks/{mineralisatie => mineralization}/nsupply-kpi.tsx (99%)
rename fdm-app/app/components/blocks/{mineralisatie => mineralization}/skeletons.tsx (85%)
rename fdm-app/app/integrations/{mineralisatie.server.ts => mineralization.server.ts} (99%)
rename fdm-app/app/routes/{farm.$b_id_farm.$calendar.mineralisatie.$b_id._index.tsx => farm.$b_id_farm.$calendar.mineralization.$b_id._index.tsx} (95%)
rename fdm-app/app/routes/{farm.$b_id_farm.$calendar.mineralisatie.$b_id.dyna.tsx => farm.$b_id_farm.$calendar.mineralization.$b_id.dyna.tsx} (96%)
rename fdm-app/app/routes/{farm.$b_id_farm.$calendar.mineralisatie.$b_id.tsx => farm.$b_id_farm.$calendar.mineralization.$b_id.tsx} (53%)
rename fdm-app/app/routes/{farm.$b_id_farm.$calendar.mineralisatie._index.tsx => farm.$b_id_farm.$calendar.mineralization._index.tsx} (89%)
rename fdm-app/app/routes/{farm.$b_id_farm.$calendar.mineralisatie.tsx => farm.$b_id_farm.$calendar.mineralization.tsx} (96%)
diff --git a/fdm-app/app/components/blocks/header/mineralisatie.tsx b/fdm-app/app/components/blocks/header/mineralization.tsx
similarity index 96%
rename from fdm-app/app/components/blocks/header/mineralisatie.tsx
rename to fdm-app/app/components/blocks/header/mineralization.tsx
index 54e8e67e1..b3831cacd 100644
--- a/fdm-app/app/components/blocks/header/mineralisatie.tsx
+++ b/fdm-app/app/components/blocks/header/mineralization.tsx
@@ -18,7 +18,7 @@ type HeaderFieldOption = {
b_name: string | null | undefined
}
-export function HeaderMineralisatie({
+export function HeaderMineralization({
b_id_farm,
b_id,
fieldOptions,
@@ -40,7 +40,7 @@ export function HeaderMineralisatie({
Mineralisatie
@@ -65,7 +65,7 @@ export function HeaderMineralisatie({
key={option.b_id}
>
{option.b_name}
@@ -82,7 +82,7 @@ export function HeaderMineralisatie({
DYNA
diff --git a/fdm-app/app/components/blocks/mineralisatie/data-completeness.tsx b/fdm-app/app/components/blocks/mineralization/data-completeness.tsx
similarity index 99%
rename from fdm-app/app/components/blocks/mineralisatie/data-completeness.tsx
rename to fdm-app/app/components/blocks/mineralization/data-completeness.tsx
index 571dbf057..aea5f4176 100644
--- a/fdm-app/app/components/blocks/mineralisatie/data-completeness.tsx
+++ b/fdm-app/app/components/blocks/mineralization/data-completeness.tsx
@@ -18,7 +18,7 @@ import {
import type {
DataCompleteness,
NSupplyMethod,
-} from "~/integrations/mineralisatie.server"
+} from "~/integrations/mineralization.server"
const PARAM_LABELS: Record = {
a_som_loi: "Organische stof (LOI)",
diff --git a/fdm-app/app/components/blocks/mineralisatie/dyna-advice.tsx b/fdm-app/app/components/blocks/mineralization/dyna-advice.tsx
similarity index 99%
rename from fdm-app/app/components/blocks/mineralisatie/dyna-advice.tsx
rename to fdm-app/app/components/blocks/mineralization/dyna-advice.tsx
index 853f0bc15..12c3b6d03 100644
--- a/fdm-app/app/components/blocks/mineralisatie/dyna-advice.tsx
+++ b/fdm-app/app/components/blocks/mineralization/dyna-advice.tsx
@@ -7,7 +7,7 @@ import {
CardTitle,
} from "~/components/ui/card"
import { Separator } from "~/components/ui/separator"
-import type { DynaFertilizerAdvice } from "~/integrations/mineralisatie.server"
+import type { DynaFertilizerAdvice } from "~/integrations/mineralization.server"
interface DynaAdviceCardProps {
fertilizingRecommendations: DynaFertilizerAdvice | null
diff --git a/fdm-app/app/components/blocks/mineralisatie/dyna-balance.tsx b/fdm-app/app/components/blocks/mineralization/dyna-balance.tsx
similarity index 95%
rename from fdm-app/app/components/blocks/mineralisatie/dyna-balance.tsx
rename to fdm-app/app/components/blocks/mineralization/dyna-balance.tsx
index 06ecc4daa..1946aac80 100644
--- a/fdm-app/app/components/blocks/mineralisatie/dyna-balance.tsx
+++ b/fdm-app/app/components/blocks/mineralization/dyna-balance.tsx
@@ -6,7 +6,7 @@ import {
CardTitle,
} from "~/components/ui/card"
import { Separator } from "~/components/ui/separator"
-import type { DynaNitrogenBalance } from "~/integrations/mineralisatie.server"
+import type { DynaNitrogenBalance } from "~/integrations/mineralization.server"
interface DynaBalanceCardProps {
nitrogenBalance: DynaNitrogenBalance
@@ -41,7 +41,7 @@ export function DynaBalanceCard({ nitrogenBalance }: DynaBalanceCardProps) {
return (
- N-balans
+ Werkzame N-balans
Stikstofaanbod naar bron (kg N/ha/jaar)
diff --git a/fdm-app/app/components/blocks/mineralisatie/dyna-chart.tsx b/fdm-app/app/components/blocks/mineralization/dyna-chart.tsx
similarity index 99%
rename from fdm-app/app/components/blocks/mineralisatie/dyna-chart.tsx
rename to fdm-app/app/components/blocks/mineralization/dyna-chart.tsx
index 93f6f2c8d..5c67895e1 100644
--- a/fdm-app/app/components/blocks/mineralisatie/dyna-chart.tsx
+++ b/fdm-app/app/components/blocks/mineralization/dyna-chart.tsx
@@ -19,7 +19,7 @@ import {
import type {
DynaDailyPoint,
DynaFertilizerAdvice,
-} from "~/integrations/mineralisatie.server"
+} from "~/integrations/mineralization.server"
const MONTH_LABELS_NL = [
"Jan",
diff --git a/fdm-app/app/components/blocks/mineralisatie/field-list.tsx b/fdm-app/app/components/blocks/mineralization/field-list.tsx
similarity index 96%
rename from fdm-app/app/components/blocks/mineralisatie/field-list.tsx
rename to fdm-app/app/components/blocks/mineralization/field-list.tsx
index 208cf5524..3e09d8459 100644
--- a/fdm-app/app/components/blocks/mineralisatie/field-list.tsx
+++ b/fdm-app/app/components/blocks/mineralization/field-list.tsx
@@ -8,7 +8,7 @@ import {
TableHeader,
TableRow,
} from "~/components/ui/table"
-import type { NSupplyResult } from "~/integrations/mineralisatie.server"
+import type { NSupplyResult } from "~/integrations/mineralization.server"
interface FieldListProps {
results: NSupplyResult[]
@@ -46,7 +46,7 @@ export function FieldList({ results, b_id_farm, calendar }: FieldListProps) {
{result.b_name}
diff --git a/fdm-app/app/components/blocks/mineralisatie/leaching-chart.tsx b/fdm-app/app/components/blocks/mineralization/leaching-chart.tsx
similarity index 98%
rename from fdm-app/app/components/blocks/mineralisatie/leaching-chart.tsx
rename to fdm-app/app/components/blocks/mineralization/leaching-chart.tsx
index bd9e44f27..0648ccc8d 100644
--- a/fdm-app/app/components/blocks/mineralisatie/leaching-chart.tsx
+++ b/fdm-app/app/components/blocks/mineralization/leaching-chart.tsx
@@ -7,7 +7,7 @@ import {
ChartTooltip,
ChartTooltipContent,
} from "~/components/ui/chart"
-import type { DynaDailyPoint } from "~/integrations/mineralisatie.server"
+import type { DynaDailyPoint } from "~/integrations/mineralization.server"
const MONTH_LABELS_NL = [
"Jan",
diff --git a/fdm-app/app/components/blocks/mineralisatie/method-selector.tsx b/fdm-app/app/components/blocks/mineralization/method-selector.tsx
similarity index 96%
rename from fdm-app/app/components/blocks/mineralisatie/method-selector.tsx
rename to fdm-app/app/components/blocks/mineralization/method-selector.tsx
index c8db83043..589d831b2 100644
--- a/fdm-app/app/components/blocks/mineralisatie/method-selector.tsx
+++ b/fdm-app/app/components/blocks/mineralization/method-selector.tsx
@@ -6,7 +6,7 @@ import {
SelectTrigger,
SelectValue,
} from "~/components/ui/select"
-import type { NSupplyMethod } from "~/integrations/mineralisatie.server"
+import type { NSupplyMethod } from "~/integrations/mineralization.server"
const METHOD_OPTIONS: {
value: NSupplyMethod
diff --git a/fdm-app/app/components/blocks/mineralisatie/mineralisatie-chart.tsx b/fdm-app/app/components/blocks/mineralization/mineralization-chart.tsx
similarity index 97%
rename from fdm-app/app/components/blocks/mineralisatie/mineralisatie-chart.tsx
rename to fdm-app/app/components/blocks/mineralization/mineralization-chart.tsx
index 22b16fa28..5e7aab739 100644
--- a/fdm-app/app/components/blocks/mineralisatie/mineralisatie-chart.tsx
+++ b/fdm-app/app/components/blocks/mineralization/mineralization-chart.tsx
@@ -19,7 +19,7 @@ import {
import type {
NSupplyDataPoint,
NSupplyMethod,
-} from "~/integrations/mineralisatie.server"
+} from "~/integrations/mineralization.server"
const MONTH_DOYS = [1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335]
const MONTH_LABELS = [
@@ -61,7 +61,7 @@ function getCurrentDoy(): number {
// ─── Single-series chart (farm overview) ─────────────────────────────────────
-interface FarmMineralisatieChartProps {
+interface FarmMineralizationChartProps {
data: NSupplyDataPoint[]
year?: number
}
@@ -73,10 +73,10 @@ const farmChartConfig = {
},
} satisfies ChartConfig
-export function FarmMineralisatieChart({
+export function FarmMineralizationChart({
data,
year = new Date().getFullYear(),
-}: FarmMineralisatieChartProps) {
+}: FarmMineralizationChartProps) {
const currentDoy = getCurrentDoy()
const isCurrentYear = year === new Date().getFullYear()
@@ -183,7 +183,7 @@ interface FieldDataSeries {
error?: string
}
-interface FieldMineralisatieChartProps {
+interface FieldMineralizationChartProps {
series: FieldDataSeries[]
year?: number
}
@@ -236,10 +236,10 @@ function mergeSeriesData(
)
}
-export function FieldMineralisatieChart({
+export function FieldMineralizationChart({
series,
year = new Date().getFullYear(),
-}: FieldMineralisatieChartProps) {
+}: FieldMineralizationChartProps) {
const currentDoy = getCurrentDoy()
const isCurrentYear = year === new Date().getFullYear()
const mergedData = mergeSeriesData(series)
diff --git a/fdm-app/app/components/blocks/mineralisatie/nsupply-kpi.tsx b/fdm-app/app/components/blocks/mineralization/nsupply-kpi.tsx
similarity index 99%
rename from fdm-app/app/components/blocks/mineralisatie/nsupply-kpi.tsx
rename to fdm-app/app/components/blocks/mineralization/nsupply-kpi.tsx
index 45e76e6de..43b7e10ba 100644
--- a/fdm-app/app/components/blocks/mineralisatie/nsupply-kpi.tsx
+++ b/fdm-app/app/components/blocks/mineralization/nsupply-kpi.tsx
@@ -3,7 +3,7 @@ import { Separator } from "~/components/ui/separator"
import type {
NSupplyMethod,
NSupplyResult,
-} from "~/integrations/mineralisatie.server"
+} from "~/integrations/mineralization.server"
const METHOD_LABELS: Record = {
minip: "MINIP",
diff --git a/fdm-app/app/components/blocks/mineralisatie/skeletons.tsx b/fdm-app/app/components/blocks/mineralization/skeletons.tsx
similarity index 85%
rename from fdm-app/app/components/blocks/mineralisatie/skeletons.tsx
rename to fdm-app/app/components/blocks/mineralization/skeletons.tsx
index b0599567f..bf7609598 100644
--- a/fdm-app/app/components/blocks/mineralisatie/skeletons.tsx
+++ b/fdm-app/app/components/blocks/mineralization/skeletons.tsx
@@ -7,7 +7,7 @@ import {
} from "~/components/ui/card"
import { Skeleton } from "~/components/ui/skeleton"
-export function MineralisatieCardSkeleton() {
+export function MineralizationCardSkeleton() {
return (
@@ -22,7 +22,7 @@ export function MineralisatieCardSkeleton() {
)
}
-export function MineralisatieChartSkeleton() {
+export function MineralizationChartSkeleton() {
return (
@@ -40,7 +40,7 @@ export function MineralisatieChartSkeleton() {
)
}
-export function MineralisatieFieldsSkeleton() {
+export function MineralizationFieldsSkeleton() {
return (
@@ -68,20 +68,20 @@ export function MineralisatieFieldsSkeleton() {
}
/** Fallback for the farm overview page */
-export function MineralisatieFallback() {
+export function MineralizationFallback() {
return (
-
-
-
+
+
+
-
+
-
+
@@ -93,12 +93,12 @@ export function DynaFallback() {
return (
-
-
-
-
+
+
+
+
-
+
@@ -136,16 +136,16 @@ export function DynaFallback() {
}
/** Fallback for the field detail page */
-export function MineralisatieFieldDetailFallback() {
+export function MineralizationFieldDetailFallback() {
return (
-
-
-
-
+
+
+
+
-
+
diff --git a/fdm-app/app/components/blocks/sidebar/farm.tsx b/fdm-app/app/components/blocks/sidebar/farm.tsx
index a79acb6cf..e2f7e0dee 100644
--- a/fdm-app/app/components/blocks/sidebar/farm.tsx
+++ b/fdm-app/app/components/blocks/sidebar/farm.tsx
@@ -390,12 +390,12 @@ export function SidebarLabs() {
Mineralisatie
diff --git a/fdm-app/app/integrations/mineralisatie.server.ts b/fdm-app/app/integrations/mineralization.server.ts
similarity index 99%
rename from fdm-app/app/integrations/mineralisatie.server.ts
rename to fdm-app/app/integrations/mineralization.server.ts
index e64abe09f..c98a6ffc5 100644
--- a/fdm-app/app/integrations/mineralisatie.server.ts
+++ b/fdm-app/app/integrations/mineralization.server.ts
@@ -1,5 +1,5 @@
/**
- * @file mineralisatie.server.ts
+ * @file mineralization.server.ts
*
* Server-side orchestration layer for the Mineralisatie (Nitrogen Mineralization) feature.
*
diff --git a/fdm-app/app/routes/farm.$b_id_farm.$calendar.mineralisatie.$b_id._index.tsx b/fdm-app/app/routes/farm.$b_id_farm.$calendar.mineralization.$b_id._index.tsx
similarity index 95%
rename from fdm-app/app/routes/farm.$b_id_farm.$calendar.mineralisatie.$b_id._index.tsx
rename to fdm-app/app/routes/farm.$b_id_farm.$calendar.mineralization.$b_id._index.tsx
index 8c431c72a..7869fccd3 100644
--- a/fdm-app/app/routes/farm.$b_id_farm.$calendar.mineralisatie.$b_id._index.tsx
+++ b/fdm-app/app/routes/farm.$b_id_farm.$calendar.mineralization.$b_id._index.tsx
@@ -8,10 +8,10 @@ import {
NavLink,
useLoaderData,
} from "react-router"
-import { DataCompletenessCard } from "~/components/blocks/mineralisatie/data-completeness"
-import { FieldMineralisatieChart } from "~/components/blocks/mineralisatie/mineralisatie-chart"
-import { FieldNSupplyDetailsCard } from "~/components/blocks/mineralisatie/nsupply-kpi"
-import { MineralisatieFieldDetailFallback } from "~/components/blocks/mineralisatie/skeletons"
+import { DataCompletenessCard } from "~/components/blocks/mineralization/data-completeness"
+import { FieldMineralizationChart } from "~/components/blocks/mineralization/mineralization-chart"
+import { FieldNSupplyDetailsCard } from "~/components/blocks/mineralization/nsupply-kpi"
+import { MineralizationFieldDetailFallback } from "~/components/blocks/mineralization/skeletons"
import { Button } from "~/components/ui/button"
import {
Card,
@@ -34,7 +34,7 @@ import {
getNSupplyForField,
type NSupplyMethod,
type NSupplyResult,
-} from "~/integrations/mineralisatie.server"
+} from "~/integrations/mineralization.server"
import { getSession } from "~/lib/auth.server"
import { getTimeframe } from "~/lib/calendar"
import { clientConfig } from "~/lib/config"
@@ -193,7 +193,7 @@ export async function loader({ request, params }: LoaderFunctionArgs) {
}
}
-export default function MineralisatieFieldDetail() {
+export default function MineralizationFieldDetail() {
const loaderData = useLoaderData()
if (loaderData.isBufferStrip) {
@@ -217,8 +217,8 @@ export default function MineralisatieFieldDetail() {
return (