@david-xpn/llm-ui-feedback 0.1.4 → 0.1.5

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
@@ -826,13 +826,23 @@ function DraftModal({ pendingContext, addingDraft, onAdd, onCancel }) {
826
826
  // src/components/SubmitModal.tsx
827
827
  var import_react5 = require("react");
828
828
  var import_jsx_runtime6 = require("react/jsx-runtime");
829
- function SubmitModal({ count, onSubmit, onCancel, submitting }) {
829
+ function SubmitModal({ count, onSubmit, onCancel, onDone, submitting, submittedUrl }) {
830
830
  const [title, setTitle] = (0, import_react5.useState)("");
831
+ const [copied, setCopied] = (0, import_react5.useState)(false);
831
832
  const handleSubmit = () => {
832
833
  if (title.trim() && !submitting) {
833
834
  onSubmit(title.trim());
834
835
  }
835
836
  };
837
+ const handleCopy = async () => {
838
+ if (!submittedUrl) return;
839
+ try {
840
+ await navigator.clipboard.writeText(submittedUrl);
841
+ setCopied(true);
842
+ setTimeout(() => setCopied(false), 2e3);
843
+ } catch {
844
+ }
845
+ };
836
846
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
837
847
  "div",
838
848
  {
@@ -847,9 +857,12 @@ function SubmitModal({ count, onSubmit, onCancel, submitting }) {
847
857
  fontFamily: "system-ui, sans-serif"
848
858
  },
849
859
  onClick: (e) => {
850
- if (e.target === e.currentTarget && !submitting) onCancel();
860
+ if (e.target === e.currentTarget) {
861
+ if (submittedUrl) onDone();
862
+ else if (!submitting) onCancel();
863
+ }
851
864
  },
852
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
865
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
853
866
  "div",
854
867
  {
855
868
  style: {
@@ -860,7 +873,64 @@ function SubmitModal({ count, onSubmit, onCancel, submitting }) {
860
873
  maxWidth: "90vw",
861
874
  boxShadow: "0 8px 32px rgba(0,0,0,0.2)"
862
875
  },
863
- children: [
876
+ children: submittedUrl ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
877
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { style: { margin: "0 0 16px", fontSize: 16 }, children: "Feedback Submitted" }),
878
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: { margin: "0 0 12px", fontSize: 14, color: "#6b7280" }, children: "Share this link to view the feedback:" }),
879
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", gap: 8 }, children: [
880
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
881
+ "input",
882
+ {
883
+ type: "text",
884
+ value: submittedUrl,
885
+ readOnly: true,
886
+ onFocus: (e) => e.target.select(),
887
+ style: {
888
+ flex: 1,
889
+ padding: 10,
890
+ borderRadius: 8,
891
+ border: "1px solid #d1d5db",
892
+ fontSize: 13,
893
+ boxSizing: "border-box",
894
+ color: "#374151",
895
+ background: "#f9fafb"
896
+ }
897
+ }
898
+ ),
899
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
900
+ "button",
901
+ {
902
+ onClick: handleCopy,
903
+ style: {
904
+ padding: "8px 14px",
905
+ borderRadius: 8,
906
+ border: "1px solid #d1d5db",
907
+ background: copied ? "#dcfce7" : "#f3f4f6",
908
+ color: copied ? "#166534" : "#374151",
909
+ fontSize: 13,
910
+ cursor: "pointer",
911
+ whiteSpace: "nowrap"
912
+ },
913
+ children: copied ? "Copied!" : "Copy"
914
+ }
915
+ )
916
+ ] }),
917
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { display: "flex", justifyContent: "flex-end", marginTop: 16 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
918
+ "button",
919
+ {
920
+ onClick: onDone,
921
+ style: {
922
+ padding: "8px 16px",
923
+ borderRadius: 6,
924
+ border: "none",
925
+ background: "#3b82f6",
926
+ color: "#fff",
927
+ fontSize: 13,
928
+ cursor: "pointer"
929
+ },
930
+ children: "Done"
931
+ }
932
+ ) })
933
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
864
934
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { style: { margin: "0 0 16px", fontSize: 16 }, children: "Submit Feedback" }),
865
935
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { style: { margin: "0 0 12px", fontSize: 14, color: "#6b7280" }, children: [
866
936
  count,
@@ -925,7 +995,7 @@ function SubmitModal({ count, onSubmit, onCancel, submitting }) {
925
995
  }
926
996
  )
927
997
  ] })
