@innspel/react-native 0.3.0 → 0.4.0

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.cjs CHANGED
@@ -618,6 +618,32 @@ var tekst = {
618
618
  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.`,
619
619
  bliVaerende: "Bli v\xE6rende",
620
620
  gaaUtBekreft: "G\xE5 ut",
621
+ // 3c (M3.2) — oppgavene og «Hvordan gikk det?»: tre lukkede valg, aldri en skala
622
+ oppgaverTittel: "Oppgavene",
623
+ oppgaveIkkeBegynt: "Ikke begynt",
624
+ oppgaveGjort: "Gjort",
625
+ oppgaveGjortLabel: (tittel) => `Gjort: ${tittel}`,
626
+ oppgaveGjortMed: (utfall) => `Gjort \xB7 ${utfall}`,
627
+ hvordanGikkDet: "Hvordan gikk det?",
628
+ utfallFungerte: "Fungerte",
629
+ utfallDelvis: "Delvis",
630
+ utfallIkke: "Ikke",
631
+ setningLabel: "Vil du si \xE9n setning om det? (valgfritt)",
632
+ setningPlaceholder: "Kopien kom, men rullesjefen manglet p\xE5 torsdag.",
633
+ lagre: "Lagre",
634
+ lagreHint: "Ferdig \u2014 ingen flere sp\xF8rsm\xE5l n\xE5.",
635
+ /** Etter «Ikke»: feilsporet er vertens — plattformen navigerer aldri selv. */
636
+ meldFeil: "Meld det som feil",
637
+ meldFeilHint: "Gikk det ikke? Et innspill hjelper oss \xE5 finne ut hvorfor.",
638
+ svarFeil: (arsak) => `Kunne ikke lagre svaret: ${arsak}`,
639
+ // 3d (M3.2) — oppfølgingskortene (DD-34): arten avgjør knappene
640
+ oppfolgingRegion: "Oppf\xF8lging fra betaprogrammet",
641
+ oppfolgingKontakt: (nr, maks) => `Kontakt ${nr} av ${maks} \xB7 tar under ett minutt`,
642
+ oppfolgingPaaminnelseHint: (nr, maks) => `Kontakt ${nr} av ${maks} \xB7 planlagt p\xE5minnelse`,
643
+ oppfolgingUtgangHint: (nr, maks) => `Kontakt ${nr} av ${maks} \xB7 den siste vi sender`,
644
+ senere: "Senere",
645
+ svarNaa: "Svar n\xE5",
646
+ aapneOppgavene: "\xC5pne oppgavene",
621
647
  // Felles
622
648
  tilbake: "Tilbake",
623
649
  lukk: "Lukk",
@@ -1830,8 +1856,8 @@ function InnspelPrivate({ children, style }) {
1830
1856
 
1831
1857
  // src/program/InnspelProgram.tsx
1832
1858
  var import_core3 = require("@innspel/core");
1833
- var import_react14 = require("react");
1834
- var import_react_native13 = require("react-native");
1859
+ var import_react17 = require("react");
1860
+ var import_react_native16 = require("react-native");
1835
1861
 
1836
1862
  // src/program/Aksept.tsx
1837
1863
  var import_react13 = require("react");
@@ -1987,22 +2013,264 @@ function Aksept({
1987
2013
  ) }) });
1988
2014
  }
1989
2015
 
1990
- // src/program/InnspelProgram.tsx
2016
+ // src/program/HvordanGikkDet.tsx
2017
+ var import_react14 = require("react");
2018
+ var import_react_native13 = require("react-native");
1991
2019
  var import_jsx_runtime12 = require("react/jsx-runtime");
2020
+ var UTFALL = [
2021
+ { verdi: "fungerte", ikon: "\u2713", etikett: tekst.utfallFungerte },
2022
+ { verdi: "delvis", ikon: "\u25D0", etikett: tekst.utfallDelvis },
2023
+ { verdi: "ikke", ikon: "\u2715", etikett: tekst.utfallIkke }
2024
+ ];
2025
+ var SETNING_MAKS = 140;
2026
+ function utfallEtikett(verdi) {
2027
+ return UTFALL.find((u) => u.verdi === verdi)?.etikett ?? verdi;
2028
+ }
2029
+ function HvordanGikkDet({
2030
+ under,
2031
+ sender,
2032
+ feil,
2033
+ onLagre,
2034
+ onLukk
2035
+ }) {
2036
+ const tema = useTema();
2037
+ const [valgt, setValgt] = (0, import_react14.useState)();
2038
+ const [setning, setSetning] = (0, import_react14.useState)("");
2039
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.Modal, { visible: true, transparent: true, animationType: "fade", onRequestClose: onLukk, accessibilityViewIsModal: true, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.View, { style: { flex: 1, backgroundColor: tema.color.scrim, justifyContent: "flex-end", padding: tema.space.md }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2040
+ import_react_native13.View,
2041
+ {
2042
+ testID: "hvordan-gikk-det",
2043
+ accessibilityViewIsModal: true,
2044
+ style: {
2045
+ backgroundColor: tema.color.surface,
2046
+ borderRadius: tema.radius.lg,
2047
+ borderWidth: tema.hairline,
2048
+ borderColor: tema.color.borderStrong,
2049
+ padding: tema.space.md,
2050
+ gap: tema.space.md
2051
+ },
2052
+ children: [
2053
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Btn, { variant: "ghost", testID: "hvordan-tilbake", ikon: "\u2190", label: tekst.tilbake, onPress: onLukk }),
2054
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Hint, { children: under }),
2055
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(H, { children: tekst.hvordanGikkDet }),
2056
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.View, { testID: "utfall-gruppe", accessibilityRole: "radiogroup", accessibilityLabel: tekst.hvordanGikkDet, style: { flexDirection: "row", gap: tema.space.sm }, children: UTFALL.map((u) => {
2057
+ const aktiv = valgt === u.verdi;
2058
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2059
+ import_react_native13.Pressable,
2060
+ {
2061
+ testID: `utfall-${u.verdi}`,
2062
+ accessibilityRole: "radio",
2063
+ accessibilityLabel: u.etikett,
2064
+ accessibilityState: { checked: aktiv },
2065
+ onPress: () => setValgt(u.verdi),
2066
+ style: {
2067
+ flex: 1,
2068
+ minHeight: tema.touch,
2069
+ alignItems: "center",
2070
+ justifyContent: "center",
2071
+ gap: tema.space.xs,
2072
+ padding: tema.space.sm,
2073
+ borderRadius: tema.radius.md,
2074
+ borderWidth: tema.hairline,
2075
+ borderColor: aktiv ? tema.color.brand : tema.color.borderStrong,
2076
+ backgroundColor: aktiv ? tema.color.brandBg : tema.color.surfaceRaised
2077
+ },
2078
+ children: [
2079
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.Text, { accessibilityElementsHidden: true, importantForAccessibility: "no", style: { fontSize: tema.font.h3, color: tema.color.textPrimary }, children: u.ikon }),
2080
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.Text, { style: { color: tema.color.textPrimary, fontSize: tema.font.small, fontWeight: aktiv ? tema.weight.semibold : tema.weight.regular }, children: u.etikett })
2081
+ ]
2082
+ },
2083
+ u.verdi
2084
+ );
2085
+ }) }),
2086
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: { gap: tema.space.xs }, children: [
2087
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.Text, { style: { color: tema.color.textSecondary, fontSize: tema.font.small }, children: tekst.setningLabel }),
2088
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2089
+ import_react_native13.TextInput,
2090
+ {
2091
+ testID: "hvordan-setning",
2092
+ accessibilityLabel: tekst.setningLabel,
2093
+ value: setning,
2094
+ onChangeText: setSetning,
2095
+ maxLength: SETNING_MAKS,
2096
+ multiline: true,
2097
+ numberOfLines: 3,
2098
+ placeholder: tekst.setningPlaceholder,
2099
+ placeholderTextColor: tema.color.textMuted,
2100
+ style: {
2101
+ backgroundColor: tema.color.surfaceRaised,
2102
+ borderWidth: tema.hairline,
2103
+ borderColor: tema.color.borderStrong,
2104
+ borderRadius: tema.radius.md,
2105
+ padding: tema.space.md,
2106
+ color: tema.color.textPrimary,
2107
+ fontSize: tema.font.body,
2108
+ lineHeight: tema.lineHeight.body,
2109
+ minHeight: tema.touch * 2,
2110
+ textAlignVertical: "top"
2111
+ }
2112
+ }
2113
+ )
2114
+ ] }),
2115
+ feil ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Banner, { live: true, ikon: "\u26A0", tone: "danger", children: tekst.svarFeil(feil) }) : null,
2116
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2117
+ Btn,
2118
+ {
2119
+ testID: "hvordan-lagre",
2120
+ label: tekst.lagre,
2121
+ hint: tekst.lagreHint,
2122
+ disabled: valgt === void 0 || sender,
2123
+ onPress: () => {
2124
+ if (valgt === void 0) return;
2125
+ const trimmet = setning.trim();
2126
+ onLagre(valgt, trimmet.length > 0 ? trimmet : void 0);
2127
+ }
2128
+ }
2129
+ )
2130
+ ]
2131
+ }
2132
+ ) }) });
2133
+ }
2134
+
2135
+ // src/program/Oppfolging.tsx
2136
+ var import_react15 = require("react");
2137
+ var import_react_native14 = require("react-native");
2138
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2139
+ function tarSvar(kind) {
2140
+ return kind === "hvordan_gikk_det" || kind === "sjekkpunkt";
2141
+ }
2142
+ function Oppfolging({
2143
+ oppfolging,
2144
+ kontaktNr,
2145
+ maksKontakter,
2146
+ onSenere,
2147
+ onSvar,
2148
+ onAapneOppgavene,
2149
+ onGaaUt
2150
+ }) {
2151
+ const tema = useTema();
2152
+ const art = tarSvar(oppfolging.kind) ? "spoersmaal" : oppfolging.kind === "tilbud_om_utgang" ? "utgang" : "paaminnelse";
2153
+ const ikon = art === "spoersmaal" ? "\u{1F9EA}" : art === "utgang" ? "\u{1F6AA}" : "\u{1F4C5}";
2154
+ const hint = art === "spoersmaal" ? tekst.oppfolgingKontakt(kontaktNr, maksKontakter) : art === "utgang" ? tekst.oppfolgingUtgangHint(kontaktNr, maksKontakter) : tekst.oppfolgingPaaminnelseHint(kontaktNr, maksKontakter);
2155
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2156
+ import_react_native14.View,
2157
+ {
2158
+ testID: `oppfolging-${oppfolging.id}`,
2159
+ accessibilityLabel: tekst.oppfolgingRegion,
2160
+ style: {
2161
+ backgroundColor: tema.color.brandBg,
2162
+ borderWidth: tema.hairline,
2163
+ borderColor: tema.color.brand,
2164
+ borderRadius: tema.radius.lg,
2165
+ padding: tema.space.md,
2166
+ gap: tema.space.sm
2167
+ },
2168
+ children: [
2169
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { style: { flexDirection: "row", gap: tema.space.sm, alignItems: "flex-start" }, children: [
2170
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native14.Text, { accessibilityElementsHidden: true, importantForAccessibility: "no", style: { fontSize: tema.font.h3 }, children: ikon }),
2171
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { style: { flex: 1, gap: tema.space.xs }, children: [
2172
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native14.Text, { style: { color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }, children: oppfolging.question }),
2173
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Hint, { children: hint })
2174
+ ] })
2175
+ ] }),
2176
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native14.View, { style: { flexDirection: "row", gap: tema.space.sm }, children: art === "utgang" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
2177
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Btn, { grow: true, variant: "secondary", testID: `bli-vaerende-${oppfolging.id}`, label: tekst.bliVaerende, onPress: onSenere }),
2178
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Btn, { grow: true, variant: "danger", testID: `gaa-ut-${oppfolging.id}`, ikon: "\u{1F6AA}", label: tekst.gaaUtBekreft, onPress: onGaaUt })
2179
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
2180
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Btn, { grow: true, variant: "secondary", testID: `senere-${oppfolging.id}`, label: tekst.senere, onPress: onSenere }),
2181
+ art === "spoersmaal" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Btn, { grow: true, testID: `svar-naa-${oppfolging.id}`, label: tekst.svarNaa, onPress: onSvar }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Btn, { grow: true, testID: `aapne-oppgavene-${oppfolging.id}`, label: tekst.aapneOppgavene, onPress: onAapneOppgavene })
2182
+ ] }) })
2183
+ ]
2184
+ }
2185
+ );
2186
+ }
2187
+
2188
+ // src/program/Oppgaver.tsx
2189
+ var import_react16 = require("react");
2190
+ var import_react_native15 = require("react-native");
2191
+ var import_jsx_runtime14 = require("react/jsx-runtime");
2192
+ function Oppgaver({
2193
+ tasks,
2194
+ completions,
2195
+ onGjort
2196
+ }) {
2197
+ const tema = useTema();
2198
+ const ferdig = new Map(completions.map((c) => [c.taskId, c]));
2199
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native15.View, { testID: "oppgaver", accessibilityLabel: tekst.oppgaverTittel, style: { gap: tema.space.sm }, children: [...tasks].sort((a, b) => a.order - b.order).map((o) => {
2200
+ const c = ferdig.get(o.id);
2201
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2202
+ import_react_native15.View,
2203
+ {
2204
+ testID: `oppgave-${o.id}`,
2205
+ style: {
2206
+ flexDirection: "row",
2207
+ alignItems: "center",
2208
+ gap: tema.space.sm,
2209
+ paddingVertical: tema.space.xs,
2210
+ borderBottomWidth: tema.hairline,
2211
+ borderBottomColor: tema.color.border
2212
+ },
2213
+ children: [
2214
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native15.View, { style: { flex: 1, gap: tema.space.xs }, children: [
2215
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native15.Text, { style: { color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }, children: o.title }),
2216
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Hint, { children: [
2217
+ c ? tekst.oppgaveGjortMed(utfallEtikett(c.outcome)) : `${tekst.oppgaveIkkeBegynt} \xB7 ${tekst.akseptOppgaveTid(o.estimatedMinutes)}`,
2218
+ c?.text ? ` \xB7 \xAB${c.text}\xBB` : ""
2219
+ ] })
2220
+ ] }),
2221
+ c ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native15.Text, { accessibilityLabel: tekst.oppgaveGjortMed(utfallEtikett(c.outcome)), style: { color: tema.color.success, fontSize: tema.font.h3 }, children: "\u2713" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Btn, { variant: "secondary", testID: `gjort-${o.id}`, ikon: "\u2713", label: tekst.oppgaveGjort, accessibilityLabel: tekst.oppgaveGjortLabel(o.title), onPress: () => onGjort(o) })
2222
+ ]
2223
+ },
2224
+ o.id
2225
+ );
2226
+ }) });
2227
+ }
2228
+
2229
+ // src/program/InnspelProgram.tsx
2230
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1992
2231
  function InnspelProgram({
1993
2232
  invitationToken,
1994
- onEndring
2233
+ onEndring,
2234
+ onMeldFeil
1995
2235
  }) {
1996
2236
  const { client } = useInnspel();
1997
2237
  const tema = useTema();
1998
- const [mine, setMine] = (0, import_react14.useState)();
1999
- const [deltakelse, setDeltakelse] = (0, import_react14.useState)();
2000
- const [viserAksept, setViserAksept] = (0, import_react14.useState)(false);
2001
- const [viserGaaUt, setViserGaaUt] = (0, import_react14.useState)(false);
2002
- const [avvist, setAvvist] = (0, import_react14.useState)(false);
2003
- const [sender, setSender] = (0, import_react14.useState)(false);
2004
- const [feil, setFeil] = (0, import_react14.useState)();
2005
- (0, import_react14.useEffect)(() => {
2238
+ const [mine, setMine] = (0, import_react17.useState)();
2239
+ const [deltakelse, setDeltakelse] = (0, import_react17.useState)();
2240
+ const [viserAksept, setViserAksept] = (0, import_react17.useState)(false);
2241
+ const [viserGaaUt, setViserGaaUt] = (0, import_react17.useState)(false);
2242
+ const [avvist, setAvvist] = (0, import_react17.useState)(false);
2243
+ const [sender, setSender] = (0, import_react17.useState)(false);
2244
+ const [feil, setFeil] = (0, import_react17.useState)();
2245
+ const [dialog, setDialog] = (0, import_react17.useState)();
2246
+ const [svarFeil, setSvarFeil] = (0, import_react17.useState)();
2247
+ const [lagtBort, setLagtBort] = (0, import_react17.useState)(/* @__PURE__ */ new Set());
2248
+ const [meldFeilFor, setMeldFeilFor] = (0, import_react17.useState)();
2249
+ const leggBort = (0, import_react17.useCallback)((id) => setLagtBort((s) => /* @__PURE__ */ new Set([...s, id])), []);
2250
+ const lagreSvar = (0, import_react17.useCallback)(
2251
+ async (outcome, text) => {
2252
+ if (!dialog || !deltakelse) return;
2253
+ setSender(true);
2254
+ setSvarFeil(void 0);
2255
+ try {
2256
+ if (dialog.type === "oppgave") {
2257
+ const ny = await client.programs.completeTask(dialog.task.id, { outcome, ...text ? { text } : {} });
2258
+ setDeltakelse({ ...deltakelse, completions: [...deltakelse.completions, ny] });
2259
+ if (outcome === "ikke" && onMeldFeil) setMeldFeilFor(dialog.task);
2260
+ } else {
2261
+ await client.programs.respond(dialog.oppfolging.id, { outcome, ...text ? { text } : {} });
2262
+ setMine((m) => m ? { ...m, pendingFollowUps: m.pendingFollowUps.filter((f) => f.id !== dialog.oppfolging.id) } : m);
2263
+ }
2264
+ setDialog(void 0);
2265
+ } catch (e) {
2266
+ setSvarFeil(e instanceof import_core3.InnspelApiError ? e.message : "tjeneren svarte ikke.");
2267
+ } finally {
2268
+ setSender(false);
2269
+ }
2270
+ },
2271
+ [client, deltakelse, dialog, onMeldFeil]
2272
+ );
2273
+ (0, import_react17.useEffect)(() => {
2006
2274
  if (client.isAnonymous) return;
2007
2275
  let levende = true;
2008
2276
  void client.programs.list().then((svar) => {
@@ -2014,7 +2282,7 @@ function InnspelProgram({
2014
2282
  levende = false;
2015
2283
  };
2016
2284
  }, [client]);
2017
- const bliMed = (0, import_react14.useCallback)(async () => {
2285
+ const bliMed = (0, import_react17.useCallback)(async () => {
2018
2286
  if (!invitationToken) return;
2019
2287
  setSender(true);
2020
2288
  setFeil(void 0);
@@ -2029,7 +2297,7 @@ function InnspelProgram({
2029
2297
  setSender(false);
2030
2298
  }
2031
2299
  }, [client, invitationToken, onEndring]);
2032
- const gaaUt = (0, import_react14.useCallback)(async () => {
2300
+ const gaaUt = (0, import_react17.useCallback)(async () => {
2033
2301
  if (!deltakelse) return;
2034
2302
  setSender(true);
2035
2303
  try {
@@ -2047,14 +2315,69 @@ function InnspelProgram({
2047
2315
  const program = deltakelse?.program ?? invitasjon?.program;
2048
2316
  if (!program) return null;
2049
2317
  if (deltakelse) {
2050
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { testID: "program-deltakelse", accessibilityLabel: tekst.deltakelseRegion, style: { gap: tema.space.sm }, children: [
2051
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Card, { children: [
2052
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(H, { sub: tekst.deltakelsePeriode(periode(program.opensAt, program.closesAt), deltakelse.contactsSent, program.maxContacts), children: program.name }),
2053
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Hint, { children: tekst.deltakelseOppgaverKommer }),
2054
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Btn, { variant: "ghost", testID: "gaa-ut", ikon: "\u{1F6AA}", label: tekst.gaaUt, onPress: () => setViserGaaUt(true) })
2318
+ const kort = (mine?.pendingFollowUps ?? []).filter((f) => f.programId === program.id && !lagtBort.has(f.id)).sort((a, b) => a.emittedAt.localeCompare(b.emittedAt));
2319
+ const forsteKontaktNr = Math.max(1, deltakelse.contactsSent - kort.length + 1);
2320
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native16.View, { testID: "program-deltakelse", accessibilityLabel: tekst.deltakelseRegion, style: { gap: tema.space.sm }, children: [
2321
+ kort.map((f, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2322
+ Oppfolging,
2323
+ {
2324
+ oppfolging: f,
2325
+ kontaktNr: forsteKontaktNr + i,
2326
+ maksKontakter: program.maxContacts,
2327
+ onSenere: () => leggBort(f.id),
2328
+ onSvar: () => {
2329
+ setSvarFeil(void 0);
2330
+ setDialog({ type: "oppfolging", oppfolging: f });
2331
+ },
2332
+ onAapneOppgavene: () => leggBort(f.id),
2333
+ onGaaUt: () => setViserGaaUt(true)
2334
+ },
2335
+ f.id
2336
+ )),
2337
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Card, { children: [
2338
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(H, { sub: tekst.deltakelsePeriode(periode(program.opensAt, program.closesAt), deltakelse.contactsSent, program.maxContacts), children: program.name }),
2339
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2340
+ Oppgaver,
2341
+ {
2342
+ tasks: program.tasks,
2343
+ completions: deltakelse.completions,
2344
+ onGjort: (task) => {
2345
+ setSvarFeil(void 0);
2346
+ setDialog({ type: "oppgave", task });
2347
+ }
2348
+ }
2349
+ ),
2350
+ meldFeilFor && onMeldFeil ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native16.View, { style: { gap: tema.space.xs }, children: [
2351
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Hint, { children: tekst.meldFeilHint }),
2352
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2353
+ Btn,
2354
+ {
2355
+ variant: "secondary",
2356
+ testID: "meld-feil",
2357
+ ikon: "\u{1F41E}",
2358
+ label: tekst.meldFeil,
2359
+ onPress: () => {
2360
+ const task = meldFeilFor;
2361
+ setMeldFeilFor(void 0);
2362
+ onMeldFeil(task);
2363
+ }
2364
+ }
2365
+ )
2366
+ ] }) : null,
2367
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Btn, { variant: "ghost", testID: "gaa-ut", ikon: "\u{1F6AA}", label: tekst.gaaUt, onPress: () => setViserGaaUt(true) })
2055
2368
  ] }),
2056
- viserGaaUt ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.Modal, { visible: true, transparent: true, animationType: "fade", onRequestClose: () => setViserGaaUt(false), accessibilityViewIsModal: true, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.View, { style: { flex: 1, backgroundColor: tema.color.scrim, justifyContent: "flex-end", padding: tema.space.md }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2057
- import_react_native13.View,
2369
+ dialog ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2370
+ HvordanGikkDet,
2371
+ {
2372
+ under: dialog.type === "oppgave" ? dialog.task.title : dialog.oppfolging.question,
2373
+ sender,
2374
+ ...svarFeil ? { feil: svarFeil } : {},
2375
+ onLagre: (outcome, text) => void lagreSvar(outcome, text),
2376
+ onLukk: () => setDialog(void 0)
2377
+ }
2378
+ ) : null,
2379
+ viserGaaUt ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native16.Modal, { visible: true, transparent: true, animationType: "fade", onRequestClose: () => setViserGaaUt(false), accessibilityViewIsModal: true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native16.View, { style: { flex: 1, backgroundColor: tema.color.scrim, justifyContent: "flex-end", padding: tema.space.md }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2380
+ import_react_native16.View,
2058
2381
  {
2059
2382
  testID: "gaa-ut-dialog",
2060
2383
  accessibilityViewIsModal: true,
@@ -2067,11 +2390,11 @@ function InnspelProgram({
2067
2390
  gap: tema.space.md
2068
2391
  },
2069
2392
  children: [
2070
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(H, { children: tekst.gaaUtTittel }),
2071
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.Text, { style: { color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }, children: tekst.gaaUtTekst(program.name) }),
2072
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: { flexDirection: "row", gap: tema.space.sm }, children: [
2073
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Btn, { grow: true, variant: "secondary", testID: "bli-vaerende", label: tekst.bliVaerende, onPress: () => setViserGaaUt(false) }),
2074
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Btn, { grow: true, variant: "danger", testID: "bekreft-gaa-ut", ikon: "\u{1F6AA}", label: tekst.gaaUtBekreft, disabled: sender, onPress: () => void gaaUt() })
2393
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(H, { children: tekst.gaaUtTittel }),
2394
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native16.Text, { style: { color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }, children: tekst.gaaUtTekst(program.name) }),
2395
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native16.View, { style: { flexDirection: "row", gap: tema.space.sm }, children: [
2396
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Btn, { grow: true, variant: "secondary", testID: "bli-vaerende", label: tekst.bliVaerende, onPress: () => setViserGaaUt(false) }),
2397
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Btn, { grow: true, variant: "danger", testID: "bekreft-gaa-ut", ikon: "\u{1F6AA}", label: tekst.gaaUtBekreft, disabled: sender, onPress: () => void gaaUt() })
2075
2398
  ] })
2076
2399
  ]
2077
2400
  }
@@ -2079,9 +2402,9 @@ function InnspelProgram({
2079
2402
  ] });
2080
2403
  }
2081
2404
  if (!invitasjon || avvist) return null;
2082
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
2083
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2084
- import_react_native13.View,
2405
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
2406
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2407
+ import_react_native16.View,
2085
2408
  {
2086
2409
  testID: "program-banner",
2087
2410
  accessibilityLabel: tekst.invitasjonRegion,
@@ -2094,30 +2417,30 @@ function InnspelProgram({
2094
2417
  gap: tema.space.sm
2095
2418
  },
2096
2419
  children: [
2097
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: { flexDirection: "row", gap: tema.space.sm, alignItems: "flex-start" }, children: [
2098
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.Text, { accessibilityElementsHidden: true, importantForAccessibility: "no", style: { fontSize: tema.font.h3 }, children: "\u{1F9EA}" }),
2099
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: { flex: 1, gap: tema.space.xs }, children: [
2100
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.Text, { style: { color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }, children: tekst.invitasjonHva(program.name) }),
2101
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Hint, { children: tekst.invitasjonKontakter(program.maxContacts) })
2420
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native16.View, { style: { flexDirection: "row", gap: tema.space.sm, alignItems: "flex-start" }, children: [
2421
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native16.Text, { accessibilityElementsHidden: true, importantForAccessibility: "no", style: { fontSize: tema.font.h3 }, children: "\u{1F9EA}" }),
2422
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native16.View, { style: { flex: 1, gap: tema.space.xs }, children: [
2423
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native16.Text, { style: { color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }, children: tekst.invitasjonHva(program.name) }),
2424
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Hint, { children: tekst.invitasjonKontakter(program.maxContacts) })
2102
2425
  ] }),
2103
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2104
- import_react_native13.Pressable,
2426
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2427
+ import_react_native16.Pressable,
2105
2428
  {
2106
2429
  testID: "avvis-invitasjon",
2107
2430
  accessibilityRole: "button",
2108
2431
  accessibilityLabel: tekst.avvisInvitasjon,
2109
2432
  onPress: () => setAvvist(true),
2110
2433
  style: { minWidth: tema.touch, minHeight: tema.touch, alignItems: "center", justifyContent: "center" },
2111
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.Text, { style: { color: tema.color.textSecondary, fontSize: tema.font.body }, children: "\u2715" })
2434
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native16.Text, { style: { color: tema.color.textSecondary, fontSize: tema.font.body }, children: "\u2715" })
2112
2435
  }
2113
2436
  )
2114
2437
  ] }),
2115
- feil && !viserAksept ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Banner, { live: true, ikon: "\u26A0", tone: "danger", children: tekst.akseptFeil(feil) }) : null,
2116
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Btn, { variant: "secondary", testID: "les-mer", label: tekst.lesMer, onPress: () => setViserAksept(true) })
2438
+ feil && !viserAksept ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Banner, { live: true, ikon: "\u26A0", tone: "danger", children: tekst.akseptFeil(feil) }) : null,
2439
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Btn, { variant: "secondary", testID: "les-mer", label: tekst.lesMer, onPress: () => setViserAksept(true) })
2117
2440
  ]
2118
2441
  }
2119
2442
  ),
2120
- viserAksept ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2443
+ viserAksept ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2121
2444
  Aksept,
2122
2445
  {
2123
2446
  program,