@geenius/feedback 0.1.0 → 0.3.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.
Files changed (104) hide show
  1. package/package.json +16 -3
  2. package/packages/convex/dist/index.d.ts +192 -0
  3. package/packages/convex/dist/index.js +239 -0
  4. package/packages/convex/dist/index.js.map +1 -0
  5. package/packages/react/README.md +1 -1
  6. package/packages/react/dist/index.d.ts +146 -0
  7. package/packages/react/dist/index.js +545 -0
  8. package/packages/react/dist/index.js.map +1 -0
  9. package/packages/react-css/README.md +1 -1
  10. package/packages/react-css/dist/index.css +965 -0
  11. package/packages/react-css/dist/index.css.map +1 -0
  12. package/packages/react-css/dist/index.d.ts +49 -0
  13. package/packages/react-css/dist/index.js +228 -0
  14. package/packages/react-css/dist/index.js.map +1 -0
  15. package/packages/shared/README.md +1 -1
  16. package/packages/shared/dist/index.d.ts +115 -0
  17. package/packages/shared/dist/index.js +112 -0
  18. package/packages/shared/dist/index.js.map +1 -0
  19. package/packages/solidjs/README.md +1 -1
  20. package/packages/solidjs/dist/index.d.ts +128 -0
  21. package/packages/solidjs/dist/index.js +289 -0
  22. package/packages/solidjs/dist/index.js.map +1 -0
  23. package/packages/solidjs-css/README.md +1 -1
  24. package/packages/solidjs-css/dist/index.css +965 -0
  25. package/packages/solidjs-css/dist/index.css.map +1 -0
  26. package/packages/solidjs-css/dist/index.d.ts +2 -0
  27. package/packages/solidjs-css/dist/index.js +29 -0
  28. package/packages/solidjs-css/dist/index.js.map +1 -0
  29. package/.changeset/config.json +0 -11
  30. package/.github/CODEOWNERS +0 -1
  31. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -16
  32. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -11
  33. package/.github/PULL_REQUEST_TEMPLATE.md +0 -10
  34. package/.github/dependabot.yml +0 -11
  35. package/.github/workflows/ci.yml +0 -23
  36. package/.github/workflows/release.yml +0 -29
  37. package/.nvmrc +0 -1
  38. package/.project/ACCOUNT.yaml +0 -4
  39. package/.project/IDEAS.yaml +0 -7
  40. package/.project/PROJECT.yaml +0 -11
  41. package/.project/ROADMAP.yaml +0 -15
  42. package/CODE_OF_CONDUCT.md +0 -16
  43. package/CONTRIBUTING.md +0 -26
  44. package/SECURITY.md +0 -15
  45. package/SUPPORT.md +0 -8
  46. package/packages/convex/package.json +0 -42
  47. package/packages/convex/src/index.ts +0 -3
  48. package/packages/convex/src/mutations.ts +0 -88
  49. package/packages/convex/src/queries.ts +0 -78
  50. package/packages/convex/src/schema.ts +0 -47
  51. package/packages/convex/tsconfig.json +0 -18
  52. package/packages/convex/tsup.config.ts +0 -17
  53. package/packages/react/package.json +0 -49
  54. package/packages/react/src/components/FeedbackCard.tsx +0 -51
  55. package/packages/react/src/components/FeedbackForm.tsx +0 -43
  56. package/packages/react/src/components/FeedbackWidget.tsx +0 -32
  57. package/packages/react/src/components/NPSSurvey.tsx +0 -62
  58. package/packages/react/src/components/index.ts +0 -4
  59. package/packages/react/src/hooks/index.ts +0 -5
  60. package/packages/react/src/hooks/useFeedback.ts +0 -23
  61. package/packages/react/src/hooks/useFeedbackAdmin.ts +0 -24
  62. package/packages/react/src/hooks/useFeedbackForm.ts +0 -35
  63. package/packages/react/src/hooks/useNPS.ts +0 -26
  64. package/packages/react/src/index.tsx +0 -13
  65. package/packages/react/src/pages/FeedbackAdminPage.tsx +0 -71
  66. package/packages/react/src/pages/FeedbackPublicPage.tsx +0 -42
  67. package/packages/react/src/pages/FeedbackWidgetPage.tsx +0 -25
  68. package/packages/react/src/pages/index.ts +0 -3
  69. package/packages/react/tsconfig.json +0 -19
  70. package/packages/react/tsup.config.ts +0 -12
  71. package/packages/react-css/package.json +0 -36
  72. package/packages/react-css/src/components/index.ts +0 -5
  73. package/packages/react-css/src/components/index.tsx +0 -107
  74. package/packages/react-css/src/hooks/index.ts +0 -2
  75. package/packages/react-css/src/index.tsx +0 -5
  76. package/packages/react-css/src/pages/FeedbackAdminPage.tsx +0 -112
  77. package/packages/react-css/src/pages/FeedbackPage.tsx +0 -76
  78. package/packages/react-css/src/styles.css +0 -281
  79. package/packages/react-css/tsconfig.json +0 -19
  80. package/packages/react-css/tsup.config.ts +0 -10
  81. package/packages/shared/package.json +0 -44
  82. package/packages/shared/src/__tests__/feedback.test.ts +0 -72
  83. package/packages/shared/src/config.ts +0 -49
  84. package/packages/shared/src/index.ts +0 -111
  85. package/packages/shared/src/types.ts +0 -59
  86. package/packages/shared/tsconfig.json +0 -18
  87. package/packages/shared/tsup.config.ts +0 -11
  88. package/packages/shared/vitest.config.ts +0 -4
  89. package/packages/solidjs/package.json +0 -45
  90. package/packages/solidjs/src/components.tsx +0 -72
  91. package/packages/solidjs/src/index.tsx +0 -3
  92. package/packages/solidjs/src/primitives.ts +0 -49
  93. package/packages/solidjs/tsconfig.json +0 -20
  94. package/packages/solidjs/tsup.config.ts +0 -12
  95. package/packages/solidjs-css/package.json +0 -32
  96. package/packages/solidjs-css/src/index.tsx +0 -4
  97. package/packages/solidjs-css/src/pages/FeedbackAdminPage.tsx +0 -78
  98. package/packages/solidjs-css/src/pages/FeedbackPage.tsx +0 -65
  99. package/packages/solidjs-css/src/primitives/index.ts +0 -1
  100. package/packages/solidjs-css/src/styles.css +0 -281
  101. package/packages/solidjs-css/tsconfig.json +0 -20
  102. package/packages/solidjs-css/tsup.config.ts +0 -10
  103. package/pnpm-workspace.yaml +0 -2
  104. package/tsconfig.json +0 -23
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/styles.css"],"sourcesContent":["/* ─── Feedback Design Tokens (OKLCH) ──────────────────── */\n:root {\n --feedback-bg: oklch(0.12 0.01 250);\n --feedback-surface: oklch(0.16 0.01 250);\n --feedback-border: oklch(0.22 0.01 250);\n --feedback-text: oklch(0.95 0.01 250);\n --feedback-text-muted: oklch(0.58 0.02 250);\n --feedback-accent: oklch(0.65 0.20 265);\n --feedback-open: oklch(0.65 0.20 245);\n --feedback-review: oklch(0.72 0.18 60);\n --feedback-planned: oklch(0.70 0.22 280);\n --feedback-progress: oklch(0.65 0.20 265);\n --feedback-done: oklch(0.72 0.18 155);\n --feedback-declined: oklch(0.50 0.10 250);\n --feedback-bug: oklch(0.60 0.25 25);\n --feedback-feature: oklch(0.70 0.22 280);\n --feedback-suggestion: oklch(0.72 0.18 60);\n --feedback-general: oklch(0.65 0.20 245);\n --feedback-radius: 0.75rem;\n}\n\n/* ─── Feedback Card ──────────────────────────────────── */\n.feedback__card {\n display: flex;\n gap: 0.75rem;\n padding: 1rem;\n border: 1px solid var(--feedback-border);\n border-radius: var(--feedback-radius);\n background: oklch(1 0 0 / 0.02);\n transition: all 0.2s;\n cursor: pointer;\n}\n.feedback__card:hover { border-color: oklch(0.65 0.20 265 / 0.2); background: oklch(1 0 0 / 0.04); }\n.feedback__card-info { flex: 1; min-width: 0; }\n.feedback__card-badges { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.25rem; }\n.feedback__card-title { font-size: 0.875rem; font-weight: 600; color: oklch(1 0 0 / 0.9); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-bottom: 0.125rem; }\n.feedback__card-desc { font-size: 0.6875rem; color: oklch(1 0 0 / 0.4); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }\n.feedback__card-meta { display: flex; align-items: center; gap: 0.75rem; margin-top: 0.5rem; font-size: 0.625rem; color: oklch(1 0 0 / 0.25); }\n.feedback__card--bug { border-left: 3px solid var(--feedback-bug); }\n.feedback__card--feature { border-left: 3px solid var(--feedback-feature); }\n.feedback__card--suggestion { border-left: 3px solid var(--feedback-suggestion); }\n.feedback__card--general { border-left: 3px solid var(--feedback-general); }\n\n/* ─── Vote Button ────────────────────────────────────── */\n.feedback__vote-btn {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.125rem;\n padding: 0.375rem 0.5rem;\n border-radius: calc(var(--feedback-radius) * 0.8);\n border: none;\n font-size: 0.6875rem;\n font-weight: 700;\n cursor: pointer;\n transition: all 0.15s;\n font-variant-numeric: tabular-nums;\n}\n.feedback__vote-btn--inactive { background: oklch(1 0 0 / 0.05); color: oklch(1 0 0 / 0.3); }\n.feedback__vote-btn--inactive:hover { background: oklch(1 0 0 / 0.1); color: oklch(1 0 0 / 0.5); }\n.feedback__vote-btn--active { background: oklch(0.65 0.20 265 / 0.15); color: oklch(0.65 0.20 265); }\n.feedback__vote-btn-arrow { font-size: 0.875rem; }\n\n/* ─── Status Badge ───────────────────────────────────── */\n.feedback__status-badge { display: inline-flex; align-items: center; gap: 0.25rem; padding: 0.125rem 0.625rem; border-radius: 9999px; font-size: 0.625rem; font-weight: 500; }\n.feedback__status-badge--open { background: oklch(0.65 0.20 245 / 0.15); color: oklch(0.65 0.20 245); }\n.feedback__status-badge--under-review { background: oklch(0.72 0.18 60 / 0.15); color: oklch(0.72 0.18 60); }\n.feedback__status-badge--planned { background: oklch(0.70 0.22 280 / 0.15); color: oklch(0.70 0.22 280); }\n.feedback__status-badge--in-progress { background: oklch(0.65 0.20 265 / 0.15); color: oklch(0.65 0.20 265); }\n.feedback__status-badge--done { background: oklch(0.72 0.18 155 / 0.15); color: oklch(0.72 0.18 155); }\n.feedback__status-badge--declined { background: oklch(0.50 0.10 250 / 0.15); color: oklch(0.50 0.10 250); }\n\n/* ─── Priority Badge ─────────────────────────────────── */\n.feedback__priority-badge { padding: 0.125rem 0.5rem; border-radius: 9999px; font-size: 0.625rem; font-weight: 500; }\n.feedback__priority-badge--low { background: oklch(0.58 0.10 250 / 0.15); color: oklch(0.58 0.10 250); }\n.feedback__priority-badge--medium { background: oklch(0.72 0.18 60 / 0.15); color: oklch(0.72 0.18 60); }\n.feedback__priority-badge--high { background: oklch(0.68 0.22 35 / 0.15); color: oklch(0.68 0.22 35); }\n.feedback__priority-badge--critical { background: oklch(0.60 0.25 25 / 0.15); color: oklch(0.60 0.25 25); }\n\n/* ─── Type Badge ─────────────────────────────────────── */\n.feedback__type-badge { display: inline-flex; align-items: center; gap: 0.25rem; padding: 0.125rem 0.5rem; border-radius: 9999px; font-size: 0.625rem; font-weight: 500; }\n.feedback__type-badge--bug { background: oklch(0.60 0.25 25 / 0.15); color: oklch(0.60 0.25 25); }\n.feedback__type-badge--feature { background: oklch(0.70 0.22 280 / 0.15); color: oklch(0.70 0.22 280); }\n.feedback__type-badge--suggestion { background: oklch(0.72 0.18 60 / 0.15); color: oklch(0.72 0.18 60); }\n.feedback__type-badge--general { background: oklch(0.65 0.20 245 / 0.15); color: oklch(0.65 0.20 245); }\n\n/* ─── Widget ─────────────────────────────────────────── */\n.feedback__widget-trigger {\n position: fixed; top: 50%; right: 0; transform: translateY(-50%);\n z-index: 40; padding: 0.5rem 1rem; border-radius: var(--feedback-radius) 0 0 var(--feedback-radius);\n background: var(--feedback-accent); color: white; border: none; cursor: pointer;\n writing-mode: vertical-rl; font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.05em;\n box-shadow: -2px 0 12px oklch(0.65 0.20 265 / 0.3);\n}\n.feedback__widget-trigger:hover { background: oklch(0.70 0.22 265); }\n.feedback__widget-overlay { position: fixed; inset: 0; z-index: 50; display: flex; justify-content: flex-end; }\n.feedback__widget-backdrop { position: absolute; inset: 0; background: oklch(0 0 0 / 0.5); backdrop-filter: blur(4px); }\n.feedback__widget-panel { position: relative; width: 100%; max-width: 28rem; background: oklch(0.06 0.01 250); border-left: 1px solid var(--feedback-border); padding: 1.5rem; overflow-y: auto; }\n.feedback__widget-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1.5rem; }\n.feedback__widget-title { font-size: 1.125rem; font-weight: 700; color: var(--feedback-text); }\n\n/* ─── Form ───────────────────────────────────────────── */\n.feedback__form { display: flex; flex-direction: column; gap: 1rem; }\n.feedback__form-input { width: 100%; padding: 0.75rem 1rem; border: 1px solid var(--feedback-border); border-radius: var(--feedback-radius); background: oklch(1 0 0 / 0.03); font-size: 0.875rem; color: var(--feedback-text); outline: none; }\n.feedback__form-input::placeholder { color: oklch(1 0 0 / 0.3); }\n.feedback__form-input:focus { border-color: oklch(0.65 0.20 265 / 0.4); }\n.feedback__form-textarea { resize: none; min-height: 6rem; }\n.feedback__form-error { font-size: 0.6875rem; color: oklch(0.60 0.25 25); }\n.feedback__form-actions { display: flex; justify-content: flex-end; gap: 0.5rem; }\n\n/* ─── Type Selector ──────────────────────────────────── */\n.feedback__type-selector { display: flex; gap: 0.375rem; }\n.feedback__type-tab { display: flex; align-items: center; gap: 0.375rem; padding: 0.5rem 0.75rem; border-radius: calc(var(--feedback-radius) * 0.8); border: none; font-size: 0.6875rem; font-weight: 500; cursor: pointer; transition: all 0.15s; }\n.feedback__type-tab--inactive { background: oklch(1 0 0 / 0.05); color: oklch(1 0 0 / 0.5); }\n.feedback__type-tab--inactive:hover { background: oklch(1 0 0 / 0.1); }\n\n/* ─── NPS ────────────────────────────────────────────── */\n.feedback__nps { position: fixed; bottom: 1.5rem; right: 1.5rem; z-index: 50; width: 24rem; border: 1px solid oklch(1 0 0 / 0.1); border-radius: calc(var(--feedback-radius) * 1.5); background: oklch(0.08 0.01 250); padding: 1.5rem; box-shadow: 0 8px 32px oklch(0 0 0 / 0.5); }\n.feedback__nps-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.25rem; }\n.feedback__nps-title { font-size: 0.875rem; font-weight: 600; color: oklch(1 0 0 / 0.9); }\n.feedback__nps-subtitle { font-size: 0.6875rem; color: oklch(1 0 0 / 0.4); margin-bottom: 1rem; }\n.feedback__nps-scores { display: flex; gap: 0.25rem; }\n.feedback__nps-score-btn { flex: 1; padding: 0.625rem 0; border: none; border-radius: calc(var(--feedback-radius) * 0.8); background: oklch(1 0 0 / 0.05); color: oklch(1 0 0 / 0.5); font-size: 0.6875rem; font-weight: 700; cursor: pointer; transition: all 0.15s; }\n.feedback__nps-score-btn:hover { background: oklch(1 0 0 / 0.1); }\n.feedback__nps-labels { display: flex; justify-content: space-between; margin-top: 0.5rem; font-size: 0.625rem; color: oklch(1 0 0 / 0.2); }\n.feedback__nps-results { padding: 1.25rem; border: 1px solid var(--feedback-border); border-radius: var(--feedback-radius); background: oklch(1 0 0 / 0.02); }\n.feedback__nps-results-score { font-size: 1.875rem; font-weight: 900; font-variant-numeric: tabular-nums; }\n.feedback__nps-bar { display: flex; height: 1.25rem; overflow: hidden; border-radius: 9999px; margin: 1rem 0; }\n.feedback__nps-bar-detractors { background: oklch(0.60 0.25 25 / 0.7); }\n.feedback__nps-bar-passives { background: oklch(0.72 0.18 60 / 0.7); }\n.feedback__nps-bar-promoters { background: oklch(0.72 0.18 155 / 0.7); }\n.feedback__nps-breakdown { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; text-align: center; font-size: 0.6875rem; }\n\n/* ─── Board ──────────────────────────────────────────── */\n.feedback__board { display: flex; flex-direction: column; gap: 0.625rem; }\n\n/* ─── Admin Table ────────────────────────────────────── */\n.feedback__admin-table { width: 100%; font-size: 0.875rem; border-collapse: collapse; }\n.feedback__admin-table th { padding: 0.75rem 1rem; text-align: left; font-size: 0.625rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.05em; color: oklch(1 0 0 / 0.4); border-bottom: 1px solid oklch(1 0 0 / 0.08); }\n.feedback__admin-table td { padding: 0.75rem 1rem; border-bottom: 1px solid oklch(1 0 0 / 0.05); }\n.feedback__admin-table tr:hover { background: oklch(1 0 0 / 0.02); }\n.feedback__admin-select { padding: 0.25rem 0.5rem; border: 1px solid var(--feedback-border); border-radius: calc(var(--feedback-radius) * 0.6); background: oklch(1 0 0 / 0.05); font-size: 0.6875rem; color: var(--feedback-text); outline: none; }\n\n/* ─── Stats Grid ─────────────────────────────────────── */\n.feedback__stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 1rem; margin-bottom: 2rem; }\n.feedback__stat-card { padding: 1rem; border: 1px solid var(--feedback-border); border-radius: var(--feedback-radius); background: oklch(1 0 0 / 0.02); }\n.feedback__stat-icon { font-size: 1.125rem; }\n.feedback__stat-value { font-size: 1.5rem; font-weight: 700; font-variant-numeric: tabular-nums; color: oklch(1 0 0 / 0.9); }\n.feedback__stat-label { font-size: 0.6875rem; color: oklch(1 0 0 / 0.4); }\n\n/* ─── Search ─────────────────────────────────────────── */\n.feedback__search { width: 100%; max-width: 16rem; padding: 0.625rem 1rem; border: 1px solid var(--feedback-border); border-radius: var(--feedback-radius); background: oklch(1 0 0 / 0.03); font-size: 0.875rem; color: var(--feedback-text); outline: none; }\n.feedback__search::placeholder { color: oklch(1 0 0 / 0.3); }\n.feedback__search:focus { border-color: oklch(0.65 0.20 265 / 0.4); }\n\n/* ─── Filter Tabs ────────────────────────────────────── */\n.feedback__filter-tabs { display: flex; flex-wrap: wrap; gap: 0.375rem; }\n.feedback__filter-tab { padding: 0.375rem 0.75rem; border: none; border-radius: calc(var(--feedback-radius) * 0.8); font-size: 0.6875rem; font-weight: 500; cursor: pointer; }\n.feedback__filter-tab--active { background: var(--feedback-accent); color: white; }\n.feedback__filter-tab--inactive { background: oklch(1 0 0 / 0.05); color: oklch(1 0 0 / 0.5); }\n.feedback__filter-tab--inactive:hover { background: oklch(1 0 0 / 0.1); }\n\n/* ─── Btn ────────────────────────────────────────────── */\n.feedback__btn { padding: 0.5rem 1rem; border-radius: calc(var(--feedback-radius) * 0.8); font-size: 0.6875rem; font-weight: 500; cursor: pointer; border: none; transition: all 0.15s; }\n.feedback__btn--primary { background: var(--feedback-accent); color: white; }\n.feedback__btn--primary:hover { background: oklch(0.70 0.22 265); }\n.feedback__btn--outline { border: 1px solid var(--feedback-border); background: transparent; color: oklch(1 0 0 / 0.6); }\n.feedback__btn--danger { background: oklch(0.60 0.25 25 / 0.2); color: oklch(0.60 0.25 25); }\n\n/* ─── Skeleton ───────────────────────────────────────── */\n.feedback__skeleton { background: oklch(1 0 0 / 0.05); border-radius: var(--feedback-radius); animation: feedback-pulse 1.5s ease-in-out infinite; }\n@keyframes feedback-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }\n\n/* ─── Empty ──────────────────────────────────────────── */\n.feedback__empty { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 4rem 1rem; text-align: center; }\n.feedback__empty-icon { font-size: 3rem; opacity: 0.2; margin-bottom: 0.75rem; }\n.feedback__empty-text { font-size: 0.875rem; color: oklch(1 0 0 / 0.4); }\n\n/* ─── Success ────────────────────────────────────────── */\n.feedback__success { display: flex; flex-direction: column; align-items: center; padding: 2rem; text-align: center; }\n.feedback__success-icon { font-size: 2.5rem; margin-bottom: 0.75rem; }\n.feedback__success-text { font-size: 1rem; font-weight: 600; color: oklch(1 0 0 / 0.9); margin-bottom: 0.25rem; }\n.feedback__success-sub { font-size: 0.875rem; color: oklch(1 0 0 / 0.5); }\n\n/* ─── Tag ────────────────────────────────────────────── */\n.feedback__tag { padding: 0.125rem 0.375rem; border-radius: 0.25rem; background: oklch(1 0 0 / 0.05); font-size: 0.625rem; color: oklch(1 0 0 / 0.3); }\n\n/* ─── Close Button ───────────────────────────────────── */\n.feedback__close-btn { padding: 0.375rem; border: none; background: transparent; color: oklch(1 0 0 / 0.3); cursor: pointer; border-radius: calc(var(--feedback-radius) * 0.6); }\n.feedback__close-btn:hover { color: oklch(1 0 0 / 0.5); background: oklch(1 0 0 / 0.05); }\n\n/* ─── Comment Thread ─────────────────────────────────── */\n.feedback__comment-thread { display: flex; flex-direction: column; gap: 1rem; padding: 1rem; border: 1px solid var(--feedback-border); border-radius: var(--feedback-radius); background: oklch(1 0 0 / 0.01); }\n.feedback__comment { display: flex; gap: 0.75rem; }\n.feedback__comment-avatar { width: 2rem; height: 2rem; border-radius: 50%; background: oklch(0.65 0.20 265 / 0.2); display: flex; align-items: center; justify-content: center; font-size: 0.875rem; flex-shrink: 0; }\n.feedback__comment-body { flex: 1; }\n.feedback__comment-header { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.25rem; }\n.feedback__comment-author { font-size: 0.75rem; font-weight: 600; color: oklch(1 0 0 / 0.8); }\n.feedback__comment-time { font-size: 0.625rem; color: oklch(1 0 0 / 0.3); }\n.feedback__comment-text { font-size: 0.6875rem; color: oklch(1 0 0 / 0.7); line-height: 1.4; }\n.feedback__comment-reply-btn { margin-top: 0.5rem; padding: 0.25rem 0.5rem; font-size: 0.625rem; border: none; background: transparent; color: oklch(0.65 0.20 265); cursor: pointer; transition: all 0.1s; }\n.feedback__comment-reply-btn:hover { color: oklch(0.70 0.22 265); }\n\n/* ─── Rating Component ───────────────────────────────── */\n.feedback__rating { display: flex; gap: 0.25rem; }\n.feedback__rating-star { font-size: 1.5rem; cursor: pointer; opacity: 0.3; transition: all 0.15s; }\n.feedback__rating-star--filled { opacity: 1; color: oklch(0.72 0.18 60); }\n.feedback__rating-star:hover { opacity: 1; transform: scale(1.1); }\n\n/* ─── Sentiment Indicator ────────────────────────────── */\n.feedback__sentiment-card { padding: 1rem; border: 1px solid var(--feedback-border); border-radius: var(--feedback-radius); background: oklch(1 0 0 / 0.02); text-align: center; }\n.feedback__sentiment-icon { font-size: 2rem; margin-bottom: 0.5rem; }\n.feedback__sentiment-label { font-size: 0.875rem; font-weight: 600; color: oklch(1 0 0 / 0.8); margin-bottom: 0.25rem; }\n.feedback__sentiment-count { font-size: 0.6875rem; color: oklch(1 0 0 / 0.4); }\n\n/* ─── Response Panel ─────────────────────────────────── */\n.feedback__response-panel { border: 1px solid var(--feedback-border); border-radius: var(--feedback-radius); background: oklch(1 0 0 / 0.02); padding: 1rem; }\n.feedback__response-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.75rem; }\n.feedback__response-title { font-size: 0.875rem; font-weight: 600; color: oklch(1 0 0 / 0.8); }\n.feedback__response-time { font-size: 0.625rem; color: oklch(1 0 0 / 0.3); }\n.feedback__response-body { font-size: 0.6875rem; color: oklch(1 0 0 / 0.7); line-height: 1.5; }\n.feedback__response-actions { display: flex; gap: 0.5rem; margin-top: 0.75rem; }\n.feedback__response-btn { padding: 0.25rem 0.5rem; font-size: 0.625rem; border: none; background: oklch(1 0 0 / 0.05); color: oklch(1 0 0 / 0.5); cursor: pointer; border-radius: calc(var(--feedback-radius) * 0.6); transition: all 0.1s; }\n.feedback__response-btn:hover { background: oklch(1 0 0 / 0.1); color: oklch(1 0 0 / 0.6); }\n\n/* ─── Analytics Chart ────────────────────────────────── */\n.feedback__analytics { border: 1px solid var(--feedback-border); border-radius: var(--feedback-radius); background: oklch(1 0 0 / 0.02); padding: 1rem; }\n.feedback__analytics-title { font-size: 0.875rem; font-weight: 600; color: oklch(1 0 0 / 0.8); margin-bottom: 1rem; }\n.feedback__analytics-chart { display: flex; align-items: flex-end; gap: 0.5rem; height: 10rem; }\n.feedback__analytics-bar { flex: 1; border-radius: 0.25rem 0.25rem 0 0; background: linear-gradient(to top, oklch(0.65 0.20 265), oklch(0.65 0.20 265 / 0.4)); transition: all 0.2s; position: relative; }\n.feedback__analytics-bar:hover { background: linear-gradient(to top, oklch(0.70 0.22 265), oklch(0.70 0.22 265)); }\n.feedback__analytics-label { position: absolute; bottom: -1.5rem; left: 50%; transform: translateX(-50%); font-size: 0.625rem; color: oklch(1 0 0 / 0.4); white-space: nowrap; }\n\n/* ─── Filter Control Panel ───────────────────────────── */\n.feedback__filter-panel { border: 1px solid var(--feedback-border); border-radius: var(--feedback-radius); background: oklch(1 0 0 / 0.02); padding: 1rem; }\n.feedback__filter-section { margin-bottom: 1rem; }\n.feedback__filter-section:last-child { margin-bottom: 0; }\n.feedback__filter-section-title { font-size: 0.6875rem; font-weight: 600; text-transform: uppercase; color: oklch(1 0 0 / 0.4); margin-bottom: 0.5rem; letter-spacing: 0.05em; }\n.feedback__filter-options { display: flex; flex-direction: column; gap: 0.25rem; }\n.feedback__filter-option { display: flex; align-items: center; gap: 0.5rem; padding: 0.25rem 0; font-size: 0.6875rem; }\n.feedback__filter-option input { cursor: pointer; }\n.feedback__filter-option-label { color: oklch(1 0 0 / 0.7); cursor: pointer; }\n\n/* ─── Tag Selector ───────────────────────────────────── */\n.feedback__tag-selector { padding: 1rem; border: 1px solid var(--feedback-border); border-radius: var(--feedback-radius); background: oklch(1 0 0 / 0.02); }\n.feedback__tag-selector-label { display: block; font-size: 0.6875rem; font-weight: 500; color: oklch(1 0 0 / 0.6); margin-bottom: 0.5rem; text-transform: uppercase; }\n.feedback__tag-list { display: flex; flex-wrap: wrap; gap: 0.5rem; }\n.feedback__tag-item { display: inline-flex; align-items: center; gap: 0.25rem; padding: 0.375rem 0.75rem; border-radius: 9999px; background: oklch(0.65 0.20 265 / 0.15); color: oklch(0.65 0.20 265); font-size: 0.6875rem; font-weight: 500; }\n.feedback__tag-remove { margin-left: 0.25rem; cursor: pointer; font-weight: 700; opacity: 0.6; transition: opacity 0.1s; }\n.feedback__tag-remove:hover { opacity: 1; }\n\n/* ─── Feedback Form Actions ──────────────────────────── */\n.feedback__form-footer { display: flex; justify-content: space-between; align-items: center; padding-top: 1rem; border-top: 1px solid var(--feedback-border); }\n.feedback__form-counter { font-size: 0.625rem; color: oklch(1 0 0 / 0.3); }\n.feedback__form-actions-group { display: flex; gap: 0.5rem; }\n\n/* ─── Feedback Status Indicator ──────────────────────── */\n.feedback__status-indicator { display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.375rem 0.75rem; border-radius: 9999px; font-size: 0.625rem; font-weight: 500; }\n.feedback__status-indicator--new { background: oklch(0.65 0.20 245 / 0.15); color: oklch(0.65 0.20 245); }\n.feedback__status-indicator--in-review { background: oklch(0.72 0.18 60 / 0.15); color: oklch(0.72 0.18 60); }\n.feedback__status-indicator--implemented { background: oklch(0.72 0.18 155 / 0.15); color: oklch(0.72 0.18 155); }\n\n/* ─── Detailed Stats Row ─────────────────────────────── */\n.feedback__detailed-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 0.5rem; }\n.feedback__detailed-stat-item { padding: 0.75rem; border: 1px solid var(--feedback-border); border-radius: var(--feedback-radius); background: oklch(1 0 0 / 0.01); text-align: center; }\n.feedback__detailed-stat-icon { font-size: 1.25rem; margin-bottom: 0.25rem; }\n.feedback__detailed-stat-value { font-size: 1rem; font-weight: 700; color: oklch(1 0 0 / 0.9); }\n.feedback__detailed-stat-label { font-size: 0.625rem; color: oklch(1 0 0 / 0.4); margin-top: 0.25rem; }\n\n/* ─── Breadcrumb Navigation ──────────────────────────── */\n.feedback__breadcrumb { display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; margin-bottom: 1rem; }\n.feedback__breadcrumb-item { color: oklch(1 0 0 / 0.5); }\n.feedback__breadcrumb-item--active { color: oklch(1 0 0 / 0.8); font-weight: 500; }\n.feedback__breadcrumb-sep { color: oklch(1 0 0 / 0.2); margin: 0 0.25rem; }\n\n/* ─── Pagination Controls ────────────────────────────── */\n.feedback__pagination { display: flex; align-items: center; gap: 0.5rem; justify-content: center; padding: 1rem; }\n.feedback__pagination-btn { padding: 0.375rem 0.75rem; border: 1px solid var(--feedback-border); border-radius: calc(var(--feedback-radius) * 0.6); background: oklch(1 0 0 / 0.05); color: oklch(1 0 0 / 0.6); font-size: 0.6875rem; cursor: pointer; transition: all 0.1s; }\n.feedback__pagination-btn:hover:not(:disabled) { background: oklch(1 0 0 / 0.1); color: oklch(1 0 0 / 0.8); }\n.feedback__pagination-btn:disabled { opacity: 0.5; cursor: not-allowed; }\n.feedback__pagination-info { font-size: 0.6875rem; color: oklch(1 0 0 / 0.5); }\n"],"mappings":"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","names":[]}
@@ -0,0 +1,49 @@
1
+ export { FeedbackFilter, FeedbackProvider, useFeedback, useFeedbackAdmin, useFeedbackConfig, useFeedbackForm, useNPS } from '@geenius/feedback-react';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+ import { FeedbackItem, FeedbackType, NPSResponse, FeedbackPriority, FeedbackStatus } from '@geenius/feedback-shared';
4
+ export { FeedbackConfig, FeedbackItem, FeedbackPriority, FeedbackStats, FeedbackStatus, FeedbackType, NPSResponse, NPSStats } from '@geenius/feedback-shared';
5
+
6
+ declare function StatusBadge({ status }: {
7
+ status: FeedbackStatus;
8
+ }): react_jsx_runtime.JSX.Element;
9
+ declare function PriorityBadge({ priority }: {
10
+ priority: FeedbackPriority;
11
+ }): react_jsx_runtime.JSX.Element;
12
+ declare function TypeBadge({ type }: {
13
+ type: FeedbackType;
14
+ }): react_jsx_runtime.JSX.Element;
15
+ declare function FeedbackCard({ item, onVote, hasVoted, onClick }: {
16
+ item: FeedbackItem;
17
+ onVote?: (id: string) => void;
18
+ hasVoted?: boolean;
19
+ onClick?: (id: string) => void;
20
+ }): react_jsx_runtime.JSX.Element;
21
+ declare function FeedbackTypeSelector({ value, onChange }: {
22
+ value: FeedbackType;
23
+ onChange: (t: FeedbackType) => void;
24
+ }): react_jsx_runtime.JSX.Element;
25
+ declare function FeedbackForm({ onSubmit, onClose }: {
26
+ onSubmit: (data: {
27
+ type: FeedbackType;
28
+ title: string;
29
+ description: string;
30
+ }) => Promise<string>;
31
+ onClose?: () => void;
32
+ }): react_jsx_runtime.JSX.Element;
33
+ declare function FeedbackWidget({ onSubmit, position }: {
34
+ onSubmit: (data: {
35
+ type: FeedbackType;
36
+ title: string;
37
+ description: string;
38
+ }) => Promise<string>;
39
+ position?: 'left' | 'right';
40
+ }): react_jsx_runtime.JSX.Element;
41
+ declare function NPSSurvey({ onSubmit, onDismiss }: {
42
+ onSubmit: (score: number, comment?: string) => void;
43
+ onDismiss: () => void;
44
+ }): react_jsx_runtime.JSX.Element;
45
+ declare function NPSResults({ responses }: {
46
+ responses: NPSResponse[];
47
+ }): react_jsx_runtime.JSX.Element;
48
+
49
+ export { FeedbackCard, FeedbackForm, FeedbackTypeSelector, FeedbackWidget, NPSResults, NPSSurvey, PriorityBadge, StatusBadge, TypeBadge };
@@ -0,0 +1,228 @@
1
+ // src/index.tsx
2
+ import { FeedbackProvider, useFeedbackConfig } from "@geenius/feedback-react";
3
+
4
+ // src/hooks/index.ts
5
+ import { useFeedback, useFeedbackForm, useNPS, useFeedbackAdmin } from "@geenius/feedback-react";
6
+
7
+ // src/components/index.tsx
8
+ import { useState } from "react";
9
+ import { STATUS_CONFIG, PRIORITY_CONFIG, TYPE_CONFIG, FEEDBACK_TYPES, formatRelativeTime, calcNPSStats } from "@geenius/feedback-shared";
10
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
+ function StatusBadge({ status }) {
12
+ return /* @__PURE__ */ jsxs("span", { className: `feedback__status-badge feedback__status-badge--${status}`, children: [
13
+ STATUS_CONFIG[status].emoji,
14
+ " ",
15
+ STATUS_CONFIG[status].label
16
+ ] });
17
+ }
18
+ function PriorityBadge({ priority }) {
19
+ return /* @__PURE__ */ jsx("span", { className: `feedback__priority-badge feedback__priority-badge--${priority}`, children: PRIORITY_CONFIG[priority].label });
20
+ }
21
+ function TypeBadge({ type }) {
22
+ return /* @__PURE__ */ jsxs("span", { className: `feedback__type-badge feedback__type-badge--${type}`, children: [
23
+ TYPE_CONFIG[type].icon,
24
+ " ",
25
+ TYPE_CONFIG[type].label
26
+ ] });
27
+ }
28
+ function FeedbackCard({ item, onVote, hasVoted, onClick }) {
29
+ return /* @__PURE__ */ jsxs("div", { className: `feedback__card feedback__card--${item.type}`, onClick: () => onClick?.(item.id), children: [
30
+ onVote && /* @__PURE__ */ jsxs("button", { type: "button", className: `feedback__vote-btn ${hasVoted ? "feedback__vote-btn--active" : "feedback__vote-btn--inactive"}`, onClick: (e) => {
31
+ e.stopPropagation();
32
+ onVote(item.id);
33
+ }, children: [
34
+ /* @__PURE__ */ jsx("span", { className: "feedback__vote-btn-arrow", children: hasVoted ? "\u25B2" : "\u25B3" }),
35
+ /* @__PURE__ */ jsx("span", { children: item.votes })
36
+ ] }),
37
+ /* @__PURE__ */ jsxs("div", { className: "feedback__card-info", children: [
38
+ /* @__PURE__ */ jsxs("div", { className: "feedback__card-badges", children: [
39
+ /* @__PURE__ */ jsx(TypeBadge, { type: item.type }),
40
+ /* @__PURE__ */ jsx(StatusBadge, { status: item.status }),
41
+ /* @__PURE__ */ jsx(PriorityBadge, { priority: item.priority })
42
+ ] }),
43
+ /* @__PURE__ */ jsx("div", { className: "feedback__card-title", children: item.title }),
44
+ /* @__PURE__ */ jsx("div", { className: "feedback__card-desc", children: item.description }),
45
+ /* @__PURE__ */ jsxs("div", { className: "feedback__card-meta", children: [
46
+ item.userName && /* @__PURE__ */ jsx("span", { children: item.userName }),
47
+ /* @__PURE__ */ jsx("span", { children: formatRelativeTime(item.createdAt) }),
48
+ item.tags.map((t) => /* @__PURE__ */ jsx("span", { className: "feedback__tag", children: t }, t))
49
+ ] })
50
+ ] })
51
+ ] });
52
+ }
53
+ function FeedbackTypeSelector({ value, onChange }) {
54
+ return /* @__PURE__ */ jsx("div", { className: "feedback__type-selector", children: FEEDBACK_TYPES.map((t) => /* @__PURE__ */ jsxs(
55
+ "button",
56
+ {
57
+ type: "button",
58
+ onClick: () => onChange(t),
59
+ className: `feedback__type-tab ${value === t ? "" : "feedback__type-tab--inactive"}`,
60
+ style: value === t ? { background: TYPE_CONFIG[t].color, color: "white" } : void 0,
61
+ children: [
62
+ TYPE_CONFIG[t].icon,
63
+ " ",
64
+ TYPE_CONFIG[t].label
65
+ ]
66
+ },
67
+ t
68
+ )) });
69
+ }
70
+ function FeedbackForm({ onSubmit, onClose }) {
71
+ const [type, setType] = useState("general");
72
+ const [title, setTitle] = useState("");
73
+ const [desc, setDesc] = useState("");
74
+ const [submitting, setSubmitting] = useState(false);
75
+ const [error, setError] = useState(null);
76
+ const [success, setSuccess] = useState(false);
77
+ const submit = async () => {
78
+ if (!title.trim()) {
79
+ setError("Title required");
80
+ return;
81
+ }
82
+ ;
83
+ if (desc.length < 10) {
84
+ setError("10+ chars");
85
+ return;
86
+ }
87
+ setSubmitting(true);
88
+ setError(null);
89
+ try {
90
+ await onSubmit({ type, title, description: desc });
91
+ setSuccess(true);
92
+ } catch (e) {
93
+ setError(String(e));
94
+ } finally {
95
+ setSubmitting(false);
96
+ }
97
+ };
98
+ if (success) return /* @__PURE__ */ jsxs("div", { className: "feedback__success", children: [
99
+ /* @__PURE__ */ jsx("div", { className: "feedback__success-icon", children: "\u{1F389}" }),
100
+ /* @__PURE__ */ jsx("div", { className: "feedback__success-text", children: "Thank you!" }),
101
+ /* @__PURE__ */ jsx("div", { className: "feedback__success-sub", children: "Feedback submitted" })
102
+ ] });
103
+ return /* @__PURE__ */ jsxs("div", { className: "feedback__form", children: [
104
+ /* @__PURE__ */ jsx(FeedbackTypeSelector, { value: type, onChange: setType }),
105
+ /* @__PURE__ */ jsx("input", { type: "text", className: "feedback__form-input", placeholder: "Title\u2026", value: title, onChange: (e) => setTitle(e.target.value) }),
106
+ /* @__PURE__ */ jsx("textarea", { className: "feedback__form-input feedback__form-textarea", placeholder: "Description\u2026", value: desc, onChange: (e) => setDesc(e.target.value) }),
107
+ error && /* @__PURE__ */ jsx("div", { className: "feedback__form-error", children: error }),
108
+ /* @__PURE__ */ jsxs("div", { className: "feedback__form-actions", children: [
109
+ onClose && /* @__PURE__ */ jsx("button", { type: "button", className: "feedback__btn feedback__btn--outline", onClick: onClose, children: "Cancel" }),
110
+ /* @__PURE__ */ jsx("button", { type: "button", className: "feedback__btn feedback__btn--primary", onClick: submit, disabled: submitting, children: submitting ? "Submitting\u2026" : "Submit" })
111
+ ] })
112
+ ] });
113
+ }
114
+ function FeedbackWidget({ onSubmit, position = "right" }) {
115
+ const [isOpen, setIsOpen] = useState(false);
116
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
117
+ /* @__PURE__ */ jsx("button", { type: "button", className: "feedback__widget-trigger", onClick: () => setIsOpen(true), children: "Feedback" }),
118
+ isOpen && /* @__PURE__ */ jsxs("div", { className: "feedback__widget-overlay", onClick: () => setIsOpen(false), children: [
119
+ /* @__PURE__ */ jsx("div", { className: "feedback__widget-backdrop" }),
120
+ /* @__PURE__ */ jsxs("div", { className: "feedback__widget-panel", onClick: (e) => e.stopPropagation(), children: [
121
+ /* @__PURE__ */ jsxs("div", { className: "feedback__widget-header", children: [
122
+ /* @__PURE__ */ jsx("span", { className: "feedback__widget-title", children: "Send Feedback" }),
123
+ /* @__PURE__ */ jsx("button", { type: "button", className: "feedback__close-btn", onClick: () => setIsOpen(false), children: "\u2715" })
124
+ ] }),
125
+ /* @__PURE__ */ jsx(FeedbackForm, { onSubmit, onClose: () => setIsOpen(false) })
126
+ ] })
127
+ ] })
128
+ ] });
129
+ }
130
+ function NPSSurvey({ onSubmit, onDismiss }) {
131
+ const [score, setScore] = useState(null);
132
+ const [comment, setComment] = useState("");
133
+ const [step, setStep] = useState("score");
134
+ return /* @__PURE__ */ jsxs("div", { className: "feedback__nps", children: [
135
+ step === "score" && /* @__PURE__ */ jsxs("div", { children: [
136
+ /* @__PURE__ */ jsxs("div", { className: "feedback__nps-header", children: [
137
+ /* @__PURE__ */ jsx("span", { className: "feedback__nps-title", children: "How likely to recommend us?" }),
138
+ /* @__PURE__ */ jsx("button", { type: "button", className: "feedback__close-btn", onClick: onDismiss, children: "\u2715" })
139
+ ] }),
140
+ /* @__PURE__ */ jsx("div", { className: "feedback__nps-subtitle", children: "0 = Not at all \xB7 10 = Extremely likely" }),
141
+ /* @__PURE__ */ jsx("div", { className: "feedback__nps-scores", children: Array.from({ length: 11 }).map((_, i) => /* @__PURE__ */ jsx("button", { type: "button", className: "feedback__nps-score-btn", onClick: () => {
142
+ setScore(i);
143
+ setStep("comment");
144
+ }, children: i }, i)) }),
145
+ /* @__PURE__ */ jsxs("div", { className: "feedback__nps-labels", children: [
146
+ /* @__PURE__ */ jsx("span", { children: "Not likely" }),
147
+ /* @__PURE__ */ jsx("span", { children: "Very likely" })
148
+ ] })
149
+ ] }),
150
+ step === "comment" && /* @__PURE__ */ jsxs("div", { children: [
151
+ /* @__PURE__ */ jsxs("div", { className: "feedback__nps-title", style: { marginBottom: "0.75rem" }, children: [
152
+ "Score: ",
153
+ score
154
+ ] }),
155
+ /* @__PURE__ */ jsx("textarea", { className: "feedback__form-input feedback__form-textarea", value: comment, onChange: (e) => setComment(e.target.value), placeholder: "Optional\u2026" }),
156
+ /* @__PURE__ */ jsx("button", { type: "button", className: "feedback__btn feedback__btn--primary", style: { width: "100%", marginTop: "0.75rem" }, onClick: () => {
157
+ onSubmit(score, comment || void 0);
158
+ setStep("thanks");
159
+ }, children: "Submit" })
160
+ ] }),
161
+ step === "thanks" && /* @__PURE__ */ jsxs("div", { className: "feedback__success", children: [
162
+ /* @__PURE__ */ jsx("div", { className: "feedback__success-icon", children: "\u{1F389}" }),
163
+ /* @__PURE__ */ jsx("div", { className: "feedback__success-text", children: "Thank you!" })
164
+ ] })
165
+ ] });
166
+ }
167
+ function NPSResults({ responses }) {
168
+ const stats = calcNPSStats(responses);
169
+ const total = stats.totalResponses || 1;
170
+ const color = stats.npsScore >= 50 ? "oklch(0.72 0.18 155)" : stats.npsScore >= 0 ? "oklch(0.72 0.18 60)" : "oklch(0.60 0.25 25)";
171
+ return /* @__PURE__ */ jsxs("div", { className: "feedback__nps-results", children: [
172
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: "0.5rem" }, children: [
173
+ /* @__PURE__ */ jsx("span", { children: "NPS Score" }),
174
+ /* @__PURE__ */ jsx("span", { className: "feedback__nps-results-score", style: { color }, children: stats.npsScore })
175
+ ] }),
176
+ /* @__PURE__ */ jsxs("div", { className: "feedback__nps-bar", children: [
177
+ /* @__PURE__ */ jsx("div", { className: "feedback__nps-bar-detractors", style: { width: `${stats.detractors / total * 100}%` } }),
178
+ /* @__PURE__ */ jsx("div", { className: "feedback__nps-bar-passives", style: { width: `${stats.passives / total * 100}%` } }),
179
+ /* @__PURE__ */ jsx("div", { className: "feedback__nps-bar-promoters", style: { width: `${stats.promoters / total * 100}%` } })
180
+ ] }),
181
+ /* @__PURE__ */ jsxs("div", { className: "feedback__nps-breakdown", children: [
182
+ /* @__PURE__ */ jsxs("div", { children: [
183
+ /* @__PURE__ */ jsx("span", { style: { color: "oklch(0.60 0.25 25)", fontWeight: 700 }, children: stats.detractors }),
184
+ /* @__PURE__ */ jsx("br", {}),
185
+ /* @__PURE__ */ jsx("span", { style: { color: "oklch(1 0 0/0.3)" }, children: "Detractors" })
186
+ ] }),
187
+ /* @__PURE__ */ jsxs("div", { children: [
188
+ /* @__PURE__ */ jsx("span", { style: { color: "oklch(0.72 0.18 60)", fontWeight: 700 }, children: stats.passives }),
189
+ /* @__PURE__ */ jsx("br", {}),
190
+ /* @__PURE__ */ jsx("span", { style: { color: "oklch(1 0 0/0.3)" }, children: "Passives" })
191
+ ] }),
192
+ /* @__PURE__ */ jsxs("div", { children: [
193
+ /* @__PURE__ */ jsx("span", { style: { color: "oklch(0.72 0.18 155)", fontWeight: 700 }, children: stats.promoters }),
194
+ /* @__PURE__ */ jsx("br", {}),
195
+ /* @__PURE__ */ jsx("span", { style: { color: "oklch(1 0 0/0.3)" }, children: "Promoters" })
196
+ ] })
197
+ ] }),
198
+ /* @__PURE__ */ jsxs("div", { style: { marginTop: "0.75rem", paddingTop: "0.75rem", borderTop: "1px solid oklch(1 0 0/0.05)", display: "flex", justifyContent: "space-between", fontSize: "0.6875rem", color: "oklch(1 0 0/0.4)" }, children: [
199
+ /* @__PURE__ */ jsxs("span", { children: [
200
+ "Avg: ",
201
+ stats.averageScore,
202
+ "/10"
203
+ ] }),
204
+ /* @__PURE__ */ jsxs("span", { children: [
205
+ stats.totalResponses,
206
+ " responses"
207
+ ] })
208
+ ] })
209
+ ] });
210
+ }
211
+ export {
212
+ FeedbackCard,
213
+ FeedbackForm,
214
+ FeedbackProvider,
215
+ FeedbackTypeSelector,
216
+ FeedbackWidget,
217
+ NPSResults,
218
+ NPSSurvey,
219
+ PriorityBadge,
220
+ StatusBadge,
221
+ TypeBadge,
222
+ useFeedback,
223
+ useFeedbackAdmin,
224
+ useFeedbackConfig,
225
+ useFeedbackForm,
226
+ useNPS
227
+ };
228
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.tsx","../src/hooks/index.ts","../src/components/index.tsx"],"sourcesContent":["export { FeedbackProvider, useFeedbackConfig } from '@geenius/feedback-react'\nexport { useFeedback, useFeedbackForm, useNPS, useFeedbackAdmin } from './hooks'\nexport type { FeedbackFilter } from './hooks'\nexport { StatusBadge, PriorityBadge, TypeBadge, FeedbackCard, FeedbackTypeSelector, FeedbackForm, FeedbackWidget, NPSSurvey, NPSResults } from './components'\nimport './styles.css'\nexport type { FeedbackItem, NPSResponse, FeedbackConfig, FeedbackStats, NPSStats, FeedbackType, FeedbackStatus, FeedbackPriority } from '@geenius/feedback-shared'\n","export { useFeedback, useFeedbackForm, useNPS, useFeedbackAdmin } from '@geenius/feedback-react'\nexport type { FeedbackFilter } from '@geenius/feedback-react'\n","import React, { useState } from 'react'\nimport type { FeedbackItem, FeedbackType, FeedbackStatus, FeedbackPriority, NPSResponse } from '@geenius/feedback-shared'\nimport { STATUS_CONFIG, PRIORITY_CONFIG, TYPE_CONFIG, FEEDBACK_TYPES, formatRelativeTime, calcNPSStats, getNPSCategory } from '@geenius/feedback-shared'\n\nexport function StatusBadge({ status }: { status: FeedbackStatus }) {\n return <span className={`feedback__status-badge feedback__status-badge--${status}`}>{STATUS_CONFIG[status].emoji} {STATUS_CONFIG[status].label}</span>\n}\n\nexport function PriorityBadge({ priority }: { priority: FeedbackPriority }) {\n return <span className={`feedback__priority-badge feedback__priority-badge--${priority}`}>{PRIORITY_CONFIG[priority].label}</span>\n}\n\nexport function TypeBadge({ type }: { type: FeedbackType }) {\n return <span className={`feedback__type-badge feedback__type-badge--${type}`}>{TYPE_CONFIG[type].icon} {TYPE_CONFIG[type].label}</span>\n}\n\nexport function FeedbackCard({ item, onVote, hasVoted, onClick }: { item: FeedbackItem; onVote?: (id: string) => void; hasVoted?: boolean; onClick?: (id: string) => void }) {\n return (\n <div className={`feedback__card feedback__card--${item.type}`} onClick={() => onClick?.(item.id)}>\n {onVote && (\n <button type=\"button\" className={`feedback__vote-btn ${hasVoted ? 'feedback__vote-btn--active' : 'feedback__vote-btn--inactive'}`} onClick={e => { e.stopPropagation(); onVote(item.id) }}>\n <span className=\"feedback__vote-btn-arrow\">{hasVoted ? '▲' : '△'}</span>\n <span>{item.votes}</span>\n </button>\n )}\n <div className=\"feedback__card-info\">\n <div className=\"feedback__card-badges\"><TypeBadge type={item.type} /><StatusBadge status={item.status} /><PriorityBadge priority={item.priority} /></div>\n <div className=\"feedback__card-title\">{item.title}</div>\n <div className=\"feedback__card-desc\">{item.description}</div>\n <div className=\"feedback__card-meta\">{item.userName && <span>{item.userName}</span>}<span>{formatRelativeTime(item.createdAt)}</span>{item.tags.map(t => <span key={t} className=\"feedback__tag\">{t}</span>)}</div>\n </div>\n </div>\n )\n}\n\nexport function FeedbackTypeSelector({ value, onChange }: { value: FeedbackType; onChange: (t: FeedbackType) => void }) {\n return (\n <div className=\"feedback__type-selector\">\n {FEEDBACK_TYPES.map(t => <button key={t} type=\"button\" onClick={() => onChange(t)}\n className={`feedback__type-tab ${value === t ? '' : 'feedback__type-tab--inactive'}`}\n style={value === t ? { background: TYPE_CONFIG[t].color, color: 'white' } : undefined}>{TYPE_CONFIG[t].icon} {TYPE_CONFIG[t].label}</button>)}\n </div>\n )\n}\n\nexport function FeedbackForm({ onSubmit, onClose }: { onSubmit: (data: { type: FeedbackType; title: string; description: string }) => Promise<string>; onClose?: () => void }) {\n const [type, setType] = useState<FeedbackType>('general')\n const [title, setTitle] = useState(''); const [desc, setDesc] = useState('')\n const [submitting, setSubmitting] = useState(false); const [error, setError] = useState<string | null>(null); const [success, setSuccess] = useState(false)\n const submit = async () => {\n if (!title.trim()) { setError('Title required'); return }; if (desc.length < 10) { setError('10+ chars'); return }\n setSubmitting(true); setError(null); try { await onSubmit({ type, title, description: desc }); setSuccess(true) } catch (e) { setError(String(e)) } finally { setSubmitting(false) }\n }\n if (success) return <div className=\"feedback__success\"><div className=\"feedback__success-icon\">🎉</div><div className=\"feedback__success-text\">Thank you!</div><div className=\"feedback__success-sub\">Feedback submitted</div></div>\n return (\n <div className=\"feedback__form\">\n <FeedbackTypeSelector value={type} onChange={setType} />\n <input type=\"text\" className=\"feedback__form-input\" placeholder=\"Title…\" value={title} onChange={e => setTitle(e.target.value)} />\n <textarea className=\"feedback__form-input feedback__form-textarea\" placeholder=\"Description…\" value={desc} onChange={e => setDesc(e.target.value)} />\n {error && <div className=\"feedback__form-error\">{error}</div>}\n <div className=\"feedback__form-actions\">\n {onClose && <button type=\"button\" className=\"feedback__btn feedback__btn--outline\" onClick={onClose}>Cancel</button>}\n <button type=\"button\" className=\"feedback__btn feedback__btn--primary\" onClick={submit} disabled={submitting}>{submitting ? 'Submitting…' : 'Submit'}</button>\n </div>\n </div>\n )\n}\n\nexport function FeedbackWidget({ onSubmit, position = 'right' }: { onSubmit: (data: { type: FeedbackType; title: string; description: string }) => Promise<string>; position?: 'left' | 'right' }) {\n const [isOpen, setIsOpen] = useState(false)\n return (<>\n <button type=\"button\" className=\"feedback__widget-trigger\" onClick={() => setIsOpen(true)}>Feedback</button>\n {isOpen && <div className=\"feedback__widget-overlay\" onClick={() => setIsOpen(false)}>\n <div className=\"feedback__widget-backdrop\" />\n <div className=\"feedback__widget-panel\" onClick={e => e.stopPropagation()}>\n <div className=\"feedback__widget-header\"><span className=\"feedback__widget-title\">Send Feedback</span><button type=\"button\" className=\"feedback__close-btn\" onClick={() => setIsOpen(false)}>✕</button></div>\n <FeedbackForm onSubmit={onSubmit} onClose={() => setIsOpen(false)} />\n </div>\n </div>}\n </>)\n}\n\nexport function NPSSurvey({ onSubmit, onDismiss }: { onSubmit: (score: number, comment?: string) => void; onDismiss: () => void }) {\n const [score, setScore] = useState<number | null>(null); const [comment, setComment] = useState(''); const [step, setStep] = useState<'score'|'comment'|'thanks'>('score')\n return (\n <div className=\"feedback__nps\">\n {step === 'score' && <div><div className=\"feedback__nps-header\"><span className=\"feedback__nps-title\">How likely to recommend us?</span><button type=\"button\" className=\"feedback__close-btn\" onClick={onDismiss}>✕</button></div><div className=\"feedback__nps-subtitle\">0 = Not at all · 10 = Extremely likely</div>\n <div className=\"feedback__nps-scores\">{Array.from({length:11}).map((_,i) => <button key={i} type=\"button\" className=\"feedback__nps-score-btn\" onClick={() => { setScore(i); setStep('comment') }}>{i}</button>)}</div><div className=\"feedback__nps-labels\"><span>Not likely</span><span>Very likely</span></div></div>}\n {step === 'comment' && <div><div className=\"feedback__nps-title\" style={{marginBottom: '0.75rem'}}>Score: {score}</div><textarea className=\"feedback__form-input feedback__form-textarea\" value={comment} onChange={e => setComment(e.target.value)} placeholder=\"Optional…\" /><button type=\"button\" className=\"feedback__btn feedback__btn--primary\" style={{width:'100%',marginTop:'0.75rem'}} onClick={() => { onSubmit(score!, comment||undefined); setStep('thanks') }}>Submit</button></div>}\n {step === 'thanks' && <div className=\"feedback__success\"><div className=\"feedback__success-icon\">🎉</div><div className=\"feedback__success-text\">Thank you!</div></div>}\n </div>\n )\n}\n\nexport function NPSResults({ responses }: { responses: NPSResponse[] }) {\n const stats = calcNPSStats(responses); const total = stats.totalResponses || 1\n const color = stats.npsScore >= 50 ? 'oklch(0.72 0.18 155)' : stats.npsScore >= 0 ? 'oklch(0.72 0.18 60)' : 'oklch(0.60 0.25 25)'\n return (\n <div className=\"feedback__nps-results\">\n <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:'0.5rem'}}><span>NPS Score</span><span className=\"feedback__nps-results-score\" style={{color}}>{stats.npsScore}</span></div>\n <div className=\"feedback__nps-bar\"><div className=\"feedback__nps-bar-detractors\" style={{width:`${(stats.detractors/total)*100}%`}} /><div className=\"feedback__nps-bar-passives\" style={{width:`${(stats.passives/total)*100}%`}} /><div className=\"feedback__nps-bar-promoters\" style={{width:`${(stats.promoters/total)*100}%`}} /></div>\n <div className=\"feedback__nps-breakdown\"><div><span style={{color:'oklch(0.60 0.25 25)',fontWeight:700}}>{stats.detractors}</span><br/><span style={{color:'oklch(1 0 0/0.3)'}}>Detractors</span></div><div><span style={{color:'oklch(0.72 0.18 60)',fontWeight:700}}>{stats.passives}</span><br/><span style={{color:'oklch(1 0 0/0.3)'}}>Passives</span></div><div><span style={{color:'oklch(0.72 0.18 155)',fontWeight:700}}>{stats.promoters}</span><br/><span style={{color:'oklch(1 0 0/0.3)'}}>Promoters</span></div></div>\n <div style={{marginTop:'0.75rem',paddingTop:'0.75rem',borderTop:'1px solid oklch(1 0 0/0.05)',display:'flex',justifyContent:'space-between',fontSize:'0.6875rem',color:'oklch(1 0 0/0.4)'}}><span>Avg: {stats.averageScore}/10</span><span>{stats.totalResponses} responses</span></div>\n </div>\n )\n}\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- # ✦ @geenius-feedback/shared\n\n> Geenius Feedback — Shared types & Convex schema\n\n---\n\n## Overview\nBuilt with Steve Jobs-level minimalism and Jony Ive-level craftsmanship, this package is designed to deliver unparalleled developer experience (DX) and rock-solid performance.\n\n## Installation\n\n```bash\npnpm add @geenius-feedback/shared\n```\n\n## Usage\n\n```typescript\nimport { init } from '@geenius-feedback/shared';\n\n// Initialize the module with absolute precision\ninit({\n mode: 'premium',\n});\n```\n\n## Architecture\n- **Zero-config**: It just works.\n- **Strictly Typed**: Fully written in TypeScript for flawless IntelliSense.\n- **Framework Agnostic**: seamlessly integrates into the Geenius ecosystem.\n\n---\n\n*Designed by Antigravity HQ*\n
1
+ # ✦ @geenius/feedback-shared\n\n> Geenius Feedback — Shared types & Convex schema\n\n---\n\n## Overview\nBuilt with Steve Jobs-level minimalism and Jony Ive-level craftsmanship, this package is designed to deliver unparalleled developer experience (DX) and rock-solid performance.\n\n## Installation\n\n```bash\npnpm add @geenius/feedback-shared\n```\n\n## Usage\n\n```typescript\nimport { init } from '@geenius/feedback-shared';\n\n// Initialize the module with absolute precision\ninit({\n mode: 'premium',\n});\n```\n\n## Architecture\n- **Zero-config**: It just works.\n- **Strictly Typed**: Fully written in TypeScript for flawless IntelliSense.\n- **Framework Agnostic**: seamlessly integrates into the Geenius ecosystem.\n\n---\n\n*Designed by Antigravity HQ*\n
@@ -0,0 +1,115 @@
1
+ type FeedbackType = 'bug' | 'feature' | 'general' | 'suggestion';
2
+ type FeedbackStatus = 'open' | 'under-review' | 'planned' | 'in-progress' | 'done' | 'declined';
3
+ type FeedbackPriority = 'low' | 'medium' | 'high' | 'critical';
4
+ type NPSCategory = 'detractor' | 'passive' | 'promoter';
5
+ interface Attachment {
6
+ url: string;
7
+ name: string;
8
+ size: number;
9
+ }
10
+ interface FeedbackItem {
11
+ id: string;
12
+ type: FeedbackType;
13
+ title: string;
14
+ description: string;
15
+ status: FeedbackStatus;
16
+ priority: FeedbackPriority;
17
+ userId?: string;
18
+ userEmail?: string;
19
+ userName?: string;
20
+ url?: string;
21
+ browser?: string;
22
+ os?: string;
23
+ tags: string[];
24
+ votes: number;
25
+ createdAt: string;
26
+ updatedAt: string;
27
+ attachments?: Attachment[];
28
+ adminNote?: string;
29
+ }
30
+ interface NPSResponse {
31
+ id: string;
32
+ score: number;
33
+ comment?: string;
34
+ userId?: string;
35
+ submittedAt: string;
36
+ }
37
+ interface FeedbackConfig {
38
+ floatingWidget: boolean;
39
+ npsEnabled: boolean;
40
+ npsInterval: number;
41
+ categories: FeedbackType[];
42
+ allowAnonymous: boolean;
43
+ }
44
+ interface FeedbackStats {
45
+ total: number;
46
+ byType: Record<FeedbackType, number>;
47
+ byStatus: Record<FeedbackStatus, number>;
48
+ byPriority: Record<FeedbackPriority, number>;
49
+ }
50
+ interface NPSStats {
51
+ averageScore: number;
52
+ totalResponses: number;
53
+ promoters: number;
54
+ passives: number;
55
+ detractors: number;
56
+ npsScore: number;
57
+ }
58
+
59
+ /**
60
+ * @fileoverview Configuration factory for Geenius Feedback
61
+ */
62
+
63
+ interface ConfigureFeedbackOptions {
64
+ floatingWidget?: boolean;
65
+ npsEnabled?: boolean;
66
+ npsInterval?: number;
67
+ categories?: Array<'bug' | 'feature' | 'general' | 'suggestion'>;
68
+ allowAnonymous?: boolean;
69
+ }
70
+ /**
71
+ * Configure the feedback system with custom options
72
+ * @param options Configuration options for the feedback system
73
+ * @returns FeedbackConfig object ready for use
74
+ * @example
75
+ * ```ts
76
+ * const config = configureFeedback({
77
+ * floatingWidget: true,
78
+ * npsEnabled: true,
79
+ * npsInterval: 7,
80
+ * categories: ['bug', 'feature', 'general'],
81
+ * allowAnonymous: true,
82
+ * })
83
+ * ```
84
+ */
85
+ declare function configureFeedback(options?: ConfigureFeedbackOptions): FeedbackConfig;
86
+ /**
87
+ * Default feedback configuration
88
+ */
89
+ declare const defaultFeedbackConfig: FeedbackConfig;
90
+
91
+ declare const STATUS_CONFIG: Record<FeedbackStatus, {
92
+ label: string;
93
+ color: string;
94
+ emoji: string;
95
+ }>;
96
+ declare const PRIORITY_CONFIG: Record<FeedbackPriority, {
97
+ label: string;
98
+ color: string;
99
+ }>;
100
+ declare const TYPE_CONFIG: Record<FeedbackType, {
101
+ label: string;
102
+ icon: string;
103
+ color: string;
104
+ }>;
105
+ declare const FEEDBACK_TYPES: FeedbackType[];
106
+ declare const FEEDBACK_STATUSES: FeedbackStatus[];
107
+ declare const FEEDBACK_PRIORITIES: FeedbackPriority[];
108
+ declare function getStatusTransitions(status: FeedbackStatus): FeedbackStatus[];
109
+ declare function getNPSCategory(score: number): 'detractor' | 'passive' | 'promoter';
110
+ declare function calcNPSScore(responses: NPSResponse[]): number;
111
+ declare function calcNPSStats(responses: NPSResponse[]): NPSStats;
112
+ declare function calcFeedbackStats(items: FeedbackItem[]): FeedbackStats;
113
+ declare function formatRelativeTime(dateStr: string): string;
114
+
115
+ export { type Attachment, type ConfigureFeedbackOptions, FEEDBACK_PRIORITIES, FEEDBACK_STATUSES, FEEDBACK_TYPES, type FeedbackConfig, type FeedbackItem, type FeedbackPriority, type FeedbackStats, type FeedbackStatus, type FeedbackType, type NPSCategory, type NPSResponse, type NPSStats, PRIORITY_CONFIG, STATUS_CONFIG, TYPE_CONFIG, calcFeedbackStats, calcNPSScore, calcNPSStats, configureFeedback, defaultFeedbackConfig, formatRelativeTime, getNPSCategory, getStatusTransitions };