feat: add Search panel to dashboard and enrich Search tab
Dashboard: compact Search Performance panel showing top 5 queries, clicks, impressions, and avg position alongside Campaigns. Search tab: clicks/impressions trend chart, top query position tracker cards, and new queries badge.
This commit is contained in:
@@ -77,3 +77,22 @@ export async function getGSCQueryPages(siteId: string, query: string, startDate:
|
||||
export async function getGSCPageQueries(siteId: string, page: string, startDate: string, endDate: string): Promise<GSCQueryResponse> {
|
||||
return apiRequest<GSCQueryResponse>(`/sites/${siteId}/gsc/page-queries?page=${encodeURIComponent(page)}&start_date=${startDate}&end_date=${endDate}`)
|
||||
}
|
||||
|
||||
export interface GSCDailyTotal {
|
||||
date: string
|
||||
clicks: number
|
||||
impressions: number
|
||||
}
|
||||
|
||||
export interface GSCNewQueries {
|
||||
count: number
|
||||
queries: string[]
|
||||
}
|
||||
|
||||
export async function getGSCDailyTotals(siteId: string, startDate: string, endDate: string): Promise<{ daily_totals: GSCDailyTotal[] }> {
|
||||
return apiRequest<{ daily_totals: GSCDailyTotal[] }>(`/sites/${siteId}/gsc/daily-totals?start_date=${startDate}&end_date=${endDate}`)
|
||||
}
|
||||
|
||||
export async function getGSCNewQueries(siteId: string, startDate: string, endDate: string): Promise<GSCNewQueries> {
|
||||
return apiRequest<GSCNewQueries>(`/sites/${siteId}/gsc/new-queries?start_date=${startDate}&end_date=${endDate}`)
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ import { listFunnels, type Funnel } from '@/lib/api/funnels'
|
||||
import { getUptimeStatus, type UptimeStatusResponse } from '@/lib/api/uptime'
|
||||
import { listGoals, type Goal } from '@/lib/api/goals'
|
||||
import { listReportSchedules, type ReportSchedule } from '@/lib/api/report-schedules'
|
||||
import { getGSCStatus, getGSCOverview, getGSCTopQueries, getGSCTopPages } from '@/lib/api/gsc'
|
||||
import type { GSCStatus, GSCOverview, GSCQueryResponse, GSCPageResponse } from '@/lib/api/gsc'
|
||||
import { getGSCStatus, getGSCOverview, getGSCTopQueries, getGSCTopPages, getGSCDailyTotals, getGSCNewQueries } from '@/lib/api/gsc'
|
||||
import type { GSCStatus, GSCOverview, GSCQueryResponse, GSCPageResponse, GSCDailyTotal, GSCNewQueries } from '@/lib/api/gsc'
|
||||
import { getSubscription, type SubscriptionDetails } from '@/lib/api/billing'
|
||||
import type {
|
||||
Stats,
|
||||
@@ -84,6 +84,8 @@ const fetchers = {
|
||||
gscOverview: (siteId: string, start: string, end: string) => getGSCOverview(siteId, start, end),
|
||||
gscTopQueries: (siteId: string, start: string, end: string, limit: number, offset: number) => getGSCTopQueries(siteId, start, end, limit, offset),
|
||||
gscTopPages: (siteId: string, start: string, end: string, limit: number, offset: number) => getGSCTopPages(siteId, start, end, limit, offset),
|
||||
gscDailyTotals: (siteId: string, start: string, end: string) => getGSCDailyTotals(siteId, start, end),
|
||||
gscNewQueries: (siteId: string, start: string, end: string) => getGSCNewQueries(siteId, start, end),
|
||||
subscription: () => getSubscription(),
|
||||
}
|
||||
|
||||
@@ -449,6 +451,24 @@ export function useGSCTopPages(siteId: string, start: string, end: string, limit
|
||||
)
|
||||
}
|
||||
|
||||
// * Hook for GSC daily totals (clicks & impressions per day)
|
||||
export function useGSCDailyTotals(siteId: string, start: string, end: string) {
|
||||
return useSWR<{ daily_totals: GSCDailyTotal[] }>(
|
||||
siteId && start && end ? ['gscDailyTotals', siteId, start, end] : null,
|
||||
() => fetchers.gscDailyTotals(siteId, start, end),
|
||||
dashboardSWRConfig
|
||||
)
|
||||
}
|
||||
|
||||
// * Hook for GSC new queries (queries that appeared in the current period)
|
||||
export function useGSCNewQueries(siteId: string, start: string, end: string) {
|
||||
return useSWR<GSCNewQueries>(
|
||||
siteId && start && end ? ['gscNewQueries', siteId, start, end] : null,
|
||||
() => fetchers.gscNewQueries(siteId, start, end),
|
||||
dashboardSWRConfig
|
||||
)
|
||||
}
|
||||
|
||||
// * Hook for subscription details (changes rarely)
|
||||
export function useSubscription() {
|
||||
return useSWR<SubscriptionDetails>(
|
||||
|
||||
Reference in New Issue
Block a user