added logvisit form route based storeselection

This commit is contained in:
suryacp23 2026-07-29 16:06:02 +05:30
parent 0ab9be85a6
commit 30339b0443
12 changed files with 619 additions and 19 deletions

View File

@ -133,6 +133,7 @@ export class ZinoClient {
org_id: String(p.org_id ?? ''), org_id: String(p.org_id ?? ''),
name: p.name ?? '', name: p.name ?? '',
email: p.email ?? '', email: p.email ?? '',
mobile: String(p.mobile ?? p.mobile_number ?? p.phone ?? p.phone_number ?? p.user_mobile ?? ''),
roles: p.roles ?? [], roles: p.roles ?? [],
groups: p.groups ?? [], groups: p.groups ?? [],
}; };

View File

@ -10,6 +10,7 @@ export interface User {
org_id: string; org_id: string;
name: string; name: string;
email: string; email: string;
mobile?: string;
roles: string[]; roles: string[];
groups: string[]; groups: string[];
} }

View File

@ -178,6 +178,43 @@ export function DynamicForm({ client, activityId: initialActivityId, instanceId:
} }
} }
} }
if (currentActivityId === ORDER_BOOKING.activities.LOG_VISIT.uid) {
const user = client.currentUser();
const userMobile = user?.mobile || localStorage.getItem('krishna_sales_user_mobile') || user?.email;
if (userMobile) {
try {
const headers: Record<string, string> = {
'templateid': '192',
'x-pipeline-version': 'draft',
'orgid': '57',
'groupid': '25'
};
const summaryRes = await client.request<any>(
'POST',
PIPELINE.endpoints.productiveCallSummary,
{ mobile: userMobile },
headers
);
let summaryData = summaryRes.data || summaryRes;
if (Array.isArray(summaryData)) {
summaryData = summaryData[0] || {};
}
if (summaryData.productive_call !== undefined) {
summaryData.total_productive_calls = summaryData.productive_call;
}
if (summaryData.non_productive_call !== undefined) {
summaryData.total_non_productive_calls = summaryData.non_productive_call;
}
mapPrefillData(summaryData);
} catch (e) {
console.warn('Failed to load productive call summary for Log Visit', e);
}
}
}
setValues(defaultValues); setValues(defaultValues);
setLoading(false); setLoading(false);

View File

