sortBy(function ($country) { return $country->name; }); $activities = Activity::all()->sortBy(function ($activity) { return $activity->name; }); return $this->renderAdminView('@globallists/admin/index.twig', [ 'countriesCount' => $countriesCount, 'statesCount' => $statesCount, 'citiesCount' => $citiesCount, 'activitiesCount' => $activitiesCount, 'countries' => $countries, 'activities' => $activities, 'title' => 'Gerenciamento de Listas Globais' ]); } /** * List all activities. * * @return Response */ public function activitiesIndex(): Response { $activities = Activity::orderBy('activities_id')->get(); return $this->renderAdminView('@globallists/admin/activities.twig', [ 'activities' => $activities, 'title' => 'Gerenciar Atividades', 'current_locale' => \Kernel\Translator::getLocale() ?: 'pt_BR' ]); } /** * Save an activity. * * @param Request $request * @return Response */ public function activitySave(Request $request): Response { $id = $request->request->get('activities_id'); $name = $request->request->get('activities_name'); $type = $request->request->get('activities_type'); $locale = \Kernel\Translator::getLocale() ?: 'pt_BR'; if ($id) { $activity = Activity::find($id); if ($activity) { $names = $activity->activities_name; if (!is_array($names)) { $names = ['pt_BR' => $names]; } $names[$locale] = $name; $activity->update([ 'activities_name' => $names, 'activities_type' => $type, 'activities_slug' => $this->slugify($name) ]); } } else { Activity::create([ 'activities_name' => [$locale => $name], 'activities_type' => $type, 'activities_slug' => $this->slugify($name) ]); } return $this->redirect('/admin/globallists/activities'); } /** * Delete an activity. * * @param int $id * @return Response */ public function activityDelete(int $id): Response { Activity::where('activities_id', $id)->delete(); return $this->redirect('/admin/globallists/activities'); } /** * API: Get cities by state. * * @param Request $request * @param string $stateId * @return Response */ public function apiGetCities(Request $request, string $stateId): Response { try { $cities = City::where('cities_state_id', $stateId) ->orderBy('cities_name') ->get(); $data = $cities->map(function ($city) { return [ 'id' => $city->cities_id, 'name' => (string) $city->cities_name ]; })->values()->all(); return new Response(json_encode($data, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR), 200, ['Content-Type' => 'application/json']); } catch (\Throwable $e) { return new Response(json_encode(['error' => $e->getMessage()]), 500, ['Content-Type' => 'application/json']); } } /** * API: Get states by country. * * @param Request $request * @param string $countryId * @return Response */ public function apiGetStates(Request $request, string $countryId): Response { try { $states = State::where('states_country_id', $countryId) ->orderBy('states_name') ->get(); $data = $states->map(function ($state) { return [ 'id' => $state->states_id, 'name' => $state->states_name . ' (' . $state->states_uf . ')' ]; })->values()->all(); return new Response(json_encode($data, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR), 200, ['Content-Type' => 'application/json']); } catch (\Throwable $e) { return new Response(json_encode(['error' => $e->getMessage()]), 500, ['Content-Type' => 'application/json']); } } /** * API: Search activities. * * @param Request $request * @return Response */ public function apiSearchActivities(Request $request): Response { $query = $request->query->get('q'); $locale = \Kernel\Translator::getLocale() ?: 'pt_BR'; // Search in the current locale JSON key $activities = Activity::where('activities_name->' . $locale, 'LIKE', "%{$query}%") ->orWhere('activities_name->pt_BR', 'LIKE', "%{$query}%") // Fallback search in pt_BR ->limit(20) ->get(); // Map to include the translated name $results = $activities->map(function ($activity) { return [ 'activities_id' => $activity->activities_id, 'activities_name' => $activity->name // Uses the accessor we added ]; }); return new Response(json_encode($results, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR), 200, ['Content-Type' => 'application/json']); } /** * API: Lookup location by IBGE code or UF/City name. * * @param Request $request * @return Response */ public function apiLookupLocation(Request $request): Response { $ibge = $request->query->get('ibge'); $uf = $request->query->get('uf'); $cityName = $request->query->get('city'); if ($ibge) { $city = City::where('cities_ibge_code', $ibge)->first(); if ($city) { return new Response(json_encode([ 'city_id' => $city->cities_id, 'state_id' => $city->cities_state_id ], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR), 200, ['Content-Type' => 'application/json']); } } if ($uf && $cityName) { $state = State::where('states_uf', $uf)->first(); if ($state) { $city = City::where('cities_state_id', $state->states_id) ->where('cities_name', $cityName) ->first(); if ($city) { return new Response(json_encode([ 'city_id' => $city->cities_id, 'state_id' => $state->states_id ], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR), 200, ['Content-Type' => 'application/json']); } } } return new Response(json_encode(['error' => 'Location not found'], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR), 404, ['Content-Type' => 'application/json']); } /** * Simple slugify helper. */ protected function slugify($text) { $text = preg_replace('~[^\pL\d]+~u', '-', $text); $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text); $text = preg_replace('~[^-\w]+~', '', $text); $text = trim($text, '-'); $text = preg_replace('~-+~', '-', $text); $text = strtolower($text); if (empty($text)) { return 'n-a'; } return $text; } }