@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
@@ -1,18 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.json",
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "rootDir": "src",
6
- "strict": true,
7
- "skipLibCheck": true,
8
- "forceConsistentCasingInFileNames": true,
9
- "resolveJsonModule": true,
10
- "isolatedModules": true,
11
- "target": "ES2022",
12
- "module": "ESNext",
13
- "moduleResolution": "bundler"
14
- },
15
- "include": [
16
- "src"
17
- ]
18
- }
@@ -1,11 +0,0 @@
1
- import { defineConfig } from 'tsup'
2
-
3
- export default defineConfig({
4
- entry: { index: 'src/index.ts' },
5
- outDir: 'dist',
6
- format: ['esm'],
7
- dts: true,
8
- sourcemap: true,
9
- clean: true,
10
- treeshake: true,
11
- })
@@ -1,4 +0,0 @@
1
- import { defineConfig } from 'vitest/config'
2
- export default defineConfig({
3
- test: { globals: true, environment: 'node' },
4
- })
@@ -1,45 +0,0 @@
1
- {
2
- "name": "@geenius-feedback/solidjs",
3
- "version": "0.1.0",
4
- "private": false,
5
- "type": "module",
6
- "description": "Geenius Feedback — SolidJS components & primitives",
7
- "author": "Antigravity HQ",
8
- "license": "MIT",
9
- "publishConfig": {
10
- "access": "public"
11
- },
12
- "main": "./dist/index.js",
13
- "module": "./dist/index.js",
14
- "types": "./dist/index.d.ts",
15
- "exports": {
16
- ".": {
17
- "types": "./dist/index.d.ts",
18
- "import": "./dist/index.js"
19
- }
20
- },
21
- "files": [
22
- "dist",
23
- "src"
24
- ],
25
- "scripts": {
26
- "build": "tsup",
27
- "clean": "rm -rf dist",
28
- "type-check": "tsc --noEmit",
29
- "prepublishOnly": "pnpm clean && pnpm build"
30
- },
31
- "dependencies": {
32
- "@geenius-feedback/shared": "workspace:*"
33
- },
34
- "devDependencies": {
35
- "solid-js": "^1.9.0",
36
- "tsup": "^8.5.1",
37
- "typescript": "~6.0.2"
38
- },
39
- "peerDependencies": {
40
- "solid-js": "^1.8.0 || ^1.9.0"
41
- },
42
- "engines": {
43
- "node": ">=20.0.0"
44
- }
45
- }
@@ -1,72 +0,0 @@
1
- import { Show, For, createSignal } from 'solid-js'
2
- import type { FeedbackItem, FeedbackType, FeedbackStatus, FeedbackPriority } from '@geenius-feedback/shared'
3
- import { STATUS_CONFIG, PRIORITY_CONFIG, TYPE_CONFIG, FEEDBACK_TYPES, formatRelativeTime } from '@geenius-feedback/shared'
4
-
5
- export function StatusBadge(props: { status: FeedbackStatus }) {
6
- const cfg = () => STATUS_CONFIG[props.status]
7
- return <span class="inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-[10px] font-medium" style={{ background: `${cfg().color}22`, color: cfg().color }}><span>{cfg().emoji}</span>{cfg().label}</span>
8
- }
9
-
10
- export function PriorityBadge(props: { priority: FeedbackPriority }) {
11
- const cfg = () => PRIORITY_CONFIG[props.priority]
12
- return <span class="rounded-full px-2 py-0.5 text-[10px] font-medium" style={{ background: `${cfg().color}22`, color: cfg().color }}>{cfg().label}</span>
13
- }
14
-
15
- export function TypeBadge(props: { type: FeedbackType }) {
16
- const cfg = () => TYPE_CONFIG[props.type]
17
- return <span class="inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-medium" style={{ background: `${cfg().color}22`, color: cfg().color }}><span>{cfg().icon}</span>{cfg().label}</span>
18
- }
19
-
20
- export function FeedbackCard(props: { item: FeedbackItem; onVote?: (id: string) => void; hasVoted?: boolean }) {
21
- return (
22
- <div class="group flex gap-3 rounded-xl border border-white/8 bg-white/[0.02] p-4 hover:border-indigo-500/20">
23
- <Show when={props.onVote}><button type="button" onClick={() => props.onVote?.(props.item.id)}
24
- class={`flex flex-col items-center gap-0.5 rounded-lg px-2 py-1.5 text-xs font-bold ${props.hasVoted ? 'bg-indigo-500/15 text-indigo-400' : 'bg-white/5 text-white/30 hover:bg-white/10'}`}>
25
- <span class="text-sm">{props.hasVoted ? '▲' : '△'}</span><span>{props.item.votes}</span>
26
- </button></Show>
27
- <div class="flex-1 min-w-0">
28
- <div class="flex items-center gap-2 mb-1 flex-wrap"><TypeBadge type={props.item.type} /><StatusBadge status={props.item.status} /></div>
29
- <h3 class="text-sm font-semibold text-white/90 mb-0.5 truncate">{props.item.title}</h3>
30
- <p class="text-xs text-white/40 line-clamp-2">{props.item.description}</p>
31
- <div class="mt-2 text-[10px] text-white/25">{formatRelativeTime(props.item.createdAt)}</div>
32
- </div>
33
- </div>
34
- )
35
- }
36
-
37
- export function FeedbackWidget(props: { onSubmit: (data: { type: FeedbackType; title: string; description: string }) => Promise<string> }) {
38
- const [isOpen, setIsOpen] = createSignal(false)
39
- const [type, setType] = createSignal<FeedbackType>('general')
40
- const [title, setTitle] = createSignal(''); const [desc, setDesc] = createSignal('')
41
- const [submitting, setSubmitting] = createSignal(false); const [done, setDone] = createSignal(false)
42
- const submit = async () => { setSubmitting(true); try { await props.onSubmit({ type: type(), title: title(), description: desc() }); setDone(true) } finally { setSubmitting(false) } }
43
- return (<>
44
- <button type="button" onClick={() => setIsOpen(true)} class="fixed top-1/2 right-0 -translate-y-1/2 z-40 rounded-l-xl bg-indigo-600 px-2 py-4 text-white shadow-lg hover:bg-indigo-500" style={{ "writing-mode": "vertical-rl" }}><span class="text-xs font-medium tracking-wider">Feedback</span></button>
45
- <Show when={isOpen()}>
46
- <div class="fixed inset-0 z-50 flex justify-end" onClick={() => setIsOpen(false)}>
47
- <div class="absolute inset-0 bg-black/50 backdrop-blur-sm" />
48
- <div class="relative w-full max-w-md bg-[#0f0f17] border-l border-white/10 p-6" onClick={e => e.stopPropagation()}>
49
- <div class="mb-6 flex items-center justify-between"><h2 class="text-lg font-bold text-white">Send Feedback</h2><button type="button" onClick={() => setIsOpen(false)} class="text-white/30 hover:text-white/50">✕</button></div>
50
- <Show when={!done()} fallback={<div class="text-center py-8"><div class="text-4xl mb-3">🎉</div><p class="text-sm text-white/80">Thank you!</p></div>}>
51
- <div class="flex gap-1.5 mb-4"><For each={FEEDBACK_TYPES}>{t => <button type="button" onClick={() => setType(t)} class={`flex items-center gap-1 rounded-lg px-3 py-2 text-xs font-medium ${type() === t ? 'text-white' : 'bg-white/5 text-white/50'}`} style={type() === t ? { background: TYPE_CONFIG[t].color } : undefined}>{TYPE_CONFIG[t].icon} {TYPE_CONFIG[t].label}</button>}</For></div>
52
- <input type="text" placeholder="Title…" value={title()} onInput={e => setTitle((e.target as HTMLInputElement).value)} class="w-full rounded-xl border border-white/10 bg-white/5 px-4 py-3 text-sm text-white placeholder-white/30 outline-none mb-3" />
53
- <textarea placeholder="Description…" value={desc()} onInput={e => setDesc((e.target as HTMLTextAreaElement).value)} rows={4} class="w-full rounded-xl border border-white/10 bg-white/5 px-4 py-3 text-sm text-white placeholder-white/30 outline-none resize-none mb-4" />
54
- <button type="button" onClick={submit} disabled={submitting()} class="w-full rounded-lg bg-indigo-600 py-2.5 text-sm font-medium text-white hover:bg-indigo-500 disabled:opacity-50">{submitting() ? 'Submitting…' : 'Submit'}</button>
55
- </Show>
56
- </div>
57
- </div>
58
- </Show>
59
- </>)
60
- }
61
-
62
- export function NPSSurvey(props: { onSubmit: (score: number, comment?: string) => void; onDismiss: () => void }) {
63
- const [score, setScore] = createSignal<number | null>(null)
64
- const [comment, setComment] = createSignal(''); const [step, setStep] = createSignal<'score'|'comment'|'thanks'>('score')
65
- return (
66
- <div class="fixed bottom-6 right-6 z-50 w-96 rounded-2xl border border-white/10 bg-[#111118] p-6 shadow-2xl">
67
- <Show when={step() === 'score'}><div><div class="mb-1 flex items-center justify-between"><h3 class="text-sm font-semibold text-white/90">How likely to recommend us?</h3><button type="button" onClick={props.onDismiss} class="text-white/20">✕</button></div><div class="flex gap-1 mt-3"><For each={Array.from({length:11},(_,i)=>i)}>{i => <button type="button" onClick={() => { setScore(i); setStep('comment') }} class="flex-1 rounded-lg py-2.5 text-xs font-bold bg-white/5 text-white/50 hover:bg-white/10">{i}</button>}</For></div></div></Show>
68
- <Show when={step() === 'comment'}><div><p class="text-sm font-semibold text-white/90 mb-3">Score: {score()}</p><textarea value={comment()} onInput={e => setComment((e.target as HTMLTextAreaElement).value)} rows={3} class="w-full rounded-xl border border-white/10 bg-white/5 px-3 py-2 text-sm text-white outline-none resize-none mb-3" /><button type="button" onClick={() => { props.onSubmit(score()!, comment() || undefined); setStep('thanks') }} class="w-full rounded-lg bg-indigo-600 py-2 text-xs text-white">Submit</button></div></Show>
69
- <Show when={step() === 'thanks'}><div class="text-center py-4"><div class="text-3xl mb-2">🎉</div><p class="text-sm text-white/80">Thank you!</p></div></Show>
70
- </div>
71
- )
72
- }
@@ -1,3 +0,0 @@
1
- export { createFeedback, createFeedbackForm, createNPS, createFeedbackAdmin } from './primitives'
2
- export { StatusBadge, PriorityBadge, TypeBadge, FeedbackCard, FeedbackWidget, NPSSurvey } from './components'
3
- export type { FeedbackItem, NPSResponse, FeedbackConfig, FeedbackStats, NPSStats, FeedbackType, FeedbackStatus, FeedbackPriority } from '@geenius-feedback/shared'
@@ -1,49 +0,0 @@
1
- import { createSignal, createMemo } from 'solid-js'
2
- import type { FeedbackItem, FeedbackType, FeedbackStatus, FeedbackPriority, FeedbackStats, NPSResponse } from '@geenius-feedback/shared'
3
- import { calcFeedbackStats, calcNPSStats } from '@geenius-feedback/shared'
4
-
5
- export function createFeedback(items: () => FeedbackItem[] | undefined) {
6
- const [typeFilter, setTypeFilter] = createSignal<FeedbackType | undefined>()
7
- const [search, setSearch] = createSignal('')
8
- const [sort, setSort] = createSignal<'newest' | 'votes'>('newest')
9
- const isLoading = createMemo(() => items() === undefined)
10
- const stats = createMemo(() => calcFeedbackStats(items() ?? []))
11
- const filtered = createMemo(() => {
12
- let r = items() ?? []; const tf = typeFilter(); if (tf) r = r.filter(i => i.type === tf)
13
- const q = search().toLowerCase(); if (q) r = r.filter(i => i.title.toLowerCase().includes(q) || i.description.toLowerCase().includes(q))
14
- if (sort() === 'votes') r = [...r].sort((a, b) => b.votes - a.votes)
15
- return r
16
- })
17
- return { items: filtered, stats, isLoading, typeFilter, setTypeFilter, search, setSearch, sort, setSort }
18
- }
19
-
20
- export function createFeedbackForm(submitFn: (data: { type: FeedbackType; title: string; description: string }) => Promise<string>) {
21
- const [type, setType] = createSignal<FeedbackType>('general')
22
- const [title, setTitle] = createSignal(''); const [desc, setDesc] = createSignal('')
23
- const [isSubmitting, setIsSubmitting] = createSignal(false); const [error, setError] = createSignal<string | null>(null); const [success, setSuccess] = createSignal(false)
24
- const submit = async () => {
25
- if (!title().trim()) { setError('Title required'); return }; if (desc().length < 10) { setError('Description must be 10+ chars'); return }
26
- setIsSubmitting(true); setError(null)
27
- try { await submitFn({ type: type(), title: title(), description: desc() }); setSuccess(true); setTitle(''); setDesc('') }
28
- catch (e) { setError(e instanceof Error ? e.message : 'Failed') } finally { setIsSubmitting(false) }
29
- }
30
- const reset = () => { setType('general'); setTitle(''); setDesc(''); setError(null); setSuccess(false) }
31
- return { type, setType, title, setTitle, description: desc, setDescription: setDesc, submit, isSubmitting, error, success, reset }
32
- }
33
-
34
- export function createNPS(submitFn: (score: number, comment?: string) => Promise<void>) {
35
- const [isSubmitting, setIsSubmitting] = createSignal(false)
36
- const [showSurvey, setShowSurvey] = createSignal(typeof window !== 'undefined' && !localStorage.getItem('geenius-nps-last-shown'))
37
- const submit = async (score: number, comment?: string) => {
38
- setIsSubmitting(true); try { await submitFn(score, comment); localStorage.setItem('geenius-nps-last-shown', String(Date.now())); setShowSurvey(false) } finally { setIsSubmitting(false) }
39
- }
40
- const dismiss = () => { setShowSurvey(false); localStorage.setItem('geenius-nps-last-shown', String(Date.now())) }
41
- return { submit, isSubmitting, showSurvey, dismiss }
42
- }
43
-
44
- export function createFeedbackAdmin(items: () => FeedbackItem[] | undefined, mutations: { updateStatus: (id: string, s: FeedbackStatus, note?: string) => Promise<void>; updatePriority: (id: string, p: FeedbackPriority) => Promise<void>; deleteFeedback: (id: string) => Promise<void> }) {
45
- const [search, setSearch] = createSignal('')
46
- const stats = createMemo(() => calcFeedbackStats(items() ?? []))
47
- const filtered = createMemo(() => { const q = search().toLowerCase(); return q ? (items() ?? []).filter(i => i.title.toLowerCase().includes(q)) : (items() ?? []) })
48
- return { items: filtered, stats, search, setSearch, isLoading: createMemo(() => items() === undefined), ...mutations }
49
- }
@@ -1,20 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.json",
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "rootDir": "src",
6
- "jsx": "preserve",
7
- "jsxImportSource": "solid-js",
8
- "strict": true,
9
- "skipLibCheck": true,
10
- "forceConsistentCasingInFileNames": true,
11
- "resolveJsonModule": true,
12
- "isolatedModules": true,
13
- "target": "ES2022",
14
- "module": "ESNext",
15
- "moduleResolution": "bundler"
16
- },
17
- "include": [
18
- "src"
19
- ]
20
- }
@@ -1,12 +0,0 @@
1
- import { defineConfig } from 'tsup'
2
-
3
- export default defineConfig({
4
- entry: { index: 'src/index.tsx' },
5
- outDir: 'dist',
6
- format: ['esm'],
7
- dts: true,
8
- sourcemap: true,
9
- clean: true,
10
- treeshake: true,
11
- external: ['solid-js'],
12
- })
@@ -1,32 +0,0 @@
1
- {
2
- "name": "@geenius-feedback/solidjs-css",
3
- "version": "0.1.0",
4
- "description": "Geenius Feedback — SolidJS primitives (vanilla CSS variant)",
5
- "type": "module",
6
- "license": "MIT",
7
- "publishConfig": {
8
- "access": "restricted"
9
- },
10
- "main": "./src/index.tsx",
11
- "types": "./src/index.tsx",
12
- "exports": {
13
- ".": "./src/index.tsx"
14
- },
15
- "scripts": {
16
- "type-check": "tsc --noEmit"
17
- },
18
- "peerDependencies": {
19
- "solid-js": ">=1.0.0"
20
- },
21
- "dependencies": {
22
- "@geenius-feedback/shared": "workspace:*"
23
- },
24
- "devDependencies": {
25
- "solid-js": "^1.9.4",
26
- "typescript": "~6.0.2"
27
- },
28
- "author": "Antigravity HQ",
29
- "engines": {
30
- "node": ">=20.0.0"
31
- }
32
- }
@@ -1,4 +0,0 @@
1
- export { createFeedback, createFeedbackForm, createNPS, createFeedbackAdmin } from '@geenius-feedback/solidjs'
2
- export { StatusBadge, PriorityBadge, TypeBadge, FeedbackCard, FeedbackWidget, NPSSurvey } from '@geenius-feedback/solidjs'
3
- import './styles.css'
4
- export type { FeedbackItem, NPSResponse, FeedbackConfig, FeedbackStats, NPSStats, FeedbackType, FeedbackStatus, FeedbackPriority } from '@geenius-feedback/shared'
@@ -1,78 +0,0 @@
1
- import { Component } from 'solid-js';
2
- import '../styles.css';
3
-
4
- const FeedbackAdminPage: Component = () => {
5
- return (
6
- <div style={{ padding: '1.5rem' }}>
7
- <div class="feedback__breadcrumb">
8
- <span class="feedback__breadcrumb-item">Feedback</span>
9
- <span class="feedback__breadcrumb-sep">/</span>
10
- <span class="feedback__breadcrumb-item--active">Admin</span>
11
- </div>
12
-
13
- <div class="feedback__stats-grid">
14
- <div class="feedback__stat-card">
15
- <div class="feedback__stat-icon">📊</div>
16
- <div class="feedback__stat-value">7.8</div>
17
- <div class="feedback__stat-label">NPS Score</div>
18
- </div>
19
- <div class="feedback__stat-card">
20
- <div class="feedback__stat-icon">⭐</div>
21
- <div class="feedback__stat-value">4.2</div>
22
- <div class="feedback__stat-label">Avg Rating</div>
23
- </div>
24
- <div class="feedback__stat-card">
25
- <div class="feedback__stat-icon">⏱️</div>
26
- <div class="feedback__stat-value">2.1h</div>
27
- <div class="feedback__stat-label">Avg Response</div>
28
- </div>
29
- </div>
30
-
31
- <div class="feedback__filter-panel">
32
- <div class="feedback__filter-section">
33
- <div class="feedback__filter-section-title">Status</div>
34
- <div class="feedback__filter-options">
35
- <label class="feedback__filter-option">
36
- <input type="checkbox" checked />
37
- <span class="feedback__filter-option-label">Open</span>
38
- </label>
39
- <label class="feedback__filter-option">
40
- <input type="checkbox" checked />
41
- <span class="feedback__filter-option-label">Under Review</span>
42
- </label>
43
- <label class="feedback__filter-option">
44
- <input type="checkbox" checked />
45
- <span class="feedback__filter-option-label">Planned</span>
46
- </label>
47
- </div>
48
- </div>
49
- </div>
50
-
51
- <div style={{ 'margin-top': '2rem' }}>
52
- <table class="feedback__admin-table">
53
- <thead>
54
- <tr>
55
- <th>Item</th>
56
- <th>Status</th>
57
- <th>Votes</th>
58
- </tr>
59
- </thead>
60
- <tbody>
61
- <tr>
62
- <td>Add Dark Mode</td>
63
- <td>In Progress</td>
64
- <td>42</td>
65
- </tr>
66
- <tr>
67
- <td>Login Timeout Issue</td>
68
- <td>Open</td>
69
- <td>12</td>
70
- </tr>
71
- </tbody>
72
- </table>
73
- </div>
74
- </div>
75
- );
76
- };
77
-
78
- export default FeedbackAdminPage;
@@ -1,65 +0,0 @@
1
- import { Component } from 'solid-js';
2
- import '../styles.css';
3
-
4
- const FeedbackPage: Component = () => {
5
- const feedbackItems = [
6
- { id: 1, title: 'Add Dark Mode', type: 'feature', status: 'in-progress', votes: 42 },
7
- { id: 2, title: 'Bug: Login timeout issue', type: 'bug', status: 'open', votes: 12 },
8
- { id: 3, title: 'Improve API documentation', type: 'suggestion', status: 'planned', votes: 28 },
9
- ];
10
-
11
- return (
12
- <div style={{ padding: '1.5rem' }}>
13
- <div class="feedback__breadcrumb">
14
- <span class="feedback__breadcrumb-item">Feedback</span>
15
- <span class="feedback__breadcrumb-sep">/</span>
16
- <span class="feedback__breadcrumb-item--active">View All</span>
17
- </div>
18
-
19
- <div class="feedback__stats-grid">
20
- <div class="feedback__stat-card">
21
- <div class="feedback__stat-icon">💬</div>
22
- <div class="feedback__stat-value">145</div>
23
- <div class="feedback__stat-label">Total Feedback</div>
24
- </div>
25
- <div class="feedback__stat-card">
26
- <div class="feedback__stat-icon">👍</div>
27
- <div class="feedback__stat-value">89</div>
28
- <div class="feedback__stat-label">In Progress</div>
29
- </div>
30
- <div class="feedback__stat-card">
31
- <div class="feedback__stat-icon">✅</div>
32
- <div class="feedback__stat-value">34</div>
33
- <div class="feedback__stat-label">Implemented</div>
34
- </div>
35
- </div>
36
-
37
- <div class="feedback__filter-tabs" style={{ 'margin-bottom': '1.5rem' }}>
38
- <button class="feedback__filter-tab feedback__filter-tab--active">All</button>
39
- <button class="feedback__filter-tab feedback__filter-tab--inactive">Features</button>
40
- <button class="feedback__filter-tab feedback__filter-tab--inactive">Bugs</button>
41
- <button class="feedback__filter-tab feedback__filter-tab--inactive">Suggestions</button>
42
- </div>
43
-
44
- <div style={{ display: 'flex', 'flex-direction': 'column', gap: '0.75rem' }}>
45
- {feedbackItems.map(item => (
46
- <div class={`feedback__card feedback__card--${item.type}`}>
47
- <div class="feedback__vote-btn feedback__vote-btn--inactive">
48
- <span class="feedback__vote-btn-arrow">▲</span>
49
- <span>{item.votes}</span>
50
- </div>
51
- <div class="feedback__card-info">
52
- <div class="feedback__card-badges">
53
- <span class={`feedback__type-badge feedback__type-badge--${item.type}`}>{item.type}</span>
54
- <span class={`feedback__status-badge feedback__status-badge--${item.status}`}>{item.status}</span>
55
- </div>
56
- <div class="feedback__card-title">{item.title}</div>
57
- </div>
58
- </div>
59
- ))}
60
- </div>
61
- </div>
62
- );
63
- };
64
-
65
- export default FeedbackPage;
@@ -1 +0,0 @@
1
- export * from '@geenius-feedback/solidjs';