version-pill-react 1.3.0 → 1.5.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.mjs CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  // src/index.tsx
4
4
  import { useState, useEffect, useCallback } from "react";
5
+ import { createPortal } from "react-dom";
5
6
  import clsx from "clsx";
6
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
8
  var DEFAULT_BASE_URL = "https://www.versionpill.com";
@@ -38,16 +39,37 @@ var TYPE_COLORS = {
38
39
  improvement: "#3b82f6",
39
40
  chore: "#71717a"
40
41
  };
41
- var COLUMN_LABELS = {
42
- backlog: "Backlog",
43
- todo: "Planned",
44
- "in-progress": "In Progress",
45
- "in progress": "In Progress",
46
- inProgress: "In Progress",
47
- done: "Shipped",
48
- shipped: "Shipped",
49
- completed: "Shipped"
42
+ var TYPE_EMOJIS = {
43
+ feature: "\u2728",
44
+ bug: "\u{1F41B}",
45
+ improvement: "\u{1F4C8}",
46
+ chore: "\u{1F527}",
47
+ idea: "\u{1F4A1}"
50
48
  };
49
+ var PRIORITY_COLORS = {
50
+ urgent: "#ef4444",
51
+ high: "#f97316",
52
+ medium: "#3b82f6",
53
+ low: "#9ca3af"
54
+ };
55
+ var STATUS_CONFIG = {
56
+ new: { color: "#3b82f6", label: "New" },
57
+ "under review": { color: "#f59e0b", label: "Under Review" },
58
+ planned: { color: "#8b5cf6", label: "Planned" },
59
+ "in progress": { color: "#3b82f6", label: "In Progress" },
60
+ shipped: { color: "#22c55e", label: "Shipped" },
61
+ declined: { color: "#ef4444", label: "Declined" }
62
+ };
63
+ var FADE_IN_KEYFRAMES = `
64
+ @keyframes vpFadeIn {
65
+ from { opacity: 0; }
66
+ to { opacity: 1; }
67
+ }
68
+ @keyframes vpSlideUp {
69
+ from { opacity: 0; transform: translateY(8px); }
70
+ to { opacity: 1; transform: translateY(0); }
71
+ }
72
+ `;
51
73
  function useTheme(theme) {
52
74
  const [resolved, setResolved] = useState("light");
53
75
  useEffect(() => {
@@ -80,6 +102,8 @@ function VersionPill({
80
102
  const [project, setProject] = useState(null);
81
103
  const [versions, setVersions] = useState([]);
82
104
  const [roadmapTasks, setRoadmapTasks] = useState([]);
105
+ const [roadmapColumns, setRoadmapColumns] = useState([]);
106
+ const [roadmapItems, setRoadmapItems] = useState([]);
83
107
  const [ideas, setIdeas] = useState([]);
84
108
  const [loading, setLoading] = useState(true);
85
109
  const [isOpen, setIsOpen] = useState(false);
@@ -92,6 +116,10 @@ function VersionPill({
92
116
  const [ideaAuthorEmail, setIdeaAuthorEmail] = useState("");
93
117
  const [submittingIdea, setSubmittingIdea] = useState(false);
94
118
  const [ideaSubmitMessage, setIdeaSubmitMessage] = useState(null);
119
+ const [roadmapView, setRoadmapView] = useState("board");
120
+ const [isMobile, setIsMobile] = useState(false);
121
+ const [votedIdeas, setVotedIdeas] = useState(/* @__PURE__ */ new Set());
122
+ const [collapsedColumns, setCollapsedColumns] = useState(/* @__PURE__ */ new Set());
95
123
  const resolvedTheme = useTheme(theme);
96
124
  const isLight = resolvedTheme === "light";
97
125
  const sizeConfig = SIZE_CONFIG[size];
@@ -137,6 +165,11 @@ function VersionPill({
137
165
  const response = await fetch(`${baseUrl}/api/roadmap/${projectId}`);
138
166
  if (!response.ok) return;
139
167
  const data = await response.json();
168
+ if (data.columns && data.items) {
169
+ setRoadmapColumns(data.columns);
170
+ setRoadmapItems(data.items);
171
+ return;
172
+ }
140
173
  let tasks = [];
141
174
  if (Array.isArray(data.tasks)) {
142
175
  tasks = data.tasks;
@@ -156,6 +189,20 @@ function VersionPill({
156
189
  const planned = (grouped.planned || []).map((t) => mapTask(t, "todo"));
157
190
  tasks = [...inProgress, ...planned];
158
191
  }
192
+ setRoadmapColumns([
193
+ { id: "planned", name: "Planned" },
194
+ { id: "in_progress", name: "In Progress" },
195
+ { id: "completed", name: "Completed" }
196
+ ]);
197
+ setRoadmapItems(tasks.map((t) => ({
198
+ id: t.id,
199
+ title: t.title,
200
+ description: t.description,
201
+ type: t.type,
202
+ priority: t.priority,
203
+ itemType: "task",
204
+ columnId: t.column === "in-progress" ? "in_progress" : t.column === "done" || t.column === "shipped" ? "completed" : "planned"
205
+ })));
159
206
  setRoadmapTasks(tasks);
160
207
  } catch {
161
208
  }
@@ -199,9 +246,63 @@ function VersionPill({
199
246
  setSubmittingIdea(false);
200
247
  }
201
248
  }, [baseUrl, projectId, ideaTitle, ideaDescription, ideaAuthorName, ideaAuthorEmail, fetchIdeas]);
249
+ const voteIdea = useCallback(async (ideaId) => {
250
+ if (votedIdeas.has(ideaId)) return;
251
+ setIdeas((prev) => prev.map((i) => i.id === ideaId ? { ...i, votes: i.votes + 1 } : i));
252
+ setVotedIdeas((prev) => new Set(prev).add(ideaId));
253
+ try {
254
+ await fetch(`${baseUrl}/api/ideas/${projectId}/vote`, {
255
+ method: "POST",
256
+ headers: { "Content-Type": "application/json" },
257
+ body: JSON.stringify({ ideaId })
258
+ });
259
+ } catch {
260
+ setIdeas((prev) => prev.map((i) => i.id === ideaId ? { ...i, votes: i.votes - 1 } : i));
261
+ setVotedIdeas((prev) => {
262
+ const s = new Set(prev);
263
+ s.delete(ideaId);
264
+ return s;
265
+ });
266
+ }
267
+ }, [baseUrl, projectId, votedIdeas]);
202
268
  useEffect(() => {
203
269
  fetchVersion();
204
270
  }, [fetchVersion]);
271
+ useEffect(() => {
272
+ if (isOpen) {
273
+ const prev = document.body.style.overflow;
274
+ document.body.style.overflow = "hidden";
275
+ return () => {
276
+ document.body.style.overflow = prev;
277
+ };
278
+ }
279
+ }, [isOpen]);
280
+ useEffect(() => {
281
+ if (!isOpen) return;
282
+ const handleKey = (e) => {
283
+ if (e.key === "Escape") setIsOpen(false);
284
+ };
285
+ document.addEventListener("keydown", handleKey);
286
+ return () => document.removeEventListener("keydown", handleKey);
287
+ }, [isOpen]);
288
+ useEffect(() => {
289
+ const check = () => setIsMobile(window.innerWidth < 640);
290
+ check();
291
+ window.addEventListener("resize", check);
292
+ return () => window.removeEventListener("resize", check);
293
+ }, []);
294
+ useEffect(() => {
295
+ if (!isOpen) return;
296
+ const id = "vp-modal-keyframes";
297
+ if (document.getElementById(id)) return;
298
+ const style2 = document.createElement("style");
299
+ style2.id = id;
300
+ style2.textContent = FADE_IN_KEYFRAMES;
301
+ document.head.appendChild(style2);
302
+ return () => {
303
+ document.getElementById(id)?.remove();
304
+ };
305
+ }, [isOpen]);
205
306
  const handleOpen = () => {
206
307
  if (onClick) {
207
308
  onClick();
@@ -318,494 +419,842 @@ function VersionPill({
318
419
  );
319
420
  };
320
421
  const versionsArray = Array.isArray(versions) ? versions : [];
321
- const tasksArray = Array.isArray(roadmapTasks) ? roadmapTasks : [];
322
422
  const ideasArray = Array.isArray(ideas) ? ideas : [];
323
- const groupedTasks = tasksArray.reduce((acc, task) => {
324
- const col = task.column || "backlog";
325
- if (!acc[col]) acc[col] = [];
326
- acc[col].push(task);
327
- return acc;
328
- }, {});
329
423
  return /* @__PURE__ */ jsxs(Fragment, { children: [
330
424
  /* @__PURE__ */ jsx("div", { className: clsx(positionStyles[position], className), style: { display: "inline-flex" }, children: renderBadge() }),
331
- isOpen && /* @__PURE__ */ jsx("div", { style: {
332
- position: "fixed",
333
- top: 0,
334
- left: 0,
335
- right: 0,
336
- bottom: 0,
337
- width: "100vw",
338
- height: "100vh",
339
- zIndex: 2147483647,
340
- display: "flex",
341
- flexDirection: "column",
342
- boxSizing: "border-box",
343
- background: isLight ? "#fff" : "#0a0a0a"
344
- }, children: /* @__PURE__ */ jsxs(
345
- "div",
346
- {
347
- style: {
348
- display: "flex",
349
- flexDirection: "column",
350
- width: "100%",
351
- height: "100%",
352
- borderRadius: 12,
353
- overflow: "hidden"
354
- },
355
- children: [
356
- /* @__PURE__ */ jsxs(
357
- "div",
358
- {
359
- style: {
360
- flexShrink: 0,
361
- padding: "16px 20px",
362
- borderBottom: `1px solid ${isLight ? "#e5e5e5" : "#1f1f1f"}`,
363
- display: "flex",
364
- alignItems: "center",
365
- justifyContent: "space-between"
366
- },
367
- children: [
368
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 12 }, children: [
369
- project?.icon && /* @__PURE__ */ jsx("span", { style: { fontSize: 24 }, children: project.icon }),
370
- /* @__PURE__ */ jsxs("div", { children: [
371
- /* @__PURE__ */ jsx("h2", { style: { fontWeight: 600, fontSize: 18, color: isLight ? "#18181b" : "#fff", margin: 0 }, children: project?.name || "What's New" }),
372
- /* @__PURE__ */ jsxs("p", { style: { fontSize: 13, color: isLight ? "#71717a" : "#a1a1aa", margin: 0 }, children: [
373
- "v",
374
- currentVersion
375
- ] })
376
- ] })
377
- ] }),
378
- /* @__PURE__ */ jsx(
379
- "button",
380
- {
381
- onClick: () => setIsOpen(false),
382
- style: {
383
- width: 36,
384
- height: 36,
385
- display: "flex",
386
- alignItems: "center",
387
- justifyContent: "center",
388
- borderRadius: 8,
389
- background: isLight ? "#f5f5f5" : "#1f1f1f",
390
- border: "none",
391
- cursor: "pointer",
392
- color: isLight ? "#71717a" : "#a1a1aa",
393
- transition: "background 150ms"
394
- },
395
- onMouseEnter: (e) => e.currentTarget.style.background = isLight ? "#e5e5e5" : "#2a2a2a",
396
- onMouseLeave: (e) => e.currentTarget.style.background = isLight ? "#f5f5f5" : "#1f1f1f",
397
- children: /* @__PURE__ */ jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "M18 6L6 18M6 6l12 12" }) })
398
- }
399
- )
400
- ]
425
+ isOpen && createPortal(
426
+ /* @__PURE__ */ jsxs(Fragment, { children: [
427
+ /* @__PURE__ */ jsx(
428
+ "div",
429
+ {
430
+ onClick: () => setIsOpen(false),
431
+ style: {
432
+ position: "fixed",
433
+ top: 0,
434
+ left: 0,
435
+ right: 0,
436
+ bottom: 0,
437
+ zIndex: 2147483646,
438
+ background: "rgba(0,0,0,0.5)",
439
+ animation: "vpFadeIn 200ms ease-out"
401
440
  }
402
- ),
403
- /* @__PURE__ */ jsx(
404
- "div",
405
- {
406
- style: {
407
- flexShrink: 0,
408
- display: "flex",
409
- gap: 4,
410
- padding: "12px 20px",
411
- borderBottom: `1px solid ${isLight ? "#e5e5e5" : "#1f1f1f"}`
412
- },
413
- children: ["changelog", "roadmap", "ideas"].map((tab) => /* @__PURE__ */ jsxs(
414
- "button",
415
- {
416
- onClick: () => setActiveTab(tab),
417
- style: {
418
- padding: "10px 16px",
419
- borderRadius: 8,
420
- border: "none",
421
- cursor: "pointer",
422
- fontSize: 14,
423
- fontWeight: 500,
424
- background: activeTab === tab ? isLight ? "#18181b" : "#fff" : "transparent",
425
- color: activeTab === tab ? isLight ? "#fff" : "#18181b" : isLight ? "#71717a" : "#71717a",
426
- transition: "all 150ms"
427
- },
428
- children: [
429
- tab === "changelog" && "\u{1F680} Changelog",
430
- tab === "roadmap" && "\u{1F5FA}\uFE0F Roadmap",
431
- tab === "ideas" && "\u{1F4A1} Ideas"
432
- ]
433
- },
434
- tab
435
- ))
436
- }
437
- ),
438
- /* @__PURE__ */ jsxs("div", { style: { flex: 1, overflowY: "auto", padding: "20px 24px", minHeight: 0 }, children: [
439
- activeTab === "changelog" && /* @__PURE__ */ jsx("div", { style: { maxWidth: 640 }, children: versionsArray.length === 0 ? /* @__PURE__ */ jsxs("div", { style: { textAlign: "center", padding: 60, color: isLight ? "#71717a" : "#a1a1aa" }, children: [
440
- /* @__PURE__ */ jsx("div", { style: { fontSize: 48, marginBottom: 12 }, children: "\u{1F680}" }),
441
- /* @__PURE__ */ jsx("div", { style: { fontSize: 16 }, children: "No releases yet" })
442
- ] }) : versionsArray.slice(0, 10).map((version, idx) => /* @__PURE__ */ jsxs("div", { style: { marginBottom: 24, paddingBottom: 24, borderBottom: idx < versionsArray.length - 1 && idx < 9 ? `1px solid ${isLight ? "#f0f0f0" : "#1f1f1f"}` : "none" }, children: [
443
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8, marginBottom: 6 }, children: [
444
- /* @__PURE__ */ jsx("span", { style: { fontSize: 20 }, children: version.emoji || "\u{1F4E6}" }),
445
- /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, fontSize: 18, color: isLight ? "#18181b" : "#fff" }, children: version.title }),
446
- /* @__PURE__ */ jsx(
447
- "span",
448
- {
449
- style: {
450
- padding: "3px 8px",
451
- fontSize: 11,
452
- fontWeight: 500,
453
- borderRadius: 4,
454
- background: version.type === "major" ? "#f3e8ff" : version.type === "minor" ? "#dbeafe" : isLight ? "#f4f4f5" : "#1f1f1f",
455
- color: version.type === "major" ? "#7c3aed" : version.type === "minor" ? "#2563eb" : isLight ? "#52525b" : "#a1a1aa"
456
- },
457
- children: version.type
458
- }
459
- )
460
- ] }),
461
- /* @__PURE__ */ jsxs("div", { style: { fontSize: 13, color: isLight ? "#71717a" : "#71717a", marginBottom: 10 }, children: [
462
- "v",
463
- version.version,
464
- " \xB7 ",
465
- new Date(version.date).toLocaleDateString()
466
- ] }),
467
- version.description && /* @__PURE__ */ jsx("p", { style: { fontSize: 15, color: isLight ? "#52525b" : "#a1a1aa", margin: "0 0 12px 0", lineHeight: 1.6 }, children: version.description }),
468
- version.features && version.features.length > 0 && /* @__PURE__ */ jsx("ul", { style: { margin: 0, paddingLeft: 0, listStyle: "none" }, children: version.features.map((feature, i) => /* @__PURE__ */ jsxs("li", { style: { display: "flex", alignItems: "flex-start", gap: 10, fontSize: 14, color: isLight ? "#52525b" : "#a1a1aa", marginBottom: 6, lineHeight: 1.5 }, children: [
469
- /* @__PURE__ */ jsx("span", { style: { color: "#22c55e", fontSize: 14, marginTop: 2 }, children: "\u2713" }),
470
- feature
471
- ] }, i)) })
472
- ] }, idx)) }),
473
- activeTab === "roadmap" && /* @__PURE__ */ jsx("div", { style: { maxWidth: 640 }, children: Object.keys(groupedTasks).length === 0 || tasksArray.length === 0 ? /* @__PURE__ */ jsxs("div", { style: { textAlign: "center", padding: 60, color: isLight ? "#71717a" : "#a1a1aa" }, children: [
474
- /* @__PURE__ */ jsx("div", { style: { fontSize: 48, marginBottom: 12 }, children: "\u{1F5FA}\uFE0F" }),
475
- /* @__PURE__ */ jsx("div", { style: { fontSize: 16 }, children: "No public roadmap items" })
476
- ] }) : (
477
- // Show all columns that have tasks, prioritizing known columns first
478
- [.../* @__PURE__ */ new Set([
479
- ...["in-progress", "todo", "backlog"].filter((c) => groupedTasks[c]?.length > 0),
480
- ...Object.keys(groupedTasks).filter((c) => !["in-progress", "todo", "backlog", "done"].includes(c))
481
- ])].map((col) => {
482
- const tasks = groupedTasks[col];
483
- if (!tasks || tasks.length === 0) return null;
484
- const columnLabel = tasks[0]?.columnName || COLUMN_LABELS[col] || col;
485
- return /* @__PURE__ */ jsxs("div", { style: { marginBottom: 24 }, children: [
486
- /* @__PURE__ */ jsxs("h3", { style: { fontSize: 12, fontWeight: 600, color: isLight ? "#a1a1aa" : "#71717a", marginBottom: 12, textTransform: "uppercase", letterSpacing: "0.5px" }, children: [
487
- columnLabel,
488
- " (",
489
- tasks.length,
490
- ")"
491
- ] }),
492
- tasks.map((task) => /* @__PURE__ */ jsx(
493
- "div",
494
- {
495
- style: {
496
- padding: "12px 16px",
497
- marginBottom: 8,
498
- borderRadius: 8,
499
- background: isLight ? "#f5f5f5" : "#151515",
500
- border: `1px solid ${isLight ? "#e5e5e5" : "#1f1f1f"}`
501
- },
502
- children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "flex-start", gap: 10 }, children: [
503
- /* @__PURE__ */ jsx(
504
- "span",
505
- {
506
- style: {
507
- width: 8,
508
- height: 8,
509
- borderRadius: "50%",
510
- background: TYPE_COLORS[task.type] || "#71717a",
511
- flexShrink: 0,
512
- marginTop: 5
513
- }
514
- }
515
- ),
516
- /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
517
- /* @__PURE__ */ jsx("span", { style: { fontSize: 14, color: isLight ? "#18181b" : "#fff" }, children: task.title }),
518
- task.description && /* @__PURE__ */ jsx("p", { style: { fontSize: 13, color: isLight ? "#71717a" : "#a1a1aa", margin: "4px 0 0 0", lineHeight: 1.5 }, children: task.description })
519
- ] })
520
- ] })
521
- },
522
- task.id
523
- ))
524
- ] }, col);
525
- })
526
- ) }),
527
- activeTab === "ideas" && /* @__PURE__ */ jsxs("div", { style: { maxWidth: 640 }, children: [
528
- !showIdeaForm ? /* @__PURE__ */ jsxs(
529
- "button",
441
+ }
442
+ ),
443
+ /* @__PURE__ */ jsxs(
444
+ "div",
445
+ {
446
+ onClick: (e) => e.stopPropagation(),
447
+ style: {
448
+ position: "fixed",
449
+ top: isMobile ? 0 : 20,
450
+ left: isMobile ? 0 : 20,
451
+ right: isMobile ? 0 : 20,
452
+ bottom: isMobile ? 0 : 20,
453
+ zIndex: 2147483647,
454
+ display: "flex",
455
+ flexDirection: "column",
456
+ boxSizing: "border-box",
457
+ background: isLight ? "#fff" : "#0a0a0a",
458
+ borderRadius: isMobile ? 0 : 16,
459
+ overflow: "hidden",
460
+ boxShadow: "0 25px 50px -12px rgba(0,0,0,0.25)",
461
+ animation: "vpSlideUp 250ms ease-out"
462
+ },
463
+ children: [
464
+ /* @__PURE__ */ jsxs(
465
+ "div",
530
466
  {
531
- onClick: () => setShowIdeaForm(true),
532
467
  style: {
468
+ flexShrink: 0,
469
+ padding: isMobile ? "12px 16px" : "16px 20px",
470
+ borderBottom: `1px solid ${isLight ? "#e5e5e5" : "#1f1f1f"}`,
533
471
  display: "flex",
534
472
  alignItems: "center",
535
- justifyContent: "center",
536
- gap: 8,
537
- width: "100%",
538
- padding: "12px 16px",
539
- marginBottom: 20,
540
- borderRadius: 8,
541
- border: `1px dashed ${isLight ? "#d4d4d8" : "#3f3f46"}`,
542
- background: "transparent",
543
- color: isLight ? "#71717a" : "#a1a1aa",
544
- fontSize: 14,
545
- fontWeight: 500,
546
- cursor: "pointer",
547
- transition: "all 150ms"
548
- },
549
- onMouseEnter: (e) => {
550
- e.currentTarget.style.borderColor = isLight ? "#a1a1aa" : "#71717a";
551
- e.currentTarget.style.color = isLight ? "#52525b" : "#d4d4d8";
552
- },
553
- onMouseLeave: (e) => {
554
- e.currentTarget.style.borderColor = isLight ? "#d4d4d8" : "#3f3f46";
555
- e.currentTarget.style.color = isLight ? "#71717a" : "#a1a1aa";
473
+ justifyContent: "space-between"
556
474
  },
557
475
  children: [
558
- /* @__PURE__ */ jsx("span", { style: { fontSize: 18 }, children: "\u{1F4A1}" }),
559
- "Suggest a feature"
476
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: isMobile ? 8 : 12 }, children: [
477
+ project?.icon && /* @__PURE__ */ jsx("span", { style: { fontSize: isMobile ? 20 : 24 }, children: project.icon }),
478
+ /* @__PURE__ */ jsxs("div", { children: [
479
+ /* @__PURE__ */ jsx("h2", { style: { fontWeight: 600, fontSize: isMobile ? 16 : 18, color: isLight ? "#18181b" : "#fff", margin: 0 }, children: project?.name || "What's New" }),
480
+ /* @__PURE__ */ jsxs("p", { style: { fontSize: 12, color: isLight ? "#71717a" : "#a1a1aa", margin: 0 }, children: [
481
+ "v",
482
+ currentVersion
483
+ ] })
484
+ ] })
485
+ ] }),
486
+ /* @__PURE__ */ jsx(
487
+ "button",
488
+ {
489
+ onClick: () => setIsOpen(false),
490
+ style: {
491
+ width: 36,
492
+ height: 36,
493
+ display: "flex",
494
+ alignItems: "center",
495
+ justifyContent: "center",
496
+ borderRadius: 8,
497
+ background: isLight ? "#f5f5f5" : "#1f1f1f",
498
+ border: "none",
499
+ cursor: "pointer",
500
+ color: isLight ? "#71717a" : "#a1a1aa",
501
+ transition: "background 150ms"
502
+ },
503
+ onMouseEnter: (e) => e.currentTarget.style.background = isLight ? "#e5e5e5" : "#2a2a2a",
504
+ onMouseLeave: (e) => e.currentTarget.style.background = isLight ? "#f5f5f5" : "#1f1f1f",
505
+ children: /* @__PURE__ */ jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "M18 6L6 18M6 6l12 12" }) })
506
+ }
507
+ )
560
508
  ]
561
509
  }
562
- ) : /* @__PURE__ */ jsxs(
510
+ ),
511
+ /* @__PURE__ */ jsx(
563
512
  "div",
564
513
  {
565
514
  style: {
566
- padding: 16,
567
- marginBottom: 20,
568
- borderRadius: 8,
569
- background: isLight ? "#f5f5f5" : "#151515",
570
- border: `1px solid ${isLight ? "#e5e5e5" : "#1f1f1f"}`
515
+ flexShrink: 0,
516
+ display: "flex",
517
+ justifyContent: "center",
518
+ gap: 2,
519
+ padding: isMobile ? "8px 12px" : "10px 20px",
520
+ borderBottom: `1px solid ${isLight ? "#e5e5e5" : "#1f1f1f"}`,
521
+ overflowX: "auto"
571
522
  },
572
- children: [
573
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 12 }, children: [
574
- /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, color: isLight ? "#18181b" : "#fff" }, children: "Suggest a Feature" }),
575
- /* @__PURE__ */ jsx(
576
- "button",
577
- {
578
- onClick: () => {
579
- setShowIdeaForm(false);
580
- setIdeaSubmitMessage(null);
581
- },
582
- style: {
583
- background: "transparent",
584
- border: "none",
585
- color: isLight ? "#71717a" : "#a1a1aa",
586
- cursor: "pointer",
587
- fontSize: 18
588
- },
589
- children: "\xD7"
523
+ children: ["changelog", "roadmap", "ideas"].map((tab) => /* @__PURE__ */ jsxs(
524
+ "button",
525
+ {
526
+ onClick: () => setActiveTab(tab),
527
+ style: {
528
+ padding: isMobile ? "8px 16px" : "8px 20px",
529
+ borderRadius: 999,
530
+ border: "none",
531
+ cursor: "pointer",
532
+ fontSize: isMobile ? 13 : 14,
533
+ fontWeight: 500,
534
+ whiteSpace: "nowrap",
535
+ background: activeTab === tab ? isLight ? "#18181b" : "#fff" : "transparent",
536
+ color: activeTab === tab ? isLight ? "#fff" : "#18181b" : isLight ? "#71717a" : "#71717a",
537
+ transition: "all 150ms"
538
+ },
539
+ onMouseEnter: (e) => {
540
+ if (activeTab !== tab) {
541
+ e.currentTarget.style.background = isLight ? "#f4f4f5" : "#1f1f1f";
590
542
  }
591
- )
592
- ] }),
593
- /* @__PURE__ */ jsx(
594
- "input",
543
+ },
544
+ onMouseLeave: (e) => {
545
+ if (activeTab !== tab) {
546
+ e.currentTarget.style.background = "transparent";
547
+ }
548
+ },
549
+ children: [
550
+ tab === "changelog" && "\u{1F680} Changelog",
551
+ tab === "roadmap" && "\u{1F5FA}\uFE0F Roadmap",
552
+ tab === "ideas" && "\u{1F4A1} Ideas"
553
+ ]
554
+ },
555
+ tab
556
+ ))
557
+ }
558
+ ),
559
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, overflow: activeTab === "roadmap" ? "hidden" : "auto", padding: isMobile ? "16px" : "20px 24px", minHeight: 0, display: "flex", flexDirection: "column", alignItems: "center" }, children: [
560
+ activeTab === "changelog" && /* @__PURE__ */ jsx("div", { style: { maxWidth: 640, width: "100%", overflowY: "auto", flex: 1 }, children: versionsArray.length === 0 ? /* @__PURE__ */ jsxs("div", { style: { textAlign: "center", padding: 60, color: isLight ? "#71717a" : "#a1a1aa" }, children: [
561
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 48, marginBottom: 12 }, children: "\u{1F680}" }),
562
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 16 }, children: "No releases yet" })
563
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
564
+ versionsArray.slice(0, 10).map((version, idx) => {
565
+ const isLatest = idx === 0;
566
+ return /* @__PURE__ */ jsxs("div", { style: {
567
+ marginBottom: 24,
568
+ paddingBottom: 24,
569
+ paddingLeft: isLatest ? 16 : 0,
570
+ borderLeft: isLatest ? `3px solid #22c55e` : "none",
571
+ borderBottom: idx < versionsArray.length - 1 && idx < 9 ? `1px solid ${isLight ? "#f0f0f0" : "#1f1f1f"}` : "none"
572
+ }, children: [
573
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8, marginBottom: 6, flexWrap: "wrap" }, children: [
574
+ /* @__PURE__ */ jsx("span", { style: { fontSize: isLatest ? 22 : 20 }, children: version.emoji || "\u{1F4E6}" }),
575
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, fontSize: isLatest ? 20 : 18, color: isLight ? "#18181b" : "#fff" }, children: version.title }),
576
+ isLatest && /* @__PURE__ */ jsx("span", { style: {
577
+ padding: "2px 8px",
578
+ fontSize: 10,
579
+ fontWeight: 600,
580
+ borderRadius: 999,
581
+ background: isLight ? "#dcfce7" : "rgba(34,197,94,0.15)",
582
+ color: "#22c55e",
583
+ textTransform: "uppercase",
584
+ letterSpacing: "0.5px"
585
+ }, children: "Latest" }),
586
+ /* @__PURE__ */ jsx(
587
+ "span",
588
+ {
589
+ style: {
590
+ padding: "3px 10px",
591
+ fontSize: 11,
592
+ fontWeight: 500,
593
+ borderRadius: 999,
594
+ background: version.type === "major" ? isLight ? "#f3e8ff" : "rgba(147,51,234,0.15)" : version.type === "minor" ? isLight ? "#dbeafe" : "rgba(59,130,246,0.15)" : isLight ? "#f4f4f5" : "#1f1f1f",
595
+ color: version.type === "major" ? "#7c3aed" : version.type === "minor" ? "#2563eb" : isLight ? "#52525b" : "#a1a1aa"
596
+ },
597
+ children: version.type
598
+ }
599
+ )
600
+ ] }),
601
+ /* @__PURE__ */ jsxs("div", { style: { fontSize: 13, color: isLight ? "#71717a" : "#71717a", marginBottom: 10 }, children: [
602
+ "v",
603
+ version.version,
604
+ " \xB7 ",
605
+ new Date(version.date).toLocaleDateString()
606
+ ] }),
607
+ version.description && /* @__PURE__ */ jsx("p", { style: { fontSize: 15, color: isLight ? "#52525b" : "#a1a1aa", margin: "0 0 12px 0", lineHeight: 1.6 }, children: version.description }),
608
+ version.features && version.features.length > 0 && /* @__PURE__ */ jsx("ul", { style: { margin: 0, paddingLeft: 0, listStyle: "none" }, children: version.features.map((feature, i) => /* @__PURE__ */ jsxs("li", { style: { display: "flex", alignItems: "flex-start", gap: 10, fontSize: 14, color: isLight ? "#52525b" : "#a1a1aa", marginBottom: 6, lineHeight: 1.5 }, children: [
609
+ /* @__PURE__ */ jsx("span", { style: { color: "#22c55e", fontSize: 14, marginTop: 2 }, children: "\u2713" }),
610
+ feature
611
+ ] }, i)) }),
612
+ version.tasks && version.tasks.length > 0 && /* @__PURE__ */ jsx("div", { style: { marginTop: 10, paddingTop: 10, borderTop: `1px solid ${isLight ? "#f0f0f0" : "#1f1f1f"}` }, children: version.tasks.map((task, i) => /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8, fontSize: 13, color: isLight ? "#71717a" : "#a1a1aa", marginBottom: 4 }, children: [
613
+ /* @__PURE__ */ jsx("span", { style: {
614
+ width: 6,
615
+ height: 6,
616
+ borderRadius: "50%",
617
+ background: TYPE_COLORS[task.type] || "#71717a",
618
+ flexShrink: 0
619
+ } }),
620
+ task.title
621
+ ] }, i)) })
622
+ ] }, idx);
623
+ }),
624
+ versionsArray.length > 10 && /* @__PURE__ */ jsx(
625
+ "a",
626
+ {
627
+ href: `${baseUrl}/${projectId}/changelog`,
628
+ target: "_blank",
629
+ rel: "noopener noreferrer",
630
+ style: {
631
+ display: "block",
632
+ textAlign: "center",
633
+ padding: 12,
634
+ fontSize: 14,
635
+ color: "#22c55e",
636
+ textDecoration: "none"
637
+ },
638
+ children: "View all releases \u2192"
639
+ }
640
+ )
641
+ ] }) }),
642
+ activeTab === "roadmap" && /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", flex: 1, minHeight: 0, width: "100%" }, children: roadmapItems.length === 0 ? /* @__PURE__ */ jsxs("div", { style: { textAlign: "center", padding: 60, color: isLight ? "#71717a" : "#a1a1aa" }, children: [
643
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 48, marginBottom: 12 }, children: "\u{1F5FA}\uFE0F" }),
644
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 16 }, children: "No public roadmap items" })
645
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
646
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 4, marginBottom: 12, flexShrink: 0 }, children: [
647
+ /* @__PURE__ */ jsxs(
648
+ "button",
595
649
  {
596
- type: "text",
597
- value: ideaTitle,
598
- onChange: (e) => setIdeaTitle(e.target.value),
599
- placeholder: "Feature title *",
650
+ onClick: () => setRoadmapView("board"),
600
651
  style: {
601
- width: "100%",
602
- padding: "10px 12px",
603
- marginBottom: 8,
652
+ padding: "6px 10px",
604
653
  borderRadius: 6,
605
- border: `1px solid ${isLight ? "#e5e5e5" : "#2a2a2a"}`,
606
- background: isLight ? "#fff" : "#0a0a0a",
607
- color: isLight ? "#18181b" : "#fff",
608
- fontSize: 14,
609
- outline: "none",
610
- boxSizing: "border-box"
611
- }
654
+ border: `1px solid ${roadmapView === "board" ? isLight ? "#18181b" : "#fff" : isLight ? "#e5e5e5" : "#2a2a2a"}`,
655
+ background: roadmapView === "board" ? isLight ? "#18181b" : "#fff" : "transparent",
656
+ color: roadmapView === "board" ? isLight ? "#fff" : "#18181b" : isLight ? "#71717a" : "#a1a1aa",
657
+ cursor: "pointer",
658
+ fontSize: 12,
659
+ fontWeight: 500,
660
+ display: "flex",
661
+ alignItems: "center",
662
+ gap: 4
663
+ },
664
+ children: [
665
+ /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
666
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "3", width: "7", height: "7" }),
667
+ /* @__PURE__ */ jsx("rect", { x: "14", y: "3", width: "7", height: "7" }),
668
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "14", width: "7", height: "7" }),
669
+ /* @__PURE__ */ jsx("rect", { x: "14", y: "14", width: "7", height: "7" })
670
+ ] }),
671
+ "Board"
672
+ ]
612
673
  }
