Skip to content

Commit

Permalink
feat: display due tasks on the dashboard (monicahq/chandler#197)
Browse files Browse the repository at this point in the history
  • Loading branch information
djaiss authored Aug 28, 2022
1 parent 01edc35 commit 1b11380
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public function store(Request $request, int $vaultId, int $contactId)
public function update(Request $request, int $vaultId, int $contactId, int $taskId)
{
$dueAt = '';
if ($request->input('due_at')) {
if ($request->input('due_at_checked')) {
$dueAt = Carbon::parse($request->input('due_at'))->format('Y-m-d');
}

Expand All @@ -64,7 +64,7 @@ public function update(Request $request, int $vaultId, int $contactId, int $task
'contact_task_id' => $taskId,
'label' => $request->input('label'),
'description' => null,
'due_at' => $dueAt,
'due_at' => $dueAt === '' ? null : $dueAt,
];

$task = (new UpdateContactTask())->execute($data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public function show(Request $request, int $vaultId)
'lastUpdatedContacts' => VaultShowViewHelper::lastUpdatedContacts($vault),
'upcomingReminders' => VaultShowViewHelper::upcomingReminders($vault, Auth::user()),
'favorites' => VaultShowViewHelper::favorites($vault, Auth::user()),
'dueTasks' => VaultShowViewHelper::dueTasks($vault, Auth::user()),
]);
}

Expand Down
46 changes: 46 additions & 0 deletions domains/Vault/ManageVault/Web/ViewHelpers/VaultShowViewHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use App\Helpers\DateHelper;
use App\Models\Contact;
use App\Models\ContactReminder;
use App\Models\ContactTask;
use App\Models\User;
use App\Models\UserNotificationChannel;
use App\Models\Vault;
Expand Down Expand Up @@ -127,4 +128,49 @@ public static function favorites(Vault $vault, User $user): Collection
];
});
}

public static function dueTasks(Vault $vault, User $user): Collection
{
$contactIds = $vault->contacts()->select('id')->get()->toArray();
$tasks = DB::table('contact_tasks')
->where('completed', false)
->whereIn('contact_id', $contactIds)
->where('due_at', '<=', Carbon::now()->addDays(30))
->orderBy('due_at', 'asc')
->get();

return $tasks
->map(function ($task) use ($user) {
$task = ContactTask::find($task->id);
$contact = $task->contact;

return [
'id' => $task->id,
'label' => $task->label,
'description' => $task->description,
'completed' => $task->completed,
'completed_at' => $task->completed_at ? DateHelper::format($task->completed_at, $user) : null,
'due_at' => $task->due_at ? DateHelper::format($task->due_at, $user) : null,
'due_at_late' => optional($task->due_at)->isPast() ?? false,
'url' => [
'toggle' => route('contact.task.toggle', [
'vault' => $contact->vault_id,
'contact' => $contact->id,
'task' => $task->id,
]),
],
'contact' => [
'id' => $contact->id,
'name' => $contact->name,
'avatar' => $contact->avatar,
'url' => [
'show' => route('contact.show', [
'vault' => $contact->vault_id,
'contact' => $contact->id,
]),
],
],
];
});
}
}
2 changes: 2 additions & 0 deletions lang/en/vault.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
'dashboard_reminders_title' => 'Reminders for the next 30 days',
'dashboard_reminders_blank' => 'No upcoming reminders.',
'dashboard_favorites_title' => 'Favorites',
'dashboard_due_tasks_title' => 'Due and upcoming tasks',
'dashboard_due_tasks_blank' => 'No tasks.',

