feat: support children in confirmation modal

This commit is contained in:
Aarnav Tale 2024-03-30 18:42:49 -04:00
parent b146e4c3a8
commit 1d9f4553eb
No known key found for this signature in database
2 changed files with 35 additions and 48 deletions

View File

@ -1,7 +1,7 @@
import { Dialog, Transition } from '@headlessui/react'
import { XMarkIcon } from '@heroicons/react/24/outline'
import clsx from 'clsx'
import { Fragment, type SetStateAction, useState } from 'react'
import { Fragment, type ReactNode, type SetStateAction, useState } from 'react'
import Button from './Button'
@ -10,6 +10,7 @@ type HookParameters = {
description?: string;
buttonText?: string;
variant?: 'danger' | 'confirm';
children?: ReactNode;
// Optional because the button submits
onConfirm?: () => void | Promise<void>;
@ -100,11 +101,17 @@ function Modal({ parameters, isOpen, setIsOpen }: Properties) {
{parameters.description}
</Dialog.Description>
) : undefined}
{parameters.children ? (
<div className='mt-12 w-full'>
{parameters.children}
</div>
) : undefined}
<Button
variant='emphasized'
type='submit'
className={clsx(
'w-full mt-12',
'w-full',
parameters.children ? 'mt-4' : 'mt-12',
parameters.variant === 'danger'
? 'bg-red-800 dark:bg-red-500 focus:ring-red-500 dark:focus:ring-red-500'
: ''

View File

@ -7,6 +7,7 @@ import { useState } from 'react'
import Button from '~/components/Button'
import Code from '~/components/Code'
import Input from '~/components/Input'
import useModal from '~/components/Modal'
import Spinner from '~/components/Spinner'
type Properties = {
@ -16,9 +17,31 @@ type Properties = {
}
export default function Modal({ name, disabled }: Properties) {
const [isOpen, setIsOpen] = useState(false)
const [newName, setNewName] = useState(name)
const fetcher = useFetcher()
const { Modal, open } = useModal({
title: 'Rename Tailnet',
description: 'Keep in mind that changing this can lead to all sorts of unexpected behavior and may break existing devices in your tailnet.',
buttonText: 'Rename',
children: (
<Input
type='text'
className='font-mono mt-4'
value={newName}
onChange={event => {
setNewName(event.target.value)
}}
/>
),
onConfirm: () => {
fetcher.submit({
'dns_config.base_domain': newName
}, {
method: 'PATCH',
encType: 'application/json'
})
}
})
return (
<div className='flex flex-col w-2/3'>
@ -47,7 +70,7 @@ export default function Modal({ name, disabled }: Properties) {
className='text-sm w-fit'
disabled={disabled}
onClick={() => {
setIsOpen(true)
open()
}}
>
{fetcher.state === 'idle' ? undefined : (
@ -55,50 +78,7 @@ export default function Modal({ name, disabled }: Properties) {
)}
Rename Tailnet...
</Button>
<Dialog
className='relative z-50'
open={isOpen} onClose={() => {
setIsOpen(false)
}}
>
<div className='fixed inset-0 bg-black/30' aria-hidden='true'/>
<div className='fixed inset-0 flex w-screen items-center justify-center'>
<Dialog.Panel className='bg-white rounded-lg p-4 w-full max-w-md dark:bg-zinc-800'>
<Dialog.Title className='text-lg font-bold'>
Rename {name}
</Dialog.Title>
<Dialog.Description className='text-gray-500 dark:text-gray-400'>
Keep in mind that changing this can lead to all sorts
of unexpected behavior and may break existing devices
in your tailnet.
</Dialog.Description>
<Input
type='text'
className='font-mono mt-4'
value={newName}
onChange={event => {
setNewName(event.target.value)
}}
/>
<button
type='submit'
className='rounded-lg py-2 bg-gray-800 text-white w-full mt-2'
onClick={() => {
fetcher.submit({
'dns_config.base_domain': newName
}, {
method: 'PATCH',
encType: 'application/json'
})
setIsOpen(false)
}}
>
Rename
</button>
</Dialog.Panel>
</div>
</Dialog>
{Modal}
</div>
)
}