613
674
  ),
614
- /* @__PURE__ */ jsx(
615
- "textarea",
675
+ /* @__PURE__ */ jsxs(
676
+ "button",
616
677
  {
617
- value: ideaDescription,
618
- onChange: (e) => setIdeaDescription(e.target.value),
619
- placeholder: "Describe your idea...",
620
- rows: 3,
678
+ onClick: () => setRoadmapView("list"),
621
679
  style: {
622
- width: "100%",
623
- padding: "10px 12px",
624
- marginBottom: 8,
680
+ padding: "6px 10px",
625
681
  borderRadius: 6,
626
- border: `1px solid ${isLight ? "#e5e5e5" : "#2a2a2a"}`,
627
- background: isLight ? "#fff" : "#0a0a0a",
628
- color: isLight ? "#18181b" : "#fff",
629
- fontSize: 14,
630
- outline: "none",
631
- resize: "none",
632
- boxSizing: "border-box"
633
- }
682
+ border: `1px solid ${roadmapView === "list" ? isLight ? "#18181b" : "#fff" : isLight ? "#e5e5e5" : "#2a2a2a"}`,
683
+ background: roadmapView === "list" ? isLight ? "#18181b" : "#fff" : "transparent",
684
+ color: roadmapView === "list" ? isLight ? "#fff" : "#18181b" : isLight ? "#71717a" : "#a1a1aa",
685
+ cursor: "pointer",
686
+ fontSize: 12,
687
+ fontWeight: 500,
688
+ display: "flex",
689
+ alignItems: "center",
690
+ gap: 4
691
+ },
692
+ children: [
693
+ /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
694
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "6", x2: "21", y2: "6" }),
695
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "12", x2: "21", y2: "12" }),
696
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "18", x2: "21", y2: "18" }),
697
+ /* @__PURE__ */ jsx("line", { x1: "3", y1: "6", x2: "3.01", y2: "6" }),
698
+ /* @__PURE__ */ jsx("line", { x1: "3", y1: "12", x2: "3.01", y2: "12" }),
699
+ /* @__PURE__ */ jsx("line", { x1: "3", y1: "18", x2: "3.01", y2: "18" })
700
+ ] }),
701
+ "List"
702
+ ]
634
703
  }