@ -0,0 +1,555 @@
import React, { useState, useEffect, useCallback, useRef } from 'react';
import type { ZinoClient } from '../../api/client';
import type { FormScreenResponse } from '../../api/types';
import { ORDER_BOOKING, PIPELINE } from '../../api/config';
import { Button } from '../buttons/Button';
import { Select } from '../reusable/Select';
import { DateField, TimeField, FileInput, TextField } from './fields';
import { Spinner } from '../reusable/Spinner';
import { DynamicForm } from './DynamicForm';
export interface LogVisitFormProps {
client: ZinoClient;
onSuccess?: () => void;
onCancel?: () => void;
onActivityChange?: (name: string) => void;
}
// Utility to clean empty values from form data before sending API requests
const cleanFormData = (data: Record<string, any>) => {
const result: Record<string, any> = {};
Object.entries(data).forEach(([k, v]) => {
if (v !== '' && v !== null && v !== undefined && !(Array.isArray(v) && v.length === 0)) {
result[k] = v;
}
});
return result;
};
/**
* Dedicated form component for the Log Visit activity.
* Calls client.formSchema() to retrieve form screen fields dynamically,
* pre-fills daily_log & route_code from initial daily log lookup,
* lazy-fetches select_store options after daily log completion,
* handles mobile pipeline prefill,
* AND wires activity chaining seamlessly into DynamicForm for subsequent activities.
*/
export function LogVisitForm({ client, onSuccess, onCancel, onActivityChange }: LogVisitFormProps) {
const activityId = ORDER_BOOKING.activities.LOG_VISIT.uid;
const todayStr = new Date().toISOString().split('T')[0];
const nowTimeStr = new Date().toTimeString().split(' ')[0].substring(0, 5);
const [schema, setSchema] = useState<FormScreenResponse | null>(null);
const schemaRef = useRef<FormScreenResponse | null>(null);
useEffect(() => { schemaRef.current = schema; }, [schema]);
const [loadingSchema, setLoadingSchema] = useState(true);
const [values, setValues] = useState<Record<string, any>>({
date_of_visit: todayStr,
time_of_visit: nowTimeStr,
select_store: '',
upload_image: [],
daily_log: '',
route_code: '',
});
const valuesRef = useRef(values);
useEffect(() => {
valuesRef.current = values;
}, [values]);
const [storeOptions, setStoreOptions] = useState<{ value: string; label: string; _raw?: any }[]>([]);
const [fetchingDailyLog, setFetchingDailyLog] = useState(false);
const [fetchingStores, setFetchingStores] = useState(false);
const fetchingStoresRef = useRef(false);
const [chainedActivity, setChainedActivity] = useState<{
activityId: string;
instanceId?: number | string;
prefillData?: Record<string, unknown>;
} | null>(null);
const [submitting, setSubmitting] = useState(false);
const [submitError, setSubmitError] = useState<string | null>(null);
// 1. Fetch form schema from API (/app/434/view/form-screens) & Mobile Pipeline prefill
useEffect(() => {
let mounted = true;
setLoadingSchema(true);
client.formSchema(activityId)
.then(async (res) => {
if (!mounted) return;
setSchema(res);
schemaRef.current = res;
const initialValues: Record<string, any> = {
date_of_visit: todayStr,
time_of_visit: nowTimeStr,
select_store: '',
upload_image: [],
daily_log: '',
route_code: '',
};
if (res.field_defaults) {
Object.entries(res.field_defaults).forEach(([fieldId, def]) => {
if (def.value != null) {
initialValues[fieldId] = def.value;
} else if (def.prefill) {
if (def.prefill.value === 'current_date') {
initialValues[fieldId] = new Date().toISOString().split('T')[0];
} else if (def.prefill.value === 'current_time') {
initialValues[fieldId] = new Date().toTimeString().split(' ')[0].substring(0, 5);
} else if (def.prefill.value === 'current_user_id') {
const user = client.currentUser();
initialValues[fieldId] = user ? Number(user.id) : '';
} else {
initialValues[fieldId] = def.prefill.value;
}
}
});
}
if (res.prefill_data && Object.keys(res.prefill_data).length > 0) {
Object.assign(initialValues, res.prefill_data);
} else if (res.data && Object.keys(res.data).length > 0) {
Object.assign(initialValues, res.data);
}
// Execute mobile pipeline prefill
const user = client.currentUser();
const userMobile = user?.mobile || localStorage.getItem('krishna_sales_user_mobile') || user?.email;
if (userMobile) {
try {
const headers: Record<string, string> = {
'templateid': '192',
'x-pipeline-version': 'draft',
'orgid': '57',
'groupid': '25'
};
const summaryRes = await client.request<any>(
'POST',
PIPELINE.endpoints.productiveCallSummary,
{ mobile: userMobile },
headers
);
let summaryData = summaryRes.data || summaryRes;
if (Array.isArray(summaryData)) {
summaryData = summaryData[0] || {};
}
if (summaryData.productive_call !== undefined) {
summaryData.total_productive_calls = summaryData.productive_call;
}
if (summaryData.non_productive_call !== undefined) {
summaryData.total_non_productive_calls = summaryData.non_productive_call;
}
Object.assign(initialValues, summaryData);
} catch (e) {
console.warn('Failed to load productive call summary for Log Visit', e);
}
}
setValues(prev => {
const next = { ...initialValues, ...prev };
valuesRef.current = next;
return next;
});
})
.catch(err => {
console.error('Failed to load Log Visit form schema:', err);
})
.finally(() => {
if (mounted) setLoadingSchema(false);
});
return () => { mounted = false; };
}, [client, activityId, todayStr, nowTimeStr]);
// 2. Helper to fetch select_store options ONLY using updated prefilled formData
const fetchStoreOptions = useCallback(async (formDataOverride?: Record<string, any>) => {
if (fetchingStoresRef.current) return;
fetchingStoresRef.current = true;
setFetchingStores(true);
try {
const formDataToSend = cleanFormData(formDataOverride || valuesRef.current);
console.log('[LogVisitForm] Executing select_store lookup with prefilled formData:', formDataToSend);
const lookupRes = await client.wfLookupRecords({
activityId,
fieldId: 'select_store',
formData: formDataToSend,
limit: 200,
});
const arr = Array.isArray(lookupRes)
? lookupRes
: lookupRes?.data || lookupRes?.records || [];
// Find display_fields configured in schema for select_store
const selectStoreField = schemaRef.current?.fields.find(
f => f.id === 'select_store' || f.uid === 'field_1783057892381' || f.name.toLowerCase().includes('select store')
);
const displayFields = (selectStoreField?.properties?.wf_lookup_config as any)?.display_fields || [];
const opts = arr.map((row: any) => {
let labelText = '';
if (displayFields.length > 0) {
const labelParts = displayFields
.map((df: any) => row[df.field_id])
.filter((v: any) => v != null && v !== '');
if (labelParts.length > 0) {
labelText = labelParts.join(' - ');
}
}
if (!labelText) {
const storeName = row.business_name_2 || row.store_name || row.name || row.store;
const storeCode = row.store_code || row.code;
labelText = storeName
? `${storeCode ? `${storeCode} - ` : ''}${storeName}`
: `Store #${row.instance_id || row.id}`;
}
return {
value: String(row.instance_id || row.id),
label: labelText,
_raw: row,
};
});
setStoreOptions(opts);
} catch (e) {
console.error('Failed to load select_store options:', e);
} finally {
setFetchingStores(false);
fetchingStoresRef.current = false;
}
}, [client, activityId]);
// 3. Fetch Daily Log lookup data initially & prefill form state
const loadDailyLogData = useCallback(async (dateVal: string, timeVal: string) => {
setFetchingDailyLog(true);
try {
const payload = cleanFormData({
date_of_visit: dateVal,
time_of_visit: timeVal,
});
console.log('[LogVisitForm] Fetching initial daily_log lookup with payload:', payload);
const dailyLogLookupRes = await client.wfLookupRecords({
activityId,
fieldId: 'daily_log',
formData: payload,
limit: 200,
});
const arr = Array.isArray(dailyLogLookupRes)
? dailyLogLookupRes
: dailyLogLookupRes?.data || dailyLogLookupRes?.records || [];
if (arr.length > 0) {
const firstLog = arr[0];
console.log('[LogVisitForm] Successfully fetched daily log record:', firstLog);
const dailyLogInstanceId = String(firstLog.instance_id || firstLog.id || '');
const routeCode = String(
firstLog.route_code ||
firstLog.route_code_1 ||
firstLog.route_code_2 ||
firstLog.route_code_3 ||
firstLog.route ||
''
);
const updated = { ...valuesRef.current };
// Copy raw fields from daily log into state
Object.keys(firstLog).forEach(key => {
if (firstLog[key] != null && firstLog[key] !== '') {
updated[key] = firstLog[key];
}
});
if (dailyLogInstanceId) {
updated['daily_log'] = dailyLogInstanceId;
updated['field_1785225403902'] = dailyLogInstanceId;
updated['instance_id'] = firstLog.instance_id || firstLog.id;
}
if (routeCode) {
updated['route_code'] = routeCode;
updated['route_code_1'] = routeCode;
updated['route_code_2'] = routeCode;
updated['route_code_3'] = routeCode;
updated['field_1785311859486'] = routeCode;
}
valuesRef.current = updated;
setValues(updated);
console.log('[LogVisitForm] Daily log prefill complete:', updated);
} else {
console.warn('[LogVisitForm] No daily log records found for date/time:', dateVal, timeVal);
}
} catch (e) {
console.warn('Failed to load daily_log lookup for Log Visit', e);
} finally {
setFetchingDailyLog(false);
}
}, [client, activityId]);
useEffect(() => {
loadDailyLogData(values.date_of_visit, values.time_of_visit);
}, [loadDailyLogData, values.date_of_visit, values.time_of_visit]);
const handleStoreDropdownOpen = () => {
fetchStoreOptions();
};
const handleStoreSelect = (fieldId: string, val: string) => {
const selectedOpt = storeOptions.find(o => String(o.value) === String(val));
const rawRow = selectedOpt?._raw || {};
setValues(prev => {
const next: Record<string, any> = { ...prev, [fieldId]: val, select_store: val, field_1: val };
// Map raw row fields into values
Object.keys(rawRow).forEach(key => {
next[key] = rawRow[key];
});
valuesRef.current = next;
return next;
});
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setSubmitting(true);
setSubmitError(null);
try {
const validFields = schema?.fields || [];
const validFieldIds = new Set(validFields.map(f => f.id));
// Always include standard Log Visit field IDs
['select_store', 'date_of_visit', 'time_of_visit', 'upload_image', 'daily_log', 'route_code'].forEach(id => validFieldIds.add(id));
const payload: Record<string, any> = {};
validFieldIds.forEach(fieldId => {
const val = valuesRef.current[fieldId];
if (val !== undefined && val !== null && val !== '') {
payload[fieldId] = val;
}
});
// Handle image upload if present
let uploadedFiles: any[] = [];
const imgVal = valuesRef.current.upload_image;
const fileList = Array.isArray(imgVal) ? imgVal : (imgVal instanceof File ? [imgVal] : []);
for (const fileItem of fileList) {
if (fileItem instanceof File) {
const fileMeta = await client.uploadFile(fileItem, {
activityId,
fieldId: 'upload_image',
});
uploadedFiles.push(fileMeta);
} else {
uploadedFiles.push(fileItem);
}
}
payload['upload_image'] = uploadedFiles;
console.log('[LogVisitForm] Submitting clean startInstance payload:', payload);
const res: any = await client.startInstance(activityId, payload);
const chainSource = res?.activity_chain || schema?.activity_chain || [];
if (chainSource && chainSource.length > 0) {
const nextAct = chainSource[0];
console.log('[LogVisitForm] Activity chain detected, transitioning to DynamicForm:', nextAct);
onActivityChange?.(nextAct.activity_name);
setChainedActivity({
activityId: nextAct.activity_uid,
instanceId: res?.instance_id,
prefillData: { ...valuesRef.current },
});
} else {
onSuccess?.();
}
} catch (err: any) {
setSubmitError(err?.message || 'Failed to log visit.');
} finally {
setSubmitting(false);
}
};
// If activity chain triggered (e.g. Productivity of Visit), render DynamicForm seamlessly
if (chainedActivity) {
return (
<DynamicForm
client={client}
activityId={chainedActivity.activityId}
instanceId={chainedActivity.instanceId}
customPrefillData={chainedActivity.prefillData}
onSuccess={onSuccess}
onCancel={onCancel}
onActivityChange={onActivityChange}
/>
);
}
if (loadingSchema) {
return (
<div className="flex justify-center items-center py-12">
<Spinner size={24} label="Loading Log Visit form..." />
</div>
);
}
const fields = schema?.fields || [];
return (
<form onSubmit={handleSubmit} className="flex flex-col gap-4">
{fields.map(f => {
const fieldId = f.id;
const lowerId = fieldId.toLowerCase();
const lowerName = f.name.toLowerCase();
const isHidden = schema?.field_defaults?.[fieldId]?.hidden === true || (f.properties as any)?.hidden === true;
// Skip daily_log and route_code (or hidden fields) from visual rendering
if (
isHidden ||
lowerId === 'daily_log' ||
lowerId === 'field_1785225403902' ||
lowerId === 'route_code' ||
lowerId === 'field_1785311859486' ||
lowerName === 'daily log' ||
lowerName === 'route code'
) {
return null;
}
const type = f.data_type;
const val = values[fieldId];
const isDisabled = schema?.field_defaults?.[fieldId]?.disabled === true || f.properties?.disabled === true;
if (type === 'wf_lookup' || lowerId === 'select_store' || lowerName.includes('select store')) {
return (
<div key={fieldId} className="relative">
<Select
label={f.name}
required={f.mandatory}
value={(val as string) || ''}
options={[{ value: '', label: `Select ${f.name}...` }, ...storeOptions]}
onDropdownOpen={handleStoreDropdownOpen}
onChange={e => handleStoreSelect(fieldId, e.target.value)}
disabled={isDisabled}
/>
{fetchingStores && (
<div className="absolute right-3 top-9">
<Spinner size={16} />
</div>
)}
</div>
);
}
if (type.startsWith('date')) {
return (
<DateField
key={fieldId}
label={f.name}
required={f.mandatory}
disabled={isDisabled}
value={(val as string) || ''}
onChange={v => {
setValues(p => {
const next = { ...p, [fieldId]: v, date_of_visit: v };
valuesRef.current = next;
return next;
});
}}
/>
);
}
if (type.startsWith('time')) {
return (
<TimeField
key={fieldId}
label={f.name}
required={f.mandatory}
disabled={isDisabled}
value={(val as string) || ''}
onChange={v => {
setValues(p => {
const next = { ...p, [fieldId]: v, time_of_visit: v };
valuesRef.current = next;
return next;
});
}}
/>
);
}
if (type === 'image' || type === 'file') {
return (
<FileInput
key={fieldId}
label={f.name}
type={type}
required={f.mandatory}
value={val || []}
onChange={v => {
setValues(p => {
const next = { ...p, [fieldId]: v, upload_image: v };
valuesRef.current = next;
return next;
});
}}
/>
);
}
return (
<TextField
key={fieldId}
label={f.name}
required={f.mandatory}
type={type}
value={(val as string) || ''}
onChange={v => {
setValues(p => {
const next = { ...p, [fieldId]: v };
valuesRef.current = next;
return next;
});
}}
/>
);
})}
{submitError && <div className="text-sm text-ruby-600 mt-2">{submitError}</div>}
<div className="flex items-center justify-end gap-3 mt-4 pt-4 border-t border-border-subtle">
{onCancel && (
<Button type="button" variant="secondary" onClick={onCancel} disabled={submitting}>
Cancel
</Button>
)}
<Button type="submit" disabled={Boolean(submitting || fetchingDailyLog)}>
{submitting ? 'Submitting...' : 'Log Visit'}
</Button>
</div>
</form>
);
}

