Compare commits

...

1 Commits

Author SHA1 Message Date
986030cc38 chore: failed attempt at adding custom field labels
I have spent all day on it and for some reason, I can't figure it out
2024-02-18 16:01:03 +00:00
9 changed files with 101 additions and 26 deletions

View File

@ -20,6 +20,7 @@ export interface SetFieldsForDocumentOptions {
pageY: number;
pageWidth: number;
pageHeight: number;
label: string;
}[];
requestMetadata?: RequestMetadata;
}

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Field" ADD COLUMN "label" TEXT;

View File

@ -210,15 +210,15 @@ model DocumentData {
}
model DocumentMeta {
id String @id @default(cuid())
subject String?
message String?
timezone String? @default("Etc/UTC") @db.Text
password String?
dateFormat String? @default("yyyy-MM-dd hh:mm a") @db.Text
documentId Int @unique
document Document @relation(fields: [documentId], references: [id], onDelete: Cascade)
redirectUrl String?
id String @id @default(cuid())
subject String?
message String?
timezone String? @default("Etc/UTC") @db.Text
password String?
dateFormat String? @default("yyyy-MM-dd hh:mm a") @db.Text
documentId Int @unique
document Document @relation(fields: [documentId], references: [id], onDelete: Cascade)
redirectUrl String?
}
enum ReadStatus {
@ -283,6 +283,7 @@ model Field {
documentId Int?
templateId Int?
recipientId Int?
label String?
type FieldType
page Int
positionX Decimal @default(0)

View File

@ -33,6 +33,7 @@ export const fieldRouter = router({
pageY: field.pageY,
pageWidth: field.pageWidth,
pageHeight: field.pageHeight,
label: field.label,
})),
requestMetadata: extractNextApiRequestMetadata(ctx.req),
});

View File

@ -15,6 +15,7 @@ export const ZAddFieldsMutationSchema = z.object({
pageY: z.number().min(0),
pageWidth: z.number().min(0),
pageHeight: z.number().min(0),
label: z.string(),
}),
),
});

View File

