diff --git a/app/Helpers/GetNameInitMonth.php b/app/Helpers/GetNameInitMonth.php new file mode 100644 index 0000000..684cfd9 --- /dev/null +++ b/app/Helpers/GetNameInitMonth.php @@ -0,0 +1,16 @@ +translatedFormat('F'); // Januari + return strtoupper(mb_substr($bulan, 0, 1)); // J + } +} diff --git a/app/Http/Controllers/TaskmanController.php b/app/Http/Controllers/TaskmanController.php index a2c9db1..8de88ca 100644 --- a/app/Http/Controllers/TaskmanController.php +++ b/app/Http/Controllers/TaskmanController.php @@ -2,14 +2,13 @@ namespace App\Http\Controllers; -use App\Helpers\CheckTodaysInRange; -use App\Helpers\GetNumberDate; use App\Models\MonitorWeekly as ModelWeekly; use Illuminate\Http\Request; use App\Models\Taskman as ModelTaskman; use App\Models\User as ModelUser; use App\Models\Task as ModelTask; use App\Models\PlanAgenda as ModelPlan; +use App\Models\LogTask as ModelLogofTask; use Carbon\Carbon; class TaskmanController extends Controller @@ -42,7 +41,7 @@ public function goals($plan) } ]) ->orderBy('deadline', 'desc') - ->paginate(6); + ->paginate(10); $infoPlanAgenda = ModelPlan::findOrFail($plan); @@ -272,11 +271,57 @@ public function deleteItemTask(Request $request) public function listTaskByDate(Request $request) { - $tasks = ModelTask::whereDate('due', $request->date) - ->orderBy('id') + $tasks = ModelTask::with('user') // ๐ eager load user + ->whereDate('due', $request->date) + ->orderBy('id', 'DESC') ->get(); return response()->json($tasks); } + + public function addWeekly(Request $request) + { + $planAgenda = $request->input('id_plan_agn'); + $current_page = $request->input('current_page'); + + $data = [ + 'weekly' => $request->input('weeklyinit'), + 'start_date' => $request->input('start_date'), + 'end_date' => $request->input('end_date') + ]; + + if ($request->input('bufferStatus')) { + $bufferDays = max(0, (int) $request->input('bufferDays', 0)); + + $startBuffer = Carbon::parse($request->input('end_date')) + ->addDay() + ->format('Y-m-d'); + + $endBuffer = Carbon::parse($startBuffer) + ->addDays($bufferDays) + ->format('Y-m-d'); + + $data['buffer_start'] = $startBuffer; + $data['buffer_end'] = $endBuffer; + } + + if (str_contains(strtolower($request->input('weeklyinit')), 'ext')) { + $data['extention'] = 1; + } else { + $data['extention'] = 0; + } + + ModelWeekly::create($data); + + return redirect()->route('taskman.goals', [$planAgenda, 'page' => $current_page])->with('success', 'Yay, Data weekly berhasil dibuat.'); + } + + public function itemDetailTask(Request $request, $id) + { + $dataTask = ModelTask::with('user')->findOrFail($id); + $logTask = ModelLogofTask::where('id_task', $id)->first(); + + return view('home.taskman.detail_item', compact('dataTask', 'logTask')); + } } diff --git a/app/Models/AttachmentLogs.php b/app/Models/AttachmentLogs.php new file mode 100644 index 0000000..15688a4 --- /dev/null +++ b/app/Models/AttachmentLogs.php @@ -0,0 +1,24 @@ +belongsTo(LogTask::class, 'id_log', 'id'); + // 'id_log' = foreign key di attachment logs + // 'id' = primary key di log task + } +} diff --git a/app/Models/LogTask.php b/app/Models/LogTask.php new file mode 100644 index 0000000..81c15c5 --- /dev/null +++ b/app/Models/LogTask.php @@ -0,0 +1,24 @@ +belongsTo(Task::class, 'id_task', 'id'); + // 'id_task' = foreign key di log task + // 'id' = primary key di task + } +} diff --git a/composer.json b/composer.json index 0b5a44c..c78f284 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,8 @@ "app/Helpers/DayLefted.php", "app/Helpers/GetNumberDate.php", "app/Helpers/TotalDays.php", - "app/Helpers/CheckTodaysInRange.php" + "app/Helpers/CheckTodaysInRange.php", + "app/Helpers/GetNameInitMonth.php" ] }, "autoload-dev": { diff --git a/database/migrations/2026_01_21_105637_add_reschedule_to_tasks_table.php b/database/migrations/2026_01_21_105637_add_reschedule_to_tasks_table.php new file mode 100644 index 0000000..c2b77ae --- /dev/null +++ b/database/migrations/2026_01_21_105637_add_reschedule_to_tasks_table.php @@ -0,0 +1,28 @@ +string('category_evidence')->nullable()->after('detail_task'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('tasks', function (Blueprint $table) { + $table->dropColumn('category_evidence'); + }); + } +}; diff --git a/database/migrations/2026_02_10_013727_add_date_of_actual_done_to_tasks_table.php b/database/migrations/2026_02_10_013727_add_date_of_actual_done_to_tasks_table.php new file mode 100644 index 0000000..63efae5 --- /dev/null +++ b/database/migrations/2026_02_10_013727_add_date_of_actual_done_to_tasks_table.php @@ -0,0 +1,28 @@ +date('date_of_actual_done')->nullable()->after('due'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('tasks', function (Blueprint $table) { + $table->dropColumn('date_of_actual_done'); + }); + } +}; diff --git a/database/migrations/2026_02_10_014621_modify_actual_date_type_on_tasks_table.php b/database/migrations/2026_02_10_014621_modify_actual_date_type_on_tasks_table.php new file mode 100644 index 0000000..0664fdf --- /dev/null +++ b/database/migrations/2026_02_10_014621_modify_actual_date_type_on_tasks_table.php @@ -0,0 +1,32 @@ +dateTime('date_of_actual_done') + ->nullable() + ->change(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('tasks', function (Blueprint $table) { + $table->date('date_of_actual_done') + ->nullable() + ->change(); + }); + } +}; diff --git a/database/migrations/2026_02_10_015010_create_log_taks_table.php b/database/migrations/2026_02_10_015010_create_log_taks_table.php new file mode 100644 index 0000000..e33be39 --- /dev/null +++ b/database/migrations/2026_02_10_015010_create_log_taks_table.php @@ -0,0 +1,31 @@ +id(); + $table->integer('id_task'); + $table->dateTime('date_updates'); + $table->string('detail_updates'); + $table->integer('person_of_updates'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('log_taks'); + } +}; diff --git a/database/migrations/2026_02_10_015525_create_attachment_logs_table.php b/database/migrations/2026_02_10_015525_create_attachment_logs_table.php new file mode 100644 index 0000000..b91348d --- /dev/null +++ b/database/migrations/2026_02_10_015525_create_attachment_logs_table.php @@ -0,0 +1,30 @@ +id(); + $table->integer('id_log'); + $table->string('attachments'); + $table->integer('category_of_attachment'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('attachment_logs'); + } +}; diff --git a/database/seeders/LogTask.php b/database/seeders/LogTask.php new file mode 100644 index 0000000..ae62183 --- /dev/null +++ b/database/seeders/LogTask.php @@ -0,0 +1,28 @@ + 167, + 'date_updates' => now(), + 'detail_updates' => 'Task di hold, karena mau mengerjakan task Analisa HR', + 'person_of_updates' => 5, + ], + + ]; + + DB::table('log_taks')->insert($log_of_tasks); + } +} diff --git a/public/css/custom-timeline.css b/public/css/custom-timeline.css index c048483..c639049 100644 --- a/public/css/custom-timeline.css +++ b/public/css/custom-timeline.css @@ -24,7 +24,7 @@ display: block; margin-bottom: 20px; position: relative; width: 100%; -padding-right: 90px; +padding-right: 20px; } .timeline .timeline-wrapper:before { diff --git a/public/css/new-line.css b/public/css/new-line.css index 7628e3f..4d7e2de 100644 --- a/public/css/new-line.css +++ b/public/css/new-line.css @@ -1,71 +1,167 @@ +.main-wrapper { + padding: 60px 0; +} + +/* =============================== + SCROLL CONTAINER +==================================*/ +.timeline-wrapper { + position: relative; +} + +.timeline-container { + max-height: 85vh; + overflow-y: auto; + + /* Hide scrollbar */ + -ms-overflow-style: none; + scrollbar-width: none; +} + +.timeline-container::-webkit-scrollbar { + display: none; +} + +/* =============================== + SHADOW EFFECT +==================================*/ +.shadow-top, +.shadow-bottom { + position: absolute; + left: 0; + right: 0; + height: 40px; + pointer-events: none; + opacity: 0; + transition: opacity 0.3s ease; + z-index: 5; +} + +.shadow-top { + top: 0; + background: linear-gradient(to bottom, rgba(0,0,0,0.15), transparent); +} + +.shadow-bottom { + bottom: 0; + background: linear-gradient(to top, rgba(0,0,0,0.15), transparent); +} + +.shadow-visible { + opacity: 1; +} + +/* =============================== + TIMELINE +==================================*/ .timeline { - border-left: 3px solid #727cf5; - border-bottom-right-radius: 4px; - border-top-right-radius: 4px; - margin: 0 auto; - position: relative; - padding: 50px; - list-style: none; - text-align: left; - max-width: 68%; -} - -.timeline .event { - border-bottom: 1px dashed #e8ebf1; - padding-bottom: 25px; - margin-bottom: 25px; - position: relative; -} - -.timeline .event:last-of-type { - padding-bottom: 0; - margin-bottom: 0; - border: none; -} - -.timeline .event:before, -.timeline .event:after { - position: absolute; - display: block; - top: 0; -} - -.timeline .event:before { - left: -210px; - content: attr(data-date); - text-align: right; - font-weight: 100; - font-size: 0.9em; - min-width: 120px; -} - -.timeline .event:after { - box-shadow: 0 0 0 3px #727cf5; - left: -55.8px; - background: #fff; - border-radius: 50%; - height: 9px; - width: 9px; - content: ""; - top: 5px; -} - -@media (max-width: 767px) { - .timeline { - max-width: 98%; - padding: 25px; - } - - .timeline .event { - padding-top: 30px; - } - - .timeline .event:before { - left: 0px; - text-align: left; - } - - .timeline .event:after { - left: -31.8px; - } + position: relative; + padding: 20px 0; +} + +.timeline::before { + content: ""; + position: absolute; + top: 0; + left: 50%; + width: 3px; + height: 100%; + background: #4f46e5; + transform: translateX(-50%); +} + +.timeline-item { + position: relative; + margin-bottom: 80px; +} + +.timeline-card { + width: 45%; + background: #fff; + padding: 20px 25px; + border-radius: 10px; + transition: 0.3s ease; + margin-left: 10px; + margin-right: 10px; +} + +.timeline-card:hover { + transform: translateY(-5px); +} + +.timeline-item.left .timeline-card { + margin-right: auto; + text-align: right; +} + +.timeline-item.right .timeline-card { + margin-left: auto; +} + +.timeline-icon { + position: absolute; + top: 25px; + left: 50%; + width: 42px; + height: 42px; + background: #fff; + border: 3px solid #4f46e5; + border-radius: 50%; + transform: translateX(-50%); + display: flex; + align-items: center; + justify-content: center; + color: #4f46e5; + font-size: 18px; + z-index: 2; + box-shadow: 0 0 0 4px #f8f9fa; +} + +.timeline-date { + font-size: 14px; + color: #6c757d; + margin-bottom: 6px; +} + +/* =============================== + INFO STICKY +==================================*/ +.info-sticky { + position: sticky; + top: 100px; +} + +.info-card { + border-radius: 10px; +} + +/* =============================== + RESPONSIVE +==================================*/ +@media (max-width: 992px) { + + .timeline-container { + max-height: none; + overflow: visible; + } + + .shadow-top, + .shadow-bottom { + display: none; + } + + .timeline::before { + left: 20px; + } + + .timeline-icon { + left: 20px; + } + + .timeline-card { + width: 100%; + margin-left: 60px !important; + text-align: left !important; + } + } \ No newline at end of file diff --git a/public/sneat-v3.0/html/auth-forgot-password-basic.html b/public/sneat-v3.0/html/auth-forgot-password-basic.html new file mode 100644 index 0000000..ad6c9de --- /dev/null +++ b/public/sneat-v3.0/html/auth-forgot-password-basic.html @@ -0,0 +1,185 @@ + + + +
+ + + +Enter your email and we'll send you instructions to reset your password
+ + +Please sign-in to your account and start the adventure
+ + + ++ New on our platform? + + Create an account + +
+Make your app management easy and fun!
+ + + ++ Already have an account? + + Sign in instead + +
+we couldn't find the page you are looking for
+ Back to home +
+ Sorry for the inconvenience but we're performing some maintenance at the moment
+ Back to home +
+ Reporting dashboard & notifications
+Security vulnerability fix
+Integration with cloud services
+Major performance improvements
++ Timeline di kiri dapat di-scroll tanpa terlihat scrollbar. + Section ini tetap berada pada posisi sticky. +
+ +Major update with new features and improvements:
-Minor update focusing on bug fixes and stability:
-Initial release of our product with core features:
-Major update with new features and improvements in the last version of release: -
-Major update with new features and improvements:
-Major update with new features and improvements:
-Major update with new features and improvements:
-- Major update with new features and improvements in the last version of release: -
- -First developer team:
-