chore: [incomplete] trying to use checkbox without the dialog

skill issue
probably
This commit is contained in:
Ephraim Atta-Duncan
2024-04-09 21:58:16 +00:00
parent 0f0f198b44
commit aa951c1608
3 changed files with 91 additions and 86 deletions

View File

@ -1,10 +1,13 @@
'use client'; 'use client';
import { useEffect, useState, useTransition } from 'react'; import { useState, useTransition } from 'react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { zodResolver } from '@hookform/resolvers/zod';
import { Loader } from 'lucide-react'; import { Loader } from 'lucide-react';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
import { DO_NOT_INVALIDATE_QUERY_ON_MUTATION } from '@documenso/lib/constants/trpc'; import { DO_NOT_INVALIDATE_QUERY_ON_MUTATION } from '@documenso/lib/constants/trpc';
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error'; import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
@ -12,12 +15,10 @@ import type { TRecipientActionAuth } from '@documenso/lib/types/document-auth';
import type { Recipient } from '@documenso/prisma/client'; import type { Recipient } from '@documenso/prisma/client';
import type { FieldWithSignature } from '@documenso/prisma/types/field-with-signature'; import type { FieldWithSignature } from '@documenso/prisma/types/field-with-signature';
import { trpc } from '@documenso/trpc/react'; import { trpc } from '@documenso/trpc/react';
import { Button } from '@documenso/ui/primitives/button';
import { Checkbox } from '@documenso/ui/primitives/checkbox'; import { Checkbox } from '@documenso/ui/primitives/checkbox';
import { Dialog, DialogContent, DialogFooter, DialogTitle } from '@documenso/ui/primitives/dialog'; import { Form, FormControl, FormField } from '@documenso/ui/primitives/form/form';
import { useToast } from '@documenso/ui/primitives/use-toast'; import { useToast } from '@documenso/ui/primitives/use-toast';
import { useRequiredDocumentAuthContext } from './document-auth-provider';
import { SigningFieldContainer } from './signing-field-container'; import { SigningFieldContainer } from './signing-field-container';
export type CheckboxFieldProps = { export type CheckboxFieldProps = {
@ -25,12 +26,16 @@ export type CheckboxFieldProps = {
recipient: Recipient; recipient: Recipient;
}; };
const CheckBoxSchema = z.object({
check: z.boolean().default(false).optional(),
});
export const CheckboxField = ({ field, recipient }: CheckboxFieldProps) => { export const CheckboxField = ({ field, recipient }: CheckboxFieldProps) => {
const router = useRouter(); const router = useRouter();
const { toast } = useToast(); const { toast } = useToast();
const { executeActionAuthProcedure } = useRequiredDocumentAuthContext(); // const { executeActionAuthProcedure } = useRequiredDocumentAuthContext();
const [isPending, startTransition] = useTransition(); const [isPending, startTransition] = useTransition();
@ -44,30 +49,17 @@ export const CheckboxField = ({ field, recipient }: CheckboxFieldProps) => {
const isLoading = isSignFieldWithTokenLoading || isRemoveSignedFieldWithTokenLoading || isPending; const isLoading = isSignFieldWithTokenLoading || isRemoveSignedFieldWithTokenLoading || isPending;
const [showCustomTextModal, setShowCustomTextModal] = useState(false);
const [localText, setLocalCustomText] = useState(''); const [localText, setLocalCustomText] = useState('');
useEffect(() => { const form = useForm<z.infer<typeof CheckBoxSchema>>({
if (!showCustomTextModal) { resolver: zodResolver(CheckBoxSchema),
setLocalCustomText(''); defaultValues: {
} check: true,
}, [showCustomTextModal]); },
/**
* When the user clicks the sign button in the dialog where they enter the text field.
*/
const onDialogSignClick = () => {
setShowCustomTextModal(false);
void executeActionAuthProcedure({
onReauthFormSubmit: async (authOptions) => await onSign(authOptions),
actionTarget: field.type,
}); });
};
const onPreSign = () => { const onPreSign = () => {
if (!localText) { if (!localText) {
setShowCustomTextModal(true);
return false; return false;
} }
@ -127,13 +119,18 @@ export const CheckboxField = ({ field, recipient }: CheckboxFieldProps) => {
} }
}; };
const onSubmit = (data: z.infer<typeof CheckBoxSchema>) => {
console.log(data);
};
return ( return (
<SigningFieldContainer <SigningFieldContainer
field={field} field={field}
onPreSign={onPreSign} onPreSign={onPreSign}
onSign={onSign} onSign={onSign}
onRemove={onRemove} onRemove={onRemove}
type="Signature" type="Checkbox"
raw={true}
> >
{isLoading && ( {isLoading && (
<div className="bg-background absolute inset-0 flex items-center justify-center rounded-md"> <div className="bg-background absolute inset-0 flex items-center justify-center rounded-md">
@ -142,54 +139,37 @@ export const CheckboxField = ({ field, recipient }: CheckboxFieldProps) => {
)} )}
{!field.inserted && ( {!field.inserted && (
<p className="group-hover:text-primary text-muted-foreground text-lg duration-200"> // TODO: span with a box
Checkbox // <p className="group-hover:text-primary text-muted-foreground text-lg duration-200">
</p> // Checkbox
)} // </p>
{field.inserted && <p className="text-muted-foreground duration-200">{field.customText}</p>}
{/* TODO : Avoid the whole dialog thing */}
<Dialog open={showCustomTextModal} onOpenChange={setShowCustomTextModal}>
<DialogContent>
<DialogTitle>Check Field</DialogTitle>
<div className="mt-4 flex items-center space-x-2">
<Checkbox <Checkbox
id="checkbox-field" id={`field-${field.id}`}
onClick={() => {
console.log('clicked checkbox');
}}
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
setLocalCustomText(checked ? '✓' : '𐄂'); setLocalCustomText(checked ? '✓' : '𐄂');
}} }}
/> />
<label )}
htmlFor="checkbox-field"
className="font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Check Field
</label>
</div>
<DialogFooter> {field.inserted && <p className="text-muted-foreground duration-200">{field.customText}</p>}
<div className="mt-4 flex w-full flex-1 flex-nowrap gap-4">
<Button
type="button"
className="dark:bg-muted dark:hover:bg-muted/80 flex-1 bg-black/5 hover:bg-black/10"
variant="secondary"
onClick={() => {
setShowCustomTextModal(false);
setLocalCustomText('');
}}
>
Cancel
</Button>
<Button type="button" className="flex-1" onClick={() => onDialogSignClick()}> <Form {...form}>
Save Checkbox <form onSubmit={form.handleSubmit(onSubmit)}>
</Button> <FormField
</div> control={form.control}
</DialogFooter> name="check"
</DialogContent> render={({ field }) => (
</Dialog> <FormControl>
<Checkbox checked={field.value} onCheckedChange={field.onChange} />
</FormControl>
)}
/>
</form>
</Form>
</SigningFieldContainer> </SigningFieldContainer>
); );
}; };

