feat: add mood tracking (monicahq/chandler#386)
This commit is contained in:
+38
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Contact\ManageContactFeed\Web\ViewHelpers\Actions;
|
||||
|
||||
use App\Helpers\DateHelper;
|
||||
use App\Models\ContactFeedItem;
|
||||
use App\Models\User;
|
||||
|
||||
class ActionFeedMoodTrackingEvent
|
||||
{
|
||||
public static function data(ContactFeedItem $item, User $user): array
|
||||
{
|
||||
$contact = $item->contact;
|
||||
$moodTrackingEvent = $item->feedable;
|
||||
|
||||
return [
|
||||
'mood_tracking_event' => [
|
||||
'object' => $moodTrackingEvent ? [
|
||||
'id' => $moodTrackingEvent->id,
|
||||
'rated_at' => DateHelper::format($moodTrackingEvent->rated_at, $user),
|
||||
'note' => $moodTrackingEvent->note,
|
||||
'number_of_hours_slept' => $moodTrackingEvent->number_of_hours_slept,
|
||||
] : null,
|
||||
'description' => $item->description,
|
||||
],
|
||||
'contact' => [
|
||||
'id' => $contact->id,
|
||||
'name' => $contact->name,
|
||||
'age' => $contact->age,
|
||||
'avatar' => $contact->avatar,
|
||||
'url' => route('contact.show', [
|
||||
'vault' => $contact->vault_id,
|
||||
'contact' => $contact->id,
|
||||
]),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ use App\Domains\Contact\ManageContactFeed\Web\ViewHelpers\Actions\ActionFeedCont
|
||||
use App\Domains\Contact\ManageContactFeed\Web\ViewHelpers\Actions\ActionFeedGenericContactInformation;
|
||||
use App\Domains\Contact\ManageContactFeed\Web\ViewHelpers\Actions\ActionFeedGoal;
|
||||
use App\Domains\Contact\ManageContactFeed\Web\ViewHelpers\Actions\ActionFeedLabelAssigned;
|
||||
use App\Domains\Contact\ManageContactFeed\Web\ViewHelpers\Actions\ActionFeedMoodTrackingEvent;
|
||||
use App\Domains\Contact\ManageContactFeed\Web\ViewHelpers\Actions\ActionFeedPet;
|
||||
use App\Helpers\DateHelper;
|
||||
use App\Helpers\UserHelper;
|
||||
@@ -92,6 +93,11 @@ class ModuleFeedViewHelper
|
||||
case 'goal_destroyed':
|
||||
return ActionFeedGoal::data($item);
|
||||
|
||||
case 'mood_tracking_event_added':
|
||||
case 'mood_tracking_event_updated':
|
||||
case 'mood_tracking_event_deleted':
|
||||
return ActionFeedMoodTrackingEvent::data($item, $user);
|
||||
|
||||
default:
|
||||
return ActionFeedGenericContactInformation::data($item);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Contact\ManageMoodTrackingEvents\Services;
|
||||
|
||||
use App\Interfaces\ServiceInterface;
|
||||
use App\Models\ContactFeedItem;
|
||||
use App\Models\MoodTrackingEvent;
|
||||
use App\Services\BaseService;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class CreateMoodTrackingEvent extends BaseService implements ServiceInterface
|
||||
{
|
||||
private MoodTrackingEvent $moodTrackingEvent;
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the service.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'account_id' => 'required|integer|exists:accounts,id',
|
||||
'vault_id' => 'required|integer|exists:vaults,id',
|
||||
'author_id' => 'required|integer|exists:users,id',
|
||||
'contact_id' => 'required|integer|exists:contacts,id',
|
||||
'mood_tracking_parameter_id' => 'required|integer|exists:mood_tracking_parameters,id',
|
||||
'rated_at' => 'required|date_format:Y-m-d',
|
||||
'note' => 'nullable|string|max:65535',
|
||||
'number_of_hours_slept' => 'nullable|integer',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the permissions that apply to the user calling the service.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function permissions(): array
|
||||
{
|
||||
return [
|
||||
'author_must_belong_to_account',
|
||||
'vault_must_belong_to_account',
|
||||
'author_must_be_vault_editor',
|
||||
'contact_must_belong_to_vault',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mood tracking event.
|
||||
*
|
||||
* @param array $data
|
||||
* @return MoodTrackingEvent
|
||||
*/
|
||||
public function execute(array $data): MoodTrackingEvent
|
||||
{
|
||||
$this->validateRules($data);
|
||||
|
||||
$this->vault->moodTrackingParameters()
|
||||
->findOrFail($data['mood_tracking_parameter_id']);
|
||||
|
||||
$this->moodTrackingEvent = MoodTrackingEvent::create([
|
||||
'contact_id' => $this->contact->id,
|
||||
'mood_tracking_parameter_id' => $data['mood_tracking_parameter_id'],
|
||||
'rated_at' => $data['rated_at'],
|
||||
'note' => $this->valueOrNull($data, 'note'),
|
||||
'number_of_hours_slept' => $this->valueOrNull($data, 'number_of_hours_slept'),
|
||||
]);
|
||||
|
||||
$this->contact->last_updated_at = Carbon::now();
|
||||
$this->contact->save();
|
||||
|
||||
$this->createFeedItem();
|
||||
|
||||
return $this->moodTrackingEvent;
|
||||
}
|
||||
|
||||
private function createFeedItem(): void
|
||||
{
|
||||
$feedItem = ContactFeedItem::create([
|
||||
'author_id' => $this->author->id,
|
||||
'contact_id' => $this->contact->id,
|
||||
'action' => ContactFeedItem::ACTION_MOOD_TRACKING_EVENT_CREATED,
|
||||
'description' => $this->moodTrackingEvent->moodTrackingParameter->label,
|
||||
]);
|
||||
|
||||
$this->moodTrackingEvent->feedItem()->save($feedItem);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Contact\ManageMoodTrackingEvents\Services;
|
||||
|
||||
use App\Interfaces\ServiceInterface;
|
||||
use App\Models\ContactFeedItem;
|
||||
use App\Models\MoodTrackingEvent;
|
||||
use App\Services\BaseService;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class DestroyMoodTrackingEvent extends BaseService implements ServiceInterface
|
||||
{
|
||||
private MoodTrackingEvent $moodTrackingEvent;
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the service.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'account_id' => 'required|integer|exists:accounts,id',
|
||||
'vault_id' => 'required|integer|exists:vaults,id',
|
||||
'author_id' => 'required|integer|exists:users,id',
|
||||
'contact_id' => 'required|integer|exists:contacts,id',
|
||||
'mood_tracking_event_id' => 'required|integer|exists:mood_tracking_events,id',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the permissions that apply to the user calling the service.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function permissions(): array
|
||||
{
|
||||
return [
|
||||
'author_must_belong_to_account',
|
||||
'vault_must_belong_to_account',
|
||||
'contact_must_belong_to_vault',
|
||||
'author_must_be_vault_editor',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy a mood tracking event.
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public function execute(array $data): void
|
||||
{
|
||||
$this->validateRules($data);
|
||||
|
||||
$this->moodTrackingEvent = $this->contact->moodTrackingEvents()
|
||||
->findOrFail($data['mood_tracking_event_id']);
|
||||
|
||||
$this->moodTrackingEvent->delete();
|
||||
|
||||
$this->contact->last_updated_at = Carbon::now();
|
||||
$this->contact->save();
|
||||
|
||||
$this->createFeedItem();
|
||||
}
|
||||
|
||||
private function createFeedItem(): void
|
||||
{
|
||||
ContactFeedItem::create([
|
||||
'author_id' => $this->author->id,
|
||||
'contact_id' => $this->contact->id,
|
||||
'action' => ContactFeedItem::ACTION_MOOD_TRACKING_EVENT_DESTROYED,
|
||||
'description' => $this->moodTrackingEvent->moodTrackingParameter->label,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Contact\ManageMoodTrackingEvents\Services;
|
||||
|
||||
use App\Interfaces\ServiceInterface;
|
||||
use App\Models\ContactFeedItem;
|
||||
use App\Models\MoodTrackingEvent;
|
||||
use App\Services\BaseService;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class UpdateMoodTrackingEvent extends BaseService implements ServiceInterface
|
||||
{
|
||||
private MoodTrackingEvent $moodTrackingEvent;
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the service.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'account_id' => 'required|integer|exists:accounts,id',
|
||||
'vault_id' => 'required|integer|exists:vaults,id',
|
||||
'author_id' => 'required|integer|exists:users,id',
|
||||
'contact_id' => 'required|integer|exists:contacts,id',
|
||||
'mood_tracking_parameter_id' => 'required|integer|exists:mood_tracking_parameters,id',
|
||||
'mood_tracking_event_id' => 'required|integer|exists:mood_tracking_events,id',
|
||||
'rated_at' => 'required|date_format:Y-m-d',
|
||||
'note' => 'nullable|string|max:65535',
|
||||
'number_of_hours_slept' => 'nullable|integer',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the permissions that apply to the user calling the service.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function permissions(): array
|
||||
{
|
||||
return [
|
||||
'author_must_belong_to_account',
|
||||
'vault_must_belong_to_account',
|
||||
'contact_must_belong_to_vault',
|
||||
'author_must_be_vault_editor',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a mood tracking event.
|
||||
*
|
||||
* @param array $data
|
||||
* @return MoodTrackingEvent
|
||||
*/
|
||||
public function execute(array $data): MoodTrackingEvent
|
||||
{
|
||||
$this->validateRules($data);
|
||||
|
||||
$parameter = $this->vault->moodTrackingParameters()
|
||||
->findOrFail($data['mood_tracking_parameter_id']);
|
||||
|
||||
$this->moodTrackingEvent = $this->contact->moodTrackingEvents()
|
||||
->where('mood_tracking_parameter_id', $parameter->id)
|
||||
->findOrFail($data['mood_tracking_event_id']);
|
||||
|
||||
$this->moodTrackingEvent->mood_tracking_parameter_id = $data['mood_tracking_parameter_id'];
|
||||
$this->moodTrackingEvent->rated_at = $data['rated_at'];
|
||||
$this->moodTrackingEvent->note = $this->valueOrNull($data, 'note');
|
||||
$this->moodTrackingEvent->number_of_hours_slept = $this->valueOrNull($data, 'number_of_hours_slept');
|
||||
$this->moodTrackingEvent->save();
|
||||
|
||||
$this->contact->last_updated_at = Carbon::now();
|
||||
$this->contact->save();
|
||||
|
||||
$this->createFeedItem();
|
||||
|
||||
return $this->moodTrackingEvent;
|
||||
}
|
||||
|
||||
private function createFeedItem(): void
|
||||
{
|
||||
$feedItem = ContactFeedItem::create([
|
||||
'author_id' => $this->author->id,
|
||||
'contact_id' => $this->contact->id,
|
||||
'action' => ContactFeedItem::ACTION_MOOD_TRACKING_EVENT_UPDATED,
|
||||
'description' => $this->moodTrackingEvent->moodTrackingParameter->label,
|
||||
]);
|
||||
|
||||
$this->moodTrackingEvent->feedItem()->save($feedItem);
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Contact\ManageMoodTrackingEvents\Web\Controllers;
|
||||
|
||||
use App\Domains\Contact\ManageMoodTrackingEvents\Services\CreateMoodTrackingEvent;
|
||||
use App\Domains\Vault\ManageVault\Web\ViewHelpers\VaultShowViewHelper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Contact;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ContactMoodTrackingEventsController extends Controller
|
||||
{
|
||||
public function store(Request $request, int $vaultId, int $contactId): JsonResponse
|
||||
{
|
||||
$carbonDate = Carbon::parse($request->input('date'))->format('Y-m-d');
|
||||
|
||||
$data = [
|
||||
'account_id' => Auth::user()->account_id,
|
||||
'author_id' => Auth::id(),
|
||||
'vault_id' => $vaultId,
|
||||
'contact_id' => $contactId,
|
||||
'mood_tracking_parameter_id' => $request->input('parameter_id'),
|
||||
'rated_at' => $carbonDate,
|
||||
'note' => $request->input('note') ?? null,
|
||||
'number_of_hours_slept' => $request->input('hours') ?? null,
|
||||
];
|
||||
|
||||
$moodTrackingEvent = (new CreateMoodTrackingEvent())->execute($data);
|
||||
|
||||
$contact = Contact::find($contactId);
|
||||
|
||||
return response()->json([
|
||||
'data' => VaultShowViewHelper::dtoMoodTrackingEvent($moodTrackingEvent, Auth::user()),
|
||||
], 201);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Vault\ManageReports\Web\Controllers;
|
||||
|
||||
use App\Domains\Vault\ManageReports\Web\ViewHelpers\ReportIndexViewHelper;
|
||||
use App\Domains\Vault\ManageVault\Web\ViewHelpers\VaultIndexViewHelper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Vault;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class ReportIndexController extends Controller
|
||||
{
|
||||
public function index(Request $request, int $vaultId)
|
||||
{
|
||||
$vault = Vault::findOrFail($vaultId);
|
||||
|
||||
return Inertia::render('Vault/Reports/Index', [
|
||||
'layoutData' => VaultIndexViewHelper::layoutData($vault),
|
||||
'data' => ReportIndexViewHelper::data($vault),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Vault\ManageReports\Web\Controllers;
|
||||
|
||||
use App\Domains\Vault\ManageReports\Web\ViewHelpers\ReportMoodTrackingEventIndexViewHelper;
|
||||
use App\Domains\Vault\ManageVault\Web\ViewHelpers\VaultIndexViewHelper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Vault;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class ReportMoodTrackingEventController extends Controller
|
||||
{
|
||||
public function index(Request $request, int $vaultId)
|
||||
{
|
||||
$vault = Vault::findOrFail($vaultId);
|
||||
|
||||
return Inertia::render('Vault/Reports/MoodTrackingEvents/Index', [
|
||||
'layoutData' => VaultIndexViewHelper::layoutData($vault),
|
||||
'data' => ReportMoodTrackingEventIndexViewHelper::data($vault, Auth::user(), Carbon::now()->year),
|
||||
]);
|
||||
}
|
||||
}
|
||||
+10
-4
@@ -10,7 +10,6 @@ use App\Models\ContactImportantDate;
|
||||
use App\Models\User;
|
||||
use App\Models\Vault;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class ReportImportantDateSummaryIndexViewHelper
|
||||
{
|
||||
@@ -20,9 +19,9 @@ class ReportImportantDateSummaryIndexViewHelper
|
||||
*
|
||||
* @param Vault $vault
|
||||
* @param User $user
|
||||
* @return Collection
|
||||
* @return array
|
||||
*/
|
||||
public static function data(Vault $vault, User $user): Collection
|
||||
public static function data(Vault $vault, User $user): array
|
||||
{
|
||||
$contactsInVault = $vault->contacts->pluck('id')->toArray();
|
||||
$importantDates = ContactImportantDate::whereIn('contact_id', $contactsInVault)
|
||||
@@ -58,6 +57,13 @@ class ReportImportantDateSummaryIndexViewHelper
|
||||
]);
|
||||
}
|
||||
|
||||
return $monthsCollection;
|
||||
return [
|
||||
'months' => $monthsCollection,
|
||||
'url' => [
|
||||
'reports' => route('vault.reports.index', [
|
||||
'vault' => $vault->id,
|
||||
]),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Vault\ManageReports\Web\ViewHelpers;
|
||||
|
||||
use App\Models\Vault;
|
||||
|
||||
class ReportIndexViewHelper
|
||||
{
|
||||
public static function data(Vault $vault): array
|
||||
{
|
||||
return [
|
||||
'url' => [
|
||||
'mood_tracking_events' => route('vault.reports.mood_tracking_events.index', [
|
||||
'vault' => $vault->id,
|
||||
]),
|
||||
'important_date_summary' => route('vault.reports.important_dates.index', [
|
||||
'vault' => $vault->id,
|
||||
]),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Vault\ManageReports\Web\ViewHelpers;
|
||||
|
||||
use App\Helpers\DateHelper;
|
||||
use App\Models\User;
|
||||
use App\Models\Vault;
|
||||
use Carbon\CarbonImmutable;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class ReportMoodTrackingEventIndexViewHelper
|
||||
{
|
||||
public static function data(Vault $vault, User $user, int $year): array
|
||||
{
|
||||
return [
|
||||
'months' => self::year($vault, $user, $year),
|
||||
'url' => [
|
||||
'reports' => route('vault.reports.index', [
|
||||
'vault' => $vault->id,
|
||||
]),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the mood tracking events for the given year
|
||||
*
|
||||
* @param Vault $vault
|
||||
* @param User $user
|
||||
* @param int $year
|
||||
* @return Collection
|
||||
*/
|
||||
private static function year(Vault $vault, User $user, int $year): Collection
|
||||
{
|
||||
$contact = $user->getContactInVault($vault);
|
||||
|
||||
$moodTrackingEvents = $contact->moodTrackingEvents()
|
||||
->with('moodTrackingParameter')
|
||||
->whereYear('rated_at', (string) $year)
|
||||
->orderBy('rated_at', 'asc')
|
||||
->get();
|
||||
|
||||
// create the yearly calendar
|
||||
$monthsCollection = collect();
|
||||
for ($month = 1; $month < 13; $month++) {
|
||||
$currentMonth = CarbonImmutable::create($year, $month, 1);
|
||||
|
||||
$daysCollection = collect();
|
||||
for ($day = 1; $day < $currentMonth->daysInMonth; $day++) {
|
||||
$date = CarbonImmutable::create($year, $month, $day);
|
||||
|
||||
$moodTrackingForTheDay = null;
|
||||
foreach ($moodTrackingEvents as $moodTrackingEvent) {
|
||||
if ($moodTrackingEvent->rated_at->month === $date->month &&
|
||||
$moodTrackingEvent->rated_at->day === $date->day) {
|
||||
$moodTrackingForTheDay = $moodTrackingEvent;
|
||||
}
|
||||
}
|
||||
|
||||
$daysCollection->push([
|
||||
'id' => $day,
|
||||
'event' => $moodTrackingForTheDay ? [
|
||||
'id' => $moodTrackingForTheDay->id,
|
||||
'hex_color' => $moodTrackingForTheDay->moodTrackingParameter->hex_color,
|
||||
] : null,
|
||||
]);
|
||||
}
|
||||
|
||||
$monthsCollection->push([
|
||||
'id' => $month,
|
||||
'month_word' => DateHelper::formatMonthNumber($currentMonth),
|
||||
'days' => $daysCollection,
|
||||
]);
|
||||
}
|
||||
|
||||
return $monthsCollection;
|
||||
}
|
||||
}
|
||||
@@ -58,6 +58,7 @@ class VaultController extends Controller
|
||||
'upcomingReminders' => VaultShowViewHelper::upcomingReminders($vault, Auth::user()),
|
||||
'favorites' => VaultShowViewHelper::favorites($vault, Auth::user()),
|
||||
'dueTasks' => VaultShowViewHelper::dueTasks($vault, Auth::user()),
|
||||
'moodTrackingEvents' => VaultShowViewHelper::moodTrackingEvents($vault, Auth::user()),
|
||||
'loadFeedUrl' => route('vault.feed.show', [
|
||||
'vault' => $vaultId,
|
||||
]),
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Domains\Vault\ManageVault\Web\ViewHelpers;
|
||||
|
||||
use App\Helpers\DateHelper;
|
||||
use App\Models\MoodTrackingEvent;
|
||||
use App\Models\User;
|
||||
use App\Models\Vault;
|
||||
use Carbon\Carbon;
|
||||
@@ -155,4 +156,42 @@ class VaultShowViewHelper
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public static function moodTrackingEvents(Vault $vault, User $user): array
|
||||
{
|
||||
// get available mood tracking parameters
|
||||
$moodTrackingParametersCollection = $vault->moodTrackingParameters()
|
||||
->orderBy('position', 'asc')
|
||||
->get()
|
||||
->map(fn ($moodTrackingParameter) => [
|
||||
'id' => $moodTrackingParameter->id,
|
||||
'label' => $moodTrackingParameter->label,
|
||||
'hex_color' => $moodTrackingParameter->hex_color,
|
||||
]);
|
||||
|
||||
return [
|
||||
'mood_tracking_parameters' => $moodTrackingParametersCollection,
|
||||
'current_date' => Carbon::now($user->timezone)->format('Y-m-d'),
|
||||
'url' => [
|
||||
'history' => route('vault.reports.mood_tracking_events.index', [
|
||||
'vault' => $vault->id,
|
||||
]),
|
||||
'store' => route('contact.mood_tracking_event.store', [
|
||||
'vault' => $vault->id,
|
||||
'contact' => $user->getContactInVault($vault)->id,
|
||||
]),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public static function dtoMoodTrackingEvent(MoodTrackingEvent $event, User $user): array
|
||||
{
|
||||
return [
|
||||
'id' => $event->id,
|
||||
'label' => $event->moodTrackingParameter->label,
|
||||
'rated_at' => DateHelper::format($event->rated_at, $user),
|
||||
'note' => $event->note,
|
||||
'number_of_hours_slept' => $event->number_of_hours_slept,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,6 +148,17 @@ class DateHelper
|
||||
return $date->isoFormat(trans('format.day_number'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first letter of the month, like "Jan" for January.
|
||||
*
|
||||
* @param $date
|
||||
* @return string
|
||||
*/
|
||||
public static function formatMonthNumber($date): string
|
||||
{
|
||||
return $date->isoFormat(trans('format.short_month'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a collection of months.
|
||||
*
|
||||
|
||||
@@ -386,6 +386,16 @@ class Contact extends Model
|
||||
return $this->belongsToMany(LifeEvent::class, 'life_event_participants', 'contact_id', 'life_event_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mood tracking events associated with the contact.
|
||||
*
|
||||
* @return HasMany
|
||||
*/
|
||||
public function moodTrackingEvents(): HasMany
|
||||
{
|
||||
return $this->hasMany(MoodTrackingEvent::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the addresses associated with the contact.
|
||||
*
|
||||
|
||||
@@ -64,18 +64,6 @@ class ContactFeedItem extends Model
|
||||
|
||||
public const ACTION_CONTACT_ADDRESS_DESTROYED = 'address_destroyed';
|
||||
|
||||
public const ACTION_CONTACT_EVENT_CREATED = 'added an event';
|
||||
|
||||
public const ACTION_CONTACT_EVENT_UPDATED = 'updated an event';
|
||||
|
||||
public const ACTION_CONTACT_EVENT_DESTROYED = 'deleted an event';
|
||||
|
||||
public const ACTION_CONTACT_ACTIVITY_CREATED = 'added an activity';
|
||||
|
||||
public const ACTION_CONTACT_ACTIVITY_UPDATED = 'updated an activity';
|
||||
|
||||
public const ACTION_CONTACT_ACTIVITY_DESTROYED = 'deleted an activity';
|
||||
|
||||
public const ACTION_LOAN_CREATED = 'loan_created';
|
||||
|
||||
public const ACTION_LOAN_UPDATED = 'loan_updated';
|
||||
@@ -98,6 +86,12 @@ class ContactFeedItem extends Model
|
||||
|
||||
public const ACTION_CHANGE_AVATAR = 'changed_avatar';
|
||||
|
||||
public const ACTION_MOOD_TRACKING_EVENT_CREATED = 'mood_tracking_event_added';
|
||||
|
||||
public const ACTION_MOOD_TRACKING_EVENT_UPDATED = 'mood_tracking_event_updated';
|
||||
|
||||
public const ACTION_MOOD_TRACKING_EVENT_DESTROYED = 'mood_tracking_event_deleted';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphOne;
|
||||
|
||||
class MoodTrackingEvent extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'mood_tracking_events';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'contact_id',
|
||||
'mood_tracking_parameter_id',
|
||||
'rated_at',
|
||||
'note',
|
||||
'number_of_hours_slept',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be mutated to dates.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dates = [
|
||||
'rated_at',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the contact associated with the mood tracking event.
|
||||
*
|
||||
* @return BelongsTo
|
||||
*/
|
||||
public function contact(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Contact::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mood tracking parameter associated with the mood tracking event.
|
||||
*
|
||||
* @return BelongsTo
|
||||
*/
|
||||
public function moodTrackingParameter(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(MoodTrackingParameter::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mood tracking event's feed item.
|
||||
*
|
||||
* @return MorphOne
|
||||
*/
|
||||
public function feedItem(): MorphOne
|
||||
{
|
||||
return $this->morphOne(ContactFeedItem::class, 'feedable');
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class MoodTrackingParameter extends Model
|
||||
{
|
||||
@@ -36,6 +37,16 @@ class MoodTrackingParameter extends Model
|
||||
return $this->belongsTo(Vault::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mood tracking events associated with the mood tracking parameter.
|
||||
*
|
||||
* @return HasMany
|
||||
*/
|
||||
public function moodTrackingEvents(): HasMany
|
||||
{
|
||||
return $this->hasMany(MoodTrackingEvent::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the label attribute.
|
||||
* A mood tracking parameter has a default label that can be translated.
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Contact;
|
||||
use App\Models\MoodTrackingEvent;
|
||||
use App\Models\MoodTrackingParameter;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\MoodTrackingEvent>
|
||||
*/
|
||||
class MoodTrackingEventFactory extends Factory
|
||||
{
|
||||
protected $model = MoodTrackingEvent::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition()
|
||||
{
|
||||
return [
|
||||
'contact_id' => Contact::factory(),
|
||||
'mood_tracking_parameter_id' => MoodTrackingParameter::factory(),
|
||||
'rated_at' => $this->faker->dateTime(),
|
||||
'note' => $this->faker->name(),
|
||||
'number_of_hours_slept' => $this->faker->randomNumber(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('mood_tracking_events', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('contact_id');
|
||||
$table->unsignedBigInteger('mood_tracking_parameter_id');
|
||||
$table->datetime('rated_at');
|
||||
$table->text('note')->nullable();
|
||||
$table->integer('number_of_hours_slept')->nullable();
|
||||
$table->timestamps();
|
||||
$table->foreign('mood_tracking_parameter_id')->references('id')->on('mood_tracking_parameters')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('mood_tracking_events');
|
||||
}
|
||||
};
|
||||
@@ -53,6 +53,7 @@ return [
|
||||
'feed_item_favorited' => 'added the contact to the favorites',
|
||||
'feed_item_unfavorited' => 'removed the contact from the favorites',
|
||||
'feed_item_changed_avatar' => 'updated the avatar of the contact',
|
||||
'feed_item_mood_tracking_event_added' => 'logged the mood',
|
||||
|
||||
/***************************************************************
|
||||
* MODULE: GROUP
|
||||
|
||||
@@ -25,6 +25,9 @@ return [
|
||||
/* short month and the year in a format like "July 2020" - see https://carbon.nesbot.com/docs/#iso-format-available-replacements */
|
||||
'long_month_year' => 'MMMM Y',
|
||||
|
||||
/* month as a string like "Jul" - see https://carbon.nesbot.com/docs/#iso-format-available-replacements */
|
||||
'short_month' => 'MMM',
|
||||
|
||||
/* day and month in a format like "July 29th" - see https://carbon.nesbot.com/docs/#iso-format-available-replacements */
|
||||
'long_month_day' => 'MMMM Do',
|
||||
|
||||
|
||||
+5
-5
@@ -191,11 +191,11 @@ return [
|
||||
'settings_delete_cta_confirmation' => 'Are you sure? This will delete all the data inside this vault.',
|
||||
'settings_delete_destroy_success' => 'The vault has been deleted',
|
||||
|
||||
'settings_mood_tracking_parameters_awesome' => 'Awesome',
|
||||
'settings_mood_tracking_parameters_good' => 'Good',
|
||||
'settings_mood_tracking_parameters_meh' => 'Meh',
|
||||
'settings_mood_tracking_parameters_bad' => 'Bad',
|
||||
'settings_mood_tracking_parameters_awful' => 'Awful',
|
||||
'settings_mood_tracking_parameters_awesome' => '🥳 Awesome',
|
||||
'settings_mood_tracking_parameters_good' => '😀 Good',
|
||||
'settings_mood_tracking_parameters_meh' => '😐 Meh',
|
||||
'settings_mood_tracking_parameters_bad' => '😔 Bad',
|
||||
'settings_mood_tracking_parameters_awful' => '😩 Awful',
|
||||
'settings_life_event_category_transportation' => 'Transportation',
|
||||
'settings_life_event_type_transportation_bike' => 'Rode a bike',
|
||||
'settings_life_event_type_transportation_car' => 'Drove',
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 11 KiB |
@@ -156,49 +156,49 @@
|
||||
<div class="flex flex-wrap text-xs">
|
||||
<span
|
||||
v-if="!showMiddleNameField"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:text-gray-900"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:bg-slate-500 dark:text-gray-900 dark:text-white"
|
||||
@click="displayMiddleNameField">
|
||||
{{ $t('vault.create_contact_add_middle_name') }}
|
||||
</span>
|
||||
<span
|
||||
v-if="!showPrefixField"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:text-gray-900"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:bg-slate-500 dark:text-gray-900 dark:text-white"
|
||||
@click="displayPrefixField">
|
||||
{{ $t('vault.create_contact_add_prefix') }}
|
||||
</span>
|
||||
<span
|
||||
v-if="!showSuffixField"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:text-gray-900"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:bg-slate-500 dark:text-gray-900 dark:text-white"
|
||||
@click="displaySuffixField">
|
||||
{{ $t('vault.create_contact_add_suffix') }}
|
||||
</span>
|
||||
<span
|
||||
v-if="!showNicknameField"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:text-gray-900"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:bg-slate-500 dark:text-gray-900 dark:text-white"
|
||||
@click="displayNicknameField">
|
||||
{{ $t('vault.create_contact_add_nickname') }}
|
||||
</span>
|
||||
<span
|
||||
v-if="!showMaidenNameField"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:text-gray-900"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:bg-slate-500 dark:text-gray-900 dark:text-white"
|
||||
@click="displayMaidenNameField">
|
||||
{{ $t('vault.create_contact_add_maiden_name') }}
|
||||
</span>
|
||||
<span
|
||||
v-if="data.genders.length > 0 && !showGenderField"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:text-gray-900"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:bg-slate-500 dark:text-gray-900 dark:text-white"
|
||||
@click="displayGenderField">
|
||||
{{ $t('vault.create_contact_add_gender') }}
|
||||
</span>
|
||||
<span
|
||||
v-if="data.pronouns.length > 0 && !showPronounField"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:text-gray-900"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:bg-slate-500 dark:text-gray-900 dark:text-white"
|
||||
@click="displayPronounField">
|
||||
{{ $t('vault.create_contact_add_pronoun') }}
|
||||
</span>
|
||||
<span
|
||||
v-if="data.templates.length > 0 && !showTemplateField"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:text-gray-900"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:bg-slate-500 dark:text-gray-900 dark:text-white"
|
||||
@click="displayTemplateField">
|
||||
{{ $t('vault.create_contact_add_change_template') }}
|
||||
</span>
|
||||
|
||||
@@ -172,25 +172,25 @@
|
||||
<div class="mb-4 flex flex-wrap text-xs">
|
||||
<span
|
||||
v-if="!showLastNameField"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:text-gray-900"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:bg-slate-500 dark:text-gray-900 dark:text-white"
|
||||
@click="displayLastNameField">
|
||||
+ last name
|
||||
</span>
|
||||
<span
|
||||
v-if="!showMiddleNameField"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:text-gray-900"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:bg-slate-500 dark:text-gray-900 dark:text-white"
|
||||
@click="displayMiddleNameField">
|
||||
+ middle name
|
||||
</span>
|
||||
<span
|
||||
v-if="!showNicknameField"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:text-gray-900"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:bg-slate-500 dark:text-gray-900 dark:text-white"
|
||||
@click="displayNicknameField">
|
||||
+ nickname
|
||||
</span>
|
||||
<span
|
||||
v-if="!showMaidenNameField"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:text-gray-900"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:bg-slate-500 dark:text-gray-900 dark:text-white"
|
||||
@click="displayMaidenNameField">
|
||||
+ maiden name
|
||||
</span>
|
||||
@@ -288,13 +288,13 @@
|
||||
<div class="flex flex-wrap text-xs">
|
||||
<span
|
||||
v-if="data.genders.length > 0 && !showGenderField"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:text-gray-900"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:bg-slate-500 dark:text-gray-900 dark:text-white"
|
||||
@click="displayGenderField">
|
||||
+ gender
|
||||
</span>
|
||||
<span
|
||||
v-if="data.pronouns.length > 0 && !showPronounField"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:text-gray-900"
|
||||
class="mr-2 mb-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 hover:bg-slate-300 dark:bg-slate-500 dark:text-gray-900 dark:text-white"
|
||||
@click="displayPronounField">
|
||||
+ pronoun
|
||||
</span>
|
||||
|
||||
@@ -41,6 +41,9 @@
|
||||
|
||||
<!-- right -->
|
||||
<div class="p-3 sm:p-0">
|
||||
<!-- mood tracking -->
|
||||
<mood-tracking-events :data="moodTrackingEvents" />
|
||||
|
||||
<!-- upcoming reminders -->
|
||||
<upcoming-reminders :data="upcomingReminders" />
|
||||
|
||||
@@ -59,6 +62,7 @@ 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 MoodTrackingEvents from '@/Pages/Vault/Dashboard/Partials/MoodTrackingEvents.vue';
|
||||
import Feed from '@/Shared/Modules/Feed.vue';
|
||||
|
||||
export default {
|
||||
@@ -69,6 +73,7 @@ export default {
|
||||
Favorites,
|
||||
DueTasks,
|
||||
Feed,
|
||||
MoodTrackingEvents,
|
||||
},
|
||||
|
||||
props: {
|
||||
@@ -96,6 +101,10 @@ export default {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
moodTrackingEvents: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
<!-- blank state -->
|
||||
<div
|
||||
v-if="data.tasks.length == 0"
|
||||
class="mb-6 flex items-center rounded-lg border border-gray-200 bg-white p-3 dark:border-gray-800 dark:bg-gray-900">
|
||||
class="mb-2 flex items-center rounded-lg border border-gray-200 bg-white p-3 dark:border-gray-800 dark:bg-gray-900">
|
||||
<img src="/img/dashboard_blank_tasks.svg" :alt="$t('Tasks')" class="mr-2 h-14 w-14" />
|
||||
<p class="px-5 text-center">
|
||||
{{ $t('vault.dashboard_due_tasks_blank') }}
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
<script setup>
|
||||
import PrettySpan from '@/Shared/Form/PrettySpan.vue';
|
||||
import TextArea from '@/Shared/Form/TextArea.vue';
|
||||
import PrettyButton from '@/Shared/Form/PrettyButton.vue';
|
||||
import TextInput from '@/Shared/Form/TextInput.vue';
|
||||
import { useForm } from '@inertiajs/inertia-vue3';
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
data: Object,
|
||||
});
|
||||
|
||||
const loadingState = ref('');
|
||||
const createMoodEventModalShown = ref(false);
|
||||
const datePickerFieldShown = ref(false);
|
||||
const noteFieldShown = ref(false);
|
||||
const hoursSleptFieldShown = ref(false);
|
||||
const successShown = ref(false);
|
||||
|
||||
const form = useForm({
|
||||
parameter_id: 0,
|
||||
date: null,
|
||||
hours: null,
|
||||
note: null,
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
form.date = props.data.current_date;
|
||||
});
|
||||
|
||||
const showMoodEventModal = () => {
|
||||
datePickerFieldShown.value = false;
|
||||
noteFieldShown.value = false;
|
||||
hoursSleptFieldShown.value = false;
|
||||
createMoodEventModalShown.value = true;
|
||||
form.note = '';
|
||||
form.hours = null;
|
||||
};
|
||||
|
||||
const showDatePickerField = () => {
|
||||
datePickerFieldShown.value = true;
|
||||
};
|
||||
|
||||
const showNoteField = () => {
|
||||
noteFieldShown.value = true;
|
||||
};
|
||||
|
||||
const showHoursSleptField = () => {
|
||||
hoursSleptFieldShown.value = true;
|
||||
};
|
||||
|
||||
const submit = () => {
|
||||
loadingState.value = 'loading';
|
||||
|
||||
axios
|
||||
.post(props.data.url.store, form)
|
||||
.then(() => {
|
||||
createMoodEventModalShown.value = false;
|
||||
successShown.value = true;
|
||||
loadingState.value = null;
|
||||
})
|
||||
.catch((error) => {
|
||||
loadingState.value = null;
|
||||
form.errors = error.response.data;
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="mb-10">
|
||||
<h3 class="mb-3 border-b border-gray-200 pb-1 font-medium dark:border-gray-700">
|
||||
<span class="relative">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="icon-sidebar relative inline h-4 w-4 text-gray-300 hover:text-gray-600 dark:text-gray-400 hover:dark:text-gray-400">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M15.042 21.672L13.684 16.6m0 0l-2.51 2.225.569-9.47 5.227 7.917-3.286-.672zM12 2.25V4.5m5.834.166l-1.591 1.591M20.25 10.5H18M7.757 14.743l-1.59 1.59M6 10.5H3.75m4.007-4.243l-1.59-1.59" />
|
||||
</svg>
|
||||
</span>
|
||||
|
||||
Record your mood
|
||||
</h3>
|
||||
|
||||
<!-- cta -->
|
||||
<div
|
||||
v-if="!createMoodEventModalShown && !successShown"
|
||||
class="mb-4 flex items-center rounded-lg border border-gray-200 bg-white p-3 dark:border-gray-700 dark:bg-gray-900">
|
||||
<img src="/img/dashboard_blank_how_are_you.svg" :alt="$t('Reminders')" class="mr-2 h-14 w-14" />
|
||||
<div class="mb-2 flex flex-col px-5">
|
||||
<p class="mb-2">How are you?</p>
|
||||
<pretty-button :text="'Record your mood'" @click="showMoodEventModal" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- add an event modal -->
|
||||
<form
|
||||
v-if="createMoodEventModalShown"
|
||||
class="bg-form mb-6 rounded-lg border border-gray-200 dark:border-gray-700 dark:bg-gray-900"
|
||||
@submit.prevent="submit()">
|
||||
<div class="border-b border-gray-200 p-5 dark:border-gray-700">
|
||||
<div v-if="form.errors.length > 0" class="p-5">
|
||||
<errors :errors="form.errors" />
|
||||
</div>
|
||||
|
||||
<!-- mood tracking parameters -->
|
||||
<p class="mb-2 block text-sm dark:text-gray-100">How do you feel right now?</p>
|
||||
<ul class="mb-4">
|
||||
<li v-for="parameter in props.data.mood_tracking_parameters" :key="parameter.id" class="flex">
|
||||
<input
|
||||
:id="'input' + parameter.id"
|
||||
v-model="form.parameter_id"
|
||||
:value="parameter.id"
|
||||
name="date-format"
|
||||
type="radio"
|
||||
class="relative mr-3 h-4 w-4 border-gray-300 text-sky-500 dark:border-gray-700" />
|
||||
|
||||
<label
|
||||
:for="'input' + parameter.id"
|
||||
class="block cursor-pointer font-medium text-gray-700 dark:text-gray-300">
|
||||
<div class="mr-2 inline-block h-4 w-4 rounded-full" :class="parameter.hex_color" />
|
||||
{{ parameter.label }}
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="flex">
|
||||
<span
|
||||
v-if="!datePickerFieldShown"
|
||||
class="mr-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 text-sm hover:bg-slate-300 dark:bg-slate-500 dark:text-white"
|
||||
@click="showDatePickerField">
|
||||
+ change date
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="!noteFieldShown"
|
||||
class="mr-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 text-sm hover:bg-slate-300 dark:bg-slate-500 dark:text-white"
|
||||
@click="showNoteField">
|
||||
+ note
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="!hoursSleptFieldShown"
|
||||
class="mr-2 flex cursor-pointer flex-wrap rounded-lg border bg-slate-200 px-1 py-1 text-sm hover:bg-slate-300 dark:bg-slate-500 dark:text-white"
|
||||
@click="showHoursSleptField">
|
||||
+ number of hours slept
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- date picker -->
|
||||
<div v-if="datePickerFieldShown">
|
||||
<p class="mt-2 mb-2 block text-sm dark:text-gray-100">Change date</p>
|
||||
<v-date-picker v-model="form.date" :timezone="'UTC'" class="inline-block h-full" :model-config="modelConfig">
|
||||
<template #default="{ inputValue, inputEvents }">
|
||||
<input
|
||||
class="rounded border bg-white px-2 py-1 dark:bg-gray-900"
|
||||
:value="inputValue"
|
||||
v-on="inputEvents" />
|
||||
</template>
|
||||
</v-date-picker>
|
||||
</div>
|
||||
|
||||
<!-- note -->
|
||||
<div v-if="noteFieldShown" class="mt-4">
|
||||
<text-area v-model="form.note" :label="'Add a note'" :maxlength="65535" :textarea-class="'block w-full'" />
|
||||
</div>
|
||||
|
||||
<!-- hours slept -->
|
||||
<div v-if="hoursSleptFieldShown" class="mt-4">
|
||||
<text-input
|
||||
v-model="form.hours"
|
||||
:label="'Number of hours slept'"
|
||||
:autofocus="true"
|
||||
:input-class="'block w-full'"
|
||||
:type="'number'"
|
||||
:min="0"
|
||||
:max="24"
|
||||
:required="false"
|
||||
:autocomplete="false" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between p-5">
|
||||
<pretty-span :text="$t('app.cancel')" :classes="'mr-3'" @click="createMoodEventModalShown = false" />
|
||||
<pretty-button :text="$t('app.save')" :state="loadingState" :icon="'plus'" :classes="'save'" />
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- successShown -->
|
||||
<div
|
||||
v-if="successShown"
|
||||
class="mb-4 flex items-center rounded-lg border border-gray-200 bg-white p-3 dark:border-gray-700 dark:bg-gray-900">
|
||||
<img src="/img/dashboard_blank_how_are_you.svg" :alt="$t('Reminders')" class="mr-2 h-14 w-14" />
|
||||
<div class="flex flex-col px-5">
|
||||
<p class="mb-2"><span class="mr-1">🎉</span> Your mood has been recorded!</p>
|
||||
<inertia-link :href="data.url.history" class="text-center text-blue-500 hover:underline"
|
||||
>View history</inertia-link
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.icon-sidebar {
|
||||
color: #737e8d;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.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>
|
||||
@@ -4,7 +4,7 @@
|
||||
<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 dark:text-gray-400 dark:text-gray-700 dark:text-gray-300 hover:dark:text-gray-400"
|
||||
class="icon-sidebar relative inline h-4 w-4 text-gray-300 hover:text-gray-600 dark:text-gray-400 hover:dark:text-gray-400"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
|
||||
@@ -10,7 +10,34 @@ defineProps({
|
||||
|
||||
<template>
|
||||
<Layout :layout-data="layoutData" :inside-vault="true">
|
||||
<main class="relative sm:mt-24">
|
||||
<!-- breadcrumb -->
|
||||
<nav class="bg-white dark:bg-gray-900 sm:mt-20 sm:border-b">
|
||||
<div class="max-w-8xl mx-auto hidden px-4 py-2 sm:px-6 md:block">
|
||||
<div class="flex items-baseline justify-between space-x-6">
|
||||
<ul class="text-sm">
|
||||
<li class="mr-2 inline text-gray-600 dark:text-gray-400">
|
||||
{{ $t('app.breadcrumb_location') }}
|
||||
</li>
|
||||
<li class="mr-2 inline">
|
||||
<inertia-link :href="data.url.reports" class="text-blue-500 hover:underline">Reports</inertia-link>
|
||||
</li>
|
||||
<li class="relative mr-2 inline">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="icon-breadcrumb relative inline h-3 w-3"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
||||
</svg>
|
||||
</li>
|
||||
<li class="inline">List of all important dates</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="sm:mt-18 relative">
|
||||
<div class="mx-auto max-w-3xl px-2 py-2 sm:py-6 sm:px-6 lg:px-8">
|
||||
<!-- title -->
|
||||
<div class="mb-5 items-center justify-between border-b border-gray-200 pb-2 dark:border-gray-700 sm:flex">
|
||||
@@ -35,7 +62,7 @@ defineProps({
|
||||
</div>
|
||||
|
||||
<!-- iteration over the month -->
|
||||
<div v-for="month in data" :key="month.id" class="mb-6">
|
||||
<div v-for="month in data.months" :key="month.id" class="mb-6">
|
||||
<h2 class="font-bold">{{ month.month }}</h2>
|
||||
|
||||
<!-- important dates -->
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
<script setup>
|
||||
import { Link } from '@inertiajs/inertia-vue3';
|
||||
import Layout from '@/Shared/Layout.vue';
|
||||
|
||||
defineProps({
|
||||
layoutData: Object,
|
||||
data: Object,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Layout :layout-data="layoutData" :inside-vault="true">
|
||||
<main class="relative sm:mt-20">
|
||||
<div class="mx-auto max-w-md px-2 py-2 sm:py-6 sm:px-6 lg:px-8">
|
||||
<h2 class="mb-6 text-center text-lg">All the reports</h2>
|
||||
<div class="mb-12 rounded-lg border border-gray-200 bg-white p-5 dark:border-gray-700 dark:bg-gray-900">
|
||||
<ul>
|
||||
<li class="mb-2 flex justify-start">
|
||||
<Link :href="data.url.mood_tracking_events" class="text-blue-500 hover:underline">
|
||||
Mood tracking events
|
||||
</Link>
|
||||
</li>
|
||||
<li class="flex justify-start">
|
||||
<Link :href="data.url.important_date_summary" class="text-blue-500 hover:underline">
|
||||
Important date summary
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</Layout>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.icon-sidebar {
|
||||
color: #737e8d;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.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,0 +1,102 @@
|
||||
<script setup>
|
||||
import Layout from '@/Shared/Layout.vue';
|
||||
|
||||
defineProps({
|
||||
layoutData: Object,
|
||||
data: Object,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Layout :layout-data="layoutData" :inside-vault="true">
|
||||
<!-- breadcrumb -->
|
||||
<nav class="bg-white dark:bg-gray-900 sm:mt-20 sm:border-b">
|
||||
<div class="max-w-8xl mx-auto hidden px-4 py-2 sm:px-6 md:block">
|
||||
<div class="flex items-baseline justify-between space-x-6">
|
||||
<ul class="text-sm">
|
||||
<li class="mr-2 inline text-gray-600 dark:text-gray-400">
|
||||
{{ $t('app.breadcrumb_location') }}
|
||||
</li>
|
||||
<li class="mr-2 inline">
|
||||
<inertia-link :href="data.url.reports" class="text-blue-500 hover:underline">Reports</inertia-link>
|
||||
</li>
|
||||
<li class="relative mr-2 inline">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="icon-breadcrumb relative inline h-3 w-3"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
||||
</svg>
|
||||
</li>
|
||||
<li class="inline">List of all important dates</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="sm:mt-18 relative">
|
||||
<div class="mx-auto max-w-3xl px-2 py-2 sm:py-6 sm:px-6 lg:px-8">
|
||||
<!-- title -->
|
||||
<div class="mb-5 items-center justify-between border-b border-gray-200 pb-2 dark:border-gray-700 sm:flex">
|
||||
<div class="mb-2 sm:mb-0">
|
||||
<span class="relative">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="icon-sidebar relative inline h-4 w-4 text-gray-300 hover:text-gray-600 dark:text-gray-700 hover:dark:text-gray-400">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M12 8.25v-1.5m0 1.5c-1.355 0-2.697.056-4.024.166C6.845 8.51 6 9.473 6 10.608v2.513m6-4.87c1.355 0 2.697.055 4.024.165C17.155 8.51 18 9.473 18 10.608v2.513m-3-4.87v-1.5m-6 1.5v-1.5m12 9.75l-1.5.75a3.354 3.354 0 01-3 0 3.354 3.354 0 00-3 0 3.354 3.354 0 01-3 0 3.354 3.354 0 00-3 0 3.354 3.354 0 01-3 0L3 16.5m15-3.38a48.474 48.474 0 00-6-.37c-2.032 0-4.034.125-6 .37m12 0c.39.049.777.102 1.163.16 1.07.16 1.837 1.094 1.837 2.175v5.17c0 .62-.504 1.124-1.125 1.124H4.125A1.125 1.125 0 013 20.625v-5.17c0-1.08.768-2.014 1.837-2.174A47.78 47.78 0 016 13.12M12.265 3.11a.375.375 0 11-.53 0L12 2.845l.265.265zm-3 0a.375.375 0 11-.53 0L9 2.845l.265.265zm6 0a.375.375 0 11-.53 0L15 2.845l.265.265z" />
|
||||
</svg>
|
||||
</span>
|
||||
|
||||
Your mood this year
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- iteration over the month -->
|
||||
<div class="flex justify-center">
|
||||
<div v-for="month in data.months" :key="month.id" class="mb-6 flex flex-col text-center">
|
||||
<h2 class="mr-2 mb-1 font-mono text-sm font-bold">{{ month.month_word }}</h2>
|
||||
|
||||
<div v-for="day in month.days" :key="day.id">
|
||||
<div v-if="day.event" class="mr-2 inline-block h-4 w-4 rounded-full" :class="day.event.hex_color" />
|
||||
<div v-else class="mr-2 inline-block h-4 w-4 rounded-full">
|
||||
<div class="mr-2 inline-block h-4 w-4 rounded-full bg-slate-100" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</Layout>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.icon-sidebar {
|
||||
color: #737e8d;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.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>
|
||||
@@ -131,6 +131,15 @@
|
||||
"
|
||||
:data="feedItem.data"
|
||||
:contact-view-mode="contactViewMode" />
|
||||
|
||||
<mood-tracking-event
|
||||
v-if="
|
||||
feedItem.action === 'mood_tracking_event_added' ||
|
||||
feedItem.action === 'mood_tracking_event_updated' ||
|
||||
feedItem.action === 'mood_tracking_event_deleted'
|
||||
"
|
||||
:data="feedItem.data"
|
||||
:contact-view-mode="contactViewMode" />
|
||||
</div>
|
||||
|
||||
<!-- details -->
|
||||
@@ -175,6 +184,7 @@ import Addresses from '@/Shared/Modules/FeedItems/Address.vue';
|
||||
import ContactInformation from '@/Shared/Modules/FeedItems/ContactInformation.vue';
|
||||
import Pet from '@/Shared/Modules/FeedItems/Pet.vue';
|
||||
import Goal from '@/Shared/Modules/FeedItems/Goal.vue';
|
||||
import MoodTrackingEvent from '@/Shared/Modules/FeedItems/MoodTrackingEvent.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -186,6 +196,7 @@ export default {
|
||||
ContactInformation,
|
||||
Pet,
|
||||
Goal,
|
||||
MoodTrackingEvent,
|
||||
},
|
||||
|
||||
props: {
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<div class="rounded-lg border border-gray-300 dark:border-gray-700">
|
||||
<!-- contact information -->
|
||||
<div
|
||||
v-if="!contactViewMode"
|
||||
class="flex items-center border-b border-gray-300 px-3 py-2 text-sm dark:border-gray-700">
|
||||
<avatar
|
||||
:data="data.contact.avatar"
|
||||
:classes="'rounded-full border-gray-200 dark:border-gray-800 border relative h-5 w-5 mr-2'" />
|
||||
|
||||
<div class="flex flex-col">
|
||||
<inertia-link :href="data.contact.url" class="text-gray-800 hover:underline dark:text-gray-200">{{
|
||||
data.contact.name
|
||||
}}</inertia-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="px-3 py-2">
|
||||
<!-- the mood tracking event still exists in the system -->
|
||||
<div v-if="data.mood_tracking_event.object">
|
||||
<div class="mb-2 flex">
|
||||
<div class="mr-2">
|
||||
{{ data.mood_tracking_event.description }}
|
||||
</div>
|
||||
|
||||
<!-- slept for -->
|
||||
<div v-if="data.mood_tracking_event.object.number_of_hours_slept" 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="M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z" />
|
||||
</svg>
|
||||
|
||||
<span>{{ data.mood_tracking_event.object.number_of_hours_slept }} hours</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- date -->
|
||||
<div 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.5" />
|
||||
</svg>
|
||||
{{ data.mood_tracking_event.object.rated_at }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- the mood tracking event was deleted -->
|
||||
<span v-else class="mr-2 mb-2">
|
||||
<span>{{ data.mood_tracking_event.description }}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Avatar from '@/Shared/Avatar.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Avatar,
|
||||
},
|
||||
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
contactViewMode: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
+12
-1
@@ -25,6 +25,7 @@ use App\Domains\Contact\ManageJobInformation\Web\Controllers\ContactModuleJobInf
|
||||
use App\Domains\Contact\ManageLabels\Web\Controllers\ContactModuleLabelController;
|
||||
use App\Domains\Contact\ManageLoans\Web\Controllers\ContactModuleLoanController;
|
||||
use App\Domains\Contact\ManageLoans\Web\Controllers\ContactModuleToggleLoanController;
|
||||
use App\Domains\Contact\ManageMoodTrackingEvents\Web\Controllers\ContactMoodTrackingEventsController;
|
||||
use App\Domains\Contact\ManageNotes\Web\Controllers\ContactModuleNoteController;
|
||||
use App\Domains\Contact\ManageNotes\Web\Controllers\ContactNotesController;
|
||||
use App\Domains\Contact\ManagePets\Web\Controllers\ContactModulePetController;
|
||||
@@ -95,6 +96,8 @@ use App\Domains\Vault\ManageJournals\Web\Controllers\PostTagController;
|
||||
use App\Domains\Vault\ManageJournals\Web\Controllers\SliceOfLifeController;
|
||||
use App\Domains\Vault\ManageJournals\Web\Controllers\SliceOfLifeCoverImageController;
|
||||
use App\Domains\Vault\ManageReports\Web\Controllers\ReportImportantDateSummaryController;
|
||||
use App\Domains\Vault\ManageReports\Web\Controllers\ReportIndexController;
|
||||
use App\Domains\Vault\ManageReports\Web\Controllers\ReportMoodTrackingEventController;
|
||||
use App\Domains\Vault\ManageTasks\Web\Controllers\VaultTaskController;
|
||||
use App\Domains\Vault\ManageVault\Web\Controllers\VaultController;
|
||||
use App\Domains\Vault\ManageVault\Web\Controllers\VaultFeedController;
|
||||
@@ -178,7 +181,12 @@ Route::middleware([
|
||||
|
||||
// reports
|
||||
Route::prefix('reports')->group(function () {
|
||||
Route::get('', [ReportImportantDateSummaryController::class, 'index'])->name('vault.reports.index');
|
||||
Route::get('', [ReportIndexController::class, 'index'])->name('vault.reports.index');
|
||||
|
||||
// mood tracking event
|
||||
Route::get('moodTrackingEvents', [ReportMoodTrackingEventController::class, 'index'])->name('vault.reports.mood_tracking_events.index');
|
||||
|
||||
// important date summary
|
||||
Route::get('importantDates', [ReportImportantDateSummaryController::class, 'index'])->name('vault.reports.important_dates.index');
|
||||
});
|
||||
|
||||
@@ -313,6 +321,9 @@ Route::middleware([
|
||||
// groups
|
||||
Route::post('groups', [ContactModuleGroupController::class, 'store'])->name('contact.group.store');
|
||||
Route::delete('groups/{group}', [ContactModuleGroupController::class, 'destroy'])->name('contact.group.destroy');
|
||||
|
||||
// mood tracking events
|
||||
Route::post('moodTrackingEvents', [ContactMoodTrackingEventsController::class, 'store'])->name('contact.mood_tracking_event.store');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Domains\Contact\ManageContactFeed\Web\ViewHelpers\Actions;
|
||||
|
||||
use App\Domains\Contact\ManageContactFeed\Web\ViewHelpers\Actions\ActionFeedMoodTrackingEvent;
|
||||
use App\Models\Contact;
|
||||
use App\Models\ContactFeedItem;
|
||||
use App\Models\MoodTrackingEvent;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ActionFeedMoodTrackingEventTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_gets_the_data_needed_for_the_view(): void
|
||||
{
|
||||
$user = $this->createAdministrator();
|
||||
$contact = Contact::factory()->create([
|
||||
'first_name' => 'John',
|
||||
'last_name' => 'Doe',
|
||||
]);
|
||||
$moodTrackingEvent = MoodTrackingEvent::factory()->create([
|
||||
'contact_id' => $contact->id,
|
||||
'rated_at' => '2020-01-01 00:00:00',
|
||||
'note' => 'Be awesome',
|
||||
'number_of_hours_slept' => 3,
|
||||
]);
|
||||
|
||||
$feedItem = ContactFeedItem::factory()->create([
|
||||
'contact_id' => $contact->id,
|
||||
'action' => ContactFeedItem::ACTION_MOOD_TRACKING_EVENT_CREATED,
|
||||
'description' => 'Be awesome',
|
||||
]);
|
||||
$moodTrackingEvent->feedItem()->save($feedItem);
|
||||
|
||||
$array = ActionFeedMoodTrackingEvent::data($feedItem, $user);
|
||||
|
||||
$this->assertEquals(
|
||||
[
|
||||
'mood_tracking_event' => [
|
||||
'object' => [
|
||||
'id' => $moodTrackingEvent->id,
|
||||
'rated_at' => 'Jan 01, 2020',
|
||||
'note' => 'Be awesome',
|
||||
'number_of_hours_slept' => 3,
|
||||
],
|
||||
'description' => 'Be awesome',
|
||||
],
|
||||
'contact' => [
|
||||
'id' => $contact->id,
|
||||
'name' => 'John Doe',
|
||||
'age' => null,
|
||||
'avatar' => $contact->avatar,
|
||||
'url' => env('APP_URL').'/vaults/'.$contact->vault_id.'/contacts/'.$contact->id,
|
||||
],
|
||||
],
|
||||
$array
|
||||
);
|
||||
}
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Domains\Contact\ManageMoodTrackingEvents\Services;
|
||||
|
||||
use App\Domains\Contact\ManageMoodTrackingEvents\Services\CreateMoodTrackingEvent;
|
||||
use App\Exceptions\NotEnoughPermissionException;
|
||||
use App\Models\Account;
|
||||
use App\Models\Contact;
|
||||
use App\Models\ContactFeedItem;
|
||||
use App\Models\MoodTrackingParameter;
|
||||
use App\Models\User;
|
||||
use App\Models\Vault;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Tests\TestCase;
|
||||
|
||||
class CreateMoodTrackingEventTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_creates_a_mood_tracking_event(): void
|
||||
{
|
||||
$regis = $this->createUser();
|
||||
$vault = $this->createVault($regis->account);
|
||||
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
|
||||
$contact = Contact::factory()->create(['vault_id' => $vault->id]);
|
||||
$moodTrackingParameter = MoodTrackingParameter::factory()->create(['vault_id' => $vault->id]);
|
||||
|
||||
$this->executeService($regis, $regis->account, $vault, $contact, $moodTrackingParameter);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_if_wrong_parameters_are_given(): void
|
||||
{
|
||||
$request = [
|
||||
'title' => 'Ross',
|
||||
];
|
||||
|
||||
$this->expectException(ValidationException::class);
|
||||
(new CreateMoodTrackingEvent())->execute($request);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_if_user_doesnt_belong_to_account(): void
|
||||
{
|
||||
$this->expectException(ModelNotFoundException::class);
|
||||
|
||||
$regis = $this->createUser();
|
||||
$account = Account::factory()->create();
|
||||
$vault = $this->createVault($regis->account);
|
||||
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
|
||||
$contact = Contact::factory()->create(['vault_id' => $vault->id]);
|
||||
$moodTrackingParameter = MoodTrackingParameter::factory()->create(['vault_id' => $vault->id]);
|
||||
|
||||
$this->executeService($regis, $account, $vault, $contact, $moodTrackingParameter);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_if_contact_doesnt_belong_to_vault(): void
|
||||
{
|
||||
$this->expectException(ModelNotFoundException::class);
|
||||
|
||||
$regis = $this->createUser();
|
||||
$vault = $this->createVault($regis->account);
|
||||
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
|
||||
$contact = Contact::factory()->create();
|
||||
$moodTrackingParameter = MoodTrackingParameter::factory()->create(['vault_id' => $vault->id]);
|
||||
|
||||
$this->executeService($regis, $regis->account, $vault, $contact, $moodTrackingParameter);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_if_user_doesnt_have_right_permission_in_vault(): void
|
||||
{
|
||||
$this->expectException(NotEnoughPermissionException::class);
|
||||
|
||||
$regis = $this->createUser();
|
||||
$vault = $this->createVault($regis->account);
|
||||
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_VIEW, $vault);
|
||||
$contact = Contact::factory()->create(['vault_id' => $vault->id]);
|
||||
$moodTrackingParameter = MoodTrackingParameter::factory()->create(['vault_id' => $vault->id]);
|
||||
|
||||
$this->executeService($regis, $regis->account, $vault, $contact, $moodTrackingParameter);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_if_parameter_doesnt_belong_to_vault(): void
|
||||
{
|
||||
$this->expectException(ModelNotFoundException::class);
|
||||
|
||||
$regis = $this->createUser();
|
||||
$vault = $this->createVault($regis->account);
|
||||
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
|
||||
$contact = Contact::factory()->create(['vault_id' => $vault->id]);
|
||||
$moodTrackingParameter = MoodTrackingParameter::factory()->create();
|
||||
|
||||
$this->executeService($regis, $regis->account, $vault, $contact, $moodTrackingParameter);
|
||||
}
|
||||
|
||||
private function executeService(User $author, Account $account, Vault $vault, Contact $contact, MoodTrackingParameter $moodTrackingParameter): void
|
||||
{
|
||||
$request = [
|
||||
'account_id' => $account->id,
|
||||
'vault_id' => $vault->id,
|
||||
'author_id' => $author->id,
|
||||
'contact_id' => $contact->id,
|
||||
'mood_tracking_parameter_id' => $moodTrackingParameter->id,
|
||||
'rated_at' => '1982-02-03',
|
||||
'note' => 'fou',
|
||||
'number_of_hours_slept' => 3,
|
||||
];
|
||||
|
||||
$event = (new CreateMoodTrackingEvent())->execute($request);
|
||||
|
||||
$this->assertDatabaseHas('mood_tracking_events', [
|
||||
'id' => $event->id,
|
||||
'contact_id' => $contact->id,
|
||||
'mood_tracking_parameter_id' => $moodTrackingParameter->id,
|
||||
'rated_at' => '1982-02-03 00:00:00',
|
||||
'note' => 'fou',
|
||||
'number_of_hours_slept' => 3,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('contact_feed_items', [
|
||||
'contact_id' => $contact->id,
|
||||
'action' => ContactFeedItem::ACTION_MOOD_TRACKING_EVENT_CREATED,
|
||||
]);
|
||||
}
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Domains\Contact\ManageMoodTrackingEvents\Services;
|
||||
|
||||
use App\Domains\Contact\ManageMoodTrackingEvents\Services\DestroyMoodTrackingEvent;
|
||||
use App\Exceptions\NotEnoughPermissionException;
|
||||
use App\Models\Account;
|
||||
use App\Models\Contact;
|
||||
use App\Models\ContactFeedItem;
|
||||
use App\Models\MoodTrackingEvent;
|
||||
use App\Models\User;
|
||||
use App\Models\Vault;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Tests\TestCase;
|
||||
|
||||
class DestroyMoodTrackingEventTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_destroys_a_mood_tracking_event(): void
|
||||
{
|
||||
$regis = $this->createUser();
|
||||
$vault = $this->createVault($regis->account);
|
||||
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
|
||||
$contact = Contact::factory()->create(['vault_id' => $vault->id]);
|
||||
$moodTrackingEvent = MoodTrackingEvent::factory()->create([
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$this->executeService($regis, $regis->account, $vault, $contact, $moodTrackingEvent);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_if_wrong_parameters_are_given(): void
|
||||
{
|
||||
$request = [
|
||||
'title' => 'Ross',
|
||||
];
|
||||
|
||||
$this->expectException(ValidationException::class);
|
||||
(new DestroyMoodTrackingEvent())->execute($request);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_if_user_doesnt_belong_to_account(): void
|
||||
{
|
||||
$this->expectException(ModelNotFoundException::class);
|
||||
|
||||
$regis = $this->createUser();
|
||||
$account = Account::factory()->create();
|
||||
$vault = $this->createVault($regis->account);
|
||||
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
|
||||
$contact = Contact::factory()->create(['vault_id' => $vault->id]);
|
||||
$moodTrackingEvent = MoodTrackingEvent::factory()->create([
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$this->executeService($regis, $account, $vault, $contact, $moodTrackingEvent);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_if_contact_doesnt_belong_to_vault(): void
|
||||
{
|
||||
$this->expectException(ModelNotFoundException::class);
|
||||
|
||||
$regis = $this->createUser();
|
||||
$vault = $this->createVault($regis->account);
|
||||
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
|
||||
$contact = Contact::factory()->create();
|
||||
$moodTrackingEvent = MoodTrackingEvent::factory()->create([
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$this->executeService($regis, $regis->account, $vault, $contact, $moodTrackingEvent);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_if_user_doesnt_have_right_permission_in_initial_vault(): void
|
||||
{
|
||||
$this->expectException(NotEnoughPermissionException::class);
|
||||
|
||||
$regis = $this->createUser();
|
||||
$vault = $this->createVault($regis->account);
|
||||
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_VIEW, $vault);
|
||||
$contact = Contact::factory()->create(['vault_id' => $vault->id]);
|
||||
$moodTrackingEvent = MoodTrackingEvent::factory()->create([
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$this->executeService($regis, $regis->account, $vault, $contact, $moodTrackingEvent);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_if_event_does_not_exist(): void
|
||||
{
|
||||
$this->expectException(ModelNotFoundException::class);
|
||||
|
||||
$regis = $this->createUser();
|
||||
$vault = $this->createVault($regis->account);
|
||||
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
|
||||
$contact = Contact::factory()->create(['vault_id' => $vault->id]);
|
||||
$moodTrackingEvent = MoodTrackingEvent::factory()->create();
|
||||
|
||||
$this->executeService($regis, $regis->account, $vault, $contact, $moodTrackingEvent);
|
||||
}
|
||||
|
||||
private function executeService(User $author, Account $account, Vault $vault, Contact $contact, MoodTrackingEvent $moodTrackingEvent): void
|
||||
{
|
||||
$request = [
|
||||
'account_id' => $account->id,
|
||||
'vault_id' => $vault->id,
|
||||
'author_id' => $author->id,
|
||||
'contact_id' => $contact->id,
|
||||
'mood_tracking_event_id' => $moodTrackingEvent->id,
|
||||
];
|
||||
|
||||
(new DestroyMoodTrackingEvent())->execute($request);
|
||||
|
||||
$this->assertDatabaseMissing('mood_tracking_events', [
|
||||
'id' => $moodTrackingEvent->id,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('contact_feed_items', [
|
||||
'contact_id' => $contact->id,
|
||||
'action' => ContactFeedItem::ACTION_MOOD_TRACKING_EVENT_DESTROYED,
|
||||
]);
|
||||
}
|
||||
}
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Domains\Contact\ManageMoodTrackingEvents\Services;
|
||||
|
||||
use App\Domains\Contact\ManageMoodTrackingEvents\Services\UpdateMoodTrackingEvent;
|
||||
use App\Exceptions\NotEnoughPermissionException;
|
||||
use App\Models\Account;
|
||||
use App\Models\Contact;
|
||||
use App\Models\ContactFeedItem;
|
||||
use App\Models\ContactInformationType;
|
||||
use App\Models\MoodTrackingEvent;
|
||||
use App\Models\MoodTrackingParameter;
|
||||
use App\Models\User;
|
||||
use App\Models\Vault;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Tests\TestCase;
|
||||
|
||||
class UpdateMoodTrackingEventTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_updates_a_mood_tracking_event(): void
|
||||
{
|
||||
$regis = $this->createUser();
|
||||
$vault = $this->createVault($regis->account);
|
||||
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
|
||||
$contact = Contact::factory()->create(['vault_id' => $vault->id]);
|
||||
$moodTrackingParameter = MoodTrackingParameter::factory()->create(['vault_id' => $vault->id]);
|
||||
$event = MoodTrackingEvent::factory()->create([
|
||||
'contact_id' => $contact->id,
|
||||
'mood_tracking_parameter_id' => $moodTrackingParameter->id,
|
||||
]);
|
||||
|
||||
$this->executeService($regis, $regis->account, $vault, $contact, $event, $moodTrackingParameter);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_if_wrong_parameters_are_given(): void
|
||||
{
|
||||
$request = [
|
||||
'title' => 'Ross',
|
||||
];
|
||||
|
||||
$this->expectException(ValidationException::class);
|
||||
(new UpdateMoodTrackingEvent())->execute($request);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_if_user_doesnt_belong_to_account(): void
|
||||
{
|
||||
$this->expectException(ModelNotFoundException::class);
|
||||
|
||||
$regis = $this->createUser();
|
||||
$account = Account::factory()->create();
|
||||
$vault = $this->createVault($regis->account);
|
||||
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
|
||||
$contact = Contact::factory()->create(['vault_id' => $vault->id]);
|
||||
$moodTrackingParameter = MoodTrackingParameter::factory()->create(['vault_id' => $vault->id]);
|
||||
$event = MoodTrackingEvent::factory()->create([
|
||||
'contact_id' => $contact->id,
|
||||
'mood_tracking_parameter_id' => $moodTrackingParameter->id,
|
||||
]);
|
||||
|
||||
$this->executeService($regis, $account, $vault, $contact, $event, $moodTrackingParameter);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_if_contact_doesnt_belong_to_vault(): void
|
||||
{
|
||||
$this->expectException(ModelNotFoundException::class);
|
||||
|
||||
$regis = $this->createUser();
|
||||
$vault = $this->createVault($regis->account);
|
||||
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
|
||||
$contact = Contact::factory()->create();
|
||||
$moodTrackingParameter = MoodTrackingParameter::factory()->create(['vault_id' => $vault->id]);
|
||||
$event = MoodTrackingEvent::factory()->create([
|
||||
'contact_id' => $contact->id,
|
||||
'mood_tracking_parameter_id' => $moodTrackingParameter->id,
|
||||
]);
|
||||
|
||||
$this->executeService($regis, $regis->account, $vault, $contact, $event, $moodTrackingParameter);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_if_user_doesnt_have_right_permission_in_initial_vault(): void
|
||||
{
|
||||
$this->expectException(NotEnoughPermissionException::class);
|
||||
|
||||
$regis = $this->createUser();
|
||||
$vault = $this->createVault($regis->account);
|
||||
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_VIEW, $vault);
|
||||
$contact = Contact::factory()->create(['vault_id' => $vault->id]);
|
||||
$moodTrackingParameter = MoodTrackingParameter::factory()->create(['vault_id' => $vault->id]);
|
||||
$event = MoodTrackingEvent::factory()->create([
|
||||
'contact_id' => $contact->id,
|
||||
'mood_tracking_parameter_id' => $moodTrackingParameter->id,
|
||||
]);
|
||||
|
||||
$this->executeService($regis, $regis->account, $vault, $contact, $event, $moodTrackingParameter);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_if_event_is_not_in_the_contact(): void
|
||||
{
|
||||
$this->expectException(ModelNotFoundException::class);
|
||||
|
||||
$regis = $this->createUser();
|
||||
$vault = $this->createVault($regis->account);
|
||||
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
|
||||
$contact = Contact::factory()->create(['vault_id' => $vault->id]);
|
||||
$event = ContactInformationType::factory()->create();
|
||||
$moodTrackingParameter = MoodTrackingParameter::factory()->create(['vault_id' => $vault->id]);
|
||||
$event = MoodTrackingEvent::factory()->create([
|
||||
'mood_tracking_parameter_id' => $moodTrackingParameter->id,
|
||||
]);
|
||||
|
||||
$this->executeService($regis, $regis->account, $vault, $contact, $event, $moodTrackingParameter);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_if_parameter_doesnt_belong_to_vault(): void
|
||||
{
|
||||
$this->expectException(ModelNotFoundException::class);
|
||||
|
||||
$regis = $this->createUser();
|
||||
$vault = $this->createVault($regis->account);
|
||||
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
|
||||
$contact = Contact::factory()->create(['vault_id' => $vault->id]);
|
||||
$moodTrackingParameter = MoodTrackingParameter::factory()->create();
|
||||
$event = MoodTrackingEvent::factory()->create([
|
||||
'contact_id' => $contact->id,
|
||||
'mood_tracking_parameter_id' => $moodTrackingParameter->id,
|
||||
]);
|
||||
|
||||
$this->executeService($regis, $regis->account, $vault, $contact, $event, $moodTrackingParameter);
|
||||
}
|
||||
|
||||
private function executeService(User $author, Account $account, Vault $vault, Contact $contact, MoodTrackingEvent $event, MoodTrackingParameter $moodTrackingParameter): void
|
||||
{
|
||||
$request = [
|
||||
'account_id' => $account->id,
|
||||
'vault_id' => $vault->id,
|
||||
'author_id' => $author->id,
|
||||
'contact_id' => $contact->id,
|
||||
'mood_tracking_event_id' => $event->id,
|
||||
'mood_tracking_parameter_id' => $moodTrackingParameter->id,
|
||||
'rated_at' => '1982-02-03',
|
||||
'note' => 'fou',
|
||||
'number_of_hours_slept' => 3,
|
||||
];
|
||||
|
||||
$event = (new UpdateMoodTrackingEvent())->execute($request);
|
||||
|
||||
$this->assertDatabaseHas('mood_tracking_events', [
|
||||
'id' => $event->id,
|
||||
'contact_id' => $contact->id,
|
||||
'mood_tracking_parameter_id' => $moodTrackingParameter->id,
|
||||
'rated_at' => '1982-02-03 00:00:00',
|
||||
'note' => 'fou',
|
||||
'number_of_hours_slept' => 3,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('contact_feed_items', [
|
||||
'contact_id' => $contact->id,
|
||||
'action' => ContactFeedItem::ACTION_MOOD_TRACKING_EVENT_UPDATED,
|
||||
]);
|
||||
}
|
||||
}
|
||||
+13
-7
@@ -34,31 +34,37 @@ class ReportImportantDateSummaryIndexViewHelperTest extends TestCase
|
||||
'label' => 'stop it',
|
||||
]);
|
||||
|
||||
$collection = ReportImportantDateSummaryIndexViewHelper::data($vault, $user);
|
||||
$array = ReportImportantDateSummaryIndexViewHelper::data($vault, $user);
|
||||
|
||||
$this->assertEquals(
|
||||
0,
|
||||
$collection->toArray()[0]['id']
|
||||
$array['months']->toArray()[0]['id']
|
||||
);
|
||||
$this->assertEquals(
|
||||
'Oct 2022',
|
||||
$collection->toArray()[0]['month']
|
||||
$array['months']->toArray()[0]['month']
|
||||
);
|
||||
$this->assertEquals(
|
||||
[],
|
||||
$collection->toArray()[0]['important_dates']->toArray()
|
||||
$array['months']->toArray()[0]['important_dates']->toArray()
|
||||
);
|
||||
$this->assertEquals(
|
||||
$importantDate->id,
|
||||
$collection->toArray()[5]['important_dates']->toArray()[0]['id']
|
||||
$array['months']->toArray()[5]['important_dates']->toArray()[0]['id']
|
||||
);
|
||||
$this->assertEquals(
|
||||
'stop it',
|
||||
$collection->toArray()[5]['important_dates']->toArray()[0]['label']
|
||||
$array['months']->toArray()[5]['important_dates']->toArray()[0]['label']
|
||||
);
|
||||
$this->assertEquals(
|
||||
'Mar 12, 2024',
|
||||
$collection->toArray()[5]['important_dates']->toArray()[0]['happened_at']
|
||||
$array['months']->toArray()[5]['important_dates']->toArray()[0]['happened_at']
|
||||
);
|
||||
$this->assertEquals(
|
||||
[
|
||||
'reports' => env('APP_URL').'/vaults/'.$vault->id.'/reports',
|
||||
],
|
||||
$array['url']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Domains\Vault\ManageReports\Web\ViewHelpers;
|
||||
|
||||
use App\Domains\Vault\ManageReports\Web\ViewHelpers\ReportIndexViewHelper;
|
||||
use App\Models\Vault;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ReportIndexViewHelperTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_gets_the_data_needed_for_the_view(): void
|
||||
{
|
||||
$vault = Vault::factory()->create();
|
||||
$array = ReportIndexViewHelper::data($vault);
|
||||
|
||||
$this->assertEquals(
|
||||
[
|
||||
'url' => [
|
||||
'mood_tracking_events' => env('APP_URL').'/vaults/'.$vault->id.'/reports/moodTrackingEvents',
|
||||
'important_date_summary' => env('APP_URL').'/vaults/'.$vault->id.'/reports/importantDates',
|
||||
],
|
||||
],
|
||||
$array
|
||||
);
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Domains\Vault\ManageReports\Web\ViewHelpers;
|
||||
|
||||
use App\Domains\Vault\ManageReports\Web\ViewHelpers\ReportMoodTrackingEventIndexViewHelper;
|
||||
use App\Models\Contact;
|
||||
use App\Models\MoodTrackingEvent;
|
||||
use App\Models\MoodTrackingParameter;
|
||||
use App\Models\Vault;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ReportMoodTrackingEventIndexViewHelperTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_gets_the_data_needed_for_the_view(): void
|
||||
{
|
||||
Carbon::setTestNow(Carbon::create(2018, 10, 10));
|
||||
$user = $this->createUser();
|
||||
$vault = $this->createVault($user->account);
|
||||
$vault = $this->setPermissionInVault($user, Vault::PERMISSION_EDIT, $vault);
|
||||
$contact = Contact::factory()->create(['vault_id' => $vault->id]);
|
||||
$moodTrackingParameter = MoodTrackingParameter::factory()->create([
|
||||
'vault_id' => $vault->id,
|
||||
]);
|
||||
$moodTrackingEvent = MoodTrackingEvent::factory()->create([
|
||||
'contact_id' => $contact->id,
|
||||
'mood_tracking_parameter_id' => $moodTrackingParameter->id,
|
||||
'rated_at' => '2018-01-01 00:00:00',
|
||||
]);
|
||||
|
||||
$array = ReportMoodTrackingEventIndexViewHelper::data($vault, $user, 2018);
|
||||
|
||||
$this->assertEquals(
|
||||
1,
|
||||
$array['months']->toArray()[0]['id']
|
||||
);
|
||||
$this->assertEquals(
|
||||
'Jan',
|
||||
$array['months']->toArray()[0]['month_word']
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,8 @@ use App\Domains\Vault\ManageVault\Web\ViewHelpers\VaultShowViewHelper;
|
||||
use App\Models\Contact;
|
||||
use App\Models\ContactReminder;
|
||||
use App\Models\ContactTask;
|
||||
use App\Models\MoodTrackingEvent;
|
||||
use App\Models\MoodTrackingParameter;
|
||||
use App\Models\User;
|
||||
use App\Models\UserNotificationChannel;
|
||||
use App\Models\Vault;
|
||||
@@ -245,4 +247,67 @@ class VaultShowViewHelperTest extends TestCase
|
||||
$array['tasks']->toArray()
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_the_mood_tracking_parameters(): void
|
||||
{
|
||||
$ross = $this->createAdministrator();
|
||||
$vault = $this->createVault($ross->account);
|
||||
$vault = $this->setPermissionInVault($ross, Vault::PERMISSION_MANAGE, $vault);
|
||||
$moodTrackingParameter = MoodTrackingParameter::factory()->create([
|
||||
'vault_id' => $vault->id,
|
||||
]);
|
||||
$contact = $ross->getContactInVault($vault);
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2018, 1, 1));
|
||||
$array = VaultShowViewHelper::moodTrackingEvents($vault, $ross);
|
||||
|
||||
$this->assertEquals(
|
||||
[
|
||||
0 => [
|
||||
'id' => $moodTrackingParameter->id,
|
||||
'label' => $moodTrackingParameter->label,
|
||||
'hex_color' => $moodTrackingParameter->hex_color,
|
||||
],
|
||||
],
|
||||
$array['mood_tracking_parameters']->toArray()
|
||||
);
|
||||
$this->assertEquals(
|
||||
'2018-01-01',
|
||||
$array['current_date']
|
||||
);
|
||||
$this->assertEquals(
|
||||
[
|
||||
'history' => env('APP_URL').'/vaults/'.$vault->id.'/reports/moodTrackingEvents',
|
||||
'store' => env('APP_URL').'/vaults/'.$vault->id.'/contacts/'.$contact->id.'/moodTrackingEvents',
|
||||
],
|
||||
$array['url']
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_the_dto_for_mood_tracking_event(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$moodTrackingParameter = MoodTrackingParameter::factory()->create();
|
||||
$moodTrackingEvent = MoodTrackingEvent::factory()->create([
|
||||
'mood_tracking_parameter_id' => $moodTrackingParameter->id,
|
||||
'rated_at' => '2018-01-01 00:00:00',
|
||||
'note' => 'note',
|
||||
'number_of_hours_slept' => 8,
|
||||
]);
|
||||
|
||||
$array = VaultShowViewHelper::dtoMoodTrackingEvent($moodTrackingEvent, $user);
|
||||
|
||||
$this->assertEquals(
|
||||
[
|
||||
'id' => $moodTrackingEvent->id,
|
||||
'label' => $moodTrackingEvent->moodTrackingParameter->label,
|
||||
'rated_at' => 'Jan 01, 2018',
|
||||
'note' => 'note',
|
||||
'number_of_hours_slept' => 8,
|
||||
],
|
||||
$array
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -19,7 +19,6 @@ class UpdateMoodTrackingParameterPositionTest extends TestCase
|
||||
/** @test */
|
||||
public function it_updates_a_mood_tracking_parameter_position(): void
|
||||
{
|
||||
$ross = $this->createAdministrator();
|
||||
$ross = $this->createAdministrator();
|
||||
$vault = $this->createVault($ross->account);
|
||||
$vault = $this->setPermissionInVault($ross, Vault::PERMISSION_MANAGE, $vault);
|
||||
|
||||
@@ -125,6 +125,17 @@ class DateHelperTest extends TestCase
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_short_month(): void
|
||||
{
|
||||
$date = Carbon::createFromFormat('Y-m-d H:i:s', '1978-10-01 17:56:03');
|
||||
|
||||
$this->assertEquals(
|
||||
'Oct',
|
||||
DateHelper::formatMonthNumber($date)
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_short_month_and_year(): void
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@ use App\Models\Group;
|
||||
use App\Models\Label;
|
||||
use App\Models\LifeEvent;
|
||||
use App\Models\Loan;
|
||||
use App\Models\MoodTrackingEvent;
|
||||
use App\Models\Note;
|
||||
use App\Models\Pet;
|
||||
use App\Models\Post;
|
||||
@@ -282,6 +283,17 @@ class ContactTest extends TestCase
|
||||
$this->assertTrue($contact->lifeEvents()->exists());
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_has_many_mood_tracking_events(): void
|
||||
{
|
||||
$contact = Contact::factory()->create();
|
||||
MoodTrackingEvent::factory()->count(2)->create([
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$this->assertTrue($contact->moodTrackingEvents()->exists());
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_has_many_addresses(): void
|
||||
{
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Models;
|
||||
|
||||
use App\Models\MoodTrackingEvent;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\TestCase;
|
||||
|
||||
class MoodTrackingEventTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_has_one_contact()
|
||||
{
|
||||
$event = MoodTrackingEvent::factory()->create();
|
||||
|
||||
$this->assertTrue($event->contact()->exists());
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_has_one_parameter()
|
||||
{
|
||||
$event = MoodTrackingEvent::factory()->create();
|
||||
|
||||
$this->assertTrue($event->moodTrackingParameter()->exists());
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Tests\Unit\Models;
|
||||
|
||||
use App\Models\MoodTrackingEvent;
|
||||
use App\Models\MoodTrackingParameter;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\TestCase;
|
||||
@@ -32,6 +33,17 @@ class MoodTrackingParameterTest extends TestCase
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_has_many_events(): void
|
||||
{
|
||||
$parameter = MoodTrackingParameter::factory()->create();
|
||||
MoodTrackingEvent::factory()->count(2)->create([
|
||||
'mood_tracking_parameter_id' => $parameter->id,
|
||||
]);
|
||||
|
||||
$this->assertTrue($parameter->moodTrackingEvents()->exists());
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_the_custom_label_if_defined()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user