Make links consistent across insights and config
This commit is contained in:
parent
7027e85530
commit
af40abeb97
@ -4,9 +4,7 @@ import {
|
|||||||
ComponentProps,
|
ComponentProps,
|
||||||
ReactNode,
|
ReactNode,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { clsx } from 'clsx/lite';
|
|
||||||
import ChecklistRow from '../components/ChecklistRow';
|
import ChecklistRow from '../components/ChecklistRow';
|
||||||
import { FiExternalLink } from 'react-icons/fi';
|
|
||||||
import {
|
import {
|
||||||
BiData,
|
BiData,
|
||||||
BiHide,
|
BiHide,
|
||||||
@ -29,6 +27,7 @@ import { PiPaintBrushHousehold } from 'react-icons/pi';
|
|||||||
import { IoMdGrid } from 'react-icons/io';
|
import { IoMdGrid } from 'react-icons/io';
|
||||||
import { CgDebug } from 'react-icons/cg';
|
import { CgDebug } from 'react-icons/cg';
|
||||||
import EnvVar from '@/components/EnvVar';
|
import EnvVar from '@/components/EnvVar';
|
||||||
|
import AdminLink from './AdminLink';
|
||||||
|
|
||||||
export default function AdminAppConfigurationClient({
|
export default function AdminAppConfigurationClient({
|
||||||
// Storage
|
// Storage
|
||||||
@ -110,27 +109,6 @@ export default function AdminAppConfigurationClient({
|
|||||||
simplifiedView?: boolean
|
simplifiedView?: boolean
|
||||||
isAnalyzingConfiguration?: 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 &&
|
|
||||||
<>
|
|
||||||
|
|
||||||
<FiExternalLink
|
|
||||||
size={14}
|
|
||||||
className='inline translate-y-[-1.5px]'
|
|
||||||
/>
|
|
||||||
</>}
|
|
||||||
</>;
|
|
||||||
|
|
||||||
const renderEnvVars = (variables: string[]) =>
|
const renderEnvVars = (variables: string[]) =>
|
||||||
<div className="pt-1 flex flex-col gap-1">
|
<div className="pt-1 flex flex-col gap-1">
|
||||||
{variables.map(envVar =>
|
{variables.map(envVar =>
|
||||||
@ -158,7 +136,7 @@ export default function AdminAppConfigurationClient({
|
|||||||
renderSubStatus(
|
renderSubStatus(
|
||||||
type,
|
type,
|
||||||
renderEnvVars([variable]),
|
renderEnvVars([variable]),
|
||||||
'translate-y-[5px]',
|
'translate-y-[3px]',
|
||||||
);
|
);
|
||||||
|
|
||||||
const renderError = ({
|
const renderError = ({
|
||||||
@ -211,11 +189,13 @@ export default function AdminAppConfigurationClient({
|
|||||||
: renderSubStatus('optional', <>
|
: renderSubStatus('optional', <>
|
||||||
Vercel Postgres:
|
Vercel Postgres:
|
||||||
{' '}
|
{' '}
|
||||||
{renderLink(
|
<AdminLink
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
'https://vercel.com/docs/storage/vercel-postgres/quickstart#create-a-postgres-database',
|
href="https://vercel.com/docs/storage/vercel-postgres/quickstart#create-a-postgres-database"
|
||||||
'create store',
|
externalIcon
|
||||||
)}
|
>
|
||||||
|
create store
|
||||||
|
</AdminLink>
|
||||||
{' '}
|
{' '}
|
||||||
and connect to project
|
and connect to project
|
||||||
</>)}
|
</>)}
|
||||||
@ -247,11 +227,13 @@ export default function AdminAppConfigurationClient({
|
|||||||
: renderSubStatus('optional', <>
|
: renderSubStatus('optional', <>
|
||||||
{labelForStorage('vercel-blob')}:
|
{labelForStorage('vercel-blob')}:
|
||||||
{' '}
|
{' '}
|
||||||
{renderLink(
|
<AdminLink
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
'https://vercel.com/docs/storage/vercel-blob/quickstart#create-a-blob-store',
|
href="https://vercel.com/docs/storage/vercel-blob/quickstart#create-a-blob-store"
|
||||||
'create store',
|
externalIcon
|
||||||
)}
|
>
|
||||||
|
create store
|
||||||
|
</AdminLink>
|
||||||
{' '}
|
{' '}
|
||||||
and connect to project
|
and connect to project
|
||||||
</>,
|
</>,
|
||||||
@ -261,20 +243,25 @@ export default function AdminAppConfigurationClient({
|
|||||||
: renderSubStatus('optional', <>
|
: renderSubStatus('optional', <>
|
||||||
{labelForStorage('cloudflare-r2')}:
|
{labelForStorage('cloudflare-r2')}:
|
||||||
{' '}
|
{' '}
|
||||||
{renderLink(
|
<AdminLink
|
||||||
'https://github.com/sambecker/exif-photo-blog#cloudflare-r2',
|
// eslint-disable-next-line max-len
|
||||||
'create/configure bucket',
|
href="https://github.com/sambecker/exif-photo-blog#cloudflare-r2"
|
||||||
)}
|
externalIcon
|
||||||
|
>
|
||||||
|
create/configure bucket
|
||||||
|
</AdminLink>
|
||||||
</>)}
|
</>)}
|
||||||
{hasAwsS3Storage
|
{hasAwsS3Storage
|
||||||
? renderSubStatus('checked', 'AWS S3: connected')
|
? renderSubStatus('checked', 'AWS S3: connected')
|
||||||
: renderSubStatus('optional', <>
|
: renderSubStatus('optional', <>
|
||||||
{labelForStorage('aws-s3')}:
|
{labelForStorage('aws-s3')}:
|
||||||
{' '}
|
{' '}
|
||||||
{renderLink(
|
<AdminLink
|
||||||
'https://github.com/sambecker/exif-photo-blog#aws-s3',
|
href="https://github.com/sambecker/exif-photo-blog#aws-s3"
|
||||||
'create/configure bucket',
|
externalIcon
|
||||||
)}
|
>
|
||||||
|
create/configure bucket
|
||||||
|
</AdminLink>
|
||||||
</>)}
|
</>)}
|
||||||
</ChecklistRow>
|
</ChecklistRow>
|
||||||
</ChecklistGroup>
|
</ChecklistGroup>
|
||||||
@ -385,11 +372,13 @@ export default function AdminAppConfigurationClient({
|
|||||||
{kvError && renderError({
|
{kvError && renderError({
|
||||||
connection: { provider: 'Vercel KV', error: kvError},
|
connection: { provider: 'Vercel KV', error: kvError},
|
||||||
})}
|
})}
|
||||||
{renderLink(
|
<AdminLink
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
'https://vercel.com/docs/storage/vercel-kv/quickstart#create-a-kv-database',
|
href="https://vercel.com/docs/storage/vercel-kv/quickstart#create-a-kv-database"
|
||||||
'Create Vercel KV store',
|
externalIcon
|
||||||
)}
|
>
|
||||||
|
Create Vercel KV store
|
||||||
|
</AdminLink>
|
||||||
{' '}
|
{' '}
|
||||||
and connect to project in order to enable rate limiting
|
and connect to project in order to enable rate limiting
|
||||||
</ChecklistRow>
|
</ChecklistRow>
|
||||||
|
|||||||
38
src/admin/AdminLink.tsx
Normal file
38
src/admin/AdminLink.tsx
Normal 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 &&
|
||||||
|
<>
|
||||||
|
|
||||||
|
<FiExternalLink
|
||||||
|
size={14}
|
||||||
|
className="inline translate-y-[-1.5px]"
|
||||||
|
/>
|
||||||
|
</>}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -30,26 +30,17 @@ import { PATH_ADMIN_OUTDATED } from '@/app-core/paths';
|
|||||||
import { LiaBroomSolid } from 'react-icons/lia';
|
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';
|
||||||
|
|
||||||
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';
|
||||||
const DEBUG_BEHIND_BY = 9;
|
const DEBUG_BEHIND_BY = 9;
|
||||||
const DEBUG_PHOTOS_COUNT_OUTDATED = 7;
|
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) =>
|
const readmeAnchor = (anchor: string) =>
|
||||||
renderLink(
|
<AdminLink href={`${TEMPLATE_REPO_URL_README}#${anchor}`}>
|
||||||
`README/${anchor}`,
|
README/{anchor}
|
||||||
`${TEMPLATE_REPO_URL_README}#${anchor}`,
|
</AdminLink>;
|
||||||
);
|
|
||||||
|
|
||||||
const renderLabeledEnvVar = (label: string, envVar: string, value = '1') =>
|
const renderLabeledEnvVar = (label: string, envVar: string, value = '1') =>
|
||||||
<div className="flex flex-col gap-1.5">
|
<div className="flex flex-col gap-1.5">
|
||||||
@ -112,7 +103,9 @@ export default function AdminAppInsightsClient({
|
|||||||
/>}
|
/>}
|
||||||
content="This template is not forked"
|
content="This template is not forked"
|
||||||
expandContent={<>
|
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.
|
to receive the latest fixes and features.
|
||||||
{' '}
|
{' '}
|
||||||
@ -144,7 +137,9 @@ export default function AdminAppInsightsClient({
|
|||||||
behind
|
behind
|
||||||
</>}
|
</>}
|
||||||
expandContent={<>
|
expandContent={<>
|
||||||
{renderLink('Sync your fork', codeMeta?.urlRepo)}
|
<AdminLink href={codeMeta?.urlRepo ?? ''}>
|
||||||
|
Sync your fork
|
||||||
|
</AdminLink>
|
||||||
{' '}
|
{' '}
|
||||||
to receive the latest fixes and features.
|
to receive the latest fixes and features.
|
||||||
</>}
|
</>}
|
||||||
@ -190,7 +185,7 @@ export default function AdminAppInsightsClient({
|
|||||||
target="blank"
|
target="blank"
|
||||||
className="flex items-center gap-2"
|
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}
|
{VERCEL_GIT_COMMIT_SHA_SHORT ?? DEBUG_COMMIT_SHA}
|
||||||
</span>
|
</span>
|
||||||
<span className="truncate">
|
<span className="truncate">
|
||||||
@ -270,18 +265,18 @@ export default function AdminAppInsightsClient({
|
|||||||
{' '}
|
{' '}
|
||||||
portrait and landscape photos appear more consistent
|
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
|
{(gridFirst || debug) && <ScoreCardRow
|
||||||
icon={<IoMdGrid size={18} className="translate-y-[-1px]" />}
|
icon={<IoMdGrid size={18} className="translate-y-[-1px]" />}
|
||||||
content="Grid homepage"
|
content="Grid homepage"
|
||||||
expandContent={<>
|
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>}
|
</ScoreCard>}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import clsx from 'clsx/lite';
|
|||||||
import { LuLightbulb } from 'react-icons/lu';
|
import { LuLightbulb } from 'react-icons/lu';
|
||||||
|
|
||||||
export default function AdminAppInsightsIcon({
|
export default function AdminAppInsightsIcon({
|
||||||
indicator = 'blue',
|
indicator,
|
||||||
}: {
|
}: {
|
||||||
indicator?: 'blue' | 'yellow'
|
indicator?: 'blue' | 'yellow'
|
||||||
}) {
|
}) {
|
||||||
|
|||||||
@ -42,7 +42,7 @@ export default function ChecklistRow({
|
|||||||
{experimental &&
|
{experimental &&
|
||||||
<ExperimentalBadge className="translate-y-[-0.5px]" />}
|
<ExperimentalBadge className="translate-y-[-0.5px]" />}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div className="leading-relaxed">
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user