View File

@ -35,8 +35,10 @@ export type SignatureFieldProps = {
*/ */
onSign?: (documentAuthValue?: TRecipientActionAuth) => Promise<void> | void; onSign?: (documentAuthValue?: TRecipientActionAuth) => Promise<void> | void;
onRemove?: () => Promise<void> | void; onRemove?: () => Promise<void> | void;
type?: 'Date' | 'Email' | 'Name' | 'Signature'; type?: 'Date' | 'Email' | 'Name' | 'Signature' | 'Checkbox';
tooltipText?: string | null; tooltipText?: string | null;
raw?: boolean;
}; };
export const SigningFieldContainer = ({ export const SigningFieldContainer = ({
@ -48,6 +50,7 @@ export const SigningFieldContainer = ({
children, children,
type, type,
tooltipText, tooltipText,
raw = false,
}: SignatureFieldProps) => { }: SignatureFieldProps) => {
const { executeActionAuthProcedure, isAuthRedirectRequired } = useRequiredDocumentAuthContext(); const { executeActionAuthProcedure, isAuthRedirectRequired } = useRequiredDocumentAuthContext();
@ -103,7 +106,7 @@ export const SigningFieldContainer = ({
}; };
return ( return (
<FieldRootContainer field={field}> <FieldRootContainer raw={raw} field={field}>
{!field.inserted && !loading && ( {!field.inserted && !loading && (
<button <button
type="submit" type="submit"

View File

@ -18,6 +18,7 @@ export type FieldRootContainerProps = {
export type FieldContainerPortalProps = { export type FieldContainerPortalProps = {
field: Field; field: Field;
className?: string; className?: string;
raw?: boolean;
children: React.ReactNode; children: React.ReactNode;
}; };
@ -44,7 +45,7 @@ export function FieldContainerPortal({
); );
} }
export function FieldRootContainer({ field, children }: FieldContainerPortalProps) { export function FieldRootContainer({ field, children, raw = false }: FieldContainerPortalProps) {
const [isValidating, setIsValidating] = useState(false); const [isValidating, setIsValidating] = useState(false);
const ref = React.useRef<HTMLDivElement>(null); const ref = React.useRef<HTMLDivElement>(null);
@ -71,6 +72,7 @@ export function FieldRootContainer({ field, children }: FieldContainerPortalProp
return ( return (
<FieldContainerPortal field={field}> <FieldContainerPortal field={field}>
{!raw && (
<Card <Card
id={`field-${field.id}`} id={`field-${field.id}`}
className={cn( className={cn(
@ -86,6 +88,26 @@ export function FieldRootContainer({ field, children }: FieldContainerPortalProp
{children} {children}
</CardContent> </CardContent>
</Card> </Card>
)}
{raw && (
<div
onClick={() => {
console.log('clickeddd');
}}
id={`field-${field.id}`}
className={cn(
'field-card-container bg-background relative z-20 h-full w-full transition-all',
{
'border-orange-300 ring-1 ring-orange-300': !field.inserted && isValidating,
},
)}
ref={ref}
data-inserted={field.inserted ? 'true' : 'false'}
>
{children}
</div>
)}
</FieldContainerPortal> </FieldContainerPortal>
); );
} }