View File

@ -3,11 +3,13 @@ import { Input } from '../../reusable/Input';
export function DateField({ export function DateField({
label, label,
required, required,
disabled,
value, value,
onChange, onChange,
}: { }: {
label: string; label: string;
required?: boolean; required?: boolean;
disabled?: boolean;
value: string; value: string;
onChange: (val: string) => void; onChange: (val: string) => void;
}) { }) {
@ -15,6 +17,7 @@ export function DateField({
<Input <Input
label={label} label={label}
required={required} required={required}
disabled={disabled}
type="date" type="date"
value={value ?? ''} value={value ?? ''}
onChange={(e) => onChange(e.target.value)} onChange={(e) => onChange(e.target.value)}

View File

@ -3,11 +3,13 @@ import { Input } from '../../reusable/Input';
export function TimeField({ export function TimeField({
label, label,
required, required,
disabled,
value, value,
onChange, onChange,
}: { }: {
label: string; label: string;
required?: boolean; required?: boolean;
disabled?: boolean;
value: string; value: string;
onChange: (val: string) => void; onChange: (val: string) => void;
}) { }) {
@ -15,6 +17,7 @@ export function TimeField({
<Input <Input
label={label} label={label}
required={required} required={required}
disabled={disabled}
type="time" type="time"
value={value ?? ''} value={value ?? ''}
onChange={(e) => onChange(e.target.value)} onChange={(e) => onChange(e.target.value)}

View File

@ -0,0 +1,2 @@
export * from './DynamicForm';
export * from './LogVisitForm';

View File

@ -20,6 +20,7 @@ export interface SelectProps extends SelectHTMLAttributes<HTMLSelectElement> {
className?: string; className?: string;
/** Disable search header filter if set to false */ /** Disable search header filter if set to false */
searchable?: boolean; searchable?: boolean;
onDropdownOpen?: () => void;
} }
/** Custom searchable select component using React Portal to prevent container clipping. */ /** Custom searchable select component using React Portal to prevent container clipping. */
@ -33,6 +34,7 @@ export function Select({
disabled, disabled,
placeholder, placeholder,
searchable = true, searchable = true,
onDropdownOpen,
...rest ...rest
}: SelectProps) { }: SelectProps) {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
@ -123,7 +125,13 @@ export function Select({
{/* Trigger Box */} {/* Trigger Box */}
<div <div
onClick={() => !disabled && setIsOpen(!isOpen)} onClick={() => {
if (!disabled) {
const next = !isOpen;
setIsOpen(next);
if (next) onDropdownOpen?.();
}
}}
className={cn( className={cn(
"relative bg-card rounded-md h-[42px] border px-3 flex items-center justify-between cursor-pointer transition-all duration-150 select-none", "relative bg-card rounded-md h-[42px] border px-3 flex items-center justify-between cursor-pointer transition-all duration-150 select-none",
disabled && "opacity-60 cursor-not-allowed bg-slate-50", disabled && "opacity-60 cursor-not-allowed bg-slate-50",

View File

@ -5,7 +5,7 @@ import { CallDetail } from '../components/dv';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { Button } from '../components/buttons/Button'; import { Button } from '../components/buttons/Button';
import { Plus } from 'lucide-react'; import { Plus } from 'lucide-react';
import { DynamicForm } from '../components/forms/DynamicForm'; import { DynamicForm, LogVisitForm } from '../components/forms';
import { ORDER_BOOKING } from '../api/config'; import { ORDER_BOOKING } from '../api/config';
import { orderBookingClient } from '../api/clients'; import { orderBookingClient } from '../api/clients';
@ -185,10 +185,8 @@ export function CallsPage() {
title={createTitle} title={createTitle}
width="md" width="md"
> >
<DynamicForm <LogVisitForm
client={orderBookingClient} client={orderBookingClient}
activityId={ORDER_BOOKING.activities.LOG_VISIT.uid}
initialActivityName="Log Visit"
onSuccess={() => { onSuccess={() => {
setIsCreating(false); setIsCreating(false);
setRefreshKey(k => k + 1); setRefreshKey(k => k + 1);

View File

@ -5,7 +5,7 @@ import { CallDetail } from '../components/dv';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { Button } from '../components/buttons/Button'; import { Button } from '../components/buttons/Button';
import { Plus } from 'lucide-react'; import { Plus } from 'lucide-react';
import { DynamicForm } from '../components/forms/DynamicForm'; import { DynamicForm, LogVisitForm } from '../components/forms';
import { ORDER_BOOKING } from '../api/config'; import { ORDER_BOOKING } from '../api/config';
import { orderBookingClient } from '../api/clients'; import { orderBookingClient } from '../api/clients';
import { useAuth } from '../auth/context'; import { useAuth } from '../auth/context';
@ -190,10 +190,8 @@ export function MyCallsPage() {
title={createTitle} title={createTitle}
width="md" width="md"
> >
<DynamicForm <LogVisitForm
client={orderBookingClient} client={orderBookingClient}
activityId={ORDER_BOOKING.activities.LOG_VISIT.uid}
initialActivityName="Log Visit"
onSuccess={() => { onSuccess={() => {
setIsCreating(false); setIsCreating(false);
setRefreshKey(k => k + 1); setRefreshKey(k => k + 1);

View File

@ -5,8 +5,7 @@ import { OrderDetail } from '../components/dv';
import { useState } from 'react'; import { useState } from 'react';
import { Button } from '../components/buttons/Button'; import { Button } from '../components/buttons/Button';
import { Plus } from 'lucide-react'; import { Plus } from 'lucide-react';
import { DynamicForm } from '../components/forms/DynamicForm'; import { LogVisitForm } from '../components/forms';
import { ORDER_BOOKING } from '../api/config';
import { orderBookingClient } from '../api/clients'; import { orderBookingClient } from '../api/clients';
import { useAuth } from '../auth/context'; import { useAuth } from '../auth/context';
@ -46,10 +45,8 @@ export function MyOrdersPage() {
title={createTitle} title={createTitle}
width="md" width="md"
> >
<DynamicForm <LogVisitForm
client={orderBookingClient} client={orderBookingClient}
activityId={ORDER_BOOKING.activities.LOG_VISIT.uid}
initialActivityName="Place Order"
onSuccess={() => { onSuccess={() => {
setIsCreating(false); setIsCreating(false);
setRefreshKey(k => k + 1); setRefreshKey(k => k + 1);

View File

@ -5,8 +5,7 @@ import { OrderDetail } from '../components/dv';
import { useState } from 'react'; import { useState } from 'react';
import { Button } from '../components/buttons/Button'; import { Button } from '../components/buttons/Button';
import { Plus } from 'lucide-react'; import { Plus } from 'lucide-react';
import { DynamicForm } from '../components/forms/DynamicForm'; import { LogVisitForm } from '../components/forms';
import { ORDER_BOOKING } from '../api/config';
import { orderBookingClient } from '../api/clients'; import { orderBookingClient } from '../api/clients';
export function OrdersPage() { export function OrdersPage() {
@ -40,10 +39,8 @@ export function OrdersPage() {
title={createTitle} title={createTitle}
width="md" width="md"
> >
<DynamicForm <LogVisitForm
client={orderBookingClient} client={orderBookingClient}
activityId={ORDER_BOOKING.activities.LOG_VISIT.uid}
initialActivityName="Place Order"
onSuccess={() => { onSuccess={() => {
setIsCreating(false); setIsCreating(false);
setRefreshKey(k => k + 1); setRefreshKey(k => k + 1);