version-pill-react 1.5.1 → 1.6.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.js CHANGED
@@ -147,13 +147,6 @@ function VersionPill({
147
147
  const [isOpen, setIsOpen] = (0, import_react.useState)(false);
148
148
  const [activeTab, setActiveTab] = (0, import_react.useState)("changelog");
149
149
  const [hasNewVersion, setHasNewVersion] = (0, import_react.useState)(false);
150
- const [showIdeaForm, setShowIdeaForm] = (0, import_react.useState)(false);
151
- const [ideaTitle, setIdeaTitle] = (0, import_react.useState)("");
152
- const [ideaDescription, setIdeaDescription] = (0, import_react.useState)("");
153
- const [ideaAuthorName, setIdeaAuthorName] = (0, import_react.useState)("");
154
- const [ideaAuthorEmail, setIdeaAuthorEmail] = (0, import_react.useState)("");
155
- const [submittingIdea, setSubmittingIdea] = (0, import_react.useState)(false);
156
- const [ideaSubmitMessage, setIdeaSubmitMessage] = (0, import_react.useState)(null);
157
150
  const [roadmapView, setRoadmapView] = (0, import_react.useState)("board");
158
151
  const [isMobile, setIsMobile] = (0, import_react.useState)(false);
159
152
  const [votedIdeas, setVotedIdeas] = (0, import_react.useState)(/* @__PURE__ */ new Set());
@@ -254,45 +247,14 @@ function VersionPill({
254
247
  } catch {
255
248
  }
256
249
  }, [projectId, baseUrl]);
257
- const submitIdea = (0, import_react.useCallback)(async () => {
258
- if (!ideaTitle.trim()) return;
259
- setSubmittingIdea(true);
260
- setIdeaSubmitMessage(null);
261
- try {
262
- const response = await fetch(`${baseUrl}/api/ideas/${projectId}`, {
263
- method: "POST",
264
- headers: { "Content-Type": "application/json" },
265
- body: JSON.stringify({
266
- title: ideaTitle.trim(),
267
- description: ideaDescription.trim() || void 0,
268
- authorName: ideaAuthorName.trim() || void 0,
269
- authorEmail: ideaAuthorEmail.trim() || void 0
270
- })
271
- });
272
- if (!response.ok) {
273
- const error = await response.json().catch(() => ({ error: "Failed to submit" }));
274
- throw new Error(error.error || "Failed to submit idea");
275
- }
276
- setIdeaSubmitMessage({ type: "success", text: "Thanks! Your idea has been submitted." });
277
- setIdeaTitle("");
278
- setIdeaDescription("");
279
- setShowIdeaForm(false);
280
- fetchIdeas();
281
- } catch (err) {
282
- setIdeaSubmitMessage({ type: "error", text: err.message || "Failed to submit idea" });
283
- } finally {
284
- setSubmittingIdea(false);
285
- }
286
- }, [baseUrl, projectId, ideaTitle, ideaDescription, ideaAuthorName, ideaAuthorEmail, fetchIdeas]);
287
250
  const voteIdea = (0, import_react.useCallback)(async (ideaId) => {
288
251
  if (votedIdeas.has(ideaId)) return;
289
252
  setIdeas((prev) => prev.map((i) => i.id === ideaId ? { ...i, votes: i.votes + 1 } : i));
290
253
  setVotedIdeas((prev) => new Set(prev).add(ideaId));
291
254
  try {
292
- await fetch(`${baseUrl}/api/ideas/${projectId}/vote`, {
255
+ await fetch(`${baseUrl}/api/vote/${ideaId}`, {
293
256
  method: "POST",
294
- headers: { "Content-Type": "application/json" },
295
- body: JSON.stringify({ ideaId })
257
+ headers: { "Content-Type": "application/json" }
296
258
  });
297
259
  } catch {
298
260
  setIdeas((prev) => prev.map((i) => i.id === ideaId ? { ...i, votes: i.votes - 1 } : i));
@@ -927,10 +889,12 @@ function VersionPill({
927
889
  }) })
928
890
  ] }) }),
