formanitor 0.0.31 → 0.0.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
 
3
- type FieldType = 'text' | 'number' | 'textarea' | 'diagnosis_textarea' | 'richtext' | 'select' | 'multiselect' | 'radio' | 'repeatable' | 'checkbox' | 'image_upload' | 'signature' | 'date' | 'datetime' | 'editable_table' | 'static_text' | 'medications' | 'investigations' | 'procedures' | 'vitals' | 'hidden_vitals' | 'referral' | 'followup' | string;
3
+ type FieldType = 'text' | 'number' | 'textarea' | 'diagnosis_textarea' | 'richtext' | 'select' | 'multiselect' | 'radio' | 'repeatable' | 'checkbox' | 'image_upload' | 'media_upload' | 'signature' | 'date' | 'datetime' | 'editable_table' | 'static_text' | 'medications' | 'investigations' | 'procedures' | 'vitals' | 'hidden_vitals' | 'referral' | 'followup' | string;
4
4
  interface ValidationRule {
5
5
  min?: number;
6
6
  max?: number;
@@ -112,6 +112,12 @@ interface ImageUploadFieldDef extends BaseFieldDef {
112
112
  maxSize?: number;
113
113
  acceptedTypes?: string[];
114
114
  }
115
+ interface MediaUploadFieldDef extends BaseFieldDef {
116
+ type: 'media_upload';
117
+ maxSize?: number;
118
+ /** Default: images (image/*) and application/pdf */
119
+ acceptedTypes?: string[];
120
+ }
115
121
  interface SignatureFieldDef extends BaseFieldDef {
116
122
  type: 'signature';
117
123
  canvasWidth?: number;
@@ -302,7 +308,7 @@ interface DoctorFrequentItems {
302
308
  investigations?: InvestigationFrequentItem[];
303
309
  procedures?: ProcedureFrequentItem[];
304
310
  }
305
- type FieldDef = TextFieldDef | RichTextFieldDef | NumberFieldDef | SelectFieldDef | RadioFieldDef | CheckboxFieldDef | RepeatableFieldDef | ImageUploadFieldDef | SignatureFieldDef | EditableTableFieldDef | StaticTextFieldDef | MedicationsFieldDef | InvestigationsFieldDef | ProceduresFieldDef | DifferentialDiagnosisFieldDef | VitalsFieldDef | ReferralFieldDef | FollowupFieldDef | SmartTextareaFieldDef | DiagnosisTextareaFieldDef | BaseFieldDef;
311
+ type FieldDef = TextFieldDef | RichTextFieldDef | NumberFieldDef | SelectFieldDef | RadioFieldDef | CheckboxFieldDef | RepeatableFieldDef | ImageUploadFieldDef | MediaUploadFieldDef | SignatureFieldDef | EditableTableFieldDef | StaticTextFieldDef | MedicationsFieldDef | InvestigationsFieldDef | ProceduresFieldDef | DifferentialDiagnosisFieldDef | VitalsFieldDef | ReferralFieldDef | FollowupFieldDef | SmartTextareaFieldDef | DiagnosisTextareaFieldDef | BaseFieldDef;
306
312
  interface Condition {
307
313
  field?: string;
308
314
  op: '==' | '!=' | '>' | '<' | '>=' | '<=' | 'in' | 'contains';
@@ -720,6 +726,10 @@ declare const ImageUploadWidget: React.FC<{
720
726
  fieldId: string;
721
727
  }>;
722
728
 
729
+ declare const MediaUploadWidget: React.FC<{
730
+ fieldId: string;
731
+ }>;
732
+
723
733
  declare const SignatureUploadWidget: React.FC<{
724
734
  fieldId: string;
725
735
  }>;
@@ -730,6 +740,12 @@ interface ReadOnlyImageUploadProps {
730
740
  }
731
741
  declare const ReadOnlyImageUpload: React.FC<ReadOnlyImageUploadProps>;
732
742
 
743
+ interface ReadOnlyMediaUploadProps {
744
+ fieldDef: BaseFieldDef;
745
+ value: any;
746
+ }
747
+ declare const ReadOnlyMediaUpload: React.FC<ReadOnlyMediaUploadProps>;
748
+
733
749
  interface ReadOnlySignatureProps {
734
750
  fieldDef: BaseFieldDef;
735
751
  value: any;
@@ -910,4 +926,4 @@ declare const SmartTextareaWidget: React.FC<{
910
926
  fieldId: string;
911
927
  }>;
912
928
 
913
- export { type AIDifferentialDiagnosisItem, AddInvestigationField, type AddInvestigationFieldProps, AddMedicationField, type AddMedicationFieldProps, type BaseFieldDef, type CheckboxFieldDef, type ColumnLayout, type Computation, type Condition, type CreateUploadHandlerOptions, type DataSource, type DiagnosisGradeSelection, type DiagnosisTextareaFieldDef, type DiagnosisTextareaValue, DifferentialDiagnosis, type DifferentialDiagnosisFieldDef, type DifferentialDiagnosisItem, type DifferentialDiagnosisProps, type DoctorFrequentItems, DynamicForm, EMAIL_REGEX, type EditableTableColumnDef, type EditableTableFieldDef, type EventDefinition, type ExtractedKeywordMatch, type FieldDef, type FieldHandler, type FieldHandlersMap, type FieldPrefill, FieldRenderer, type FieldState, type FieldType, type FollowupFieldDef, type FollowupValue, FormControls, type FormControlsProps, type FormDef, type FormErrors, FormProvider, type FormState, FormStore, type FormValues, type FormulaComputation, type FormulaExpr, type ImageUploadFieldDef, ImageUploadWidget, type Investigation, type InvestigationFrequentItem, type InvestigationSearchResult, type InvestigationsFieldDef, type LayoutNode, type MatchedCondition, type Medication, type MedicationFrequentItem, type MedicationSearchResult, type MedicationsFieldDef, type NumberFieldDef, type Permission, type PresignedUploadResponse, type ProcedureFrequentItem, type ProceduresFieldDef, type RadioFieldDef, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlySignature, ReadOnlyTable, type ReferralFieldDef, type ReferralItem, type RepeatableFieldDef, type RichTextFieldDef, RichTextWidget, type Rule, type RuleAction, type RuleResult, type ScoreComputation, type ScoreRange, type Section, type SectionChild, type SelectFieldDef, type SelectOption, type SignatureFieldDef, SignatureUploadWidget, SmartForm, type SmartFormProps, type SmartKeywordsResult, type SmartTextareaFieldDef, type SmartTextareaValue, SmartTextareaWidget, type StaticTextFieldDef, type StoreConfig, type SubmissionData, type SumComputation, type TextFieldDef, type ValidationRule, type VitalsFieldDef, type WebhookDef, type Workflow, type WorkflowTransition, createUploadHandler, evaluateRules, useField, useFieldHandlers, useForm, useFormStore, useFrequentItems, useSmartKeywords, validateField, validateForm };
929
+ export { type AIDifferentialDiagnosisItem, AddInvestigationField, type AddInvestigationFieldProps, AddMedicationField, type AddMedicationFieldProps, type BaseFieldDef, type CheckboxFieldDef, type ColumnLayout, type Computation, type Condition, type CreateUploadHandlerOptions, type DataSource, type DiagnosisGradeSelection, type DiagnosisTextareaFieldDef, type DiagnosisTextareaValue, DifferentialDiagnosis, type DifferentialDiagnosisFieldDef, type DifferentialDiagnosisItem, type DifferentialDiagnosisProps, type DoctorFrequentItems, DynamicForm, EMAIL_REGEX, type EditableTableColumnDef, type EditableTableFieldDef, type EventDefinition, type ExtractedKeywordMatch, type FieldDef, type FieldHandler, type FieldHandlersMap, type FieldPrefill, FieldRenderer, type FieldState, type FieldType, type FollowupFieldDef, type FollowupValue, FormControls, type FormControlsProps, type FormDef, type FormErrors, FormProvider, type FormState, FormStore, type FormValues, type FormulaComputation, type FormulaExpr, type ImageUploadFieldDef, ImageUploadWidget, type Investigation, type InvestigationFrequentItem, type InvestigationSearchResult, type InvestigationsFieldDef, type LayoutNode, type MatchedCondition, type MediaUploadFieldDef, MediaUploadWidget, type Medication, type MedicationFrequentItem, type MedicationSearchResult, type MedicationsFieldDef, type NumberFieldDef, type Permission, type PresignedUploadResponse, type ProcedureFrequentItem, type ProceduresFieldDef, type RadioFieldDef, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlyMediaUpload, ReadOnlySignature, ReadOnlyTable, type ReferralFieldDef, type ReferralItem, type RepeatableFieldDef, type RichTextFieldDef, RichTextWidget, type Rule, type RuleAction, type RuleResult, type ScoreComputation, type ScoreRange, type Section, type SectionChild, type SelectFieldDef, type SelectOption, type SignatureFieldDef, SignatureUploadWidget, SmartForm, type SmartFormProps, type SmartKeywordsResult, type SmartTextareaFieldDef, type SmartTextareaValue, SmartTextareaWidget, type StaticTextFieldDef, type StoreConfig, type SubmissionData, type SumComputation, type TextFieldDef, type ValidationRule, type VitalsFieldDef, type WebhookDef, type Workflow, type WorkflowTransition, createUploadHandler, evaluateRules, useField, useFieldHandlers, useForm, useFormStore, useFrequentItems, useSmartKeywords, validateField, validateForm };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
 
3
- type FieldType = 'text' | 'number' | 'textarea' | 'diagnosis_textarea' | 'richtext' | 'select' | 'multiselect' | 'radio' | 'repeatable' | 'checkbox' | 'image_upload' | 'signature' | 'date' | 'datetime' | 'editable_table' | 'static_text' | 'medications' | 'investigations' | 'procedures' | 'vitals' | 'hidden_vitals' | 'referral' | 'followup' | string;
3
+ type FieldType = 'text' | 'number' | 'textarea' | 'diagnosis_textarea' | 'richtext' | 'select' | 'multiselect' | 'radio' | 'repeatable' | 'checkbox' | 'image_upload' | 'media_upload' | 'signature' | 'date' | 'datetime' | 'editable_table' | 'static_text' | 'medications' | 'investigations' | 'procedures' | 'vitals' | 'hidden_vitals' | 'referral' | 'followup' | string;
4
4
  interface ValidationRule {
5
5
  min?: number;
6
6
  max?: number;
@@ -112,6 +112,12 @@ interface ImageUploadFieldDef extends BaseFieldDef {
112
112
  maxSize?: number;
113
113
  acceptedTypes?: string[];
114
114
  }
115
+ interface MediaUploadFieldDef extends BaseFieldDef {
116
+ type: 'media_upload';
117
+ maxSize?: number;
118
+ /** Default: images (image/*) and application/pdf */
119
+ acceptedTypes?: string[];
120
+ }
115
121
  interface SignatureFieldDef extends BaseFieldDef {
116
122
  type: 'signature';
117
123
  canvasWidth?: number;
@@ -302,7 +308,7 @@ interface DoctorFrequentItems {
302
308
  investigations?: InvestigationFrequentItem[];
303
309
  procedures?: ProcedureFrequentItem[];
304
310
  }
305
- type FieldDef = TextFieldDef | RichTextFieldDef | NumberFieldDef | SelectFieldDef | RadioFieldDef | CheckboxFieldDef | RepeatableFieldDef | ImageUploadFieldDef | SignatureFieldDef | EditableTableFieldDef | StaticTextFieldDef | MedicationsFieldDef | InvestigationsFieldDef | ProceduresFieldDef | DifferentialDiagnosisFieldDef | VitalsFieldDef | ReferralFieldDef | FollowupFieldDef | SmartTextareaFieldDef | DiagnosisTextareaFieldDef | BaseFieldDef;
311
+ type FieldDef = TextFieldDef | RichTextFieldDef | NumberFieldDef | SelectFieldDef | RadioFieldDef | CheckboxFieldDef | RepeatableFieldDef | ImageUploadFieldDef | MediaUploadFieldDef | SignatureFieldDef | EditableTableFieldDef | StaticTextFieldDef | MedicationsFieldDef | InvestigationsFieldDef | ProceduresFieldDef | DifferentialDiagnosisFieldDef | VitalsFieldDef | ReferralFieldDef | FollowupFieldDef | SmartTextareaFieldDef | DiagnosisTextareaFieldDef | BaseFieldDef;
306
312
  interface Condition {
307
313
  field?: string;
308
314
  op: '==' | '!=' | '>' | '<' | '>=' | '<=' | 'in' | 'contains';
@@ -720,6 +726,10 @@ declare const ImageUploadWidget: React.FC<{
720
726
  fieldId: string;
721
727
  }>;
722
728
 
729
+ declare const MediaUploadWidget: React.FC<{
730
+ fieldId: string;
731
+ }>;
732
+
723
733
  declare const SignatureUploadWidget: React.FC<{
724
734
  fieldId: string;
725
735
  }>;
@@ -730,6 +740,12 @@ interface ReadOnlyImageUploadProps {
730
740
  }
731
741
  declare const ReadOnlyImageUpload: React.FC<ReadOnlyImageUploadProps>;
732
742
 
743
+ interface ReadOnlyMediaUploadProps {
744
+ fieldDef: BaseFieldDef;
745
+ value: any;
746
+ }
747
+ declare const ReadOnlyMediaUpload: React.FC<ReadOnlyMediaUploadProps>;
748
+
733
749
  interface ReadOnlySignatureProps {
734
750
  fieldDef: BaseFieldDef;
735
751
  value: any;
@@ -910,4 +926,4 @@ declare const SmartTextareaWidget: React.FC<{
910
926
  fieldId: string;
911
927
  }>;
912
928
 
913
- export { type AIDifferentialDiagnosisItem, AddInvestigationField, type AddInvestigationFieldProps, AddMedicationField, type AddMedicationFieldProps, type BaseFieldDef, type CheckboxFieldDef, type ColumnLayout, type Computation, type Condition, type CreateUploadHandlerOptions, type DataSource, type DiagnosisGradeSelection, type DiagnosisTextareaFieldDef, type DiagnosisTextareaValue, DifferentialDiagnosis, type DifferentialDiagnosisFieldDef, type DifferentialDiagnosisItem, type DifferentialDiagnosisProps, type DoctorFrequentItems, DynamicForm, EMAIL_REGEX, type EditableTableColumnDef, type EditableTableFieldDef, type EventDefinition, type ExtractedKeywordMatch, type FieldDef, type FieldHandler, type FieldHandlersMap, type FieldPrefill, FieldRenderer, type FieldState, type FieldType, type FollowupFieldDef, type FollowupValue, FormControls, type FormControlsProps, type FormDef, type FormErrors, FormProvider, type FormState, FormStore, type FormValues, type FormulaComputation, type FormulaExpr, type ImageUploadFieldDef, ImageUploadWidget, type Investigation, type InvestigationFrequentItem, type InvestigationSearchResult, type InvestigationsFieldDef, type LayoutNode, type MatchedCondition, type Medication, type MedicationFrequentItem, type MedicationSearchResult, type MedicationsFieldDef, type NumberFieldDef, type Permission, type PresignedUploadResponse, type ProcedureFrequentItem, type ProceduresFieldDef, type RadioFieldDef, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlySignature, ReadOnlyTable, type ReferralFieldDef, type ReferralItem, type RepeatableFieldDef, type RichTextFieldDef, RichTextWidget, type Rule, type RuleAction, type RuleResult, type ScoreComputation, type ScoreRange, type Section, type SectionChild, type SelectFieldDef, type SelectOption, type SignatureFieldDef, SignatureUploadWidget, SmartForm, type SmartFormProps, type SmartKeywordsResult, type SmartTextareaFieldDef, type SmartTextareaValue, SmartTextareaWidget, type StaticTextFieldDef, type StoreConfig, type SubmissionData, type SumComputation, type TextFieldDef, type ValidationRule, type VitalsFieldDef, type WebhookDef, type Workflow, type WorkflowTransition, createUploadHandler, evaluateRules, useField, useFieldHandlers, useForm, useFormStore, useFrequentItems, useSmartKeywords, validateField, validateForm };
929
+ export { type AIDifferentialDiagnosisItem, AddInvestigationField, type AddInvestigationFieldProps, AddMedicationField, type AddMedicationFieldProps, type BaseFieldDef, type CheckboxFieldDef, type ColumnLayout, type Computation, type Condition, type CreateUploadHandlerOptions, type DataSource, type DiagnosisGradeSelection, type DiagnosisTextareaFieldDef, type DiagnosisTextareaValue, DifferentialDiagnosis, type DifferentialDiagnosisFieldDef, type DifferentialDiagnosisItem, type DifferentialDiagnosisProps, type DoctorFrequentItems, DynamicForm, EMAIL_REGEX, type EditableTableColumnDef, type EditableTableFieldDef, type EventDefinition, type ExtractedKeywordMatch, type FieldDef, type FieldHandler, type FieldHandlersMap, type FieldPrefill, FieldRenderer, type FieldState, type FieldType, type FollowupFieldDef, type FollowupValue, FormControls, type FormControlsProps, type FormDef, type FormErrors, FormProvider, type FormState, FormStore, type FormValues, type FormulaComputation, type FormulaExpr, type ImageUploadFieldDef, ImageUploadWidget, type Investigation, type InvestigationFrequentItem, type InvestigationSearchResult, type InvestigationsFieldDef, type LayoutNode, type MatchedCondition, type MediaUploadFieldDef, MediaUploadWidget, type Medication, type MedicationFrequentItem, type MedicationSearchResult, type MedicationsFieldDef, type NumberFieldDef, type Permission, type PresignedUploadResponse, type ProcedureFrequentItem, type ProceduresFieldDef, type RadioFieldDef, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlyMediaUpload, ReadOnlySignature, ReadOnlyTable, type ReferralFieldDef, type ReferralItem, type RepeatableFieldDef, type RichTextFieldDef, RichTextWidget, type Rule, type RuleAction, type RuleResult, type ScoreComputation, type ScoreRange, type Section, type SectionChild, type SelectFieldDef, type SelectOption, type SignatureFieldDef, SignatureUploadWidget, SmartForm, type SmartFormProps, type SmartKeywordsResult, type SmartTextareaFieldDef, type SmartTextareaValue, SmartTextareaWidget, type StaticTextFieldDef, type StoreConfig, type SubmissionData, type SumComputation, type TextFieldDef, type ValidationRule, type VitalsFieldDef, type WebhookDef, type Workflow, type WorkflowTransition, createUploadHandler, evaluateRules, useField, useFieldHandlers, useForm, useFormStore, useFrequentItems, useSmartKeywords, validateField, validateForm };
package/dist/index.mjs CHANGED
@@ -423,7 +423,7 @@ var FormStore = class {
423
423
  result[field.id] = parts.length > 0 ? parts.join("\n\n") : null;
424
424
  return;
425
425
  }
426
- if (field.type === "image_upload" || field.type === "signature") {
426
+ if (field.type === "image_upload" || field.type === "media_upload" || field.type === "signature") {
427
427
  const raw = values[field.id];
428
428
  if (raw !== void 0 && raw !== null && raw !== "") {
429
429
  const key = typeof raw === "string" ? raw : raw.s3_key || raw.value || null;
@@ -2151,6 +2151,162 @@ var ImageUploadWidget = ({ fieldId }) => {
2151
2151
  showError && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-500", children: error })
2152
2152
  ] });
2153
2153
  };
2154
+ function urlLooksLikePdf(url) {
2155
+ return /\.pdf($|\?)/i.test(url) || url.toLowerCase().includes("application/pdf");
2156
+ }
2157
+ function isAcceptedMediaFile(file) {
2158
+ if (file.type.startsWith("image/")) return true;
2159
+ if (file.type === "application/pdf") return true;
2160
+ if (file.name.toLowerCase().endsWith(".pdf")) return true;
2161
+ return false;
2162
+ }
2163
+ var MediaUploadWidget = ({ fieldId }) => {
2164
+ const { fieldDef, value, setValue, setTouched, error, disabled, touched } = useField(fieldId);
2165
+ const store = useFormStore();
2166
+ const { state } = useForm();
2167
+ const [isUploading, setIsUploading] = useState(false);
2168
+ const [preview, setPreview] = useState(null);
2169
+ const [previewIsPdf, setPreviewIsPdf] = useState(false);
2170
+ const fileInputRef = useRef(null);
2171
+ const pendingPreviewKindRef = useRef(null);
2172
+ const showError = !!error && (touched || state.submitAttempted);
2173
+ if (!fieldDef) return null;
2174
+ const uploadHandler = store.getUploadHandler();
2175
+ if (!uploadHandler) {
2176
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
2177
+ /* @__PURE__ */ jsxs(Label, { htmlFor: fieldId, children: [
2178
+ fieldDef.label,
2179
+ fieldDef.required && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
2180
+ ] }),
2181
+ /* @__PURE__ */ jsx("div", { className: "border-2 border-red-300 rounded-lg p-4 bg-red-50", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-red-600", children: "Upload handler not configured. Please provide an onUpload function in FormProvider config." }) })
2182
+ ] });
2183
+ }
2184
+ React15__default.useEffect(() => {
2185
+ if (value && typeof value === "string") {
2186
+ setPreview(value);
2187
+ if (pendingPreviewKindRef.current) {
2188
+ setPreviewIsPdf(pendingPreviewKindRef.current === "pdf");
2189
+ pendingPreviewKindRef.current = null;
2190
+ } else {
2191
+ setPreviewIsPdf(urlLooksLikePdf(value));
2192
+ }
2193
+ } else {
2194
+ setPreview(null);
2195
+ setPreviewIsPdf(false);
2196
+ }
2197
+ }, [value]);
2198
+ const handleFileSelect = async (event) => {
2199
+ const file = event.target.files?.[0];
2200
+ if (!file) return;
2201
+ if (!isAcceptedMediaFile(file)) {
2202
+ alert("Please select an image or PDF file");
2203
+ return;
2204
+ }
2205
+ const maxSize = 10 * 1024 * 1024;
2206
+ if (file.size > maxSize) {
2207
+ alert("File size must be less than 10MB");
2208
+ return;
2209
+ }
2210
+ const isPdf = file.type === "application/pdf" || file.name.toLowerCase().endsWith(".pdf");
2211
+ setIsUploading(true);
2212
+ setTouched();
2213
+ store.incrementPendingUploads();
2214
+ try {
2215
+ const previewUrl = URL.createObjectURL(file);
2216
+ setPreview(previewUrl);
2217
+ setPreviewIsPdf(isPdf);
2218
+ const s3Key = await uploadHandler(file, file.name);
2219
+ pendingPreviewKindRef.current = isPdf ? "pdf" : "image";
2220
+ setValue(s3Key);
2221
+ } catch (error2) {
2222
+ console.error("Upload failed:", error2);
2223
+ const errorMessage = error2 instanceof Error ? error2.message : "Upload failed. Please try again.";
2224
+ alert(errorMessage);
2225
+ setPreview(null);
2226
+ setPreviewIsPdf(false);
2227
+ } finally {
2228
+ setIsUploading(false);
2229
+ store.decrementPendingUploads();
2230
+ }
2231
+ };
2232
+ const handleRemove = () => {
2233
+ pendingPreviewKindRef.current = null;
2234
+ setValue(null);
2235
+ setPreview(null);
2236
+ setPreviewIsPdf(false);
2237
+ if (fileInputRef.current) {
2238
+ fileInputRef.current.value = "";
2239
+ }
2240
+ setTouched();
2241
+ };
2242
+ const handleUploadClick = () => {
2243
+ fileInputRef.current?.click();
2244
+ };
2245
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
2246
+ /* @__PURE__ */ jsxs(Label, { htmlFor: fieldId, children: [
2247
+ fieldDef.label,
2248
+ fieldDef.required && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
2249
+ ] }),
2250
+ /* @__PURE__ */ jsx("div", { className: "border-2 border-dashed border-gray-300 rounded-lg p-4", children: preview ? /* @__PURE__ */ jsxs("div", { className: "relative", children: [
2251
+ previewIsPdf ? /* @__PURE__ */ jsx(
2252
+ "iframe",
2253
+ {
2254
+ src: preview,
2255
+ title: "Uploaded PDF",
2256
+ className: "w-full max-h-48 min-h-36 rounded-lg border border-gray-200 bg-white"
2257
+ }
2258
+ ) : /* @__PURE__ */ jsx(
2259
+ "img",
2260
+ {
2261
+ src: preview,
2262
+ alt: "Uploaded image",
2263
+ className: "max-w-full max-h-48 mx-auto rounded-lg"
2264
+ }
2265
+ ),
2266
+ /* @__PURE__ */ jsx(
2267
+ Button,
2268
+ {
2269
+ type: "button",
2270
+ variant: "destructive",
2271
+ size: "sm",
2272
+ className: "absolute top-2 right-2",
2273
+ onClick: handleRemove,
2274
+ disabled: disabled || isUploading,
2275
+ children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
2276
+ }
2277
+ )
2278
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "text-center py-8", children: [
2279
+ /* @__PURE__ */ jsx(Image, { className: "h-12 w-12 mx-auto text-gray-400 mb-4" }),
2280
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-600 mb-4", children: "Click to upload an image or PDF, or drag and drop" }),
2281
+ /* @__PURE__ */ jsxs(
2282
+ Button,
2283
+ {
2284
+ type: "button",
2285
+ variant: "outline",
2286
+ onClick: handleUploadClick,
2287
+ disabled: disabled || isUploading,
2288
+ children: [
2289
+ /* @__PURE__ */ jsx(Upload, { className: "h-4 w-4 mr-2" }),
2290
+ isUploading ? "Uploading..." : "Choose Image"
2291
+ ]
2292
+ }
2293
+ )
2294
+ ] }) }),
2295
+ /* @__PURE__ */ jsx(
2296
+ "input",
2297
+ {
2298
+ ref: fileInputRef,
2299
+ type: "file",
2300
+ accept: "image/*,application/pdf",
2301
+ onChange: handleFileSelect,
2302
+ className: "hidden",
2303
+ disabled: disabled || isUploading
2304
+ }
2305
+ ),
2306
+ fieldDef.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500", children: fieldDef.description }),
2307
+ showError && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-500", children: error })
2308
+ ] });
2309
+ };
2154
2310
  var distance = (a, b) => Math.hypot(a.x - b.x, a.y - b.y);
2155
2311
  var smoothPoint = (prev, curr, smoothing = 0.75) => {
2156
2312
  if (!prev) return curr;
@@ -7415,6 +7571,8 @@ function renderWidget(fieldId, fieldDef) {
7415
7571
  return /* @__PURE__ */ jsx(RepeatableWidget, { fieldId });
7416
7572
  case "image_upload":
7417
7573
  return /* @__PURE__ */ jsx(ImageUploadWidget, { fieldId });
7574
+ case "media_upload":
7575
+ return /* @__PURE__ */ jsx(MediaUploadWidget, { fieldId });
7418
7576
  case "signature":
7419
7577
  return /* @__PURE__ */ jsx(SignatureUploadWidget, { fieldId });
7420
7578
  case "editable_table":
@@ -7822,6 +7980,55 @@ var ReadOnlyImageUpload = ({
7822
7980
  fieldDef.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500", children: fieldDef.description })
7823
7981
  ] });
7824
7982
  };
7983
+ function urlLooksLikePdf2(url) {
7984
+ return /\.pdf($|\?)/i.test(url) || url.toLowerCase().includes("application/pdf");
7985
+ }
7986
+ var ReadOnlyMediaUpload = ({
7987
+ fieldDef,
7988
+ value
7989
+ }) => {
7990
+ const [useIframe, setUseIframe] = useState(false);
7991
+ let url = null;
7992
+ if (typeof value === "string") {
7993
+ url = value;
7994
+ } else if (value && typeof value === "object") {
7995
+ const typed = value;
7996
+ url = typed.presigned_url || typed.value || typed.s3_key || null;
7997
+ }
7998
+ useEffect(() => {
7999
+ setUseIframe(false);
8000
+ }, [url]);
8001
+ const showAsPdf = url && (urlLooksLikePdf2(url) || useIframe);
8002
+ if (!url) {
8003
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
8004
+ /* @__PURE__ */ jsx(Label, { children: fieldDef.label }),
8005
+ /* @__PURE__ */ jsx("div", { className: "border border-gray-200 rounded-lg p-4 bg-gray-50", children: /* @__PURE__ */ jsxs("div", { className: "text-center py-4", children: [
8006
+ /* @__PURE__ */ jsx(Image, { className: "h-8 w-8 mx-auto text-gray-400 mb-2" }),
8007
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: "No file uploaded" })
8008
+ ] }) })
8009
+ ] });
8010
+ }
8011
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
8012
+ /* @__PURE__ */ jsx(Label, { children: fieldDef.label }),
8013
+ /* @__PURE__ */ jsx("div", { className: "border border-gray-200 rounded-lg p-4 bg-white", children: showAsPdf ? /* @__PURE__ */ jsx(
8014
+ "iframe",
8015
+ {
8016
+ src: url,
8017
+ title: `${fieldDef.label} PDF`,
8018
+ className: "w-full max-h-48 min-h-36 rounded-lg border border-gray-200 bg-white"
8019
+ }
8020
+ ) : /* @__PURE__ */ jsx(
8021
+ "img",
8022
+ {
8023
+ src: url,
8024
+ alt: `${fieldDef.label} upload`,
8025
+ className: "max-w-full max-h-48 mx-auto rounded-lg",
8026
+ onError: () => setUseIframe(true)
8027
+ }
8028
+ ) }),
8029
+ fieldDef.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500", children: fieldDef.description })
8030
+ ] });
8031
+ };
7825
8032
  var ReadOnlySignature = ({
7826
8033
  fieldDef,
7827
8034
  value
@@ -8023,6 +8230,8 @@ var ReadOnlyFieldRenderer = ({ fieldDef, value }) => {
8023
8230
  return /* @__PURE__ */ jsx(ReadOnlyRepeatable, { fieldDef, value });
8024
8231
  case "image_upload":
8025
8232
  return /* @__PURE__ */ jsx(ReadOnlyImageUpload, { fieldDef, value });
8233
+ case "media_upload":
8234
+ return /* @__PURE__ */ jsx(ReadOnlyMediaUpload, { fieldDef, value });
8026
8235
  case "signature":
8027
8236
  return /* @__PURE__ */ jsx(ReadOnlySignature, { fieldDef, value });
8028
8237
  case "editable_table":
@@ -8230,6 +8439,6 @@ function createUploadHandler(options) {
8230
8439
  };
8231
8440
  }
8232
8441
 
8233
- export { AddInvestigationField, AddMedicationField, DifferentialDiagnosis, DynamicForm, EMAIL_REGEX, FieldRenderer, FormControls, FormProvider, FormStore, ImageUploadWidget, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlySignature, ReadOnlyTable, RichTextWidget, SignatureUploadWidget, SmartForm, SmartTextareaWidget, createUploadHandler, evaluateRules, useField, useFieldHandlers, useForm, useFormStore, useFrequentItems, useSmartKeywords, validateField, validateForm };
8442
+ export { AddInvestigationField, AddMedicationField, DifferentialDiagnosis, DynamicForm, EMAIL_REGEX, FieldRenderer, FormControls, FormProvider, FormStore, ImageUploadWidget, MediaUploadWidget, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlyMediaUpload, ReadOnlySignature, ReadOnlyTable, RichTextWidget, SignatureUploadWidget, SmartForm, SmartTextareaWidget, createUploadHandler, evaluateRules, useField, useFieldHandlers, useForm, useFormStore, useFrequentItems, useSmartKeywords, validateField, validateForm };
8234
8443
  //# sourceMappingURL=index.mjs.map
8235
8444
  //# sourceMappingURL=index.mjs.map