Skip to main content

Overview

Sampling point actions provide CRUD operations for sampling points and analytics endpoints for dashboard metrics. All functions are located in src/app/actions/sampling-points.ts.

Sampling Point Operations

getSamplingPointsService

Retrieves a paginated list of sampling points with optional filtering.
params
object
Query parameters for filtering and pagination
page
number
Page number (default: 1)
limit
number
Items per page (default: 10)
Search term for filtering sampling points
data
SamplingPoint[]
Array of sampling point objects
meta
SamplingPointsMeta
Pagination metadata
page
number
Current page number
limit
number
Items per page
total
number
Total number of sampling points
total_pages
number
Total number of pages
has_next
boolean
Whether there is a next page
has_prev
boolean
Whether there is a previous page
import { getSamplingPointsService } from "@/app/actions";

export default async function SamplingPointsPage({ searchParams }) {
  const params = await searchParams;
  const page = parseInt(String(params?.page ?? 1), 10);
  const limit = parseInt(String(params?.limit ?? 10), 10);
  const search = typeof params?.search === "string" ? params.search : "";

  const { data: samplingPoints, meta } = await getSamplingPointsService({ 
    page, 
    limit, 
    search 
  });

  return <SamplingPointTable data={samplingPoints} meta={meta} />;
}
On permission errors (403), this function returns an empty data array with zero total instead of throwing an error.

getSamplingPointService

Retrieves a single sampling point by ID.
id
string
required
Unique sampling point identifier
data
SamplingPoint
Complete sampling point object with parent asset and assignee details
import { getSamplingPointService } from "@/app/actions";

const samplingPoint = await getSamplingPointService("sp-123");

console.log(samplingPoint.name);
console.log(samplingPoint.parent_asset.name);
console.log(samplingPoint.status);
console.log(samplingPoint.assignee?.first_name);

addSamplingPointService

Creates a new sampling point.
payload
AddSamplingPointPayload
required
Sampling point creation data
name
string
required
Sampling point name
tag
string
required
Sampling point tag/identifier
parent_asset
object
required
id
string
required
Parent asset ID
circuit_type
string
required
Circuit type
component_type
string
required
Component type
sample_frequency
string
required
Sample frequency
system_capacity
string
required
System capacity
current_oil_grade
string
required
Current oil grade
status
string
required
Sampling point status
severity
string
required
Severity level
assignee
object
required
id
string
required
Assigned user ID
sampling_route
object
required
id
string
required
Sampling route ID
sampling_port_type
string
required
Sampling port type
sampling_port_location
string
required
Sampling port location
lab_destination
string
required
Lab destination
sampling_volume
string
required
Sampling volume
special_instructions
string
Special instructions
last_sample_date
string
required
Last sample date
effective_date
string
required
Effective date
next_due_date
string
required
Next due date
attachments
array
Attachments array
url
string
Attachment URL
name
string
required
Attachment name
response
ApiResponse
Standard API response object
success
boolean
Whether the operation succeeded
statusCode
number
HTTP status code
message
string
Response message
data
object
Created sampling point data
"use client";
import { addSamplingPointService } from "@/app/actions";
import { AddSamplingPointPayload } from "@/schema";
import { toast } from "sonner";

export function AddSamplingPointForm() {
  const handleSubmit = async (data: AddSamplingPointPayload) => {
    const response = await addSamplingPointService(data);
    
    if (response.success) {
      toast.success("Sampling point added successfully");
      router.push("/sampling-points");
    } else {
      toast.error(response.message || "Failed to add sampling point");
    }
  };

  return <form onSubmit={handleSubmit}>...</form>;
}

editSamplingPointService

Updates an existing sampling point.
id
string
required
Sampling point ID to update
payload
AddSamplingPointPayload
required
Updated sampling point data (same structure as addSamplingPointService)
response
ApiResponse
Standard API response object
import { editSamplingPointService } from "@/app/actions";
import { toast } from "sonner";

