Created
June 11, 2022 22:22
-
-
Save 28development/4e651e53cd0af432ef2ebd4850629612 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { gql, useMutation } from '@apollo/client'; | |
import dynamic from 'next/dynamic'; | |
import { array, object, string } from 'zod'; | |
import { Form, useZodForm } from '../ui/Form'; | |
import Modal from '../ui/Modal'; | |
import TagSelection from './TagSelection'; | |
import TechSelection from './TechSelection'; | |
interface Props { | |
open: boolean; | |
setOpen: (open: boolean) => void; | |
} | |
const newSnippetSchema = object({ | |
title: string().min(1), | |
description: string().min(1), | |
tags: array(string()), | |
technologies: array(string()), | |
content: string().min(1), | |
}); | |
const Editor = dynamic(() => import('~/components/Editor'), { ssr: false }); | |
export default function CreateSnippetModal(props: Props) { | |
const { open, setOpen } = props; | |
const [createSnippet] = useMutation( | |
gql` | |
mutation CreateSnippetMutation($input: CreateSnippetInput!) { | |
createSnippet(input: $input) { | |
id | |
title | |
description | |
content | |
tags { | |
id | |
name | |
} | |
technologies { | |
id | |
name | |
} | |
} | |
} | |
`, | |
); | |
const form = useZodForm({ | |
schema: newSnippetSchema, | |
}); | |
return ( | |
<Form | |
form={form} | |
onSubmit={({ title, description, tags, techs, content }) => | |
createSnippet({ | |
variables: { | |
input: { | |
title, | |
description, | |
tags, | |
techs, | |
content, | |
}, | |
}, | |
}) | |
} | |
> | |
<Modal | |
title="Create Snippet" | |
description="Create a new snippet" | |
open={open} | |
setOpen={setOpen} | |
size="xl" | |
actions={ | |
<> | |
<button | |
type="submit" | |
className="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-cyan-600 text-base font-medium text-white hover:bg-cyan-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-cyan-500 sm:ml-3 sm:w-auto sm:text-sm" | |
> | |
Create | |
</button> | |
<button | |
type="button" | |
className="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-cyan-500 sm:mt-0 sm:w-auto sm:text-sm" | |
onClick={() => setOpen(false)} | |
> | |
Cancel | |
</button> | |
</> | |
} | |
> | |
<> | |
<div className="flex"> | |
<div className="flex-1 w-full sm:w-1/2"> | |
<TechSelection {...form.register('technologies')} /> | |
</div> | |
<div className="flex-1 w-full sm:w-1/2"> | |
<TagSelection {...form.register('tags')} /> | |
</div> | |
</div> | |
<div className="py-2"> | |
<Editor {...form.register('content')} /> | |
</div> | |
</> | |
</Modal> | |
</Form> | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Fragment, useRef } from 'react'; | |
import { Dialog, Transition } from '@headlessui/react'; | |
import clsx from 'clsx'; | |
interface Props { | |
open: boolean; | |
setOpen: (open: boolean) => void; | |
title: string; | |
description: string; | |
icon?: JSX.Element; | |
children?: JSX.Element; | |
actions?: JSX.Element; | |
size: 'sm' | 'md' | 'lg' | 'xl'; | |
} | |
export default function Modal(props: Props) { | |
const { open, setOpen, title, description, icon, children, actions, size } = | |
props; | |
const cancelButtonRef = useRef(null); | |
return ( | |
<Transition.Root show={open} as={Fragment}> | |
<Dialog | |
as="div" | |
className="fixed z-10 inset-0 overflow-y-auto" | |
initialFocus={cancelButtonRef} | |
onClose={setOpen} | |
> | |
<div className="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"> | |
<Transition.Child | |
as={Fragment} | |
enter="ease-out duration-300" | |
enterFrom="opacity-0" | |
enterTo="opacity-100" | |
leave="ease-in duration-200" | |
leaveFrom="opacity-100" | |
leaveTo="opacity-0" | |
> | |
<Dialog.Overlay className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" /> | |
</Transition.Child> | |
{/* This element is to trick the browser into centering the modal contents. */} | |
<span | |
className="hidden sm:inline-block sm:align-middle sm:h-screen" | |
aria-hidden="true" | |
> | |
​ | |
</span> | |
<Transition.Child | |
as={Fragment} | |
enter="ease-out duration-300" | |
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" | |
enterTo="opacity-100 translate-y-0 sm:scale-100" | |
leave="ease-in duration-200" | |
leaveFrom="opacity-100 translate-y-0 sm:scale-100" | |
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" | |
> | |
<div | |
className={clsx( | |
size === 'sm' && 'md:w-64', | |
size === 'md' && 'md:w-1/2', | |
size === 'lg' && 'md:w-6/12', | |
size === 'xl' && 'md:w-10/12', | |
'w-11/12 shadow-none backdrop-blur-md bg-white/80 relative inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden transform transition-all sm:my-8 sm:align-middle sm:p-6', | |
)} | |
> | |
<div className="sm:flex sm:items-start"> | |
{icon && ( | |
<div className="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-cyan-100 sm:mx-0 sm:h-10 sm:w-10"> | |
{icon} | |
</div> | |
)} | |
<div className="mt-3 text-center sm:mt-0 sm:text-left w-full"> | |
<Dialog.Title | |
as="h3" | |
className="text-lg leading-6 font-medium text-gray-900" | |
> | |
{title} | |
</Dialog.Title> | |
<div className="mt-2 flex flex-col"> | |
<p className="text-sm text-gray-500">{description}</p> | |
{children} | |
</div> | |
</div> | |
</div> | |
<div className="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse"> | |
{actions} | |
</div> | |
</div> | |
</Transition.Child> | |
</div> | |
</Dialog> | |
</Transition.Root> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment