Skip to main content
The Locations Management interface allows administrators to maintain geographic data used throughout AutoLog, including countries, cities, and parking facilities.

Overview

Location management is divided into three main areas:
  • Countries - Country-level geographic data
  • Cities - City/municipality information
  • Parkings - Parking facility locations (future)
This geographic hierarchy ensures consistent location data across user profiles, vehicle assignments, and operational reporting.

Countries Management

Accessing Countries

Navigate to Administration > Locations > Countries to manage country data.

Permissions Required

ActionPermission
View countriesver_paises
Create countriescrear_paises
Edit countrieseditar_paises
Delete countrieseliminar_paises or editar_paises
Admin users have access to all location management features by default.

Creating a Country

1

Open Country Form

Click the New Country button in the toolbar
2

Enter Country Name

nombre
string
required
Country name (2-60 characters)
Examples:
  • Honduras
  • Guatemala
  • El Salvador
3

Save

Click Save to create the country. The form validates:
  • Minimum 2 characters
  • Maximum 60 characters
  • Required field (cannot be empty)
Validation Schema:
const validationSchema = yup.object({
  nombre: yup
    .string()
    .transform((v) => (typeof v === 'string' ? v.trim() : v))
    .min(2, 'Mínimo 2 caracteres')
    .max(60, 'Máximo 60 caracteres')
    .required('Requerido'),
});

Editing a Country

To modify an existing country:
  1. Click the three-dot menu on the country row
  2. Select Edit
  3. Update the country name
  4. Click Save
The country is updated using:
await updateCountry(countryId, {
  id: countryId,
  nombre: trimmedName
});

Deleting a Country

Deleting a country that is referenced by cities or users may cause data integrity issues. Consider the impact before deletion.
To delete a country:
  1. Click the three-dot menu on the country row
  2. Select Delete (if available in your configuration)
  3. Confirm the deletion
Delete functionality is currently commented out in the UI but can be enabled by uncommenting the delete menu item in /pages/Administration/Locations/Countries.jsx:382-389.

Searching Countries

Use the search bar to filter countries by name:
  • Real-time filtering as you type
  • Case-insensitive matching
  • Click the X icon to clear search

Cities Management

Accessing Cities

Navigate to Administration > Locations > Cities to manage city data.

Permissions Required

ActionPermission
View citiesver_ciudades
Create citiescrear_ciudades
Edit citieseditar_ciudades
Delete citieseliminar_ciudades or editar_ciudades

Creating a City

Cities must be associated with a country.
1

Open City Form

Click the New City button in the toolbar
2

Enter City Details

nombre
string
required
City name (minimum 2 characters)
id_pais
select
required
Select the country this city belongs to
3

Save

Click Save to create the city
Validation Schema:
const validationSchema = yup.object({
  nombre: yup
    .string()
    .transform((v) => (typeof v === 'string' ? v.trim() : v))
    .min(2, 'Mínimo 2 caracteres')
    .required('Requerido'),
  id_pais: yup.string().required('Debes seleccionar un país'),
});

Editing a City

To modify an existing city:
  1. Click the three-dot menu on the city row
  2. Select Edit
  3. Update the city name or country
  4. Click Save
Changing a city’s country association may affect users and vehicles assigned to that city. Verify impact before saving.

Deleting a City

To delete a city:
  1. Click the three-dot menu on the city row
  2. Select Delete
  3. Confirm the action
Deleting a city removes it from user profiles and may affect location-based reports. Ensure no active users or assets are assigned to this city.

Searching Cities

The city search filters by:
  • City name
  • Country name (if provided by backend as pais or pais_nombre)
Search is performed in real-time with case-insensitive matching.

Cities Display

Cities are displayed in a table with:
ColumnDescription
NameCity name
CountryCountry name in a soft chip
ActionsEdit/Delete menu
Country information appears as a colored chip for quick visual reference.

Data Loading

Countries Loading

Countries are loaded using:
const data = await getCountries();
setCountries(Array.isArray(data) ? data : []);

Cities Loading

Cities and countries are loaded in parallel for efficiency:
const [citiesData, countriesData] = await Promise.all([
  getCities(),
  getCountries(),
]);
This ensures:
  • Fast page load times
  • Country dropdown is immediately available
  • Reduced waiting time for users

UI States and Error Handling

Loading State

While data is loading:
  • Circular progress indicator displayed
  • Table is hidden
  • User cannot perform actions

Error State

If data loading fails:
  • Error card displayed with descriptive message
  • Retry button to reload data
  • Network errors are detected with regex: /failed to fetch|network/i

Empty State

When no locations exist:
  • Icon with “No data” message
  • Encouragement to create first entry
  • New button remains available

No Search Results

When search yields no matches:
  • “No matches found” message in table
  • Suggestion to clear or modify search
  • All data preserved, only display filtered

Location Services API

Countries API

import {
  getCountries,
  addCountry,
  updateCountry,
  deleteCountry,
} from '@/services/LocationServices';
Get all countries:
const countries = await getCountries();
// Returns: Array of { id, nombre }
Create country:
const result = await addCountry({ nombre: 'Nicaragua' });
Update country:
const result = await updateCountry(countryId, {
  id: countryId,
  nombre: 'Updated Name'
});
Delete country:
const result = await deleteCountry(countryId);

Cities API

import {
  getCities,
  addCity,
  updateCity,
  deleteCity,
} from '@/services/LocationServices';
Get all cities:
const cities = await getCities();
// Returns: Array of { id, nombre, id_pais, pais_nombre }
Create city:
const result = await addCity({
  nombre: 'Tegucigalpa',
  id_pais: '1'
});
Update city:
const result = await updateCity(cityId, {
  id: cityId,
  nombre: 'Updated Name',
  id_pais: '1'
});
Delete city:
const result = await deleteCity(cityId);

