Skip to content

Commit

Permalink
feat: add concept of contact card (monicahq/chandler#222)
Browse files Browse the repository at this point in the history
  • Loading branch information
djaiss authored and asbiin committed Mar 31, 2023
1 parent 1eb89fe commit 72f38a0
Show file tree
Hide file tree
Showing 10 changed files with 218 additions and 111 deletions.
33 changes: 33 additions & 0 deletions app/Helpers/ContactCardHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace App\Helpers;

use App\Contact\ManageGroups\Web\ViewHelpers\GroupsViewHelper;
use App\Models\Contact;
use App\Models\User;

class ContactCardHelper
{
/**
* Get all the information about a contact needed to display the contact card
* component.
*
* @param Contact $contact
* @param User $user
* @return array
*/
public static function data(Contact $contact, User $user): array
{
return [
'id' => $contact->id,
'name' => $contact->name,
'age' => $contact->age,
'avatar' => $contact->avatar,
'groups' => GroupsViewHelper::summary($contact),
'url' => route('contact.show', [
'vault' => $contact->vault_id,
'contact' => $contact->id,
]),
];
}
}
2 changes: 2 additions & 0 deletions database/factories/ContactImportantDateTypeFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Database\Factories;

use App\Models\ContactImportantDate;
use App\Models\ContactImportantDateType;
use App\Models\Vault;
use Illuminate\Database\Eloquent\Factories\Factory;
Expand All @@ -25,6 +26,7 @@ public function definition()
return [
'vault_id' => Vault::factory(),
'label' => 'birthdate',
'internal_type' => ContactImportantDate::TYPE_BIRTHDATE,
'can_be_deleted' => true,
];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Contact\ManageLoans\Web\ViewHelpers;

use App\Helpers\ContactCardHelper;
use App\Helpers\DateHelper;
use App\Helpers\MonetaryNumberHelper;
use App\Models\Contact;
Expand Down Expand Up @@ -39,18 +40,10 @@ public static function dtoLoan(Loan $loan, Contact $contact, User $user): array
{
$loaners = $loan->loaners->unique('id');
$loanees = $loan->loanees->unique('id');
$loanersCollection = $loaners->map(function ($loaner) {
return [
'id' => $loaner->id,
'name' => $loaner->name,
];
});
$loaneesCollection = $loanees->map(function ($loanee) {
return [
'id' => $loanee->id,
'name' => $loanee->name,
];
$loanersCollection = $loaners->map(function ($loaner) use ($user) {
return ContactCardHelper::data($loaner, $user);
});
$loaneesCollection = $loanees->map(fn ($loanee) => ContactCardHelper::data($loanee, $user));

return [
'id' => $loan->id,
Expand Down
10 changes: 2 additions & 8 deletions resources/js/Pages/Vault/Dashboard/Partials/Feed/Activity.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,8 @@
</div>
<div class="border-t border-gray-200 px-3 py-2 dark:border-gray-700">
<span class="mr-3 text-sm text-gray-500"> With </span>
<div class="relative mr-3 inline text-sm">
<small-contact top="4px;" />
</div>
<div class="inline text-sm">
<small-contact top="4px;" />
</div>
<div class="relative mr-3 inline text-sm"></div>
<div class="inline text-sm"></div>
</div>
<div class="flex border-t border-gray-200 px-3 py-2 dark:border-gray-700">
<div class="mr-3">
Expand Down Expand Up @@ -72,12 +68,10 @@
</template>

<script>
import SmallContact from '@/Shared/SmallContact.vue';
import HoverMenu from '@/Shared/HoverMenu.vue';
export default {
components: {
SmallContact,
HoverMenu,
},
};
Expand Down
107 changes: 107 additions & 0 deletions resources/js/Shared/ContactCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<template>
<div class="relative inline" :style="'top: ' + top">
<a-popover placement="bottomLeft">
<!-- popup that appears on mouse over -->
<template #content>
<div class="flex">
<!-- avatar -->
<div class="mr-2">
<div v-if="contact.avatar.type === 'svg'" class="h-16 w-16 rounded-full" v-html="contact.avatar.content" />
<img v-else class="h-16 w-16 rounded-full" :src="contact.avatar.content" alt="avatar" />
</div>

<div>
<p class="mb-2 text-lg font-semibold">{{ contact.name }}</p>

<!-- birthdate -->
<p class="flex items-center">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="mr-1 h-4 w-4 text-gray-400">
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 012.25-2.25h13.5A2.25 2.25 0 0121 7.5v11.25m-18 0A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75m-18 0v-7.5A2.25 2.25 0 015.25 9h13.5A2.25 2.25 0 0121 11.25v7.5m-9-6h.008v.008H12v-.008zM12 15h.008v.008H12V15zm0 2.25h.008v.008H12v-.008zM9.75 15h.008v.008H9.75V15zm0 2.25h.008v.008H9.75v-.008zM7.5 15h.008v.008H7.5V15zm0 2.25h.008v.008H7.5v-.008zm6.75-4.5h.008v.008h-.008v-.008zm0 2.25h.008v.008h-.008V15zm0 2.25h.008v.008h-.008v-.008zm2.25-4.5h.008v.008H16.5v-.008zm0 2.25h.008v.008H16.5V15z" />
</svg>

<span v-if="contact.age">{{ contact.age }}</span>
<span v-else class="text-sm italic text-gray-600">Unknown</span>
</p>

<!-- groups -->
<div v-if="contact.groups.length > 0" class="mt-2 flex items-start">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="mr-2 h-4 w-4 text-gray-400">
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M18 18.72a9.094 9.094 0 003.741-.479 3 3 0 00-4.682-2.72m.94 3.198l.001.031c0 .225-.012.447-.037.666A11.944 11.944 0 0112 21c-2.17 0-4.207-.576-5.963-1.584A6.062 6.062 0 016 18.719m12 0a5.971 5.971 0 00-.941-3.197m0 0A5.995 5.995 0 0012 12.75a5.995 5.995 0 00-5.058 2.772m0 0a3 3 0 00-4.681 2.72 8.986 8.986 0 003.74.477m.94-3.197a5.971 5.971 0 00-.94 3.197M15 6.75a3 3 0 11-6 0 3 3 0 016 0zm6 3a2.25 2.25 0 11-4.5 0 2.25 2.25 0 014.5 0zm-13.5 0a2.25 2.25 0 11-4.5 0 2.25 2.25 0 014.5 0z" />
</svg>

<ul>
<li v-for="group in contact.groups" :key="group.id" class="group-list-item">
<inertia-link class="text-blue-500 hover:underline">
{{ group.name }}
</inertia-link>
</li>
</ul>
</div>
</div>
</div>
</template>
<template v-if="showName" #title>
<span>{{ contact.name }}</span>
</template>

<!-- default state -->
<div class="inline-flex items-center text-sm">
<!-- avatar -->
<div class="img relative">
<inertia-link :href="contact.url">
<div v-if="contact.avatar.type === 'svg'" :class="avatarClasses" v-html="contact.avatar.content" />
<img v-else :class="avatarClasses" :src="contact.avatar.content" alt="avatar" />
</inertia-link>
</div>

<!-- name -->
<a v-if="showName" class="colored-link" href="">{{ contact.name }}</a>
</div>
</a-popover>
</div>
</template>

<script>
export default {
components: {},
props: {
top: {
type: String,
default: '0px',
},
contact: {
type: Object,
default: null,
},
avatarClasses: {
type: String,
default: '',
},
displayName: {
type: Boolean,
default: true,
},
},
};
</script>

<style lang="scss" scoped></style>
15 changes: 4 additions & 11 deletions resources/js/Shared/Modules/Loans.vue
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,7 @@
<div v-if="editedLoanId != loan.id" class="mr-3 flex items-center">
<div class="flex -space-x-2 overflow-hidden">
<div v-for="loaner in loan.loaners" :key="loaner.id">
<small-contact
:div-outer-class="'inline-block rounded-full ring-2 ring-white'"
:show-name="false"
:preview-contact-size="30" />
<contact-card :contact="loaner" :avatarClasses="'h-7 w-7 rounded-full mr-2'" :displayName="false" />
</div>
</div>

Expand All @@ -192,10 +189,7 @@
</svg>

<div v-for="loanee in loan.loanees" :key="loanee.id">
<small-contact
:div-outer-class="'inline-block rounded-full ring-2 ring-white'"
:show-name="false"
:preview-contact-size="30" />
<contact-card :contact="loanee" :avatarClasses="'h-7 w-7 rounded-full mr-2'" :displayName="false" />
</div>
</div>

Expand Down Expand Up @@ -227,7 +221,6 @@

<!-- actions -->
<div class="flex items-center justify-between px-3 py-2">
<!-- <small-contact /> -->
<ul class="text-sm">
<!-- settle -->
<li
Expand Down Expand Up @@ -415,9 +408,9 @@ import PrettySpan from '@/Shared/Form/PrettySpan.vue';
import TextInput from '@/Shared/Form/TextInput.vue';
import TextArea from '@/Shared/Form/TextArea.vue';
import Errors from '@/Shared/Form/Errors.vue';
import SmallContact from '@/Shared/SmallContact.vue';
import ContactSelector from '@/Shared/Form/ContactSelector.vue';
import Dropdown from '@/Shared/Form/Dropdown.vue';
import ContactCard from '@/Shared/ContactCard.vue';
export default {
components: {
Expand All @@ -426,9 +419,9 @@ export default {
TextInput,
TextArea,
Errors,
SmallContact,
Dropdown,
ContactSelector,
ContactCard,
},
props: {
Expand Down
66 changes: 0 additions & 66 deletions resources/js/Shared/SmallContact.vue

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -123,21 +123,11 @@ public function it_gets_the_data_transfer_object(): void
$array['currency_name']
);
$this->assertEquals(
[
0 => [
'id' => $contact->id,
'name' => $contact->name,
],
],
$array['loaners']->toArray()
1,
count($array['loaners']->toArray())
);
$this->assertEquals(
[
0 => [
'id' => $otherContact->id,
'name' => $otherContact->name,
],
],
$this->assertCount(
1,
$array['loanees']->toArray()
);
$this->assertEquals(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function it_gets_the_data_needed_for_the_data_transfer_object(): void
[
'id' => $type->id,
'label' => $type->label,
'internal_type' => null,
'internal_type' => 'birthdate',
'can_be_deleted' => true,
'url' => [
'update' => env('APP_URL').'/vaults/'.$vault->id.'/settings/contactImportantDateTypes/'.$type->id,
Expand Down
Loading

0 comments on commit 72f38a0

Please sign in to comment.