@ -4,6 +4,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Caveat } from 'next/font/google';
import { Label } from '@radix-ui/react-label';
import { Check, ChevronsUpDown, Info } from 'lucide-react';
import { useFieldArray, useForm } from 'react-hook-form';
@ -20,6 +21,7 @@ import { cn } from '../../lib/utils';
import { Button } from '../button';
import { Card, CardContent } from '../card';
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem } from '../command';
import { Input } from '../input';
import { Popover, PopoverContent, PopoverTrigger } from '../popover';
import { useStep } from '../stepper';
import { Tooltip, TooltipContent, TooltipTrigger } from '../tooltip';
@ -32,6 +34,7 @@ import {
DocumentFlowFormContainerStep,
} from './document-flow-root';
import { FieldItem } from './field-item';
import type { TDocumentFlowFormSchema } from './types';
import { type DocumentFlowStep, FRIENDLY_FIELD_TYPE } from './types';
const fontCaveat = Caveat({
@ -47,6 +50,8 @@ const DEFAULT_WIDTH_PERCENT = 15;
const MIN_HEIGHT_PX = 60;
const MIN_WIDTH_PX = 200;
type ActiveField = TDocumentFlowFormSchema['fields'][0];
export type AddFieldsFormProps = {
documentFlow: DocumentFlowStep;
hideRecipients?: boolean;
@ -69,6 +74,7 @@ export const AddFieldsFormPartial = ({
control,
handleSubmit,
formState: { isSubmitting },
setValue,
} = useForm<TAddFieldsFormSchema>({
defaultValues: {
fields: fields.map((field) => ({
@ -82,11 +88,23 @@ export const AddFieldsFormPartial = ({
pageHeight: Number(field.height),
signerEmail:
recipients.find((recipient) => recipient.id === field.recipientId)?.email ?? '',
label: field.label ?? '',
})),
},
});
// const addLabelForm = useForm<TAddCustomLabelFormSchema>({
// defaultValues: {
// label: '',
// },
// });
// const onCustomLabelFormSubmit = (data: TAddCustomLabelFormSchema) => {
// console.log('Custom label', data);
// };
const onFormSubmit = handleSubmit(onSubmit);
// const onAddCustomLabelFormSubmit = addLabelForm.handleSubmit(onCustomLabelFormSubmit);
const {
append,
@ -101,6 +119,8 @@ export const AddFieldsFormPartial = ({
const [selectedField, setSelectedField] = useState<FieldType | null>(null);
const [selectedSigner, setSelectedSigner] = useState<Recipient | null>(null);
const [showRecipientsSelector, setShowRecipientsSelector] = useState(false);
const [activeField, setActiveField] = useState<ActiveField | null>(null);
const [fieldLabel, setFieldLabel] = useState<Record<string, string> | null>({});
const hasSelectedSignerBeenSent = selectedSigner?.sendStatus === SendStatus.SENT;
@ -186,12 +206,13 @@ export const AddFieldsFormPartial = ({
pageWidth: fieldPageWidth,
pageHeight: fieldPageHeight,
signerEmail: selectedSigner.email,
label: activeField?.label ?? fieldLabel?.[activeField?.formId ?? ''] ?? '',
});
setIsFieldWithinBounds(false);
setSelectedField(null);
},
[append, isWithinPageBounds, selectedField, selectedSigner, getPage],
[append, isWithinPageBounds, selectedField, selectedSigner, activeField, fieldLabel, getPage],
);
const onFieldResize = useCallback(
@ -257,7 +278,7 @@ export const AddFieldsFormPartial = ({
window.removeEventListener('mousemove', onMouseMove);
window.removeEventListener('mouseup', onMouseClick);
};
}, [onMouseClick, onMouseMove, selectedField]);
}, [onMouseClick, onMouseMove, selectedField, activeField]);
useEffect(() => {
const observer = new MutationObserver((_mutations) => {
@ -311,6 +332,8 @@ export const AddFieldsFormPartial = ({
);
}, [recipientsByRole]);
console.log(localFields[0].label);
return (
<>
<DocumentFlowFormContainerHeader
@ -342,19 +365,24 @@ export const AddFieldsFormPartial = ({
</Card>
)}
{localFields.map((field, index) => (
<FieldItem
key={index}
field={field}
disabled={selectedSigner?.email !== field.signerEmail || hasSelectedSignerBeenSent}
minHeight={fieldBounds.current.height}
minWidth={fieldBounds.current.width}
passive={isFieldWithinBounds && !!selectedField}
onResize={(options) => onFieldResize(options, index)}
onMove={(options) => onFieldMove(options, index)}
onRemove={() => remove(index)}
/>
))}
{localFields.map((field, index) => {
return (
<FieldItem
key={index}
field={field}
disabled={selectedSigner?.email !== field.signerEmail || hasSelectedSignerBeenSent}
minHeight={fieldBounds.current.height}
minWidth={fieldBounds.current.width}
passive={isFieldWithinBounds && !!selectedField}
onResize={(options) => onFieldResize(options, index)}
onClick={(field) => {
setActiveField(field);
}}
onMove={(options) => onFieldMove(options, index)}
onRemove={() => remove(index)}
/>
);
})}
{!hideRecipients && (
<Popover open={showRecipientsSelector} onOpenChange={setShowRecipientsSelector}>
@ -462,7 +490,7 @@ export const AddFieldsFormPartial = ({
</Popover>
)}
<div className="-mx-2 flex-1 overflow-y-auto px-2">
<div className="-mx-2 flex-1 px-2">
<fieldset disabled={isFieldsDisabled} className="grid grid-cols-2 gap-x-4 gap-y-8">
<button
type="button"
@ -554,6 +582,40 @@ export const AddFieldsFormPartial = ({
</button>
</fieldset>
</div>
{activeField && (
<div className="-mx-2 my-8 flex-1 gap-1.5 px-2">
<Label htmlFor="form-label">Custom Label</Label>
<div className="mt-2 flex w-full items-center space-x-2">
<Input
type="text"
className="w-full"
placeholder="Label"
id="form-label"
value={fieldLabel?.[activeField.formId] ?? activeField.label}
onChange={(e) => {
setFieldLabel((prev) => ({
...prev,
[activeField.formId]: e.target.value,
}));
setValue(
'fields',
localFields.map((field) => {
if (field.formId === activeField.formId) {
return {
...field,
label: fieldLabel?.[activeField.formId] ?? activeField.label ?? '',
};
}
return field;
}),
);
}}
/>
</div>
</div>
)}
</div>
</DocumentFlowFormContainerContent>

View File

@ -14,6 +14,7 @@ export const ZAddFieldsFormSchema = z.object({
pageY: z.number().min(0),
pageWidth: z.number().min(0),
pageHeight: z.number().min(0),
label: z.string().min(1),
}),
),
});

View File

@ -23,6 +23,7 @@ export type FieldItemProps = {
minWidth?: number;
onResize?: (_node: HTMLElement) => void;
onMove?: (_node: HTMLElement) => void;
onClick?: (field: Field) => void;
onRemove?: () => void;
};
@ -35,6 +36,7 @@ export const FieldItem = ({
onResize,
onMove,
onRemove,
onClick,
}: FieldItemProps) => {
const [active, setActive] = useState(false);
const [coords, setCoords] = useState({
@ -106,7 +108,10 @@ export const FieldItem = ({
width: coords.pageWidth,
}}
bounds={`${PDF_VIEWER_PAGE_SELECTOR}[data-page-number="${field.pageNumber}"]`}
onDragStart={() => setActive(true)}
onDragStart={() => {
setActive(true);
onClick?.(field);
}}
onResizeStart={() => setActive(true)}
onResizeStop={(_e, _d, ref) => {
setActive(false);

View File

@ -30,6 +30,7 @@ export const ZDocumentFlowFormSchema = z.object({
pageY: z.number().min(0),
pageWidth: z.number().min(0),
pageHeight: z.number().min(0),
label: z.string().optional(),
}),
),