@@ -45,6 +45,7 @@ import {
4545 TextSearch ,
4646 Filter ,
4747 WholeWord ,
48+ BarChart ,
4849} from "lucide-react" ;
4950import {
5051 DropdownMenu ,
@@ -409,18 +410,51 @@ function IndustryRankingsTable({
409410 </ TableCell >
410411 </ TableRow >
411412 ) : (
412- brands . map ( ( entity , index ) => (
413- < TableRow
414- key = { index }
415- className = "dark:text-white text-black border-[#e2e2e2]/40 dark:border-accent cursor-pointer"
416- onClick = { ( ) => {
417- setSelectedBrand ( new Set ( [ entity . brand_name ] ) ) ;
418- toastSonner . info (
419- `You have selected ${ entity . brand_name } `
420- ) ;
421- } }
422- >
423- < TableCell className = "font-medium" > { index + 1 } </ TableCell >
413+ ( ( ) => {
414+ // Calculate visibility scores and sort brands
415+ const brandsWithScores = brands . map ( ( entity ) => ( {
416+ ...entity ,
417+ visibilityScore : (
418+ ( 100 *
419+ ( Number ( getCoverageRatio ( entity , "count" ) ) +
420+ getMentionsIndex ( entity ) ) ) /
421+ 2
422+ )
423+ } ) ) ;
424+
425+ // Sort by visibility score in descending order
426+ brandsWithScores . sort ( ( a , b ) => b . visibilityScore - a . visibilityScore ) ;
427+
428+ // Calculate ranks with ties
429+ let currentRank = 1 ;
430+ let previousScore = null ;
431+ let rankCounter = 0 ;
432+
433+ const brandsWithRanks = brandsWithScores . map ( ( entity ) => {
434+ rankCounter ++ ;
435+ if ( previousScore !== null && entity . visibilityScore !== previousScore ) {
436+ currentRank = rankCounter ;
437+ }
438+ previousScore = entity . visibilityScore ;
439+
440+ return {
441+ ...entity ,
442+ rank : currentRank
443+ } ;
444+ } ) ;
445+
446+ return brandsWithRanks . map ( ( entity , index ) => (
447+ < TableRow
448+ key = { index }
449+ className = "dark:text-white text-black border-[#e2e2e2]/40 dark:border-accent cursor-pointer"
450+ onClick = { ( ) => {
451+ setSelectedBrand ( new Set ( [ entity . brand_name ] ) ) ;
452+ toastSonner . info (
453+ `You have selected ${ entity . brand_name } `
454+ ) ;
455+ } }
456+ >
457+ < TableCell className = "font-medium" > { entity . rank } </ TableCell >
424458 < TableCell className = "flex items-center gap-2" >
425459 < div className = "whitespace-normal break-words max-w-[150px] flex items-center" >
426460 { /* {brandFetch.find((brand) =>
@@ -456,17 +490,12 @@ function IndustryRankingsTable({
456490 ⌀ { getCoverageRatio ( entity , "ratio" ) }
457491 </ TableCell >
458492 < TableCell >
459- { (
460- ( 100 *
461- ( Number ( getCoverageRatio ( entity , "count" ) ) +
462- getMentionsIndex ( entity ) ) ) /
463- 2
464- ) . toFixed ( 1 ) }
465- %
493+ { entity . visibilityScore . toFixed ( 1 ) } %
466494 </ TableCell >
467- < TableCell > { entity . total_mentions } </ TableCell >
468- </ TableRow >
469- ) )
495+ < TableCell > { entity . total_mentions } </ TableCell >
496+ </ TableRow >
497+ ) ) ;
498+ } ) ( )
470499 ) }
471500 </ TableBody >
472501 </ Table >
@@ -3994,7 +4023,10 @@ function DashboardContent() {
39944023 < em className = "text-white" >
39954024 "{ selectedQuery ?. query } "
39964025 </ em >
3997- from < span className = "font-semibold" > { analysis_models . length } Models Analysis</ span >
4026+ </ p >
4027+ < p className = "text-muted-foreground items-center flex" >
4028+ < BarChart className = "w-4 h-4 mr-2" />
4029+ < span className = "font-regular" > { analysis_models . length } Models Analysis found { brandMentionsInSummaries . length } entities</ span >
39984030 </ p >
39994031 < AnimatePresence >
40004032 { isExpanded && (
@@ -4190,28 +4222,6 @@ function DashboardContent() {
41904222 brand = { currentBrand }
41914223 orientation = { "horizontal" }
41924224 />
4193- { /* <Tabs defaultValue="keywords" className="w-full">
4194- <TabsList className="grid w-full grid-cols-2 bg-muted/20">
4195- <TabsTrigger
4196- value="keywords"
4197- className="data-[state=active]:bg-blue-500/10"
4198- >
4199- Keywords
4200- </TabsTrigger>
4201- <TabsTrigger
4202- value="steps"
4203- className="data-[state=active]:bg-blue-500/10"
4204- >
4205- Steps
4206- </TabsTrigger>
4207- </TabsList>
4208- <TabsContent value="keywords">
4209- <KeywordAnalysisCard />
4210- </TabsContent>
4211- <TabsContent value="steps">
4212-
4213- </TabsContent>
4214- </Tabs> */ }
42154225 </ TabsContent >
42164226 < TabsContent value = "response" >
42174227 < div className = "flex gap-4 items-center" >
@@ -4300,6 +4310,73 @@ function DashboardContent() {
43004310 } ) ( ) }
43014311 </ TabsContent >
43024312 < TabsContent value = "citations" >
4313+ < div className = "flex gap-4 items-center mb-5" >
4314+ { /* Date Range Selection */ }
4315+ { new Date ( selectedQuery . results [ 0 ] ?. analysis_date ) . toLocaleString ( undefined , {
4316+ year : 'numeric' ,
4317+ month : 'long' ,
4318+ day : 'numeric' ,
4319+ hour : '2-digit' ,
4320+ minute : '2-digit' ,
4321+ second : '2-digit' ,
4322+ timeZoneName : 'short'
4323+ } ) }
4324+
4325+ < DropdownMenu >
4326+ < DropdownMenuTrigger asChild >
4327+ < Button
4328+ variant = "outline"
4329+ className = "w-full !border !border-accent md:w-fit"
4330+ >
4331+ { selectedModel . size === 0
4332+ ? "All Models"
4333+ : selectedModel . size === 1
4334+ ? Array . from ( selectedModel ) [ 0 ]
4335+ : `${ selectedModel . size } models selected` }
4336+ < span >
4337+ < ChevronDown className = "w-4 h-4 opacity-40" />
4338+ </ span >
4339+ </ Button >
4340+ </ DropdownMenuTrigger >
4341+ < DropdownMenuContent className = "w-56" >
4342+ < DropdownMenuLabel >
4343+ Filter by Model
4344+ </ DropdownMenuLabel >
4345+ < DropdownMenuSeparator />
4346+ < DropdownMenuCheckboxItem
4347+ checked = { selectedModel . size === 0 }
4348+ onCheckedChange = { ( checked ) => {
4349+ if ( checked ) {
4350+ setSelectedModel ( new Set < string > ( [ ] ) ) ;
4351+ }
4352+ } }
4353+ >
4354+ All Models
4355+ </ DropdownMenuCheckboxItem >
4356+ < ScrollArea className = "max-h-[200px]" >
4357+ { analysis_models ?. map ( ( model : string ) => (
4358+ < DropdownMenuCheckboxItem
4359+ key = { model }
4360+ checked = { selectedModel . has ( model ) }
4361+ onCheckedChange = { ( checked ) => {
4362+ setSelectedModel ( ( prev ) => {
4363+ const newSelection = new Set ( prev ) ;
4364+ if ( checked ) {
4365+ newSelection . add ( model ) ;
4366+ } else {
4367+ newSelection . delete ( model ) ;
4368+ }
4369+ return newSelection ;
4370+ } ) ;
4371+ } }
4372+ >
4373+ { model }
4374+ </ DropdownMenuCheckboxItem >
4375+ ) ) }
4376+ </ ScrollArea >
4377+ </ DropdownMenuContent >
4378+ </ DropdownMenu >
4379+ </ div >
43034380 < CitationsCard
43044381 results = { results || [ ] }
43054382 selectedDateRange = { selectedDateRange }
0 commit comments