Tutorial

Field Service App

Document service visits with verifiable evidence. For field service companies.

60 min
Intermediate
React Native
1-50 users

Overview

Build a field service app that:
• Documents every service visit
• Records before/after photos
• Captures technician location
• Creates verifiable service logs

Perfect for HVAC, plumbing, electrical, and maintenance companies.

Setup

npx create-expo-app FieldServiceApp
cd FieldServiceApp
npm install @immutis/react-native

# Or add to existing app
npm install @immutis/react-native

Step 1: Authenticate Technician

// services/auth.ts
import { supabase } from '@supabase/supabase-js'

export async function loginTechnician(email: string, password: string) {
  const { data, error } = await supabase.auth.signInWithPassword({
    email,
    password
  })
  
  if (error) throw error
  return data.user
}

Step 2: Before Photo

// screens/ServiceVisit.tsx
import { useImmutis } from '@immutis/react-native'

export function ServiceVisitScreen({ route, navigation }) {
  const { capture } = useImmutis()
  const [step, setStep] = useState('before') // 'before' | 'work' | 'after'
  
  const captureBefore = async () => {
    const evidence = await capture({
      type: 'photo',
      location: true,
      timestamp: true,
      metadata: {
        visitId: visit.id,
        step: 'before',
        technicianId: technician.id
      }
    })
    
    setBeforeEvidence(evidence)
    setStep('work')
  }
  
  return (
    <View>
      <Text>Step: {step.toUpperCase()}</Text>
      <Button onPress={captureBefore} disabled={step !== 'before'}>
        Capture Before Photo
      </Button>
    </View>
  )
}

Step 3: Work Documentation

// Continue documenting during the job
const captureWorkUpdate = async (description: string) => {
  const evidence = await capture({
    type: 'photo',
    location: true,
    timestamp: true,
    metadata: {
      visitId: visit.id,
      step: 'work',
      description // e.g., "Replaced filter", "Fixed leak"
    }
  })
  
  // Work updates create a timeline
  workLogs.push(evidence)
}

Step 4: After Photo

// Capture completion photo
const captureAfter = async () => {
  const evidence = await capture({
    type: 'photo',
    location: true,
    timestamp: true,
    metadata: {
      visitId: visit.id,
      step: 'after'
    }
  })
  
  // Complete the visit
  await completeVisit(visit.id, {
    before: beforeEvidence,
    work: workLogs,
    after: evidence
  })
}

Step 5: Customer Signature

// Capture customer signature
import { SignatureCapture } from 'react-native-signature-canvas'

<SignatureCapture
  onOK={(signature) => saveSignature(signature)}
  onClear={() => setSignature(null)}
/>

// Store with visit
const completeVisit = async (visitId, data) => {
  await db.visit.update({
    where: { id: visitId },
    data: {
      ...data,
      customerSignature: data.signature,
      completedAt: new Date()
    }
  })
}

Step 6: Generate Report

// Generate PDF report for customer
import { PdfGenerator } from '@immutis/reportkit'

async function generateReport(visitId) {
  const visit = await getVisit(visitId)
  
  const pdf = await PdfGenerator.create({
    title: 'Service Report',
    sections: [
      { title: 'Before', image: visit.before.thumbnail },
      { title: 'Work Performed', items: visit.work },
      { title: 'After', image: visit.after.thumbnail },
      { title: 'Location', data: visit.before.location },
      { title: 'Signature', image: visit.customerSignature }
    ]
  })
  
  // Email to customer
  await emailReport(customer.email, pdf)
}

Complete Workflow

1. Technician logs in
2. Capture before photo
3. Document work (multiple photos)
4. Capture after photo
5. Customer signs
6. Generate PDF report

Every service call is now fully documented and verifiable.