Add insights empty state

This commit is contained in:
Sam Becker 2025-02-15 23:18:08 -06:00
parent b9baf65bf9
commit 6078fe8385
2 changed files with 120 additions and 84 deletions

View File

@ -0,0 +1,29 @@
import clsx from 'clsx/lite';
import { ReactNode } from 'react';
import { IoInformationCircleOutline } from 'react-icons/io5';
export default function AdminEmptyState({
icon,
children,
includeContainer = true,
}: {
icon?: ReactNode
children: ReactNode
includeContainer?: boolean
}) {
return (
<div className={clsx(
'flex flex-col gap-4 justify-center items-center p-8',
includeContainer &&'component-surface shadow-xs',
)}>
<div className={clsx(
'size-14 flex justify-center items-center',
'text-[1.75rem] text-medium',
'border border-main rounded-xl shadow-xs',
)}>
{icon ?? <IoInformationCircleOutline />}
</div>
{children}
</div>
);
}

View File

@ -31,6 +31,7 @@ import { LiaBroomSolid } from 'react-icons/lia';
import { IoMdGrid } from 'react-icons/io'; import { IoMdGrid } from 'react-icons/io';
import { RiSpeedMiniLine } from 'react-icons/ri'; import { RiSpeedMiniLine } from 'react-icons/ri';
import AdminLink from '../AdminLink'; import AdminLink from '../AdminLink';
import AdminEmptyState from '../AdminEmptyState';
const DEBUG_COMMIT_SHA = '4cd29ed'; const DEBUG_COMMIT_SHA = '4cd29ed';
const DEBUG_COMMIT_MESSAGE = 'Long commit message for debugging purposes'; const DEBUG_COMMIT_MESSAGE = 'Long commit message for debugging purposes';
@ -93,8 +94,8 @@ export default function AdminAppInsightsClient({
return ( return (
<div className="space-y-6 md:space-y-8"> <div className="space-y-6 md:space-y-8">
{(codeMeta?.isBaseRepo || codeMeta?.isForkedFromBase || debug) && <> {(codeMeta || debug) && <>
<ScoreCard title="Build details"> <ScoreCard title="Source code">
{(noFork || debug) && {(noFork || debug) &&
<ScoreCardRow <ScoreCardRow
icon={<FaCircleInfo icon={<FaCircleInfo
@ -195,91 +196,97 @@ export default function AdminAppInsightsClient({
/> />
</ScoreCard> </ScoreCard>
</>} </>}
{(hasTemplateRecommendations(insights) || debug) && <ScoreCard title="Template recommendations">
<ScoreCard title="Template recommendations"> {(hasTemplateRecommendations(insights) || debug)
{(noAiRateLimiting || debug) && <ScoreCardRow ? <>
icon={<PiWarningBold {(noAiRateLimiting || debug) && <ScoreCardRow
size={17} icon={<PiWarningBold
className="translate-x-[0.5px] text-amber-600" size={17}
className="translate-x-[0.5px] text-amber-600"
/>}
content="AI enabled without rate limiting"
expandContent={<>
Create Vercel KV store and link to this project
in order prevent abuse by to enabling rate limiting.
</>}
/>} />}
content="AI enabled without rate limiting" {(noStaticOptimization || debug) && <ScoreCardRow
expandContent={<> icon={<RiSpeedMiniLine
Create Vercel KV store and link to this project size={19}
in order prevent abuse by to enabling rate limiting. className="translate-x-[1px] translate-y-[-1.5px]"
</>} />}
/>} content="Speed up page load times"
{(noStaticOptimization || debug) && <ScoreCardRow expandContent={<>
icon={<RiSpeedMiniLine Improve load times by enabling static optimization
size={19} {' '}
className="translate-x-[1px] translate-y-[-1.5px]" on:
<div className="flex flex-col gap-y-4 mt-3">
{renderLabeledEnvVar(
'Photo pages',
'NEXT_PUBLIC_STATICALLY_OPTIMIZE_PHOTOS',
)}
{renderLabeledEnvVar(
'Photo OG images',
'NEXT_PUBLIC_STATICALLY_OPTIMIZE_PHOTO_OG_IMAGES',
)}
{renderLabeledEnvVar(
'Category pages (tags, cameras, etc.)',
'NEXT_PUBLIC_STATICALLY_OPTIMIZE_PHOTO_CATEGORIES',
)}
{renderLabeledEnvVar(
'Category OG images',
'NEXT_PUBLIC_STATICALLY_OPTIMIZE_PHOTO_CATEGORY_OG_IMAGES',
)}
<span>
See {readmeAnchor('performance')} for cost implications.
</span>
</div>
</>}
/>} />}
content="Speed up page load times" {(noAi || debug) && <ScoreCardRow
expandContent={<> icon={<TbSparkles size={17} />}
Improve load times by enabling static optimization content="Improve SEO + accessibility with AI"
{' '} expandContent={<>
on: Enable automatic AI text generation
<div className="flex flex-col gap-y-4 mt-3"> {' '}
{renderLabeledEnvVar( by setting <EnvVar variable="OPENAI_SECRET_KEY" />.
'Photo pages', {' '}
'NEXT_PUBLIC_STATICALLY_OPTIMIZE_PHOTOS', Further instruction and cost considerations in
)} {' '}
{renderLabeledEnvVar( {readmeAnchor('ai-text-generation')}.
'Photo OG images', </>}
'NEXT_PUBLIC_STATICALLY_OPTIMIZE_PHOTO_OG_IMAGES',
)}
{renderLabeledEnvVar(
'Category pages (tags, cameras, etc.)',
'NEXT_PUBLIC_STATICALLY_OPTIMIZE_PHOTO_CATEGORIES',
)}
{renderLabeledEnvVar(
'Category OG images',
'NEXT_PUBLIC_STATICALLY_OPTIMIZE_PHOTO_CATEGORY_OG_IMAGES',
)}
<span>
See {readmeAnchor('performance')} for cost implications.
</span>
</div>
</>}
/>}
{(noAi || debug) && <ScoreCardRow
icon={<TbSparkles size={17} />}
content="Improve SEO + accessibility with AI"
expandContent={<>
Enable automatic AI text generation
{' '}
by setting <EnvVar variable="OPENAI_SECRET_KEY" />.
{' '}
Further instruction and cost considerations in
{' '}
{readmeAnchor('ai-text-generation')}.
</>}
/>}
{(photoMatting || debug) && <ScoreCardRow
icon={<MdAspectRatio
size={17}
className="rotate-90 translate-x-[-1px]"
/>} />}
content="Vertical photos may benefit from matting" {(photoMatting || debug) && <ScoreCardRow
expandContent={<> icon={<MdAspectRatio
Enable photo matting to make size={17}
{' '} className="rotate-90 translate-x-[-1px]"
portrait and landscape photos appear more consistent />}
{' '} content="Vertical photos may benefit from matting"
<EnvVar variable="NEXT_PUBLIC_MATTE_PHOTOS" value="1" />. expandContent={<>
</>} Enable photo matting to make
/>} {' '}
{(gridFirst || debug) && <ScoreCardRow portrait and landscape photos appear more consistent
icon={<IoMdGrid size={18} className="translate-y-[-1px]" />} {' '}
content="Grid homepage" <EnvVar variable="NEXT_PUBLIC_MATTE_PHOTOS" value="1" />.
expandContent={<> </>}
Now that you have enough photos, consider switching your />}
{' '} {(gridFirst || debug) && <ScoreCardRow
default view to grid by setting icon={<IoMdGrid size={18} className="translate-y-[-1px]" />}
{' '} content="Grid homepage"
<EnvVar variable="NEXT_PUBLIC_GRID_HOMEPAGE_ENABLED" value="1" />. expandContent={<>
</>} Now that you have enough photos, consider switching your
/>} {' '}
</ScoreCard>} default view to grid by setting
{' '}
{/* eslint-disable-next-line max-len */}
<EnvVar variable="NEXT_PUBLIC_GRID_HOMEPAGE_ENABLED" value="1" />.
</>}
/>}
</>
: <AdminEmptyState includeContainer={false}>
Nothing to report!
</AdminEmptyState>}
</ScoreCard>
<ScoreCard title="Library Stats"> <ScoreCard title="Library Stats">
{(outdatedPhotos || debug) && <ScoreCardRow {(outdatedPhotos || debug) && <ScoreCardRow
icon={<LiaBroomSolid icon={<LiaBroomSolid