Skip to content

Commit

Permalink
feat: calendar view in a vault (monicahq/chandler#464)
Browse files Browse the repository at this point in the history
  • Loading branch information
djaiss authored May 5, 2023
1 parent 23f98ae commit 4da9a21
Show file tree
Hide file tree
Showing 34 changed files with 843 additions and 7 deletions.
2 changes: 2 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
nodeLinker: node-modules

yarnPath: .yarn/releases/yarn-3.5.0.cjs

checksumBehavior: update
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

namespace App\Domains\Vault\ManageCalendar\Web\Controllers;

use App\Domains\Vault\ManageCalendar\Web\ViewHelpers\VaultCalendarIndexViewHelper;
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 VaultCalendarController extends Controller
{
public function index(Request $request, Vault $vault)
{
$vault = Vault::findOrFail($vault->id);

return Inertia::render('Vault/Calendar/Index', [
'layoutData' => VaultIndexViewHelper::layoutData($vault),
'data' => VaultCalendarIndexViewHelper::data(
vault: $vault,
user: Auth::user(),
year: Carbon::now()->year,
month: Carbon::now()->month,
),
]);
}

public function month(Request $request, Vault $vault, int $year, int $month)
{
$vault = Vault::findOrFail($vault->id);

return Inertia::render('Vault/Calendar/Index', [
'layoutData' => VaultIndexViewHelper::layoutData($vault),
'data' => VaultCalendarIndexViewHelper::data(
vault: $vault,
user: Auth::user(),
year: $year,
month: $month,
),
]);
}

public function day(Request $request, Vault $vault, int $year, int $month, int $day)
{
$vault = Vault::findOrFail($vault->id);

return response()->json([
'data' => VaultCalendarIndexViewHelper::getDayInformation(
vault: $vault,
user: Auth::user(),
year: $year,
month: $month,
day: $day,
),
], 200);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
<?php

namespace App\Domains\Vault\ManageCalendar\Web\ViewHelpers;

use App\Helpers\ContactCardHelper;
use App\Helpers\DateHelper;
use App\Models\ContactImportantDate;
use App\Models\MoodTrackingEvent;
use App\Models\Post;
use App\Models\User;
use App\Models\Vault;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Support\Collection;

class VaultCalendarIndexViewHelper
{
public static function data(Vault $vault, User $user, int $year, int $month): array
{
$date = Carbon::createFromDate($year, $month, 1);
$previousMonth = $date->copy()->subMonth();
$nextMonth = $date->copy()->addMonth();

$collection = self::buildMonth($vault, $user, $year, $month);

return [
'weeks' => $collection,
'current_month' => DateHelper::formatLongMonthAndYear($date),
'previous_month' => DateHelper::formatLongMonthAndYear($previousMonth),
'next_month' => DateHelper::formatLongMonthAndYear($nextMonth),
'url' => [
'previous' => route('vault.calendar.month', [
'vault' => $vault->id,
'year' => $previousMonth->year,
'month' => $previousMonth->month,
]),
'next' => route('vault.calendar.month', [
'vault' => $vault->id,
'year' => $nextMonth->year,
'month' => $nextMonth->month,
]),
],
];
}

/**
* Completely copied from https://tighten.com/insights/building-a-calendar-with-carbon/.
*/
public static function buildMonth(Vault $vault, User $user, int $year, int $month): Collection
{
$firstDayOfMonth = CarbonImmutable::create($year, $month, 1)->startOfMonth();
$lastDayOfMonth = CarbonImmutable::create($year, $month, 1)->endOfMonth();
$startOfWeek = $firstDayOfMonth->startOfWeek();
$endOfWeek = $lastDayOfMonth->endOfWeek();
$contactsId = $vault->contacts()->pluck('id');

// @phpstan-ignore-next-line
return collect($startOfWeek->toPeriod($endOfWeek)->toArray())
->map(fn (CarbonImmutable $day) => [
'id' => $day->day,
'date' => $day->format('d'),
'is_today' => $day->isToday(),
'is_in_month' => $day->month === $firstDayOfMonth->month,
'important_dates' => self::getImportantDates($day->month, $day->day, $contactsId),
'mood_events' => self::getMood($vault, $user, $day),
'posts' => self::getJournalEntries($vault, $day),
'url' => [
'show' => route('vault.calendar.day', [
'vault' => $vault->id,
'year' => $day->year,
'month' => $day->month,
'day' => $day->day,
]),
],
])
->chunk(7);
}

public static function getImportantDates(int $month, int $day, Collection $contactsId): Collection
{
return ContactImportantDate::where('day', $day)
->where('month', $month)
->whereIn('contact_id', $contactsId)
->with('contact')
->get()
->unique('contact_id')
->map(fn (ContactImportantDate $importantDate) => [
'id' => $importantDate->id,
'label' => $importantDate->label,
'type' => [
'id' => $importantDate->contactImportantDateType?->id,
'label' => $importantDate->contactImportantDateType?->label,
],
'contact' => ContactCardHelper::data($importantDate->contact),
]);
}

public static function getMood(Vault $vault, User $user, CarbonImmutable $date): Collection
{
$contact = $user->getContactInVault($vault);

return $contact->moodTrackingEvents()
->with('moodTrackingParameter')
->whereDate('rated_at', $date)
->get()
->map(fn (MoodTrackingEvent $moodTrackingEvent) => [
'id' => $moodTrackingEvent->id,
'note' => $moodTrackingEvent->note,
'number_of_hours_slept' => $moodTrackingEvent->number_of_hours_slept,
'mood_tracking_parameter' => [
'id' => $moodTrackingEvent->moodTrackingParameter->id,
'label' => $moodTrackingEvent->moodTrackingParameter->label,
'hex_color' => $moodTrackingEvent->moodTrackingParameter->hex_color,
],
]);
}

public static function getJournalEntries(Vault $vault, CarbonImmutable $day): Collection
{
$journalIds = $vault->journals->pluck('id');

return Post::whereIn('journal_id', $journalIds)
->whereDate('written_at', $day)
->with('journal')
->get()
->map(fn (Post $post) => [
'id' => $post->id,
'title' => $post->title,
'url' => [
'show' => route('post.show', [
'vault' => $post->journal->vault_id,
'journal' => $post->journal_id,
'post' => $post->id,
]),
],
]);
}

public static function getDayInformation(Vault $vault, User $user, int $year, int $month, int $day): array
{
$date = Carbon::createFromDate($year, $month, $day);
$immutableDate = CarbonImmutable::createFromDate($year, $month, $day);
$contactsId = $vault->contacts()->pluck('id');

return [
'day' => DateHelper::formatFullDate($date),
'important_dates' => self::getImportantDates($date->month, $date->day, $contactsId),
'mood_events' => self::getMood($vault, $user, $immutableDate),
'posts' => self::getJournalEntries($vault, $immutableDate),
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public function rules(): array
'show_journal_tab' => 'required|boolean',
'show_companies_tab' => 'required|boolean',
'show_reports_tab' => 'required|boolean',
'show_calendar_tab' => 'required|boolean',
];
}

Expand Down Expand Up @@ -51,6 +52,7 @@ public function execute(array $data): Vault
$this->vault->show_journal_tab = $data['show_journal_tab'];
$this->vault->show_companies_tab = $data['show_companies_tab'];
$this->vault->show_reports_tab = $data['show_reports_tab'];
$this->vault->show_calendar_tab = $data['show_calendar_tab'];
$this->vault->save();

return $this->vault;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public static function layoutData(Vault $vault = null): array
'show_journal_tab' => $vault->show_journal_tab,
'show_companies_tab' => $vault->show_companies_tab,
'show_reports_tab' => $vault->show_reports_tab,
'show_calendar_tab' => $vault->show_calendar_tab,
],
'url' => [
'dashboard' => route('vault.show', [
Expand All @@ -43,6 +44,9 @@ public static function layoutData(Vault $vault = null): array
'contacts' => route('contact.index', [
'vault' => $vault->id,
]),
'calendar' => route('vault.calendar.index', [
'vault' => $vault->id,
]),
'journals' => route('journal.index', [
'vault' => $vault->id,
]),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public function update(Request $request, string $vaultId)
'show_journal_tab' => $request->boolean('show_journal_tab'),
'show_companies_tab' => $request->boolean('show_companies_tab'),
'show_reports_tab' => $request->boolean('show_reports_tab'),
'show_calendar_tab' => $request->boolean('show_calendar_tab'),
];

(new UpdateVaultTabVisibility())->execute($data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ public static function data(Vault $vault): array
'show_journal_tab' => $vault->show_journal_tab,
'show_companies_tab' => $vault->show_companies_tab,
'show_reports_tab' => $vault->show_reports_tab,
'show_calendar_tab' => $vault->show_calendar_tab,
],
'url' => [
'template_update' => route('vault.settings.template.update', [
Expand Down
2 changes: 2 additions & 0 deletions app/Models/Vault.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class Vault extends Model
'show_files_tab',
'show_journal_tab',
'show_companies_tab',
'show_calendar_tab',
];

/**
Expand All @@ -57,6 +58,7 @@ class Vault extends Model
*/
protected $casts = [
'show_group_tab' => 'boolean',
'show_calendar_tab' => 'boolean',
'show_tasks_tab' => 'boolean',
'show_files_tab' => 'boolean',
'show_journal_tab' => 'boolean',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public function up()
$table->boolean('show_journal_tab')->default(true);
$table->boolean('show_companies_tab')->default(true);
$table->boolean('show_reports_tab')->default(true);
$table->boolean('show_calendar_tab')->default(true);
$table->timestamps();
});
}
Expand Down
Loading

0 comments on commit 4da9a21

Please sign in to comment.