diff --git a/.changeset/all-schools-lay.md b/.changeset/all-schools-lay.md new file mode 100644 index 000000000..ea0aaacda --- /dev/null +++ b/.changeset/all-schools-lay.md @@ -0,0 +1,5 @@ +--- +"@svenvw/fdm-app": minor +--- + +Add titles and descriptions to pages diff --git a/.changeset/fluffy-hotels-switch.md b/.changeset/fluffy-hotels-switch.md new file mode 100644 index 000000000..80f283263 --- /dev/null +++ b/.changeset/fluffy-hotels-switch.md @@ -0,0 +1,5 @@ +--- +"@svenvw/fdm-app": minor +--- + +Add a message at signin page that the app is still in development diff --git a/.changeset/warm-dryers-start.md b/.changeset/warm-dryers-start.md new file mode 100644 index 000000000..2a5866116 --- /dev/null +++ b/.changeset/warm-dryers-start.md @@ -0,0 +1,5 @@ +--- +"@svenvw/fdm-app": minor +--- + +Make fdm-app configurable for various settings, including the name diff --git a/fdm-app/.env.example b/fdm-app/.env.example index eb5d3597e..12563eca9 100644 --- a/fdm-app/.env.example +++ b/fdm-app/.env.example @@ -1,85 +1,90 @@ -# NodeJS Configuration -# Sets the environment for the application (development, production). -# Example: development, production +# ------------------------------------- +# General Application Configuration +# ------------------------------------- +# Sets the environment (development, production). Affects logging, error handling, etc. +# Required: Yes NODE_ENV= -# Secret key used to sign session cookies. -# Must be a strong, randomly generated string. Do not hardcode or commit this value to version control. Use a secure secret management system. -# Rotate this key periodically. Compromising this secret can allow attackers to hijack user sessions. -FDM_SESSION_SECRET= +# Public name of the application displayed in the UI. +# Required: Yes +VITE_FDM_NAME= -# DB configuration -# The hostname or IP address of the PostgreSQL database server. -POSTGRES_HOST= +# Port the application server will listen on. +# Required: Yes (Defaults may exist in deployment environment) +PORT= -# The port number on which the PostgreSQL database server is listening. Defaults to 5432 if not specified. -POSTGRES_PORT= +# ------------------------------------- +# Session Management +# ------------------------------------- +# Secret key used to sign session cookies. MUST be a strong, random string. +# Keep this secret and rotate periodically. +# Required: Yes +FDM_SESSION_SECRET= -# The name of the PostgreSQL database to connect to. +# ------------------------------------- +# Database Configuration (PostgreSQL) +# ------------------------------------- +# Required: Yes +POSTGRES_HOST= +POSTGRES_PORT=5432 # Default PostgreSQL port POSTGRES_DB= - -# The username used to authenticate with the PostgreSQL database server. POSTGRES_USER= - -# The password used to authenticate with the PostgreSQL database server. Ensure this is stored securely and not exposed in version control. POSTGRES_PASSWORD= -# Mapbox configuration -# API token for Mapbox services. Required to use Mapbox features. -# Obtain your token from the Mapbox website. Keep this token secure and do not expose it in version control. -MAPBOX_TOKEN= - -# Authentication configuration -# Secret key used BY better-auth +# ------------------------------------- +# Authentication (Better Auth & OAuth Providers) +# ------------------------------------- +# Secret key used BY the better-auth library. +# Required: Yes BETTER_AUTH_SECRET= -# URL of application used by better-auth +# Full base URL of this application (used for redirects by better-auth). +# Example: http://localhost:5173 or https://yourdomain.com +# Required: Yes BETTER_AUTH_URL= +# Google OAuth Credentials (Optional: Leave empty to disable Google Sign-In) +# Required: No GOOGLE_CLIENT_ID= - GOOGLE_CLIENT_SECRET= -# Microsoft OAuth2 client ID obtained from Azure Portal +# Microsoft OAuth Credentials (Optional: Leave empty to disable Microsoft Sign-In) +# Required: No MS_CLIENT_ID= - -# Microsoft OAuth2 client secret obtained from Azure Portal. Keep this secure and never commit to version control. MS_CLIENT_SECRET= -# URL of .fgb file that contains the fields available to be selected -AVAILABLE_FIELDS_URL= +# ------------------------------------- +# Map & Data Configuration +# ------------------------------------- +# Mapbox API token for displaying maps. +# Required: Yes (for map functionality) +MAPBOX_TOKEN= +# URL to the FlatGeobuf (.fgb) file containing selectable field geometries. +# Required: Yes (for field selection functionality) +AVAILABLE_FIELDS_URL= -# Sentry configuration -# Sentry organization +# ------------------------------------- +# Analytics & Error Tracking (Optional) +# ------------------------------------- +# To enable Sentry error tracking and performance monitoring, fill in ALL VITE_SENTRY_* variables below. +# Leave them empty to disable Sentry integration. +# Required: No VITE_SENTRY_ORG= - -# Sentry project VITE_SENTRY_PROJECT= - -# Sentry DSN VITE_SENTRY_DSN= - -# Sentry auth token +VITE_SENTRY_TRACE_SAMPLE_RATE=1.0 # Sample rate for performance monitoring (0.0 to 1.0) +VITE_SENTRY_REPLAY_SAMPLE_RATE=0.1 # Sample rate for session replay (0.0 to 1.0) +VITE_SENTRY_REPLAY_SAMPLE_RATE_ON_ERROR=1.0 # Sample rate for session replay when errors occur (0.0 to 1.0) +VITE_SENTRY_PROFILE_SAMPLE_RATE=1.0 # Sample rate for profiling (0.0 to 1.0) +VITE_SENTRY_SECURITY_REPORT_URI= # Used for CSP reporting + +# Sentry Auth Token (Required ONLY for uploading source maps during build, not for runtime) +# Required: No (for runtime) SENTRY_AUTH_TOKEN= -# Sentry trace sample rate -VITE_SENTRY_TRACE_SAMPLE_RATE= - -# Sentry replay sample rate -VITE_SENTRY_REPLAY_SAMPLE_RATE= - -# Sentry replay sample rate on error -VITE_SENTRY_REPLAY_SAMPLE_RATE_ON_ERROR= - -# Sentry profile sample rate -VITE_SENTRY_PROFILE_SAMPLE_RATE= - -# Sentry security report URI for CSP reporting -VITE_SENTRY_SECURITY_REPORT_URI= - -# Posthog configuration -# Posthog public key -VITE_PUBLIC_POSTHOG_KEY= -# Posthog host -VITE_PUBLIC_POSTHOG_HOST= \ No newline at end of file +# To enable PostHog product analytics, fill in BOTH variables below. +# Leave them empty to disable PostHog integration. +# Required: No +VITE_PUBLIC_POSTHOG_KEY= # Example: phc_... +VITE_PUBLIC_POSTHOG_HOST= # Example: https://eu.i.posthog.com diff --git a/fdm-app/README.md b/fdm-app/README.md index fe4301478..e6e780f5c 100644 --- a/fdm-app/README.md +++ b/fdm-app/README.md @@ -24,9 +24,25 @@ The `fdm-app` is a React application providing a user-friendly interface for vis pnpm add @svenvw/fdm-app ``` -3. **Configuration:** Set the required environment variables, including the database URL, API keys, and other relevant settings. Create a `.env` file in the root directory of your application and copy the values from the `.env.example` file. +3. **Configuration:** + Configure the application by setting environment variables. Create a `.env` file in the `fdm-app` directory by copying the provided `.env.example` file: -4. **Running the App:** + ```bash + cp .env.example .env + ``` + + Edit the `.env` file and provide values for the necessary variables. Key configuration areas include: + * **General:** Application name (`VITE_FDM_NAME`), environment (`NODE_ENV`). + * **Session:** A strong secret key (`FDM_SESSION_SECRET`). + * **Database:** Connection details for your PostgreSQL database. + * **Authentication:** Secrets and URLs for `better-auth` and optionally OAuth providers (Google, Microsoft). + * **Mapbox:** API token for map rendering (`MAPBOX_TOKEN`). + * **Data URLs:** Paths to external data files (`AVAILABLE_FIELDS_URL`). + * **Analytics (Optional):** Configuration for Sentry and/or PostHog. These services are disabled by default. To enable them, provide the relevant keys/DSNs as described in `.env.example`. + + Refer to the comments within the `.env.example` file for detailed explanations of each variable and whether it's required. **Never commit your `.env` file to version control.** + +4. **Running the App:** ```bash # Development mode pnpm dev diff --git a/fdm-app/app/components/blocks/farm.tsx b/fdm-app/app/components/blocks/farm.tsx index e13c9cebb..87eaa4d19 100644 --- a/fdm-app/app/components/blocks/farm.tsx +++ b/fdm-app/app/components/blocks/farm.tsx @@ -2,8 +2,7 @@ import { zodResolver } from "@hookform/resolvers/zod" import { Form } from "react-router" import { RemixFormProvider, useRemixForm } from "remix-hook-form" import type { z } from "zod" - -import { Button } from "@/components/ui/button" +import { Button } from "~/components/ui/button" import { Card, CardContent, @@ -11,7 +10,7 @@ import { CardFooter, CardHeader, CardTitle, -} from "@/components/ui/card" +} from "~/components/ui/card" import { FormControl, FormDescription, @@ -19,8 +18,8 @@ import { FormItem, FormLabel, FormMessage, -} from "@/components/ui/form" -import { Input } from "@/components/ui/input" +} from "~/components/ui/form" +import { Input } from "~/components/ui/input" import { LoadingSpinner } from "../custom/loadingspinner" export interface fertilizersListType { diff --git a/fdm-app/app/components/blocks/fields.tsx b/fdm-app/app/components/blocks/fields.tsx index aa89c08f4..987a94ddb 100644 --- a/fdm-app/app/components/blocks/fields.tsx +++ b/fdm-app/app/components/blocks/fields.tsx @@ -1,10 +1,11 @@ +import { useToast } from "@/hooks/use-toast" import type { FeatureCollection } from "geojson" +import { Check, ChevronsUpDown } from "lucide-react" import { useEffect, useState } from "react" import { Form, useNavigation } from "react-router" - -import { FieldMap } from "@/components/blocks/field-map" -// Components -import { Button } from "@/components/ui/button" +import { ClientOnly } from "remix-utils/client-only" +import { FieldMap } from "~/components/blocks/field-map" +import { Button } from "~/components/ui/button" import { Card, CardContent, @@ -12,7 +13,7 @@ import { CardFooter, CardHeader, CardTitle, -} from "@/components/ui/card" +} from "~/components/ui/card" import { Command, CommandEmpty, @@ -20,25 +21,22 @@ import { CommandInput, CommandItem, CommandList, -} from "@/components/ui/command" -import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" +} from "~/components/ui/command" +import { Input } from "~/components/ui/input" +import { Label } from "~/components/ui/label" import { Popover, PopoverContent, PopoverTrigger, -} from "@/components/ui/popover" +} from "~/components/ui/popover" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, -} from "@/components/ui/select" -import { useToast } from "@/hooks/use-toast" -import { cn } from "@/lib/utils" -import { Check, ChevronsUpDown } from "lucide-react" -import { ClientOnly } from "remix-utils/client-only" +} from "~/components/ui/select" +import { cn } from "~/lib/utils" import { Skeleton } from "../ui/skeleton" interface CultivationOption { diff --git a/fdm-app/app/components/custom/atlas/atlas-panels.tsx b/fdm-app/app/components/custom/atlas/atlas-panels.tsx index 950026f2f..d24023d03 100644 --- a/fdm-app/app/components/custom/atlas/atlas-panels.tsx +++ b/fdm-app/app/components/custom/atlas/atlas-panels.tsx @@ -1,6 +1,13 @@ -import { LoadingSpinner } from "@/components/custom/loadingspinner" -import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert" -import { Button } from "@/components/ui/button" +import type { FeatureCollection } from "geojson" +import throttle from "lodash.throttle" +import { Check, Info } from "lucide-react" +import { useEffect, useState } from "react" +import { useMap } from "react-map-gl" +import type { MapBoxZoomEvent, MapEvent, MapMouseEvent } from "react-map-gl" +import { data, useFetcher } from "react-router" +import { LoadingSpinner } from "~/components/custom/loadingspinner" +import { Alert, AlertDescription, AlertTitle } from "~/components/ui/alert" +import { Button } from "~/components/ui/button" import { Card, CardContent, @@ -8,15 +15,8 @@ import { CardFooter, CardHeader, CardTitle, -} from "@/components/ui/card" -import { cn } from "@/lib/utils" -import type { FeatureCollection } from "geojson" -import throttle from "lodash.throttle" -import { Check, Info } from "lucide-react" -import { useEffect, useState } from "react" -import { useMap } from "react-map-gl" -import type { MapBoxZoomEvent, MapEvent, MapMouseEvent } from "react-map-gl" -import { useFetcher } from "react-router" +} from "~/components/ui/card" +import { cn } from "~/lib/utils" export function FieldsPanelHover({ zoomLevelFields, diff --git a/fdm-app/app/components/custom/atlas/atlas-sources.tsx b/fdm-app/app/components/custom/atlas/atlas-sources.tsx index fdefd63c1..333b6b160 100644 --- a/fdm-app/app/components/custom/atlas/atlas-sources.tsx +++ b/fdm-app/app/components/custom/atlas/atlas-sources.tsx @@ -4,7 +4,7 @@ import throttle from "lodash.throttle" import { type Dispatch, type SetStateAction, useEffect, useState } from "react" import { Source, useMap } from "react-map-gl" import { generateFeatureClass } from "./atlas-functions" -import type { fieldsAvailableUrlType } from "./atlas.d" +import type { FieldsAvailableUrlType } from "./atlas.d" export function FieldsSourceNotClickable({ id, @@ -108,7 +108,7 @@ export function FieldsSourceAvailable({ children, }: { id: string - url: fieldsAvailableUrlType + url: FieldsAvailableUrlType zoomLevelFields: number children: JSX.Element }) { diff --git a/fdm-app/app/components/custom/atlas/atlas.d.tsx b/fdm-app/app/components/custom/atlas/atlas.d.tsx index f5a76b5c5..656643560 100644 --- a/fdm-app/app/components/custom/atlas/atlas.d.tsx +++ b/fdm-app/app/components/custom/atlas/atlas.d.tsx @@ -7,7 +7,7 @@ export interface MapFieldsProps { mapboxToken: string mapStyle: "mapbox://styles/mapbox/satellite-streets-v12" fieldsSelected: FeatureCollection | null - fieldsAvailableUrl: fieldsAvailableUrlType + fieldsAvailableUrl: FieldsAvailableUrlType fieldsSaved: FeatureCollection | null } diff --git a/fdm-app/app/components/custom/banner.tsx b/fdm-app/app/components/custom/banner.tsx index 10e5d6d14..c284f513f 100644 --- a/fdm-app/app/components/custom/banner.tsx +++ b/fdm-app/app/components/custom/banner.tsx @@ -1,7 +1,8 @@ -import { Button } from "@/components/ui/button" -import { Cookie, CookieIcon, X } from "lucide-react" +import { Cookie, X } from "lucide-react" import posthog from "posthog-js" import { useEffect, useState } from "react" +import { Button } from "~/components/ui/button" +import { clientConfig } from "~/lib/config" type ConsentType = "yes" | "no" | "undecided" @@ -36,7 +37,8 @@ export function Banner() { }, []) useEffect(() => { - if (consentGiven !== "undecided") { + // Set PostHog persistence based on consent, if PostHog is configured + if (clientConfig.analytics.posthog && consentGiven !== "undecided") { try { posthog.set_config({ persistence: @@ -116,7 +118,7 @@ export function Banner() {
- Wij gebruiken cookies enkel om FDM te
+ {`Wij gebruiken cookies enkel om ${clientConfig.name} te
verbeteren, zodat we weten wat er goed en
- fout gaat.
+ fout gaat.`}
Geen zorgen, we gebruiken ze niet voor
advertenties en ook niet om je online te
diff --git a/fdm-app/app/components/custom/combobox.tsx b/fdm-app/app/components/custom/combobox.tsx
index e7b785297..0f69d5fca 100644
--- a/fdm-app/app/components/custom/combobox.tsx
+++ b/fdm-app/app/components/custom/combobox.tsx
@@ -1,6 +1,6 @@
+import { Check, ChevronsUpDown } from "lucide-react"
import { type ReactNode, useMemo, useState } from "react"
-
-import { Button } from "@/components/ui/button"
+import { Button } from "~/components/ui/button"
import {
Command,
CommandEmpty,
@@ -8,7 +8,7 @@ import {
CommandInput,
CommandItem,
CommandList,
-} from "@/components/ui/command"
+} from "~/components/ui/command"
import {
FormControl,
FormDescription,
@@ -16,14 +16,13 @@ import {
FormItem,
FormLabel,
FormMessage,
-} from "@/components/ui/form"
+} from "~/components/ui/form"
import {
Popover,
PopoverContent,
PopoverTrigger,
-} from "@/components/ui/popover"
-import { cn } from "@/lib/utils"
-import { Check, ChevronsUpDown } from "lucide-react"
+} from "~/components/ui/popover"
+import { cn } from "~/lib/utils"
type optionType = {
value: string
diff --git a/fdm-app/app/components/custom/cultivation/form.tsx b/fdm-app/app/components/custom/cultivation/form.tsx
index c41c575f7..504a3c84c 100644
--- a/fdm-app/app/components/custom/cultivation/form.tsx
+++ b/fdm-app/app/components/custom/cultivation/form.tsx
@@ -1,5 +1,15 @@
-import { Button } from "@/components/ui/button"
-import { Calendar } from "@/components/ui/calendar"
+import { zodResolver } from "@hookform/resolvers/zod"
+import { format } from "date-fns/format"
+import { nl } from "date-fns/locale/nl"
+import { CalendarIcon } from "lucide-react"
+import { useEffect } from "react"
+import { Form } from "react-router"
+import { RemixFormProvider, useRemixForm } from "remix-hook-form"
+import type { z } from "zod"
+import { Combobox } from "~/components/custom/combobox"
+import { LoadingSpinner } from "~/components/custom/loadingspinner"
+import { Button } from "~/components/ui/button"
+import { Calendar } from "~/components/ui/calendar"
import {
FormControl,
FormDescription,
@@ -7,23 +17,13 @@ import {
FormItem,
FormLabel,
FormMessage,
-} from "@/components/ui/form"
+} from "~/components/ui/form"
import {
Popover,
PopoverContent,
PopoverTrigger,
-} from "@/components/ui/popover"
-import { cn } from "@/lib/utils"
-import { zodResolver } from "@hookform/resolvers/zod"
-import { format } from "date-fns/format"
-import { nl } from "date-fns/locale/nl"
-import { CalendarIcon } from "lucide-react"
-import { useEffect } from "react"
-import { Form } from "react-router"
-import { RemixFormProvider, useRemixForm } from "remix-hook-form"
-import type { z } from "zod"
-import { Combobox } from "../combobox"
-import { LoadingSpinner } from "../loadingspinner"
+} from "~/components/ui/popover"
+import { cn } from "~/lib/utils"
import { FormSchema } from "./schema"
import type { CultivationsFormProps } from "./types"
diff --git a/fdm-app/app/components/custom/cultivation/list.tsx b/fdm-app/app/components/custom/cultivation/list.tsx
index 35ed9ce8a..c8ebaca67 100644
--- a/fdm-app/app/components/custom/cultivation/list.tsx
+++ b/fdm-app/app/components/custom/cultivation/list.tsx
@@ -1,8 +1,8 @@
-import { Button } from "@/components/ui/button"
import { format } from "date-fns/format"
import { Pencil, Trash2 } from "lucide-react"
import { NavLink, useFetcher } from "react-router"
-import { LoadingSpinner } from "../loadingspinner"
+import { LoadingSpinner } from "~/components/custom/loadingspinner"
+import { Button } from "~/components/ui/button"
import type { Cultivation } from "./types"
interface Harvest {
diff --git a/fdm-app/app/components/custom/error.tsx b/fdm-app/app/components/custom/error.tsx
index 871bb1a4a..4206dc1e9 100644
--- a/fdm-app/app/components/custom/error.tsx
+++ b/fdm-app/app/components/custom/error.tsx
@@ -1,7 +1,7 @@
import { ArrowLeft, Copy, Home } from "lucide-react"
import { useEffect, useState } from "react"
import { NavLink } from "react-router"
-import { Button } from "../ui/button"
+import { Button } from "~/components/ui/button"
/**
* Displays a full-screen error block with tailored messaging and navigation options.
diff --git a/fdm-app/app/components/custom/farm/farm-content.tsx b/fdm-app/app/components/custom/farm/farm-content.tsx
index 575cae807..8f578f607 100644
--- a/fdm-app/app/components/custom/farm/farm-content.tsx
+++ b/fdm-app/app/components/custom/farm/farm-content.tsx
@@ -1,9 +1,9 @@
+import type { ReactNode } from "react"
+import { Outlet } from "react-router"
import {
SidebarPage,
type SidebarPageProps,
-} from "@/components/custom/sidebar-page"
-import type { ReactNode } from "react"
-import { Outlet } from "react-router"
+} from "~/components/custom/sidebar-page"
interface FarmContentProps {
sidebarItems?: SidebarPageProps["items"]
diff --git a/fdm-app/app/components/custom/farm/farm-header.tsx b/fdm-app/app/components/custom/farm/farm-header.tsx
index 060db55ee..ce5c41f3b 100644
--- a/fdm-app/app/components/custom/farm/farm-header.tsx
+++ b/fdm-app/app/components/custom/farm/farm-header.tsx
@@ -1,24 +1,23 @@
+import { ChevronDown } from "lucide-react"
+import { NavLink } from "react-router"
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbSeparator,
-} from "@/components/ui/breadcrumb"
-import { Separator } from "@/components/ui/separator"
-import { SidebarTrigger } from "@/components/ui/sidebar"
-
-import { Button } from "@/components/ui/button"
+} from "~/components/ui/breadcrumb"
+import { Button } from "~/components/ui/button"
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuTrigger,
-} from "@/components/ui/dropdown-menu"
-import { cn } from "@/lib/utils"
-import { useCalendarStore } from "@/store/calendar"
-import { ChevronDown } from "lucide-react"
-import { NavLink } from "react-router"
+} from "~/components/ui/dropdown-menu"
+import { Separator } from "~/components/ui/separator"
+import { SidebarTrigger } from "~/components/ui/sidebar"
+import { cn } from "~/lib/utils"
+import { useCalendarStore } from "~/store/calendar"
import type {
FarmOptions,
FertilizerOption,
diff --git a/fdm-app/app/components/custom/farm/farm-pagination.tsx b/fdm-app/app/components/custom/farm/farm-pagination.tsx
index bf34254e4..c8311d5b8 100644
--- a/fdm-app/app/components/custom/farm/farm-pagination.tsx
+++ b/fdm-app/app/components/custom/farm/farm-pagination.tsx
@@ -3,7 +3,7 @@ import {
PaginationContent,
PaginationItem,
PaginationLink,
-} from "@/components/ui/pagination"
+} from "~/components/ui/pagination"
import type { PaginationItems } from "./farm.d"
interface PaginationLayoutProps {
diff --git a/fdm-app/app/components/custom/farm/farm-title.tsx b/fdm-app/app/components/custom/farm/farm-title.tsx
index e4946e7d2..4dc581312 100644
--- a/fdm-app/app/components/custom/farm/farm-title.tsx
+++ b/fdm-app/app/components/custom/farm/farm-title.tsx
@@ -1,4 +1,4 @@
-import { Separator } from "@/components/ui/separator"
+import { Separator } from "~/components/ui/separator"
interface FarmTitleProps {
title: string
diff --git a/fdm-app/app/components/custom/fertilizer-applications.tsx b/fdm-app/app/components/custom/fertilizer-applications.tsx
index a104116a2..5aaa72066 100644
--- a/fdm-app/app/components/custom/fertilizer-applications.tsx
+++ b/fdm-app/app/components/custom/fertilizer-applications.tsx
@@ -1,6 +1,16 @@
-import { Combobox } from "@/components/custom/combobox"
-import { Button } from "@/components/ui/button"
-import { Calendar } from "@/components/ui/calendar"
+import { zodResolver } from "@hookform/resolvers/zod"
+import { format } from "date-fns"
+import { CalendarIcon } from "lucide-react"
+import { useEffect } from "react"
+import { Form, useFetcher } from "react-router"
+import { RemixFormProvider, useRemixForm } from "remix-hook-form"
+import type { z } from "zod"
+import { Combobox } from "~/components/custom/combobox"
+import { FormSchema } from "~/components/custom/fertilizer-applications/formschema"
+import type { FertilizerApplicationsFormProps } from "~/components/custom/fertilizer-applications/types.d"
+import { LoadingSpinner } from "~/components/custom/loadingspinner"
+import { Button } from "~/components/ui/button"
+import { Calendar } from "~/components/ui/calendar"
import {
FormControl,
FormDescription,
@@ -8,25 +18,15 @@ import {
FormItem,
FormLabel,
FormMessage,
-} from "@/components/ui/form"
-import { Input } from "@/components/ui/input"
+} from "~/components/ui/form"
+import { Input } from "~/components/ui/input"
import {
Popover,
PopoverContent,
PopoverTrigger,
-} from "@/components/ui/popover"
-import { Separator } from "@/components/ui/separator"
-import { cn } from "@/lib/utils"
-import { zodResolver } from "@hookform/resolvers/zod"
-import { format } from "date-fns"
-import { CalendarIcon } from "lucide-react"
-import { useEffect } from "react"
-import { Form, useFetcher } from "react-router"
-import { RemixFormProvider, useRemixForm } from "remix-hook-form"
-import type { z } from "zod"
-import { FormSchema } from "./fertilizer-applications/formschema"
-import type { FertilizerApplicationsFormProps } from "./fertilizer-applications/types.d"
-import { LoadingSpinner } from "./loadingspinner"
+} from "~/components/ui/popover"
+import { Separator } from "~/components/ui/separator"
+import { cn } from "~/lib/utils"
export function FertilizerApplicationsForm(
props: FertilizerApplicationsFormProps,
diff --git a/fdm-app/app/components/custom/fertilizer-applications/cards.tsx b/fdm-app/app/components/custom/fertilizer-applications/cards.tsx
index 9c0dda288..84c3d4755 100644
--- a/fdm-app/app/components/custom/fertilizer-applications/cards.tsx
+++ b/fdm-app/app/components/custom/fertilizer-applications/cards.tsx
@@ -1,13 +1,13 @@
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
+import type { Dose } from "@svenvw/fdm-calculator"
+import { Lightbulb, Scale } from "lucide-react"
+import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card"
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
-} from "@/components/ui/tooltip"
-import { cn } from "@/lib/utils"
-import type { Dose } from "@svenvw/fdm-calculator"
-import { Lightbulb, Scale } from "lucide-react"
+} from "~/components/ui/tooltip"
+import { cn } from "~/lib/utils"
import type { FertilizerApplicationsCardProps } from "./types.d"
function FertilizerApplicationsCard({
diff --git a/fdm-app/app/components/custom/fertilizer-applications/form.tsx b/fdm-app/app/components/custom/fertilizer-applications/form.tsx
index d87d42524..8874a1f25 100644
--- a/fdm-app/app/components/custom/fertilizer-applications/form.tsx
+++ b/fdm-app/app/components/custom/fertilizer-applications/form.tsx
@@ -1,5 +1,13 @@
-import { Button } from "@/components/ui/button"
-import { Calendar } from "@/components/ui/calendar"
+import { zodResolver } from "@hookform/resolvers/zod"
+import { format } from "date-fns"
+import { nl } from "date-fns/locale/nl"
+import { CalendarIcon } from "lucide-react"
+import { useEffect } from "react"
+import { Form } from "react-hook-form"
+import { RemixFormProvider, useRemixForm } from "remix-hook-form"
+import type { z } from "zod"
+import { Button } from "~/components/ui/button"
+import { Calendar } from "~/components/ui/calendar"
import {
FormControl,
FormDescription,
@@ -7,22 +15,14 @@ import {
FormItem,
FormLabel,
FormMessage,
-} from "@/components/ui/form"
-import { Input } from "@/components/ui/input"
+} from "~/components/ui/form"
+import { Input } from "~/components/ui/input"
import {
Popover,
PopoverContent,
PopoverTrigger,
-} from "@/components/ui/popover"
-import { cn } from "@/lib/utils"
-import { zodResolver } from "@hookform/resolvers/zod"
-import { format } from "date-fns"
-import { nl } from "date-fns/locale/nl"
-import { CalendarIcon } from "lucide-react"
-import { useEffect } from "react"
-import { Form } from "react-hook-form"
-import { RemixFormProvider, useRemixForm } from "remix-hook-form"
-import type { z } from "zod"
+} from "~/components/ui/popover"
+import { cn } from "~/lib/utils"
import { Combobox } from "../combobox"
import { LoadingSpinner } from "../loadingspinner"
import { FormSchema } from "./formschema"
diff --git a/fdm-app/app/components/custom/fertilizer-applications/list.tsx b/fdm-app/app/components/custom/fertilizer-applications/list.tsx
index 585002496..fdefcf577 100644
--- a/fdm-app/app/components/custom/fertilizer-applications/list.tsx
+++ b/fdm-app/app/components/custom/fertilizer-applications/list.tsx
@@ -1,5 +1,5 @@
-import { Button } from "@/components/ui/button"
import { format } from "date-fns"
+import { Button } from "~/components/ui/button"
import { LoadingSpinner } from "../loadingspinner"
import type { FertilizerApplication } from "./types.d"
diff --git a/fdm-app/app/components/custom/fertilizer/column-header.tsx b/fdm-app/app/components/custom/fertilizer/column-header.tsx
index dff88df81..27922207e 100644
--- a/fdm-app/app/components/custom/fertilizer/column-header.tsx
+++ b/fdm-app/app/components/custom/fertilizer/column-header.tsx
@@ -1,15 +1,14 @@
import type { Column } from "@tanstack/react-table"
import { ArrowDown, ArrowUp, ChevronsUpDown, EyeOff } from "lucide-react"
-
-import { Button } from "@/components/ui/button"
+import { Button } from "~/components/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
-} from "@/components/ui/dropdown-menu"
-import { cn } from "@/lib/utils"
+} from "~/components/ui/dropdown-menu"
+import { cn } from "~/lib/utils"
interface DataTableColumnHeaderProps
+ Let op! +
++ {`${clientConfig.name} is nog in ontwikkeling. Functionaliteiten + kunnen nog ontbreken of veranderen.`} +
+