diff --git a/app/Domains/Contact/ManageContactAddresses/Services/RemoveAddressFromContact.php b/app/Domains/Contact/ManageContactAddresses/Services/RemoveAddressFromContact.php index 176fa9b6f..868b38324 100644 --- a/app/Domains/Contact/ManageContactAddresses/Services/RemoveAddressFromContact.php +++ b/app/Domains/Contact/ManageContactAddresses/Services/RemoveAddressFromContact.php @@ -72,6 +72,10 @@ private function validate(): void private function remove(): void { $this->contact->addresses()->detach($this->address); + + if ($this->address->contacts()->count() === 0) { + $this->address->delete(); + } } private function createFeedItem(): void diff --git a/app/Domains/Contact/ManageContactAddresses/Web/Controllers/ContactModuleAddressController.php b/app/Domains/Contact/ManageContactAddresses/Web/Controllers/ContactModuleAddressController.php index 24e6b6643..4fd33c496 100644 --- a/app/Domains/Contact/ManageContactAddresses/Web/Controllers/ContactModuleAddressController.php +++ b/app/Domains/Contact/ManageContactAddresses/Web/Controllers/ContactModuleAddressController.php @@ -8,6 +8,7 @@ use App\Domains\Vault\ManageAddresses\Services\CreateAddress; use App\Domains\Vault\ManageAddresses\Services\UpdateAddress; use App\Http\Controllers\Controller; +use App\Models\Address; use App\Models\Contact; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; @@ -31,7 +32,12 @@ public function store(Request $request, int $vaultId, int $contactId) 'longitude' => null, ]; - $address = (new CreateAddress())->execute($data); + if (! $request->input('existing_address')) { + $address = (new CreateAddress())->execute($data); + } else { + $address = Address::where('vault_id', $vaultId) + ->findOrFail($request->input('existing_address_id')); + } (new AssociateAddressToContact())->execute([ 'account_id' => Auth::user()->account_id, diff --git a/app/Domains/Contact/ManageContactAddresses/Web/ViewHelpers/ModuleContactAddressesViewHelper.php b/app/Domains/Contact/ManageContactAddresses/Web/ViewHelpers/ModuleContactAddressesViewHelper.php index 088c0c9ca..b99f943cc 100644 --- a/app/Domains/Contact/ManageContactAddresses/Web/ViewHelpers/ModuleContactAddressesViewHelper.php +++ b/app/Domains/Contact/ManageContactAddresses/Web/ViewHelpers/ModuleContactAddressesViewHelper.php @@ -12,12 +12,12 @@ class ModuleContactAddressesViewHelper { public static function data(Contact $contact, User $user): array { - $activeAddressesCollection = $contact->addresses() + $contactActiveAddressesCollection = $contact->addresses() ->wherePivot('is_past_address', false) ->get() ->map(fn (Address $address) => self::dto($contact, $address, $user)); - $inactiveAddressesCollection = $contact->addresses() + $contactInactiveAddressesCollection = $contact->addresses() ->wherePivot('is_past_address', true) ->get() ->map(fn (Address $address) => self::dto($contact, $address, $user)); @@ -31,10 +31,18 @@ public static function data(Contact $contact, User $user): array 'selected' => false, ]); + $vaultAddressesCollection = $contact->vault->addresses() + ->get() + ->map(fn (Address $address) => [ + 'id' => $address->id, + 'address' => MapHelper::getAddressAsString($address), + ]); + return [ - 'active_addresses' => $activeAddressesCollection, - 'inactive_addresses' => $inactiveAddressesCollection, + 'active_addresses' => $contactActiveAddressesCollection, + 'inactive_addresses' => $contactInactiveAddressesCollection, 'address_types' => $addressTypesCollection, + 'addresses_in_vault' => $vaultAddressesCollection, 'url' => [ 'store' => route('contact.address.store', [ 'vault' => $contact->vault_id, diff --git a/app/Domains/Vault/ManageReports/Web/Controllers/ReportAddressesCitiesController.php b/app/Domains/Vault/ManageReports/Web/Controllers/ReportAddressesCitiesController.php new file mode 100644 index 000000000..a3af22a40 --- /dev/null +++ b/app/Domains/Vault/ManageReports/Web/Controllers/ReportAddressesCitiesController.php @@ -0,0 +1,24 @@ + VaultIndexViewHelper::layoutData($vault), + 'data' => ReportCitiesShowViewHelper::data($vault, $city), + ]); + } +} diff --git a/app/Domains/Vault/ManageReports/Web/Controllers/ReportAddressesController.php b/app/Domains/Vault/ManageReports/Web/Controllers/ReportAddressesController.php new file mode 100644 index 000000000..1a29e7033 --- /dev/null +++ b/app/Domains/Vault/ManageReports/Web/Controllers/ReportAddressesController.php @@ -0,0 +1,23 @@ + VaultIndexViewHelper::layoutData($vault), + 'data' => ReportAddressIndexViewHelper::data($vault), + ]); + } +} diff --git a/app/Domains/Vault/ManageReports/Web/Controllers/ReportAddressesCountriesController.php b/app/Domains/Vault/ManageReports/Web/Controllers/ReportAddressesCountriesController.php new file mode 100644 index 000000000..949a9538a --- /dev/null +++ b/app/Domains/Vault/ManageReports/Web/Controllers/ReportAddressesCountriesController.php @@ -0,0 +1,24 @@ + VaultIndexViewHelper::layoutData($vault), + 'data' => ReportCountriesShowViewHelper::data($vault, $country), + ]); + } +} diff --git a/app/Domains/Vault/ManageReports/Web/ViewHelpers/ReportAddressIndexViewHelper.php b/app/Domains/Vault/ManageReports/Web/ViewHelpers/ReportAddressIndexViewHelper.php new file mode 100644 index 000000000..957153721 --- /dev/null +++ b/app/Domains/Vault/ManageReports/Web/ViewHelpers/ReportAddressIndexViewHelper.php @@ -0,0 +1,60 @@ +addresses() + ->select('id', 'city') + ->whereNotNull('city') + ->withCount('contacts') + ->distinct('city') + ->get() + ->map(fn ($address) => [ + 'id' => $address->id, + 'name' => Str::ucfirst($address->city), + 'contacts' => $address->contacts_count, + 'url' => [ + 'index' => route('vault.reports.addresses.cities.show', [ + 'vault' => $vault->id, + 'city' => urlencode(utf8_encode($address->city)), + ]), + ], + ]) + ->unique('name'); + + // all the countries in the vault + $countries = $vault->addresses() + ->select('id', 'country') + ->whereNotNull('country') + ->withCount('contacts') + ->distinct('country') + ->get() + ->map(fn ($address) => [ + 'id' => $address->id, + 'name' => Str::ucfirst($address->country), + 'contacts' => $address->contacts_count, + 'url' => [ + 'index' => route('vault.reports.addresses.countries.show', [ + 'vault' => $vault->id, + 'country' => urlencode(utf8_encode($address->country)), + ]), + ], + ]) + ->unique('name'); + + return [ + 'cities' => $cities, + 'countries' => $countries, + ]; + } +} diff --git a/app/Domains/Vault/ManageReports/Web/ViewHelpers/ReportCitiesShowViewHelper.php b/app/Domains/Vault/ManageReports/Web/ViewHelpers/ReportCitiesShowViewHelper.php new file mode 100644 index 000000000..fb85d95fc --- /dev/null +++ b/app/Domains/Vault/ManageReports/Web/ViewHelpers/ReportCitiesShowViewHelper.php @@ -0,0 +1,48 @@ +addresses() + ->whereNotNull('city') + ->where('city', Str::ucfirst($city)) + ->orWhere('city', Str::lcfirst($city)) + ->with('contacts') + ->get() + ->map(fn ($address) => [ + 'id' => $address->id, + 'name' => Str::ucfirst($address->city), + 'address' => MapHelper::getAddressAsString($address), + 'contacts' => $address->contacts() + ->get() + ->map(fn (Contact $contact) => ContactCardHelper::data($contact)), + ]); + + $wikipediaInformation = WikipediaHelper::getInformation($city); + + return [ + 'city' => Str::ucfirst($city), + 'addresses' => $addresses, + 'wikipedia' => [ + 'url' => $wikipediaInformation['url'], + 'description' => $wikipediaInformation['description'], + 'thumbnail' => $wikipediaInformation['thumbnail'], + ], + 'url' => [ + 'addresses' => route('vault.reports.addresses.index', [ + 'vault' => $vault->id, + ]), + ], + ]; + } +} diff --git a/app/Domains/Vault/ManageReports/Web/ViewHelpers/ReportCountriesShowViewHelper.php b/app/Domains/Vault/ManageReports/Web/ViewHelpers/ReportCountriesShowViewHelper.php new file mode 100644 index 000000000..c0d9a083c --- /dev/null +++ b/app/Domains/Vault/ManageReports/Web/ViewHelpers/ReportCountriesShowViewHelper.php @@ -0,0 +1,48 @@ +addresses() + ->whereNotNull('country') + ->where('country', Str::ucfirst($country)) + ->orWhere('country', Str::lcfirst($country)) + ->with('contacts') + ->get() + ->map(fn ($address) => [ + 'id' => $address->id, + 'name' => Str::ucfirst($address->country), + 'address' => MapHelper::getAddressAsString($address), + 'contacts' => $address->contacts() + ->get() + ->map(fn (Contact $contact) => ContactCardHelper::data($contact)), + ]); + + $wikipediaInformation = WikipediaHelper::getInformation($country); + + return [ + 'country' => Str::ucfirst($country), + 'addresses' => $addresses, + 'wikipedia' => [ + 'url' => $wikipediaInformation['url'], + 'description' => $wikipediaInformation['description'], + 'thumbnail' => $wikipediaInformation['thumbnail'], + ], + 'url' => [ + 'addresses' => route('vault.reports.addresses.index', [ + 'vault' => $vault->id, + ]), + ], + ]; + } +} diff --git a/app/Domains/Vault/ManageReports/Web/ViewHelpers/ReportIndexViewHelper.php b/app/Domains/Vault/ManageReports/Web/ViewHelpers/ReportIndexViewHelper.php index 5101ba409..ddfa5cc54 100644 --- a/app/Domains/Vault/ManageReports/Web/ViewHelpers/ReportIndexViewHelper.php +++ b/app/Domains/Vault/ManageReports/Web/ViewHelpers/ReportIndexViewHelper.php @@ -10,6 +10,9 @@ public static function data(Vault $vault): array { return [ 'url' => [ + 'addresses' => route('vault.reports.addresses.index', [ + 'vault' => $vault->id, + ]), 'mood_tracking_events' => route('vault.reports.mood_tracking_events.index', [ 'vault' => $vault->id, ]), diff --git a/app/Helpers/WikipediaHelper.php b/app/Helpers/WikipediaHelper.php new file mode 100644 index 000000000..808c96038 --- /dev/null +++ b/app/Helpers/WikipediaHelper.php @@ -0,0 +1,46 @@ + 'query', + 'prop' => 'description|pageimages', + 'titles' => $topic, + 'pithumbsize' => 400, + 'format' => 'json', + ]); + + $url = 'https://en.wikipedia.org/w/api.php?'.$query; + + $response = Http::get($url)->throw(); + + if ($response->json('query.pages.*.missing')[0] === true) { + return [ + 'url' => null, + 'description' => null, + 'thumbnail' => null, + ]; + } + + return [ + 'url' => 'https://en.wikipedia.org/wiki/'.Str::slug($topic), + 'description' => $response->json('query.pages.*.description')[0], + 'thumbnail' => $response->json('query.pages.*.thumbnail.source')[0], + ]; + } +} diff --git a/resources/js/Pages/Vault/Reports/Address/Cities/Index.vue b/resources/js/Pages/Vault/Reports/Address/Cities/Index.vue new file mode 100644 index 000000000..ce68d7786 --- /dev/null +++ b/resources/js/Pages/Vault/Reports/Address/Cities/Index.vue @@ -0,0 +1,123 @@ + + + + + diff --git a/resources/js/Pages/Vault/Reports/Address/Countries/Index.vue b/resources/js/Pages/Vault/Reports/Address/Countries/Index.vue new file mode 100644 index 000000000..d4c7682a8 --- /dev/null +++ b/resources/js/Pages/Vault/Reports/Address/Countries/Index.vue @@ -0,0 +1,123 @@ + + + + + diff --git a/resources/js/Pages/Vault/Reports/Address/Index.vue b/resources/js/Pages/Vault/Reports/Address/Index.vue new file mode 100644 index 000000000..15c8a4a1f --- /dev/null +++ b/resources/js/Pages/Vault/Reports/Address/Index.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/resources/js/Pages/Vault/Reports/Index.vue b/resources/js/Pages/Vault/Reports/Index.vue index de3417348..c40c04246 100644 --- a/resources/js/Pages/Vault/Reports/Index.vue +++ b/resources/js/Pages/Vault/Reports/Index.vue @@ -15,6 +15,11 @@ defineProps({

All the reports