Add 'Settings' to site checklist

This commit is contained in:
Sam Becker 2023-09-22 21:55:03 -05:00
parent 6e54f877bd
commit 2bb98eddda
6 changed files with 125 additions and 33 deletions

View File

@ -14,6 +14,7 @@ import { IS_PRO_MODE } from '@/site/config';
import PhotoTag from '@/tag/PhotoTag'; import PhotoTag from '@/tag/PhotoTag';
import { Metadata } from 'next'; import { Metadata } from 'next';
// Limit edge runtime to Pro due to function size limit
export const runtime = IS_PRO_MODE ? 'edge' : 'nodejs'; export const runtime = IS_PRO_MODE ? 'edge' : 'nodejs';
export async function generateMetadata(): Promise<Metadata> { export async function generateMetadata(): Promise<Metadata> {

View File

@ -8,6 +8,7 @@ import PhotosEmptyState from '@/photo/PhotosEmptyState';
import { IS_PRO_MODE } from '@/site/config'; import { IS_PRO_MODE } from '@/site/config';
import { Metadata } from 'next'; import { Metadata } from 'next';
// Limit edge runtime to Pro due to function size limit
export const runtime = IS_PRO_MODE ? 'edge' : 'nodejs'; export const runtime = IS_PRO_MODE ? 'edge' : 'nodejs';
export async function generateMetadata(): Promise<Metadata> { export async function generateMetadata(): Promise<Metadata> {

View File

@ -1,21 +1,27 @@
import { ReactNode } from 'react';
import { cc } from '@/utility/css'; import { cc } from '@/utility/css';
export default function Checklist({ export default function Checklist({
title, title,
icon,
children, children,
}: { }: {
title?: string title: string
children: React.ReactNode icon?: ReactNode
children: ReactNode
}) { }) {
return ( return (
<div> <div>
{title && <div className={cc(
<div className={cc( 'flex items-center gap-3',
'font-bold dark:text-gray-300', 'dark:text-gray-300',
'pl-4 mb-2', 'pl-[18px] mb-3',
)}> )}>
{icon}
<div className="text-lg">
{title} {title}
</div>} </div>
</div>
<div className={cc( <div className={cc(
'bg-white dark:bg-black', 'bg-white dark:bg-black',
'dark:text-gray-400', 'dark:text-gray-400',

View File

@ -1,6 +1,6 @@
import { ReactNode } from 'react'; import { ReactNode } from 'react';
import { cc } from '@/utility/css'; import { cc } from '@/utility/css';
import Spinner from '@/components/Spinner'; import StatusIcon from './StatusIcon';
export default function ChecklistRow({ export default function ChecklistRow({
title, title,
@ -21,20 +21,16 @@ export default function ChecklistRow({
'px-4 pt-2 pb-2.5', 'px-4 pt-2 pb-2.5',
'text-left', 'text-left',
)}> )}>
<div className="min-w-[1rem] pt-[1px]"> <StatusIcon
{isPending type={status ? 'checked' : optional ? 'optional' : 'missing'}
? <div className="translate-y-0.5"> loading={isPending}
<Spinner size={14} /> />
</div>
: <div className="text-[0.8rem]" style={{ fontFamily: 'emoji' }}>
{status
? '✅'
: optional ? '⚠️' : '❌'}
</div>}
</div>
<div className="flex flex-col items-start"> <div className="flex flex-col items-start">
<div className="font-bold dark:text-gray-300"> <div className={cc(
{title}{optional && ' (optional)'} 'font-bold dark:text-gray-300',
)}>
{title}
{optional && ' (optional)'}
</div> </div>
<div> <div>
{children} {children}

View File

@ -0,0 +1,44 @@
import {
BiSolidCheckboxChecked,
BiSolidCheckboxMinus,
BiSolidXSquare,
} from 'react-icons/bi';
import Spinner from './Spinner';
export default function StatusIcon({
type,
loading,
}: {
type: 'checked' | 'missing' | 'optional'
loading?: boolean
}) {
const getIcon = () => {
switch (type) {
case 'checked':
return <BiSolidCheckboxChecked
size={18}
className="text-green-400"
/>;
case 'missing':
return <BiSolidXSquare
size={14}
className="text-red-400 translate-x-[2px] translate-y-[1.5px]"
/>;
case 'optional':
return <BiSolidCheckboxMinus
size={18}
className="text-gray-400 dark:text-gray-500"
/>;
}
};
return (
<div className="min-w-[1.2rem] pt-[1px]">
{loading
? <div className="translate-y-0.5">
<Spinner size={14} />
</div>
: getIcon()}
</div>
);
}

View File

@ -5,7 +5,14 @@ import { useRouter } from 'next/navigation';
import { cc } from '@/utility/css'; import { cc } from '@/utility/css';
import ChecklistRow from '../components/ChecklistRow'; import ChecklistRow from '../components/ChecklistRow';
import { FiCheckSquare, FiExternalLink } from 'react-icons/fi'; import { FiCheckSquare, FiExternalLink } from 'react-icons/fi';
import { BiCopy, BiRefresh } from 'react-icons/bi'; import {
BiCog,
BiCopy,
BiData,
BiLockAlt,
BiPencil,
BiRefresh,
} from 'react-icons/bi';
import IconButton from '@/components/IconButton'; import IconButton from '@/components/IconButton';
import { toast } from 'sonner'; import { toast } from 'sonner';
import InfoBlock from '@/components/InfoBlock'; import InfoBlock from '@/components/InfoBlock';
@ -18,6 +25,8 @@ export default function SiteChecklistClient({
hasBlob, hasBlob,
hasAuth, hasAuth,
hasAdminUser, hasAdminUser,
showRepoLink,
isProMode,
showRefreshButton, showRefreshButton,
secret, secret,
}: { }: {
@ -27,6 +36,8 @@ export default function SiteChecklistClient({
hasBlob: boolean hasBlob: boolean
hasAuth: boolean hasAuth: boolean
hasAdminUser: boolean hasAdminUser: boolean
showRepoLink: boolean
isProMode: boolean
showRefreshButton?: boolean showRefreshButton?: boolean
secret: string secret: string
}) { }) {
@ -100,8 +111,11 @@ export default function SiteChecklistClient({
</div>; </div>;
return ( return (
<div className="text-sm max-w-xl space-y-4"> <div className="text-sm max-w-xl space-y-6">
<Checklist title="Site content"> <Checklist
title="Content"
icon={<BiPencil size={16} />}
>
<ChecklistRow <ChecklistRow
title="Add title" title="Add title"
status={hasTitle} status={hasTitle}
@ -120,7 +134,10 @@ export default function SiteChecklistClient({
{renderEnvVars(['NEXT_PUBLIC_SITE_DOMAIN'])} {renderEnvVars(['NEXT_PUBLIC_SITE_DOMAIN'])}
</ChecklistRow> </ChecklistRow>
</Checklist> </Checklist>
<Checklist title="Storage"> <Checklist
title="Storage"
icon={<BiData size={16} />}
>
<ChecklistRow <ChecklistRow
title="Setup database" title="Setup database"
status={hasPostgres} status={hasPostgres}
@ -146,7 +163,10 @@ export default function SiteChecklistClient({
and connect to project and connect to project
</ChecklistRow> </ChecklistRow>
</Checklist> </Checklist>
<Checklist title="Authentication"> <Checklist
title="Authentication"
icon={<BiLockAlt size={16} />}
>
<ChecklistRow <ChecklistRow
title="Setup auth" title="Setup auth"
status={hasAuth} status={hasAuth}
@ -182,13 +202,37 @@ export default function SiteChecklistClient({
'ADMIN_PASSWORD', 'ADMIN_PASSWORD',
])} ])}
</ChecklistRow> </ChecklistRow>
{showRefreshButton &&
<div className="py-4 space-y-4">
<button onClick={refreshPage}>
Check
</button>
</div>}
</Checklist> </Checklist>
<Checklist
title="Settings"
icon={<BiCog size={16} />}
>
<ChecklistRow
title="Show Repo Link"
status={showRepoLink}
isPending={isPendingPage}
optional
>
Set environment variable to {'"1"'} to hide footer link:
{renderEnvVars(['NEXT_PUBLIC_HIDE_REPO_LINK'])}
</ChecklistRow>
<ChecklistRow
title="Pro Mode"
status={isProMode}
isPending={isPendingPage}
optional
>
Set environment variable to {'"1"'} to enable Pro Mode
(includes additional edge functions and higher quality images):
{renderEnvVars(['NEXT_PUBLIC_PRO_MODE'])}
</ChecklistRow>
</Checklist>
{showRefreshButton &&
<div className="py-4 space-y-4">
<button onClick={refreshPage}>
Check
</button>
</div>}
<div className="px-10 text-gray-500"> <div className="px-10 text-gray-500">
Changes to environment variables require a redeploy Changes to environment variables require a redeploy
or reboot of local dev server or reboot of local dev server