@innspel/react-native 0.10.1 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/InnspelProvider.tsx
2
2
  import { createContext as createContext3, useCallback as useCallback3, useContext as useContext4, useMemo as useMemo4, useRef as useRef5, useState as useState5 } from "react";
3
- import { View as View9 } from "react-native";
3
+ import { View as View10 } from "react-native";
4
4
 
5
5
  // src/skjermbilde.ts
6
6
  import { createContext, useContext } from "react";
@@ -74,6 +74,7 @@ var t = {
74
74
  onActionPrimary: "#04252A",
75
75
  actionSecondaryBorder: "#7C8894",
76
76
  actionSecondaryText: "#F2F4F6",
77
+ actionText: "#5AD3E2",
77
78
  brand: "#5AD3E2",
78
79
  onBrand: "#04252A",
79
80
  brandFill: "#0E7C8C",
@@ -161,6 +162,7 @@ var light = {
161
162
  onActionPrimary: "#FFFFFF",
162
163
  actionSecondaryBorder: "#6F7883",
163
164
  actionSecondaryText: "#14181D",
165
+ actionText: "#0A6673",
164
166
  brand: "#0A6673",
165
167
  onBrand: "#FFFFFF",
166
168
  brandFill: "#0A6673",
@@ -356,7 +358,7 @@ import {
356
358
  InnspelQueueFullError
357
359
  } from "@innspel/core";
358
360
  import { useCallback as useCallback2, useContext as useContext3, useEffect as useEffect2, useRef as useRef4, useState as useState4 } from "react";
359
- import { KeyboardAvoidingView, Modal, Pressable as Pressable6, View as View8 } from "react-native";
361
+ import { KeyboardAvoidingView, Modal, Pressable as Pressable5, View as View9 } from "react-native";
360
362
  import { initialWindowMetrics, SafeAreaInsetsContext } from "react-native-safe-area-context";
361
363
 
362
364
  // src/Ikon.tsx
@@ -387,12 +389,21 @@ var calendar_outline_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox=
387
389
  // ../../node_modules/ionicons/dist/svg/camera-outline.svg
388
390
  var camera_outline_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="ionicon"><path d="m350.54 148.68-26.62-42.06C318.31 100.08 310.62 96 302 96h-92c-8.62 0-16.31 4.08-21.92 10.62l-26.62 42.06C155.85 155.23 148.62 160 140 160H80a32 32 0 0 0-32 32v192a32 32 0 0 0 32 32h352a32 32 0 0 0 32-32V192a32 32 0 0 0-32-32h-59c-8.65 0-16.85-4.77-22.46-11.32" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/><circle cx="256" cy="272" r="80" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/><path d="M124 158v-22h-24v22" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/></svg>';
389
391
 
392
+ // ../../node_modules/ionicons/dist/svg/chatbox-outline.svg
393
+ var chatbox_outline_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="ionicon"><path d="M408 64H104a56.16 56.16 0 0 0-56 56v192a56.16 56.16 0 0 0 56 56h40v80l93.72-78.14a8 8 0 0 1 5.13-1.86H408a56.16 56.16 0 0 0 56-56V120a56.16 56.16 0 0 0-56-56Z" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32px"/></svg>';
394
+
390
395
  // ../../node_modules/ionicons/dist/svg/checkmark-circle-outline.svg
391
396
  var checkmark_circle_outline_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="ionicon"><path d="M448 256c0-106-86-192-192-192S64 150 64 256s86 192 192 192 192-86 192-192Z" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32px"/><path d="M352 176 217.6 336 160 272" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/></svg>';
392
397
 
398
+ // ../../node_modules/ionicons/dist/svg/checkmark-outline.svg
399
+ var checkmark_outline_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="ionicon"><path d="M416 128 192 384l-96-96" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px"/></svg>';
400
+
393
401
  // ../../node_modules/ionicons/dist/svg/chevron-down-outline.svg
394
402
  var chevron_down_outline_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="ionicon"><path d="m112 184 144 144 144-144" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48px"/></svg>';
395
403
 
404
+ // ../../node_modules/ionicons/dist/svg/chevron-forward-outline.svg
405
+ var chevron_forward_outline_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="ionicon"><path d="m184 112 144 144-144 144" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48px"/></svg>';
406
+
396
407
  // ../../node_modules/ionicons/dist/svg/chevron-up-outline.svg
397
408
  var chevron_up_outline_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="ionicon"><path d="m112 328 144-144 144 144" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48px"/></svg>';
398
409
 
@@ -470,8 +481,14 @@ var IKONER = Object.fromEntries(
470
481
  "bug-outline": bug_outline_default,
471
482
  "calendar-outline": calendar_outline_default,
472
483
  "camera-outline": camera_outline_default,
484
+ // «Send» og «Send nytt innspill» — ikonkartet i wireframen (R8.3).
485
+ "chatbox-outline": chatbox_outline_default,
473
486
  "checkmark-circle-outline": checkmark_circle_outline_default,
487
+ // Haken ALENE: sporingslinjens passerte ledd er allerede en sirkel (R8.3).
488
+ "checkmark-outline": checkmark_outline_default,
474
489
  "chevron-down-outline": chevron_down_outline_default,
490
+ // Sporvalgets rader peker videre (R8.3, DD-63) — dekorativ, etiketten bærer meningen.
491
+ "chevron-forward-outline": chevron_forward_outline_default,
475
492
  "chevron-up-outline": chevron_up_outline_default,
476
493
  "close-circle-outline": close_circle_outline_default,
477
494
  "close-outline": close_outline_default,
@@ -544,9 +561,9 @@ function Btn({
544
561
  const tema = useTema();
545
562
  const c = tema.color;
546
563
  const forbi = useTrykkForbiForelder(onPress, !!disabled, tema.touch / 2);
547
- const bakgrunn = variant === "primary" ? c.actionPrimary : variant === "secondary" ? c.surfaceRaised : "transparent";
548
- const tekstfarge = variant === "primary" ? c.onActionPrimary : variant === "danger" ? c.danger : c.actionSecondaryText;
549
- const kant = variant === "ghost" ? "transparent" : variant === "primary" ? c.actionPrimary : c.actionSecondaryBorder;
564
+ const bakgrunn = variant === "primary" ? c.actionPrimary : variant === "tonet" ? c.brandBg : variant === "secondary" ? c.surfaceRaised : "transparent";
565
+ const tekstfarge = variant === "primary" ? c.onActionPrimary : variant === "tonet" ? c.brand : variant === "danger" ? c.danger : c.actionSecondaryText;
566
+ const kant = variant === "ghost" || variant === "tonet" ? "transparent" : variant === "primary" ? c.actionPrimary : c.actionSecondaryBorder;
550
567
  return /* @__PURE__ */ jsxs(View, { style: grow ? { flex: 1 } : void 0, children: [
551
568
  /* @__PURE__ */ jsxs(
552
569
  Pressable,
@@ -621,34 +638,151 @@ function useTrykkForbiForelder(onPress, laast, slingring) {
621
638
  [slingring]
622
639
  );
623
640
  }
624
- function H({ children, sub }) {
641
+ function H({
642
+ children,
643
+ sub,
644
+ meta,
645
+ nivaa = 2,
646
+ testID
647
+ }) {
625
648
  const tema = useTema();
626
- return /* @__PURE__ */ jsxs(View, { style: { gap: tema.space.xs }, children: [
627
- /* @__PURE__ */ jsx2(
628
- Text,
629
- {
630
- accessibilityRole: "header",
631
- style: {
632
- color: tema.color.textPrimary,
633
- fontSize: tema.font.h2,
634
- lineHeight: tema.lineHeight.h2,
635
- fontWeight: tema.weight.semibold
636
- },
637
- children
638
- }
639
- ),
640
- sub ? /* @__PURE__ */ jsx2(
641
- Text,
642
- {
643
- style: {
644
- color: tema.color.textSecondary,
645
- fontSize: tema.font.small,
646
- lineHeight: tema.lineHeight.small
647
- },
648
- children: sub
649
- }
650
- ) : null
651
- ] });
649
+ return (
650
+ /*
651
+ * `ark-tittel` er ETT fast punkt i arket, likt i hvert steg (#304): iOS-flytene lukker
652
+ * tastaturet med et trykk på tomt område fordi Maestros `hideKeyboard` ikke finnes der,
653
+ * og det var settets eneste koordinatavhengige linje. Bare skjermens EGEN overskrift
654
+ * (`nivaa` 2) får den — en overskrift inne i et kort eller en dialog er `nivaa` 3, og to
655
+ * like testID-er på skjermen gjør flyten tvetydig. Den valgfrie `testID` står fortsatt
656
+ * på teksten, så ingen eksisterende flyt eller test flytter seg.
657
+ */
658
+ /* @__PURE__ */ jsxs(View, { testID: nivaa === 2 ? "ark-tittel" : void 0, style: { gap: tema.space.xs }, children: [
659
+ /* @__PURE__ */ jsx2(
660
+ Text,
661
+ {
662
+ testID,
663
+ accessibilityRole: "header",
664
+ style: {
665
+ color: tema.color.textPrimary,
666
+ fontSize: nivaa === 2 ? tema.font.h2 : tema.font.h3,
667
+ lineHeight: nivaa === 2 ? tema.lineHeight.h2 : tema.lineHeight.h3,
668
+ fontWeight: tema.weight.bold
669
+ },
670
+ children
671
+ }
672
+ ),
673
+ sub ? /* @__PURE__ */ jsx2(Sek, { children: sub }) : null,
674
+ meta ? /* @__PURE__ */ jsx2(Meta, { children: meta }) : null
675
+ ] })
676
+ );
677
+ }
678
+ function Brodtekst({ children, testID }) {
679
+ const tema = useTema();
680
+ return /* @__PURE__ */ jsx2(
681
+ Text,
682
+ {
683
+ testID,
684
+ style: { color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body },
685
+ children
686
+ }
687
+ );
688
+ }
689
+ function Sek({ children, testID }) {
690
+ const tema = useTema();
691
+ return /* @__PURE__ */ jsx2(
692
+ Text,
693
+ {
694
+ testID,
695
+ style: { color: tema.color.textSecondary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body },
696
+ children
697
+ }
698
+ );
699
+ }
700
+ function Helt({
701
+ children,
702
+ testID,
703
+ farge,
704
+ live
705
+ }) {
706
+ const tema = useTema();
707
+ return /* @__PURE__ */ jsx2(
708
+ Text,
709
+ {
710
+ testID,
711
+ ...live ? { accessibilityRole: "alert", accessibilityLiveRegion: "polite" } : {},
712
+ style: {
713
+ color: farge ?? tema.color.textPrimary,
714
+ fontSize: tema.font.h1,
715
+ lineHeight: tema.lineHeight.h1,
716
+ fontWeight: tema.weight.bold
717
+ },
718
+ children
719
+ }
720
+ );
721
+ }
722
+ function Meta({ children, testID, farge }) {
723
+ const tema = useTema();
724
+ return /* @__PURE__ */ jsx2(
725
+ Text,
726
+ {
727
+ testID,
728
+ style: { color: farge ?? tema.color.textMuted, fontSize: tema.font.small, lineHeight: tema.lineHeight.small },
729
+ children
730
+ }
731
+ );
732
+ }
733
+ function Tekstknapp({
734
+ label,
735
+ ikon,
736
+ onPress,
737
+ noytral,
738
+ disabled,
739
+ testID,
740
+ accessibilityLabel
741
+ }) {
742
+ const tema = useTema();
743
+ const farge = disabled ? tema.color.textDisabled : noytral ? tema.color.textPrimary : tema.color.actionText;
744
+ return /* @__PURE__ */ jsxs(
745
+ Pressable,
746
+ {
747
+ testID,
748
+ accessibilityRole: "button",
749
+ accessibilityLabel: accessibilityLabel ?? label,
750
+ accessibilityState: { disabled: !!disabled },
751
+ disabled,
752
+ onPress,
753
+ style: {
754
+ alignSelf: "flex-start",
755
+ minHeight: tema.touch,
756
+ flexDirection: "row",
757
+ alignItems: "center",
758
+ gap: tema.space.sm
759
+ },
760
+ children: [
761
+ ikon ? /* @__PURE__ */ jsx2(Ikon, { navn: ikon, storrelse: "minste", farge }) : null,
762
+ /* @__PURE__ */ jsx2(Text, { style: { color: farge, fontSize: tema.font.body, fontWeight: tema.weight.semibold }, children: label })
763
+ ]
764
+ }
765
+ );
766
+ }
767
+ function Pille({ children, testID }) {
768
+ const tema = useTema();
769
+ return /* @__PURE__ */ jsx2(
770
+ Text,
771
+ {
772
+ testID,
773
+ style: {
774
+ color: tema.color.info,
775
+ backgroundColor: tema.color.infoBg,
776
+ fontSize: tema.font.small,
777
+ lineHeight: tema.lineHeight.small,
778
+ fontWeight: tema.weight.semibold,
779
+ borderRadius: tema.radius.pill,
780
+ paddingHorizontal: tema.space.sm,
781
+ overflow: "hidden"
782
+ },
783
+ children
784
+ }
785
+ );
652
786
  }
653
787
  function Hint({ children }) {
654
788
  const tema = useTema();
@@ -667,12 +801,16 @@ function Hint({ children }) {
667
801
  function Card({
668
802
  children,
669
803
  dashed,
670
- style
804
+ style,
805
+ testID,
806
+ accessibilityLabel
671
807
  }) {
672
808
  const tema = useTema();
673
809
  return /* @__PURE__ */ jsx2(
674
810
  View,
675
811
  {
812
+ testID,
813
+ ...accessibilityLabel ? { accessibilityLabel } : {},
676
814
  style: [
677
815
  {
678
816
  backgroundColor: tema.color.surface,
@@ -689,12 +827,19 @@ function Card({
689
827
  }
690
828
  );
691
829
  }
692
- function StatusPill({ ikon, etikett, fg, bg }) {
830
+ function StatusPill({
831
+ ikon,
832
+ etikett,
833
+ fg,
834
+ bg,
835
+ testID
836
+ }) {
693
837
  const tema = useTema();
694
838
  const farge = (navn, reserve) => tema.color[navn] ?? reserve;
695
839
  return /* @__PURE__ */ jsxs(
696
840
  View,
697
841
  {
842
+ testID,
698
843
  style: {
699
844
  flexDirection: "row",
700
845
  alignItems: "center",
@@ -741,8 +886,8 @@ function Banner({
741
886
  style: {
742
887
  flex: 1,
743
888
  color: tema.color[tone],
744
- fontSize: tema.font.small,
745
- lineHeight: tema.lineHeight.small
889
+ fontSize: tema.font.body,
890
+ lineHeight: tema.lineHeight.body
746
891
  },
747
892
  children
748
893
  }
@@ -759,30 +904,82 @@ function saksnr(id) {
759
904
  return rest.length > 8 ? rest.slice(-4) : rest;
760
905
  }
761
906
  var stor = (s) => s ? s.charAt(0).toUpperCase() + s.slice(1) : s;
907
+ var PLATTFORM_ORD = {
908
+ android: "Android",
909
+ ios: "iOS",
910
+ web: "Web",
911
+ tvos: "TV"
912
+ };
913
+ var SPRAAK_ORD = {
914
+ nb: "Norsk (bokm\xE5l)",
915
+ nn: "Norsk (nynorsk)",
916
+ no: "Norsk",
917
+ se: "Nordsamisk",
918
+ en: "Engelsk",
919
+ sv: "Svensk",
920
+ da: "Dansk",
921
+ fi: "Finsk",
922
+ is: "Islandsk",
923
+ de: "Tysk",
924
+ nl: "Nederlandsk",
925
+ fr: "Fransk",
926
+ es: "Spansk",
927
+ it: "Italiensk",
928
+ pt: "Portugisisk",
929
+ pl: "Polsk",
930
+ lt: "Litauisk",
931
+ ru: "Russisk",
932
+ uk: "Ukrainsk",
933
+ ar: "Arabisk",
934
+ so: "Somali",
935
+ ti: "Tigrinja",
936
+ tr: "Tyrkisk",
937
+ ur: "Urdu",
938
+ fa: "Persisk",
939
+ th: "Thai",
940
+ vi: "Vietnamesisk",
941
+ zh: "Kinesisk",
942
+ ja: "Japansk",
943
+ ko: "Koreansk"
944
+ };
945
+ function plattformOrd(verdi) {
946
+ return PLATTFORM_ORD[verdi.toLowerCase()] ?? stor(verdi);
947
+ }
948
+ function spraakOrd(verdi) {
949
+ const hoved = verdi.toLowerCase().split(/[-_]/)[0] ?? verdi;
950
+ return SPRAAK_ORD[hoved] ?? stor(hoved);
951
+ }
952
+ var TALLORD = ["null", "\xE9n", "to", "tre"];
953
+ var tallord = (n) => TALLORD[n] ?? String(n);
762
954
  var tekst = {
763
955
  // 2b — første valg
764
956
  valgTittel: "Hva gjelder det?",
765
957
  sporFeil: "Noe virker ikke",
958
+ /** DD-67, produkteier 2026-09-20: dette er VALGETS tekst, ikke en hjelpetekst. */
766
959
  sporFeilUnder: "Noe er galt eller virker rart",
767
960
  sporOnske: "Jeg \xF8nsker meg noe",
768
961
  sporOnskeUnder: "Noe du savner eller vil ha annerledes",
769
- // 2c — kjente feil (DD-29, DD-30)
962
+ /**
963
+ * Anonym modus (DD-62 (3)). Portalens ordlyd, med widgetens ord. ALDRI «du er ikke logget
964
+ * inn»: anonym modus er leietakerens valg ved `init()`, og widgeten vet ikke om
965
+ * innsenderen er logget inn i vertsappen.
966
+ */
967
+ sendAnonymtHint: "Innspillet kobles ikke til deg, og du kan ikke f\xF8lge det etterp\xE5.",
968
+ // 2c — kjente feil (DD-29, DD-30). Ingen undertittel: overskriften stiller spørsmålet.
770
969
  kjenteFeilTittelFeil: "Er det dette du ser?",
771
- kjenteFeilUnderFeil: "Kjenner du igjen en av disse?",
772
970
  kjenteFeilTittelOnske: "Har noen \xF8nsket dette?",
773
- kjenteFeilUnderOnske: "Ett trykk legger deg til p\xE5 \xF8nsket \u2014 ingen ny sak.",
774
971
  svarJa: "Ja, jeg ogs\xE5",
775
972
  svarLigner: "Ligner, men ikke helt",
776
973
  svarNei: "Nei, det er noe annet",
777
974
  omvei: "Omvei:",
778
975
  rettesI: (versjon) => `Rettes i ${versjon}`,
779
976
  rettetI: (versjon) => `Rettet i ${versjon}`,
977
+ /** Hvert kort er ÉN gruppe med samlet navn; de tre svarene er knapper i den. */
978
+ kjentFeilGruppe: (tittel, status, versjon) => versjon ? `Kjent feil: ${tittel}, ${status}, ${versjon}` : `Kjent feil: ${tittel}, ${status}`,
780
979
  // 2d + 2e — feltet og kontekstlinja
781
980
  /**
782
- * «Ditt innspill», ikke «Din feil» (DD-54). «Din» festet saken til personen, og
783
- * «feil» karakteriserte den før noen hadde lest den — innsenderen leste det som
784
- * skyld. Ønskesporet beholder «Ditt ønske»: et ønske er ingen feil, og der finnes
785
- * ikke problemet. De to står aldri ved siden av hverandre; sporet velges før dette.
981
+ * «Ditt innspill», ikke «Din feil» (DD-54). «Din» festet saken til personen, og «feil»
982
+ * karakteriserte den før noen hadde lest den — innsenderen leste det som skyld.
786
983
  */
787
984
  feltLabelFeil: "Ditt innspill",
788
985
  feltLabelOnske: "Ditt \xF8nske",
@@ -794,10 +991,30 @@ var tekst = {
794
991
  /** DD-44: minimum tegn er det ENESTE kravet. */
795
992
  forKort: (min) => `Minst ${min} tegn. Ingenting annet er obligatorisk.`,
796
993
  tellerFull: " \u2014 kort og konkret holder",
797
- kontekstLinje: "Legges ved: skjerm, appversjon, plattform, OS",
798
- kontekstVis: " \u2014 Vis",
994
+ /**
995
+ * DD-05 ordrett: «Én linje «Vis» under feltet ekspanderer». Lukket er linja en
996
+ * OPPSUMMERING — den navngir det innsenderen kjenner igjen; lista er hele sannheten.
997
+ */
998
+ kontekstLinjeLukket: "Skjerm og enhet legges ved",
999
+ kontekstLinjeApen: "Dette legges ved",
1000
+ kontekstVis: "Vis",
1001
+ kontekstSkjul: "Skjul",
799
1002
  kontekstFjern: "Fjern",
800
- kontekstAldri: "Aldri: navn, e-post, telefon, posisjon eller det som st\xE5r p\xE5 skjermen.",
1003
+ kontekstFjernA11y: (etikett) => `Fjern ${etikett.toLowerCase()} fra innsendingen`,
1004
+ /** K5 — skjermens ene hjelpesetning, og bare når lista står. */
1005
+ kontekstAldri: "Aldri navn, e-post, telefon, posisjon eller det som st\xE5r p\xE5 skjermen.",
1006
+ /**
1007
+ * Etikettene er portalens: samme felt, samme ord i begge flater (DD-50, presisert
1008
+ * 2026-09-20). Fram til R8.3 sto det «Plattform» og «OS» her.
1009
+ */
1010
+ kontekstEtiketter: {
1011
+ screen: "Skjerm",
1012
+ appVersion: "Appversjon",
1013
+ platform: "Enhet",
1014
+ os: "System",
1015
+ build: "Bygg",
1016
+ locale: "Spr\xE5k"
1017
+ },
801
1018
  lenketTil: (tittel) => `Lenket til: \xAB${tittel}\xBB`,
802
1019
  fjernLenke: "Fjern lenken til den kjente feilen",
803
1020
  // 2f — skjermbilde (K4, DD-39, DD-40, DD-42)
@@ -835,11 +1052,15 @@ var tekst = {
835
1052
  monsterFjern: "Fjern",
836
1053
  monsterBehold: "Behold",
837
1054
  monsterForklaring: "Teksten endres bare hvis du trykker Fjern. Vi fjerner aldri noe stille.",
838
- // 2g — kvittering
839
- kvitteringSendt: "Sendt",
840
- kvitteringRegistrert: "Registrert",
1055
+ /* 2g — kvitteringen som KORT (DD-07, P1 (a) 2026-09-20).
1056
+ Etiketten sier hva som skjedde; HELTEN er løftets setning. */
1057
+ kvitteringSendtDato: (dato) => `Sendt ${dato}`,
1058
+ kvitteringSendtAnonymtDato: (dato) => `Sendt anonymt ${dato}`,
1059
+ kvitteringRegistrertDato: (dato) => `Registrert ${dato}`,
1060
+ kvitteringLagretDato: (dato) => `Lagret ${dato}`,
841
1061
  kvitteringFeil: "Du f\xE5r beskjed n\xE5r den er rettet, eller hvis vi trenger mer.",
842
1062
  kvitteringJaOgsa: "Du f\xE5r beskjed n\xE5r den er rettet.",
1063
+ kvitteringUnder: "Ligger under \xABMine innspill\xBB og oppdaterer seg selv.",
843
1064
  saksnummer: (nr) => `Sak ${saksnr(nr)}`,
844
1065
  tilbakeTilAppen: "Tilbake til appen",
845
1066
  /** DD-42: saken er sendt, bildet kom ikke med — aldri en blokkert innsending. */
@@ -847,9 +1068,12 @@ var tekst = {
847
1068
  tekstenErLagret: "Teksten din er lagret.",
848
1069
  vedleggFeiletBanner: "Bildet ble ikke lastet opp. Saken er sendt uten det \u2014 vil du, kan du sende et nytt innspill med bilde.",
849
1070
  saksnummerUtenVedlegg: (nr) => `Sak ${saksnr(nr)} \xB7 uten vedlegg`,
850
- // 2i — tilstander
851
- koKvitteringTittel: "Lagret \u2014 sendes n\xE5r du er p\xE5 nett",
852
- offlineBanner: "Ingen nett. Lagres og sendes automatisk \u2014 du ser det under \xABMine innspill\xBB til det er sendt.",
1071
+ /* 2i — køet uten nett (DD-41, presisert 2026-09-20). Kortet lover ikke svar, og det er
1072
+ derfor ikke kvitteringen: kvitteringen kommer når køen tømmes. */
1073
+ koIngenNett: "Ingen nett",
1074
+ koHelt: "Sendes n\xE5r du er p\xE5 nett.",
1075
+ koUnder: "Du ser den under \xABMine innspill\xBB til den er sendt.",
1076
+ offlineBanner: "Ingen nett. Lagres og sendes automatisk.",
853
1077
  offlineLagre: "Lagre \u2014 sendes n\xE5r du er p\xE5 nett",
854
1078
  /** DD-41: et skjermbilde køes aldri. */
855
1079
  offlineUtenBilde: "Skjermbilde kan ikke legges ved uten nett. Teksten sendes; bildet ble ikke lagret.",
@@ -860,18 +1084,23 @@ var tekst = {
860
1084
  /** Knappen på første steg med innspill fra før (DD-62): tallet er det som gjør den til en inngang. */
861
1085
  mineMedAntall: (n) => `Mine innspill \xB7 ${n}`,
862
1086
  mineEtikett: (n) => `Mine innspill, ${n} innspill`,
863
- mineUnder: "Status og hva du kan vente deg.",
864
- mineTom: "Du har ikke sendt noe enn\xE5.",
865
- mineIkkeSendt: "Ikke sendt enn\xE5",
866
- mineSak: (nr) => `Sak ${saksnr(nr)}`,
1087
+ mineLaster: "Henter innspillene dine",
1088
+ /** DD-19: tomheten er OVERSKRIFTEN, ikke en grå linje under tittelen. */
1089
+ mineTomTittel: "Du har ikke sendt noe enn\xE5",
1090
+ /** Ordrett portalens `mineTomHint` — én innsender, to flater, samme setning. */
1091
+ mineTomHint: (leietaker) => `Det f\xF8rste innspillet tar under et minutt. Feil eller \xF8nske \u2014 ${leietaker} svarer p\xE5 begge.`,
1092
+ mineTomHintGenerisk: "Det f\xF8rste innspillet tar under et minutt. Feil eller \xF8nske \u2014 du f\xE5r svar p\xE5 begge.",
1093
+ /** Køraden har ingen saksnummer å vise — hodet sier hva den er i stedet (DD-41). */
1094
+ mineIkkeSendtHode: (spor) => `${stor(spor)} \xB7 ikke sendt enn\xE5`,
1095
+ mineFeil: "Innspillene dine kunne ikke hentes n\xE5.",
867
1096
  /** «Feil · sak 2041» — sporet først, aldri rå id og aldri kontraktens type (DD-50). */
868
1097
  sakHode: (spor, nr) => `${stor(spor)} \xB7 sak ${saksnr(nr)}`,
869
1098
  /** F14: svaret kom siden forrige gang denne enheten viste lista. */
870
1099
  nyttSvar: "Nytt svar",
871
1100
  // Leietakeren fjernet vedlegget. Bare AT — aldri hvorfor, av hvem eller når.
872
1101
  bildeFjernet: "Bildet er fjernet.",
873
- svarFra: (leietaker) => `Svar fra ${leietaker}`,
874
- svarFraGenerisk: "Svar",
1102
+ svarFra: (leietaker, dato) => `Svar fra ${leietaker} \xB7 ${dato}`,
1103
+ svarFraGenerisk: (dato) => `Svar \xB7 ${dato}`,
875
1104
  // DD-69 — «Legg til mer»: innsenderens egne ord, ikke et svar på svaret.
876
1105
  leggTilMer: "Legg til mer",
877
1106
  leggTilMerLabel: "Legg til mer p\xE5 denne saken",
@@ -889,76 +1118,108 @@ var tekst = {
889
1118
  sendNytt: "Send nytt innspill",
890
1119
  /** Tom tilstand: det finnes ikke noe «nytt» å sende når ingenting er sendt. */
891
1120
  sendForste: "Send innspill",
892
- // 3a — invitasjonsbanneret (DD-12)
1121
+ /* Sporingslinjen (DD-08/DD-28 presisert 2026-09-20). Ordene er innsenderens, aldri
1122
+ kontraktens: ingen status-enum, ingen «deadline». Samme ord som portalen. */
1123
+ sporEtikett: "Sakens gang",
1124
+ sporSvarInnen: "Svar innen",
1125
+ /** Mottatt: fristen finnes ikke ennå, og vi lover ingen dato på en sak ingen har åpnet. */
1126
+ sporDatoenSettes: "dato kommer",
1127
+ /** Planlagt/Bygges: kontrakten har ingen leveringsdato, og DD-28 forbyr en ETA. */
1128
+ sporIngenDato: "ingen dato lovet",
1129
+ sporNaarTenantTarDen: (leietaker) => `n\xE5r ${leietaker} tar den`,
1130
+ sporNaarDenTasOpp: "n\xE5r de tar den",
1131
+ /** P3 (a), produkteier 2026-09-20. Klientregel på `deadlineAt` — ingen ny status. */
1132
+ sporFristenErGatt: "Fristen er g\xE5tt",
1133
+ // 3a — invitasjonsbanneret (DD-12). Kontakttaket står IKKE her (DD-14).
893
1134
  invitasjonRegion: "Invitasjon til betaprogram",
894
1135
  invitasjonHva: (navn) => `Vil du teste \xAB${navn}\xBB?`,
895
- invitasjonKontakter: (maks) => `Vi tar kontakt maks ${maks} ganger. Du kan g\xE5 ut n\xE5r som helst.`,
1136
+ /** Én meta-linje med det kontrakten har: antall oppgaver og perioden. */
1137
+ invitasjonMeta: (oppgaver, periode2) => `${oppgaver} oppgaver \xB7 ${periode2}`,
896
1138
  lesMer: "Les mer og bli med",
897
1139
  avvisInvitasjon: "Avvis invitasjonen",
898
1140
  // 3b — aksepten (DD-13, DD-32, DD-37)
899
- akseptHva: "Hva testes",
900
- /** DD-32: tallene på én linje, FØR forklaringen — N oppgaver · ca. M min hver · dato–dato · maks K kontakter. */
901
- akseptTall: (oppgaver, minutter, periode2, kontakter) => `${oppgaver} oppgaver \xB7 ca. ${minutter} min hver \xB7 ${periode2} \xB7 maks ${kontakter} kontakter`,
1141
+ /**
1142
+ * DD-32, presisert 2026-09-20: tallene skal være SANNE. Summen når anslagene er ulike —
1143
+ * et snitt av 5, 3 og 2 er ikke sant for noen av oppgavene.
1144
+ */
1145
+ akseptTallSum: (oppgaver, minutter, periode2) => `${oppgaver} oppgaver \xB7 ca. ${minutter} min i alt \xB7 ${periode2}`,
1146
+ akseptTallHver: (oppgaver, minutter, periode2) => `${oppgaver} oppgaver \xB7 ca. ${minutter} min hver \xB7 ${periode2}`,
902
1147
  akseptOppgaver: "Hva vi ber om",
903
1148
  akseptOppgaveTid: (minutter) => `ca. ${minutter} min`,
904
- akseptKjenteFeil: (antall) => `Kjente feil (${antall})`,
905
- akseptKjenteFeilUnder: "Disse trenger du ikke melde \u2014 vi vet om dem.",
1149
+ akseptKjenteFeil: "Kjente feil vi vet om",
906
1150
  akseptInnsamling: "Hva som samles inn",
907
- akseptInnsamlingTekst: "Skjerm, appversjon, plattform, OS og hva du svarer. Aldri navn, e-post, telefon eller posisjon.",
908
- akseptVilkar: "Les vilk\xE5rene (\xE5pnes i nettleser)",
909
- akseptVilkarHint: "Bare en lenke. Ingen avkryssing, ingen signatur \u2014 \xABBli med\xBB binder deg ikke til noe.",
910
- akseptIngenVilkar: "Ingen vilk\xE5r, ingen avtale \u2014 plattformen kjenner ikke navnet ditt og kan ikke inng\xE5 \xE9n.",
911
- akseptUtgang: "Du kan g\xE5 ut n\xE5r som helst \u2014 herfra.",
1151
+ /** Samme ord som kontekstlista (DD-50): «enhet», ikke «plattform». */
1152
+ akseptInnsamlingTekst: "Skjerm, appversjon, enhet og det du svarer. Aldri navn, e-post, telefon eller posisjon.",
1153
+ akseptVilkar: "Les vilk\xE5rene",
1154
+ /**
1155
+ * Skjermens ENE hjelpesetning: taket og utgangen i én (DD-67). «høyst N» — tallet er
1156
+ * `maxContacts`, et TAK som kan senkes og aldri heves, og antall oppfølginger er malene,
1157
+ * som kan være færre. «Vi spør tre ganger» lover noe som ikke er sant (DD-14).
1158
+ */
1159
+ akseptTakOgUtgang: (maks) => `Vi sp\xF8r h\xF8yst ${tallord(maks)} ${maks === 1 ? "gang" : "ganger"} underveis. Du kan g\xE5 ut n\xE5r som helst \u2014 ingen vilk\xE5r, ingen avtale.`,
1160
+ akseptTakOgUtgangVilkar: (maks) => `Vi sp\xF8r h\xF8yst ${tallord(maks)} ${maks === 1 ? "gang" : "ganger"} underveis. Du kan g\xE5 ut n\xE5r som helst.`,
912
1161
  bliMed: "Bli med",
913
1162
  bliMedHint: "Samtykket gjelder bare dette programmet.",
914
1163
  /** DD-12: tokenet er engangs og kom i leietakerens egen kanal — plattformen sender aldri. */
915
1164
  bliMedUtenToken: "\xC5pne lenken vi sendte deg for \xE5 bli med.",
916
1165
  akseptFeil: (arsak) => `Kunne ikke bli med: ${arsak}`,
917
- // 3c (M3.1-delen) — deltakelsen og «Gå ut» (DD-36)
1166
+ // 3c — deltakelsen og «Gå ut» (DD-36). Kontakttaket står IKKE her (DD-14).
918
1167
  deltakelseRegion: "Ditt betaprogram",
919
- deltakelsePeriode: (periode2, brukt, maks) => `${periode2} \xB7 Vi tar kontakt maks ${maks} ganger \u2014 ${brukt} brukt`,
920
- deltakelseOppgaverKommer: "Oppgavene kan gj\xF8res n\xE5r det passer deg.",
921
1168
  gaaUt: "G\xE5 ut av programmet",
922
1169
  gaaUtTittel: "G\xE5 ut av programmet?",
923
1170
  gaaUtTekst: (navn) => `Du tas ut av testgruppen med en gang. \xAB${navn}\xBB sl\xE5s av for deg, og vi tar ikke kontakt igjen. Det du allerede har svart, beholdes.`,
924
1171
  bliVaerende: "Bli v\xE6rende",
925
1172
  gaaUtBekreft: "G\xE5 ut",
926
- // 3c (M3.2) — oppgavene og «Hvordan gikk det?»: tre lukkede valg, aldri en skala
1173
+ /* Programmets sporingslinje (P1 (a), produkteier 2026-09-20): deltakelsen bæres av
1174
+ linjen, ikke av et kvitteringskort — merkefargen er for det som er SENDT (DD-41). */
1175
+ programSporEtikett: "Programmets gang",
1176
+ programBleMed: "Du ble med",
1177
+ programGjort: (gjort, av) => `${gjort} av ${av} gjort`,
1178
+ programOver: "Programmet er over",
1179
+ /** Under nå-leddet, ÉN linje. Aldri «to igjen»: «1 av 3» sier alt tallet sier (DD-08). */
1180
+ programNaarDetPasser: "n\xE5r det passer",
1181
+ // 3c — oppgavene
927
1182
  oppgaverTittel: "Oppgavene",
928
- oppgaveIkkeBegynt: "Ikke begynt",
929
1183
  oppgaveGjort: "Gjort",
930
1184
  oppgaveGjortLabel: (tittel) => `Gjort: ${tittel}`,
931
- oppgaveGjortMed: (utfall) => `Pr\xF8vd \xB7 ${utfall}`,
1185
+ /** Oppgavens ENE meta-linje i `small` (DD-67). Setningen hennes står i `body` under. */
1186
+ oppgaveGjortMeta: (dato, utfall) => `Gjort ${dato} \xB7 ${utfall.toLowerCase()}`,
1187
+ oppgaveTid: (minutter, skjerm) => `ca. ${minutter} min${skjerm ? ` \xB7 ${skjerm}` : ""}`,
1188
+ oppgaveUbekreftet: "Svaret ble ikke bekreftet \u2014 merk den p\xE5 nytt",
1189
+ oppgaveRadA11y: (nr, tittel, status) => `Oppgave ${nr}: ${tittel}, ${status}`,
1190
+ oppgaveIkkeGjort: "ikke gjort",
1191
+ // 3e — «Hvordan gikk det?»: tre lukkede valg, aldri en skala (DD-15)
932
1192
  hvordanGikkDet: "Hvordan gikk det?",
933
1193
  utfallFungerte: "Fungerte",
934
1194
  utfallDelvis: "Fungerte delvis",
935
1195
  utfallIkke: "Fungerte ikke",
936
- setningLabel: "Vil du si \xE9n setning om det? (valgfritt)",
937
- setningPlaceholder: "Kopien kom, men rullesjefen manglet p\xE5 torsdag.",
1196
+ setningLabel: "Vil du si \xE9n setning om det?",
1197
+ setningValgfritt: "Valgfritt",
938
1198
  lagre: "Lagre",
939
- lagreHint: "Ferdig \u2014 ingen flere sp\xF8rsm\xE5l n\xE5.",
940
1199
  /** Etter «Ikke»: feilsporet er vertens — plattformen navigerer aldri selv. */
941
1200
  meldFeil: "Meld det som feil",
942
- meldFeilHint: "Gikk det ikke? Et innspill hjelper oss \xE5 finne ut hvorfor.",
943
1201
  svarFeil: (arsak) => `Kunne ikke lagre svaret: ${arsak}`,
944
- // 3d (M3.2) — oppfølgingskortene (DD-34): arten avgjør knappene
1202
+ // 3d — oppfølgingskortene (DD-34): arten avgjør knappene. Ingen kontaktnummer (DD-14).
945
1203
  oppfolgingRegion: "Oppf\xF8lging fra betaprogrammet",
946
- oppfolgingKontakt: (nr, maks) => `Kontakt ${nr} av ${maks} \xB7 tar under ett minutt`,
947
- oppfolgingPaaminnelseHint: (nr, maks) => `Kontakt ${nr} av ${maks} \xB7 planlagt p\xE5minnelse`,
948
- oppfolgingUtgangHint: (nr, maks) => `Kontakt ${nr} av ${maks} \xB7 den siste vi sender`,
1204
+ oppfolgingKost: "Ett sp\xF8rsm\xE5l \xB7 tar under ett minutt",
949
1205
  senere: "Senere",
950
1206
  svarNaa: "Svar n\xE5",
951
1207
  aapneOppgavene: "\xC5pne oppgavene",
952
1208
  // Felles
953
1209
  tilbake: "Tilbake",
954
1210
  lukk: "Lukk",
955
- venterPaaNett: "Venter p\xE5 nett \u2014 sendes automatisk",
1211
+ venterPaaNett: "Venter p\xE5 nett",
956
1212
  feil: "feil",
957
1213
  onske: "\xF8nske"
958
1214
  };
959
1215
  var lofte = {
960
- venterNett: "Sendes automatisk n\xE5r du er p\xE5 nett \u2014 kvitteringen kommer da."
1216
+ venterNett: "Sendes automatisk n\xE5r du er p\xE5 nett."
961
1217
  };
1218
+ function kontekstVerdi(felt, verdi) {
1219
+ if (felt === "platform") return plattformOrd(verdi);
1220
+ if (felt === "locale") return spraakOrd(verdi);
1221
+ return verdi;
1222
+ }
962
1223
 
963
1224
  // src/widget/Felt.tsx
964
1225
  import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
@@ -992,20 +1253,13 @@ function Felt({
992
1253
  const full = brukt >= textMaxLength;
993
1254
  const visTeller = brukt >= textMaxLength * 0.8;
994
1255
  const uavklart = funn.find((f) => !beholdt.includes(f.match));
995
- const linjer = useMemo2(() => {
996
- const etiketter = {
997
- screen: "Skjerm",
998
- appVersion: "Appversjon",
999
- platform: "Plattform",
1000
- os: "OS",
1001
- build: "Bygg",
1002
- locale: "Spr\xE5k"
1003
- };
1004
- return Object.entries(etiketter).map(([felt, etikett]) => {
1005
- const verdi2 = kontekst[felt];
1006
- return verdi2 && !fjernedeFelter.includes(felt) ? { felt, etikett, verdi: verdi2 } : null;
1007
- }).filter((x) => x !== null);
1008
- }, [kontekst, fjernedeFelter]);
1256
+ const linjer = useMemo2(
1257
+ () => Object.entries(tekst.kontekstEtiketter).map(([felt, etikett]) => {
1258
+ const r\u00E5 = kontekst[felt];
1259
+ return r\u00E5 && !fjernedeFelter.includes(felt) ? { felt, etikett, verdi: kontekstVerdi(felt, r\u00E5) } : null;
1260
+ }).filter((x) => x !== null),
1261
+ [kontekst, fjernedeFelter]
1262
+ );
1009
1263
  return /* @__PURE__ */ jsxs2(View2, { testID: "skjema", style: { flexGrow: 1, flexShrink: 1, gap: tema.space.md }, children: [
1010
1264
  /* @__PURE__ */ jsxs2(
1011
1265
  ScrollView,
@@ -1062,8 +1316,8 @@ function Felt({
1062
1316
  accessibilityLiveRegion: "polite",
1063
1317
  style: {
1064
1318
  color: tema.color.warning,
1065
- fontSize: tema.font.small,
1066
- lineHeight: tema.lineHeight.small,
1319
+ fontSize: tema.font.body,
1320
+ lineHeight: tema.lineHeight.body,
1067
1321
  fontWeight: tema.weight.medium
1068
1322
  },
1069
1323
  children: tekst.monsterSpm[uavklart.kind]
@@ -1200,17 +1454,16 @@ function Felt({
1200
1454
  bildeNotat ? /* @__PURE__ */ jsx3(View2, { testID: "bilde-notat", children: /* @__PURE__ */ jsx3(Hint, { children: bildeNotat }) }) : null
1201
1455
  ] })
1202
1456
  ) : null,
1203
- /* @__PURE__ */ jsxs2(View2, { style: { borderTopWidth: tema.hairline, borderTopColor: tema.color.border, paddingTop: tema.space.sm }, children: [
1204
- /* @__PURE__ */ jsx3(
1457
+ /* @__PURE__ */ jsxs2(View2, { style: { borderTopWidth: tema.hairline, borderTopColor: tema.color.border, paddingTop: tema.space.xs }, children: [
1458
+ /* @__PURE__ */ jsxs2(
1205
1459
  Pressable2,
1206
1460
  {
1207
1461
  testID: "kontekst-bryter",
1208
1462
  accessibilityRole: "button",
1209
1463
  accessibilityState: { expanded: apen },
1210
- accessibilityLabel: `${tekst.kontekstLinje}${apen ? "" : tekst.kontekstVis}`,
1211
1464
  onPress: () => setApen((a) => !a),
1212
- style: { minHeight: tema.touch, justifyContent: "center" },
1213
- children: /* @__PURE__ */ jsxs2(View2, { style: { flexDirection: "row", alignItems: "center", gap: tema.space.xs }, children: [
1465
+ style: { minHeight: tema.touch, flexDirection: "row", alignItems: "center", gap: tema.space.sm },
1466
+ children: [
1214
1467
  /* @__PURE__ */ jsx3(
1215
1468
  Ikon,
1216
1469
  {
@@ -1219,11 +1472,9 @@ function Felt({
1219
1472
  farge: tema.color.textSecondary
1220
1473
  }
1221
1474
  ),
1222
- /* @__PURE__ */ jsxs2(Text2, { style: { flex: 1, color: tema.color.textSecondary, fontSize: tema.font.small }, children: [
1223
- tekst.kontekstLinje,
1224
- apen ? "" : tekst.kontekstVis
1225
- ] })
1226
- ] })
1475
+ /* @__PURE__ */ jsx3(Text2, { style: { flex: 1, color: tema.color.textSecondary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }, children: apen ? tekst.kontekstLinjeApen : tekst.kontekstLinjeLukket }),
1476
+ /* @__PURE__ */ jsx3(Text2, { style: { color: tema.color.actionText, fontSize: tema.font.body, fontWeight: tema.weight.semibold }, children: apen ? tekst.kontekstSkjul : tekst.kontekstVis })
1477
+ ]
1227
1478
  }
1228
1479
  ),
1229
1480
  apen ? /* @__PURE__ */ jsxs2(View2, { children: [
@@ -1233,26 +1484,29 @@ function Felt({
1233
1484
  style: {
1234
1485
  flexDirection: "row",
1235
1486
  alignItems: "center",
1236
- gap: tema.space.sm,
1487
+ gap: tema.space.md,
1237
1488
  minHeight: tema.touch,
1238
- borderBottomWidth: tema.hairline,
1239
- borderBottomColor: tema.color.border
1489
+ borderTopWidth: tema.hairline,
1490
+ borderTopColor: tema.color.border
1240
1491
  },
1241
1492
  children: [
1242
- /* @__PURE__ */ jsx3(Text2, { style: { color: tema.color.textMuted, fontSize: tema.font.small, minWidth: tema.touch * 2 }, children: l.etikett }),
1243
- /* @__PURE__ */ jsx3(Text2, { style: { flex: 1, color: tema.color.textPrimary, fontSize: tema.font.small }, children: l.verdi }),
1493
+ /* @__PURE__ */ jsx3(Meta, { testID: `kontekst-etikett-${l.felt}`, children: l.etikett }),
1494
+ /* @__PURE__ */ jsx3(View2, { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsx3(
1495
+ Text2,
1496
+ {
1497
+ testID: `kontekst-verdi-${l.felt}`,
1498
+ style: { color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body, fontWeight: tema.weight.semibold },
1499
+ children: l.verdi
1500
+ }
1501
+ ) }),
1244
1502
  /* @__PURE__ */ jsx3(
1245
- Pressable2,
1503
+ Tekstknapp,
1246
1504
  {
1247
1505
  testID: `fjern-${l.felt}`,
1248
- accessibilityRole: "button",
1249
- accessibilityLabel: `${tekst.kontekstFjern} ${l.etikett.toLowerCase()} fra innsendingen`,
1250
- onPress: () => onFjernKontekst(l.felt),
1251
- style: { minWidth: tema.touch, minHeight: tema.touch, alignItems: "center", justifyContent: "center" },
1252
- children: /* @__PURE__ */ jsxs2(View2, { style: { flexDirection: "row", alignItems: "center", gap: tema.space.xs }, children: [
1253
- /* @__PURE__ */ jsx3(Ikon, { navn: "close-outline", storrelse: "minste", farge: tema.color.textSecondary }),
1254
- /* @__PURE__ */ jsx3(Text2, { style: { color: tema.color.textSecondary, fontSize: tema.font.small }, children: tekst.kontekstFjern })
1255
- ] })
1506
+ ikon: "close-outline",
1507
+ label: tekst.kontekstFjern,
1508
+ accessibilityLabel: tekst.kontekstFjernA11y(l.etikett),
1509
+ onPress: () => onFjernKontekst(l.felt)
1256
1510
  }
1257
1511
  )
1258
1512
  ]
@@ -1284,26 +1538,23 @@ function Felt({
1284
1538
  import "react";
1285
1539
  import { Pressable as Pressable3, Text as Text3, View as View3 } from "react-native";
1286
1540
  import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1287
- function Valg({ onVelg }) {
1541
+ function Valg({ onVelg, anonym }) {
1288
1542
  const tema = useTema();
1289
- const flate = (spor, ikon, label, under) => /* @__PURE__ */ jsxs3(
1543
+ const rad = (spor, ikon, label, under, forst) => /* @__PURE__ */ jsxs3(
1290
1544
  Pressable3,
1291
1545
  {
1292
1546
  testID: `spor-${spor}`,
1293
1547
  accessibilityRole: "button",
1294
- accessibilityLabel: `${label}. ${under}`,
1548
+ accessibilityLabel: `${label}, ${under}`,
1295
1549
  onPress: () => onVelg(spor),
1296
1550
  style: {
1297
- flex: 1,
1298
- minHeight: tema.touch * 3,
1299
- backgroundColor: tema.color.surface,
1300
- borderWidth: tema.hairline,
1301
- borderColor: tema.color.borderStrong,
1302
- borderRadius: tema.radius.lg,
1551
+ flexDirection: "row",
1303
1552
  alignItems: "center",
1304
- justifyContent: "center",
1305
- gap: tema.space.sm,
1306
- padding: tema.space.md
1553
+ gap: tema.space.md,
1554
+ minHeight: tema.touch + tema.space.lg,
1555
+ paddingVertical: tema.space.sm,
1556
+ borderTopWidth: forst ? 0 : tema.hairline,
1557
+ borderTopColor: tema.color.border
1307
1558
  },
1308
1559
  children: [
1309
1560
  /* @__PURE__ */ jsx4(
@@ -1311,8 +1562,8 @@ function Valg({ onVelg }) {
1311
1562
  {
1312
1563
  testID: `spor-${spor}-ikonflate`,
1313
1564
  style: {
1314
- width: 2 * tema.icon.inline + 2 * tema.space.md,
1315
- height: 2 * tema.icon.inline + 2 * tema.space.md,
1565
+ width: tema.touch + tema.space.sm,
1566
+ height: tema.touch + tema.space.sm,
1316
1567
  borderRadius: tema.radius.pill,
1317
1568
  backgroundColor: tema.color.brandBg,
1318
1569
  alignItems: "center",
@@ -1321,28 +1572,21 @@ function Valg({ onVelg }) {
1321
1572
  children: /* @__PURE__ */ jsx4(Ikon, { navn: ikon, storrelse: "stor", farge: tema.color.brand })
1322
1573
  }
1323
1574
  ),
1324
- /* @__PURE__ */ jsx4(
1325
- Text3,
1326
- {
1327
- style: {
1328
- color: tema.color.textPrimary,
1329
- fontSize: tema.font.h3,
1330
- fontWeight: tema.weight.semibold,
1331
- textAlign: "center"
1332
- },
1333
- children: label
1334
- }
1335
- ),
1336
- /* @__PURE__ */ jsx4(Text3, { style: { color: tema.color.textMuted, fontSize: tema.font.small, textAlign: "center" }, children: under })
1575
+ /* @__PURE__ */ jsxs3(View3, { style: { flex: 1, minWidth: 0 }, children: [
1576
+ /* @__PURE__ */ jsx4(Text3, { style: { color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body, fontWeight: tema.weight.semibold }, children: label }),
1577
+ /* @__PURE__ */ jsx4(Text3, { style: { color: tema.color.textMuted, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }, children: under })
1578
+ ] }),
1579
+ /* @__PURE__ */ jsx4(Ikon, { navn: "chevron-forward-outline", storrelse: "minste", farge: tema.color.textMuted })
1337
1580
  ]
1338
1581
  }
1339
1582
  );
1340
- return /* @__PURE__ */ jsxs3(View3, { style: { flex: 1, gap: tema.space.lg }, children: [
1583
+ return /* @__PURE__ */ jsxs3(View3, { style: { gap: tema.space.lg }, children: [
1341
1584
  /* @__PURE__ */ jsx4(H, { children: tekst.valgTittel }),
1342
- /* @__PURE__ */ jsx4(View3, { style: { flex: 1, justifyContent: "flex-end" }, children: /* @__PURE__ */ jsxs3(View3, { style: { flexDirection: "row", gap: tema.space.md }, children: [
1343
- flate("feil", "bug", tekst.sporFeil, tekst.sporFeilUnder),
1344
- flate("onske", "bulb", tekst.sporOnske, tekst.sporOnskeUnder)
1345
- ] }) })
1585
+ /* @__PURE__ */ jsxs3(View3, { children: [
1586
+ rad("feil", "bug", tekst.sporFeil, tekst.sporFeilUnder, true),
1587
+ rad("onske", "bulb", tekst.sporOnske, tekst.sporOnskeUnder, false)
1588
+ ] }),
1589
+ anonym ? /* @__PURE__ */ jsx4(Hint, { children: tekst.sendAnonymtHint }) : null
1346
1590
  ] });
1347
1591
  }
1348
1592
 
@@ -1361,84 +1605,102 @@ function KjenteFeil({
1361
1605
  onNei
1362
1606
  }) {
1363
1607
  const tema = useTema();
1608
+ const tittel = spor === "onske" ? tekst.kjenteFeilTittelOnske : tekst.kjenteFeilTittelFeil;
1364
1609
  if (laster) {
1365
1610
  return /* @__PURE__ */ jsxs4(View4, { style: { flex: 1, gap: tema.space.md }, children: [
1366
- /* @__PURE__ */ jsx5(H, { sub: spor === "onske" ? tekst.kjenteFeilUnderOnske : tekst.kjenteFeilUnderFeil, children: spor === "onske" ? tekst.kjenteFeilTittelOnske : tekst.kjenteFeilTittelFeil }),
1611
+ /* @__PURE__ */ jsx5(H, { children: tittel }),
1367
1612
  /* @__PURE__ */ jsx5(ActivityIndicator, { accessibilityLabel: "Sjekker kjente feil", color: tema.color.textSecondary })
1368
1613
  ] });
1369
1614
  }
1370
1615
  return /* @__PURE__ */ jsxs4(View4, { testID: "kjente-feil", style: { flexGrow: 1, flexShrink: 1, gap: tema.space.md }, children: [
1371
- /* @__PURE__ */ jsx5(H, { sub: spor === "onske" ? tekst.kjenteFeilUnderOnske : tekst.kjenteFeilUnderFeil, children: spor === "onske" ? tekst.kjenteFeilTittelOnske : tekst.kjenteFeilTittelFeil }),
1616
+ /* @__PURE__ */ jsx5(H, { children: tittel }),
1372
1617
  /* @__PURE__ */ jsx5(
1373
1618
  ScrollView2,
1374
1619
  {
1375
1620
  testID: "kjente-feil-liste",
1376
1621
  style: { flexGrow: 0, flexShrink: 1 },
1377
- contentContainerStyle: { gap: tema.space.md },
1378
1622
  keyboardShouldPersistTaps: "handled",
1379
- children: kort.slice(0, MAKS_KORT).map((k) => {
1623
+ children: kort.slice(0, MAKS_KORT).map((k, i) => {
1380
1624
  const o = knownIssueStatus[k.status] ?? knownIssueStatus.aktiv;
1381
- const versjon = k.fixedIn ? k.status === "fikset" ? tekst.rettetI(k.fixedIn) : tekst.rettesI(k.fixedIn) : void 0;
1382
- const kontekst = versjon ? `${k.title}. ${o.etikett}. ${versjon}` : `${k.title}. ${o.etikett}`;
1383
- return /* @__PURE__ */ jsxs4(Card, { children: [
1384
- /* @__PURE__ */ jsx5(
1385
- Text4,
1386
- {
1387
- style: {
1388
- color: tema.color.textPrimary,
1389
- fontSize: tema.font.body,
1390
- lineHeight: tema.lineHeight.body,
1391
- fontWeight: tema.weight.medium
1392
- },
1393
- children: k.title
1394
- }
1395
- ),
1396
- k.workaround ? /* @__PURE__ */ jsxs4(
1397
- Text4,
1398
- {
1399
- style: {
1400
- color: tema.color.textSecondary,
1401
- fontSize: tema.font.small,
1402
- lineHeight: tema.lineHeight.small
1403
- },
1404
- children: [
1625
+ const rettet = k.status === "fikset";
1626
+ const statusOrd = rettet && k.fixedIn ? tekst.rettetI(k.fixedIn) : o.etikett;
1627
+ const tillegg = !rettet && k.fixedIn ? `\xB7 ${tekst.rettesI(k.fixedIn).toLowerCase()}` : void 0;
1628
+ const gruppe = tekst.kjentFeilGruppe(k.title, statusOrd, tillegg?.replace("\xB7 ", ""));
1629
+ return /* @__PURE__ */ jsxs4(
1630
+ View4,
1631
+ {
1632
+ testID: `kjent-feil-${k.id}`,
1633
+ style: {
1634
+ gap: tema.space.sm,
1635
+ paddingVertical: tema.space.md,
1636
+ borderTopWidth: i === 0 ? 0 : tema.hairline,
1637
+ borderTopColor: tema.color.border
1638
+ },
1639
+ children: [
1640
+ /* @__PURE__ */ jsx5(
1641
+ Text4,
1642
+ {
1643
+ testID: `kjent-feil-tittel-${k.id}`,
1644
+ style: {
1645
+ color: tema.color.textPrimary,
1646
+ fontSize: tema.font.body,
1647
+ lineHeight: tema.lineHeight.body,
1648
+ fontWeight: tema.weight.semibold
1649
+ },
1650
+ children: k.title
1651
+ }
1652
+ ),
1653
+ k.workaround ? /* @__PURE__ */ jsxs4(Sek, { testID: `kjent-feil-omvei-${k.id}`, children: [
1405
1654
  tekst.omvei,
1406
1655
  " ",
1407
1656
  k.workaround
1408
- ]
1409
- }
1410
- ) : null,
1411
- /* @__PURE__ */ jsxs4(View4, { style: { flexDirection: "row", alignItems: "center", gap: tema.space.sm, flexWrap: "wrap" }, children: [
1412
- /* @__PURE__ */ jsx5(StatusPill, { ikon: o.ikon, etikett: o.etikett, fg: o.fg, bg: o.bg }),
1413
- versjon ? /* @__PURE__ */ jsx5(Text4, { style: { color: tema.color.textSecondary, fontSize: tema.font.small }, children: versjon }) : null
1414
- ] }),
1415
- /* @__PURE__ */ jsxs4(View4, { style: { flexDirection: "row", gap: tema.space.sm }, children: [
1416
- /* @__PURE__ */ jsx5(
1417
- Btn,
1418
- {
1419
- grow: true,
1420
- testID: `ja-ogsa-${k.id}`,
1421
- label: tekst.svarJa,
1422
- accessibilityLabel: `${tekst.svarJa}. ${kontekst}`,
1423
- disabled: sender,
1424
- busy: sender,
1425
- onPress: () => onJaOgsa(k)
1426
- }
1427
- ),
1428
- /* @__PURE__ */ jsx5(
1429
- Btn,
1430
- {
1431
- grow: true,
1432
- variant: "secondary",
1433
- testID: `ligner-${k.id}`,
1434
- label: tekst.svarLigner,
1435
- accessibilityLabel: `${tekst.svarLigner}. ${kontekst}`,
1436
- disabled: sender,
1437
- onPress: () => onLigner(k)
1438
- }
1439
- )
1440
- ] })
1441
- ] }, k.id);
1657
+ ] }) : null,
1658
+ /* @__PURE__ */ jsxs4(View4, { style: { flexDirection: "row", alignItems: "center", gap: tema.space.sm, flexWrap: "wrap" }, children: [
1659
+ /* @__PURE__ */ jsxs4(View4, { style: { flexDirection: "row", alignItems: "center", gap: tema.space.xs }, children: [
1660
+ /* @__PURE__ */ jsx5(Ikon, { navn: o.ikon, storrelse: "minste", farge: tema.color[o.fg] }),
1661
+ /* @__PURE__ */ jsx5(
1662
+ Text4,
1663
+ {
1664
+ style: {
1665
+ color: tema.color[o.fg],
1666
+ fontSize: tema.font.small,
1667
+ lineHeight: tema.lineHeight.small,
1668
+ fontWeight: tema.weight.semibold
1669
+ },
1670
+ children: statusOrd
1671
+ }
1672
+ )
1673
+ ] }),
1674
+ tillegg ? /* @__PURE__ */ jsx5(Text4, { style: { color: tema.color.textMuted, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }, children: tillegg }) : null
1675
+ ] }),
1676
+ /* @__PURE__ */ jsxs4(View4, { style: { flexDirection: "row", alignItems: "center", gap: tema.space.md }, children: [
1677
+ /* @__PURE__ */ jsx5(
1678
+ Btn,
1679
+ {
1680
+ variant: "tonet",
1681
+ testID: `ja-ogsa-${k.id}`,
1682
+ label: tekst.svarJa,
1683
+ accessibilityLabel: `${tekst.svarJa}. ${gruppe}`,
1684
+ disabled: sender,
1685
+ busy: sender,
1686
+ onPress: () => onJaOgsa(k)
1687
+ }
1688
+ ),
1689
+ /* @__PURE__ */ jsx5(
1690
+ Tekstknapp,
1691
+ {
1692
+ testID: `ligner-${k.id}`,
1693
+ label: tekst.svarLigner,
1694
+ accessibilityLabel: `${tekst.svarLigner}. ${gruppe}`,
1695
+ disabled: sender,
1696
+ onPress: () => onLigner(k)
1697
+ }
1698
+ )
1699
+ ] })
1700
+ ]
1701
+ },
1702
+ k.id
1703
+ );
1442
1704
  })
1443
1705
  }
1444
1706
  ),
@@ -1448,6 +1710,10 @@ function KjenteFeil({
1448
1710
 
1449
1711
  // src/widget/Kvittering.tsx
1450
1712
  import "react";
1713
+ import { Text as Text6, View as View6 } from "react-native";
1714
+
1715
+ // src/widget/Sporingslinje.tsx
1716
+ import "react";
1451
1717
  import { Text as Text5, View as View5 } from "react-native";
1452
1718
 
1453
1719
  // src/widget/status.ts
@@ -1456,6 +1722,12 @@ function formaterFrist(iso) {
1456
1722
  if (Number.isNaN(d.getTime())) return iso;
1457
1723
  return new Intl.DateTimeFormat("nb-NO", { day: "numeric", month: "long" }).format(d);
1458
1724
  }
1725
+ var KORT_MANED = ["jan", "feb", "mar", "apr", "mai", "jun", "jul", "aug", "sep", "okt", "nov", "des"];
1726
+ function formaterKortFrist(iso) {
1727
+ const d = new Date(iso);
1728
+ if (Number.isNaN(d.getTime())) return iso;
1729
+ return `${d.getDate()}. ${KORT_MANED[d.getMonth()]}`;
1730
+ }
1459
1731
  function statusVisning(status, type, deadlineAt) {
1460
1732
  const o = submissionStatus[status];
1461
1733
  const spor = type === "onske" ? "onske" : "feil";
@@ -1479,66 +1751,265 @@ var venterVisning = {
1479
1751
  lofte: lofte.venterNett
1480
1752
  };
1481
1753
 
1482
- // src/widget/Kvittering.tsx
1754
+ // src/widget/Sporingslinje.tsx
1483
1755
  import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1756
+ var HOVEDLINJE = ["ny", "vurderes", "planlagt", "bygges", "levert"];
1757
+ function erApen(rad) {
1758
+ if (rad.pending === true) return false;
1759
+ return rad.statusType === "reviewing" || rad.statusType === "active";
1760
+ }
1761
+ function sporingsledd(rad, tenantName, naa = /* @__PURE__ */ new Date()) {
1762
+ if (rad.pending === true || !erApen(rad)) return [];
1763
+ const type = rad.type;
1764
+ const navn = (status) => statusVisning(status, type).etikett;
1765
+ const ikon = (status) => statusVisning(status, type).ikon;
1766
+ const ledd = [];
1767
+ if (rad.status === "kjent_feil") {
1768
+ ledd.push({ nokkel: "ny", etikett: navn("ny"), tilstand: "gjort", detalj: formaterFrist(rad.createdAt) });
1769
+ ledd.push({ nokkel: "kjent_feil", etikett: navn("kjent_feil"), tilstand: "naa", ikon: ikon("kjent_feil"), detalj: formaterFrist(rad.statusChangedAt) });
1770
+ ledd.push({ nokkel: "slutt", etikett: navn("levert"), tilstand: "kommer", detalj: tekst.sporIngenDato });
1771
+ return ledd;
1772
+ }
1773
+ const naaIndeks = HOVEDLINJE.indexOf(rad.status);
1774
+ if (naaIndeks < 0) return [];
1775
+ for (let i = 0; i <= naaIndeks; i++) {
1776
+ const status = HOVEDLINJE[i];
1777
+ const erNaa = i === naaIndeks;
1778
+ ledd.push({
1779
+ nokkel: status,
1780
+ etikett: navn(status),
1781
+ tilstand: erNaa ? "naa" : "gjort",
1782
+ ...erNaa ? { ikon: ikon(status) } : {},
1783
+ // Mottatt har `createdAt`, nå-leddet har `statusChangedAt`. Et passert ledd mellom dem
1784
+ // har ingen dato i kontrakten, og får derfor ingen.
1785
+ ...i === 0 ? { detalj: formaterFrist(rad.createdAt) } : erNaa ? { detalj: formaterFrist(rad.statusChangedAt) } : {}
1786
+ });
1787
+ }
1788
+ if (rad.status === "ny") {
1789
+ ledd.push({
1790
+ nokkel: "vurderes",
1791
+ etikett: navn("vurderes"),
1792
+ tilstand: "kommer",
1793
+ detalj: tenantName ? tekst.sporNaarTenantTarDen(tenantName) : tekst.sporNaarDenTasOpp
1794
+ });
1795
+ }
1796
+ if (rad.statusType === "reviewing") {
1797
+ const frist = rad.deadlineAt;
1798
+ const gatt = frist !== void 0 && rad.status === "vurderes" && new Date(frist).getTime() < naa.getTime();
1799
+ ledd.push(
1800
+ gatt ? { nokkel: "slutt", etikett: tekst.sporFristenErGatt, tilstand: "brutt", ikon: "warning-outline", tall: formaterKortFrist(frist) } : {
1801
+ nokkel: "slutt",
1802
+ etikett: tekst.sporSvarInnen,
1803
+ tilstand: "kommer",
1804
+ ...frist ? { tall: formaterKortFrist(frist) } : { detalj: tekst.sporDatoenSettes }
1805
+ }
1806
+ );
1807
+ } else {
1808
+ ledd.push({ nokkel: "slutt", etikett: navn("levert"), tilstand: "kommer", detalj: tekst.sporIngenDato });
1809
+ }
1810
+ return ledd;
1811
+ }
1812
+ function Sporingslinje({
1813
+ ledd,
1814
+ testID,
1815
+ etikett = tekst.sporEtikett
1816
+ }) {
1817
+ const tema = useTema();
1818
+ if (ledd.length === 0) return null;
1819
+ const farge = (l) => l.tilstand === "brutt" ? tema.color.warning : l.tilstand === "gjort" ? tema.color.success : l.tilstand === "naa" ? tema.color.brand : tema.color.borderStrong;
1820
+ return /* @__PURE__ */ jsx6(
1821
+ View5,
1822
+ {
1823
+ testID,
1824
+ accessibilityRole: "list",
1825
+ accessibilityLabel: etikett,
1826
+ style: { flexDirection: "row", alignItems: "flex-start", gap: tema.space.xs },
1827
+ children: ledd.map((l, i) => {
1828
+ const siste = i === ledd.length - 1;
1829
+ const c = farge(l);
1830
+ return /* @__PURE__ */ jsxs5(
1831
+ View5,
1832
+ {
1833
+ testID: testID ? `${testID}-ledd-${l.nokkel}` : void 0,
1834
+ style: siste ? { flexShrink: 0, gap: tema.space.xs } : { flex: 1, minWidth: 0, gap: tema.space.xs },
1835
+ children: [
1836
+ /* @__PURE__ */ jsxs5(View5, { style: { flexDirection: "row", alignItems: "center", gap: tema.space.xs }, children: [
1837
+ /* @__PURE__ */ jsx6(
1838
+ View5,
1839
+ {
1840
+ style: {
1841
+ width: tema.space.lg,
1842
+ height: tema.space.lg,
1843
+ borderRadius: tema.radius.pill,
1844
+ borderWidth: tema.hairline * 2,
1845
+ borderColor: c,
1846
+ borderStyle: l.tilstand === "kommer" ? "dashed" : "solid",
1847
+ backgroundColor: l.tilstand === "gjort" ? tema.color.success : "transparent",
1848
+ alignItems: "center",
1849
+ justifyContent: "center"
1850
+ },
1851
+ children: l.tilstand === "gjort" ? /* @__PURE__ */ jsx6(Ikon, { navn: "checkmark-outline", storrelse: "minste", farge: tema.color.bg }) : l.ikon ? /* @__PURE__ */ jsx6(Ikon, { navn: l.ikon, storrelse: "minste", farge: c }) : null
1852
+ }
1853
+ ),
1854
+ !siste ? /* @__PURE__ */ jsx6(
1855
+ View5,
1856
+ {
1857
+ style: {
1858
+ flex: 1,
1859
+ height: tema.hairline * 2,
1860
+ borderRadius: tema.radius.pill,
1861
+ backgroundColor: l.tilstand === "gjort" ? tema.color.success : tema.color.borderStrong
1862
+ }
1863
+ }
1864
+ ) : null
1865
+ ] }),
1866
+ /* @__PURE__ */ jsx6(
1867
+ Text5,
1868
+ {
1869
+ style: {
1870
+ color: l.tilstand === "brutt" ? tema.color.warning : l.tilstand === "kommer" ? tema.color.textMuted : tema.color.textPrimary,
1871
+ fontSize: tema.font.small,
1872
+ lineHeight: tema.lineHeight.small,
1873
+ fontWeight: l.tilstand === "naa" || l.tilstand === "brutt" ? tema.weight.semibold : tema.weight.regular
1874
+ },
1875
+ children: l.etikett
1876
+ }
1877
+ ),
1878
+ l.tall !== void 0 ? /* @__PURE__ */ jsx6(Helt, { testID: testID ? `${testID}-tall` : void 0, farge: l.tilstand === "brutt" ? tema.color.warning : tema.color.textPrimary, children: l.tall }) : l.detalj !== void 0 ? /* @__PURE__ */ jsx6(Text5, { style: { color: tema.color.textMuted, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }, children: l.detalj }) : null
1879
+ ]
1880
+ },
1881
+ l.nokkel
1882
+ );
1883
+ })
1884
+ }
1885
+ );
1886
+ }
1887
+
1888
+ // src/widget/Kvittering.tsx
1889
+ import { Fragment, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1484
1890
  function Kvittering({
1485
1891
  art,
1486
1892
  saksnummer,
1487
1893
  vedlegg,
1488
1894
  frist,
1895
+ sak,
1896
+ anonym,
1897
+ tenantName,
1489
1898
  onLukk
1490
1899
  }) {
1491
1900
  const tema = useTema();
1492
- const innhold = {
1493
- feil: { h: tekst.kvitteringSendt, p: tekst.kvitteringFeil },
1494
- // Løftet er NØYAKTIG det «Mine innspill» og panelet viser for «Vurderes»:
1495
- // det leses fra temaet, så kvitteringen og statusen ikke kan si to ting.
1496
- onske: { h: tekst.kvitteringSendt, p: statusVisning("vurderes", "onske", frist).lofte },
1497
- jaOgsa: { h: tekst.kvitteringRegistrert, p: tekst.kvitteringJaOgsa },
1498
- // Køet offline: kvitteringen kan IKKE love svar på noe som ikke er sendt
1499
- // (DD-41 presiserer DD-07). Den lover bare at det sendes.
1500
- k\u00F8: { h: tekst.koKvitteringTittel, p: tekst.offlineBanner }
1901
+ const ko = art === "k\xF8";
1902
+ const helt = {
1903
+ feil: tekst.kvitteringFeil,
1904
+ // Løftet er NØYAKTIG det «Mine innspill» og panelet viser for «Vurderes»: det leses fra
1905
+ // temaet, så kvitteringen og statusen ikke kan si to ting.
1906
+ onske: statusVisning("vurderes", "onske", frist).lofte,
1907
+ jaOgsa: tekst.kvitteringJaOgsa,
1908
+ k\u00F8: tekst.koHelt
1501
1909
  }[art];
1502
- const overskrift = vedlegg === "feilet" ? tekst.kvitteringVedleggFeilet : innhold.h;
1503
- const brodtekst = vedlegg === "feilet" ? `${tekst.tekstenErLagret} ${innhold.p}` : innhold.p;
1504
- return /* @__PURE__ */ jsxs5(View5, { style: { flex: 1, justifyContent: "center", gap: tema.space.lg }, children: [
1505
- /* @__PURE__ */ jsxs5(View5, { style: { alignItems: "center", gap: tema.space.md }, children: [
1506
- /* @__PURE__ */ jsx6(
1507
- Ikon,
1508
- {
1509
- navn: art === "k\xF8" ? "swap-vertical-outline" : "checkmark-circle-outline",
1510
- storrelse: "stor",
1511
- farge: art === "k\xF8" ? tema.color.neutral : tema.color.success
1512
- }
1513
- ),
1514
- /* @__PURE__ */ jsx6(H, { children: overskrift }),
1515
- vedlegg === "feilet" ? /* @__PURE__ */ jsx6(Banner, { ikon: "warning-outline", tone: "warning", children: tekst.vedleggFeiletBanner }) : null,
1516
- vedlegg === "forkastet" ? /* @__PURE__ */ jsx6(Banner, { ikon: "image-outline", tone: "info", children: tekst.offlineUtenBilde }) : null,
1517
- /* @__PURE__ */ jsx6(
1518
- Text5,
1519
- {
1520
- testID: "kvittering-tekst",
1521
- accessibilityRole: "alert",
1522
- accessibilityLiveRegion: "polite",
1523
- style: {
1524
- color: tema.color.textPrimary,
1525
- fontSize: tema.font.body,
1526
- lineHeight: tema.lineHeight.body,
1527
- textAlign: "center"
1528
- },
1529
- children: brodtekst
1530
- }
1531
- ),
1532
- saksnummer ? /* @__PURE__ */ jsx6(Hint, { children: vedlegg === "feilet" ? tekst.saksnummerUtenVedlegg(saksnummer) : tekst.saksnummer(saksnummer) }) : null
1533
- ] }),
1534
- /* @__PURE__ */ jsx6(Btn, { testID: "tilbake-til-appen", label: tekst.tilbakeTilAppen, onPress: onLukk })
1910
+ const dato = formaterFrist(sak?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString());
1911
+ const etikett = vedlegg === "feilet" ? tekst.kvitteringVedleggFeilet : ko ? tekst.kvitteringLagretDato(dato) : art === "jaOgsa" ? tekst.kvitteringRegistrertDato(dato) : anonym ? tekst.kvitteringSendtAnonymtDato(dato) : tekst.kvitteringSendtDato(dato);
1912
+ const ledd = sak && !ko ? sporingsledd(sak, tenantName) : [];
1913
+ const under = anonym ? void 0 : ko ? tekst.koUnder : saksnummer ? tekst.kvitteringUnder : void 0;
1914
+ return /* @__PURE__ */ jsxs6(View6, { testID: "kvittering", style: { flex: 1, gap: tema.space.md }, children: [
1915
+ vedlegg === "feilet" ? /* @__PURE__ */ jsx7(Banner, { ikon: "warning-outline", tone: "warning", children: tekst.vedleggFeiletBanner }) : null,
1916
+ vedlegg === "forkastet" ? /* @__PURE__ */ jsx7(Banner, { ikon: "image-outline", tone: "info", children: tekst.offlineUtenBilde }) : null,
1917
+ /* @__PURE__ */ jsxs6(
1918
+ View6,
1919
+ {
1920
+ testID: "kvittering-kort",
1921
+ style: {
1922
+ backgroundColor: ko ? tema.color.surface : tema.color.brandFill,
1923
+ borderRadius: tema.radius.lg,
1924
+ borderWidth: ko ? tema.hairline : 0,
1925
+ borderStyle: ko ? "dashed" : "solid",
1926
+ borderColor: tema.color.borderInteractive,
1927
+ padding: tema.space.md,
1928
+ gap: tema.space.md
1929
+ },
1930
+ children: [
1931
+ /* @__PURE__ */ jsxs6(View6, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", gap: tema.space.sm }, children: [
1932
+ /* @__PURE__ */ jsxs6(View6, { style: { flexDirection: "row", alignItems: "center", gap: tema.space.sm, flexShrink: 1 }, children: [
1933
+ /* @__PURE__ */ jsx7(
1934
+ Ikon,
1935
+ {
1936
+ navn: ko ? "swap-vertical-outline" : "checkmark-circle-outline",
1937
+ farge: ko ? tema.color.textSecondary : tema.color.onBrandFill
1938
+ }
1939
+ ),
1940
+ tenantName ? /* @__PURE__ */ jsx7(
1941
+ Text6,
1942
+ {
1943
+ style: {
1944
+ color: ko ? tema.color.textPrimary : tema.color.onBrandFill,
1945
+ fontSize: tema.font.body,
1946
+ fontWeight: tema.weight.bold
1947
+ },
1948
+ children: tenantName
1949
+ }
1950
+ ) : null
1951
+ ] }),
1952
+ ko ? /* @__PURE__ */ jsxs6(View6, { style: { flexDirection: "row", alignItems: "center", gap: tema.space.xs }, children: [
1953
+ /* @__PURE__ */ jsx7(Ikon, { navn: "cloud-offline-outline", storrelse: "minste", farge: tema.color.textMuted }),
1954
+ /* @__PURE__ */ jsx7(Text6, { style: { color: tema.color.textMuted, fontSize: tema.font.small, fontWeight: tema.weight.semibold }, children: tekst.koIngenNett })
1955
+ ] }) : saksnummer ? /* @__PURE__ */ jsx7(
1956
+ Text6,
1957
+ {
1958
+ style: { color: tema.color.onBrandFill, fontSize: tema.font.small, fontWeight: tema.weight.semibold },
1959
+ children: vedlegg === "feilet" ? tekst.saksnummerUtenVedlegg(saksnummer) : tekst.saksnummer(saksnummer)
1960
+ }
1961
+ ) : null
1962
+ ] }),
1963
+ /* @__PURE__ */ jsxs6(View6, { style: { gap: tema.space.xs }, children: [
1964
+ /* @__PURE__ */ jsx7(
1965
+ Text6,
1966
+ {
1967
+ style: {
1968
+ color: ko ? tema.color.textMuted : tema.color.onBrandFill,
1969
+ fontSize: tema.font.small,
1970
+ lineHeight: tema.lineHeight.small
1971
+ },
1972
+ children: etikett
1973
+ }
1974
+ ),
1975
+ /* @__PURE__ */ jsx7(Helt, { testID: "kvittering-tekst", live: true, farge: ko ? tema.color.textPrimary : tema.color.onBrandFill, children: vedlegg === "feilet" ? `${tekst.tekstenErLagret} ${helt}` : helt })
1976
+ ] }),
1977
+ under ? /* @__PURE__ */ jsxs6(Fragment, { children: [
1978
+ /* @__PURE__ */ jsx7(
1979
+ View6,
1980
+ {
1981
+ style: {
1982
+ borderTopWidth: tema.hairline,
1983
+ borderTopColor: ko ? tema.color.borderStrong : tema.color.onBrandFill,
1984
+ borderStyle: "dashed"
1985
+ }
1986
+ }
1987
+ ),
1988
+ /* @__PURE__ */ jsx7(
1989
+ Text6,
1990
+ {
1991
+ testID: "kvittering-under",
1992
+ style: {
1993
+ color: ko ? tema.color.textPrimary : tema.color.onBrandFill,
1994
+ fontSize: tema.font.body,
1995
+ lineHeight: tema.lineHeight.body
1996
+ },
1997
+ children: under
1998
+ }
1999
+ )
2000
+ ] }) : null
2001
+ ]
2002
+ }
2003
+ ),
2004
+ ledd.length > 0 ? /* @__PURE__ */ jsx7(Sporingslinje, { ledd, testID: "kvittering-spor" }) : null,
2005
+ /* @__PURE__ */ jsx7(View6, { style: { flex: 1, justifyContent: "flex-end", paddingTop: tema.space.sm }, children: /* @__PURE__ */ jsx7(Btn, { testID: "tilbake-til-appen", label: tekst.tilbakeTilAppen, onPress: onLukk }) })
1535
2006
  ] });
1536
2007
  }
1537
2008
 
1538
2009
  // src/widget/MineInnspill.tsx
1539
2010
  import { InnspelApiError, NettverksFeil } from "@innspel/core";
1540
2011
  import { forwardRef, useEffect, useImperativeHandle, useRef as useRef2, useState as useState2 } from "react";
1541
- import { ActivityIndicator as ActivityIndicator2, Keyboard, Pressable as Pressable4, ScrollView as ScrollView3, Text as Text6, TextInput as TextInput2, View as View6 } from "react-native";
2012
+ import { ActivityIndicator as ActivityIndicator2, Keyboard, ScrollView as ScrollView3, Text as Text7, TextInput as TextInput2, View as View7 } from "react-native";
1542
2013
 
1543
2014
  // src/widget/nyttSvar.ts
1544
2015
  var N\u00D8KKEL = "innspel:svar-sett";
@@ -1561,7 +2032,7 @@ async function markerSvarSett(storage, n\u00E5 = Date.now()) {
1561
2032
  }
1562
2033
 
1563
2034
  // src/widget/MineInnspill.tsx
1564
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
2035
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1565
2036
  var MineInnspill = forwardRef(function MineInnspill2({
1566
2037
  rader,
1567
2038
  laster,
@@ -1645,9 +2116,10 @@ var MineInnspill = forwardRef(function MineInnspill2({
1645
2116
  useEffect(() => {
1646
2117
  if (!laster && rader.length) void markerSvarSett(storage).catch(() => void 0);
1647
2118
  }, [storage, laster, rader]);
1648
- return /* @__PURE__ */ jsxs6(View6, { style: { flex: 1, gap: tema.space.md }, children: [
1649
- /* @__PURE__ */ jsx7(H, { sub: tekst.mineUnder, children: tekst.mineTittel }),
1650
- laster ? /* @__PURE__ */ jsx7(ActivityIndicator2, { accessibilityLabel: "Henter innspillene dine", color: tema.color.textSecondary }) : rader.length === 0 ? /* @__PURE__ */ jsx7(Hint, { children: tekst.mineTom }) : /* @__PURE__ */ jsx7(ScrollView3, { ref: rulleRef, style: { flex: 1 }, contentContainerStyle: { gap: tema.space.sm }, keyboardShouldPersistTaps: "handled", children: visning.map(({ rad, nytt }) => {
2119
+ const tom = !laster && rader.length === 0;
2120
+ return /* @__PURE__ */ jsxs7(View7, { style: { flex: 1, gap: tema.space.md }, children: [
2121
+ tom ? /* @__PURE__ */ jsx8(H, { sub: tenantName ? tekst.mineTomHint(tenantName) : tekst.mineTomHintGenerisk, children: tekst.mineTomTittel }) : /* @__PURE__ */ jsx8(H, { children: tekst.mineTittel }),
2122
+ laster ? /* @__PURE__ */ jsx8(ActivityIndicator2, { accessibilityLabel: tekst.mineLaster, color: tema.color.textSecondary }) : tom ? null : /* @__PURE__ */ jsx8(ScrollView3, { ref: rulleRef, style: { flex: 1 }, contentContainerStyle: { gap: tema.space.md }, keyboardShouldPersistTaps: "handled", children: visning.map(({ rad, nytt }) => {
1651
2123
  const venter = rad.pending === true;
1652
2124
  const v = venter ? venterVisning : statusVisning(rad.status, rad.type, rad.deadlineAt);
1653
2125
  const nokkel = venter ? rad.clientRef : rad.id;
@@ -1660,69 +2132,69 @@ var MineInnspill = forwardRef(function MineInnspill2({
1660
2132
  const brukt = utkast.length;
1661
2133
  const full = brukt >= maks;
1662
2134
  const visTeller = brukt >= maks * 0.8;
1663
- return /* @__PURE__ */ jsx7(
1664
- View6,
2135
+ const ledd = venter ? [] : sporingsledd(rad, tenantName);
2136
+ return /* @__PURE__ */ jsx8(
2137
+ View7,
1665
2138
  {
1666
2139
  onLayout: (e) => {
1667
2140
  if (sakId !== void 0) kortY.current.set(sakId, e.nativeEvent.layout.y);
1668
2141
  },
1669
- children: /* @__PURE__ */ jsxs6(Card, { dashed: venter, children: [
1670
- /* @__PURE__ */ jsxs6(View6, { style: { flexDirection: "row", alignItems: "center", gap: tema.space.xs, flexWrap: "wrap" }, children: [
1671
- /* @__PURE__ */ jsx7(Hint, { children: venter ? `${tekst.mineIkkeSendt} \xB7 ${rad.type === "onske" ? tekst.onske : tekst.feil}` : tekst.sakHode(rad.type === "onske" ? tekst.onske : tekst.feil, rad.id) }),
1672
- nytt ? /* @__PURE__ */ jsx7(
1673
- Text6,
2142
+ children: /* @__PURE__ */ jsxs7(Card, { dashed: venter, testID: `sakskort-${nokkel}`, children: [
2143
+ /* @__PURE__ */ jsxs7(View7, { style: { flexDirection: "row", alignItems: "center", gap: tema.space.sm, flexWrap: "wrap" }, children: [
2144
+ /* @__PURE__ */ jsx8(
2145
+ Ikon,
1674
2146
  {
1675
- testID: "nytt-svar",
1676
- style: {
1677
- color: tema.color.info,
1678
- backgroundColor: tema.color.infoBg,
1679
- fontSize: tema.font.tiny,
1680
- fontWeight: tema.weight.semibold,
1681
- borderRadius: tema.radius.pill,
1682
- paddingHorizontal: tema.space.sm
1683
- },
1684
- children: tekst.nyttSvar
2147
+ navn: rad.type === "onske" ? "bulb" : "bug",
2148
+ storrelse: "minste",
2149
+ farge: tema.color.brand
1685
2150
  }
1686
- ) : null
2151
+ ),
2152
+ /* @__PURE__ */ jsx8(Meta, { children: venter ? tekst.mineIkkeSendtHode(rad.type === "onske" ? tekst.onske : tekst.feil) : tekst.sakHode(rad.type === "onske" ? tekst.onske : tekst.feil, rad.id) }),
2153
+ nytt ? /* @__PURE__ */ jsx8(Pille, { testID: "nytt-svar", children: tekst.nyttSvar }) : null
1687
2154
  ] }),
1688
- /* @__PURE__ */ jsx7(
1689
- Text6,
1690
- {
1691
- style: {
1692
- color: tema.color.textPrimary,
1693
- fontSize: tema.font.body,
1694
- lineHeight: tema.lineHeight.body
1695
- },
1696
- children: rad.text
1697
- }
1698
- ),
1699
- tillegg.length > 0 ? /* @__PURE__ */ jsx7(View6, { testID: `tillegg-${sakId}`, style: { gap: tema.space.xs }, children: tillegg.map((a) => /* @__PURE__ */ jsxs6(
1700
- View6,
2155
+ /* @__PURE__ */ jsx8(Brodtekst, { testID: `sakstekst-${nokkel}`, children: rad.text }),
2156
+ tillegg.length > 0 ? /* @__PURE__ */ jsx8(View7, { testID: `tillegg-${sakId}`, style: { gap: tema.space.sm }, children: tillegg.map((a) => /* @__PURE__ */ jsxs7(
2157
+ View7,
1701
2158
  {
1702
2159
  style: {
1703
2160
  borderLeftWidth: tema.hairline * 2,
1704
2161
  borderLeftColor: tema.color.border,
1705
- paddingLeft: tema.space.sm,
2162
+ paddingLeft: tema.space.md,
1706
2163
  gap: tema.space.xs
1707
2164
  },
1708
2165
  children: [
1709
- /* @__PURE__ */ jsxs6(View6, { style: { flexDirection: "row", alignItems: "center", gap: tema.space.xs }, children: [
1710
- /* @__PURE__ */ jsx7(Ikon, { navn: "add-outline", storrelse: "minste", farge: tema.color.textSecondary }),
1711
- /* @__PURE__ */ jsx7(Text6, { style: { color: tema.color.textSecondary, fontSize: tema.font.small }, children: tekst.duLaTil(formaterFrist(a.createdAt)) })
1712
- ] }),
1713
- /* @__PURE__ */ jsx7(Text6, { style: { color: tema.color.textPrimary, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }, children: a.text })
2166
+ /* @__PURE__ */ jsx8(Meta, { children: tekst.duLaTil(formaterFrist(a.createdAt)) }),
2167
+ /* @__PURE__ */ jsx8(Brodtekst, { testID: `tillegg-tekst-${a.id}`, children: a.text })
1714
2168
  ]
1715
2169
  },
1716
2170
  a.id
1717
2171
  )) }) : null,
1718
- /* @__PURE__ */ jsxs6(View6, { style: { gap: tema.space.xs }, children: [
1719
- /* @__PURE__ */ jsx7(StatusPill, { ikon: v.ikon, etikett: v.etikett, fg: v.fg, bg: v.bg }),
1720
- /* @__PURE__ */ jsx7(Hint, { children: v.lofte })
1721
- ] }),
1722
- sakId !== void 0 && lagtTil === sakId ? /* @__PURE__ */ jsx7(Text6, { accessibilityLiveRegion: "polite", testID: `lagt-til-${sakId}`, style: { color: tema.color.success, fontSize: tema.font.small }, children: tekst.lagtTil }) : null,
1723
- feltApent ? /* @__PURE__ */ jsxs6(View6, { testID: `tillegg-felt-${sakId}`, style: { gap: tema.space.sm }, children: [
1724
- /* @__PURE__ */ jsx7(Text6, { style: { color: tema.color.textSecondary, fontSize: tema.font.small }, children: tekst.leggTilMerLabel }),
1725
- /* @__PURE__ */ jsx7(
2172
+ svar ? /* @__PURE__ */ jsxs7(
2173
+ View7,
2174
+ {
2175
+ testID: `svar-${sakId}`,
2176
+ style: {
2177
+ borderLeftWidth: tema.hairline * 2,
2178
+ borderLeftColor: tema.color.brand,
2179
+ paddingLeft: tema.space.md,
2180
+ gap: tema.space.xs
2181
+ },
2182
+ children: [
2183
+ /* @__PURE__ */ jsx8(Meta, { children: tenantName ? tekst.svarFra(tenantName, formaterFrist(svar.at)) : tekst.svarFraGenerisk(formaterFrist(svar.at)) }),
2184
+ /* @__PURE__ */ jsx8(Brodtekst, { testID: `svar-tekst-${sakId}`, children: svar.text })
2185
+ ]
2186
+ }
2187
+ ) : null,
2188
+ ledd.length > 0 ? /* @__PURE__ */ jsx8(Sporingslinje, { ledd, testID: `spor-${sakId}` }) : /* @__PURE__ */ jsx8(StatusPill, { testID: `status-pille-${nokkel}`, ikon: v.ikon, etikett: v.etikett, fg: v.fg, bg: v.bg }),
2189
+ /* @__PURE__ */ jsx8(Sek, { testID: `lofte-${nokkel}`, children: v.lofte }),
2190
+ !venter && rad.attachmentRemoved ? /* @__PURE__ */ jsxs7(View7, { testID: `bilde-fjernet-${rad.id}`, style: { flexDirection: "row", gap: tema.space.xs, alignItems: "center" }, children: [
2191
+ /* @__PURE__ */ jsx8(Ikon, { navn: "trash-outline", storrelse: "minste", farge: tema.color.textMuted }),
2192
+ /* @__PURE__ */ jsx8(Hint, { children: tekst.bildeFjernet })
2193
+ ] }) : null,
2194
+ sakId !== void 0 && lagtTil === sakId ? /* @__PURE__ */ jsx8(Text7, { accessibilityLiveRegion: "polite", testID: `lagt-til-${sakId}`, style: { color: tema.color.success, fontSize: tema.font.small }, children: tekst.lagtTil }) : null,
2195
+ feltApent ? /* @__PURE__ */ jsxs7(View7, { testID: `tillegg-felt-${sakId}`, style: { gap: tema.space.sm }, children: [
2196
+ /* @__PURE__ */ jsx8(Meta, { children: tekst.leggTilMerLabel }),
2197
+ /* @__PURE__ */ jsx8(
1726
2198
  TextInput2,
1727
2199
  {
1728
2200
  testID: "tillegg-tekst",
@@ -1749,8 +2221,8 @@ var MineInnspill = forwardRef(function MineInnspill2({
1749
2221
  }
1750
2222
  }
1751
2223
  ),
1752
- visTeller ? /* @__PURE__ */ jsxs6(
1753
- Text6,
2224
+ visTeller ? /* @__PURE__ */ jsxs7(
2225
+ Text7,
1754
2226
  {
1755
2227
  testID: "tillegg-teller",
1756
2228
  accessibilityLiveRegion: full ? "assertive" : "polite",
@@ -1763,50 +2235,17 @@ var MineInnspill = forwardRef(function MineInnspill2({
1763
2235
  ]
1764
2236
  }
1765
2237
  ) : null,
1766
- feil?.id === sakId ? /* @__PURE__ */ jsx7(Text6, { accessibilityLiveRegion: "assertive", testID: `tillegg-feil-${sakId}`, style: { color: tema.color.danger, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }, children: feil.tekst }) : null
1767
- ] }) : kanLeggeTil ? /* @__PURE__ */ jsxs6(
1768
- Pressable4,
2238
+ feil?.id === sakId ? /* @__PURE__ */ jsx8(Text7, { accessibilityLiveRegion: "assertive", testID: `tillegg-feil-${sakId}`, style: { color: tema.color.danger, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }, children: feil.tekst }) : null
2239
+ ] }) : kanLeggeTil ? /* @__PURE__ */ jsx8(
2240
+ Tekstknapp,
1769
2241
  {
1770
2242
  testID: `legg-til-mer-${sakId}`,
1771
- accessibilityRole: "button",
2243
+ ikon: "add-outline",
2244
+ label: tekst.leggTilMer,
1772
2245
  accessibilityLabel: tekst.leggTilMerLabel,
1773
- onPress: () => sakId !== void 0 && apneFelt(sakId),
1774
- style: { alignSelf: "flex-start", minHeight: tema.touch, flexDirection: "row", alignItems: "center", gap: tema.space.xs, paddingHorizontal: tema.space.sm },
1775
- children: [
1776
- /* @__PURE__ */ jsx7(Ikon, { navn: "add-outline", storrelse: "minste", farge: tema.color.actionSecondaryText }),
1777
- /* @__PURE__ */ jsx7(Text6, { style: { color: tema.color.actionSecondaryText, fontSize: tema.font.body, fontWeight: tema.weight.semibold }, children: tekst.leggTilMer })
1778
- ]
1779
- }
1780
- ) : taketN\u00E5dd ? /* @__PURE__ */ jsx7(Hint, { children: tekst.tilleggTak }) : null,
1781
- !venter && rad.attachmentRemoved ? /* @__PURE__ */ jsxs6(View6, { testID: `bilde-fjernet-${rad.id}`, style: { flexDirection: "row", gap: tema.space.xs, alignItems: "center" }, children: [
1782
- /* @__PURE__ */ jsx7(Ikon, { navn: "trash-outline", storrelse: "minste", farge: tema.color.textMuted }),
1783
- /* @__PURE__ */ jsx7(Hint, { children: tekst.bildeFjernet })
1784
- ] }) : null,
1785
- svar ? /* @__PURE__ */ jsxs6(
1786
- View6,
1787
- {
1788
- style: {
1789
- borderLeftWidth: tema.hairline * 2,
1790
- borderLeftColor: tema.color.brand,
1791
- paddingLeft: tema.space.sm,
1792
- gap: tema.space.xs
1793
- },
1794
- children: [
1795
- /* @__PURE__ */ jsx7(Text6, { style: { color: tema.color.textSecondary, fontSize: tema.font.small }, children: tenantName ? tekst.svarFra(tenantName) : tekst.svarFraGenerisk }),
1796
- /* @__PURE__ */ jsx7(
1797
- Text6,
1798
- {
1799
- style: {
1800
- color: tema.color.textPrimary,
1801
- fontSize: tema.font.small,
1802
- lineHeight: tema.lineHeight.small
1803
- },
1804
- children: svar.text
1805
- }
1806
- )
1807
- ]
2246
+ onPress: () => sakId !== void 0 && apneFelt(sakId)
1808
2247
  }
1809
- ) : null
2248
+ ) : taketN\u00E5dd ? /* @__PURE__ */ jsx8(Hint, { children: tekst.tilleggTak }) : null
1810
2249
  ] })
1811
2250
  },
1812
2251
  nokkel
@@ -1815,9 +2254,9 @@ var MineInnspill = forwardRef(function MineInnspill2({
1815
2254
  apen !== null ? (
1816
2255
  // F32: fotens plass — én primærhandling om gangen. «Send nytt innspill» er borte til
1817
2256
  // tillegget er sendt eller avbrutt, så første trykk aldri treffer feil knapp.
1818
- /* @__PURE__ */ jsxs6(View6, { testID: "tillegg-fot", style: { gap: tema.space.sm }, children: [
1819
- /* @__PURE__ */ jsxs6(View6, { style: { flexDirection: "row", gap: tema.space.sm }, children: [
1820
- /* @__PURE__ */ jsx7(
2257
+ /* @__PURE__ */ jsxs7(View7, { testID: "tillegg-fot", style: { gap: tema.space.sm }, children: [
2258
+ /* @__PURE__ */ jsxs7(View7, { style: { flexDirection: "row", gap: tema.space.sm }, children: [
2259
+ /* @__PURE__ */ jsx8(
1821
2260
  Btn,
1822
2261
  {
1823
2262
  testID: "tillegg-send",
@@ -1829,19 +2268,19 @@ var MineInnspill = forwardRef(function MineInnspill2({
1829
2268
  grow: true
1830
2269
  }
1831
2270
  ),
1832
- /* @__PURE__ */ jsx7(Btn, { testID: "tillegg-avbryt", label: tekst.avbryt, variant: "secondary", onPress: avbryt, grow: true })
2271
+ /* @__PURE__ */ jsx8(Btn, { testID: "tillegg-avbryt", label: tekst.avbryt, variant: "secondary", onPress: avbryt, grow: true })
1833
2272
  ] }),
1834
- /* @__PURE__ */ jsx7(Hint, { children: tekst.leggTilMerHint })
2273
+ /* @__PURE__ */ jsx8(Hint, { children: tekst.leggTilMerHint })
1835
2274
  ] })
1836
- ) : /* @__PURE__ */ jsx7(Btn, { testID: "send-nytt", label: rader.length === 0 ? tekst.sendForste : tekst.sendNytt, onPress: onNytt })
2275
+ ) : /* @__PURE__ */ jsx8(Btn, { testID: "send-nytt", ikon: "chatbox-outline", label: tom ? tekst.sendForste : tekst.sendNytt, onPress: onNytt })
1837
2276
  ] });
1838
2277
  });
1839
2278
 
1840
2279
  // src/widget/Skjermbilde.tsx
1841
2280
  import { skaler, strokTilRekter, treffer, trykkTilRekt } from "@innspel/core";
1842
2281
  import { useCallback, useMemo as useMemo3, useRef as useRef3, useState as useState3 } from "react";
1843
- import { Image as Image2, Pressable as Pressable5, StyleSheet, Text as Text7, View as View7 } from "react-native";
1844
- import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
2282
+ import { Image as Image2, Pressable as Pressable4, StyleSheet, Text as Text8, View as View8 } from "react-native";
2283
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1845
2284
  function Skjermbilde({
1846
2285
  bilde,
1847
2286
  automaskerRot,
@@ -1900,8 +2339,8 @@ function Skjermbilde({
1900
2339
  };
1901
2340
  const knapp = (id, ikon, label) => {
1902
2341
  const valgt = id === "allTekst" ? allTekst : verktoy === id && !allTekst;
1903
- return /* @__PURE__ */ jsxs7(
1904
- Pressable5,
2342
+ return /* @__PURE__ */ jsxs8(
2343
+ Pressable4,
1905
2344
  {
1906
2345
  testID: `verktoy-${id}`,
1907
2346
  accessibilityRole: "button",
@@ -1923,9 +2362,9 @@ function Skjermbilde({
1923
2362
  backgroundColor: valgt ? tema.color.surfaceRaised : "transparent"
1924
2363
  },
1925
2364
  children: [
1926
- /* @__PURE__ */ jsx8(Ikon, { navn: ikon, farge: tema.color.textPrimary }),
1927
- /* @__PURE__ */ jsx8(
1928
- Text7,
2365
+ /* @__PURE__ */ jsx9(Ikon, { navn: ikon, farge: tema.color.textPrimary }),
2366
+ /* @__PURE__ */ jsx9(
2367
+ Text8,
1929
2368
  {
1930
2369
  style: {
1931
2370
  color: tema.color.textPrimary,
@@ -1941,16 +2380,16 @@ function Skjermbilde({
1941
2380
  );
1942
2381
  };
1943
2382
  const a11y = tekst.skjermbildeA11y(automasker.length, egne.length, allTekst);
1944
- return /* @__PURE__ */ jsxs7(View7, { testID: "skjermbilde-steg", style: { flexGrow: 1, flexShrink: 1, gap: tema.space.md }, children: [
1945
- /* @__PURE__ */ jsx8(H, { sub: kilde === "galleri" ? tekst.skjermbildeUnderGalleri : tekst.skjermbildeUnder, children: tekst.skjermbildeTittel }),
1946
- notat ? /* @__PURE__ */ jsx8(View7, { testID: "bilde-notat", children: /* @__PURE__ */ jsx8(Hint, { children: notat }) }) : null,
1947
- /* @__PURE__ */ jsxs7(View7, { accessibilityRole: "toolbar", accessibilityLabel: tekst.maskering, style: { flexDirection: "row", gap: tema.space.sm }, children: [
2383
+ return /* @__PURE__ */ jsxs8(View8, { testID: "skjermbilde-steg", style: { flexGrow: 1, flexShrink: 1, gap: tema.space.md }, children: [
2384
+ /* @__PURE__ */ jsx9(H, { sub: kilde === "galleri" ? tekst.skjermbildeUnderGalleri : tekst.skjermbildeUnder, children: tekst.skjermbildeTittel }),
2385
+ notat ? /* @__PURE__ */ jsx9(View8, { testID: "bilde-notat", children: /* @__PURE__ */ jsx9(Hint, { children: notat }) }) : null,
2386
+ /* @__PURE__ */ jsxs8(View8, { accessibilityRole: "toolbar", accessibilityLabel: tekst.maskering, style: { flexDirection: "row", gap: tema.space.sm }, children: [
1948
2387
  knapp("felt", "scan-outline", tekst.maskerFelt),
1949
2388
  knapp("pensel", "brush-outline", tekst.tegnOver),
1950
2389
  knapp("allTekst", "grid-outline", tekst.maskerAllTekst)
1951
2390
  ] }),
1952
- /* @__PURE__ */ jsx8(
1953
- View7,
2391
+ /* @__PURE__ */ jsx9(
2392
+ View8,
1954
2393
  {
1955
2394
  testID: "skjermbilde-ramme",
1956
2395
  onLayout,
@@ -1963,8 +2402,8 @@ function Skjermbilde({
1963
2402
  borderRadius: tema.radius.md,
1964
2403
  overflow: "hidden"
1965
2404
  },
1966
- children: /* @__PURE__ */ jsx8(View7, { testID: "skjermbilde-flate", pointerEvents: "box-none", style: [StyleSheet.absoluteFill, { alignItems: "center", justifyContent: "center" }], children: visning ? /* @__PURE__ */ jsxs7(
1967
- View7,
2405
+ children: /* @__PURE__ */ jsx9(View8, { testID: "skjermbilde-flate", pointerEvents: "box-none", style: [StyleSheet.absoluteFill, { alignItems: "center", justifyContent: "center" }], children: visning ? /* @__PURE__ */ jsxs8(
2406
+ View8,
1968
2407
  {
1969
2408
  ref: previewRef,
1970
2409
  collapsable: false,
@@ -1979,7 +2418,7 @@ function Skjermbilde({
1979
2418
  onResponderTerminate: onRelease,
1980
2419
  style: { width: visning.width, height: visning.height, backgroundColor: screenRules.previewBackdrop },
1981
2420
  children: [
1982
- /* @__PURE__ */ jsx8(
2421
+ /* @__PURE__ */ jsx9(
1983
2422
  Image2,
1984
2423
  {
1985
2424
  testID: "skjermbilde-bilde",
@@ -1989,8 +2428,8 @@ function Skjermbilde({
1989
2428
  accessibilityIgnoresInvertColors: true
1990
2429
  }
1991
2430
  ),
1992
- automasker.map((r, i) => /* @__PURE__ */ jsx8(
1993
- View7,
2431
+ automasker.map((r, i) => /* @__PURE__ */ jsx9(
2432
+ View8,
1994
2433
  {
1995
2434
  testID: `automask-${i}`,
1996
2435
  pointerEvents: "none",
@@ -2011,16 +2450,16 @@ function Skjermbilde({
2011
2450
  // (skjermKontrastpar i theme.ts). textSecondary var 2,2:1 (C11a).
2012
2451
  // Ikonet arver samme farge: det er unntaket i «Styling» — maskeringen
2013
2452
  // tegnes i faste signalfarger, ikke i palettens.
2014
- /* @__PURE__ */ jsxs7(View7, { style: { flexDirection: "row", alignItems: "center", gap: tema.space.xs }, children: [
2015
- /* @__PURE__ */ jsx8(Ikon, { navn: "lock-closed-outline", storrelse: "minste", farge: screenRules.autoMaskText }),
2016
- /* @__PURE__ */ jsx8(Text7, { style: { color: screenRules.autoMaskText, fontSize: tema.font.small }, numberOfLines: 1, children: tekst.maskertAvAppen })
2453
+ /* @__PURE__ */ jsxs8(View8, { style: { flexDirection: "row", alignItems: "center", gap: tema.space.xs }, children: [
2454
+ /* @__PURE__ */ jsx9(Ikon, { navn: "lock-closed-outline", storrelse: "minste", farge: screenRules.autoMaskText }),
2455
+ /* @__PURE__ */ jsx9(Text8, { style: { color: screenRules.autoMaskText, fontSize: tema.font.small }, numberOfLines: 1, children: tekst.maskertAvAppen })
2017
2456
  ] })
2018
2457
  ) : null
2019
2458
  },
2020
2459
  `auto-${i}`
2021
2460
  )),
2022
- egne.map((r, i) => /* @__PURE__ */ jsx8(
2023
- View7,
2461
+ egne.map((r, i) => /* @__PURE__ */ jsx9(
2462
+ View8,
2024
2463
  {
2025
2464
  testID: `maske-${i}`,
2026
2465
  pointerEvents: "none",
@@ -2033,14 +2472,14 @@ function Skjermbilde({
2033
2472
  ) : null })
2034
2473
  }
2035
2474
  ),
2036
- automasker.length ? /* @__PURE__ */ jsxs7(View7, { style: { flexDirection: "row", alignItems: "center", gap: tema.space.xs }, children: [
2037
- /* @__PURE__ */ jsx8(Ikon, { navn: "lock-closed-outline", storrelse: "minste", farge: tema.color.textMuted }),
2038
- /* @__PURE__ */ jsx8(Hint, { children: tekst.maskertAvAppenHint })
2475
+ automasker.length ? /* @__PURE__ */ jsxs8(View8, { style: { flexDirection: "row", alignItems: "center", gap: tema.space.xs }, children: [
2476
+ /* @__PURE__ */ jsx9(Ikon, { navn: "lock-closed-outline", storrelse: "minste", farge: tema.color.textMuted }),
2477
+ /* @__PURE__ */ jsx9(Hint, { children: tekst.maskertAvAppenHint })
2039
2478
  ] }) : null,
2040
- egne.length ? /* @__PURE__ */ jsx8(Hint, { children: tekst.dittStrok }) : null,
2041
- allTekst ? /* @__PURE__ */ jsx8(Hint, { children: tekst.allTekstHint }) : null,
2042
- /* @__PURE__ */ jsxs7(View7, { testID: "skjermbilde-fot", style: { flexShrink: 0, gap: tema.space.sm }, children: [
2043
- /* @__PURE__ */ jsx8(
2479
+ egne.length ? /* @__PURE__ */ jsx9(Hint, { children: tekst.dittStrok }) : null,
2480
+ allTekst ? /* @__PURE__ */ jsx9(Hint, { children: tekst.allTekstHint }) : null,
2481
+ /* @__PURE__ */ jsxs8(View8, { testID: "skjermbilde-fot", style: { flexShrink: 0, gap: tema.space.sm }, children: [
2482
+ /* @__PURE__ */ jsx9(
2044
2483
  Btn,
2045
2484
  {
2046
2485
  variant: "secondary",
@@ -2051,7 +2490,7 @@ function Skjermbilde({
2051
2490
  onPress: () => setEgne((x) => x.slice(0, -1))
2052
2491
  }
2053
2492
  ),
2054
- /* @__PURE__ */ jsx8(
2493
+ /* @__PURE__ */ jsx9(
2055
2494
  Btn,
2056
2495
  {
2057
2496
  variant: "danger",
@@ -2062,13 +2501,13 @@ function Skjermbilde({
2062
2501
  disabled: komponerer
2063
2502
  }
2064
2503
  ),
2065
- /* @__PURE__ */ jsx8(Btn, { testID: "legg-ved", label: tekst.leggVed, onPress: onLeggVed, disabled: komponerer || !visning })
2504
+ /* @__PURE__ */ jsx9(Btn, { testID: "legg-ved", label: tekst.leggVed, onPress: onLeggVed, disabled: komponerer || !visning })
2066
2505
  ] })
2067
2506
  ] });
2068
2507
  }
2069
2508
 
2070
2509
  // src/widget/Widget.tsx
2071
- import { Fragment, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
2510
+ import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
2072
2511
  var FANGST = { format: "jpg", quality: 0.85 };
2073
2512
  function Widget({
2074
2513
  client,
@@ -2290,6 +2729,9 @@ function Widget({
2290
2729
  setKvittering({
2291
2730
  art: spor,
2292
2731
  nr: res.submission.id,
2732
+ // Kortet får HELE saken: sporingslinjen leser `status`, `createdAt` og
2733
+ // `statusChangedAt` derfra — ingen nye felter, ingen ny kontrakt (DD-28).
2734
+ sak: res.submission,
2293
2735
  // Tidsløftet i kvitteringen er DATOEN fra svaret, aldri «innen 90 dager» (DD-07, DD-28).
2294
2736
  ...res.submission.deadlineAt ? { frist: res.submission.deadlineAt } : {},
2295
2737
  ...res.attachment?.status === "failed" ? { vedlegg: "feilet" } : {}
@@ -2310,7 +2752,7 @@ function Widget({
2310
2752
  setSender(true);
2311
2753
  try {
2312
2754
  const res = await client.knownIssues.confirm(k.id);
2313
- setKvittering({ art: "jaOgsa", nr: res.id });
2755
+ setKvittering({ art: "jaOgsa", nr: res.id, sak: res });
2314
2756
  setSteg("kvittering");
2315
2757
  } catch (e) {
2316
2758
  setFeil(e instanceof InnspelApiError2 ? e.message : "tjeneren svarte ikke.");
@@ -2342,7 +2784,7 @@ function Widget({
2342
2784
  if (harUtkast) setSteg(stegForMine);
2343
2785
  else nullstill();
2344
2786
  }, [harUtkast, stegForMine, nullstill]);
2345
- return /* @__PURE__ */ jsx9(
2787
+ return /* @__PURE__ */ jsx10(
2346
2788
  Modal,
2347
2789
  {
2348
2790
  visible: synlig,
@@ -2350,14 +2792,14 @@ function Widget({
2350
2792
  animationType: "slide",
2351
2793
  onRequestClose: androidTilbake,
2352
2794
  accessibilityViewIsModal: true,
2353
- children: /* @__PURE__ */ jsx9(
2795
+ children: /* @__PURE__ */ jsx10(
2354
2796
  KeyboardAvoidingView,
2355
2797
  {
2356
2798
  behavior: "padding",
2357
2799
  keyboardVerticalOffset: -insets.bottom,
2358
2800
  style: { flex: 1, backgroundColor: tema.color.scrim, justifyContent: "flex-end", paddingTop: insets.top },
2359
- children: /* @__PURE__ */ jsxs8(
2360
- View8,
2801
+ children: /* @__PURE__ */ jsxs9(
2802
+ View9,
2361
2803
  {
2362
2804
  testID: "innspel-widget",
2363
2805
  accessibilityViewIsModal: true,
@@ -2378,37 +2820,37 @@ function Widget({
2378
2820
  ...steg === "skjermbilde" ? { height: "92%" } : {}
2379
2821
  },
2380
2822
  children: [
2381
- /* @__PURE__ */ jsxs8(View8, { style: { flexDirection: "row", justifyContent: "space-between", alignItems: "center" }, children: [
2382
- steg !== "valg" && steg !== "kvittering" ? /* @__PURE__ */ jsx9(Btn, { variant: "ghost", testID: "tilbake", ikon: "arrow-back-outline", label: tekst.tilbake, onPress: gaaTilbake }) : /* @__PURE__ */ jsx9(View8, {}),
2383
- /* @__PURE__ */ jsx9(
2384
- Pressable6,
2823
+ /* @__PURE__ */ jsxs9(View9, { style: { flexDirection: "row", justifyContent: "space-between", alignItems: "center" }, children: [
2824
+ steg !== "valg" && steg !== "kvittering" ? /* @__PURE__ */ jsx10(Btn, { variant: "ghost", testID: "tilbake", ikon: "arrow-back-outline", label: tekst.tilbake, onPress: gaaTilbake }) : /* @__PURE__ */ jsx10(View9, {}),
2825
+ /* @__PURE__ */ jsx10(
2826
+ Pressable5,
2385
2827
  {
2386
2828
  testID: "lukk",
2387
2829
  accessibilityRole: "button",
2388
2830
  accessibilityLabel: tekst.lukk,
2389
2831
  onPress: steg === "kvittering" ? lukkOgNullstill : lukk,
2390
2832
  style: { minWidth: tema.touch, minHeight: tema.touch, alignItems: "center", justifyContent: "center" },
2391
- children: /* @__PURE__ */ jsx9(Ikon, { navn: "close-outline", farge: tema.color.textSecondary })
2833
+ children: /* @__PURE__ */ jsx10(Ikon, { navn: "close-outline", farge: tema.color.textSecondary })
2392
2834
  }
2393
2835
  )
2394
2836
  ] }),
2395
- feil ? /* @__PURE__ */ jsx9(Banner, { live: true, ikon: "warning-outline", tone: "danger", children: tekst.sendefeilBanner(feil) }) : null,
2396
- !online && steg !== "kvittering" && steg !== "mine" ? /* @__PURE__ */ jsx9(Banner, { ikon: "cloud-offline-outline", tone: "info", testID: "offline-banner", children: tekst.offlineBanner }) : null,
2397
- steg === "valg" ? /* @__PURE__ */ jsxs8(Fragment, { children: [
2398
- /* @__PURE__ */ jsx9(Valg, { onVelg: velgSpor }),
2399
- !client.isAnonymous ? /* @__PURE__ */ jsx9(
2837
+ feil ? /* @__PURE__ */ jsx10(Banner, { live: true, ikon: "warning-outline", tone: "danger", children: tekst.sendefeilBanner(feil) }) : null,
2838
+ !online && steg !== "kvittering" && steg !== "mine" ? /* @__PURE__ */ jsx10(Banner, { ikon: "cloud-offline-outline", tone: "info", testID: "offline-banner", children: tekst.offlineBanner }) : null,
2839
+ steg === "valg" ? /* @__PURE__ */ jsxs9(Fragment2, { children: [
2840
+ /* @__PURE__ */ jsx10(Valg, { onVelg: velgSpor, anonym: client.isAnonymous }),
2841
+ !client.isAnonymous ? /* @__PURE__ */ jsx10(View9, { style: { flex: 1, justifyContent: "flex-end" }, children: /* @__PURE__ */ jsx10(
2400
2842
  Btn,
2401
2843
  {
2402
- variant: mine.length > 0 ? "secondary" : "ghost",
2844
+ variant: "secondary",
2403
2845
  testID: "mine-innspill",
2404
2846
  ikon: "list-outline",
2405
2847
  label: mine.length > 0 ? tekst.mineMedAntall(mine.length) : tekst.mineTittel,
2406
2848
  accessibilityLabel: mine.length > 0 ? tekst.mineEtikett(mine.length) : tekst.mineTittel,
2407
2849
  onPress: () => void visMine()
2408
2850
  }
2409
- ) : null
2851
+ ) }) : null
2410
2852
  ] }) : null,
2411
- steg === "kjenteFeil" ? /* @__PURE__ */ jsx9(
2853
+ steg === "kjenteFeil" ? /* @__PURE__ */ jsx10(
2412
2854
  KjenteFeil,
2413
2855
  {
2414
2856
  kort,
@@ -2423,7 +2865,7 @@ function Widget({
2423
2865
  onNei: () => setSteg("felt")
2424
2866
  }
2425
2867
  ) : null,
2426
- steg === "felt" ? /* @__PURE__ */ jsx9(
2868
+ steg === "felt" ? /* @__PURE__ */ jsx10(
2427
2869
  Felt,
2428
2870
  {
2429
2871
  spor,
@@ -2447,7 +2889,7 @@ function Widget({
2447
2889
  onFjernVedlegg: fjernBilde
2448
2890
  }
2449
2891
  ) : null,
2450
- steg === "skjermbilde" && bilde ? /* @__PURE__ */ jsx9(
2892
+ steg === "skjermbilde" && bilde ? /* @__PURE__ */ jsx10(
2451
2893
  Skjermbilde,
2452
2894
  {
2453
2895
  bilde,
@@ -2461,17 +2903,20 @@ function Widget({
2461
2903
  onLeggVed: leggVedBilde
2462
2904
  }
2463
2905
  ) : null,
2464
- steg === "kvittering" && kvittering ? /* @__PURE__ */ jsx9(
2906
+ steg === "kvittering" && kvittering ? /* @__PURE__ */ jsx10(
2465
2907
  Kvittering,
2466
2908
  {
2467
2909
  art: kvittering.art,
2468
2910
  ...kvittering.nr ? { saksnummer: kvittering.nr } : {},
2469
2911
  ...kvittering.vedlegg ? { vedlegg: kvittering.vedlegg } : {},
2470
2912
  ...kvittering.frist ? { frist: kvittering.frist } : {},
2913
+ ...kvittering.sak && kvittering.sak.pending !== true ? { sak: kvittering.sak } : {},
2914
+ ...tenantName ? { tenantName } : {},
2915
+ anonym: client.isAnonymous,
2471
2916
  onLukk: lukkOgNullstill
2472
2917
  }
2473
2918
  ) : null,
2474
- steg === "mine" ? /* @__PURE__ */ jsx9(
2919
+ steg === "mine" ? /* @__PURE__ */ jsx10(
2475
2920
  MineInnspill,
2476
2921
  {
2477
2922
  ref: mineRef,
@@ -2515,7 +2960,7 @@ function fjernetKontekst(client, fjernede, skjerm) {
2515
2960
  }
2516
2961
 
2517
2962
  // src/InnspelProvider.tsx
2518
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
2963
+ import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
2519
2964
  var Kontekst = createContext3(null);
2520
2965
  function InnspelProvider({
2521
2966
  client,
@@ -2550,9 +2995,9 @@ function InnspelProvider({
2550
2995
  () => ({ adapter: screenshot ?? null, rootRef, privat }),
2551
2996
  [screenshot, privat]
2552
2997
  );
2553
- return /* @__PURE__ */ jsx10(Kontekst.Provider, { value: verdi, children: /* @__PURE__ */ jsx10(SkjermbildeContext.Provider, { value: skjermbilde, children: /* @__PURE__ */ jsxs9(TemaProvider, { value: tema, children: [
2554
- /* @__PURE__ */ jsx10(View9, { ref: rootRef, collapsable: false, style: { flex: 1 }, testID: "innspel-rot", children }),
2555
- /* @__PURE__ */ jsx10(
2998
+ return /* @__PURE__ */ jsx11(Kontekst.Provider, { value: verdi, children: /* @__PURE__ */ jsx11(SkjermbildeContext.Provider, { value: skjermbilde, children: /* @__PURE__ */ jsxs10(TemaProvider, { value: tema, children: [
2999
+ /* @__PURE__ */ jsx11(View10, { ref: rootRef, collapsable: false, style: { flex: 1 }, testID: "innspel-rot", children }),
3000
+ /* @__PURE__ */ jsx11(
2556
3001
  Widget,
2557
3002
  {
2558
3003
  client,
@@ -2578,8 +3023,8 @@ function useInnspel() {
2578
3023
 
2579
3024
  // src/InnspelPrivate.tsx
2580
3025
  import { useEffect as useEffect3, useRef as useRef6 } from "react";
2581
- import { View as View10 } from "react-native";
2582
- import { jsx as jsx11 } from "react/jsx-runtime";
3026
+ import { View as View11 } from "react-native";
3027
+ import { jsx as jsx12 } from "react/jsx-runtime";
2583
3028
  function InnspelPrivate({ children, style }) {
2584
3029
  const ref = useRef6(null);
2585
3030
  const kontekst = useSkjermbilde();
@@ -2588,7 +3033,7 @@ function InnspelPrivate({ children, style }) {
2588
3033
  if (!registrer) return;
2589
3034
  return registrer(ref);
2590
3035
  }, [registrer]);
2591
- return /* @__PURE__ */ jsx11(View10, { ref, collapsable: false, style, testID: "innspel-privat", children });
3036
+ return /* @__PURE__ */ jsx12(View11, { ref, collapsable: false, style, testID: "innspel-privat", children });
2592
3037
  }
2593
3038
 
2594
3039
  // src/program/InnspelProgram.tsx
@@ -2596,11 +3041,7 @@ import {
2596
3041
  InnspelApiError as InnspelApiError3
2597
3042
  } from "@innspel/core";
2598
3043
  import { useCallback as useCallback4, useEffect as useEffect4, useState as useState7 } from "react";
2599
- import { Modal as Modal4, Pressable as Pressable9, Text as Text12, View as View15 } from "react-native";
2600
-
2601
- // src/program/Aksept.tsx
2602
- import "react";
2603
- import { Linking, Modal as Modal2, Pressable as Pressable7, ScrollView as ScrollView4, Text as Text8, View as View11 } from "react-native";
3044
+ import { Modal as Modal4, Pressable as Pressable8, View as View16 } from "react-native";
2604
3045
 
2605
3046
  // src/program/periode.ts
2606
3047
  var MANEDER = [
@@ -2624,13 +3065,31 @@ function periode(opensAt, closesAt) {
2624
3065
  const sammeManed = fra.getMonth() === til.getMonth() && fra.getFullYear() === til.getFullYear();
2625
3066
  return sammeManed ? `${fra.getDate()}.\u2013${til.getDate()}. ${MANEDER[til.getMonth()]}` : `${fra.getDate()}. ${MANEDER[fra.getMonth()]} \u2013 ${til.getDate()}. ${MANEDER[til.getMonth()]}`;
2626
3067
  }
2627
- function minutterPerOppgave(tasks) {
2628
- if (tasks.length === 0) return 0;
2629
- return Math.round(tasks.reduce((sum, t2) => sum + t2.estimatedMinutes, 0) / tasks.length);
3068
+ function minutterLinje(tasks) {
3069
+ if (tasks.length === 0) return { minutter: 0, like: true };
3070
+ const forste = tasks[0].estimatedMinutes;
3071
+ const like = tasks.every((t2) => t2.estimatedMinutes === forste);
3072
+ return like ? { minutter: forste, like: true } : { minutter: tasks.reduce((sum, t2) => sum + t2.estimatedMinutes, 0), like: false };
2630
3073
  }
2631
3074
 
2632
3075
  // src/program/Aksept.tsx
2633
- import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
3076
+ import "react";
3077
+ import { Linking, Modal as Modal2, Pressable as Pressable6, ScrollView as ScrollView4, Text as Text9, View as View12 } from "react-native";
3078
+ import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
3079
+ function Seksjon({ tittel, children }) {
3080
+ const tema = useTema();
3081
+ return /* @__PURE__ */ jsxs11(View12, { style: { gap: tema.space.sm }, children: [
3082
+ /* @__PURE__ */ jsx13(
3083
+ Text9,
3084
+ {
3085
+ accessibilityRole: "header",
3086
+ style: { color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body, fontWeight: tema.weight.bold },
3087
+ children: tittel
3088
+ }
3089
+ ),
3090
+ children
3091
+ ] });
3092
+ }
2634
3093
  function Aksept({
2635
3094
  program,
2636
3095
  harToken,
@@ -2640,14 +3099,15 @@ function Aksept({
2640
3099
  onLukk
2641
3100
  }) {
2642
3101
  const tema = useTema();
2643
- const tall = tekst.akseptTall(
3102
+ const { minutter, like } = minutterLinje(program.tasks);
3103
+ const tall = (like ? tekst.akseptTallHver : tekst.akseptTallSum)(
2644
3104
  program.tasks.length,
2645
- minutterPerOppgave(program.tasks),
2646
- periode(program.opensAt, program.closesAt),
2647
- program.maxContacts
3105
+ minutter,
3106
+ periode(program.opensAt, program.closesAt)
2648
3107
  );
2649
- return /* @__PURE__ */ jsx12(Modal2, { visible: true, transparent: true, animationType: "slide", onRequestClose: onLukk, accessibilityViewIsModal: true, children: /* @__PURE__ */ jsx12(View11, { style: { flex: 1, backgroundColor: tema.color.scrim, justifyContent: "flex-end" }, children: /* @__PURE__ */ jsxs10(
2650
- View11,
3108
+ const medVilkar = !!program.termsUrl && !program.commitmentFree;
3109
+ return /* @__PURE__ */ jsx13(Modal2, { visible: true, transparent: true, animationType: "slide", onRequestClose: onLukk, accessibilityViewIsModal: true, children: /* @__PURE__ */ jsx13(View12, { style: { flex: 1, backgroundColor: tema.color.scrim, justifyContent: "flex-end" }, children: /* @__PURE__ */ jsxs11(
3110
+ View12,
2651
3111
  {
2652
3112
  testID: "program-aksept",
2653
3113
  accessibilityViewIsModal: true,
@@ -2661,17 +3121,17 @@ function Aksept({
2661
3121
  minHeight: "60%"
2662
3122
  },
2663
3123
  children: [
2664
- /* @__PURE__ */ jsxs10(View11, { style: { flexDirection: "row", justifyContent: "space-between", alignItems: "center" }, children: [
2665
- /* @__PURE__ */ jsx12(Btn, { variant: "ghost", testID: "aksept-tilbake", ikon: "arrow-back-outline", label: tekst.tilbake, onPress: onLukk }),
2666
- /* @__PURE__ */ jsx12(View11, {})
3124
+ /* @__PURE__ */ jsxs11(View12, { style: { flexDirection: "row", justifyContent: "space-between", alignItems: "center" }, children: [
3125
+ /* @__PURE__ */ jsx13(Btn, { variant: "ghost", testID: "aksept-tilbake", ikon: "arrow-back-outline", label: tekst.tilbake, onPress: onLukk }),
3126
+ /* @__PURE__ */ jsx13(View12, {})
2667
3127
  ] }),
2668
- feil ? /* @__PURE__ */ jsx12(Banner, { live: true, ikon: "warning-outline", tone: "danger", children: tekst.akseptFeil(feil) }) : null,
2669
- /* @__PURE__ */ jsxs10(ScrollView4, { contentContainerStyle: { gap: tema.space.md }, children: [
2670
- /* @__PURE__ */ jsx12(H, { sub: tekst.akseptHva, children: program.name }),
2671
- /* @__PURE__ */ jsx12(
2672
- Text8,
3128
+ feil ? /* @__PURE__ */ jsx13(Banner, { live: true, ikon: "warning-outline", tone: "danger", children: tekst.akseptFeil(feil) }) : null,
3129
+ /* @__PURE__ */ jsxs11(ScrollView4, { contentContainerStyle: { gap: tema.space.lg }, children: [
3130
+ /* @__PURE__ */ jsx13(H, { testID: "aksept-tittel", sub: program.hypothesis, children: program.name }),
3131
+ /* @__PURE__ */ jsx13(
3132
+ Text9,
2673
3133
  {
2674
- accessibilityRole: "text",
3134
+ testID: "aksept-tall",
2675
3135
  style: {
2676
3136
  color: tema.color.textPrimary,
2677
3137
  fontSize: tema.font.body,
@@ -2681,79 +3141,116 @@ function Aksept({
2681
3141
  children: tall
2682
3142
  }
2683
3143
  ),
2684
- /* @__PURE__ */ jsx12(Text8, { style: { color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }, children: program.hypothesis }),
2685
- /* @__PURE__ */ jsxs10(Card, { children: [
2686
- /* @__PURE__ */ jsx12(H, { children: tekst.akseptOppgaver }),
2687
- program.tasks.map((o) => /* @__PURE__ */ jsxs10(View11, { style: { gap: tema.space.xs }, children: [
2688
- /* @__PURE__ */ jsx12(Text8, { style: { color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }, children: o.title }),
2689
- /* @__PURE__ */ jsxs10(Hint, { children: [
2690
- tekst.akseptOppgaveTid(o.estimatedMinutes),
2691
- o.screenHint ? ` \xB7 ${o.screenHint}` : ""
2692
- ] })
2693
- ] }, o.id))
2694
- ] }),
2695
- program.knownIssues.length > 0 ? /* @__PURE__ */ jsxs10(Card, { children: [
2696
- /* @__PURE__ */ jsx12(H, { sub: tekst.akseptKjenteFeilUnder, children: tekst.akseptKjenteFeil(program.knownIssues.length) }),
2697
- program.knownIssues.map((k) => {
2698
- const o = knownIssueStatus[k.status] ?? knownIssueStatus.aktiv;
2699
- return /* @__PURE__ */ jsxs10(View11, { style: { gap: tema.space.xs }, children: [
2700
- /* @__PURE__ */ jsx12(Text8, { style: { color: tema.color.textPrimary, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }, children: k.title }),
2701
- k.workaround ? /* @__PURE__ */ jsxs10(Text8, { style: { color: tema.color.textSecondary, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }, children: [
2702
- tekst.omvei,
2703
- " ",
2704
- k.workaround
2705
- ] }) : null,
2706
- k.fixedIn ? /* @__PURE__ */ jsx12(
2707
- StatusPill,
3144
+ /* @__PURE__ */ jsx13(Seksjon, { tittel: tekst.akseptOppgaver, children: /* @__PURE__ */ jsx13(View12, { children: program.tasks.map((o, i) => /* @__PURE__ */ jsxs11(
3145
+ View12,
3146
+ {
3147
+ style: {
3148
+ flexDirection: "row",
3149
+ alignItems: "center",
3150
+ gap: tema.space.sm,
3151
+ minHeight: tema.touch + tema.space.sm,
3152
+ paddingVertical: tema.space.sm,
3153
+ borderTopWidth: i === 0 ? 0 : tema.hairline,
3154
+ borderTopColor: tema.color.border
3155
+ },
3156
+ children: [
3157
+ /* @__PURE__ */ jsx13(
3158
+ View12,
2708
3159
  {
2709
- ikon: o.ikon,
2710
- etikett: k.status === "fikset" ? tekst.rettetI(k.fixedIn) : tekst.rettesI(k.fixedIn),
2711
- fg: o.fg,
2712
- bg: o.bg
3160
+ style: {
3161
+ width: tema.space.lg,
3162
+ height: tema.space.lg,
3163
+ borderRadius: tema.radius.pill,
3164
+ borderWidth: tema.hairline * 2,
3165
+ borderStyle: "dashed",
3166
+ borderColor: tema.color.borderStrong
3167
+ }
2713
3168
  }
2714
- ) : null
2715
- ] }, k.id);
2716
- })
2717
- ] }) : null,
2718
- /* @__PURE__ */ jsxs10(Card, { children: [
2719
- /* @__PURE__ */ jsx12(H, { sub: tekst.akseptInnsamlingTekst, children: tekst.akseptInnsamling }),
2720
- /* @__PURE__ */ jsx12(Hint, { children: tekst.kontekstAldri })
2721
- ] }),
2722
- program.termsUrl && !program.commitmentFree ? /* @__PURE__ */ jsxs10(View11, { style: { gap: tema.space.xs }, children: [
2723
- /* @__PURE__ */ jsx12(
2724
- Pressable7,
3169
+ ),
3170
+ /* @__PURE__ */ jsxs11(View12, { style: { flex: 1, minWidth: 0 }, children: [
3171
+ /* @__PURE__ */ jsx13(
3172
+ Text9,
3173
+ {
3174
+ style: { color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body, fontWeight: tema.weight.semibold },
3175
+ children: o.title
3176
+ }
3177
+ ),
3178
+ /* @__PURE__ */ jsx13(Meta, { children: tekst.oppgaveTid(o.estimatedMinutes, o.screenHint) })
3179
+ ] })
3180
+ ]
3181
+ },
3182
+ o.id
3183
+ )) }) }),
3184
+ program.knownIssues.length > 0 ? /* @__PURE__ */ jsx13(Seksjon, { tittel: tekst.akseptKjenteFeil, children: /* @__PURE__ */ jsx13(View12, { children: program.knownIssues.map((k, i) => {
3185
+ const o = knownIssueStatus[k.status] ?? knownIssueStatus.aktiv;
3186
+ const rettet = k.status === "fikset";
3187
+ const statusOrd = rettet && k.fixedIn ? tekst.rettetI(k.fixedIn) : o.etikett;
3188
+ const tillegg = !rettet && k.fixedIn ? `\xB7 ${tekst.rettesI(k.fixedIn).toLowerCase()}` : void 0;
3189
+ return /* @__PURE__ */ jsxs11(
3190
+ View12,
3191
+ {
3192
+ style: {
3193
+ gap: tema.space.xs,
3194
+ paddingVertical: tema.space.sm,
3195
+ borderTopWidth: i === 0 ? 0 : tema.hairline,
3196
+ borderTopColor: tema.color.border
3197
+ },
3198
+ children: [
3199
+ /* @__PURE__ */ jsx13(
3200
+ Text9,
3201
+ {
3202
+ style: { color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body, fontWeight: tema.weight.semibold },
3203
+ children: k.title
3204
+ }
3205
+ ),
3206
+ k.workaround ? /* @__PURE__ */ jsxs11(Sek, { children: [
3207
+ tekst.omvei,
3208
+ " ",
3209
+ k.workaround
3210
+ ] }) : null,
3211
+ /* @__PURE__ */ jsxs11(View12, { style: { flexDirection: "row", alignItems: "center", gap: tema.space.sm, flexWrap: "wrap" }, children: [
3212
+ /* @__PURE__ */ jsxs11(View12, { style: { flexDirection: "row", alignItems: "center", gap: tema.space.xs }, children: [
3213
+ /* @__PURE__ */ jsx13(Ikon, { navn: o.ikon, storrelse: "minste", farge: tema.color[o.fg] }),
3214
+ /* @__PURE__ */ jsx13(
3215
+ Text9,
3216
+ {
3217
+ style: {
3218
+ color: tema.color[o.fg],
3219
+ fontSize: tema.font.small,
3220
+ lineHeight: tema.lineHeight.small,
3221
+ fontWeight: tema.weight.semibold
3222
+ },
3223
+ children: statusOrd
3224
+ }
3225
+ )
3226
+ ] }),
3227
+ tillegg ? /* @__PURE__ */ jsx13(Meta, { children: tillegg }) : null
3228
+ ] })
3229
+ ]
3230
+ },
3231
+ k.id
3232
+ );
3233
+ }) }) }) : null,
3234
+ /* @__PURE__ */ jsxs11(Seksjon, { tittel: tekst.akseptInnsamling, children: [
3235
+ /* @__PURE__ */ jsx13(Sek, { children: tekst.akseptInnsamlingTekst }),
3236
+ medVilkar ? /* @__PURE__ */ jsxs11(
3237
+ Pressable6,
2725
3238
  {
2726
3239
  testID: "vilkar-lenke",
2727
3240
  accessibilityRole: "link",
2728
3241
  accessibilityLabel: tekst.akseptVilkar,
2729
3242
  onPress: () => void Linking.openURL(String(program.termsUrl)),
2730
- style: { minHeight: tema.touch, justifyContent: "center" },
2731
- children: /* @__PURE__ */ jsxs10(View11, { style: { flexDirection: "row", alignItems: "center", gap: tema.space.xs }, children: [
2732
- /* @__PURE__ */ jsx12(Ikon, { navn: "open-outline", farge: tema.color.textPrimary }),
2733
- /* @__PURE__ */ jsx12(
2734
- Text8,
2735
- {
2736
- style: { color: tema.color.textPrimary, fontSize: tema.font.body, textDecorationLine: "underline" },
2737
- children: tekst.akseptVilkar
2738
- }
2739
- )
2740
- ] })
2741
- }
2742
- ),
2743
- /* @__PURE__ */ jsx12(Hint, { children: tekst.akseptVilkarHint })
2744
- ] }) : /* @__PURE__ */ jsx12(Hint, { children: tekst.akseptIngenVilkar }),
2745
- /* @__PURE__ */ jsxs10(View11, { style: { flexDirection: "row", alignItems: "flex-start", gap: tema.space.sm }, children: [
2746
- /* @__PURE__ */ jsx12(Ikon, { navn: "exit-outline", farge: tema.color.textPrimary }),
2747
- /* @__PURE__ */ jsx12(
2748
- Text8,
2749
- {
2750
- style: { flex: 1, color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body },
2751
- children: tekst.akseptUtgang
3243
+ style: { minHeight: tema.touch, flexDirection: "row", alignItems: "center", gap: tema.space.sm },
3244
+ children: [
3245
+ /* @__PURE__ */ jsx13(Ikon, { navn: "open-outline", storrelse: "minste", farge: tema.color.actionText }),
3246
+ /* @__PURE__ */ jsx13(Text9, { style: { color: tema.color.actionText, fontSize: tema.font.body, fontWeight: tema.weight.semibold }, children: tekst.akseptVilkar })
3247
+ ]
2752
3248
  }
2753
- )
3249
+ ) : null,
3250
+ /* @__PURE__ */ jsx13(Hint, { children: medVilkar ? tekst.akseptTakOgUtgangVilkar(program.maxContacts) : tekst.akseptTakOgUtgang(program.maxContacts) })
2754
3251
  ] })
2755
3252
  ] }),
2756
- /* @__PURE__ */ jsx12(
3253
+ /* @__PURE__ */ jsx13(
2757
3254
  Btn,
2758
3255
  {
2759
3256
  testID: "bli-med",
@@ -2770,8 +3267,8 @@ function Aksept({
2770
3267
 
2771
3268
  // src/program/HvordanGikkDet.tsx
2772
3269
  import { useState as useState6 } from "react";
2773
- import { Modal as Modal3, Pressable as Pressable8, Text as Text9, TextInput as TextInput3, View as View12 } from "react-native";
2774
- import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
3270
+ import { Modal as Modal3, Pressable as Pressable7, Text as Text10, TextInput as TextInput3, View as View13 } from "react-native";
3271
+ import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
2775
3272
  var UTFALL = [
2776
3273
  { verdi: "fungerte", ikon: "checkmark-circle-outline", etikett: tekst.utfallFungerte },
2777
3274
  { verdi: "delvis", ikon: "contrast-outline", etikett: tekst.utfallDelvis },
@@ -2783,64 +3280,113 @@ function utfallEtikett(verdi) {
2783
3280
  }
2784
3281
  function HvordanGikkDet({
2785
3282
  under,
3283
+ spoersmaal,
2786
3284
  sender,
2787
3285
  feil,
2788
3286
  onLagre,
3287
+ onMeldFeil,
2789
3288
  onLukk
2790
3289
  }) {
2791
3290
  const tema = useTema();
2792
3291
  const [valgt, setValgt] = useState6();
2793
3292
  const [setning, setSetning] = useState6("");
2794
- return /* @__PURE__ */ jsx13(Modal3, { visible: true, transparent: true, animationType: "fade", onRequestClose: onLukk, accessibilityViewIsModal: true, children: /* @__PURE__ */ jsx13(View12, { style: { flex: 1, backgroundColor: tema.color.scrim, justifyContent: "flex-end", padding: tema.space.md }, children: /* @__PURE__ */ jsxs11(
2795
- View12,
3293
+ const tekstVerdi = () => {
3294
+ const trimmet = setning.trim();
3295
+ return trimmet.length > 0 ? trimmet : void 0;
3296
+ };
3297
+ return /* @__PURE__ */ jsx14(Modal3, { visible: true, transparent: true, animationType: "slide", onRequestClose: onLukk, accessibilityViewIsModal: true, children: /* @__PURE__ */ jsx14(View13, { style: { flex: 1, backgroundColor: tema.color.scrim, justifyContent: "flex-end" }, children: /* @__PURE__ */ jsxs12(
3298
+ View13,
2796
3299
  {
2797
3300
  testID: "hvordan-gikk-det",
2798
3301
  accessibilityViewIsModal: true,
2799
3302
  style: {
2800
- backgroundColor: tema.color.surface,
2801
- borderRadius: tema.radius.lg,
2802
- borderWidth: tema.hairline,
2803
- borderColor: tema.color.borderStrong,
2804
- padding: tema.space.md,
2805
- gap: tema.space.md
3303
+ backgroundColor: tema.color.bg,
3304
+ borderTopLeftRadius: tema.radius.lg * 2,
3305
+ borderTopRightRadius: tema.radius.lg * 2,
3306
+ padding: tema.screenPadding,
3307
+ gap: tema.space.md,
3308
+ maxHeight: "92%"
2806
3309
  },
2807
3310
  children: [
2808
- /* @__PURE__ */ jsx13(Btn, { variant: "ghost", testID: "hvordan-tilbake", ikon: "arrow-back-outline", label: tekst.tilbake, onPress: onLukk }),
2809
- /* @__PURE__ */ jsx13(Hint, { children: under }),
2810
- /* @__PURE__ */ jsx13(H, { children: tekst.hvordanGikkDet }),
2811
- /* @__PURE__ */ jsx13(View12, { testID: "utfall-gruppe", accessibilityRole: "radiogroup", accessibilityLabel: tekst.hvordanGikkDet, style: { flexDirection: "row", gap: tema.space.sm }, children: UTFALL.map((u) => {
2812
- const aktiv = valgt === u.verdi;
2813
- return /* @__PURE__ */ jsxs11(
2814
- Pressable8,
2815
- {
2816
- testID: `utfall-${u.verdi}`,
2817
- accessibilityRole: "radio",
2818
- accessibilityLabel: u.etikett,
2819
- accessibilityState: { checked: aktiv },
2820
- onPress: () => setValgt(u.verdi),
2821
- style: {
2822
- flex: 1,
2823
- minHeight: tema.touch,
2824
- alignItems: "center",
2825
- justifyContent: "center",
2826
- gap: tema.space.xs,
2827
- padding: tema.space.sm,
2828
- borderRadius: tema.radius.md,
2829
- borderWidth: tema.hairline,
2830
- borderColor: aktiv ? tema.color.brand : tema.color.borderStrong,
2831
- backgroundColor: aktiv ? tema.color.brandBg : tema.color.surfaceRaised
2832
- },
2833
- children: [
2834
- /* @__PURE__ */ jsx13(Ikon, { navn: u.ikon, farge: tema.color.textPrimary }),
2835
- /* @__PURE__ */ jsx13(Text9, { style: { color: tema.color.textPrimary, fontSize: tema.font.small, fontWeight: aktiv ? tema.weight.semibold : tema.weight.regular }, children: u.etikett })
2836
- ]
2837
- },
2838
- u.verdi
2839
- );
2840
- }) }),
2841
- /* @__PURE__ */ jsxs11(View12, { style: { gap: tema.space.xs }, children: [
2842
- /* @__PURE__ */ jsx13(Text9, { style: { color: tema.color.textSecondary, fontSize: tema.font.small }, children: tekst.setningLabel }),
2843
- /* @__PURE__ */ jsx13(
3311
+ /* @__PURE__ */ jsxs12(View13, { style: { flexDirection: "row", justifyContent: "space-between", alignItems: "center" }, children: [
3312
+ /* @__PURE__ */ jsx14(Btn, { variant: "ghost", testID: "hvordan-tilbake", ikon: "arrow-back-outline", label: tekst.tilbake, onPress: onLukk }),
3313
+ /* @__PURE__ */ jsx14(View13, {})
3314
+ ] }),
3315
+ /* @__PURE__ */ jsxs12(View13, { style: { gap: tema.space.xs }, children: [
3316
+ under ? /* @__PURE__ */ jsx14(Meta, { children: under }) : null,
3317
+ /* @__PURE__ */ jsx14(H, { children: spoersmaal ?? tekst.hvordanGikkDet })
3318
+ ] }),
3319
+ /* @__PURE__ */ jsx14(
3320
+ View13,
3321
+ {
3322
+ testID: "utfall-gruppe",
3323
+ accessibilityRole: "radiogroup",
3324
+ accessibilityLabel: spoersmaal ?? tekst.hvordanGikkDet,
3325
+ children: UTFALL.map((u, i) => {
3326
+ const aktiv = valgt === u.verdi;
3327
+ return /* @__PURE__ */ jsxs12(
3328
+ Pressable7,
3329
+ {
3330
+ testID: `utfall-${u.verdi}`,
3331
+ accessibilityRole: "radio",
3332
+ accessibilityLabel: u.etikett,
3333
+ accessibilityState: { checked: aktiv },
3334
+ onPress: () => setValgt(u.verdi),
3335
+ style: {
3336
+ flexDirection: "row",
3337
+ alignItems: "center",
3338
+ gap: tema.space.md,
3339
+ minHeight: tema.touch + tema.space.sm,
3340
+ borderTopWidth: i === 0 ? 0 : tema.hairline,
3341
+ borderTopColor: tema.color.border
3342
+ },
3343
+ children: [
3344
+ /* @__PURE__ */ jsx14(
3345
+ View13,
3346
+ {
3347
+ testID: aktiv ? `utfall-merke-${u.verdi}` : void 0,
3348
+ style: {
3349
+ width: tema.space.lg,
3350
+ height: tema.space.lg,
3351
+ borderRadius: tema.radius.pill,
3352
+ alignItems: "center",
3353
+ justifyContent: "center",
3354
+ backgroundColor: aktiv ? tema.color.brand : "transparent",
3355
+ borderWidth: tema.hairline * 2,
3356
+ borderColor: aktiv ? tema.color.brand : tema.color.borderInteractive
3357
+ },
3358
+ children: aktiv ? /* @__PURE__ */ jsx14(Ikon, { navn: "checkmark-outline", storrelse: "minste", farge: tema.color.onBrand }) : null
3359
+ }
3360
+ ),
3361
+ /* @__PURE__ */ jsx14(Ikon, { navn: u.ikon, farge: tema.color.textSecondary }),
3362
+ /* @__PURE__ */ jsx14(
3363
+ Text10,
3364
+ {
3365
+ testID: `utfall-etikett-${u.verdi}`,
3366
+ style: {
3367
+ flex: 1,
3368
+ color: tema.color.textPrimary,
3369
+ fontSize: tema.font.body,
3370
+ lineHeight: tema.lineHeight.body,
3371
+ fontWeight: aktiv ? tema.weight.semibold : tema.weight.regular
3372
+ },
3373
+ children: u.etikett
3374
+ }
3375
+ )
3376
+ ]
3377
+ },
3378
+ u.verdi
3379
+ );
3380
+ })
3381
+ }
3382
+ ),
3383
+ /* @__PURE__ */ jsxs12(View13, { style: { gap: tema.space.sm }, children: [
3384
+ /* @__PURE__ */ jsxs12(Text10, { style: { color: tema.color.textSecondary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }, children: [
3385
+ tekst.setningLabel,
3386
+ " ",
3387
+ /* @__PURE__ */ jsx14(Text10, { style: { color: tema.color.textMuted }, children: tekst.setningValgfritt })
3388
+ ] }),
3389
+ /* @__PURE__ */ jsx14(
2844
3390
  TextInput3,
2845
3391
  {
2846
3392
  testID: "hvordan-setning",
@@ -2849,9 +3395,7 @@ function HvordanGikkDet({
2849
3395
  onChangeText: setSetning,
2850
3396
  maxLength: SETNING_MAKS,
2851
3397
  multiline: true,
2852
- numberOfLines: 3,
2853
- placeholder: tekst.setningPlaceholder,
2854
- placeholderTextColor: tema.color.textMuted,
3398
+ numberOfLines: 2,
2855
3399
  style: {
2856
3400
  backgroundColor: tema.color.surfaceRaised,
2857
3401
  borderWidth: tema.hairline,
@@ -2861,24 +3405,33 @@ function HvordanGikkDet({
2861
3405
  color: tema.color.textPrimary,
2862
3406
  fontSize: tema.font.body,
2863
3407
  lineHeight: tema.lineHeight.body,
2864
- minHeight: tema.touch * 2,
3408
+ minHeight: tema.touch * 1.5,
2865
3409
  textAlignVertical: "top"
2866
3410
  }
2867
3411
  }
2868
3412
  )
2869
3413
  ] }),
2870
- feil ? /* @__PURE__ */ jsx13(Banner, { live: true, ikon: "warning-outline", tone: "danger", children: tekst.svarFeil(feil) }) : null,
2871
- /* @__PURE__ */ jsx13(
3414
+ valgt === "ikke" && onMeldFeil ? /* @__PURE__ */ jsx14(
3415
+ Tekstknapp,
3416
+ {
3417
+ testID: "meld-feil",
3418
+ ikon: "bug-outline",
3419
+ label: tekst.meldFeil,
3420
+ disabled: sender,
3421
+ onPress: () => onMeldFeil("ikke", tekstVerdi())
3422
+ }
3423
+ ) : null,
3424
+ feil ? /* @__PURE__ */ jsx14(Banner, { live: true, ikon: "warning-outline", tone: "danger", children: tekst.svarFeil(feil) }) : null,
3425
+ /* @__PURE__ */ jsx14(
2872
3426
  Btn,
2873
3427
  {
2874
3428
  testID: "hvordan-lagre",
2875
3429
  label: tekst.lagre,
2876
- hint: tekst.lagreHint,
2877
3430
  disabled: valgt === void 0 || sender,
3431
+ busy: sender,
2878
3432
  onPress: () => {
2879
3433
  if (valgt === void 0) return;
2880
- const trimmet = setning.trim();
2881
- onLagre(valgt, trimmet.length > 0 ? trimmet : void 0);
3434
+ onLagre(valgt, tekstVerdi());
2882
3435
  }
2883
3436
  }
2884
3437
  )
@@ -2889,15 +3442,13 @@ function HvordanGikkDet({
2889
3442
 
2890
3443
  // src/program/Oppfolging.tsx
2891
3444
  import "react";
2892
- import { Text as Text10, View as View13 } from "react-native";
2893
- import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
3445
+ import { View as View14 } from "react-native";
3446
+ import { Fragment as Fragment3, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
2894
3447
  function tarSvar(kind) {
2895
3448
  return kind === "hvordan_gikk_det" || kind === "sjekkpunkt";
2896
3449
  }
2897
3450
  function Oppfolging({
2898
3451
  oppfolging,
2899
- kontaktNr,
2900
- maksKontakter,
2901
3452
  onSenere,
2902
3453
  onSvar,
2903
3454
  onAapneOppgavene,
@@ -2905,45 +3456,28 @@ function Oppfolging({
2905
3456
  }) {
2906
3457
  const tema = useTema();
2907
3458
  const art = tarSvar(oppfolging.kind) ? "spoersmaal" : oppfolging.kind === "tilbud_om_utgang" ? "utgang" : "paaminnelse";
2908
- const ikon = art === "spoersmaal" ? "flask-outline" : art === "utgang" ? "exit-outline" : "calendar-outline";
2909
- const hint = art === "spoersmaal" ? tekst.oppfolgingKontakt(kontaktNr, maksKontakter) : art === "utgang" ? tekst.oppfolgingUtgangHint(kontaktNr, maksKontakter) : tekst.oppfolgingPaaminnelseHint(kontaktNr, maksKontakter);
2910
- return /* @__PURE__ */ jsxs12(
2911
- View13,
3459
+ return /* @__PURE__ */ jsxs13(
3460
+ View14,
2912
3461
  {
2913
3462
  testID: `oppfolging-${oppfolging.id}`,
2914
3463
  accessibilityLabel: tekst.oppfolgingRegion,
2915
3464
  style: {
2916
3465
  backgroundColor: tema.color.brandBg,
2917
- borderWidth: tema.hairline,
2918
- borderColor: tema.color.brand,
2919
3466
  borderRadius: tema.radius.lg,
2920
3467
  padding: tema.space.md,
2921
- gap: tema.space.sm
3468
+ gap: tema.space.md
2922
3469
  },
2923
3470
  children: [
2924
- /* @__PURE__ */ jsxs12(View13, { style: { flexDirection: "row", gap: tema.space.sm, alignItems: "flex-start" }, children: [
2925
- /* @__PURE__ */ jsx14(Ikon, { navn: ikon, farge: tema.color.textPrimary }),
2926
- /* @__PURE__ */ jsxs12(View13, { style: { flex: 1, gap: tema.space.xs }, children: [
2927
- /* @__PURE__ */ jsx14(Text10, { style: { color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }, children: oppfolging.question }),
2928
- /* @__PURE__ */ jsx14(Hint, { children: hint })
2929
- ] })
3471
+ /* @__PURE__ */ jsxs13(View14, { style: { flexDirection: "row", gap: tema.space.sm, alignItems: "flex-start" }, children: [
3472
+ /* @__PURE__ */ jsx15(View14, { style: { paddingTop: tema.space.xs }, children: /* @__PURE__ */ jsx15(Ikon, { navn: "flask-outline", farge: tema.color.brand }) }),
3473
+ /* @__PURE__ */ jsx15(View14, { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsx15(H, { nivaa: 3, meta: tekst.oppfolgingKost, children: oppfolging.question }) })
2930
3474
  ] }),
2931
- /* @__PURE__ */ jsx14(View13, { style: { flexDirection: "row", gap: tema.space.sm }, children: art === "utgang" ? /* @__PURE__ */ jsxs12(Fragment2, { children: [
2932
- /* @__PURE__ */ jsx14(Btn, { grow: true, variant: "secondary", testID: `bli-vaerende-${oppfolging.id}`, label: tekst.bliVaerende, onPress: onSenere }),
2933
- /* @__PURE__ */ jsx14(
2934
- Btn,
2935
- {
2936
- grow: true,
2937
- variant: "danger",
2938
- testID: `gaa-ut-${oppfolging.id}`,
2939
- ikon: "exit-outline",
2940
- label: tekst.gaaUtBekreft,
2941
- onPress: onGaaUt
2942
- }
2943
- )
2944
- ] }) : /* @__PURE__ */ jsxs12(Fragment2, { children: [
2945
- /* @__PURE__ */ jsx14(Btn, { grow: true, variant: "secondary", testID: `senere-${oppfolging.id}`, label: tekst.senere, onPress: onSenere }),
2946
- art === "spoersmaal" ? /* @__PURE__ */ jsx14(Btn, { grow: true, testID: `svar-naa-${oppfolging.id}`, label: tekst.svarNaa, onPress: onSvar }) : /* @__PURE__ */ jsx14(Btn, { grow: true, testID: `aapne-oppgavene-${oppfolging.id}`, label: tekst.aapneOppgavene, onPress: onAapneOppgavene })
3475
+ /* @__PURE__ */ jsx15(View14, { style: { flexDirection: "row", gap: tema.space.sm }, children: art === "utgang" ? /* @__PURE__ */ jsxs13(Fragment3, { children: [
3476
+ /* @__PURE__ */ jsx15(Btn, { grow: true, variant: "secondary", testID: `bli-vaerende-${oppfolging.id}`, label: tekst.bliVaerende, onPress: onSenere }),
3477
+ /* @__PURE__ */ jsx15(Btn, { grow: true, variant: "secondary", testID: `gaa-ut-${oppfolging.id}`, ikon: "exit-outline", label: tekst.gaaUtBekreft, onPress: onGaaUt })
3478
+ ] }) : /* @__PURE__ */ jsxs13(Fragment3, { children: [
3479
+ /* @__PURE__ */ jsx15(Btn, { grow: true, variant: "secondary", testID: `senere-${oppfolging.id}`, label: tekst.senere, onPress: onSenere }),
3480
+ art === "spoersmaal" ? /* @__PURE__ */ jsx15(Btn, { grow: true, testID: `svar-naa-${oppfolging.id}`, label: tekst.svarNaa, onPress: onSvar }) : /* @__PURE__ */ jsx15(Btn, { grow: true, testID: `aapne-oppgavene-${oppfolging.id}`, label: tekst.aapneOppgavene, onPress: onAapneOppgavene })
2947
3481
  ] }) })
2948
3482
  ]
2949
3483
  }
@@ -2952,52 +3486,73 @@ function Oppfolging({
2952
3486
 
2953
3487
  // src/program/Oppgaver.tsx
2954
3488
  import "react";
2955
- import { Text as Text11, View as View14 } from "react-native";
2956
- import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
3489
+ import { Text as Text11, View as View15 } from "react-native";
3490
+ import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
2957
3491
  function Oppgaver({
2958
3492
  tasks,
2959
3493
  completions,
3494
+ over,
2960
3495
  onGjort
2961
3496
  }) {
2962
3497
  const tema = useTema();
2963
3498
  const ferdig = new Map(completions.map((c) => [c.taskId, c]));
2964
- return /* @__PURE__ */ jsx15(View14, { testID: "oppgaver", accessibilityLabel: tekst.oppgaverTittel, style: { gap: tema.space.sm }, children: [...tasks].sort((a, b) => a.order - b.order).map((o) => {
3499
+ return /* @__PURE__ */ jsx16(View15, { testID: "oppgaver", accessibilityLabel: tekst.oppgaverTittel, children: [...tasks].sort((a, b) => a.order - b.order).map((o, i) => {
2965
3500
  const c = ferdig.get(o.id);
2966
- return /* @__PURE__ */ jsxs13(
2967
- View14,
3501
+ const meta = c ? tekst.oppgaveGjortMeta(formaterFrist(c.at), utfallEtikett(c.outcome)) : tekst.oppgaveTid(o.estimatedMinutes, o.screenHint);
3502
+ return /* @__PURE__ */ jsxs14(
3503
+ View15,
2968
3504
  {
2969
3505
  testID: `oppgave-${o.id}`,
3506
+ accessibilityLabel: tekst.oppgaveRadA11y(i + 1, o.title, c ? meta : tekst.oppgaveIkkeGjort),
2970
3507
  style: {
2971
3508
  flexDirection: "row",
2972
3509
  alignItems: "center",
2973
3510
  gap: tema.space.sm,
2974
- paddingVertical: tema.space.xs,
2975
- borderBottomWidth: tema.hairline,
2976
- borderBottomColor: tema.color.border
3511
+ minHeight: tema.touch + tema.space.sm,
3512
+ paddingVertical: tema.space.sm,
3513
+ borderTopWidth: i === 0 ? 0 : tema.hairline,
3514
+ borderTopColor: tema.color.border
2977
3515
  },
2978
3516
  children: [
2979
- /* @__PURE__ */ jsxs13(View14, { style: { flex: 1, gap: tema.space.xs }, children: [
2980
- /* @__PURE__ */ jsx15(Text11, { style: { color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }, children: o.title }),
2981
- /* @__PURE__ */ jsxs13(Hint, { children: [
2982
- c ? tekst.oppgaveGjortMed(utfallEtikett(c.outcome)) : `${tekst.oppgaveIkkeBegynt} \xB7 ${tekst.akseptOppgaveTid(o.estimatedMinutes)}`,
2983
- c?.text ? ` \xB7 \xAB${c.text}\xBB` : ""
2984
- ] })
3517
+ /* @__PURE__ */ jsx16(
3518
+ View15,
3519
+ {
3520
+ style: {
3521
+ width: tema.space.lg,
3522
+ height: tema.space.lg,
3523
+ borderRadius: tema.radius.pill,
3524
+ alignItems: "center",
3525
+ justifyContent: "center",
3526
+ backgroundColor: c ? tema.color.success : "transparent",
3527
+ borderWidth: c ? 0 : tema.hairline * 2,
3528
+ borderStyle: "dashed",
3529
+ borderColor: tema.color.borderStrong
3530
+ },
3531
+ children: c ? /* @__PURE__ */ jsx16(Ikon, { navn: "checkmark-outline", storrelse: "minste", farge: tema.color.bg }) : null
3532
+ }
3533
+ ),
3534
+ /* @__PURE__ */ jsxs14(View15, { style: { flex: 1, minWidth: 0 }, children: [
3535
+ /* @__PURE__ */ jsx16(
3536
+ Text11,
3537
+ {
3538
+ testID: `oppgave-tittel-${o.id}`,
3539
+ style: { color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body, fontWeight: tema.weight.semibold },
3540
+ children: o.title
3541
+ }
3542
+ ),
3543
+ /* @__PURE__ */ jsx16(Meta, { testID: `oppgave-meta-${o.id}`, children: meta }),
3544
+ c?.text ? /* @__PURE__ */ jsx16(Sek, { testID: `oppgave-setning-${o.id}`, children: c.text }) : null
2985
3545
  ] }),
2986
- c ? (
2987
- // Merket er den eneste flaten der ikonet står alene, så etiketten
2988
- // ligger på containeren: skjermleseren hører utfallet, ikke «hake».
2989
- /* @__PURE__ */ jsx15(View14, { accessibilityLabel: tekst.oppgaveGjortMed(utfallEtikett(c.outcome)), accessible: true, children: /* @__PURE__ */ jsx15(Ikon, { navn: "checkmark-circle-outline", farge: tema.color.success }) })
2990
- ) : /* @__PURE__ */ jsx15(
3546
+ !c && !over ? /* @__PURE__ */ jsx16(
2991
3547
  Btn,
2992
3548
  {
2993
- variant: "secondary",
3549
+ variant: "tonet",
2994
3550
  testID: `gjort-${o.id}`,
2995
- ikon: "checkmark-circle-outline",
2996
3551
  label: tekst.oppgaveGjort,
2997
3552
  accessibilityLabel: tekst.oppgaveGjortLabel(o.title),
2998
3553
  onPress: () => onGjort(o)
2999
3554
  }
3000
- )
3555
+ ) : null
3001
3556
  ]
3002
3557
  },
3003
3558
  o.id
@@ -3005,8 +3560,33 @@ function Oppgaver({
3005
3560
  }) });
3006
3561
  }
3007
3562
 
3563
+ // src/program/ProgramSpor.tsx
3564
+ import "react";
3565
+ import { jsx as jsx17 } from "react/jsx-runtime";
3566
+ function programErOver(deltakelse, program, naa = /* @__PURE__ */ new Date()) {
3567
+ return deltakelse.status === "fullfoert" || new Date(program.closesAt).getTime() < naa.getTime();
3568
+ }
3569
+ function programledd(deltakelse, program, naa = /* @__PURE__ */ new Date()) {
3570
+ const over = programErOver(deltakelse, program, naa);
3571
+ const gjort = deltakelse.completions.length;
3572
+ const av = program.tasks.length;
3573
+ const alt = av > 0 && gjort >= av;
3574
+ return [
3575
+ { nokkel: "ble-med", etikett: tekst.programBleMed, tilstand: "gjort", detalj: formaterFrist(deltakelse.joinedAt) },
3576
+ {
3577
+ nokkel: "gjort",
3578
+ etikett: tekst.programGjort(gjort, av),
3579
+ ...over || alt ? { tilstand: "gjort" } : { tilstand: "naa", ikon: "flask-outline", detalj: tekst.programNaarDetPasser }
3580
+ },
3581
+ over ? { nokkel: "over", etikett: tekst.programOver, tilstand: "gjort", detalj: formaterFrist(program.closesAt) } : { nokkel: "over", etikett: tekst.programOver, tilstand: "kommer", tall: formaterKortFrist(program.closesAt) }
3582
+ ];
3583
+ }
3584
+ function ProgramSpor({ deltakelse, program }) {
3585
+ return /* @__PURE__ */ jsx17(Sporingslinje, { ledd: programledd(deltakelse, program), testID: "program-spor", etikett: tekst.programSporEtikett });
3586
+ }
3587
+
3008
3588
  // src/program/InnspelProgram.tsx
3009
- import { Fragment as Fragment3, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
3589
+ import { Fragment as Fragment4, jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
3010
3590
  function InnspelProgram({
3011
3591
  invitationToken,
3012
3592
  onEndring,
@@ -3024,10 +3604,9 @@ function InnspelProgram({
3024
3604
  const [dialog, setDialog] = useState7();
3025
3605
  const [svarFeil, setSvarFeil] = useState7();
3026
3606
  const [lagtBort, setLagtBort] = useState7(/* @__PURE__ */ new Set());
3027
- const [meldFeilFor, setMeldFeilFor] = useState7();
3028
3607
  const leggBort = useCallback4((id) => setLagtBort((s) => /* @__PURE__ */ new Set([...s, id])), []);
3029
3608
  const lagreSvar = useCallback4(
3030
- async (outcome, text) => {
3609
+ async (outcome, text, meldEtterpaa = false) => {
3031
3610
  if (!dialog || !deltakelse) return;
3032
3611
  setSender(true);
3033
3612
  setSvarFeil(void 0);
@@ -3035,7 +3614,7 @@ function InnspelProgram({
3035
3614
  if (dialog.type === "oppgave") {
3036
3615
  const ny = await client.programs.completeTask(dialog.task.id, { outcome, ...text ? { text } : {} });
3037
3616
  setDeltakelse({ ...deltakelse, completions: [...deltakelse.completions, ny] });
3038
- if (outcome === "ikke" && onMeldFeil) setMeldFeilFor(dialog.task);
3617
+ if (meldEtterpaa && onMeldFeil) onMeldFeil(dialog.task);
3039
3618
  } else {
3040
3619
  await client.programs.respond(dialog.oppfolging.id, { outcome, ...text ? { text } : {} });
3041
3620
  setMine((m) => m ? { ...m, pendingFollowUps: m.pendingFollowUps.filter((f) => f.id !== dialog.oppfolging.id) } : m);
@@ -3095,14 +3674,12 @@ function InnspelProgram({
3095
3674
  if (!program) return null;
3096
3675
  if (deltakelse) {
3097
3676
  const kort = (mine?.pendingFollowUps ?? []).filter((f) => f.programId === program.id && !lagtBort.has(f.id)).sort((a, b) => a.emittedAt.localeCompare(b.emittedAt));
3098
- const forsteKontaktNr = Math.max(1, deltakelse.contactsSent - kort.length + 1);
3099
- return /* @__PURE__ */ jsxs14(View15, { testID: "program-deltakelse", accessibilityLabel: tekst.deltakelseRegion, style: { gap: tema.space.sm }, children: [
3100
- kort.map((f, i) => /* @__PURE__ */ jsx16(
3677
+ const over = programErOver(deltakelse, program);
3678
+ return /* @__PURE__ */ jsxs15(View16, { testID: "program-deltakelse", accessibilityLabel: tekst.deltakelseRegion, style: { gap: tema.space.md }, children: [
3679
+ kort.map((f) => /* @__PURE__ */ jsx18(
3101
3680
  Oppfolging,
3102
3681
  {
3103
3682
  oppfolging: f,
3104
- kontaktNr: forsteKontaktNr + i,
3105
- maksKontakter: program.maxContacts,
3106
3683
  onSenere: () => leggBort(f.id),
3107
3684
  onSvar: () => {
3108
3685
  setSvarFeil(void 0);
@@ -3113,50 +3690,37 @@ function InnspelProgram({
3113
3690
  },
3114
3691
  f.id
3115
3692
  )),
3116
- /* @__PURE__ */ jsxs14(Card, { children: [
3117
- /* @__PURE__ */ jsx16(H, { sub: tekst.deltakelsePeriode(periode(program.opensAt, program.closesAt), deltakelse.contactsSent, program.maxContacts), children: program.name }),
3118
- /* @__PURE__ */ jsx16(
3693
+ /* @__PURE__ */ jsxs15(Card, { style: { gap: tema.space.md }, children: [
3694
+ /* @__PURE__ */ jsx18(H, { children: program.name }),
3695
+ /* @__PURE__ */ jsx18(ProgramSpor, { deltakelse, program }),
3696
+ feil ? /* @__PURE__ */ jsx18(Banner, { live: true, ikon: "warning-outline", tone: "warning", children: feil }) : null,
3697
+ /* @__PURE__ */ jsx18(
3119
3698
  Oppgaver,
3120
3699
  {
3121
3700
  tasks: program.tasks,
3122
3701
  completions: deltakelse.completions,
3702
+ over,
3123
3703
  onGjort: (task) => {
3124
3704
  setSvarFeil(void 0);
3125
3705
  setDialog({ type: "oppgave", task });
3126
3706
  }
3127
3707
  }
3128
3708
  ),
3129
- meldFeilFor && onMeldFeil ? /* @__PURE__ */ jsxs14(View15, { style: { gap: tema.space.xs }, children: [
3130
- /* @__PURE__ */ jsx16(Hint, { children: tekst.meldFeilHint }),
3131
- /* @__PURE__ */ jsx16(
3132
- Btn,
3133
- {
3134
- variant: "secondary",
3135
- testID: "meld-feil",
3136
- ikon: "bug-outline",
3137
- label: tekst.meldFeil,
3138
- onPress: () => {
3139
- const task = meldFeilFor;
3140
- setMeldFeilFor(void 0);
3141
- onMeldFeil(task);
3142
- }
3143
- }
3144
- )
3145
- ] }) : null,
3146
- /* @__PURE__ */ jsx16(Btn, { variant: "ghost", testID: "gaa-ut", ikon: "exit-outline", label: tekst.gaaUt, onPress: () => setViserGaaUt(true) })
3709
+ /* @__PURE__ */ jsx18(Tekstknapp, { noytral: true, testID: "gaa-ut", ikon: "exit-outline", label: tekst.gaaUt, onPress: () => setViserGaaUt(true) })
3147
3710
  ] }),
3148
- dialog ? /* @__PURE__ */ jsx16(
3711
+ dialog ? /* @__PURE__ */ jsx18(
3149
3712
  HvordanGikkDet,
3150
3713
  {
3151
- under: dialog.type === "oppgave" ? dialog.task.title : dialog.oppfolging.question,
3714
+ ...dialog.type === "oppgave" ? { under: dialog.task.title } : { spoersmaal: dialog.oppfolging.question },
3152
3715
  sender,
3153
3716
  ...svarFeil ? { feil: svarFeil } : {},
3717
+ ...dialog.type === "oppgave" && onMeldFeil ? { onMeldFeil: (outcome, text) => void lagreSvar(outcome, text, true) } : {},
3154
3718
  onLagre: (outcome, text) => void lagreSvar(outcome, text),
3155
3719
  onLukk: () => setDialog(void 0)
3156
3720
  }
3157
3721
  ) : null,
3158
- viserGaaUt ? /* @__PURE__ */ jsx16(Modal4, { visible: true, transparent: true, animationType: "fade", onRequestClose: () => setViserGaaUt(false), accessibilityViewIsModal: true, children: /* @__PURE__ */ jsx16(View15, { style: { flex: 1, backgroundColor: tema.color.scrim, justifyContent: "flex-end", padding: tema.space.md }, children: /* @__PURE__ */ jsxs14(
3159
- View15,
3722
+ viserGaaUt ? /* @__PURE__ */ jsx18(Modal4, { visible: true, transparent: true, animationType: "fade", onRequestClose: () => setViserGaaUt(false), accessibilityViewIsModal: true, children: /* @__PURE__ */ jsx18(View16, { style: { flex: 1, backgroundColor: tema.color.scrim, justifyContent: "flex-end", padding: tema.space.md }, children: /* @__PURE__ */ jsxs15(
3723
+ View16,
3160
3724
  {
3161
3725
  testID: "gaa-ut-dialog",
3162
3726
  accessibilityViewIsModal: true,
@@ -3169,11 +3733,11 @@ function InnspelProgram({
3169
3733
  gap: tema.space.md
3170
3734
  },
3171
3735
  children: [
3172
- /* @__PURE__ */ jsx16(H, { children: tekst.gaaUtTittel }),
3173
- /* @__PURE__ */ jsx16(Text12, { style: { color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }, children: tekst.gaaUtTekst(program.name) }),
3174
- /* @__PURE__ */ jsxs14(View15, { style: { flexDirection: "row", gap: tema.space.sm }, children: [
3175
- /* @__PURE__ */ jsx16(Btn, { grow: true, variant: "secondary", testID: "bli-vaerende", label: tekst.bliVaerende, onPress: () => setViserGaaUt(false) }),
3176
- /* @__PURE__ */ jsx16(
3736
+ /* @__PURE__ */ jsx18(H, { nivaa: 3, children: tekst.gaaUtTittel }),
3737
+ /* @__PURE__ */ jsx18(Brodtekst, { children: tekst.gaaUtTekst(program.name) }),
3738
+ /* @__PURE__ */ jsxs15(View16, { style: { flexDirection: "row", gap: tema.space.sm }, children: [
3739
+ /* @__PURE__ */ jsx18(Btn, { grow: true, variant: "secondary", testID: "bli-vaerende", label: tekst.bliVaerende, onPress: () => setViserGaaUt(false) }),
3740
+ /* @__PURE__ */ jsx18(
3177
3741
  Btn,
3178
3742
  {
3179
3743
  grow: true,
@@ -3192,45 +3756,40 @@ function InnspelProgram({
3192
3756
  ] });
3193
3757
  }
3194
3758
  if (!invitasjon || avvist) return null;
3195
- return /* @__PURE__ */ jsxs14(Fragment3, { children: [
3196
- /* @__PURE__ */ jsxs14(
3197
- View15,
3759
+ return /* @__PURE__ */ jsxs15(Fragment4, { children: [
3760
+ /* @__PURE__ */ jsxs15(
3761
+ View16,
3198
3762
  {
3199
3763
  testID: "program-banner",
3200
3764
  accessibilityLabel: tekst.invitasjonRegion,
3201
3765
  style: {
3202
3766
  backgroundColor: tema.color.brandBg,
3203
3767
  borderRadius: tema.radius.lg,
3204
- borderWidth: tema.hairline,
3205
- borderColor: tema.color.brand,
3206
3768
  padding: tema.space.md,
3207
- gap: tema.space.sm
3769
+ gap: tema.space.md
3208
3770
  },
3209
3771
  children: [
3210
- /* @__PURE__ */ jsxs14(View15, { style: { flexDirection: "row", gap: tema.space.sm, alignItems: "flex-start" }, children: [
3211
- /* @__PURE__ */ jsx16(Ikon, { navn: "flask-outline", farge: tema.color.textPrimary }),
3212
- /* @__PURE__ */ jsxs14(View15, { style: { flex: 1, gap: tema.space.xs }, children: [
3213
- /* @__PURE__ */ jsx16(Text12, { style: { color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }, children: tekst.invitasjonHva(program.name) }),
3214
- /* @__PURE__ */ jsx16(Hint, { children: tekst.invitasjonKontakter(program.maxContacts) })
3215
- ] }),
3216
- /* @__PURE__ */ jsx16(
3217
- Pressable9,
3772
+ /* @__PURE__ */ jsxs15(View16, { style: { flexDirection: "row", gap: tema.space.sm, alignItems: "flex-start" }, children: [
3773
+ /* @__PURE__ */ jsx18(View16, { style: { paddingTop: tema.space.xs }, children: /* @__PURE__ */ jsx18(Ikon, { navn: "flask-outline", farge: tema.color.brand }) }),
3774
+ /* @__PURE__ */ jsx18(View16, { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsx18(H, { nivaa: 3, meta: tekst.invitasjonMeta(program.tasks.length, periode(program.opensAt, program.closesAt)), children: tekst.invitasjonHva(program.name) }) }),
3775
+ /* @__PURE__ */ jsx18(
3776
+ Pressable8,
3218
3777
  {
3219
3778
  testID: "avvis-invitasjon",
3220
3779
  accessibilityRole: "button",
3221
3780
  accessibilityLabel: tekst.avvisInvitasjon,
3222
3781
  onPress: () => setAvvist(true),
3223
3782
  style: { minWidth: tema.touch, minHeight: tema.touch, alignItems: "center", justifyContent: "center" },
3224
- children: /* @__PURE__ */ jsx16(Ikon, { navn: "close-outline", farge: tema.color.textSecondary })
3783
+ children: /* @__PURE__ */ jsx18(Ikon, { navn: "close-outline", farge: tema.color.textSecondary })
3225
3784
  }
3226
3785
  )
3227
3786
  ] }),
3228
- feil && !viserAksept ? /* @__PURE__ */ jsx16(Banner, { live: true, ikon: "warning-outline", tone: "danger", children: tekst.akseptFeil(feil) }) : null,
3229
- /* @__PURE__ */ jsx16(Btn, { variant: "secondary", testID: "les-mer", label: tekst.lesMer, onPress: () => setViserAksept(true) })
3787
+ feil && !viserAksept ? /* @__PURE__ */ jsx18(Banner, { live: true, ikon: "warning-outline", tone: "danger", children: tekst.akseptFeil(feil) }) : null,
3788
+ /* @__PURE__ */ jsx18(Btn, { testID: "les-mer", label: tekst.lesMer, onPress: () => setViserAksept(true) })
3230
3789
  ]
3231
3790
  }
3232
3791
  ),
3233
- viserAksept ? /* @__PURE__ */ jsx16(
3792
+ viserAksept ? /* @__PURE__ */ jsx18(
3234
3793
  Aksept,
3235
3794
  {
3236
3795
  program,