Skip to content

Commit b193c6f

Browse files
committed
problem: video and images not rendered, layout sucks
1 parent 818735a commit b193c6f

9 files changed

Lines changed: 710 additions & 455 deletions

File tree

src/components/app-sidebar.tsx

Lines changed: 108 additions & 188 deletions
Large diffs are not rendered by default.
Lines changed: 32 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -1,143 +1,44 @@
1-
"use client"
2-
31
import * as React from "react"
4-
import { FancyBox, type FancyBoxItem } from "@/components/ui/fancy-box"
5-
import { Button } from "@/components/ui/button"
6-
import { Badge } from "@/components/ui/badge"
7-
import { eventKinds, popularKinds } from "@/lib/event-kinds"
8-
import { FilterIcon, XIcon } from "lucide-react"
2+
import { Input } from "@/components/ui/input"
93

104
interface EventKindFilterProps {
115
selectedKinds: number[]
126
onKindsChange: (kinds: number[]) => void
137
className?: string
148
}
159

16-
const PRESET_FILTERS = [
17-
{ label: "Core", kinds: [0, 1, 3, 4, 6, 7] },
18-
{ label: "Social", kinds: [0, 1, 6, 7, 1111] },
19-
{ label: "Media", kinds: [20, 21, 22, 1063, 1222] },
20-
{ label: "Commerce", kinds: [1021, 1022, 30017, 30018, 30020] },
21-
{ label: "Bitcoin", kinds: [9734, 9735, 7375, 13194] },
22-
{ label: "Popular", kinds: popularKinds },
23-
]
24-
2510
export function EventKindFilter({ selectedKinds, onKindsChange, className }: EventKindFilterProps) {
26-
// Convert event kinds to FancyBox items
27-
const fancyBoxItems: FancyBoxItem[] = React.useMemo(
28-
() => eventKinds.map((kind) => ({
29-
value: kind.kind.toString(),
30-
label: `${kind.kind}: ${kind.label}`,
31-
description: kind.description,
32-
category: kind.category,
33-
deprecated: kind.deprecated,
34-
})),
35-
[]
36-
)
37-
38-
// Convert selected kinds to strings for FancyBox
39-
const selectedValues = selectedKinds.map(String)
40-
41-
const handleSelectionChange = React.useCallback(
42-
(values: string[]) => {
43-
// Parse custom values as numbers and filter out invalid ones
44-
const kinds = values
45-
.map((v) => parseInt(v, 10))
46-
.filter((k) => !isNaN(k))
47-
.sort((a, b) => a - b)
48-
onKindsChange(kinds)
49-
},
50-
[onKindsChange]
51-
)
52-
53-
const applyPreset = React.useCallback(
54-
(preset: typeof PRESET_FILTERS[0]) => {
55-
onKindsChange(preset.kinds)
56-
},
57-
[onKindsChange]
58-
)
59-
60-
const clearAll = React.useCallback(() => {
61-
onKindsChange([])
62-
}, [onKindsChange])
63-
64-
const hasFilters = selectedKinds.length > 0
11+
const [text, setText] = React.useState(() => selectedKinds.join(", "))
12+
13+
React.useEffect(() => {
14+
const fromProps = selectedKinds.join(", ")
15+
const parsedFromText = text
16+
.split(",")
17+
.map(s => parseInt(s.trim(), 10))
18+
.filter(n => Number.isFinite(n) && n >= 0)
19+
if (parsedFromText.join(", ") !== fromProps) {
20+
setText(fromProps)
21+
}
22+
}, [selectedKinds]) // eslint-disable-line react-hooks/exhaustive-deps
23+
24+
const handleChange = (value: string) => {
25+
setText(value)
26+
const kinds = value
27+
.split(",")
28+
.map(s => s.trim())
29+
.filter(s => s.length > 0)
30+
.map(s => parseInt(s, 10))
31+
.filter(n => Number.isFinite(n) && n >= 0)
32+
onKindsChange(kinds)
33+
}
6534

6635
return (
67-
<div className={className}>
68-
<div className="flex items-center gap-2 mb-3">
69-
<FilterIcon className="h-4 w-4 text-muted-foreground" />
70-
<span className="text-sm font-medium">Event Kinds</span>
71-
{hasFilters && (
72-
<Badge variant="secondary" className="text-xs">
73-
{selectedKinds.length}
74-
</Badge>
75-
)}
76-
{hasFilters && (
77-
<Button
78-
variant="ghost"
79-
size="sm"
80-
onClick={clearAll}
81-
className="h-8 w-8 p-0 ml-auto"
82-
>
83-
<XIcon className="h-4 w-4" />
84-
</Button>
85-
)}
86-
</div>
87-
88-
<FancyBox
89-
items={fancyBoxItems}
90-
selectedValues={selectedValues}
91-
onSelectionChange={handleSelectionChange}
92-
placeholder="Filter by event kinds..."
93-
searchPlaceholder="Search event kinds..."
94-
maxDisplay={2}
95-
allowCustomValues={true}
96-
customValuePlaceholder="Add custom kind number..."
97-
groupByCategory={true}
98-
className="w-full"
99-
/>
100-
101-
{/* Preset buttons */}
102-
<div className="flex flex-wrap gap-1 mt-2">
103-
{PRESET_FILTERS.map((preset) => (
104-
<Button
105-
key={preset.label}
106-
variant="outline"
107-
size="sm"
108-
onClick={() => applyPreset(preset)}
109-
className="h-8 px-3 text-xs"
110-
>
111-
{preset.label}
112-
</Button>
113-
))}
114-
</div>
115-
116-
{/* Active filters display */}
117-
{hasFilters && (
118-
<div className="mt-2 text-xs text-muted-foreground">
119-
Filtering {selectedKinds.length} event kind{selectedKinds.length !== 1 ? 's' : ''}:
120-
<div className="flex flex-wrap gap-1 mt-1">
121-
{selectedKinds.slice(0, 10).map((kind) => {
122-
const eventKind = eventKinds.find((k) => k.kind === kind)
123-
return (
124-
<Badge
125-
key={kind}
126-
variant="outline"
127-
className={`text-xs ${eventKind?.deprecated ? 'opacity-60' : ''}`}
128-
>
129-
{kind}
130-
</Badge>
131-
)
132-
})}
133-
{selectedKinds.length > 10 && (
134-
<Badge variant="outline" className="text-xs">
135-
+{selectedKinds.length - 10} more
136-
</Badge>
137-
)}
138-
</div>
139-
</div>
140-
)}
141-
</div>
36+
<Input
37+
type="text"
38+
value={text}
39+
onChange={(e) => handleChange(e.target.value)}
40+
placeholder="Filter by kinds (comma-separated)"
41+
className={className}
42+
/>
14243
)
143-
}
44+
}

0 commit comments

Comments
 (0)