From d17482b3e97382a102ebb717a47825686257927a Mon Sep 17 00:00:00 2001 From: butburg Date: Tue, 3 Sep 2024 00:09:09 +0200 Subject: [PATCH] Improving usability from the app --- .timetracker | 2 +- src/app/Http/Controllers/AdminController.php | 2 +- src/app/Http/Controllers/PostController.php | 50 ++-- .../Http/Controllers/ProfileController.php | 92 +++++--- src/app/Http/Requests/Auth/LoginRequest.php | 25 +- .../Http/Requests/ProfileUpdateRequest.php | 26 ++- src/app/Models/Session.php | 19 ++ src/app/Models/User.php | 24 +- src/resources/views/admin/dashboard.blade.php | 25 -- src/resources/views/admin/index.blade.php | 21 ++ .../views/admin/partials/user-tile.blade.php | 83 +++++++ .../views/auth/verify-email.blade.php | 16 +- .../gallery/comment/show-comments.blade.php | 2 +- .../components/gallery/gallery.blade.php | 5 +- .../views/layouts/navigation.blade.php | 4 +- src/resources/views/posts/index.blade.php | 214 +++++++++--------- src/resources/views/profile/edit.blade.php | 14 +- .../partials/delete-user-form.blade.php | 2 - .../update-profile-information-form.blade.php | 39 ++-- src/routes/web.php | 15 +- 20 files changed, 409 insertions(+), 271 deletions(-) create mode 100644 src/app/Models/Session.php delete mode 100644 src/resources/views/admin/dashboard.blade.php create mode 100644 src/resources/views/admin/index.blade.php create mode 100644 src/resources/views/admin/partials/user-tile.blade.php diff --git a/.timetracker b/.timetracker index b2ad8f9..3c5ec3a 100644 --- a/.timetracker +++ b/.timetracker @@ -1 +1 @@ -{"total":171378,"sessions":[{"begin":"2024-05-24T11:32:18+02:00","end":"2024-05-24T11:32:26+02:00","duration":8},{"begin":"2024-05-24T11:32:27+02:00","end":"2024-05-24T11:34:28+02:00","duration":121},{"begin":"2024-05-24T11:34:46+02:00","end":"2024-05-24T11:34:48+02:00","duration":2},{"begin":"2024-05-24T11:34:57+02:00","end":"2024-05-24T11:38:44+02:00","duration":227},{"begin":"2024-05-24T11:40:40+02:00","end":"2024-05-24T12:16:37+02:00","duration":2157},{"begin":"2024-05-24T12:16:52+02:00","end":"2024-05-24T12:39:34+02:00","duration":1362},{"begin":"2024-05-24T13:00:12+02:00","end":"2024-05-24T13:03:23+02:00","duration":191},{"begin":"2024-05-24T13:07:04+02:00","end":"2024-05-24T14:12:49+02:00","duration":3945},{"begin":"2024-05-24T14:14:17+02:00","end":"2024-05-24T14:23:17+02:00","duration":540},{"begin":"2024-05-24T14:23:48+02:00","end":"2024-05-24T14:48:36+02:00","duration":1488},{"begin":"2024-05-24T14:49:01+02:00","end":"2024-05-24T15:24:18+02:00","duration":2117},{"begin":"2024-05-24T15:25:37+02:00","end":"2024-05-24T15:28:41+02:00","duration":184},{"begin":"2024-05-26T15:17:54+02:00","end":"2024-05-26T15:22:58+02:00","duration":304},{"begin":"2024-05-26T15:28:15+02:00","end":"2024-05-26T15:43:24+02:00","duration":909},{"begin":"2024-05-26T15:44:37+02:00","end":"2024-05-26T15:51:01+02:00","duration":384},{"begin":"2024-05-26T15:54:12+02:00","end":"2024-05-26T16:07:56+02:00","duration":824},{"begin":"2024-05-26T16:07:56+02:00","end":"2024-05-26T16:15:50+02:00","duration":474},{"begin":"2024-05-26T16:16:17+02:00","end":"2024-05-26T16:38:57+02:00","duration":1360},{"begin":"2024-05-26T20:55:51+02:00","end":"2024-05-26T21:10:25+02:00","duration":874},{"begin":"2024-05-26T21:13:13+02:00","end":"2024-05-26T21:32:00+02:00","duration":1127},{"begin":"2024-05-26T21:42:16+02:00","end":"2024-05-26T21:51:09+02:00","duration":533},{"begin":"2024-05-26T22:32:32+02:00","end":"2024-05-26T22:41:03+02:00","duration":511},{"begin":"2024-05-26T22:47:19+02:00","end":"2024-05-26T23:05:45+02:00","duration":1106},{"begin":"2024-05-27T16:07:05+02:00","end":"2024-05-27T16:10:06+02:00","duration":181},{"begin":"2024-05-27T16:11:01+02:00","end":"2024-05-27T16:52:36+02:00","duration":2495},{"begin":"2024-05-27T16:53:16+02:00","end":"2024-05-27T17:19:26+02:00","duration":1570},{"begin":"2024-05-27T21:12:07+02:00","end":"2024-05-27T21:15:38+02:00","duration":211},{"begin":"2024-05-28T09:09:41+02:00","end":"2024-05-28T09:14:21+02:00","duration":280},{"begin":"2024-05-28T09:43:08+02:00","end":"2024-05-28T09:50:56+02:00","duration":468},{"begin":"2024-05-28T10:01:12+02:00","end":"2024-05-28T10:09:54+02:00","duration":522},{"begin":"2024-05-28T10:11:10+02:00","end":"2024-05-28T10:16:59+02:00","duration":349},{"begin":"2024-05-28T10:22:36+02:00","end":"2024-05-28T10:29:58+02:00","duration":442},{"begin":"2024-05-28T10:32:11+02:00","end":"2024-05-28T10:42:29+02:00","duration":618},{"begin":"2024-05-28T10:42:42+02:00","end":"2024-05-28T10:45:52+02:00","duration":190},{"begin":"2024-05-28T10:46:10+02:00","end":"2024-05-28T10:49:11+02:00","duration":181},{"begin":"2024-05-28T10:50:30+02:00","end":"2024-05-28T10:56:46+02:00","duration":376},{"begin":"2024-05-28T10:57:52+02:00","end":"2024-05-28T11:02:02+02:00","duration":250},{"begin":"2024-05-28T11:07:49+02:00","end":"2024-05-28T11:10:52+02:00","duration":183},{"begin":"2024-05-28T12:29:08+02:00","end":"2024-05-28T12:38:44+02:00","duration":576},{"begin":"2024-05-28T16:39:49+02:00","end":"2024-05-28T16:42:51+02:00","duration":182},{"begin":"2024-05-28T17:25:20+02:00","end":"2024-05-28T17:28:21+02:00","duration":181},{"begin":"2024-05-28T17:58:20+02:00","end":"2024-05-28T18:14:17+02:00","duration":957},{"begin":"2024-05-28T18:14:23+02:00","end":"2024-05-28T18:36:17+02:00","duration":1314},{"begin":"2024-05-28T23:15:57+02:00","end":"2024-05-28T23:46:31+02:00","duration":1834},{"begin":"2024-05-28T23:46:35+02:00","end":"2024-05-28T23:55:16+02:00","duration":521},{"begin":"2024-05-29T14:36:59+02:00","end":"2024-05-29T14:40:47+02:00","duration":228},{"begin":"2024-05-29T14:49:58+02:00","end":"2024-05-29T14:54:36+02:00","duration":278},{"begin":"2024-05-29T14:55:10+02:00","end":"2024-05-29T14:56:29+02:00","duration":79},{"begin":"2024-05-29T14:56:33+02:00","end":"2024-05-29T14:57:13+02:00","duration":40},{"begin":"2024-05-29T14:57:17+02:00","end":"2024-05-29T15:11:31+02:00","duration":854},{"begin":"2024-05-29T16:36:49+02:00","end":"2024-05-29T16:39:50+02:00","duration":181},{"begin":"2024-05-31T12:20:27+02:00","end":"2024-05-31T12:23:25+02:00","duration":178},{"begin":"2024-05-31T14:28:22+02:00","end":"2024-05-31T14:31:59+02:00","duration":217},{"begin":"2024-05-31T14:32:22+02:00","end":"2024-05-31T15:17:52+02:00","duration":2730},{"begin":"2024-05-31T15:18:45+02:00","end":"2024-05-31T15:40:35+02:00","duration":1310},{"begin":"2024-05-31T15:40:45+02:00","end":"2024-05-31T16:18:02+02:00","duration":2237},{"begin":"2024-05-31T16:18:33+02:00","end":"2024-05-31T16:47:51+02:00","duration":1758},{"begin":"2024-05-31T19:06:34+02:00","end":"2024-05-31T19:21:05+02:00","duration":871},{"begin":"2024-05-31T19:23:13+02:00","end":"2024-05-31T19:30:54+02:00","duration":461},{"begin":"2024-05-31T19:33:31+02:00","end":"2024-05-31T19:41:39+02:00","duration":488},{"begin":"2024-05-31T19:48:56+02:00","end":"2024-05-31T19:51:57+02:00","duration":181},{"begin":"2024-06-03T13:44:39+02:00","end":"2024-06-03T14:08:55+02:00","duration":1456},{"begin":"2024-06-03T14:10:13+02:00","end":"2024-06-03T14:13:59+02:00","duration":226},{"begin":"2024-06-03T14:13:59+02:00","end":"2024-06-03T14:22:15+02:00","duration":496},{"begin":"2024-06-03T16:08:24+02:00","end":"2024-06-03T16:50:27+02:00","duration":2523},{"begin":"2024-06-03T16:53:34+02:00","end":"2024-06-03T17:36:28+02:00","duration":2574},{"begin":"2024-06-03T17:37:13+02:00","end":"2024-06-03T18:00:40+02:00","duration":1407},{"begin":"2024-06-03T18:02:38+02:00","end":"2024-06-03T18:16:40+02:00","duration":842},{"begin":"2024-06-03T18:17:10+02:00","end":"2024-06-03T18:27:11+02:00","duration":601},{"begin":"2024-06-03T18:27:12+02:00","end":"2024-06-03T18:37:03+02:00","duration":591},{"begin":"2024-06-03T18:37:08+02:00","end":"2024-06-03T18:52:39+02:00","duration":931},{"begin":"2024-06-03T18:54:04+02:00","end":"2024-06-03T19:11:17+02:00","duration":1033},{"begin":"2024-06-04T17:24:35+02:00","end":"2024-06-04T17:47:58+02:00","duration":1403},{"begin":"2024-06-04T17:49:33+02:00","end":"2024-06-04T17:54:38+02:00","duration":305},{"begin":"2024-06-04T17:55:53+02:00","end":"2024-06-04T18:02:40+02:00","duration":407},{"begin":"2024-06-04T18:03:47+02:00","end":"2024-06-04T18:16:55+02:00","duration":788},{"begin":"2024-06-04T18:30:53+02:00","end":"2024-06-04T18:44:22+02:00","duration":809},{"begin":"2024-06-04T18:47:15+02:00","end":"2024-06-04T18:50:25+02:00","duration":190},{"begin":"2024-06-04T18:50:44+02:00","end":"2024-06-04T19:03:26+02:00","duration":762},{"begin":"2024-06-04T19:04:41+02:00","end":"2024-06-04T19:17:31+02:00","duration":770},{"begin":"2024-06-04T19:22:30+02:00","end":"2024-06-04T19:37:08+02:00","duration":878},{"begin":"2024-06-04T19:38:32+02:00","end":"2024-06-04T20:03:04+02:00","duration":1472},{"begin":"2024-06-04T22:56:34+02:00","end":"2024-06-04T22:59:35+02:00","duration":181},{"begin":"2024-06-05T00:23:31+02:00","end":"2024-06-05T00:27:38+02:00","duration":247},{"begin":"2024-06-05T00:30:27+02:00","end":"2024-06-05T00:33:43+02:00","duration":196},{"begin":"2024-06-05T00:34:37+02:00","end":"2024-06-05T00:39:05+02:00","duration":268},{"begin":"2024-06-05T00:41:24+02:00","end":"2024-06-05T00:46:51+02:00","duration":327},{"begin":"2024-06-05T00:49:14+02:00","end":"2024-06-05T00:52:15+02:00","duration":181},{"begin":"2024-06-05T00:52:49+02:00","end":"2024-06-05T00:55:50+02:00","duration":181},{"begin":"2024-06-05T00:56:32+02:00","end":"2024-06-05T01:07:08+02:00","duration":636},{"begin":"2024-06-05T01:08:59+02:00","end":"2024-06-05T01:12:04+02:00","duration":185},{"begin":"2024-06-05T01:16:35+02:00","end":"2024-06-05T01:21:24+02:00","duration":289},{"begin":"2024-06-05T01:22:12+02:00","end":"2024-06-05T01:30:50+02:00","duration":518},{"begin":"2024-06-05T01:33:46+02:00","end":"2024-06-05T01:56:59+02:00","duration":1393},{"begin":"2024-06-14T10:45:43+02:00","end":"2024-06-14T10:51:11+02:00","duration":328},{"begin":"2024-06-14T10:51:48+02:00","end":"2024-06-14T10:59:52+02:00","duration":484},{"begin":"2024-06-14T11:00:19+02:00","end":"2024-06-14T11:15:42+02:00","duration":923},{"begin":"2024-06-14T11:24:01+02:00","end":"2024-06-14T11:27:44+02:00","duration":223},{"begin":"2024-06-14T11:29:27+02:00","end":"2024-06-14T11:42:56+02:00","duration":809},{"begin":"2024-06-14T11:54:20+02:00","end":"2024-06-14T12:11:05+02:00","duration":1005},{"begin":"2024-06-14T12:43:23+02:00","end":"2024-06-14T12:50:50+02:00","duration":447},{"begin":"2024-06-14T12:53:31+02:00","end":"2024-06-14T13:02:02+02:00","duration":511},{"begin":"2024-06-14T13:24:00+02:00","end":"2024-06-14T14:02:02+02:00","duration":2282},{"begin":"2024-06-14T14:02:10+02:00","end":"2024-06-14T14:21:48+02:00","duration":1178},{"begin":"2024-06-14T14:29:37+02:00","end":"2024-06-14T14:33:00+02:00","duration":203},{"begin":"2024-06-14T14:53:30+02:00","end":"2024-06-14T14:56:31+02:00","duration":181},{"begin":"2024-06-14T14:58:33+02:00","end":"2024-06-14T15:02:24+02:00","duration":231},{"begin":"2024-06-14T15:02:41+02:00","end":"2024-06-14T15:47:20+02:00","duration":2679},{"begin":"2024-06-14T15:51:31+02:00","end":"2024-06-14T16:39:03+02:00","duration":2852},{"begin":"2024-06-14T16:43:46+02:00","end":"2024-06-14T17:03:31+02:00","duration":1185},{"begin":"2024-06-14T17:07:20+02:00","end":"2024-06-14T17:24:07+02:00","duration":1007},{"begin":"2024-06-14T17:25:34+02:00","end":"2024-06-14T17:29:33+02:00","duration":239},{"begin":"2024-06-14T17:36:56+02:00","end":"2024-06-14T17:41:24+02:00","duration":268},{"begin":"2024-06-14T17:45:19+02:00","end":"2024-06-14T17:50:29+02:00","duration":310},{"begin":"2024-06-14T17:50:58+02:00","end":"2024-06-14T17:56:32+02:00","duration":334},{"begin":"2024-06-14T17:56:49+02:00","end":"2024-06-14T18:32:50+02:00","duration":2161},{"begin":"2024-06-14T18:34:01+02:00","end":"2024-06-14T18:41:12+02:00","duration":431},{"begin":"2024-06-14T18:42:05+02:00","end":"2024-06-14T18:50:00+02:00","duration":475},{"begin":"2024-06-14T18:51:52+02:00","end":"2024-06-14T18:58:40+02:00","duration":408},{"begin":"2024-06-14T18:58:43+02:00","end":"2024-06-14T19:10:21+02:00","duration":698},{"begin":"2024-06-14T19:14:01+02:00","end":"2024-06-14T20:01:47+02:00","duration":2866},{"begin":"2024-06-14T20:04:08+02:00","end":"2024-06-14T20:07:36+02:00","duration":208},{"begin":"2024-06-17T09:22:04+02:00","end":"2024-06-17T09:25:06+02:00","duration":182},{"begin":"2024-06-17T18:07:14+02:00","end":"2024-06-17T18:14:52+02:00","duration":458},{"begin":"2024-06-17T18:16:23+02:00","end":"2024-06-17T18:30:36+02:00","duration":853},{"begin":"2024-06-17T21:57:54+02:00","end":"2024-06-17T22:11:46+02:00","duration":832},{"begin":"2024-06-17T22:15:23+02:00","end":"2024-06-17T22:29:45+02:00","duration":862},{"begin":"2024-06-17T22:32:12+02:00","end":"2024-06-17T22:37:05+02:00","duration":293},{"begin":"2024-06-17T22:46:42+02:00","end":"2024-06-17T22:49:53+02:00","duration":191},{"begin":"2024-06-17T22:54:14+02:00","end":"2024-06-17T22:58:03+02:00","duration":229},{"begin":"2024-06-17T22:58:06+02:00","end":"2024-06-17T23:29:27+02:00","duration":1881},{"begin":"2024-06-18T09:28:46+02:00","end":"2024-06-18T09:50:34+02:00","duration":1308},{"begin":"2024-06-18T18:52:10+02:00","end":"2024-06-18T18:52:23+02:00","duration":13},{"begin":"2024-06-19T10:25:22+02:00","end":"2024-06-19T10:25:32+02:00","duration":10},{"begin":"2024-06-20T17:27:08+02:00","end":"2024-06-20T17:30:09+02:00","duration":181},{"begin":"2024-06-20T17:35:26+02:00","end":"2024-06-20T17:42:52+02:00","duration":446},{"begin":"2024-06-20T17:43:27+02:00","end":"2024-06-20T18:08:55+02:00","duration":1528},{"begin":"2024-06-20T18:09:48+02:00","end":"2024-06-20T18:36:52+02:00","duration":1624},{"begin":"2024-06-20T18:37:26+02:00","end":"2024-06-20T19:11:12+02:00","duration":2026},{"begin":"2024-06-20T19:13:33+02:00","end":"2024-06-20T19:21:45+02:00","duration":492},{"begin":"2024-06-20T19:25:33+02:00","end":"2024-06-20T19:49:35+02:00","duration":1442},{"begin":"2024-06-20T19:53:28+02:00","end":"2024-06-20T20:07:17+02:00","duration":829},{"begin":"2024-06-20T22:11:00+02:00","end":"2024-06-20T22:20:13+02:00","duration":553},{"begin":"2024-06-20T22:27:38+02:00","end":"2024-06-20T22:34:06+02:00","duration":388},{"begin":"2024-06-20T23:12:19+02:00","end":"2024-06-20T23:21:50+02:00","duration":571},{"begin":"2024-06-20T23:23:45+02:00","end":"2024-06-20T23:31:12+02:00","duration":447},{"begin":"2024-06-20T23:32:09+02:00","end":"2024-06-20T23:45:11+02:00","duration":782},{"begin":"2024-06-20T23:57:44+02:00","end":"2024-06-21T00:18:00+02:00","duration":1216},{"begin":"2024-06-26T14:06:52+02:00","end":"2024-06-26T14:07:31+02:00","duration":39},{"begin":"2024-06-27T21:25:49+02:00","end":"2024-06-27T21:37:26+02:00","duration":697},{"begin":"2024-06-27T21:39:26+02:00","end":"2024-06-27T21:52:45+02:00","duration":799},{"begin":"2024-06-27T21:53:03+02:00","end":"2024-06-27T22:01:30+02:00","duration":507},{"begin":"2024-06-27T22:08:47+02:00","end":"2024-06-27T22:47:20+02:00","duration":2313},{"begin":"2024-06-27T22:50:46+02:00","end":"2024-06-27T22:53:52+02:00","duration":186},{"begin":"2024-06-27T22:56:10+02:00","end":"2024-06-27T22:59:59+02:00","duration":229},{"begin":"2024-06-27T23:04:35+02:00","end":"2024-06-27T23:22:30+02:00","duration":1075},{"begin":"2024-06-27T23:26:23+02:00","end":"2024-06-27T23:46:30+02:00","duration":1207},{"begin":"2024-06-27T23:49:43+02:00","end":"2024-06-27T23:52:44+02:00","duration":181},{"begin":"2024-06-27T23:53:00+02:00","end":"2024-06-28T00:18:09+02:00","duration":1509},{"begin":"2024-06-28T00:20:04+02:00","end":"2024-06-28T00:30:38+02:00","duration":634},{"begin":"2024-06-28T00:30:48+02:00","end":"2024-06-28T00:40:55+02:00","duration":607},{"begin":"2024-06-28T13:52:56+02:00","end":"2024-06-28T13:55:57+02:00","duration":181},{"begin":"2024-06-28T13:56:39+02:00","end":"2024-06-28T14:05:32+02:00","duration":533},{"begin":"2024-06-28T14:06:40+02:00","end":"2024-06-28T14:34:26+02:00","duration":1666},{"begin":"2024-06-28T14:34:54+02:00","end":"2024-06-28T14:37:55+02:00","duration":181},{"begin":"2024-06-30T20:17:49+02:00","end":"2024-06-30T20:20:50+02:00","duration":181},{"begin":"2024-06-30T21:30:41+02:00","end":"2024-06-30T21:34:31+02:00","duration":230},{"begin":"2024-07-01T10:08:19+02:00","end":"2024-07-01T10:10:23+02:00","duration":124},{"begin":"2024-07-01T20:01:35+02:00","end":"2024-07-01T20:04:36+02:00","duration":181},{"begin":"2024-07-01T20:24:04+02:00","end":"2024-07-01T20:39:23+02:00","duration":919},{"begin":"2024-07-01T21:45:27+02:00","end":"2024-07-01T22:19:49+02:00","duration":2062},{"begin":"2024-07-01T22:20:25+02:00","end":"2024-07-01T22:24:54+02:00","duration":269},{"begin":"2024-07-01T22:25:54+02:00","end":"2024-07-01T22:57:41+02:00","duration":1907},{"begin":"2024-07-01T23:06:14+02:00","end":"2024-07-01T23:25:36+02:00","duration":1162},{"begin":"2024-07-02T13:13:20+02:00","end":"2024-07-02T13:16:21+02:00","duration":181},{"begin":"2024-07-03T15:10:51+02:00","end":"2024-07-03T15:13:52+02:00","duration":181},{"begin":"2024-07-03T15:13:58+02:00","end":"2024-07-03T15:20:15+02:00","duration":377},{"begin":"2024-07-03T15:21:59+02:00","end":"2024-07-03T15:26:17+02:00","duration":258},{"begin":"2024-07-04T14:05:18+02:00","end":"2024-07-04T14:23:18+02:00","duration":1080},{"begin":"2024-07-04T16:17:06+02:00","end":"2024-07-04T16:20:07+02:00","duration":181},{"begin":"2024-07-04T16:25:42+02:00","end":"2024-07-04T16:33:57+02:00","duration":495},{"begin":"2024-07-04T16:35:10+02:00","end":"2024-07-04T16:57:01+02:00","duration":1311},{"begin":"2024-07-04T16:57:30+02:00","end":"2024-07-04T17:01:32+02:00","duration":242},{"begin":"2024-07-04T17:01:46+02:00","end":"2024-07-04T17:46:10+02:00","duration":2664},{"begin":"2024-07-04T17:48:14+02:00","end":"2024-07-04T17:56:19+02:00","duration":485},{"begin":"2024-07-04T18:19:20+02:00","end":"2024-07-04T18:25:07+02:00","duration":347},{"begin":"2024-07-04T18:26:24+02:00","end":"2024-07-04T18:59:34+02:00","duration":1990},{"begin":"2024-07-04T20:35:30+02:00","end":"2024-07-04T20:59:14+02:00","duration":1424},{"begin":"2024-07-04T21:08:42+02:00","end":"2024-07-04T21:12:13+02:00","duration":211},{"begin":"2024-07-04T21:17:03+02:00","end":"2024-07-04T21:20:36+02:00","duration":213},{"begin":"2024-07-04T21:23:59+02:00","end":"2024-07-04T21:28:20+02:00","duration":261},{"begin":"2024-07-04T21:28:40+02:00","end":"2024-07-04T21:31:42+02:00","duration":182},{"begin":"2024-07-04T21:38:46+02:00","end":"2024-07-04T22:03:51+02:00","duration":1505},{"begin":"2024-07-04T22:20:24+02:00","end":"2024-07-04T22:27:47+02:00","duration":443},{"begin":"2024-07-05T12:35:04+02:00","end":"2024-07-05T12:38:05+02:00","duration":181},{"begin":"2024-07-05T14:13:17+02:00","end":"2024-07-05T14:18:04+02:00","duration":287},{"begin":"2024-07-05T14:22:12+02:00","end":"2024-07-05T14:30:36+02:00","duration":504},{"begin":"2024-07-05T14:41:57+02:00","end":"2024-07-05T14:45:27+02:00","duration":210},{"begin":"2024-07-05T14:54:01+02:00","end":"2024-07-05T14:57:02+02:00","duration":181},{"begin":"2024-07-05T14:59:32+02:00","end":"2024-07-05T15:08:34+02:00","duration":542},{"begin":"2024-07-05T15:11:05+02:00","end":"2024-07-05T15:17:59+02:00","duration":414},{"begin":"2024-07-05T15:18:34+02:00","end":"2024-07-05T15:24:14+02:00","duration":340},{"begin":"2024-07-05T15:27:26+02:00","end":"2024-07-05T15:46:17+02:00","duration":1131},{"begin":"2024-07-05T15:48:10+02:00","end":"2024-07-05T16:18:28+02:00","duration":1818},{"begin":"2024-07-05T16:28:39+02:00","end":"2024-07-05T16:55:18+02:00","duration":1599},{"begin":"2024-07-06T23:50:32+02:00","end":"2024-07-06T23:56:27+02:00","duration":355},{"begin":"2024-07-06T23:58:53+02:00","end":"2024-07-07T00:00:07+02:00","duration":74},{"begin":"2024-07-07T00:03:50+02:00","end":"2024-07-07T00:08:16+02:00","duration":266},{"begin":"2024-07-07T00:29:03+02:00","end":"2024-07-07T00:32:16+02:00","duration":193},{"begin":"2024-07-07T00:37:09+02:00","end":"2024-07-07T00:42:30+02:00","duration":321},{"begin":"2024-07-07T00:57:45+02:00","end":"2024-07-07T01:00:46+02:00","duration":181},{"begin":"2024-07-07T01:22:26+02:00","end":"2024-07-07T01:25:41+02:00","duration":195},{"begin":"2024-07-07T13:29:41+02:00","end":"2024-07-07T13:32:40+02:00","duration":179},{"begin":"2024-07-07T14:19:21+02:00","end":"2024-07-07T14:36:31+02:00","duration":1030},{"begin":"2024-07-07T16:00:50+02:00","end":"2024-07-07T16:06:00+02:00","duration":310},{"begin":"2024-07-07T16:12:42+02:00","end":"2024-07-07T16:15:43+02:00","duration":181},{"begin":"2024-07-07T16:53:42+02:00","end":"2024-07-07T17:13:01+02:00","duration":1159},{"begin":"2024-07-07T17:13:33+02:00","end":"2024-07-07T17:21:36+02:00","duration":483},{"begin":"2024-07-07T17:23:07+02:00","end":"2024-07-07T17:30:22+02:00","duration":435},{"begin":"2024-07-07T17:33:10+02:00","end":"2024-07-07T17:36:11+02:00","duration":181},{"begin":"2024-07-07T17:36:19+02:00","end":"2024-07-07T17:39:31+02:00","duration":192},{"begin":"2024-07-07T17:40:59+02:00","end":"2024-07-07T17:59:43+02:00","duration":1124},{"begin":"2024-08-26T15:13:15+02:00","end":"2024-08-26T15:13:52+02:00","duration":37},{"begin":"2024-08-26T15:13:53+02:00","end":"2024-08-26T15:13:55+02:00","duration":2},{"begin":"2024-08-26T15:13:55+02:00","end":"2024-08-26T15:15:14+02:00","duration":79},{"begin":"2024-08-26T15:15:14+02:00","end":"2024-08-26T15:20:06+02:00","duration":291},{"begin":"2024-08-26T15:20:50+02:00","end":"2024-08-26T15:25:08+02:00","duration":258},{"begin":"2024-08-26T15:25:10+02:00","end":"2024-08-26T15:32:43+02:00","duration":452},{"begin":"2024-08-26T15:33:16+02:00","end":"2024-08-26T15:39:00+02:00","duration":344},{"begin":"2024-08-26T16:07:35+02:00","end":"2024-08-26T16:10:36+02:00","duration":181},{"begin":"2024-08-26T16:14:08+02:00","end":"2024-08-26T16:15:04+02:00","duration":56},{"begin":"2024-08-28T18:17:44+02:00","end":"2024-08-28T18:23:20+02:00","duration":336},{"begin":"2024-08-28T18:26:49+02:00","end":"2024-08-28T18:35:26+02:00","duration":517},{"begin":"2024-08-28T18:35:34+02:00","end":"2024-08-28T19:04:26+02:00","duration":1732},{"begin":"2024-08-28T19:11:59+02:00","end":"2024-08-28T19:15:38+02:00","duration":219},{"begin":"2024-08-28T19:16:22+02:00","end":"2024-08-28T19:19:39+02:00","duration":197},{"begin":"2024-08-28T19:40:08+02:00","end":"2024-08-28T19:58:09+02:00","duration":1081},{"begin":"2024-08-28T20:46:30+02:00","end":"2024-08-28T21:12:42+02:00","duration":1571}]} \ No newline at end of file +{"total":197714,"sessions":[{"begin":"2024-05-24T11:32:18+02:00","end":"2024-05-24T11:32:26+02:00","duration":8},{"begin":"2024-05-24T11:32:27+02:00","end":"2024-05-24T11:34:28+02:00","duration":121},{"begin":"2024-05-24T11:34:46+02:00","end":"2024-05-24T11:34:48+02:00","duration":2},{"begin":"2024-05-24T11:34:57+02:00","end":"2024-05-24T11:38:44+02:00","duration":227},{"begin":"2024-05-24T11:40:40+02:00","end":"2024-05-24T12:16:37+02:00","duration":2157},{"begin":"2024-05-24T12:16:52+02:00","end":"2024-05-24T12:39:34+02:00","duration":1362},{"begin":"2024-05-24T13:00:12+02:00","end":"2024-05-24T13:03:23+02:00","duration":191},{"begin":"2024-05-24T13:07:04+02:00","end":"2024-05-24T14:12:49+02:00","duration":3945},{"begin":"2024-05-24T14:14:17+02:00","end":"2024-05-24T14:23:17+02:00","duration":540},{"begin":"2024-05-24T14:23:48+02:00","end":"2024-05-24T14:48:36+02:00","duration":1488},{"begin":"2024-05-24T14:49:01+02:00","end":"2024-05-24T15:24:18+02:00","duration":2117},{"begin":"2024-05-24T15:25:37+02:00","end":"2024-05-24T15:28:41+02:00","duration":184},{"begin":"2024-05-26T15:17:54+02:00","end":"2024-05-26T15:22:58+02:00","duration":304},{"begin":"2024-05-26T15:28:15+02:00","end":"2024-05-26T15:43:24+02:00","duration":909},{"begin":"2024-05-26T15:44:37+02:00","end":"2024-05-26T15:51:01+02:00","duration":384},{"begin":"2024-05-26T15:54:12+02:00","end":"2024-05-26T16:07:56+02:00","duration":824},{"begin":"2024-05-26T16:07:56+02:00","end":"2024-05-26T16:15:50+02:00","duration":474},{"begin":"2024-05-26T16:16:17+02:00","end":"2024-05-26T16:38:57+02:00","duration":1360},{"begin":"2024-05-26T20:55:51+02:00","end":"2024-05-26T21:10:25+02:00","duration":874},{"begin":"2024-05-26T21:13:13+02:00","end":"2024-05-26T21:32:00+02:00","duration":1127},{"begin":"2024-05-26T21:42:16+02:00","end":"2024-05-26T21:51:09+02:00","duration":533},{"begin":"2024-05-26T22:32:32+02:00","end":"2024-05-26T22:41:03+02:00","duration":511},{"begin":"2024-05-26T22:47:19+02:00","end":"2024-05-26T23:05:45+02:00","duration":1106},{"begin":"2024-05-27T16:07:05+02:00","end":"2024-05-27T16:10:06+02:00","duration":181},{"begin":"2024-05-27T16:11:01+02:00","end":"2024-05-27T16:52:36+02:00","duration":2495},{"begin":"2024-05-27T16:53:16+02:00","end":"2024-05-27T17:19:26+02:00","duration":1570},{"begin":"2024-05-27T21:12:07+02:00","end":"2024-05-27T21:15:38+02:00","duration":211},{"begin":"2024-05-28T09:09:41+02:00","end":"2024-05-28T09:14:21+02:00","duration":280},{"begin":"2024-05-28T09:43:08+02:00","end":"2024-05-28T09:50:56+02:00","duration":468},{"begin":"2024-05-28T10:01:12+02:00","end":"2024-05-28T10:09:54+02:00","duration":522},{"begin":"2024-05-28T10:11:10+02:00","end":"2024-05-28T10:16:59+02:00","duration":349},{"begin":"2024-05-28T10:22:36+02:00","end":"2024-05-28T10:29:58+02:00","duration":442},{"begin":"2024-05-28T10:32:11+02:00","end":"2024-05-28T10:42:29+02:00","duration":618},{"begin":"2024-05-28T10:42:42+02:00","end":"2024-05-28T10:45:52+02:00","duration":190},{"begin":"2024-05-28T10:46:10+02:00","end":"2024-05-28T10:49:11+02:00","duration":181},{"begin":"2024-05-28T10:50:30+02:00","end":"2024-05-28T10:56:46+02:00","duration":376},{"begin":"2024-05-28T10:57:52+02:00","end":"2024-05-28T11:02:02+02:00","duration":250},{"begin":"2024-05-28T11:07:49+02:00","end":"2024-05-28T11:10:52+02:00","duration":183},{"begin":"2024-05-28T12:29:08+02:00","end":"2024-05-28T12:38:44+02:00","duration":576},{"begin":"2024-05-28T16:39:49+02:00","end":"2024-05-28T16:42:51+02:00","duration":182},{"begin":"2024-05-28T17:25:20+02:00","end":"2024-05-28T17:28:21+02:00","duration":181},{"begin":"2024-05-28T17:58:20+02:00","end":"2024-05-28T18:14:17+02:00","duration":957},{"begin":"2024-05-28T18:14:23+02:00","end":"2024-05-28T18:36:17+02:00","duration":1314},{"begin":"2024-05-28T23:15:57+02:00","end":"2024-05-28T23:46:31+02:00","duration":1834},{"begin":"2024-05-28T23:46:35+02:00","end":"2024-05-28T23:55:16+02:00","duration":521},{"begin":"2024-05-29T14:36:59+02:00","end":"2024-05-29T14:40:47+02:00","duration":228},{"begin":"2024-05-29T14:49:58+02:00","end":"2024-05-29T14:54:36+02:00","duration":278},{"begin":"2024-05-29T14:55:10+02:00","end":"2024-05-29T14:56:29+02:00","duration":79},{"begin":"2024-05-29T14:56:33+02:00","end":"2024-05-29T14:57:13+02:00","duration":40},{"begin":"2024-05-29T14:57:17+02:00","end":"2024-05-29T15:11:31+02:00","duration":854},{"begin":"2024-05-29T16:36:49+02:00","end":"2024-05-29T16:39:50+02:00","duration":181},{"begin":"2024-05-31T12:20:27+02:00","end":"2024-05-31T12:23:25+02:00","duration":178},{"begin":"2024-05-31T14:28:22+02:00","end":"2024-05-31T14:31:59+02:00","duration":217},{"begin":"2024-05-31T14:32:22+02:00","end":"2024-05-31T15:17:52+02:00","duration":2730},{"begin":"2024-05-31T15:18:45+02:00","end":"2024-05-31T15:40:35+02:00","duration":1310},{"begin":"2024-05-31T15:40:45+02:00","end":"2024-05-31T16:18:02+02:00","duration":2237},{"begin":"2024-05-31T16:18:33+02:00","end":"2024-05-31T16:47:51+02:00","duration":1758},{"begin":"2024-05-31T19:06:34+02:00","end":"2024-05-31T19:21:05+02:00","duration":871},{"begin":"2024-05-31T19:23:13+02:00","end":"2024-05-31T19:30:54+02:00","duration":461},{"begin":"2024-05-31T19:33:31+02:00","end":"2024-05-31T19:41:39+02:00","duration":488},{"begin":"2024-05-31T19:48:56+02:00","end":"2024-05-31T19:51:57+02:00","duration":181},{"begin":"2024-06-03T13:44:39+02:00","end":"2024-06-03T14:08:55+02:00","duration":1456},{"begin":"2024-06-03T14:10:13+02:00","end":"2024-06-03T14:13:59+02:00","duration":226},{"begin":"2024-06-03T14:13:59+02:00","end":"2024-06-03T14:22:15+02:00","duration":496},{"begin":"2024-06-03T16:08:24+02:00","end":"2024-06-03T16:50:27+02:00","duration":2523},{"begin":"2024-06-03T16:53:34+02:00","end":"2024-06-03T17:36:28+02:00","duration":2574},{"begin":"2024-06-03T17:37:13+02:00","end":"2024-06-03T18:00:40+02:00","duration":1407},{"begin":"2024-06-03T18:02:38+02:00","end":"2024-06-03T18:16:40+02:00","duration":842},{"begin":"2024-06-03T18:17:10+02:00","end":"2024-06-03T18:27:11+02:00","duration":601},{"begin":"2024-06-03T18:27:12+02:00","end":"2024-06-03T18:37:03+02:00","duration":591},{"begin":"2024-06-03T18:37:08+02:00","end":"2024-06-03T18:52:39+02:00","duration":931},{"begin":"2024-06-03T18:54:04+02:00","end":"2024-06-03T19:11:17+02:00","duration":1033},{"begin":"2024-06-04T17:24:35+02:00","end":"2024-06-04T17:47:58+02:00","duration":1403},{"begin":"2024-06-04T17:49:33+02:00","end":"2024-06-04T17:54:38+02:00","duration":305},{"begin":"2024-06-04T17:55:53+02:00","end":"2024-06-04T18:02:40+02:00","duration":407},{"begin":"2024-06-04T18:03:47+02:00","end":"2024-06-04T18:16:55+02:00","duration":788},{"begin":"2024-06-04T18:30:53+02:00","end":"2024-06-04T18:44:22+02:00","duration":809},{"begin":"2024-06-04T18:47:15+02:00","end":"2024-06-04T18:50:25+02:00","duration":190},{"begin":"2024-06-04T18:50:44+02:00","end":"2024-06-04T19:03:26+02:00","duration":762},{"begin":"2024-06-04T19:04:41+02:00","end":"2024-06-04T19:17:31+02:00","duration":770},{"begin":"2024-06-04T19:22:30+02:00","end":"2024-06-04T19:37:08+02:00","duration":878},{"begin":"2024-06-04T19:38:32+02:00","end":"2024-06-04T20:03:04+02:00","duration":1472},{"begin":"2024-06-04T22:56:34+02:00","end":"2024-06-04T22:59:35+02:00","duration":181},{"begin":"2024-06-05T00:23:31+02:00","end":"2024-06-05T00:27:38+02:00","duration":247},{"begin":"2024-06-05T00:30:27+02:00","end":"2024-06-05T00:33:43+02:00","duration":196},{"begin":"2024-06-05T00:34:37+02:00","end":"2024-06-05T00:39:05+02:00","duration":268},{"begin":"2024-06-05T00:41:24+02:00","end":"2024-06-05T00:46:51+02:00","duration":327},{"begin":"2024-06-05T00:49:14+02:00","end":"2024-06-05T00:52:15+02:00","duration":181},{"begin":"2024-06-05T00:52:49+02:00","end":"2024-06-05T00:55:50+02:00","duration":181},{"begin":"2024-06-05T00:56:32+02:00","end":"2024-06-05T01:07:08+02:00","duration":636},{"begin":"2024-06-05T01:08:59+02:00","end":"2024-06-05T01:12:04+02:00","duration":185},{"begin":"2024-06-05T01:16:35+02:00","end":"2024-06-05T01:21:24+02:00","duration":289},{"begin":"2024-06-05T01:22:12+02:00","end":"2024-06-05T01:30:50+02:00","duration":518},{"begin":"2024-06-05T01:33:46+02:00","end":"2024-06-05T01:56:59+02:00","duration":1393},{"begin":"2024-06-14T10:45:43+02:00","end":"2024-06-14T10:51:11+02:00","duration":328},{"begin":"2024-06-14T10:51:48+02:00","end":"2024-06-14T10:59:52+02:00","duration":484},{"begin":"2024-06-14T11:00:19+02:00","end":"2024-06-14T11:15:42+02:00","duration":923},{"begin":"2024-06-14T11:24:01+02:00","end":"2024-06-14T11:27:44+02:00","duration":223},{"begin":"2024-06-14T11:29:27+02:00","end":"2024-06-14T11:42:56+02:00","duration":809},{"begin":"2024-06-14T11:54:20+02:00","end":"2024-06-14T12:11:05+02:00","duration":1005},{"begin":"2024-06-14T12:43:23+02:00","end":"2024-06-14T12:50:50+02:00","duration":447},{"begin":"2024-06-14T12:53:31+02:00","end":"2024-06-14T13:02:02+02:00","duration":511},{"begin":"2024-06-14T13:24:00+02:00","end":"2024-06-14T14:02:02+02:00","duration":2282},{"begin":"2024-06-14T14:02:10+02:00","end":"2024-06-14T14:21:48+02:00","duration":1178},{"begin":"2024-06-14T14:29:37+02:00","end":"2024-06-14T14:33:00+02:00","duration":203},{"begin":"2024-06-14T14:53:30+02:00","end":"2024-06-14T14:56:31+02:00","duration":181},{"begin":"2024-06-14T14:58:33+02:00","end":"2024-06-14T15:02:24+02:00","duration":231},{"begin":"2024-06-14T15:02:41+02:00","end":"2024-06-14T15:47:20+02:00","duration":2679},{"begin":"2024-06-14T15:51:31+02:00","end":"2024-06-14T16:39:03+02:00","duration":2852},{"begin":"2024-06-14T16:43:46+02:00","end":"2024-06-14T17:03:31+02:00","duration":1185},{"begin":"2024-06-14T17:07:20+02:00","end":"2024-06-14T17:24:07+02:00","duration":1007},{"begin":"2024-06-14T17:25:34+02:00","end":"2024-06-14T17:29:33+02:00","duration":239},{"begin":"2024-06-14T17:36:56+02:00","end":"2024-06-14T17:41:24+02:00","duration":268},{"begin":"2024-06-14T17:45:19+02:00","end":"2024-06-14T17:50:29+02:00","duration":310},{"begin":"2024-06-14T17:50:58+02:00","end":"2024-06-14T17:56:32+02:00","duration":334},{"begin":"2024-06-14T17:56:49+02:00","end":"2024-06-14T18:32:50+02:00","duration":2161},{"begin":"2024-06-14T18:34:01+02:00","end":"2024-06-14T18:41:12+02:00","duration":431},{"begin":"2024-06-14T18:42:05+02:00","end":"2024-06-14T18:50:00+02:00","duration":475},{"begin":"2024-06-14T18:51:52+02:00","end":"2024-06-14T18:58:40+02:00","duration":408},{"begin":"2024-06-14T18:58:43+02:00","end":"2024-06-14T19:10:21+02:00","duration":698},{"begin":"2024-06-14T19:14:01+02:00","end":"2024-06-14T20:01:47+02:00","duration":2866},{"begin":"2024-06-14T20:04:08+02:00","end":"2024-06-14T20:07:36+02:00","duration":208},{"begin":"2024-06-17T09:22:04+02:00","end":"2024-06-17T09:25:06+02:00","duration":182},{"begin":"2024-06-17T18:07:14+02:00","end":"2024-06-17T18:14:52+02:00","duration":458},{"begin":"2024-06-17T18:16:23+02:00","end":"2024-06-17T18:30:36+02:00","duration":853},{"begin":"2024-06-17T21:57:54+02:00","end":"2024-06-17T22:11:46+02:00","duration":832},{"begin":"2024-06-17T22:15:23+02:00","end":"2024-06-17T22:29:45+02:00","duration":862},{"begin":"2024-06-17T22:32:12+02:00","end":"2024-06-17T22:37:05+02:00","duration":293},{"begin":"2024-06-17T22:46:42+02:00","end":"2024-06-17T22:49:53+02:00","duration":191},{"begin":"2024-06-17T22:54:14+02:00","end":"2024-06-17T22:58:03+02:00","duration":229},{"begin":"2024-06-17T22:58:06+02:00","end":"2024-06-17T23:29:27+02:00","duration":1881},{"begin":"2024-06-18T09:28:46+02:00","end":"2024-06-18T09:50:34+02:00","duration":1308},{"begin":"2024-06-18T18:52:10+02:00","end":"2024-06-18T18:52:23+02:00","duration":13},{"begin":"2024-06-19T10:25:22+02:00","end":"2024-06-19T10:25:32+02:00","duration":10},{"begin":"2024-06-20T17:27:08+02:00","end":"2024-06-20T17:30:09+02:00","duration":181},{"begin":"2024-06-20T17:35:26+02:00","end":"2024-06-20T17:42:52+02:00","duration":446},{"begin":"2024-06-20T17:43:27+02:00","end":"2024-06-20T18:08:55+02:00","duration":1528},{"begin":"2024-06-20T18:09:48+02:00","end":"2024-06-20T18:36:52+02:00","duration":1624},{"begin":"2024-06-20T18:37:26+02:00","end":"2024-06-20T19:11:12+02:00","duration":2026},{"begin":"2024-06-20T19:13:33+02:00","end":"2024-06-20T19:21:45+02:00","duration":492},{"begin":"2024-06-20T19:25:33+02:00","end":"2024-06-20T19:49:35+02:00","duration":1442},{"begin":"2024-06-20T19:53:28+02:00","end":"2024-06-20T20:07:17+02:00","duration":829},{"begin":"2024-06-20T22:11:00+02:00","end":"2024-06-20T22:20:13+02:00","duration":553},{"begin":"2024-06-20T22:27:38+02:00","end":"2024-06-20T22:34:06+02:00","duration":388},{"begin":"2024-06-20T23:12:19+02:00","end":"2024-06-20T23:21:50+02:00","duration":571},{"begin":"2024-06-20T23:23:45+02:00","end":"2024-06-20T23:31:12+02:00","duration":447},{"begin":"2024-06-20T23:32:09+02:00","end":"2024-06-20T23:45:11+02:00","duration":782},{"begin":"2024-06-20T23:57:44+02:00","end":"2024-06-21T00:18:00+02:00","duration":1216},{"begin":"2024-06-26T14:06:52+02:00","end":"2024-06-26T14:07:31+02:00","duration":39},{"begin":"2024-06-27T21:25:49+02:00","end":"2024-06-27T21:37:26+02:00","duration":697},{"begin":"2024-06-27T21:39:26+02:00","end":"2024-06-27T21:52:45+02:00","duration":799},{"begin":"2024-06-27T21:53:03+02:00","end":"2024-06-27T22:01:30+02:00","duration":507},{"begin":"2024-06-27T22:08:47+02:00","end":"2024-06-27T22:47:20+02:00","duration":2313},{"begin":"2024-06-27T22:50:46+02:00","end":"2024-06-27T22:53:52+02:00","duration":186},{"begin":"2024-06-27T22:56:10+02:00","end":"2024-06-27T22:59:59+02:00","duration":229},{"begin":"2024-06-27T23:04:35+02:00","end":"2024-06-27T23:22:30+02:00","duration":1075},{"begin":"2024-06-27T23:26:23+02:00","end":"2024-06-27T23:46:30+02:00","duration":1207},{"begin":"2024-06-27T23:49:43+02:00","end":"2024-06-27T23:52:44+02:00","duration":181},{"begin":"2024-06-27T23:53:00+02:00","end":"2024-06-28T00:18:09+02:00","duration":1509},{"begin":"2024-06-28T00:20:04+02:00","end":"2024-06-28T00:30:38+02:00","duration":634},{"begin":"2024-06-28T00:30:48+02:00","end":"2024-06-28T00:40:55+02:00","duration":607},{"begin":"2024-06-28T13:52:56+02:00","end":"2024-06-28T13:55:57+02:00","duration":181},{"begin":"2024-06-28T13:56:39+02:00","end":"2024-06-28T14:05:32+02:00","duration":533},{"begin":"2024-06-28T14:06:40+02:00","end":"2024-06-28T14:34:26+02:00","duration":1666},{"begin":"2024-06-28T14:34:54+02:00","end":"2024-06-28T14:37:55+02:00","duration":181},{"begin":"2024-06-30T20:17:49+02:00","end":"2024-06-30T20:20:50+02:00","duration":181},{"begin":"2024-06-30T21:30:41+02:00","end":"2024-06-30T21:34:31+02:00","duration":230},{"begin":"2024-07-01T10:08:19+02:00","end":"2024-07-01T10:10:23+02:00","duration":124},{"begin":"2024-07-01T20:01:35+02:00","end":"2024-07-01T20:04:36+02:00","duration":181},{"begin":"2024-07-01T20:24:04+02:00","end":"2024-07-01T20:39:23+02:00","duration":919},{"begin":"2024-07-01T21:45:27+02:00","end":"2024-07-01T22:19:49+02:00","duration":2062},{"begin":"2024-07-01T22:20:25+02:00","end":"2024-07-01T22:24:54+02:00","duration":269},{"begin":"2024-07-01T22:25:54+02:00","end":"2024-07-01T22:57:41+02:00","duration":1907},{"begin":"2024-07-01T23:06:14+02:00","end":"2024-07-01T23:25:36+02:00","duration":1162},{"begin":"2024-07-02T13:13:20+02:00","end":"2024-07-02T13:16:21+02:00","duration":181},{"begin":"2024-07-03T15:10:51+02:00","end":"2024-07-03T15:13:52+02:00","duration":181},{"begin":"2024-07-03T15:13:58+02:00","end":"2024-07-03T15:20:15+02:00","duration":377},{"begin":"2024-07-03T15:21:59+02:00","end":"2024-07-03T15:26:17+02:00","duration":258},{"begin":"2024-07-04T14:05:18+02:00","end":"2024-07-04T14:23:18+02:00","duration":1080},{"begin":"2024-07-04T16:17:06+02:00","end":"2024-07-04T16:20:07+02:00","duration":181},{"begin":"2024-07-04T16:25:42+02:00","end":"2024-07-04T16:33:57+02:00","duration":495},{"begin":"2024-07-04T16:35:10+02:00","end":"2024-07-04T16:57:01+02:00","duration":1311},{"begin":"2024-07-04T16:57:30+02:00","end":"2024-07-04T17:01:32+02:00","duration":242},{"begin":"2024-07-04T17:01:46+02:00","end":"2024-07-04T17:46:10+02:00","duration":2664},{"begin":"2024-07-04T17:48:14+02:00","end":"2024-07-04T17:56:19+02:00","duration":485},{"begin":"2024-07-04T18:19:20+02:00","end":"2024-07-04T18:25:07+02:00","duration":347},{"begin":"2024-07-04T18:26:24+02:00","end":"2024-07-04T18:59:34+02:00","duration":1990},{"begin":"2024-07-04T20:35:30+02:00","end":"2024-07-04T20:59:14+02:00","duration":1424},{"begin":"2024-07-04T21:08:42+02:00","end":"2024-07-04T21:12:13+02:00","duration":211},{"begin":"2024-07-04T21:17:03+02:00","end":"2024-07-04T21:20:36+02:00","duration":213},{"begin":"2024-07-04T21:23:59+02:00","end":"2024-07-04T21:28:20+02:00","duration":261},{"begin":"2024-07-04T21:28:40+02:00","end":"2024-07-04T21:31:42+02:00","duration":182},{"begin":"2024-07-04T21:38:46+02:00","end":"2024-07-04T22:03:51+02:00","duration":1505},{"begin":"2024-07-04T22:20:24+02:00","end":"2024-07-04T22:27:47+02:00","duration":443},{"begin":"2024-07-05T12:35:04+02:00","end":"2024-07-05T12:38:05+02:00","duration":181},{"begin":"2024-07-05T14:13:17+02:00","end":"2024-07-05T14:18:04+02:00","duration":287},{"begin":"2024-07-05T14:22:12+02:00","end":"2024-07-05T14:30:36+02:00","duration":504},{"begin":"2024-07-05T14:41:57+02:00","end":"2024-07-05T14:45:27+02:00","duration":210},{"begin":"2024-07-05T14:54:01+02:00","end":"2024-07-05T14:57:02+02:00","duration":181},{"begin":"2024-07-05T14:59:32+02:00","end":"2024-07-05T15:08:34+02:00","duration":542},{"begin":"2024-07-05T15:11:05+02:00","end":"2024-07-05T15:17:59+02:00","duration":414},{"begin":"2024-07-05T15:18:34+02:00","end":"2024-07-05T15:24:14+02:00","duration":340},{"begin":"2024-07-05T15:27:26+02:00","end":"2024-07-05T15:46:17+02:00","duration":1131},{"begin":"2024-07-05T15:48:10+02:00","end":"2024-07-05T16:18:28+02:00","duration":1818},{"begin":"2024-07-05T16:28:39+02:00","end":"2024-07-05T16:55:18+02:00","duration":1599},{"begin":"2024-07-06T23:50:32+02:00","end":"2024-07-06T23:56:27+02:00","duration":355},{"begin":"2024-07-06T23:58:53+02:00","end":"2024-07-07T00:00:07+02:00","duration":74},{"begin":"2024-07-07T00:03:50+02:00","end":"2024-07-07T00:08:16+02:00","duration":266},{"begin":"2024-07-07T00:29:03+02:00","end":"2024-07-07T00:32:16+02:00","duration":193},{"begin":"2024-07-07T00:37:09+02:00","end":"2024-07-07T00:42:30+02:00","duration":321},{"begin":"2024-07-07T00:57:45+02:00","end":"2024-07-07T01:00:46+02:00","duration":181},{"begin":"2024-07-07T01:22:26+02:00","end":"2024-07-07T01:25:41+02:00","duration":195},{"begin":"2024-07-07T13:29:41+02:00","end":"2024-07-07T13:32:40+02:00","duration":179},{"begin":"2024-07-07T14:19:21+02:00","end":"2024-07-07T14:36:31+02:00","duration":1030},{"begin":"2024-07-07T16:00:50+02:00","end":"2024-07-07T16:06:00+02:00","duration":310},{"begin":"2024-07-07T16:12:42+02:00","end":"2024-07-07T16:15:43+02:00","duration":181},{"begin":"2024-07-07T16:53:42+02:00","end":"2024-07-07T17:13:01+02:00","duration":1159},{"begin":"2024-07-07T17:13:33+02:00","end":"2024-07-07T17:21:36+02:00","duration":483},{"begin":"2024-07-07T17:23:07+02:00","end":"2024-07-07T17:30:22+02:00","duration":435},{"begin":"2024-07-07T17:33:10+02:00","end":"2024-07-07T17:36:11+02:00","duration":181},{"begin":"2024-07-07T17:36:19+02:00","end":"2024-07-07T17:39:31+02:00","duration":192},{"begin":"2024-07-07T17:40:59+02:00","end":"2024-07-07T17:59:43+02:00","duration":1124},{"begin":"2024-08-26T15:13:15+02:00","end":"2024-08-26T15:13:52+02:00","duration":37},{"begin":"2024-08-26T15:13:53+02:00","end":"2024-08-26T15:13:55+02:00","duration":2},{"begin":"2024-08-26T15:13:55+02:00","end":"2024-08-26T15:15:14+02:00","duration":79},{"begin":"2024-08-26T15:15:14+02:00","end":"2024-08-26T15:20:06+02:00","duration":291},{"begin":"2024-08-26T15:20:50+02:00","end":"2024-08-26T15:25:08+02:00","duration":258},{"begin":"2024-08-26T15:25:10+02:00","end":"2024-08-26T15:32:43+02:00","duration":452},{"begin":"2024-08-26T15:33:16+02:00","end":"2024-08-26T15:39:00+02:00","duration":344},{"begin":"2024-08-26T16:07:35+02:00","end":"2024-08-26T16:10:36+02:00","duration":181},{"begin":"2024-08-26T16:14:08+02:00","end":"2024-08-26T16:15:04+02:00","duration":56},{"begin":"2024-08-28T18:17:44+02:00","end":"2024-08-28T18:23:20+02:00","duration":336},{"begin":"2024-08-28T18:26:49+02:00","end":"2024-08-28T18:35:26+02:00","duration":517},{"begin":"2024-08-28T18:35:34+02:00","end":"2024-08-28T19:04:26+02:00","duration":1732},{"begin":"2024-08-28T19:11:59+02:00","end":"2024-08-28T19:15:38+02:00","duration":219},{"begin":"2024-08-28T19:16:22+02:00","end":"2024-08-28T19:19:39+02:00","duration":197},{"begin":"2024-08-28T19:40:08+02:00","end":"2024-08-28T19:58:09+02:00","duration":1081},{"begin":"2024-08-28T20:46:30+02:00","end":"2024-08-28T21:12:42+02:00","duration":1571},{"begin":"2024-08-28T21:14:58+02:00","end":"2024-08-28T21:29:47+02:00","duration":889},{"begin":"2024-09-02T09:59:46+02:00","end":"2024-09-02T10:00:04+02:00","duration":17},{"begin":"2024-09-02T10:00:06+02:00","end":"2024-09-02T10:00:35+02:00","duration":28},{"begin":"2024-09-02T12:06:07+02:00","end":"2024-09-02T12:06:14+02:00","duration":7},{"begin":"2024-09-02T13:34:07+02:00","end":"2024-09-02T13:37:08+02:00","duration":181},{"begin":"2024-09-02T13:38:06+02:00","end":"2024-09-02T13:41:28+02:00","duration":201},{"begin":"2024-09-02T13:42:50+02:00","end":"2024-09-02T13:46:11+02:00","duration":201},{"begin":"2024-09-02T13:49:13+02:00","end":"2024-09-02T13:58:02+02:00","duration":529},{"begin":"2024-09-02T13:58:37+02:00","end":"2024-09-02T14:05:15+02:00","duration":397},{"begin":"2024-09-02T14:05:20+02:00","end":"2024-09-02T14:08:28+02:00","duration":188},{"begin":"2024-09-02T14:12:39+02:00","end":"2024-09-02T14:16:40+02:00","duration":241},{"begin":"2024-09-02T14:18:51+02:00","end":"2024-09-02T14:22:36+02:00","duration":225},{"begin":"2024-09-02T14:36:32+02:00","end":"2024-09-02T14:41:30+02:00","duration":298},{"begin":"2024-09-02T14:41:42+02:00","end":"2024-09-02T14:45:50+02:00","duration":248},{"begin":"2024-09-02T14:45:56+02:00","end":"2024-09-02T14:54:17+02:00","duration":501},{"begin":"2024-09-02T14:55:41+02:00","end":"2024-09-02T14:57:16+02:00","duration":95},{"begin":"2024-09-02T14:57:20+02:00","end":"2024-09-02T15:23:56+02:00","duration":1595},{"begin":"2024-09-02T15:24:04+02:00","end":"2024-09-02T15:27:13+02:00","duration":189},{"begin":"2024-09-02T15:29:27+02:00","end":"2024-09-02T15:34:40+02:00","duration":313},{"begin":"2024-09-02T15:48:11+02:00","end":"2024-09-02T15:51:29+02:00","duration":198},{"begin":"2024-09-02T15:58:29+02:00","end":"2024-09-02T16:01:30+02:00","duration":181},{"begin":"2024-09-02T16:12:04+02:00","end":"2024-09-02T17:25:24+02:00","duration":4399},{"begin":"2024-09-02T17:27:25+02:00","end":"2024-09-02T18:31:31+02:00","duration":3846},{"begin":"2024-09-02T18:34:44+02:00","end":"2024-09-02T18:37:53+02:00","duration":189},{"begin":"2024-09-02T18:58:46+02:00","end":"2024-09-02T19:17:07+02:00","duration":1100},{"begin":"2024-09-02T19:26:30+02:00","end":"2024-09-02T19:37:22+02:00","duration":652},{"begin":"2024-09-02T19:42:29+02:00","end":"2024-09-02T19:46:07+02:00","duration":218},{"begin":"2024-09-02T19:48:00+02:00","end":"2024-09-02T19:58:57+02:00","duration":657},{"begin":"2024-09-02T20:00:07+02:00","end":"2024-09-02T20:03:33+02:00","duration":206},{"begin":"2024-09-02T20:04:34+02:00","end":"2024-09-02T20:08:13+02:00","duration":219},{"begin":"2024-09-02T20:08:23+02:00","end":"2024-09-02T20:16:40+02:00","duration":497},{"begin":"2024-09-02T20:18:09+02:00","end":"2024-09-02T20:23:04+02:00","duration":295},{"begin":"2024-09-02T20:23:29+02:00","end":"2024-09-02T20:38:30+02:00","duration":901},{"begin":"2024-09-02T20:38:32+02:00","end":"2024-09-02T20:43:10+02:00","duration":278},{"begin":"2024-09-02T20:43:20+02:00","end":"2024-09-02T20:52:29+02:00","duration":549},{"begin":"2024-09-02T20:55:06+02:00","end":"2024-09-02T20:58:13+02:00","duration":187},{"begin":"2024-09-02T20:59:10+02:00","end":"2024-09-02T21:39:14+02:00","duration":2403},{"begin":"2024-09-02T21:55:24+02:00","end":"2024-09-02T22:18:45+02:00","duration":1401},{"begin":"2024-09-02T23:29:59+02:00","end":"2024-09-02T23:34:41+02:00","duration":281},{"begin":"2024-09-02T23:35:13+02:00","end":"2024-09-02T23:57:29+02:00","duration":1336}]} \ No newline at end of file diff --git a/src/app/Http/Controllers/AdminController.php b/src/app/Http/Controllers/AdminController.php index c27f2ae..a665983 100644 --- a/src/app/Http/Controllers/AdminController.php +++ b/src/app/Http/Controllers/AdminController.php @@ -10,6 +10,6 @@ class AdminController extends Controller public function dashboard() { $users = User::withCount('posts', 'comments')->get(); - return view('admin.dashboard', compact('users')); + return view('admin.index', compact('users')); } } diff --git a/src/app/Http/Controllers/PostController.php b/src/app/Http/Controllers/PostController.php index e305034..7291545 100644 --- a/src/app/Http/Controllers/PostController.php +++ b/src/app/Http/Controllers/PostController.php @@ -14,16 +14,14 @@ use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Storage; -class PostController extends Controller -{ +class PostController extends Controller { /** * Display a listing of the resource. */ - public function index(): View - { + public function index(): View { $userId = Auth::id(); $userType = Auth::user()->usertype; - + // Retrieve published and draft posts from the database $draftPosts = Post::whereNotNull('user_id') ->where('user_id', $userId) @@ -46,26 +44,24 @@ public function index(): View /** * Display a special listing of the resources with all only for admin. */ - public function all(): View - { + public function all(): View { // Retrieve published and draft posts from the database and pass them to the view return view('posts.index', [ 'draftPosts' => Post::where('is_published', false) ->orderBy('updated_at', 'desc') - ->paginate(10), + ->paginate(15), 'publishedPosts' => Post::where('is_published', true) ->orderBy('updated_at', 'desc') - ->paginate(10), + ->paginate(15), ]); } /** * Display the gallery with pagination. */ - public function gallery(Request $request): View - { + public function gallery(Request $request): View { $posts = Post::where('is_published', true) ->orderBy('created_at', 'desc') - ->paginate(10); + ->paginate(15); return view('welcome', compact('posts')); } @@ -73,8 +69,7 @@ public function gallery(Request $request): View /** * Show the form for creating a new resource. */ - public function create(): View - { + public function create(): View { // Return the view for creating a new post return view('posts.edit'); } @@ -82,8 +77,7 @@ public function create(): View /** * Store a newly created resource in storage. */ - public function store(StoreRequest $request, CreateImageVariants $createImageVariants): RedirectResponse - { + public function store(StoreRequest $request, CreateImageVariants $createImageVariants): RedirectResponse { // Validate the incoming request $validated = $request->validated(); @@ -128,8 +122,7 @@ public function store(StoreRequest $request, CreateImageVariants $createImageVar /** * Display the specified resource. */ - public function show(string $id): View - { + public function show(string $id): View { $post = Post::findOrFail($id); return view('posts.show', compact('post')); } @@ -137,8 +130,7 @@ public function show(string $id): View /** * Show the form for editing the specified resource. */ - public function edit(string $id): View - { + public function edit(string $id): View { // Retrieve the post with the specified ID $post = Post::findOrFail($id); @@ -158,8 +150,7 @@ public function edit(string $id): View /** * Update the specified resource in storage. */ - public function update(UpdateRequest $request, string $id, CreateImageVariants $createImageVariants): RedirectResponse - { + public function update(UpdateRequest $request, string $id, CreateImageVariants $createImageVariants): RedirectResponse { // Find the post with the specified ID $post = Post::findOrFail($id); @@ -208,8 +199,7 @@ public function update(UpdateRequest $request, string $id, CreateImageVariants $ /** * Remove the specified resource from storage. */ - public function destroy(string $id): RedirectResponse - { + public function destroy(string $id): RedirectResponse { $post = Post::findOrFail($id); $this->userIsOwner($post->user_id); @@ -240,8 +230,7 @@ public function destroy(string $id): RedirectResponse /** * Mark the specified post as published. */ - public function publish(string $id): RedirectResponse - { + public function publish(string $id): RedirectResponse { // Find the post with the specified ID and update its publication status $post = Post::findOrFail($id); @@ -260,8 +249,7 @@ public function publish(string $id): RedirectResponse /** * Mark the specified post as a draft. */ - public function makedraft(string $id): RedirectResponse - { + public function makedraft(string $id): RedirectResponse { // Find the post with the specified ID and update its publication status $post = Post::findOrFail($id); // Check if the authenticated user owns the post @@ -286,8 +274,7 @@ public function makedraft(string $id): RedirectResponse /* * Hide the specified post (unpublish it without making it a draft). */ - public function hide(string $id): RedirectResponse - { + public function hide(string $id): RedirectResponse { $post = Post::findOrFail($id); // Check if the authenticated user owns the post @@ -309,8 +296,7 @@ public function hide(string $id): RedirectResponse return redirect()->route('posts.index'); } - private function userIsOwner($user_id_from_post): void - { + private function userIsOwner($user_id_from_post): void { if ($user_id_from_post !== Auth::id() and Auth::user()->usertype !== 'admin') { abort(403, 'Unauthorized action.'); } diff --git a/src/app/Http/Controllers/ProfileController.php b/src/app/Http/Controllers/ProfileController.php index 75651b5..70d7867 100644 --- a/src/app/Http/Controllers/ProfileController.php +++ b/src/app/Http/Controllers/ProfileController.php @@ -17,60 +17,63 @@ use Illuminate\View\View; class ProfileController extends Controller { - /** - * Update the user's profile information. - */ - public function update(ProfileUpdateRequest $request): RedirectResponse { - $user = $request->user(); - $validatedData = $request->validated(); - // Check if the name has changed - if ($user->name !== $validatedData['name']) { + public function updateName(ProfileUpdateRequest $request): RedirectResponse { - // Validate the name change interval - $statusMessage = LastNameChange::getNameChangeStatus($user->last_name_change, 30); - if ($statusMessage) { - return Redirect::back()->withErrors(['name' => $statusMessage]); - } + $user = Auth::user(); + $name = $request->validated()['name']; + // Check if the name has changed + if ($user->name === $name) { + // No change detected, return to the same route with a message + return Redirect::back()->withErrors(['name' => 'That\'s your name already :P']); + } - // Update previous_name and last_name_change - $user->previous_name = $user->name; - $user->last_name_change = now(); + // Validate the name change interval + $statusMessage = LastNameChange::getNameChangeStatus($user->last_name_change, 30); + if ($statusMessage) { + session()->flash('notif.success', 'Failed!'); + return Redirect::back()->withErrors(['name' => $statusMessage]); } - // Update user profile information - $user->fill($validatedData); + // Update previous_name and last_name_change + $user->previous_name = $user->name; + $user->last_name_change = now(); + + // Update the username + $user->name = $name; + $user->save(); + - // Handle email verification reset if email has changed - if ($user->isDirty('email')) { - $user->email_verified_at = null; + session()->flash('notif.success', 'Your username updated successfully!'); + return Redirect::route('profile.edit'); + } + + public function updateEmail(ProfileUpdateRequest $request): RedirectResponse { + + $user = Auth::user(); + $email = $request->validated()['email']; + + if ($user->email === $email) { + // No change detected, return to the same route with a message + return Redirect::back()->withErrors(['email' => 'That\'s your email already :P']); } + // Handle email verification reset + $user->email_verified_at = null; + $user->email = $email; $user->save(); - return Redirect::route('profile.edit')->with('status', 'profile-updated'); + session()->flash('notif.success', 'Your mail updated successfully!'); + return Redirect::route('profile.edit'); } - /** - * Display the user's profile form. - */ - public function edit(Request $request): View { - return view('profile.edit', [ - 'user' => $request->user(), - ]); - } - /** * Update the user's profile image. */ - public function updateImage(FormRequest $request, CreateImageVariants $createImageVariants): RedirectResponse { - $validated = $request->validate([ - 'profile_image' => 'required|image|mimes:jpeg,png,jpg,gif|max:4096', - ]); - - $imageFile = $validated['profile_image']; + public function updateImage(ProfileUpdateRequest $request, CreateImageVariants $createImageVariants): RedirectResponse { $user = Auth::user(); + $imageFile = $request->validated()['profile_image']; // Check if the user already has a profile image $image = $user->image ?: new Image(['user_id' => $user->id]); @@ -92,6 +95,21 @@ public function updateImage(FormRequest $request, CreateImageVariants $createIma return Redirect::route('profile.edit')->with('status', 'profile-updated'); } + /** + * Display the user's profile form. + */ + public function edit(Request $request): View { + return view('profile.edit', [ + 'user' => $request->user(), + ]); + } + + public function show(Request $request): View { + return view('profile.show', [ + 'user' => $request->user(), + ]); + } + /** * Delete the user's account. */ diff --git a/src/app/Http/Requests/Auth/LoginRequest.php b/src/app/Http/Requests/Auth/LoginRequest.php index d0d7cde..b3f8316 100644 --- a/src/app/Http/Requests/Auth/LoginRequest.php +++ b/src/app/Http/Requests/Auth/LoginRequest.php @@ -9,13 +9,11 @@ use Illuminate\Support\Str; use Illuminate\Validation\ValidationException; -class LoginRequest extends FormRequest -{ +class LoginRequest extends FormRequest { /** * Determine if the user is authorized to make this request. */ - public function authorize(): bool - { + public function authorize(): bool { return true; } @@ -24,8 +22,7 @@ public function authorize(): bool * * @return array */ - public function rules(): array - { + public function rules(): array { return [ 'email' => ['required', 'string', 'email'], 'password' => ['required', 'string'], @@ -37,8 +34,7 @@ public function rules(): array * * @throws \Illuminate\Validation\ValidationException */ - public function authenticate(): void - { + public function authenticate(): void { $this->ensureIsNotRateLimited(); if (! Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) { @@ -49,8 +45,15 @@ public function authenticate(): void ]); } + // Automatically mark the email as verified in development environments $user = Auth::user(); + if (app()->environment('local', 'development') && !$user->hasVerifiedEmail()) { + $user->markEmailAsVerified(); + // Flash a session message to notify the user + session()->flash('notif.success', 'Your email has been automatically verified for development purposes.'); + } + RateLimiter::clear($this->throttleKey()); } @@ -59,8 +62,7 @@ public function authenticate(): void * * @throws \Illuminate\Validation\ValidationException */ - public function ensureIsNotRateLimited(): void - { + public function ensureIsNotRateLimited(): void { if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) { return; } @@ -80,8 +82,7 @@ public function ensureIsNotRateLimited(): void /** * Get the rate limiting throttle key for the request. */ - public function throttleKey(): string - { + public function throttleKey(): string { return Str::transliterate(Str::lower($this->string('email')) . '|' . $this->ip()); } } diff --git a/src/app/Http/Requests/ProfileUpdateRequest.php b/src/app/Http/Requests/ProfileUpdateRequest.php index 0d5a402..927ce79 100644 --- a/src/app/Http/Requests/ProfileUpdateRequest.php +++ b/src/app/Http/Requests/ProfileUpdateRequest.php @@ -6,19 +6,27 @@ use Illuminate\Foundation\Http\FormRequest; use Illuminate\Validation\Rule; -class ProfileUpdateRequest extends FormRequest -{ +class ProfileUpdateRequest extends FormRequest { /** * Get the validation rules that apply to the request. * * @return array */ - public function rules(): array - { - return [ - 'name' => ['required', 'string', 'max:255', Rule::unique(User::class)->ignore($this->user()->id)], - 'email' => ['required', 'string', 'lowercase', 'email', 'max:255', Rule::unique(User::class)->ignore($this->user()->id)], - 'profile_image' => ['nullable|image|mimes:jpeg,png,jpg,gif,svg|max:4096'], - ]; + public function rules(): array { + $rules = []; + + if ($this->routeIs('profile.updateName')) { + $rules['name'] = ['required', 'string', 'max:255', Rule::unique(User::class)->ignore($this->user()->id)]; + } + + if ($this->routeIs('profile.updateEmail')) { + $rules['email'] = ['required', 'string', 'lowercase', 'email', 'max:255', Rule::unique(User::class)->ignore($this->user()->id)]; + } + + if ($this->routeIs('profile.updateImage')) { + $rules['profile_image'] = ['required', 'image', 'mimes:jpeg,png,jpg,gif,svg', 'max:4096']; + } + + return $rules; } } diff --git a/src/app/Models/Session.php b/src/app/Models/Session.php new file mode 100644 index 0000000..be79cc3 --- /dev/null +++ b/src/app/Models/Session.php @@ -0,0 +1,19 @@ +belongsTo(User::class); + } +} diff --git a/src/app/Models/User.php b/src/app/Models/User.php index 4d8162d..f861762 100644 --- a/src/app/Models/User.php +++ b/src/app/Models/User.php @@ -7,11 +7,11 @@ use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; +use App\Models\Session; use Illuminate\Notifications\Notifiable; -class User extends Authenticatable implements MustVerifyEmail -{ +class User extends Authenticatable implements MustVerifyEmail { use HasFactory, Notifiable; /** @@ -21,21 +21,23 @@ class User extends Authenticatable implements MustVerifyEmail */ protected $fillable = ['name', 'email', 'password', 'profile_image', 'usertype']; - public function posts() - { + public function posts() { return $this->hasMany(Post::class); } - public function comments() - { + public function comments() { return $this->hasMany(Comment::class); } - public function image() - { + public function image() { return $this->hasOne(Image::class); } + // Define a custom hasOne relationship to the sessions table + public function session() { + return $this->hasOne(Session::class, 'user_id', 'id'); + } + /** * Get the former name if it is within the given days limit. @@ -43,8 +45,7 @@ public function image() * @param int $daysLimit * @return string|null */ - public function getFormerNameIfApplicable(int $daysLimit = 90): ?string - { + public function getFormerNameIfApplicable(int $daysLimit = 90): ?string { if ($this->previous_name) { $lastNameChangeDate = $this->last_name_change ? Carbon::parse($this->last_name_change) : null; $daysPassed = $lastNameChangeDate ? $lastNameChangeDate->diffInDays(Carbon::now()) : null; @@ -69,8 +70,7 @@ public function getFormerNameIfApplicable(int $daysLimit = 90): ?string * * @return array */ - protected function casts(): array - { + protected function casts(): array { return [ 'email_verified_at' => 'datetime', 'password' => 'hashed', diff --git a/src/resources/views/admin/dashboard.blade.php b/src/resources/views/admin/dashboard.blade.php deleted file mode 100644 index 6cc0d47..0000000 --- a/src/resources/views/admin/dashboard.blade.php +++ /dev/null @@ -1,25 +0,0 @@ - - - Admin Dashboard - - -
-
-
-
- - All posts -
-
-
- -
-
-
- @include('admin.partials.user-list') -
-
-
-
-
diff --git a/src/resources/views/admin/index.blade.php b/src/resources/views/admin/index.blade.php new file mode 100644 index 0000000..b5bfe80 --- /dev/null +++ b/src/resources/views/admin/index.blade.php @@ -0,0 +1,21 @@ + + + Admin Dashboard + + {{-- Check if there is a notif.success flash session --}} + @if (Session::has('notif.success')) +
+ {{ Session::get('notif.success') }} +
+ @endif + +
+ + +
+ @foreach ($users as $user) + @include('admin.partials.user-tile', ['user' => $user]) + @endforeach +
+ +
diff --git a/src/resources/views/admin/partials/user-tile.blade.php b/src/resources/views/admin/partials/user-tile.blade.php new file mode 100644 index 0000000..368e333 --- /dev/null +++ b/src/resources/views/admin/partials/user-tile.blade.php @@ -0,0 +1,83 @@ +
+ +
+ + @if ($user->getFormerNameIfApplicable()) +

+ Formerly: {{ $user->getFormerNameIfApplicable() }} +

+ @endif +

{{ $user->name }}

+

{{ $user->email }}

+ +

+ {{ $user->usertype }} +

+ +
+

+ Registered: {{ $user->created_at->format('M d, Y') }} +

+

+ Last Updated: {{ $user->updated_at->format('M d, Y') }} +

+

+ @if ($user->email_verified_at) + Email Verified: {{ $user->email_verified_at->format('M d, Y') }} + @else + Email Verified: No + @endif +

+

+ Seen: + @if ($user->session) + {{ \Carbon\Carbon::parse($user->session->last_activity)->diffForHumans() }} + @else + Offline + @endif +

+
+
+
diff --git a/src/resources/views/auth/verify-email.blade.php b/src/resources/views/auth/verify-email.blade.php index 6b91652..2654862 100644 --- a/src/resources/views/auth/verify-email.blade.php +++ b/src/resources/views/auth/verify-email.blade.php @@ -1,13 +1,14 @@ -
+
- {{ __('Thanks for signing up! Before getting started, could you verify your email address by clicking on the link we just emailed to you? If you didn\'t receive the email, we will gladly send you another.') }} + {{ __('Thanks for signing up! Before getting started, could you verify your email address :email by clicking on + the link we just emailed to you? If you didn\'t receive the email, we will gladly send you another.',['email' => Auth::user()->email]) }}
@if (session('status') == 'verification-link-sent') -
- {{ __('A new verification link has been sent to the email address you provided during registration.') }} +
+ {{ __('A new verification link has been sent to :email', ['email' => Auth::user()->email]) }}
@endif @@ -25,12 +26,13 @@
@csrf -
- + diff --git a/src/resources/views/components/gallery/comment/show-comments.blade.php b/src/resources/views/components/gallery/comment/show-comments.blade.php index efc811a..be36bbe 100644 --- a/src/resources/views/components/gallery/comment/show-comments.blade.php +++ b/src/resources/views/components/gallery/comment/show-comments.blade.php @@ -1,5 +1,5 @@ {{-- list comments --}} -@forelse ($post->comments->reverse() as $comment) +@forelse ($post->comments as $comment) {{-- ->reverse() --}}
@if (!(Auth::id() === $comment->user_id))
diff --git a/src/resources/views/components/gallery/gallery.blade.php b/src/resources/views/components/gallery/gallery.blade.php index b3b8ab1..d1db330 100644 --- a/src/resources/views/components/gallery/gallery.blade.php +++ b/src/resources/views/components/gallery/gallery.blade.php @@ -43,11 +43,12 @@

- - + +
diff --git a/src/resources/views/layouts/navigation.blade.php b/src/resources/views/layouts/navigation.blade.php index 7d78154..d2645c0 100644 --- a/src/resources/views/layouts/navigation.blade.php +++ b/src/resources/views/layouts/navigation.blade.php @@ -65,7 +65,7 @@ class="inline-flex items-center justify-center rounded-md p-2 text-c-text transi
{{ Str::limit(Auth::user()->name, 30, '...') }}
@if (Auth::user()->usertype == 'admin') - + {{ __('Admin Dashboard') }} @endif @@ -107,7 +107,7 @@ class="inline-flex items-center rounded-md border border-transparent px-3 py-2 t @if (Auth::user()->usertype == 'admin') - + {{ __('Admin Dashboard') }} @endif diff --git a/src/resources/views/posts/index.blade.php b/src/resources/views/posts/index.blade.php index 3e11802..9acbacb 100644 --- a/src/resources/views/posts/index.blade.php +++ b/src/resources/views/posts/index.blade.php @@ -7,7 +7,12 @@
Your Posts - + {{-- check if there is a notif.success flash session --}} + @if (Session::has('notif.success')) +
+ {{ Session::get('notif.success') }} +
+ @endif
@@ -53,56 +58,57 @@ class="font-semibold">delete your post at any time. @forelse ($draftPosts->sortByDesc('created_at') as $post) -
- - -
-
- - - -
- -
- - {{ $post->title }} - Created - {{ $post->created_at->diffForHumans() }} - Update - {{ $post->updated_at->diffForHumans() }} - Comments: - {{ $post->comments->count() }} -
+
+ + +
+ + +
+ {{ $post->title }} - -
- - - PUBLISH - - - EDIT - - -
- @csrf - @method('delete') - -
+ Created: {{ $post->created_at->diffForHumans() }} + + @if ($post->created_at !== $post->updated_at) + Last update: {{ $post->updated_at->diffForHumans() }} + @endif
- @empty -
- No draft posts found. + + +
+ + + PUBLISH + + + EDIT + + +
+ @csrf + @method('delete') + +
+
+ @empty + Create a new post! +
+ No draft posts found. +
@endforelse
@@ -118,72 +124,74 @@ class="flex items-center gap-1 rounded-md border border-l-4 border-red-500 px-4 @forelse ($publishedPosts->sortByDesc('created_at') as $post) -
- -
-
- - - -
- -
- {{ $post->title }} - @if (!$post->is_published) - (HIDDEN) - @endif - Created - {{ $post->created_at->diffForHumans() }} - Update - {{ $post->updated_at->diffForHumans() }} - Comments: - {{ $post->comments->count() }} - -
+
+ +
+ + +
+ {{ $post->title }} - -
- - @if ($isAdmin) - EDIT + @if (!$post->is_published) + (HIDDEN) @endif - @if ($post->is_published) - - - HIDE ◐ - - @else - - - UNHIDE - + Created: {{ $post->created_at->diffForHumans() }} + + @if ($post->created_at !== $post->updated_at) + Last update: {{ $post->updated_at->diffForHumans() }} @endif - -
- @csrf - @method('delete') - -
+ Comments: {{ $post->comments->count() }}
- @empty -
- No published posts found. + + +
+ + @if ($isAdmin) + EDIT + @endif + + @if ($post->is_published) + + + HIDE ◐ + + @else + + + UNHIDE + + @endif + + +
+ @csrf + @method('delete') + +
+
+ @empty +
+ No published posts found. Create a post and publish + it! +
@endforelse
- + \ No newline at end of file diff --git a/src/resources/views/profile/edit.blade.php b/src/resources/views/profile/edit.blade.php index 6e9adbf..2f313c3 100644 --- a/src/resources/views/profile/edit.blade.php +++ b/src/resources/views/profile/edit.blade.php @@ -1,7 +1,15 @@ - Profile - +
+ Profile + {{-- check if there is a notif.success flash session --}} + @if (Session::has('notif.success')) +
+ {{ Session::get('notif.success') }} +
+ @endif + +
@@ -55,4 +63,4 @@
- + \ No newline at end of file diff --git a/src/resources/views/profile/partials/delete-user-form.blade.php b/src/resources/views/profile/partials/delete-user-form.blade.php index cc02b42..46768da 100644 --- a/src/resources/views/profile/partials/delete-user-form.blade.php +++ b/src/resources/views/profile/partials/delete-user-form.blade.php @@ -41,8 +41,6 @@
- -
diff --git a/src/resources/views/profile/partials/update-profile-information-form.blade.php b/src/resources/views/profile/partials/update-profile-information-form.blade.php index 9b8b675..0192b11 100644 --- a/src/resources/views/profile/partials/update-profile-information-form.blade.php +++ b/src/resources/views/profile/partials/update-profile-information-form.blade.php @@ -1,48 +1,53 @@
-

{{ __('Profile Information') }}

-

{{ __("Update your account's profile information and email address. A username is how others recognize you.") }}

-
- @csrf -
- -
+ + @csrf @method('patch') -
+ required autocomplete="name" maxlength="120" />
+
+ {{ __('Update Username') }} + @if (session('status') === 'profile-updated') +

+ {{ __('Username updated.') }} +

+ @endif +
+
+ +
+ @csrf + @method('patch')
+ required autocomplete="email" maxlength="120" /> - @if ($user instanceof \Illuminate\Contracts\Auth\MustVerifyEmail && !$user->hasVerifiedEmail())

{{ __('Your email address is unverified.') }} -

- @if (session('status') === 'verification-link-sent')

{{ __('A new verification link has been sent to your email address.') }} @@ -52,13 +57,7 @@ class="rounded-md text-sm text-gray-600 underline hover:text-gray-900 focus:outl @endif

- {{ __('Save') }} - - @if (session('status') === 'profile-updated') -

{{ __('Saved.') }}

- @endif + {{ __('Update Email') }}
-
diff --git a/src/routes/web.php b/src/routes/web.php index 8e5f0c1..1a87909 100644 --- a/src/routes/web.php +++ b/src/routes/web.php @@ -26,12 +26,23 @@ Route::middleware('auth', 'verified')->group(function () { // Routes here are accessible to authenticated users only!! - Route::get('/admin/dashboard', [AdminController::class, 'dashboard'])->name('admin.dashboard')->middleware(Admin::class); + Route::get('/admin', [AdminController::class, 'dashboard'])->name('admin.index')->middleware(Admin::class); Route::get('/admin/posts', [PostController::class, 'all'])->name('posts.index')->middleware(Admin::class); // Profiles + Route::get('/profile/{user}', [ProfileController::class, 'show'])->name('profile.show'); + Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit'); - Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update'); + + Route::patch('/profile/update-name', [ProfileController::class, 'updateName']) + ->name('profile.updateName'); + + Route::patch('/profile/update-email', [ProfileController::class, 'updateEmail']) + ->name('profile.updateEmail'); + + Route::patch('/profile/update-image', [ProfileController::class, 'updateImage']) + ->name('profile.updateImage'); + Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy'); Route::put('/profile/update-image', [ProfileController::class, 'updateImage'])->name('profile.updateImage');