929
891
  activeTab === "ideas" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { maxWidth: 640, width: "100%", overflowY: "auto", flex: 1 }, children: [
930
- !showIdeaForm ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
931
- "button",
892
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
893
+ "a",
932
894
  {
933
- onClick: () => setShowIdeaForm(true),
895
+ href: `${baseUrl}/${projectId}/feature-requests`,
896
+ target: "_blank",
897
+ rel: "noopener noreferrer",
934
898
  style: {
935
899
  display: "flex",
936
900
  alignItems: "center",
@@ -940,195 +904,27 @@ function VersionPill({
940
904
  padding: "12px 16px",
941
905
  marginBottom: 20,
942
906
  borderRadius: 999,
943
- border: `1px dashed ${isLight ? "#d4d4d8" : "#3f3f46"}`,
944
- background: "transparent",
945
- color: isLight ? "#71717a" : "#a1a1aa",
907
+ border: `1px solid ${isLight ? "#22c55e" : "rgba(34,197,94,0.4)"}`,
908
+ background: isLight ? "rgba(34,197,94,0.05)" : "rgba(34,197,94,0.08)",
909
+ color: "#22c55e",
946
910
  fontSize: 14,
947
911
  fontWeight: 500,
948
912
  cursor: "pointer",
949
- transition: "all 150ms"
950
- },
951
- onMouseEnter: (e) => {
952
- e.currentTarget.style.borderColor = isLight ? "#a1a1aa" : "#71717a";
953
- e.currentTarget.style.color = isLight ? "#52525b" : "#d4d4d8";
954
- },
955
- onMouseLeave: (e) => {
956
- e.currentTarget.style.borderColor = isLight ? "#d4d4d8" : "#3f3f46";
957
- e.currentTarget.style.color = isLight ? "#71717a" : "#a1a1aa";
913
+ transition: "all 150ms",
914
+ textDecoration: "none",
915
+ boxSizing: "border-box"
958
916
  },
959
917
  children: [
960
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 18 }, children: "\u{1F4A1}" }),
961
- "Suggest a feature"
962
- ]
963
- }
964
- ) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
965
- "div",
966
- {
967
- style: {
968
- padding: 16,
969
- marginBottom: 20,
970
- borderRadius: 12,
971
- background: isLight ? "#f5f5f5" : "#151515",
972
- border: `1px solid ${isLight ? "#e5e5e5" : "#1f1f1f"}`
973
- },
974
- children: [
975
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 12 }, children: [
976
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontWeight: 600, color: isLight ? "#18181b" : "#fff" }, children: "Suggest a Feature" }),
977
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
978
- "button",
979
- {
980
- onClick: () => {
981
- setShowIdeaForm(false);
982
- setIdeaSubmitMessage(null);
983
- },
984
- style: {
985
- background: "transparent",
986
- border: "none",
987
- color: isLight ? "#71717a" : "#a1a1aa",
988
- cursor: "pointer",
989
- fontSize: 18
990
- },
991
- children: "\xD7"
992
- }
993
- )
994
- ] }),
995
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
996
- "input",
997
- {
998
- type: "text",
999
- value: ideaTitle,
1000
- onChange: (e) => setIdeaTitle(e.target.value),
1001
- placeholder: "Feature title *",
1002
- style: {
1003
- width: "100%",
1004
- padding: "10px 12px",
1005
- marginBottom: 8,
1006
- borderRadius: 6,
1007
- border: `1px solid ${isLight ? "#e5e5e5" : "#2a2a2a"}`,
1008
- background: isLight ? "#fff" : "#0a0a0a",
1009
- color: isLight ? "#18181b" : "#fff",
1010
- fontSize: 14,
1011
- outline: "none",
1012
- boxSizing: "border-box"
1013
- }
1014
- }
1015
- ),
1016
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1017
- "textarea",
1018
- {
1019
- value: ideaDescription,
1020
- onChange: (e) => setIdeaDescription(e.target.value),
1021
- placeholder: "Describe your idea...",
1022
- rows: 3,
1023
- style: {
1024
- width: "100%",
1025
- padding: "10px 12px",
1026
- marginBottom: 8,
1027
- borderRadius: 6,
1028
- border: `1px solid ${isLight ? "#e5e5e5" : "#2a2a2a"}`,
1029
- background: isLight ? "#fff" : "#0a0a0a",
1030
- color: isLight ? "#18181b" : "#fff",
1031
- fontSize: 14,
1032
- outline: "none",
1033
- resize: "none",
1034
- boxSizing: "border-box"
1035
- }
1036
- }
1037
- ),
1038
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gridTemplateColumns: isMobile ? "1fr" : "1fr 1fr", gap: 8, marginBottom: 12 }, children: [
1039
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1040
- "input",
1041
- {
1042
- type: "text",
1043
- value: ideaAuthorName,
1044
- onChange: (e) => setIdeaAuthorName(e.target.value),
1045
- placeholder: "Name (optional)",
1046
- style: {
1047
- width: "100%",
1048
- padding: "8px 12px",
1049
- borderRadius: 6,
1050
- border: `1px solid ${isLight ? "#e5e5e5" : "#2a2a2a"}`,
1051
- background: isLight ? "#fff" : "#0a0a0a",
1052
- color: isLight ? "#18181b" : "#fff",
1053
- fontSize: 13,
1054
- outline: "none",
1055
- boxSizing: "border-box"
1056
- }
1057
- }
1058
- ),
1059
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1060
- "input",
1061
- {
1062
- type: "email",
1063
- value: ideaAuthorEmail,
1064
- onChange: (e) => setIdeaAuthorEmail(e.target.value),
1065
- placeholder: "Email *",
1066
- style: {
1067
- width: "100%",
1068
- padding: "8px 12px",
1069
- borderRadius: 6,
1070
- border: `1px solid ${isLight ? "#e5e5e5" : "#2a2a2a"}`,
1071
- background: isLight ? "#fff" : "#0a0a0a",
1072
- color: isLight ? "#18181b" : "#fff",
1073
- fontSize: 13,
1074
- outline: "none",
1075
- boxSizing: "border-box"
1076
- }
1077
- }
1078
- )
1079
- ] }),
1080
- ideaSubmitMessage && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
1081
- padding: "8px 12px",
1082
- marginBottom: 12,
1083
- borderRadius: 6,
1084
- background: ideaSubmitMessage.type === "success" ? isLight ? "#dcfce7" : "#14532d" : isLight ? "#fee2e2" : "#450a0a",
1085
- color: ideaSubmitMessage.type === "success" ? isLight ? "#166534" : "#86efac" : isLight ? "#dc2626" : "#fca5a5",
1086
- fontSize: 13
1087
- }, children: ideaSubmitMessage.text }),
1088
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1089
- "button",
1090
- {
1091
- onClick: submitIdea,
1092
- disabled: submittingIdea || !ideaTitle.trim() || !ideaAuthorEmail.trim(),
1093
- style: {
1094
- width: "100%",
1095
- padding: "10px 16px",
1096
- borderRadius: 999,
1097
- border: "none",
1098
- background: "#22c55e",
1099
- color: "#fff",
1100
- fontSize: 14,
1101
- fontWeight: 500,
1102
- cursor: submittingIdea || !ideaTitle.trim() || !ideaAuthorEmail.trim() ? "not-allowed" : "pointer",
1103
- opacity: submittingIdea || !ideaTitle.trim() || !ideaAuthorEmail.trim() ? 0.6 : 1,
1104
- transition: "opacity 150ms"
1105
- },
1106
- children: submittingIdea ? "Submitting..." : "Submit Idea"
1107
- }
1108
- )
918
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 16 }, children: "\u{1F4A1}" }),
919
+ "Suggest a feature",
920
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", style: { marginLeft: 2 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M7 17L17 7M17 7H7M17 7v10" }) })
1109
921
  ]
