import dayjs from 'dayjs' import { Auth, Database, Realtime, Storage } from 'icons' import sumBy from 'lodash/sumBy' import { ChevronDown } from 'lucide-react' import Link from 'next/link' import { useRouter } from 'next/router' import { useState } from 'react' import { useParams } from 'common' import BarChart from 'components/ui/Charts/BarChart' import { InlineLink } from 'components/ui/InlineLink' import Panel from 'components/ui/Panel' import { ProjectLogStatsVariables, UsageApiCounts, useProjectLogStatsQuery, } from 'data/analytics/project-log-stats-query' import { useFillTimeseriesSorted } from 'hooks/analytics/useFillTimeseriesSorted' import { useCurrentOrgPlan } from 'hooks/misc/useCurrentOrgPlan' import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled' import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization' import type { ChartIntervals } from 'types' import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuTrigger, Loading, Tooltip, TooltipContent, TooltipTrigger, } from 'ui' type ChartIntervalKey = ProjectLogStatsVariables['interval'] const LOG_RETENTION = { free: 1, pro: 7, team: 28, enterprise: 90, platform: 1 } const CHART_INTERVALS: ChartIntervals[] = [ { key: '1hr', label: 'Last 60 minutes', startValue: 1, startUnit: 'hour', format: 'MMM D, h:mma', availableIn: ['free', 'pro', 'team', 'enterprise', 'platform'], }, { key: '1day', label: 'Last 24 hours', startValue: 24, startUnit: 'hour', format: 'MMM D, ha', availableIn: ['free', 'pro', 'team', 'enterprise', 'platform'], }, { key: '7day', label: 'Last 7 days', startValue: 7, startUnit: 'day', format: 'MMM D', availableIn: ['pro', 'team', 'enterprise'], }, ] const ProjectUsage = () => { const router = useRouter() const { ref: projectRef } = useParams() const { data: organization } = useSelectedOrganizationQuery() const { projectAuthAll: authEnabled, projectStorageAll: storageEnabled } = useIsFeatureEnabled([ 'project_auth:all', 'project_storage:all', ]) const { plan } = useCurrentOrgPlan() const DEFAULT_INTERVAL: ChartIntervalKey = plan?.id === 'free' ? '1hr' : '1day' const [interval, setInterval] = useState(DEFAULT_INTERVAL) const { data, isPending: isLoading } = useProjectLogStatsQuery({ projectRef, interval }) const selectedInterval = CHART_INTERVALS.find((i) => i.key === interval) || CHART_INTERVALS[1] const startDateLocal = dayjs().subtract( selectedInterval.startValue, selectedInterval.startUnit as dayjs.ManipulateType ) const endDateLocal = dayjs() const { data: charts } = useFillTimeseriesSorted( data?.result || [], 'timestamp', [ 'total_auth_requests', 'total_rest_requests', 'total_storage_requests', 'total_realtime_requests', ], 0, startDateLocal.toISOString(), endDateLocal.toISOString(), 5 ) const datetimeFormat = selectedInterval.format || 'MMM D, ha' const handleBarClick = ( value: UsageApiCounts, _type: 'rest' | 'realtime' | 'storage' | 'auth' ) => { const unit = selectedInterval.startUnit const selectedStart = dayjs(value?.timestamp) const selectedEnd = selectedStart.add(1, unit) if (_type === 'rest') { router.push( `/project/${projectRef}/logs/edge-logs?its=${selectedStart.toISOString()}&ite=${selectedEnd.toISOString()}` ) return } router.push( `/project/${projectRef}/logs/edge-logs?its=${selectedStart.toISOString()}&ite=${selectedEnd.toISOString()}&f=${JSON.stringify( { product: { [_type]: true, }, } )}` ) } return (
setInterval(interval as ProjectLogStatsVariables['interval']) } > {CHART_INTERVALS.map((i) => { const disabled = !i.availableIn?.includes(plan?.id || 'free') if (disabled) { const retentionDuration = LOG_RETENTION[plan?.id ?? 'free'] return ( {i.label}

{plan?.name} plan only includes up to {retentionDuration} day {retentionDuration > 1 ? 's' : ''} of log retention

Upgrade your plan {' '} to increase log retention and view statistics for the{' '} {i.label.toLowerCase()}

) } else { return ( {i.label} ) } })}
Statistics for {selectedInterval.label.toLowerCase()}
} title="Database" href={`/project/${projectRef}/editor`} /> handleBarClick(v as UsageApiCounts, 'rest')} customDateFormat={datetimeFormat} highlightedValue={sumBy(charts, 'total_rest_requests')} /> {authEnabled && (
} title="Auth" href={`/project/${projectRef}/auth/users`} /> handleBarClick(v as UsageApiCounts, 'auth')} customDateFormat={datetimeFormat} highlightedValue={sumBy(charts || [], 'total_auth_requests')} /> )} {storageEnabled && ( } title="Storage" href={`/project/${projectRef}/storage/buckets`} /> handleBarClick(v as UsageApiCounts, 'storage')} customDateFormat={datetimeFormat} highlightedValue={sumBy(charts, 'total_storage_requests')} /> )} } title="Realtime" /> handleBarClick(v as UsageApiCounts, 'realtime')} customDateFormat={datetimeFormat} highlightedValue={sumBy(charts, 'total_realtime_requests')} /> ) } export default ProjectUsage const PanelHeader = (props: any) => { const Tag = props?.href ? Link : 'div' return (
{props.icon}

{props.title}

) }