635
- ),
636
- /* @__PURE__ */ jsxs("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8, marginBottom: 12 }, children: [
637
- /* @__PURE__ */ jsx(
638
- "input",
704
+ )
705
+ ] }),
706
+ roadmapView === "board" && /* @__PURE__ */ jsx("div", { style: {
707
+ display: "flex",
708
+ gap: 12,
709
+ flex: 1,
710
+ minHeight: 0,
711
+ overflow: "hidden",
712
+ flexDirection: isMobile ? "column" : "row",
713
+ overflowY: isMobile ? "auto" : "hidden"
714
+ }, children: roadmapColumns.map((col) => {
715
+ const colItems = roadmapItems.filter((item) => item.columnId === col.id);
716
+ const isCollapsed = isMobile && collapsedColumns.has(col.id);
717
+ return /* @__PURE__ */ jsxs("div", { style: {
718
+ flex: isMobile ? "none" : 1,
719
+ minWidth: 0,
720
+ display: "flex",
721
+ flexDirection: "column",
722
+ minHeight: isMobile ? "auto" : 0
723
+ }, children: [
724
+ /* @__PURE__ */ jsxs(
725
+ "button",
639
726
  {
640
- type: "text",
641
- value: ideaAuthorName,
642
- onChange: (e) => setIdeaAuthorName(e.target.value),
643
- placeholder: "Name (optional)",
727
+ onClick: () => isMobile && setCollapsedColumns((prev) => {
728
+ const s = new Set(prev);
729
+ s.has(col.id) ? s.delete(col.id) : s.add(col.id);
730
+ return s;
731
+ }),
644
732
  style: {
733
+ display: "flex",
734
+ alignItems: "center",
735
+ gap: 6,
736
+ fontSize: 12,
737
+ fontWeight: 600,
738
+ color: isLight ? "#a1a1aa" : "#71717a",
739
+ marginBottom: 8,
740
+ textTransform: "uppercase",
741
+ letterSpacing: "0.5px",
742
+ flexShrink: 0,
743
+ background: "none",
744
+ border: "none",
745
+ cursor: isMobile ? "pointer" : "default",
746
+ padding: 0,
645
747
  width: "100%",
646
- padding: "8px 12px",
647
- borderRadius: 6,
648
- border: `1px solid ${isLight ? "#e5e5e5" : "#2a2a2a"}`,
649
- background: isLight ? "#fff" : "#0a0a0a",
650
- color: isLight ? "#18181b" : "#fff",
651
- fontSize: 13,
652
- outline: "none",
653
- boxSizing: "border-box"
654
- }
748
+ textAlign: "left"
749
+ },
750
+ children: [
751
+ isMobile && /* @__PURE__ */ jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", style: { transform: isCollapsed ? "rotate(-90deg)" : "rotate(0)", transition: "transform 150ms" }, children: /* @__PURE__ */ jsx("path", { d: "M6 9l6 6 6-6" }) }),
752
+ col.name,
753
+ /* @__PURE__ */ jsx("span", { style: {
754
+ padding: "1px 6px",
755
+ fontSize: 11,
756
+ fontWeight: 500,
757
+ borderRadius: 999,
758
+ background: isLight ? "#f4f4f5" : "#1f1f1f",
759
+ color: isLight ? "#71717a" : "#a1a1aa"
760
+ }, children: colItems.length })
761
+ ]
655
762
  }
656
763
  ),
657
- /* @__PURE__ */ jsx(
658
- "input",
764
+ !isCollapsed && /* @__PURE__ */ jsxs("div", { style: {
765
+ display: "flex",
766
+ flexDirection: "column",
767
+ gap: 8,
768
+ flex: isMobile ? "none" : 1,
769
+ overflowY: isMobile ? "visible" : "auto",
770
+ minHeight: 0,
771
+ paddingRight: isMobile ? 0 : 2,
772
+ paddingBottom: isMobile ? 12 : 0
773
+ }, children: [
774
+ colItems.map((item) => {
775
+ const priorityColor = PRIORITY_COLORS[item.priority || ""] || "transparent";
776
+ return /* @__PURE__ */ jsx(
777
+ "div",
778
+ {
779
+ style: {
780
+ padding: "12px 14px",
781
+ borderRadius: 8,
782
+ background: isLight ? "#f9fafb" : "#151515",
783
+ border: `1px solid ${isLight ? "#e5e5e5" : "#1f1f1f"}`,
784
+ borderLeft: `3px solid ${priorityColor}`,
785
+ transition: "border-color 150ms"
786
+ },
787
+ onMouseEnter: (e) => e.currentTarget.style.borderColor = isLight ? "#d4d4d8" : "#3f3f46",
788
+ onMouseLeave: (e) => e.currentTarget.style.borderColor = isLight ? "#e5e5e5" : "#1f1f1f",
789
+ children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "flex-start", gap: 8 }, children: [
790
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
791
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6, marginBottom: 4 }, children: [
792
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 13 }, children: TYPE_EMOJIS[item.type || ""] || "\u{1F4CB}" }),
793
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 13, fontWeight: 500, color: isLight ? "#18181b" : "#fff" }, children: item.title })
794
+ ] }),
795
+ item.description && /* @__PURE__ */ jsx("p", { style: {
796
+ fontSize: 12,
797
+ color: isLight ? "#71717a" : "#a1a1aa",
798
+ margin: "0 0 0 0",
799
+ lineHeight: 1.4,
800
+ overflow: "hidden",
801
+ display: "-webkit-box",
802
+ WebkitLineClamp: 2,
803
+ WebkitBoxOrient: "vertical"
804
+ }, children: item.description })
805
+ ] }),
806
+ item.itemType === "idea" && /* @__PURE__ */ jsxs("span", { style: {
807
+ fontSize: 11,
808
+ fontWeight: 600,
809
+ color: isLight ? "#ea580c" : "#fb923c",
810
+ background: isLight ? "rgba(249,115,22,0.1)" : "rgba(249,115,22,0.15)",
811
+ padding: "2px 6px",
812
+ borderRadius: 4,
813
+ flexShrink: 0
814
+ }, children: [
815
+ item.votes ?? 0,
816
+ "\u2191"
817
+ ] })
818
+ ] })
819
+ },
820
+ item.id
821
+ );
822
+ }),
823
+ colItems.length === 0 && /* @__PURE__ */ jsx("div", { style: {
824
+ padding: 20,
825
+ textAlign: "center",
826
+ fontSize: 13,
827
+ color: isLight ? "#a1a1aa" : "#525252",
828
+ borderRadius: 8,
829
+ border: `1px dashed ${isLight ? "#e5e5e5" : "#1f1f1f"}`
830
+ }, children: "No items" })
831
+ ] })
832
+ ] }, col.id);
833
+ }) }),
834
+ roadmapView === "list" && /* @__PURE__ */ jsx("div", { style: { flex: 1, overflowY: "auto", minHeight: 0 }, children: roadmapColumns.map((col) => {
835
+ const colItems = roadmapItems.filter((item) => item.columnId === col.id);
836
+ if (colItems.length === 0) return null;
837
+ return /* @__PURE__ */ jsxs("div", { style: { marginBottom: 20 }, children: [
838
+ /* @__PURE__ */ jsxs("h3", { style: {
839
+ fontSize: 12,
840
+ fontWeight: 600,
841
+ color: isLight ? "#a1a1aa" : "#71717a",
842
+ marginBottom: 8,
843
+ textTransform: "uppercase",
844
+ letterSpacing: "0.5px",
845
+ display: "flex",
846
+ alignItems: "center",
847
+ gap: 6
848
+ }, children: [
849
+ col.name,
850
+ /* @__PURE__ */ jsx("span", { style: {
851
+ padding: "1px 6px",
852
+ fontSize: 11,
853
+ fontWeight: 500,
854
+ borderRadius: 999,
855
+ background: isLight ? "#f4f4f5" : "#1f1f1f",
856
+ color: isLight ? "#71717a" : "#a1a1aa"
857
+ }, children: colItems.length })
858
+ ] }),
859
+ colItems.map((item) => /* @__PURE__ */ jsxs(
860
+ "div",
659
861
  {
660
- type: "email",
661
- value: ideaAuthorEmail,
662
- onChange: (e) => setIdeaAuthorEmail(e.target.value),
663
- placeholder: "Email (optional)",
664
862
  style: {
665
- width: "100%",
666
- padding: "8px 12px",
863
+ display: "flex",
864
+ alignItems: "center",
865
+ gap: 10,
866
+ padding: "10px 12px",
667
867
  borderRadius: 6,
668
- border: `1px solid ${isLight ? "#e5e5e5" : "#2a2a2a"}`,
669
- background: isLight ? "#fff" : "#0a0a0a",
670
- color: isLight ? "#18181b" : "#fff",
671
- fontSize: 13,
672
- outline: "none",
673
- boxSizing: "border-box"
868
+ marginBottom: 4,
869
+ background: isLight ? "#f9fafb" : "#151515",
870
+ border: `1px solid ${isLight ? "#f0f0f0" : "#1a1a1a"}`
871
+ },
872
+ children: [
873
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 13, flexShrink: 0 }, children: TYPE_EMOJIS[item.type || ""] || "\u{1F4CB}" }),
874
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 13, fontWeight: 500, color: isLight ? "#18181b" : "#fff", flex: 1, minWidth: 0 }, children: item.title }),
875
+ item.priority && /* @__PURE__ */ jsx("span", { style: {
876
+ padding: "2px 8px",
877
+ fontSize: 10,
878
+ fontWeight: 500,
879
+ borderRadius: 999,
880
+ background: isLight ? "#f4f4f5" : "#1f1f1f",
881
+ color: PRIORITY_COLORS[item.priority] || (isLight ? "#71717a" : "#a1a1aa"),
882
+ flexShrink: 0
883
+ }, children: item.priority })
884
+ ]
885
+ },
886
+ item.id
887
+ ))
888
+ ] }, col.id);
889
+ }) })
890
+ ] }) }),
891
+ activeTab === "ideas" && /* @__PURE__ */ jsxs("div", { style: { maxWidth: 640, width: "100%", overflowY: "auto", flex: 1 }, children: [
892
+ !showIdeaForm ? /* @__PURE__ */ jsxs(
893
+ "button",
894
+ {
895
+ onClick: () => setShowIdeaForm(true),
896
+ style: {
897
+ display: "flex",
898
+ alignItems: "center",
899
+ justifyContent: "center",
900
+ gap: 8,
901
+ width: "100%",
902
+ padding: "12px 16px",
903
+ marginBottom: 20,
904
+ borderRadius: 999,
905
+ border: `1px dashed ${isLight ? "#d4d4d8" : "#3f3f46"}`,
906
+ background: "transparent",
907
+ color: isLight ? "#71717a" : "#a1a1aa",
908
+ fontSize: 14,
909
+ fontWeight: 500,
910
+ cursor: "pointer",
911
+ transition: "all 150ms"
912
+ },
913
+ onMouseEnter: (e) => {
914
+ e.currentTarget.style.borderColor = isLight ? "#a1a1aa" : "#71717a";
915
+ e.currentTarget.style.color = isLight ? "#52525b" : "#d4d4d8";
916
+ },
917
+ onMouseLeave: (e) => {
918
+ e.currentTarget.style.borderColor = isLight ? "#d4d4d8" : "#3f3f46";
919
+ e.currentTarget.style.color = isLight ? "#71717a" : "#a1a1aa";
920
+ },
921
+ children: [
922
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 18 }, children: "\u{1F4A1}" }),
923
+ "Suggest a feature"
924
+ ]
925
+ }
926
+ ) : /* @__PURE__ */ jsxs(
927
+ "div",
928
+ {
929
+ style: {
930
+ padding: 16,
931
+ marginBottom: 20,
932
+ borderRadius: 12,
933
+ background: isLight ? "#f5f5f5" : "#151515",
934
+ border: `1px solid ${isLight ? "#e5e5e5" : "#1f1f1f"}`
935
+ },
936
+ children: [
937
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 12 }, children: [
938
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, color: isLight ? "#18181b" : "#fff" }, children: "Suggest a Feature" }),
939
+ /* @__PURE__ */ jsx(
940
+ "button",
941
+ {
942
+ onClick: () => {
943
+ setShowIdeaForm(false);
944
+ setIdeaSubmitMessage(null);
945
+ },
946
+ style: {
947
+ background: "transparent",
948
+ border: "none",
949
+ color: isLight ? "#71717a" : "#a1a1aa",
950
+ cursor: "pointer",
951
+ fontSize: 18
952
+ },
953
+ children: "\xD7"
954
+ }
955
+ )
956
+ ] }),
957
+ /* @__PURE__ */ jsx(
958
+ "input",
959
+ {
960
+ type: "text",
961
+ value: ideaTitle,
962
+ onChange: (e) => setIdeaTitle(e.target.value),
963
+ placeholder: "Feature title *",
964
+ style: {
965
+ width: "100%",
966
+ padding: "10px 12px",
967
+ marginBottom: 8,
968
+ borderRadius: 6,
969
+ border: `1px solid ${isLight ? "#e5e5e5" : "#2a2a2a"}`,
970
+ background: isLight ? "#fff" : "#0a0a0a",
971
+ color: isLight ? "#18181b" : "#fff",
972
+ fontSize: 14,
973
+ outline: "none",
974
+ boxSizing: "border-box"
975
+ }
674
976
  }
675
- }
676
- )
677
- ] }),
678
- ideaSubmitMessage && /* @__PURE__ */ jsx("div", { style: {
679
- padding: "8px 12px",
680
- marginBottom: 12,
681
- borderRadius: 6,
682
- background: ideaSubmitMessage.type === "success" ? isLight ? "#dcfce7" : "#14532d" : isLight ? "#fee2e2" : "#450a0a",
683
- color: ideaSubmitMessage.type === "success" ? isLight ? "#166534" : "#86efac" : isLight ? "#dc2626" : "#fca5a5",
684
- fontSize: 13
685
- }, children: ideaSubmitMessage.text }),
977
+ ),
978
+ /* @__PURE__ */ jsx(
979
+ "textarea",
980
+ {
981
+ value: ideaDescription,
982
+ onChange: (e) => setIdeaDescription(e.target.value),
983
+ placeholder: "Describe your idea...",
984
+ rows: 3,
985
+ style: {
986
+ width: "100%",
987
+ padding: "10px 12px",
988
+ marginBottom: 8,
989
+ borderRadius: 6,
990
+ border: `1px solid ${isLight ? "#e5e5e5" : "#2a2a2a"}`,
991
+ background: isLight ? "#fff" : "#0a0a0a",
992
+ color: isLight ? "#18181b" : "#fff",
993
+ fontSize: 14,
994
+ outline: "none",
995
+ resize: "none",
996
+ boxSizing: "border-box"
997
+ }
998
+ }
999
+ ),
1000
+ /* @__PURE__ */ jsxs("div", { style: { display: "grid", gridTemplateColumns: isMobile ? "1fr" : "1fr 1fr", gap: 8, marginBottom: 12 }, children: [
1001
+ /* @__PURE__ */ jsx(
1002
+ "input",
1003
+ {
1004
+ type: "text",
1005
+ value: ideaAuthorName,
1006
+ onChange: (e) => setIdeaAuthorName(e.target.value),
1007
+ placeholder: "Name (optional)",
1008
+ style: {
1009
+ width: "100%",
1010
+ padding: "8px 12px",
1011
+ borderRadius: 6,
1012
+ border: `1px solid ${isLight ? "#e5e5e5" : "#2a2a2a"}`,
1013
+ background: isLight ? "#fff" : "#0a0a0a",
1014
+ color: isLight ? "#18181b" : "#fff",
1015
+ fontSize: 13,
1016
+ outline: "none",
1017
+ boxSizing: "border-box"
1018
+ }
1019
+ }
1020
+ ),
1021
+ /* @__PURE__ */ jsx(
1022
+ "input",
1023
+ {
1024
+ type: "email",
1025
+ value: ideaAuthorEmail,
1026
+ onChange: (e) => setIdeaAuthorEmail(e.target.value),
1027
+ placeholder: "Email *",
1028
+ style: {
1029
+ width: "100%",
1030
+ padding: "8px 12px",
1031
+ borderRadius: 6,
1032
+ border: `1px solid ${isLight ? "#e5e5e5" : "#2a2a2a"}`,
1033
+ background: isLight ? "#fff" : "#0a0a0a",
1034
+ color: isLight ? "#18181b" : "#fff",
1035
+ fontSize: 13,
1036
+ outline: "none",
1037
+ boxSizing: "border-box"
1038
+ }
1039
+ }
1040
+ )
1041
+ ] }),
1042
+ ideaSubmitMessage && /* @__PURE__ */ jsx("div", { style: {
1043
+ padding: "8px 12px",
1044
+ marginBottom: 12,
1045
+ borderRadius: 6,
1046
+ background: ideaSubmitMessage.type === "success" ? isLight ? "#dcfce7" : "#14532d" : isLight ? "#fee2e2" : "#450a0a",
1047
+ color: ideaSubmitMessage.type === "success" ? isLight ? "#166534" : "#86efac" : isLight ? "#dc2626" : "#fca5a5",
1048
+ fontSize: 13
1049
+ }, children: ideaSubmitMessage.text }),
1050
+ /* @__PURE__ */ jsx(
1051
+ "button",
1052
+ {
1053
+ onClick: submitIdea,
1054
+ disabled: submittingIdea || !ideaTitle.trim() || !ideaAuthorEmail.trim(),
1055
+ style: {
1056
+ width: "100%",
1057
+ padding: "10px 16px",
1058
+ borderRadius: 999,
1059
+ border: "none",
1060
+ background: "#22c55e",
1061
+ color: "#fff",
1062
+ fontSize: 14,
1063
+ fontWeight: 500,
1064
+ cursor: submittingIdea || !ideaTitle.trim() || !ideaAuthorEmail.trim() ? "not-allowed" : "pointer",
1065
+ opacity: submittingIdea || !ideaTitle.trim() || !ideaAuthorEmail.trim() ? 0.6 : 1,
1066
+ transition: "opacity 150ms"
1067
+ },
1068
+ children: submittingIdea ? "Submitting..." : "Submit Idea"
1069
+ }
1070
+ )
1071
+ ]
1072
+ }
1073
+ ),
1074
+ ideasArray.length === 0 && !showIdeaForm ? /* @__PURE__ */ jsxs("div", { style: { textAlign: "center", padding: 60, color: isLight ? "#71717a" : "#a1a1aa" }, children: [
1075
+ /* @__PURE__ */ 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__ */ 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" }) }),
1076
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 16, fontWeight: 500, marginBottom: 8 }, children: "No feature requests yet" }),
686
1077
  /* @__PURE__ */ jsx(
687
1078
  "button",
688
1079
  {
689
- onClick: submitIdea,
690
- disabled: submittingIdea || !ideaTitle.trim(),
1080
+ onClick: () => setShowIdeaForm(true),
691
1081
  style: {
692
- width: "100%",
693
- padding: "10px 16px",
694
- borderRadius: 6,
1082
+ padding: "8px 20px",
1083
+ borderRadius: 999,
695
1084
  border: "none",
696
1085
  background: "#22c55e",
697
1086
  color: "#fff",
698
1087
  fontSize: 14,
699
1088
  fontWeight: 500,
700
- cursor: submittingIdea || !ideaTitle.trim() ? "not-allowed" : "pointer",
701
- opacity: submittingIdea || !ideaTitle.trim() ? 0.6 : 1,
702
- transition: "opacity 150ms"
1089
+ cursor: "pointer"
703
1090
  },
704
- children: submittingIdea ? "Submitting..." : "Submit Idea"
1091
+ children: "Suggest a feature"
705
1092
  }
706
1093
  )
