Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 61 additions & 14 deletions components/ResearchTrackCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,14 @@ export function ResearchTrackCard({ track, isExpanded, onToggle }: ResearchTrack
onToggle(newState);
};

const isInactive = track.status === 'inactive';

return (
<div className="grid transition-all duration-300 ease-in-out h-fit">
<Card
className={`bg-white border-slate-200 hover:bg-slate-50 transition-all duration-200 cursor-pointer group relative plausible-event-name=${track.title.replace(' ', '+')}+Research+Card+Click`}
className={`bg-white border-slate-200 hover:bg-slate-50 transition-all duration-200 cursor-pointer group relative plausible-event-name=${track.title.replace(' ', '+')}+Research+Card+Click ${
isInactive ? 'opacity-60 grayscale' : ''
}`}
onClick={handleToggle}
>
<div className="absolute top-4 right-4">
Expand All @@ -107,21 +111,38 @@ export function ResearchTrackCard({ track, isExpanded, onToggle }: ResearchTrack
<div className={`p-2 rounded-lg ${colorClasses.progressBg} text-white`}>
{track.icon}
</div>
<CardTitle className="text-slate-900">{track.title}</CardTitle>
<div className="flex items-center gap-2">
<CardTitle className={`${isInactive ? 'text-slate-500' : 'text-slate-900'}`}>
{track.title}
</CardTitle>
{isInactive && (
<Badge variant="outline" className="text-xs bg-slate-100 text-slate-500 border-slate-300">
Inactive
</Badge>
)}
</div>
</div>
<div className="my-4">
<div className="flex justify-between mb-1">
<span className="text-sm text-slate-600">Progress</span>
<span className="text-sm font-medium">{track.progress}%</span>
<span className={`text-sm ${isInactive ? 'text-slate-400' : 'text-slate-600'}`}>
Progress
</span>
<span className={`text-sm font-medium ${isInactive ? 'text-slate-400' : ''}`}>
{track.progress}%
</span>
</div>
<div className="h-2 w-full bg-slate-100 rounded-full overflow-hidden">
<div
className={`h-full ${colorClasses.progressBg} rounded-full`}
className={`h-full ${colorClasses.progressBg} rounded-full ${
isInactive ? 'opacity-50' : ''
}`}
style={{ width: `${track.progress}%` }}
></div>
</div>
</div>
<p className="text-sm text-slate-600 mb-2">{track.description}</p>
<p className={`text-sm mb-2 ${isInactive ? 'text-slate-400' : 'text-slate-600'}`}>
{track.description}
</p>
</CardHeader>

<CardContent className="flex-1">
Expand All @@ -138,14 +159,28 @@ export function ResearchTrackCard({ track, isExpanded, onToggle }: ResearchTrack
{track.milestones.map((milestone, index) => (
<div key={index} className="flex items-start gap-2 text-sm">
<div
className={`w-2 h-2 rounded-full mt-1.5 shrink-0 ${milestone.completed ? colorClasses.progressBg : 'bg-slate-300'}`}
className={`w-2 h-2 rounded-full mt-1.5 shrink-0 ${milestone.completed ? colorClasses.progressBg : 'bg-slate-300'} ${
isInactive ? 'opacity-50' : ''
}`}
/>
<div>
<p className={milestone.completed ? 'text-slate-900' : 'text-slate-500'}>
<p
className={`${
milestone.completed
? isInactive
? 'text-slate-400'
: 'text-slate-900'
: isInactive
? 'text-slate-300'
: 'text-slate-500'
}`}
>
{milestone.title}
</p>
{milestone.date && (
<p className="text-xs text-slate-400">{milestone.date}</p>
<p className={`text-xs ${isInactive ? 'text-slate-300' : 'text-slate-400'}`}>
{milestone.date}
</p>
)}
</div>
</div>
Expand All @@ -160,24 +195,32 @@ export function ResearchTrackCard({ track, isExpanded, onToggle }: ResearchTrack
<Link
href={resource.url}
key={index}
className="flex items-center gap-2 text-sm text-slate-700 hover:text-slate-900 hover:underline"
className={`flex items-center gap-2 text-sm hover:underline ${
isInactive
? 'text-slate-400 hover:text-slate-500'
: 'text-slate-700 hover:text-slate-900'
}`}
target="_blank"
onClick={handleResourceClick}
>
<ExternalLink className="h-3.5 w-3.5 shrink-0" />
<span>{resource.title}</span>
<span className="text-xs text-slate-400 ml-auto">{resource.type}</span>
<span className={`text-xs ml-auto ${isInactive ? 'text-slate-300' : 'text-slate-400'}`}>
{resource.type}
</span>
</Link>
))}
</div>
</div>
</div>
</div>
<p className="text-sm text-slate-600 mt-2">
<p className={`text-sm mt-2 ${isInactive ? 'text-slate-400' : 'text-slate-600'}`}>
Lead:{' '}
<Link
href={track.leadLink}
className="text-slate-700 hover:text-slate-900 hover:underline"
className={`hover:underline ${
isInactive ? 'text-slate-400 hover:text-slate-500' : 'text-slate-700 hover:text-slate-900'
}`}
>
{track.lead}
</Link>
Expand All @@ -187,7 +230,11 @@ export function ResearchTrackCard({ track, isExpanded, onToggle }: ResearchTrack
<CardFooter className="pt-2 border-t border-slate-100">
<div className="flex gap-1 flex-wrap">
{track.tags.map((tag, i) => (
<Badge key={i} variant="outline" className="bg-slate-100 text-xs">
<Badge
key={i}
variant="outline"
className={`text-xs ${isInactive ? 'bg-slate-50 text-slate-400 border-slate-200' : 'bg-slate-100'}`}
>
{tag}
</Badge>
))}
Expand Down
41 changes: 30 additions & 11 deletions components/ResearchTracks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export function ResearchTracks() {
const [searchTerm, setSearchTerm] = useState('');
const [selectedTags, setSelectedTags] = useState<string[]>([]);
const [allExpanded, setAllExpanded] = useState(true); // Start with all expanded
const [showInactive, setShowInactive] = useState(false); // Hide inactive by default

// Get unique tags from all research tracks
const allTags = Array.from(new Set(researchTracksData.flatMap((track) => track.tags))).sort();
Expand All @@ -19,8 +20,15 @@ export function ResearchTracks() {
(searchTerm === '' ||
track.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
track.description.toLowerCase().includes(searchTerm.toLowerCase())) &&
(selectedTags.length === 0 || selectedTags.some((tag) => track.tags.includes(tag))),
);
(selectedTags.length === 0 || selectedTags.some((tag) => track.tags.includes(tag))) &&
(showInactive || track.status === 'active'),
).sort((a, b) => {
// Sort by status: active first, inactive last
if (a.status === 'active' && b.status === 'inactive') return -1;
if (a.status === 'inactive' && b.status === 'active') return 1;
// If both have same status, maintain original order
return 0;
});

const toggleTag = (tag: string) => {
setSelectedTags((prev) =>
Expand Down Expand Up @@ -57,15 +65,26 @@ export function ResearchTracks() {
)}
</button>
</div>
<div className="relative w-64">
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-slate-400" />
<Input
type="text"
placeholder="Search research tracks..."
className="pl-8 bg-white border-slate-200"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
<div className="flex items-center gap-4">
<label className="flex items-center gap-2 text-sm font-medium text-slate-600">
<input
type="checkbox"
checked={showInactive}
onChange={(e) => setShowInactive(e.target.checked)}
className="rounded border-slate-300 text-slate-600 focus:ring-slate-500"
/>
Show inactive tracks
</label>
<div className="relative w-64">
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-slate-400" />
<Input
type="text"
placeholder="Search research tracks..."
className="pl-8 bg-white border-slate-200"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
</div>
</div>
</div>

Expand Down
7 changes: 7 additions & 0 deletions data/research-tracks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export interface ResearchTrack {
description: string;
icon: ReactNode;
colorClass: string;
status: 'active' | 'inactive';
progress: number;
lead: string;
leadLink: string;
Expand Down Expand Up @@ -37,6 +38,7 @@ export const researchTracksData: ResearchTrack[] = [
and advanced hardware testing.',
icon: <Lock className="h-5 w-5" />,
colorClass: 'blue',
status: 'active',
progress: 10,
lead: 'Dmitry Khovratovich',
leadLink: 'https://x.com/Khovr',
Expand Down Expand Up @@ -94,6 +96,7 @@ export const researchTracksData: ResearchTrack[] = [
replacement for BLS signatures.',
icon: <FileCheck className="h-5 w-5" />,
colorClass: 'green',
status: 'active',
progress: 70,
lead: 'Benedikt Wagner',
leadLink: 'https://benedikt-wagner.dev/',
Expand Down Expand Up @@ -153,6 +156,7 @@ export const researchTracksData: ResearchTrack[] = [
signature aggregation, including various options like Binus M3, SP1, KRU, STU, Jolt, and OpenVM.',
icon: <Cpu className="h-5 w-5" />,
colorClass: 'amber',
status: 'active',
progress: 10,
lead: 'Thomas Coratger',
leadLink: 'https://x.com/tcoratger',
Expand Down Expand Up @@ -197,6 +201,7 @@ export const researchTracksData: ResearchTrack[] = [
more validators.',
icon: <Feather className="h-5 w-5" />,
colorClass: 'red',
status: 'inactive',
progress: 10,
lead: 'Josh Beal',
leadLink: 'https://x.com/TheBealDeal',
Expand Down Expand Up @@ -228,6 +233,7 @@ export const researchTracksData: ResearchTrack[] = [
that the zkEVM implementations are correct.',
icon: <FileCode className="h-5 w-5" />,
colorClass: 'indigo',
status: 'active',
progress: 10,
lead: 'Alex Hicks',
leadLink: 'https://x.com/alexanderlhicks',
Expand Down Expand Up @@ -272,6 +278,7 @@ export const researchTracksData: ResearchTrack[] = [
and while uncompromising on decentralization.",
icon: <Waypoints className="h-5 w-5" />,
colorClass: 'teal',
status: 'active',
progress: 10,
lead: 'Pop',
leadLink: 'https://github.com/ppopth',
Expand Down
Loading