/***************************************************************
* VAULT DASHBOARD REMINDERS
Expand Down
45 changes: 9 additions & 36 deletions resources/js/Pages/Vault/Dashboard/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -98,41 +98,8 @@
<!-- upcoming reminders -->
<upcoming-reminders :data="upcomingReminders" />

<h3 class="mb-3 border-b border-gray-200 pb-1 font-medium">
<span class="relative">
<svg
xmlns="http://www.w3.org/2000/svg"
class="icon-sidebar relative inline h-4 w-4 text-gray-300 hover:text-gray-600"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4" />
</svg>
</span>
Tasks
</h3>
<div class="relative mb-3 flex items-start">
<input
id="remember-me"
name="remember-me"
type="checkbox"
class="focus:ring-3 relative h-4 w-4 rounded border border-gray-300 bg-gray-50 focus:ring-blue-300 dark:border-gray-600 dark:bg-gray-700 dark:ring-offset-gray-800 dark:focus:ring-blue-600" />
<label for="remember-me" class="ml-2 block cursor-pointer text-sm text-gray-900">
Remember mea sdfasdf asdf asdf asdf sdf
</label>
</div>
<div class="flex items-start">
<input
id="remember-me"
name="remember-me"
type="checkbox"
class="focus:ring-3 relative h-4 w-4 rounded border border-gray-300 bg-gray-50 focus:ring-blue-300 dark:border-gray-600 dark:bg-gray-700 dark:ring-offset-gray-800 dark:focus:ring-blue-600" />
<label for="remember-me" class="ml-2 block cursor-pointer text-sm text-gray-900"> Remember me </label>
</div>
<!-- tasks -->
<due-tasks :data="dueTasks" />
</div>
</div>
</div>
Expand All @@ -145,6 +112,7 @@ import Layout from '@/Shared/Layout.vue';
import LastUpdated from '@/Pages/Vault/Dashboard/Partials/LastUpdated.vue';
import UpcomingReminders from '@/Pages/Vault/Dashboard/Partials/UpcomingReminders.vue';
import Favorites from '@/Pages/Vault/Dashboard/Partials/Favorites.vue';
import DueTasks from '@/Pages/Vault/Dashboard/Partials/DueTasks.vue';
import Activity from '@/Pages/Vault/Dashboard/Partials/Feed/Activity.vue';
import Entry from '@/Pages/Vault/Dashboard/Partials/Feed/Entry.vue';
import Goal from '@/Pages/Vault/Dashboard/Partials/Feed/Goal.vue';
Expand All @@ -158,6 +126,7 @@ export default {
LastUpdated,
UpcomingReminders,
Favorites,
DueTasks,
PrettyButton,
Entry,
Activity,
Expand All @@ -183,6 +152,10 @@ export default {
type: Object,
default: null,
},
dueTasks: {
type: Object,
default: null,
},
},
data() {
Expand All @@ -203,7 +176,7 @@ export default {

<style lang="scss" scoped>
.grid {
grid-template-columns: 200px 1fr 300px;
grid-template-columns: 200px 1fr 400px;
}
@media (max-width: 480px) {
Expand Down
136 changes: 136 additions & 0 deletions resources/js/Pages/Vault/Dashboard/Partials/DueTasks.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<template>
<div class="mb-10">
<h3 class="mb-3 border-b border-gray-200 pb-1 font-medium">
<span class="relative">
<svg
xmlns="http://www.w3.org/2000/svg"
class="icon-sidebar relative inline h-4 w-4 text-gray-300 hover:text-gray-600"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4" />
</svg>
</span>

{{ $t('vault.dashboard_due_tasks_title') }}
</h3>

<!-- list of tasks -->
<div v-if="data.length > 0">
<ul class="mb-4 rounded-lg border border-gray-200">
<li
v-for="task in data"
:key="task.id"
class="item-list flex border-b border-gray-200 px-3 py-2 hover:bg-slate-50">
<input
:id="task.id"
v-model="task.completed"
:name="task.id"
type="checkbox"
class="focus:ring-3 relative h-4 w-4 rounded border border-gray-300 bg-gray-50 focus:ring-blue-300 dark:border-gray-600 dark:bg-gray-700 dark:ring-offset-gray-800 dark:focus:ring-blue-600"
@change="toggle(task)" />

<div>
<label :for="task.id" class="ml-2 mb-2 flex cursor-pointer text-gray-900">
{{ task.label }}
</label>

<div class="flex items-center text-sm">
<!-- due date -->
<span
v-if="task.due_at"
:class="task.due_at_late ? 'bg-red-400/10 text-red-600' : 'bg-sky-400/10 text-sky-600'"
class="ml-2 mr-4 flex items-center rounded-full px-2 py-0.5 text-xs font-medium leading-5 dark:text-sky-400">
<svg
xmlns="http://www.w3.org/2000/svg"
class="mr-1 h-3 w-3"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2">
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
</svg>
<span class="">{{ task.due_at }}</span>
</span>

<!-- contact -->
<div class="flex items-center">
<avatar :data="task.contact.avatar" :classes="'mr-2 h-5 w-5 rounded-full'" />

<inertia-link :href="task.contact.url.show" class="text-blue-500 hover:underline">
{{ task.contact.name }}
</inertia-link>
</div>
</div>
</div>
</li>
</ul>
</div>

<!-- blank state -->
<div v-if="data.length == 0" class="mb-6 rounded-lg border border-gray-200 bg-white">
<p class="p-5 text-center">
{{ $t('vault.dashboard_due_tasks_blank') }}
</p>
</div>
</div>
</template>

<script>
import Avatar from '@/Shared/Avatar.vue';
export default {
components: {
Avatar,
},
props: {
data: {
type: Object,
default: null,
},
},
methods: {
toggle(task) {
axios.put(task.url.toggle).catch((error) => {
this.form.errors = error.response.data;
});
},
},
};
</script>

<style lang="scss" scoped>
.icon-sidebar {
color: #737e8d;
top: -2px;
}
input[type='checkbox'] {
top: 4px;
}
.item-list {
&:hover:first-child {
border-top-left-radius: 8px;
border-top-right-radius: 8px;
}
&:last-child {
border-bottom: 0;
}
&:hover:last-child {
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
}
}
</style>

0 comments on commit 1b11380

Please sign in to comment.