928
- ]
998
+ ] })
929
999
  }
930
1000
  )
931
1001
  }
@@ -1234,7 +1304,8 @@ var initialState = {
1234
1304
  selectedDraftIds: /* @__PURE__ */ new Set(),
1235
1305
  submitModalOpen: false,
1236
1306
  addingDraft: false,
1237
- submitting: false
1307
+ submitting: false,
1308
+ submittedShareUrl: null
1238
1309
  };
1239
1310
  function widgetReducer(state, action) {
1240
1311
  switch (action.type) {
@@ -1279,12 +1350,15 @@ function widgetReducer(state, action) {
1279
1350
  return { ...state, submitModalOpen: false };
1280
1351
  case "SET_SUBMITTING":
1281
1352
  return { ...state, submitting: action.submitting };
1353
+ case "SUBMIT_SUCCESS":
1354
+ return { ...state, submitting: false, submittedShareUrl: action.shareUrl };
1282
1355
  case "SUBMIT_COMPLETE": {
1283
1356
  const submitted = new Set(action.submittedIds);
1284
1357
  return {
1285
1358
  ...state,
1286
1359
  submitting: false,
1287
1360
  submitModalOpen: false,
1361
+ submittedShareUrl: null,
1288
1362
  drafts: state.drafts.filter((d) => !submitted.has(d.id)),
1289
1363
  selectedDraftIds: /* @__PURE__ */ new Set()
1290
1364
  };
@@ -1462,16 +1536,24 @@ function FeedbackWidget({
1462
1536
  });
1463
1537
  }
1464
1538
  }, [api]);
1539
+ const submittedDraftIdsRef = (0, import_react7.useRef)([]);
1465
1540
  const handleSubmit = (0, import_react7.useCallback)(async (title) => {
1466
1541
  dispatch({ type: "SET_SUBMITTING", submitting: true });
1467
1542
  const draftIds = Array.from(state.selectedDraftIds);
1543
+ submittedDraftIdsRef.current = draftIds;
1468
1544
  try {
1469
- await api.submitSession({ title, draftIds });
1470
- dispatch({ type: "SUBMIT_COMPLETE", submittedIds: draftIds });
1545
+ const result = await api.submitSession({ title, draftIds });
1546
+ const group = result.feedbackGroup;
1547
+ const shareUrl = group.shareToken ? `${apiUrl}/feedback-groups/${group.id}/markdown?token=${group.shareToken}` : "";
1548
+ dispatch({ type: "SUBMIT_SUCCESS", shareUrl });
1471
1549
  } catch {
1472
1550
  dispatch({ type: "SET_SUBMITTING", submitting: false });
1473
1551
  }
1474
- }, [state.selectedDraftIds, api]);
1552
+ }, [state.selectedDraftIds, api, apiUrl]);
1553
+ const handleSubmitDone = (0, import_react7.useCallback)(() => {
1554
+ dispatch({ type: "SUBMIT_COMPLETE", submittedIds: submittedDraftIdsRef.current });
1555
+ submittedDraftIdsRef.current = [];
1556
+ }, []);
1475
1557
  if (session.status === "loading") return null;
1476
1558
  return (0, import_react_dom.createPortal)(
1477
1559
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
@@ -1518,7 +1600,9 @@ function FeedbackWidget({
1518
1600
  count: state.selectedDraftIds.size,
1519
1601
  onSubmit: handleSubmit,
1520
1602
  onCancel: () => dispatch({ type: "CLOSE_SUBMIT_MODAL" }),
1521
- submitting: state.submitting
1603
+ onDone: handleSubmitDone,
1604
+ submitting: state.submitting,
1605
+ submittedUrl: state.submittedShareUrl
1522
1606
  }
1523
1607
  )
1524
1608
  ] }),