707
- ]
708
- }
709
- ),
710
- ideasArray.length === 0 && !showIdeaForm ? /* @__PURE__ */ jsxs("div", { style: { textAlign: "center", padding: 60, color: isLight ? "#71717a" : "#a1a1aa" }, children: [
711
- /* @__PURE__ */ jsx("div", { style: { fontSize: 48, marginBottom: 12 }, children: "\u{1F4A1}" }),
712
- /* @__PURE__ */ jsx("div", { style: { fontSize: 16 }, children: "No feature requests yet" }),
713
- /* @__PURE__ */ jsx("div", { style: { fontSize: 14, marginTop: 8 }, children: "Be the first to suggest one!" })
714
- ] }) : ideasArray.map((idea) => /* @__PURE__ */ jsxs(
1094
+ ] }) : (() => {
1095
+ const statusOrder = ["under review", "planned", "in progress", "new", "shipped"];
1096
+ const grouped = {};
1097
+ ideasArray.forEach((idea) => {
1098
+ const status = (idea.status || "new").toLowerCase();
1099
+ if (!grouped[status]) grouped[status] = [];
1100
+ grouped[status].push(idea);
1101
+ });
1102
+ return statusOrder.map((status) => {
1103
+ const items = grouped[status];
1104
+ if (!items || items.length === 0) return null;
1105
+ const cfg = STATUS_CONFIG[status] || { color: "#71717a", label: status };
1106
+ return /* @__PURE__ */ jsxs("div", { style: { marginBottom: 20 }, children: [
1107
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8, marginBottom: 10 }, children: [
1108
+ /* @__PURE__ */ jsx("span", { style: {
1109
+ width: 8,
1110
+ height: 8,
1111
+ borderRadius: "50%",
1112
+ background: cfg.color,
1113
+ flexShrink: 0
1114
+ } }),
1115
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 13, fontWeight: 600, color: isLight ? "#52525b" : "#a1a1aa", textTransform: "uppercase", letterSpacing: "0.5px" }, children: cfg.label }),
1116
+ /* @__PURE__ */ jsx("span", { style: {
1117
+ padding: "1px 6px",
1118
+ fontSize: 11,
1119
+ fontWeight: 500,
1120
+ borderRadius: 999,
1121
+ background: isLight ? "#f4f4f5" : "#1f1f1f",
1122
+ color: isLight ? "#71717a" : "#a1a1aa"
1123
+ }, children: items.length })
1124
+ ] }),
1125
+ items.map((idea) => {
1126
+ const hasVoted = votedIdeas.has(idea.id) || idea.hasVoted;
1127
+ return /* @__PURE__ */ jsxs(
1128
+ "div",
1129
+ {
1130
+ style: {
1131
+ padding: isMobile ? 12 : 16,
1132
+ marginBottom: 8,
1133
+ borderRadius: 10,
1134
+ background: isLight ? "#f9fafb" : "#151515",
1135
+ border: `1px solid ${isLight ? "#e5e5e5" : "#1f1f1f"}`,
1136
+ display: "flex",
1137
+ alignItems: "flex-start",
1138
+ gap: isMobile ? 10 : 16
1139
+ },
1140
+ children: [
1141
+ /* @__PURE__ */ jsxs(
1142
+ "button",
1143
+ {
1144
+ onClick: () => voteIdea(idea.id),
1145
+ disabled: hasVoted,
1146
+ style: {
1147
+ display: "flex",
1148
+ flexDirection: "column",
1149
+ alignItems: "center",
1150
+ padding: "8px 12px",
1151
+ borderRadius: 8,
1152
+ background: hasVoted ? isLight ? "#dcfce7" : "rgba(34,197,94,0.15)" : isLight ? "#fff" : "#0a0a0a",
1153
+ border: `1px solid ${hasVoted ? "#22c55e" : isLight ? "#e5e5e5" : "#2a2a2a"}`,
1154
+ minWidth: 48,
1155
+ cursor: hasVoted ? "default" : "pointer",
1156
+ transition: "all 150ms"
1157
+ },
1158
+ onMouseEnter: (e) => {
1159
+ if (!hasVoted) {
1160
+ e.currentTarget.style.borderColor = "#22c55e";
1161
+ e.currentTarget.style.background = isLight ? "#f0fdf4" : "rgba(34,197,94,0.1)";
1162
+ }
1163
+ },
1164
+ onMouseLeave: (e) => {
1165
+ if (!hasVoted) {
1166
+ e.currentTarget.style.borderColor = isLight ? "#e5e5e5" : "#2a2a2a";
1167
+ e.currentTarget.style.background = isLight ? "#fff" : "#0a0a0a";
1168
+ }
1169
+ },
1170
+ children: [
1171
+ /* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: hasVoted ? "#22c55e" : "none", stroke: hasVoted ? "#22c55e" : isLight ? "#71717a" : "#a1a1aa", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "M18 15l-6-6-6 6" }) }),
1172
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 16, fontWeight: 600, color: hasVoted ? "#22c55e" : isLight ? "#18181b" : "#fff" }, children: idea.votes })
1173
+ ]
1174
+ }
1175
+ ),
1176
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
1177
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8, marginBottom: 4, flexWrap: "wrap" }, children: [
1178
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 15, fontWeight: 500, color: isLight ? "#18181b" : "#fff" }, children: idea.title }),
1179
+ idea.status && /* @__PURE__ */ jsx("span", { style: {
1180
+ padding: "2px 8px",
1181
+ fontSize: 10,
1182
+ fontWeight: 500,
1183
+ borderRadius: 999,
1184
+ background: isLight ? `${cfg.color}15` : `${cfg.color}20`,
1185
+ color: cfg.color,
1186
+ textTransform: "uppercase",
1187
+ letterSpacing: "0.3px"
1188
+ }, children: cfg.label })
1189
+ ] }),
1190
+ idea.description && /* @__PURE__ */ jsx("div", { style: { fontSize: 14, color: isLight ? "#71717a" : "#a1a1aa", lineHeight: 1.5 }, children: idea.description })
1191
+ ] })
1192
+ ]
1193
+ },
1194
+ idea.id
1195
+ );
1196
+ })
1197
+ ] }, status);
1198
+ });
1199
+ })()
1200
+ ] })
1201
+ ] }),
1202
+ /* @__PURE__ */ jsxs(
715
1203
  "div",
716
1204
  {
717
1205
  style: {
718
- padding: 16,
719
- marginBottom: 12,
720
- borderRadius: 8,
721
- background: isLight ? "#f5f5f5" : "#151515",
722
- border: `1px solid ${isLight ? "#e5e5e5" : "#1f1f1f"}`,
1206
+ flexShrink: 0,
1207
+ padding: "16px 24px",
1208
+ borderTop: `1px solid ${isLight ? "#e5e5e5" : "#1f1f1f"}`,
723
1209
  display: "flex",
724
- alignItems: "flex-start",
725
- gap: 16
1210
+ alignItems: "center",
1211
+ justifyContent: "space-between"
726
1212
  },
727
1213
  children: [
1214
+ showBranding && /* @__PURE__ */ jsx(
1215
+ "a",
1216
+ {
1217
+ href: "https://versionpill.com",
1218
+ target: "_blank",
1219
+ rel: "noopener noreferrer",
1220
+ style: { fontSize: 12, color: isLight ? "#a1a1aa" : "#525252", textDecoration: "none" },
1221
+ children: "Powered by Version Pill"
1222
+ }
1223
+ ),
728
1224
  /* @__PURE__ */ jsxs(
729
- "div",
1225
+ "a",
730
1226
  {
1227
+ href: `${baseUrl}/${projectId}/${activeTab === "ideas" ? "feature-requests" : activeTab}`,
1228
+ target: "_blank",
1229
+ rel: "noopener noreferrer",
731
1230
  style: {
732
- display: "flex",
733
- flexDirection: "column",
734
- alignItems: "center",
735
- padding: "8px 12px",
736
- borderRadius: 6,
737
- background: isLight ? "#fff" : "#0a0a0a",
738
- minWidth: 50
1231
+ padding: "10px 20px",
1232
+ fontSize: 14,
1233
+ fontWeight: 500,
1234
+ borderRadius: 8,
1235
+ background: "#22c55e",
1236
+ color: "#fff",
1237
+ textDecoration: "none",
1238
+ transition: "background 150ms"
739
1239
  },
1240
+ onMouseEnter: (e) => e.currentTarget.style.background = "#16a34a",
1241
+ onMouseLeave: (e) => e.currentTarget.style.background = "#22c55e",
740
1242
  children: [
741
- /* @__PURE__ */ jsx("span", { style: { fontSize: 18, fontWeight: 600, color: isLight ? "#18181b" : "#fff" }, children: idea.votes }),
742
- /* @__PURE__ */ jsx("span", { style: { fontSize: 11, color: isLight ? "#71717a" : "#71717a" }, children: "votes" })
1243
+ "View Full ",
1244
+ activeTab === "changelog" ? "Changelog" : activeTab === "roadmap" ? "Roadmap" : "Ideas",
1245
+ " \u2192"
743
1246
  ]
744
1247
  }
745
- ),
746
- /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
747
- /* @__PURE__ */ jsx("div", { style: { fontSize: 16, fontWeight: 500, color: isLight ? "#18181b" : "#fff", marginBottom: 4 }, children: idea.title }),
748
- idea.description && /* @__PURE__ */ jsx("div", { style: { fontSize: 14, color: isLight ? "#71717a" : "#71717a", lineHeight: 1.5 }, children: idea.description })
749
- ] })
1248
+ )
750
1249
  ]
