11//import { DraftStats } from '@/lib/enhancers/draftStats'
22
33import { GitPullRequestIcon , IssueOpenedIcon } from '@primer/octicons-react'
4- import { twMerge } from 'tailwind-merge'
54import { cva , type VariantProps } from 'class-variance-authority'
65import {
76 Archive ,
87 Clock ,
98 Code ,
9+ EyeOff ,
1010 Filter ,
1111 Image ,
1212 Link ,
@@ -17,13 +17,11 @@ import {
1717 TextSelect ,
1818} from 'lucide-react'
1919import { useMemo , useState } from 'react'
20+ import { twMerge } from 'tailwind-merge'
2021import type { CommentSpot } from '@/lib/enhancer'
2122import type { DraftStats } from '@/lib/enhancers/draftStats'
2223
2324interface FilterState {
24- hasLink : boolean
25- hasImage : boolean
26- hasCode : boolean
2725 sentFilter : 'all' | 'sent' | 'unsent'
2826 searchQuery : string
2927 showArchived : boolean
@@ -33,11 +31,23 @@ interface FilterState {
3331const statBadge = cva (
3432 'inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-xs font-normal tracking-normal' ,
3533 {
34+ defaultVariants : {
35+ clickable : false ,
36+ } ,
3637 variants : {
38+ clickable : {
39+ false : '' ,
40+ true : 'cursor-pointer border border-transparent hover:border-current border-dashed' ,
41+ } ,
42+ selected : {
43+ false : '' ,
44+ true : 'border-solid border-current' ,
45+ } ,
3746 type : {
3847 archived : 'bg-gray-50 text-yellow-700' ,
3948 blank : 'bg-transparent text-gray-700' ,
4049 code : 'bg-pink-50 text-pink-700' ,
50+ hideArchived : 'bg-transparent text-gray-700' ,
4151 image : 'bg-purple-50 text-purple-700' ,
4252 link : 'bg-blue-50 text-blue-700' ,
4353 open : 'bg-cyan-50 text-cyan-700' ,
@@ -46,13 +56,6 @@ const statBadge = cva(
4656 time : 'bg-gray-50 text-gray-700' ,
4757 unsent : 'bg-amber-100 text-amber-700' ,
4858 } ,
49- clickable : {
50- true : 'cursor-pointer border border-transparent hover:border-current' ,
51- false : '' ,
52- } ,
53- } ,
54- defaultVariants : {
55- clickable : false ,
5659 } ,
5760 } ,
5861)
@@ -62,6 +65,7 @@ const typeIcons = {
6265 archived : Archive ,
6366 blank : Archive ,
6467 code : Code ,
68+ hideArchived : EyeOff ,
6569 image : Image ,
6670 link : Link ,
6771 open : Monitor ,
@@ -76,18 +80,22 @@ type BadgeProps = VariantProps<typeof statBadge> & {
7680 type : keyof typeof typeIcons
7781 text ?: number | string
7882 onClick ?: ( ) => void
83+ selected ?: boolean
7984}
8085
81- const Badge = ( { text, type, onClick } : BadgeProps ) => {
86+ const Badge = ( { text, type, onClick, selected } : BadgeProps ) => {
8287 const Icon = typeIcons [ type ]
8388 const Component = onClick ? 'button' : 'span'
8489
8590 return (
8691 < Component
87- className = { twMerge ( statBadge ( {
88- type,
89- clickable : ! ! onClick
90- } ) ) }
92+ className = { twMerge (
93+ statBadge ( {
94+ clickable : ! ! onClick ,
95+ selected : selected || false ,
96+ type,
97+ } ) ,
98+ ) }
9199 onClick = { onClick }
92100 { ...( onClick && { type : 'button' } ) }
93101 >
@@ -336,9 +344,6 @@ export const ClaudePrototype = () => {
336344 const [ drafts ] = useState ( generateMockDrafts ( ) )
337345 const [ selectedIds , setSelectedIds ] = useState ( new Set ( ) )
338346 const [ filters , setFilters ] = useState < FilterState > ( {
339- hasCode : false ,
340- hasImage : false ,
341- hasLink : false ,
342347 searchQuery : '' ,
343348 sentFilter : 'all' ,
344349 showArchived : false ,
@@ -351,15 +356,6 @@ export const ClaudePrototype = () => {
351356
352357 const filteredDrafts = useMemo ( ( ) => {
353358 let filtered = [ ...drafts ]
354- if ( filters . hasCode ) {
355- filtered = filtered . filter ( ( d ) => d . latestDraft . stats . codeBlocks . length > 0 )
356- }
357- if ( filters . hasImage ) {
358- filtered = filtered . filter ( ( d ) => d . latestDraft . stats . images . length > 0 )
359- }
360- if ( filters . hasLink ) {
361- filtered = filtered . filter ( ( d ) => d . latestDraft . stats . links . length > 0 )
362- }
363359 if ( ! filters . showArchived ) {
364360 filtered = filtered . filter ( ( d ) => ! d . isArchived )
365361 }
@@ -435,14 +431,7 @@ export const ClaudePrototype = () => {
435431 )
436432 }
437433
438- if (
439- filteredDrafts . length === 0 &&
440- ( filters . searchQuery ||
441- filters . hasCode ||
442- filters . hasImage ||
443- filters . hasLink ||
444- filters . sentFilter !== 'all' )
445- ) {
434+ if ( filteredDrafts . length === 0 && ( filters . searchQuery || filters . sentFilter !== 'all' ) ) {
446435 return (
447436 < div className = 'min-h-screen bg-white' >
448437 < div className = 'p-6 border-b' >
@@ -468,12 +457,9 @@ export const ClaudePrototype = () => {
468457 type = 'button'
469458 onClick = { ( ) => {
470459 setFilters ( {
471- hasCode : false ,
472- hasImage : false ,
473- hasLink : false ,
474460 searchQuery : '' ,
475461 sentFilter : 'all' ,
476- showArchived : true
462+ showArchived : true ,
477463 } )
478464 } }
479465 className = 'text-blue-600 hover:underline'
@@ -567,7 +553,7 @@ export const ClaudePrototype = () => {
567553 )
568554}
569555function filterControls (
570- _filters : FilterState ,
556+ filters : FilterState ,
571557 updateFilter : < K extends keyof FilterState > ( key : K , value : FilterState [ K ] ) => void ,
572558) {
573559 return (
@@ -576,63 +562,37 @@ function filterControls(
576562 < div className = 'relative flex overflow-hidden' >
577563 < Badge
578564 type = 'archived'
579- text = 'include'
565+ text = 'show archived'
566+ selected = { filters . showArchived }
580567 onClick = { ( ) => updateFilter ( 'showArchived' , true ) }
581568 />
582569 < Badge
583- type = 'blank '
570+ type = 'hideArchived '
584571 text = 'hide archived'
572+ selected = { ! filters . showArchived }
585573 onClick = { ( ) => updateFilter ( 'showArchived' , false ) }
586574 />
587575 </ div >
588576 < div className = 'relative flex overflow-hidden' >
589577 < Badge
590578 type = 'unsent'
579+ text = 'unsent only'
580+ selected = { filters . sentFilter === 'unsent' }
591581 onClick = { ( ) => updateFilter ( 'sentFilter' , 'unsent' ) }
592582 />
593583 < Badge
594584 type = 'blank'
595585 text = 'both'
586+ selected = { filters . sentFilter === 'all' }
596587 onClick = { ( ) => updateFilter ( 'sentFilter' , 'all' ) }
597588 />
598589 < Badge
599590 type = 'sent'
591+ text = 'sent only'
592+ selected = { filters . sentFilter === 'sent' }
600593 onClick = { ( ) => updateFilter ( 'sentFilter' , 'sent' ) }
601594 />
602595 </ div >
603- < div className = 'relative flex' >
604- < Badge
605- type = 'link'
606- onClick = { ( ) => updateFilter ( 'hasLink' , true ) }
607- />
608- < Badge
609- type = 'blank'
610- text = 'optional'
611- onClick = { ( ) => updateFilter ( 'hasLink' , false ) }
612- />
613- </ div >
614- < div className = 'relative flex overflow-hidden' >
615- < Badge
616- type = 'image'
617- onClick = { ( ) => updateFilter ( 'hasImage' , true ) }
618- />
619- < Badge
620- type = 'blank'
621- text = 'optional'
622- onClick = { ( ) => updateFilter ( 'hasImage' , false ) }
623- />
624- </ div >
625- < div className = 'relative flex overflow-hidden' >
626- < Badge
627- type = 'code'
628- onClick = { ( ) => updateFilter ( 'hasCode' , true ) }
629- />
630- < Badge
631- type = 'blank'
632- text = 'optional'
633- onClick = { ( ) => updateFilter ( 'hasCode' , false ) }
634- />
635- </ div >
636596 </ div >
637597 </ div >
638598 )
0 commit comments