1110
922
  }
1111
923
  ),
1112
- ideasArray.length === 0 && !showIdeaForm ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { textAlign: "center", padding: 60, color: isLight ? "#71717a" : "#a1a1aa" }, children: [
924
+ ideasArray.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { textAlign: "center", padding: 60, color: isLight ? "#71717a" : "#a1a1aa" }, children: [
1113
925
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", style: { marginBottom: 12, opacity: 0.5 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" }) }),
1114
926
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 16, fontWeight: 500, marginBottom: 8 }, children: "No feature requests yet" }),
1115
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1116
- "button",
1117
- {
1118
- onClick: () => setShowIdeaForm(true),
1119
- style: {
1120
- padding: "8px 20px",
1121
- borderRadius: 999,
1122
- border: "none",
1123
- background: "#22c55e",
1124
- color: "#fff",
1125
- fontSize: 14,
1126
- fontWeight: 500,
1127
- cursor: "pointer"
1128
- },
1129
- children: "Suggest a feature"
1130
- }
1131
- )
927
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 13, color: isLight ? "#a1a1aa" : "#525252" }, children: "Be the first to suggest one!" })
1132
928
  ] }) : (() => {
1133
929
  const statusOrder = ["under review", "planned", "in progress", "new", "shipped"];
1134
930
  const grouped = {};