File size: 3,047 Bytes
709db16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/** Bottom sheet to finish a pending entry: Worked | Partial | Failed. */

import { useEffect, useState } from "preact/hooks";
import { patchEntry, type Entry } from "../api";
import { Button } from "./Button";
import { ResultChips, type ResolveResult } from "./ResultChips";
import { Sheet } from "./Sheet";
import { useToast } from "./Toast";

type Props = {
  open: boolean;
  queue: Entry[];
  onClose: () => void;
  onQueueChange: (next: Entry[]) => void;
  onResolved: () => void;
};

export function ResolvePendingSheet({
  open,
  queue,
  onClose,
  onQueueChange,
  onResolved,
}: Props) {
  const toast = useToast();
  const current = queue[0] ?? null;
  const [result, setResult] = useState<ResolveResult | null>(null);
  const [remedy, setRemedy] = useState("");
  const [busy, setBusy] = useState(false);

  useEffect(() => {
    if (!current) return;
    setResult(null);
    setRemedy(current.remedy || "");
  }, [current?.id]);

  if (!open) return null;

  const save = async () => {
    if (!current || !result) return;
    setBusy(true);
    try {
      await patchEntry(current.id, { result, remedy: remedy.trim() });
      toast.show("Saved");
      onResolved();
      const rest = queue.slice(1);
      if (rest.length) {
        onQueueChange(rest);
      } else {
        onClose();
      }
    } catch (err) {
      toast.show(err instanceof Error ? err.message : "Could not save", "error");
    } finally {
      setBusy(false);
    }
  };

  return (
    <Sheet
      open={open}
      title="Finish entry"
      onClose={onClose}
      tall
    >
      {current ? (
        <div class="resolve-sheet stack">
          <div class="resolve-snippet surface-card">
            {current.activity ? (
              <p class="muted resolve-activity">{current.activity}</p>
            ) : null}
            <p>{current.happened}</p>
          </div>

          <div>
            <span class="field-label">Result</span>
            <ResultChips
              value={result}
              excludePending
              onChange={(value) => setResult(value as ResolveResult)}
            />
          </div>

          <div>
            <label class="field-label" for="resolve-remedy">
              Remedy
            </label>
            <input
              id="resolve-remedy"
              class="field-input"
              type="text"
              value={remedy}
              placeholder="What did you try?"
              onInput={(e) => setRemedy((e.target as HTMLInputElement).value)}
            />
          </div>

          {queue.length > 1 ? (
            <p class="muted">{queue.length - 1} more pending after this</p>
          ) : null}

          <div class="resolve-sticky">
            <Button
              disabled={busy || !result}
              onClick={save}
              className="btn-large"
            >
              {busy ? "Saving…" : "Save result"}
            </Button>
          </div>
        </div>
      ) : (
        <p class="muted">Nothing pending.</p>
      )}
    </Sheet>
  );
}