Skip to content

Resource Management

This page covers how to manage resources in the admin panel: clients, brands, campaigns (production runs), trackers, and locations.

Campaign Management (Clients, Brands, Campaigns)

Clients, brands, and campaigns (production runs) are all managed from a single page — Campaign Management, at /clients — rather than separate list pages. It presents four linked, drill-down columns:

  1. Clients: paginated and searchable
  2. Brands: brands belonging to the selected client
  3. Campaigns: parent production runs ("batches") belonging to the selected brand
  4. Child runs: child production runs belonging to the selected campaign/parent batch

Selecting an item in one column loads and enables the next column. Each column supports adding, editing, and deleting items (edit/delete actions appear on hovering a card), plus its own text filter. On narrower screens the four columns stack into full-width, independently scrollable rows instead of sitting side by side, and selecting an item auto-scrolls the next column into view.

Clients

  • Create, edit, and delete clients
  • Each client card shows its brand count
  • Deleting a client is blocked (with a reason shown in the UI) while it still has brands

Brands

  • Create, edit, and delete brands for the selected client
  • Each brand card shows its campaign (production run) count
  • Deleting a brand is blocked while it still has campaigns

Campaigns (Production Runs)

  • Create, edit, and delete campaigns for the selected brand
  • Each campaign card shows its date range, number of child runs, and total tracker count (own + all children), plus a status badge (for example, active/upcoming/ended, derived from its start/end dates)
  • Each campaign card links directly to its trackers (/trackers/{id}) and to its locations, pre-filtered to that campaign (/locations?campaign_id={id})
  • Deleting a campaign is blocked while it has trackers assigned or child runs

Child Runs

  • Create, edit, and delete child runs under the selected campaign/parent batch
  • Child runs behave like campaigns for tracker/location purposes but are nested under a parent's date window
  • Creating or editing a child run pre-fills the parent's date window as context

CSV Import

Trackers are imported into a specific campaign or child run, not the top-level page. See the Tracker CSV Import guide.

Tracker Management

There's no longer a standalone, global "Trackers" list — the /trackers route now points users to Campaign Management, since a tracker always belongs to a specific campaign or child run. From there, opening a campaign or child run's tracker link (/trackers/{id}) shows that run's tracker view, which allows you to:

  • View trackers in a sortable list or card layout (toggle persists per browser)
  • Sort by tracker name, MAC address, or last report received time (ascending/descending)
  • Create, edit, and delete trackers within that run
  • Move one or more trackers to a different run — by drag-and-drop onto a radial "move wheel," by pasting a list of tracker identifiers (paste-select), or via the move dialog
  • Import trackers from a CSV file (see below)
  • Export the current run's trackers to CSV

Location Management

The admin panel allows you to manage two types of locations with customizable geofence settings, from the /locations page:

Delivery Locations

Delivery locations are places where trackers are delivered. The delivery locations section allows you to:

  • Create new delivery locations
  • Edit existing delivery locations
  • Delete delivery locations
  • View delivery locations on a map with geofence visualization
  • Configure custom geofence sizes for each location

Storage Locations

Storage locations are places where trackers are stored. The storage locations section allows you to:

  • Create new storage locations
  • Edit existing storage locations
  • Delete storage locations
  • View storage locations on a map with geofence visualization
  • Configure custom geofence sizes for each location

Locations can be filtered by brand and by campaign, and the campaign filter is pre-applied when arriving from a campaign card's "locations" link (/locations?campaign_id={id}) in Campaign Management.

Geofence Configuration

Both delivery and storage locations support customizable geofence sizes:

Geofence Settings

  • Default Size: 100 meters
  • Range: 100m to 1000m
  • Increments: 50m steps (100m, 150m, 200m, 250m, etc.)
  • Purpose: Defines the radius around each location for geofence detection

Setting Geofence Size

  1. When creating or editing a location, use the "Geofence Size (meters)" dropdown
  2. Select from predefined options ranging from 100m (Default) to 1000m (Maximum)
  3. The map will show a real-time preview of the geofence circle
  4. The geofence size is displayed in the location details view

Map Visualization

  • Interactive Maps: Both create/edit and detail view pages show the geofence as a colored circle
  • Color Coding: Blue circles for delivery locations, green circles for storage locations
  • Real-time Updates: The circle size updates immediately when changing the geofence setting
  • Transparency: Semi-transparent fill allows viewing map details underneath

Relationship Navigation

The admin panel implements a consistent pattern for navigating between related resources using clickable cards and links, rather than a dedicated "field" component per relationship:

  • Client → Brands: selecting a client card in Campaign Management loads its brands into the next column
  • Brand → Campaigns: selecting a brand card loads its campaigns into the next column
  • Campaign → Child runs: selecting a campaign card loads its child runs into the next column
  • Campaign/Child run → Trackers: each campaign/child-run card links directly to /trackers/{id}
  • Campaign/Child run → Locations: each campaign/child-run card links directly to /locations?campaign_id={id}
  • User → Clients: each user card shows the clients they have access to as chips

Sorting and Caching

The admin panel supports sorting data in tables/cards by various columns. The sorting functionality is implemented both in the frontend and backend:

  1. Frontend Implementation:
  2. Each list/card view maintains its own sorting state (field and order), persisted to local storage per view
  3. Visual indicators show the current sort field and direction
  4. Clicking a sortable column header (or card-sort menu option) toggles between ascending and descending order
  5. Clicking a different column/option sets that as the new sort field with ascending order

  6. Backend Implementation:

  7. API endpoints accept sort_field and sort_order parameters
  8. Sorting is applied before pagination to ensure consistent results
  9. Special handling for null values ensures they appear at the end of sorted lists
  10. For relationship-based sorting, the backend performs additional queries to fetch the related data for sorting

  11. Caching Mechanism:

  12. The backend implements a comprehensive caching strategy that properly handles sorted data
  13. Cache keys include sorting parameters to ensure different sort configurations get different cache entries
  14. Sorting is applied before caching, so cached data is already properly sorted
  15. When retrieving from cache, the correctly sorted data is returned without needing to re-sort
  16. Cache invalidation occurs when records are created, updated, or deleted