Make links consistent across insights and config

This commit is contained in:
Sam Becker 2025-02-15 18:16:23 -06:00
parent 7027e85530
commit af40abeb97
5 changed files with 88 additions and 66 deletions

View File

@ -4,9 +4,7 @@ import {
ComponentProps,
ReactNode,
} from 'react';
import { clsx } from 'clsx/lite';
import ChecklistRow from '../components/ChecklistRow';
import { FiExternalLink } from 'react-icons/fi';
import {
BiData,
BiHide,
@ -29,6 +27,7 @@ import { PiPaintBrushHousehold } from 'react-icons/pi';
import { IoMdGrid } from 'react-icons/io';
import { CgDebug } from 'react-icons/cg';
import EnvVar from '@/components/EnvVar';
import AdminLink from './AdminLink';
export default function AdminAppConfigurationClient({
// Storage
@ -110,27 +109,6 @@ export default function AdminAppConfigurationClient({
simplifiedView?: boolean
isAnalyzingConfiguration?: boolean
}) {
const renderLink = (href: string, text: string, external = true) =>
<>
<a {...{
href,
...external && { target: '_blank', rel: 'noopener noreferrer' },
className: clsx(
'underline hover:no-underline',
),
}}>
{text}
</a>
{external &&
<>
&nbsp;
<FiExternalLink
size={14}
className='inline translate-y-[-1.5px]'
/>
</>}
</>;
const renderEnvVars = (variables: string[]) =>
<div className="pt-1 flex flex-col gap-1">
{variables.map(envVar =>
@ -158,7 +136,7 @@ export default function AdminAppConfigurationClient({
renderSubStatus(
type,
renderEnvVars([variable]),
'translate-y-[5px]',
'translate-y-[3px]',
);
const renderError = ({
@ -211,11 +189,13 @@ export default function AdminAppConfigurationClient({
: renderSubStatus('optional', <>
Vercel Postgres:
{' '}
{renderLink(
<AdminLink
// eslint-disable-next-line max-len
'https://vercel.com/docs/storage/vercel-postgres/quickstart#create-a-postgres-database',
'create store',
)}
href="https://vercel.com/docs/storage/vercel-postgres/quickstart#create-a-postgres-database"
externalIcon
>
create store
</AdminLink>
{' '}
and connect to project
</>)}
@ -247,11 +227,13 @@ export default function AdminAppConfigurationClient({
: renderSubStatus('optional', <>
{labelForStorage('vercel-blob')}:
{' '}
{renderLink(
<AdminLink
// eslint-disable-next-line max-len
'https://vercel.com/docs/storage/vercel-blob/quickstart#create-a-blob-store',
'create store',
)}
href="https://vercel.com/docs/storage/vercel-blob/quickstart#create-a-blob-store"
externalIcon
>
create store
</AdminLink>
{' '}
and connect to project
</>,
@ -261,20 +243,25 @@ export default function AdminAppConfigurationClient({
: renderSubStatus('optional', <>
{labelForStorage('cloudflare-r2')}:
{' '}
{renderLink(
'https://github.com/sambecker/exif-photo-blog#cloudflare-r2',
'create/configure bucket',
)}
<AdminLink
// eslint-disable-next-line max-len
href="https://github.com/sambecker/exif-photo-blog#cloudflare-r2"
externalIcon
>
create/configure bucket
</AdminLink>
</>)}
{hasAwsS3Storage
? renderSubStatus('checked', 'AWS S3: connected')
: renderSubStatus('optional', <>
{labelForStorage('aws-s3')}:
{' '}
{renderLink(
'https://github.com/sambecker/exif-photo-blog#aws-s3',
'create/configure bucket',
)}
<AdminLink
href="https://github.com/sambecker/exif-photo-blog#aws-s3"
externalIcon
>
create/configure bucket
</AdminLink>
</>)}
</ChecklistRow>
</ChecklistGroup>
@ -385,11 +372,13 @@ export default function AdminAppConfigurationClient({
{kvError && renderError({
connection: { provider: 'Vercel KV', error: kvError},
})}
{renderLink(
<AdminLink
// eslint-disable-next-line max-len
'https://vercel.com/docs/storage/vercel-kv/quickstart#create-a-kv-database',
'Create Vercel KV store',
)}
href="https://vercel.com/docs/storage/vercel-kv/quickstart#create-a-kv-database"
externalIcon
>
Create Vercel KV store
</AdminLink>
{' '}
and connect to project in order to enable rate limiting
</ChecklistRow>

38
src/admin/AdminLink.tsx Normal file
View File

@ -0,0 +1,38 @@
import clsx from 'clsx/lite';
import Link from 'next/link';
import { ComponentProps } from 'react';
import { FiExternalLink } from 'react-icons/fi';
export default function AdminLink({
href,
className,
children,
externalIcon,
...props
}: ComponentProps<typeof Link> & {
externalIcon?: boolean
}) {
return (
<>
<Link
{...props}
href={href}
target="blank"
className={clsx(
'underline underline-offset-4',
'decoration-gray-300 dark:decoration-gray-700',
className,
)}
>
{children}
</Link>
{externalIcon &&
<>
&nbsp;
<FiExternalLink
size={14}
className="inline translate-y-[-1.5px]"
/>
</>}
</>
);
}

View File

@ -30,26 +30,17 @@ import { PATH_ADMIN_OUTDATED } from '@/app-core/paths';
import { LiaBroomSolid } from 'react-icons/lia';
import { IoMdGrid } from 'react-icons/io';
import { RiSpeedMiniLine } from 'react-icons/ri';
import AdminLink from '../AdminLink';
const DEBUG_COMMIT_SHA = '4cd29ed';
const DEBUG_COMMIT_MESSAGE = 'Long commit message for debugging purposes';
const DEBUG_BEHIND_BY = 9;
const DEBUG_PHOTOS_COUNT_OUTDATED = 7;
const renderLink = (text: string, href = '') =>
<a
href={href}
target="blank"
className="underline underline-offset-4 decoration-gray-300"
>
{text}
</a>;
const readmeAnchor = (anchor: string) =>
renderLink(
`README/${anchor}`,
`${TEMPLATE_REPO_URL_README}#${anchor}`,
);
<AdminLink href={`${TEMPLATE_REPO_URL_README}#${anchor}`}>
README/{anchor}
</AdminLink>;
const renderLabeledEnvVar = (label: string, envVar: string, value = '1') =>
<div className="flex flex-col gap-1.5">
@ -112,7 +103,9 @@ export default function AdminAppInsightsClient({
/>}
content="This template is not forked"
expandContent={<>
{renderLink('Fork original template', TEMPLATE_REPO_URL_FORK)}
<AdminLink href={TEMPLATE_REPO_URL_FORK}>
Fork original template
</AdminLink>
{' '}
to receive the latest fixes and features.
{' '}
@ -144,7 +137,9 @@ export default function AdminAppInsightsClient({
behind
</>}
expandContent={<>
{renderLink('Sync your fork', codeMeta?.urlRepo)}
<AdminLink href={codeMeta?.urlRepo ?? ''}>
Sync your fork
</AdminLink>
{' '}
to receive the latest fixes and features.
</>}
@ -190,7 +185,7 @@ export default function AdminAppInsightsClient({
target="blank"
className="flex items-center gap-2"
>
<span className="text-medium">
<span className="text-medium hidden sm:inline-block">
{VERCEL_GIT_COMMIT_SHA_SHORT ?? DEBUG_COMMIT_SHA}
</span>
<span className="truncate">
@ -270,18 +265,18 @@ export default function AdminAppInsightsClient({
{' '}
portrait and landscape photos appear more consistent
{' '}
<EnvVar variable="NEXT_PUBLIC_MATTE_PHOTOS" value="1" />
<EnvVar variable="NEXT_PUBLIC_MATTE_PHOTOS" value="1" />.
</>}
/>}
{(gridFirst || debug) && <ScoreCardRow
icon={<IoMdGrid size={18} className="translate-y-[-1px]" />}
content="Grid homepage"
expandContent={<>
Now that you have a sufficient amount of photos, you can
Now that you have enough photos, consider switching your
{' '}
enable grid homepage by setting
default view to grid by setting
{' '}
<EnvVar variable="NEXT_PUBLIC_GRID_HOMEPAGE_ENABLED" value="1" />
<EnvVar variable="NEXT_PUBLIC_GRID_HOMEPAGE_ENABLED" value="1" />.
</>}
/>}
</ScoreCard>}

View File

@ -2,7 +2,7 @@ import clsx from 'clsx/lite';
import { LuLightbulb } from 'react-icons/lu';
export default function AdminAppInsightsIcon({
indicator = 'blue',
indicator,
}: {
indicator?: 'blue' | 'yellow'
}) {

View File

@ -42,7 +42,7 @@ export default function ChecklistRow({
{experimental &&
<ExperimentalBadge className="translate-y-[-0.5px]" />}
</div>
<div>
<div className="leading-relaxed">
{children}
</div>
</div>