2 Commits

Author SHA1 Message Date
f03faabbee UI tweaks on admin side
All checks were successful
Publish Docker Image / Publish Docker Image (push) Successful in 11s
2024-10-23 16:52:10 -04:00
353fb3899e PDF error handling 2024-10-23 12:26:21 -04:00
24 changed files with 289 additions and 260 deletions

View File

@ -35,7 +35,7 @@ const Routes = () => {
<Route path="/admin/resume" page={ResumeAdminResumePage} name="adminResume" />
</Set>
<Set wrap={ScaffoldLayout} title="Projects" titleTo="projects" buttonLabel="New Project" buttonTo="newProject">
<Set wrap={ScaffoldLayout} title="Projects" titleTo="adminProjects" buttonLabel="New Project" buttonTo="newProject">
<Route path="/admin/projects/new" page={ProjectNewProjectPage} name="newProject" />
<Route path="/admin/projects/{id:Int}/edit" page={ProjectEditProjectPage} name="editProject" />
<Route path="/admin/projects/{id:Int}" page={ProjectAdminProjectPage} name="adminProject" />

View File

@ -9,54 +9,50 @@ interface ColorPickerProps {
setColor: React.Dispatch<React.SetStateAction<string>>
}
const ColorPicker = ({ color, setColor }: ColorPickerProps) => {
return (
<div className="flex flex-col space-y-2 bg-base-100 p-2 rounded-xl w-min">
<section className="w-52">
<HexColorPicker color={color} onChange={setColor} />
</section>
<div className="flex space-x-2 w-52">
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
<label className="input input-bordered flex items-center gap-2 input-sm w-full grow">
<Icon path={mdiPound} className="size-4 opacity-70" />
<HexColorInput color={color} className="w-16" />
</label>
<button
type="button"
className="btn btn-square btn-sm"
onClick={async () => {
try {
await navigator.clipboard.writeText(color)
toast.success('Copied color to clipboard')
} catch {
toast.error(`Failed to copy, please try again`)
}
}}
>
<Icon path={mdiContentCopy} className="size-4" />
</button>
<button
type="button"
className="btn btn-square btn-sm "
onClick={async () => {
try {
const clipboardText = await navigator.clipboard.readText()
const hexColorRegex =
/^#(?:(?:[\da-f]{3}){1,2}|(?:[\da-f]{4}){1,2})$/i
const ColorPicker = ({ color, setColor }: ColorPickerProps) => (
<div className="flex flex-col space-y-2 bg-base-100 p-2 rounded-xl">
<HexColorPicker color={color} onChange={setColor} />
<div className="flex space-x-2">
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
<label className="input input-bordered flex items-center gap-2 input-sm grow">
<Icon path={mdiPound} className="size-4 opacity-70" />
<HexColorInput color={color} className="w-16" />
</label>
<button
type="button"
className="btn btn-square btn-sm"
onClick={async () => {
try {
await navigator.clipboard.writeText(color)
toast.success('Copied color to clipboard')
} catch {
toast.error(`Failed to copy, please try again`)
}
}}
>
<Icon path={mdiContentCopy} className="size-4" />
</button>
<button
type="button"
className="btn btn-square btn-sm"
onClick={async () => {
try {
const clipboardText = await navigator.clipboard.readText()
const hexColorRegex =
/^#(?:(?:[\da-f]{3}){1,2}|(?:[\da-f]{4}){1,2})$/i
if (!hexColorRegex.test(clipboardText))
toast.error(`Text is not a valid hex color`)
else setColor(clipboardText)
} catch {
toast.error(`Failed to paste, please try again`)
}
}}
>
<Icon path={mdiContentPaste} className="size-4" />
</button>
</div>
if (!hexColorRegex.test(clipboardText))
toast.error(`Text is not a valid hex color`)
else setColor(clipboardText)
} catch {
toast.error(`Failed to paste, please try again`)
}
}}
>
<Icon path={mdiContentPaste} className="size-4" />
</button>
</div>
)
}
</div>
)
export default ColorPicker

View File

@ -1,19 +1,37 @@
import { useState } from 'react'
import { mdiAlertOutline } from '@mdi/js'
import Icon from '@mdi/react'
interface PDFProps {
url: string
form?: boolean
}
const PDF = ({ url, form = false }: PDFProps) => (
<embed
src={url}
title="PDF"
type="application/pdf"
style={{
width: 'calc(100vw - 1rem)',
height: `calc(100vh - ${form ? '8.5rem' : '6rem'})`,
}}
className="rounded-xl"
/>
)
const PDF = ({ url, form = false }: PDFProps) => {
const [error, setError] = useState<boolean>(false)
return error ? (
<div role="alert" className="alert alert-warning">
<Icon path={mdiAlertOutline} className="size-7" />
<span>
Could not load PDF, this is common in in-app browsers, try opening this
page in a regular browser
</span>
</div>
) : (
<iframe
src={url}
title="PDF"
style={{
width: 'calc(100vw - 1rem)',
height: `calc(100vh - ${form ? '8.5rem' : '6rem'})`,
}}
className="rounded-xl"
onError={() => setError(true)}
onLoad={() => setError(false)}
/>
)
}
export default PDF

View File

@ -127,14 +127,13 @@ const PortraitForm = ({ portrait }: PortraitFormProps) => {
)
else
return (
<div className="mx-auto w-fit space-y-2">
<div className="mx-auto max-w-prose space-y-2">
{!fileId ? (
<>
<Uploader
onComplete={onUploadComplete}
width="22rem"
height="34.5rem"
className="flex justify-center"
width="auto"
height="30rem"
/>
<p className="text-center">
High quality, 4:5 aspect ratio image recommended

View File

@ -46,29 +46,28 @@ const AdminProject = ({ project }: Props) => {
}
return (
<div className="flex w-full justify-center">
<div className="flex justify-center">
<div>
<div className="overflow-hidden overflow-x-auto rounded-xl bg-base-100">
<table className="table">
<thead className="bg-base-200 font-syne">
<tr>
<th className="w-0">
<th colSpan={2}>
Project {project.id}: {project.title}
</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
<tr>
<th>ID</th>
<th className="text-right">ID</th>
<td>{project.id}</td>
</tr>
<tr>
<th>Title</th>
<th className="text-right">Title</th>
<td>{project.title}</td>
</tr>
<tr>
<th>Description</th>
<th className="text-right">Description</th>
<td>
<article className="prose">
{parseHtml(project.description)}
@ -76,11 +75,11 @@ const AdminProject = ({ project }: Props) => {
</td>
</tr>
<tr>
<th>Date</th>
<th className="text-right">Date</th>
<td>{timeTag(project.date)}</td>
</tr>
<tr>
<th>Images</th>
<th className="text-right">Images</th>
<td>
<div className="flex flex-wrap gap-2">
{project.images.map((image, i) => (
@ -98,7 +97,7 @@ const AdminProject = ({ project }: Props) => {
</td>
</tr>
<tr>
<th>Tags</th>
<th className="text-right">Tags</th>
<td>
<div className="flex flex-wrap gap-2">
{project.tags.map((tag, i) => (
@ -120,19 +119,30 @@ const AdminProject = ({ project }: Props) => {
</td>
</tr>
<tr>
<th>Links</th>
<th className="text-right">Links</th>
<td>
<div className="flex flex-wrap gap-2">
{project.links.map((link, i) => (
<a
href={link}
target="_blank"
className="badge badge-ghost text-nowrap"
key={i}
rel="noreferrer"
>
{link}
</a>
<>
<a
href={link}
target="_blank"
className="hidden sm:flex badge badge-ghost text-nowrap"
key={i}
rel="noreferrer"
>
{link}
</a>
<a
href={link}
target="_blank"
className="btn btn-sm btn-square sm:hidden"
key={i}
rel="noreferrer"
>
{i + 1}
</a>
</>
))}
</div>
</td>

View File

@ -73,12 +73,12 @@ export const Success = ({ project }: CellSuccessProps<EditProjectById>) => {
) => updateProject({ variables: { id, input } })
return (
<div className="flex w-full justify-center">
<div className="overflow-hidden overflow-x-auto rounded-xl bg-base-100">
<table className="table w-80">
<div className="flex mx-auto max-w-prose justify-center">
<div className="overflow-hidden w-full overflow-x-auto rounded-xl bg-base-100">
<table className="table">
<thead className="bg-base-200 font-syne">
<tr>
<th className="w-0">Edit Project {project.id}</th>
<th>Edit Project {project.id}</th>
</tr>
</thead>
<tbody>

View File

@ -38,9 +38,9 @@ const NewProject = () => {
createProject({ variables: { input } })
return (
<div className="flex w-full justify-center">
<div className="overflow-hidden overflow-x-auto rounded-xl bg-base-100">
<table className="table w-80">
<div className="flex mx-auto max-w-prose justify-center">
<div className="overflow-hidden w-full overflow-x-auto rounded-xl bg-base-100">
<table className="table">
<thead className="bg-base-200 font-syne">
<tr>
<th>New Project</th>

View File

@ -119,7 +119,7 @@ const ProjectForm = (props: ProjectFormProps) => {
<Form<FormProject>
onSubmit={onSubmit}
error={props.error}
className="space-y-2 w-80"
className="space-y-2"
>
<Label name="title" className="form-control w-full">
<Label
@ -261,9 +261,8 @@ const ProjectForm = (props: ProjectFormProps) => {
{appendUploader && (
<Uploader
onComplete={onUploadComplete}
width="20rem"
width="auto"
height="30rem"
className="flex justify-center"
maxFiles={10}
disabled={props.loading}
/>
@ -272,9 +271,8 @@ const ProjectForm = (props: ProjectFormProps) => {
) : (
<Uploader
onComplete={onUploadComplete}
width="20rem"
width="auto"
height="30rem"
className="flex justify-center pt-3"
maxFiles={10}
disabled={props.loading}
/>

View File

@ -123,14 +123,13 @@ const ResumeForm = ({ resume }: ResumeFormProps) => {
)
else
return (
<div className="mx-auto w-fit space-y-2">
<div className="mx-auto max-w-prose space-y-2">
{!fileId ? (
<>
<Uploader
onComplete={onUploadComplete}
width="22rem"
height="11.5rem"
className="flex justify-center"
width="auto"
height="30rem"
type="pdf"
/>
</>

View File

@ -43,120 +43,122 @@ const RichTextEditor = ({ editor }: RichTextEditorProps) => {
return (
<div className="flex flex-col gap-2">
<div className="flex flex-wrap gap-2 justify-center">
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('link') ? 'btn-primary' : ''}`}
onClick={setLink}
>
<Icon path={mdiLinkVariant} className="size-5" />
</button>
<button
type="button"
className="btn btn-sm btn-square"
onClick={() => editor.chain().focus().unsetLink().run()}
disabled={!editor.isActive('link')}
>
<Icon path={mdiLinkVariantOff} className="size-5" />
</button>
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('bulletList') ? 'btn-primary' : ''}`}
onClick={() => editor.chain().focus().toggleBulletList().run()}
>
<Icon path={mdiFormatListBulleted} className="size-5" />
</button>
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('orderedList') ? 'btn-primary' : ''}`}
onClick={() => editor.chain().focus().toggleOrderedList().run()}
>
<Icon path={mdiFormatListNumbered} className="size-5" />
</button>
<button
type="button"
className="btn btn-sm btn-square"
onClick={() => editor.chain().focus().unsetAllMarks().run()}
>
<Icon path={mdiFormatClear} className="size-5" />
</button>
<button
type="button"
className="btn btn-sm btn-square"
onClick={() => editor.chain().focus().undo().run()}
disabled={!editor.can().chain().focus().undo().run()}
>
<Icon path={mdiUndoVariant} className="size-5" />
</button>
<button
type="button"
className="btn btn-sm btn-square"
onClick={() => editor.chain().focus().redo().run()}
disabled={!editor.can().chain().focus().redo().run()}
>
<Icon path={mdiRedoVariant} className="size-5" />
</button>
</div>
<div className="flex flex-wrap gap-2 justify-center">
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('bold') ? 'btn-primary' : ''}`}
onClick={() => editor.chain().focus().toggleBold().run()}
disabled={!editor.can().chain().focus().toggleBold().run()}
>
<Icon path={mdiFormatBold} className="size-5" />
</button>
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('italic') ? 'btn-primary' : ''}`}
onClick={() => editor.chain().focus().toggleItalic().run()}
disabled={!editor.can().chain().focus().toggleItalic().run()}
>
<Icon path={mdiFormatItalic} className="size-5" />
</button>
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('underline') ? 'btn-primary' : ''}`}
onClick={() => editor.chain().focus().toggleUnderline().run()}
disabled={!editor.can().chain().focus().toggleUnderline().run()}
>
<Icon path={mdiFormatUnderline} className="size-5" />
</button>
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('static') ? 'btn-primary' : ''}`}
onClick={() => editor.chain().focus().toggleStrike().run()}
disabled={!editor.can().chain().focus().toggleStrike().run()}
>
<Icon path={mdiFormatStrikethrough} className="size-5" />
</button>
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('code') ? 'btn-primary' : ''}`}
onClick={() => editor.chain().focus().toggleCode().run()}
disabled={!editor.can().chain().focus().toggleCode().run()}
>
<Icon path={mdiXml} className="size-5" />
</button>
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('codeBlock') ? 'btn-primary' : ''}`}
onClick={() => editor.chain().focus().toggleCodeBlock().run()}
disabled={!editor.can().chain().focus().toggleCodeBlock().run()}
>
<Icon path={mdiCodeBracesBox} className="size-5" />
</button>
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('blockquote') ? 'btn-primary' : ''}`}
onClick={() => editor.chain().focus().toggleBlockquote().run()}
>
<Icon path={mdiFormatQuoteClose} className="size-5" />
</button>
<div className="flex justify-center flex-wrap gap-2">
<div className="flex gap-2 h-min justify-center">
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('link') ? 'btn-primary' : ''}`}
onClick={setLink}
>
<Icon path={mdiLinkVariant} className="size-5" />
</button>
<button
type="button"
className="btn btn-sm btn-square"
onClick={() => editor.chain().focus().unsetLink().run()}
disabled={!editor.isActive('link')}
>
<Icon path={mdiLinkVariantOff} className="size-5" />
</button>
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('bulletList') ? 'btn-primary' : ''}`}
onClick={() => editor.chain().focus().toggleBulletList().run()}
>
<Icon path={mdiFormatListBulleted} className="size-5" />
</button>
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('orderedList') ? 'btn-primary' : ''}`}
onClick={() => editor.chain().focus().toggleOrderedList().run()}
>
<Icon path={mdiFormatListNumbered} className="size-5" />
</button>
<button
type="button"
className="btn btn-sm btn-square"
onClick={() => editor.chain().focus().unsetAllMarks().run()}
>
<Icon path={mdiFormatClear} className="size-5" />
</button>
<button
type="button"
className="btn btn-sm btn-square"
onClick={() => editor.chain().focus().undo().run()}
disabled={!editor.can().chain().focus().undo().run()}
>
<Icon path={mdiUndoVariant} className="size-5" />
</button>
<button
type="button"
className="btn btn-sm btn-square"
onClick={() => editor.chain().focus().redo().run()}
disabled={!editor.can().chain().focus().redo().run()}
>
<Icon path={mdiRedoVariant} className="size-5" />
</button>
</div>
<div className="flex gap-2 h-min justify-center">
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('bold') ? 'btn-primary' : ''}`}
onClick={() => editor.chain().focus().toggleBold().run()}
disabled={!editor.can().chain().focus().toggleBold().run()}
>
<Icon path={mdiFormatBold} className="size-5" />
</button>
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('italic') ? 'btn-primary' : ''}`}
onClick={() => editor.chain().focus().toggleItalic().run()}
disabled={!editor.can().chain().focus().toggleItalic().run()}
>
<Icon path={mdiFormatItalic} className="size-5" />
</button>
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('underline') ? 'btn-primary' : ''}`}
onClick={() => editor.chain().focus().toggleUnderline().run()}
disabled={!editor.can().chain().focus().toggleUnderline().run()}
>
<Icon path={mdiFormatUnderline} className="size-5" />
</button>
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('static') ? 'btn-primary' : ''}`}
onClick={() => editor.chain().focus().toggleStrike().run()}
disabled={!editor.can().chain().focus().toggleStrike().run()}
>
<Icon path={mdiFormatStrikethrough} className="size-5" />
</button>
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('code') ? 'btn-primary' : ''}`}
onClick={() => editor.chain().focus().toggleCode().run()}
disabled={!editor.can().chain().focus().toggleCode().run()}
>
<Icon path={mdiXml} className="size-5" />
</button>
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('codeBlock') ? 'btn-primary' : ''}`}
onClick={() => editor.chain().focus().toggleCodeBlock().run()}
disabled={!editor.can().chain().focus().toggleCodeBlock().run()}
>
<Icon path={mdiCodeBracesBox} className="size-5" />
</button>
<button
type="button"
className={`btn btn-sm btn-square ${editor.isActive('blockquote') ? 'btn-primary' : ''}`}
onClick={() => editor.chain().focus().toggleBlockquote().run()}
>
<Icon path={mdiFormatQuoteClose} className="size-5" />
</button>
</div>
</div>
<EditorContent
editor={editor}
className="textarea textarea-bordered font-normal prose"
className="textarea textarea-bordered font-normal prose max-w-full"
/>
</div>
)

View File

@ -71,9 +71,9 @@ export const Success = ({ social }: CellSuccessProps<EditSocialById>) => {
}
return (
<div className="flex w-full justify-center">
<div className="overflow-hidden overflow-x-auto rounded-xl bg-base-100">
<table className="table w-80">
<div className="flex mx-auto max-w-80 sm:max-w-sm md:max-w-md lg:max-w-lg xl:max-w-xl 2xl:max-w-2xl justify-center">
<div className="overflow-hidden w-full overflow-x-auto rounded-xl bg-base-100">
<table className="table">
<thead className="bg-base-200 font-syne">
<tr>
<th className="w-0">Edit Social {social.id}</th>

View File

@ -38,9 +38,9 @@ const NewSocial = () => {
createSocial({ variables: { input } })
return (
<div className="flex w-full justify-center">
<div className="overflow-hidden overflow-x-auto rounded-xl bg-base-100">
<table className="table w-80">
<div className="flex mx-auto max-w-80 sm:max-w-sm md:max-w-md lg:max-w-lg xl:max-w-xl 2xl:max-w-2xl justify-center">
<div className="overflow-hidden w-full overflow-x-auto rounded-xl bg-base-100">
<table className="table">
<thead className="bg-base-200 font-syne">
<tr>
<th>New Social</th>

View File

@ -44,31 +44,32 @@ const Social = ({ social }: Props) => {
}
return (
<div className="flex w-full justify-center">
<div className="w-80">
<div className="flex mx-auto max-w-80 sm:max-w-sm md:max-w-md lg:max-w-lg xl:max-w-xl 2xl:max-w-2xl justify-center">
<div className="w-full">
<div className="overflow-hidden overflow-x-auto rounded-xl bg-base-100">
<table className="table">
<thead className="bg-base-200 font-syne">
<th className="w-0">
Social {social.id}: {social.name}
</th>
<th>&nbsp;</th>
<tr>
<th colSpan={2}>
Social {social.id}: {social.name}
</th>
</tr>
</thead>
<tbody>
<tr>
<th>ID</th>
<th className="text-right">ID</th>
<td>{social.id}</td>
</tr>
<tr>
<th>Type</th>
<th className="text-right">Type</th>
<td>{getLogoComponent(social.type)}</td>
</tr>
<tr>
<th>Name</th>
<th className="text-right">Name</th>
<td>{social.name}</td>
</tr>
<tr>
<th>Username</th>
<th className="text-right">Username</th>
<td>{social.username}</td>
</tr>
</tbody>

View File

@ -33,6 +33,6 @@ export const Failure = ({
export const Success = ({
social,
}: CellSuccessProps<FindSocialById, FindSocialByIdVariables>) => {
return <Social social={social} />
}
}: CellSuccessProps<FindSocialById, FindSocialByIdVariables>) => (
<Social social={social} />
)

View File

@ -99,7 +99,7 @@ const SocialForm = (props: SocialFormProps) => {
<Form<FormSocial>
onSubmit={onSubmit}
error={props.error}
className="h-128 max-w-80 space-y-2"
className="h-128 space-y-2"
>
<Label name="name" className="form-control w-full">
<Label

View File

@ -59,8 +59,8 @@ export const Success = ({ tag }: CellSuccessProps<EditTagById>) => {
updateTag({ variables: { id, input } })
return (
<div className="flex w-full justify-center">
<div className="overflow-hidden overflow-x-auto rounded-xl bg-base-100">
<div className="flex mx-auto max-w-80 sm:max-w-sm md:max-w-md lg:max-w-lg xl:max-w-xl 2xl:max-w-2xl justify-center">
<div className="overflow-hidden w-full overflow-x-auto rounded-xl bg-base-100">
<table className="table">
<thead className="bg-base-200 font-syne">
<tr>

View File

@ -34,8 +34,8 @@ const NewTag = () => {
const onSave = (input: CreateTagInput) => createTag({ variables: { input } })
return (
<div className="flex w-full justify-center">
<div className="overflow-hidden overflow-x-auto rounded-xl bg-base-100">
<div className="flex mx-auto max-w-80 sm:max-w-sm md:max-w-md lg:max-w-lg xl:max-w-xl 2xl:max-w-2xl justify-center">
<div className="overflow-hidden w-full overflow-x-auto rounded-xl bg-base-100">
<table className="table">
<thead className="bg-base-200 font-syne">
<tr>

View File

@ -42,8 +42,8 @@ const Tag = ({ tag }: Props) => {
}
return (
<div className="flex w-full justify-center">
<div className="w-80">
<div className="flex mx-auto max-w-80 sm:max-w-sm md:max-w-md lg:max-w-lg xl:max-w-xl 2xl:max-w-2xl justify-center">
<div className="w-full">
<div className="overflow-hidden overflow-x-auto rounded-xl bg-base-100">
<table className="table">
<thead className="bg-base-200 font-syne">
@ -54,15 +54,15 @@ const Tag = ({ tag }: Props) => {
</thead>
<tbody>
<tr>
<th>ID</th>
<th className="text-right">ID</th>
<td>{tag.id}</td>
</tr>
<tr>
<th>Tag</th>
<th className="text-right">Tag</th>
<td>{tag.tag}</td>
</tr>
<tr>
<th>Color</th>
<th className="text-right">Color</th>
<td>
<div
className="badge whitespace-nowrap"

View File

@ -35,7 +35,7 @@ const TagForm = (props: TagFormProps) => {
<Form<FormTag>
onSubmit={onSubmit}
error={props.error}
className="max-w-56 space-y-2"
className="space-y-2"
>
<Label name="tag" className="form-control w-full">
<Label

View File

@ -50,7 +50,7 @@ const TagsList = ({ tags }: FindTags) => {
<th className="w-0">&nbsp;</th>
</tr>
</thead>
<tbody>
<tbody className="overflow-y-scroll">
{tags.map((tag, i) => {
const actionButtons = (
<>

View File

@ -26,7 +26,7 @@ const TagsSelector = ({
}, [selectedTags, _tags])
return (
<div className="w-80 space-y-2">
<div className="space-y-2">
{tags.length > 0 && (
<>
<p className="font-semibold">Tags</p>

View File

@ -29,22 +29,24 @@ export const Failure = ({
}: CellFailureProps<AdminTitlesQueryVariables>) => <CellFailure error={error} />
export const Success = ({ titles }: CellSuccessProps<AdminTitlesQuery>) => (
<div className="flex w-full justify-center">
<div className="overflow-hidden overflow-x-auto rounded-xl bg-base-100">
<table className="table w-80">
<thead className="bg-base-200 font-syne">
<tr>
<th className="w-0">Titles</th>
</tr>
</thead>
<tbody>
<tr>
<th>
<TitlesForm titles={titles} />
</th>
</tr>
</tbody>
</table>
<div className="flex mx-auto max-w-80 sm:max-w-sm md:max-w-md lg:max-w-lg xl:max-w-xl 2xl:max-w-2xl justify-center">
<div className="w-full">
<div className="overflow-hidden overflow-x-auto rounded-xl bg-base-100">
<table className="table">
<thead className="bg-base-200 font-syne">
<tr>
<th className="w-0">Titles</th>
</tr>
</thead>
<tbody>
<tr>
<th>
<TitlesForm titles={titles} />
</th>
</tr>
</tbody>
</table>
</div>
</div>
</div>
)

View File

@ -55,9 +55,9 @@ const TitlesForm = ({ titles }: TitlesFormProps) => {
})
return (
<Form onSubmit={onSubmit} className="max-w-80 space-y-2">
<Form onSubmit={onSubmit} className="space-y-2">
<p className="text-center opacity-70">
The first one gets displayed for longer
The first title gets displayed for longer
</p>
{Array.from({ length: MAX_TITLES }).map((_, i) => (
<Label key={i} name={`title${i}`} className="form-control w-full">

View File

@ -23,3 +23,7 @@
.ProseMirror:focus {
outline: none;
}
.w-full .react-colorful {
width: auto;
}