Skip to content

Commit

Permalink
Added timezone for user; Moved dashboard to controller
Browse files Browse the repository at this point in the history
  • Loading branch information
korridor committed Mar 19, 2024
1 parent 0fd8abd commit fb1d127
Show file tree
Hide file tree
Showing 16 changed files with 494 additions and 308 deletions.
2 changes: 2 additions & 0 deletions app/Actions/Fortify/UpdateUserProfileInformation.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public function update(User $user, array $input): void
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'email', 'max:255', Rule::unique('users')->ignore($user->id)],
'photo' => ['nullable', 'mimes:jpg,jpeg,png', 'max:1024'],
'timezone' => ['required', 'timezone:all'],
])->validateWithBag('updateProfileInformation');

if (isset($input['photo'])) {
Expand All @@ -36,6 +37,7 @@ public function update(User $user, array $input): void
$user->forceFill([
'name' => $input['name'],
'email' => $input['email'],
'timezone' => $input['timezone'],
])->save();
}
}
Expand Down
9 changes: 9 additions & 0 deletions app/Http/Controllers/Web/Controller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace App\Http\Controllers\Web;

abstract class Controller extends \App\Http\Controllers\Controller
{
}
222 changes: 222 additions & 0 deletions app/Http/Controllers/Web/DashboardController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
<?php

declare(strict_types=1);

namespace App\Http\Controllers\Web;

use App\Models\User;
use App\Service\DashboardService;
use Illuminate\Support\Str;
use Inertia\Inertia;
use Inertia\Response;

class DashboardController extends Controller
{
public function dashboard(DashboardService $dashboardService): Response
{
/** @var User $user */
$user = auth()->user();
$dailyTrackedHours = $dashboardService->getDailyTrackedHours($user, 60);
$weeklyHistory = $dashboardService->getWeeklyHistory($user);

return Inertia::render('Dashboard', [
'weeklyProjectOverview' => [
[
'value' => 120,
'name' => 'Project 11',
'color' => '#26a69a',
],
[
'value' => 200,
'name' => 'Project 2',
'color' => '#d4e157',
],
[
'value' => 150,
'name' => 'Project 3',
'color' => '#ff7043',
],
],
'latestTasks' => [
// the 4 tasks with the most recent time entries
[
'id' => Str::uuid(),
'name' => 'Task 1',
'project_name' => 'Research',
'project_id' => Str::uuid(),
],
[
'id' => Str::uuid(),
'name' => 'Task 2',
'project_name' => 'Research',
'project_id' => Str::uuid(),
],
[
'id' => Str::uuid(),
'name' => 'Task 3',
'project_name' => 'Research',
'project_id' => Str::uuid(),
],
[
'id' => Str::uuid(),
'name' => 'Task 4',
'project_name' => 'Research',
'project_id' => Str::uuid(),
],
],
'lastSevenDays' => [
// the last 7 days with statistics for the time entries
[
'date' => '2024-02-26',
'duration' => 3600, // in seconds
// if that is too difficult we can just skip that for now
'history' => [
// duration in s of the 3h windows for the day starting at 00:00
300,
0,
500,
0,
100,
200,
100,
300,
],
],
[
'date' => '2024-02-25',
'duration' => 7200, // in seconds
'history' => [
// duration in s of the 3h windows for the day starting at 00:00
300,
0,
500,
0,
100,
200,
100,
300,
],
],
[
'date' => '2024-02-24',
'duration' => 10800, // in seconds
'history' => [
// duration in s of the 3h windows for the day starting at 00:00
300,
0,
500,
0,
100,
200,
100,
300,
],
],
[
'date' => '2024-02-23',
'duration' => 14400, // in seconds
'history' => [
// duration in s of the 3h windows for the day starting at 00:00
300,
0,
500,
0,
100,
200,
100,
300,
],
],
[
'date' => '2024-02-22',
'duration' => 18000, // in seconds
'history' => [
// duration in s of the 3h windows for the day starting at 00:00
300,
0,
500,
0,
100,
200,
100,
300,
],
],
[
'date' => '2024-02-21',
'duration' => 21600, // in seconds
'history' => [
// duration in s of the 3h windows for the day starting at 00:00
300,
0,
500,
0,
100,
200,
100,
300,
],
],
[
'date' => '2024-02-20',
'duration' => 25200, // in seconds
'history' => [
// duration in s of the 3h windows for the day starting at 00:00
300,
0,
500,
0,
100,
200,
100,
300,
],
],

],
'latestTeamActivity' => [
// the 4 most recently active members of your team with user_id, name, description of the latest time entry, time_entry_id, task_id and a boolean status if the team member is currently working
[
'user_id' => Str::uuid(),
'name' => 'John Doe',
'description' => 'Working on the new feature',
'time_entry_id' => Str::uuid(),
'task_id' => Str::uuid(),
'status' => true,
],
[
'user_id' => Str::uuid(),
'name' => 'Jane Doe',
'description' => 'Working on the new feature',
'time_entry_id' => Str::uuid(),
'task_id' => Str::uuid(),
'status' => false,
],
[
'user_id' => Str::uuid(),
'name' => 'John Smith',
'description' => 'Working on the new feature',
'time_entry_id' => Str::uuid(),
'task_id' => Str::uuid(),
'status' => true,
],
[
'user_id' => Str::uuid(),
'name' => 'Jane Smith',
'description' => 'Working on the new feature',
'time_entry_id' => Str::uuid(),
'task_id' => Str::uuid(),
'status' => false,
],
],
'dailyTrackedHours' => $dailyTrackedHours,
'totalWeeklyTime' => 400,
'totalWeeklyBillableTime' => 300,
'totalWeeklyBillableAmount' => [
'value' => 300.5,
'currency' => 'USD',
],
'weeklyHistory' => $weeklyHistory,
]);
}
}
1 change: 1 addition & 0 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
* @property string $email
* @property string|null $email_verified_at
* @property string|null $password
* @property string $timezone
* @property bool $is_placeholder
* @property Collection<Organization> $organizations
* @property Collection<TimeEntry> $timeEntries
Expand Down
11 changes: 11 additions & 0 deletions app/Providers/JetstreamServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
use App\Actions\Jetstream\UpdateOrganization;
use App\Models\Organization;
use App\Models\OrganizationInvitation;
use App\Service\TimezoneService;
use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;
use Laravel\Jetstream\Jetstream;