751
- },
752
- idea.id
753
- ))
754
- ] })
755
- ] }),
756
- /* @__PURE__ */ jsxs(
757
- "div",
758
- {
759
- style: {
760
- flexShrink: 0,
761
- padding: "16px 24px",
762
- borderTop: `1px solid ${isLight ? "#e5e5e5" : "#1f1f1f"}`,
763
- display: "flex",
764
- alignItems: "center",
765
- justifyContent: "space-between"
766
- },
767
- children: [
768
- showBranding && /* @__PURE__ */ jsx(
769
- "a",
770
- {
771
- href: "https://versionpill.com",
772
- target: "_blank",
773
- rel: "noopener noreferrer",
774
- style: { fontSize: 12, color: isLight ? "#a1a1aa" : "#525252", textDecoration: "none" },
775
- children: "Powered by Version Pill"
776
- }
777
- ),
778
- /* @__PURE__ */ jsxs(
779
- "a",
780
- {
781
- href: `${baseUrl}/${projectId}/${activeTab === "ideas" ? "feature-requests" : activeTab}`,
782
- target: "_blank",
783
- rel: "noopener noreferrer",
784
- style: {
785
- padding: "10px 20px",
786
- fontSize: 14,
787
- fontWeight: 500,
788
- borderRadius: 8,
789
- background: "#22c55e",
790
- color: "#fff",
791
- textDecoration: "none",
792
- transition: "background 150ms"
793
- },
794
- onMouseEnter: (e) => e.currentTarget.style.background = "#16a34a",
795
- onMouseLeave: (e) => e.currentTarget.style.background = "#22c55e",
796
- children: [
797
- "View Full ",
798
- activeTab === "changelog" ? "Changelog" : activeTab === "roadmap" ? "Roadmap" : "Ideas",
799
- " \u2192"
800
- ]
801
- }
802
- )
803
- ]
804
- }
805
- )
806
- ]
807
- }
808
- ) })
1250
+ }
1251
+ )
1252
+ ]
1253
+ }
1254
+ )
1255
+ ] }),
1256
+ document.body
1257
+ )
809
1258
  ] });
810
1259
  }
811
1260
  function VersionBadge({