const handleUpdate = async (
  samplingPointId: string,
  data: AddSamplingPointPayload
) => {
  const response = await editSamplingPointService(samplingPointId, data);
  
  if (response.success) {
    toast.success("Sampling point updated successfully");
  } else {
    toast.error(response.message);
  }
};

deleteSamplingPointService

Deletes a sampling point.
id
string
required
Sampling point ID to delete
response
ApiResponse
Standard API response object
import { deleteSamplingPointService } from "@/app/actions";
import { toast } from "sonner";

const handleDelete = async (samplingPointId: string) => {
  const response = await deleteSamplingPointService(samplingPointId);
  
  if (response.success) {
    toast.success("Sampling point deleted successfully");
  } else {
    toast.error(response.message);
  }
};

Analytics Operations

getSamplingPointsAnalyticsService

Retrieves sampling point analytics for dashboard metrics.
data
SamplingPointAnalytics | null
Sampling point analytics data or null on error
total_sampling_points
number
Total number of sampling points
sampling_points_due
number
Number of sampling points due
sampling_points_overdue
number
Number of sampling points overdue
total_trend_percentage
number
Total trend percentage
due_trend_percentage
number
Due trend percentage
overdue_trend_percentage
number
Overdue trend percentage
import { getSamplingPointsAnalyticsService } from "@/app/actions";

export default async function Dashboard() {
  const analytics = await getSamplingPointsAnalyticsService();

  if (!analytics) {
    return <div>Analytics unavailable</div>;
  }

  return (
    <div>
      <MetricCard 
        title="Total Sampling Points" 
        value={analytics.total_sampling_points}
        trend={analytics.total_trend_percentage}
      />
      <MetricCard 
        title="Due" 
        value={analytics.sampling_points_due}
        trend={analytics.due_trend_percentage}
      />
      <MetricCard 
        title="Overdue" 
        value={analytics.sampling_points_overdue}
        trend={analytics.overdue_trend_percentage}
      />
    </div>
  );
}
Returns null on permission errors (403) or network issues instead of throwing.

Type Definitions

SamplingPoint

The complete sampling point object includes extensive details about the sampling point, parent asset, assignee, and sampling route. Key fields:
interface SamplingPoint {
  id: string;
  name: string;
  tag: string;
  parent_asset: {
    id: string;
    name: string;
    tag: string;
    type: string;
    // ... additional asset fields
  };
  circuit_type: string;
  component_type: string;
  sample_frequency: string;
  system_capacity: string;
  current_oil_grade: string;
  status: string;
  severity: string;
  sampling_port_type: string;
  sampling_port_location: string;
  lab_destination: string;
  sampling_volume: string;
  special_instructions: string;
  last_sample_date: number;
  effective_date: number;
  next_due_date: number;
  assignee?: {
    id: string;
    first_name: string;
    last_name: string;
    email: string;
  } | null;
  sampling_route?: {
    id: string;
    name: string;
    description?: string;
  } | null;
  attachments?: Array<{
    name: string;
    url: string;
  }>;
  created_at: number;
  created_at_datetime: string;
  updated_at: number;
  updated_at_datetime: string;
}

SamplingPointAnalytics

interface SamplingPointAnalytics {
  total_sampling_points: number;
  sampling_points_due: number;
  sampling_points_overdue: number;
  total_trend_percentage: number;
  due_trend_percentage: number;
  overdue_trend_percentage: number;
}
Import from the appropriate locations:
import {
  getSamplingPointsService,
  addSamplingPointService,
  editSamplingPointService,
  deleteSamplingPointService,
  getSamplingPointService,
  getSamplingPointsAnalyticsService,
} from "@/app/actions";
import { SamplingPoint, SamplingPointAnalytics } from "@/types";
import { AddSamplingPointPayload, ADD_SAMPLING_POINT_SCHEMA } from "@/schema";
import { ApiResponse } from "@/app/actions";

Build docs developers (and LLMs) love