Integration with User Management

Locations integrate with user management:

User City Assignment

When creating or editing users:
  1. Cities are loaded as autocomplete options
  2. User selects city from dropdown
  3. City ID is stored in id_ciudad field
  4. City name is displayed in user table
<Autocomplete
  options={ciudades}
  getOptionLabel={(opt) => opt?.nombre ?? opt?.ciudad ?? ''}
  value={ciudades.find(c => String(c.id) === String(formik.values.ciudad)) || null}
  onChange={(_, opt) => formik.setFieldValue('ciudad', opt ? String(opt.id) : '')}
/>

City Resolution

User city names are resolved using:
const getCiudadNombre = useCallback(
  (id) => ciudades.find(c => String(c.id) === String(id))?.nombre || '',
  [ciudades]
);

Best Practices

Location Data Management
  1. Standardize Names: Use official country and city names
  2. Avoid Duplicates: Check for existing entries before creating new ones
  3. Maintain Hierarchy: Always assign cities to correct countries
  4. Plan Before Deleting: Verify no users or assets depend on location
  5. Regular Audits: Review location data quarterly for accuracy
Data Integrity Warnings
  • Deleting a country with associated cities will cause orphaned records
  • Deleting a city assigned to users will break user profiles
  • Always check dependencies before deletion
  • Consider deactivation instead of deletion for historical data
  • Backup location data before bulk changes

Troubleshooting

Countries Not Loading

  1. Verify ver_paises permission
  2. Check network connection
  3. Look for errors in browser console
  4. Ensure LocationServices endpoints are configured
  5. Click Retry button if error state is shown

Cities Not Loading

  1. Verify ver_ciudades permission
  2. Check if countries loaded successfully (cities depend on countries)
  3. Review network tab for failed API calls
  4. Verify backend returns proper format: { id, nombre, id_pais, pais_nombre }

Country Dropdown Empty in City Form

  1. Ensure countries were loaded before opening form
  2. Check countriesList state in component
  3. Verify parallel loading didn’t fail for countries
  4. Reload page to trigger fresh data fetch

Save Operations Failing

  1. Check form validation errors (red text below fields)
  2. Verify required fields are filled
  3. Ensure country is selected for cities
  4. Check backend logs for validation errors
  5. Verify you have create/edit permissions

Search Not Working

  1. Ensure data has loaded (not in loading state)
  2. Try clearing search and re-entering
  3. Check if special characters are causing issues
  4. Verify search term matches actual data

Performance Considerations

Lazy Loading

Location components implement efficient loading patterns:
  • Data loaded only when page is accessed
  • Parallel requests for cities and countries
  • Minimal re-renders with React hooks

Filtering Performance

Search filtering uses useMemo for optimal performance:
const filtered = useMemo(() => {
  const s = search.toLowerCase();
  return cities.filter(c => {
    const cityName = (c.nombre || '').toLowerCase();
    const countryName = (c.pais || '').toLowerCase();
    return cityName.includes(s) || countryName.includes(s);
  });
}, [cities, search]);
Filtering recalculates only when cities or search changes.

Parkings Management

AutoLog includes a complete parking facility management system for tracking vehicle parking locations.

Overview

The Parkings feature (/parkings) allows you to:
  • Create and manage parking location records
  • Associate parking spots with cities
  • Track available parking facilities
  • Filter and search parking locations
  • Assign vehicles to specific parking spots

Data Structure

Each parking record includes:
{
  id_ubicacion: 5,
  nombre_ubicacion: "Main Office Parking - Building A",
  id_ciudad: 3,
  ciudad: "San Pedro Sula",  // Auto-populated from city relationship
  nombre_ciudad: "San Pedro Sula"
}

Creating a Parking Location

1

Navigate to Parkings

Go to AdministrationParkings (/parkings)
2

Click Create

Click the + Add Parking button (requires crear_estacionamiento permission)
3

Fill Details

Enter the parking information:
  • Location Name (nombre_ubicacion): Descriptive name (min 2 characters, required)
  • City (id_ciudad): Select from configured cities (required)
4

Submit

Click Save to create the parking location

Permissions

ActionPermissionDescription
View parkingsver_estacionamientosView parking list
Create parkingcrear_estacionamientoAdd new parking locations
Edit parkingeditar_estacionamientoModify existing parkings
Delete parkingeliminar_estacionamientoRemove parking locations

Search and Filter

The parkings list supports real-time search:
  • Search by parking name
  • Search by city name
  • Case-insensitive matching
// Example: Filtering parkings
const filtered = parkings.filter((p) => {
  const name = (p.nombre_ubicacion || "").toLowerCase();
  const cityName = (p.ciudad || p.nombre_ciudad || "").toLowerCase();
  return name.includes(searchTerm) || cityName.includes(searchTerm);
});

API Services

From ParkingServices.jsx: getParkings()
  • Returns: Array of parking objects
  • Endpoint: endpoints.getParkings
addParking(parking)
  • Parameters: { nombre_ubicacion, id_ciudad }
  • Returns: Created parking object
updateParking(id, parking)
  • Parameters: Parking ID and updated data
  • Returns: Updated parking object
deleteParking(id)
  • Parameters: Parking ID
  • Returns: Success confirmation

Validation Rules

From the Yup schema:
{
  nombre_ubicacion: yup.string()
    .transform((v) => typeof v === "string" ? v.trim() : v)
    .min(2, "Minimum 2 characters")
    .required("Required"),
  id_ciudad: yup.string()
    .required("Must select a city")
}

Integration with Vehicles

Parkings can be assigned to vehicles through the id_ubicacion_actual field, enabling:
  • Current vehicle location tracking
  • Parking utilization reports
  • Location-based vehicle searches

Build docs developers (and LLMs) love