-
-
Notifications
You must be signed in to change notification settings - Fork 144
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added timezone for user; Moved dashboard to controller
- Loading branch information
Showing
16 changed files
with
494 additions
and
308 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
], | ||
]; | ||
} | ||
} |
Oops, something went wrong.