Expand Down Expand Up @@ -112,5 +114,14 @@ protected function configurePermissions(): void

Jetstream::role('placeholder', 'Placeholder', [
])->description('Placeholders are used for importing data. They cannot log in and have no permissions.');

Jetstream::inertia()->whenRendering(
'Profile/Show',
function (Request $request, array $data) {
return array_merge($data, [
'timezones' => $this->app->get(TimezoneService::class)->getSelectOptions(),
]);
}
);
}
}
106 changes: 106 additions & 0 deletions app/Service/DashboardService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php

declare(strict_types=1);

namespace App\Service;

use App\Models\TimeEntry;
use App\Models\User;
use Carbon\Carbon;
use Carbon\CarbonTimeZone;
use Illuminate\Support\Facades\DB;

class DashboardService
{
/**
* @return array<int, string>
*/
private function lastDays(int $days, CarbonTimeZone $timeZone): array
{
$result = [];
$date = Carbon::now($timeZone);
for ($i = 0; $i < $days; $i++) {
$result[] = $date->format('Y-m-d');
$date = $date->subDay();
}

return $result;
}

/**
* Get the daily tracked hours for the user
* First value: date
* Second value: seconds
*
* @return array<int, array{0: string, 1: int}>
*/
public function getDailyTrackedHours(User $user, int $days): array
{
$timezone = new CarbonTimeZone($user->timezone);
$timezoneShift = $timezone->getOffset(new \DateTime('now', new \DateTimeZone('UTC')));

if ($timezoneShift > 0) {
$dateWithTimeZone = 'start + INTERVAL \''.$timezoneShift.' second\'';
} elseif ($timezoneShift < 0) {
$dateWithTimeZone = 'start - INTERVAL \''.abs($timezoneShift).' second\'';
} else {
$dateWithTimeZone = 'start';
}

$resultDb = TimeEntry::query()
->select(DB::raw('DATE('.$dateWithTimeZone.') as date, round(sum(extract(epoch from (coalesce("end", now()) - start)))) as value'))
->where('user_id', '=', $user->id)
->groupBy(DB::raw('DATE('.$dateWithTimeZone.')'))
->orderBy('date')
->get()
->pluck('value', 'date');

$result = [];
$lastDays = $this->lastDays($days, $timezone);

foreach ($lastDays as $day) {
$result[] = [$day, (int) ($resultDb->get($day) ?? 0)];
}

return $result;
}

/**
* Statistics for the current week starting at Monday / Sunday
*
* @return array<int, array{date: string, duration: int}>
*/
public function getWeeklyHistory(User $user): array
{
return [
[
'date' => '2024-02-26',
'duration' => 3600,
],
[
'date' => '2024-02-27',
'duration' => 2000,
],
[
'date' => '2024-02-28',
'duration' => 4000,
],
[
'date' => '2024-02-29',
'duration' => 3000,
],
[
'date' => '2024-03-01',
'duration' => 5000,
],
[
'date' => '2024-03-02',
'duration' => 3000,
],
[
'date' => '2024-03-03',
'duration' => 2000,
],
];
}
}
Loading

0 comments on commit fb1d127

Please sign in to comment.