From b001c6bfbf7ba22661f90b1fe8c67d6bd279f500 Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Wed, 1 Apr 2026 20:18:54 +0700 Subject: [PATCH] feat: update notification system to use key-based messages and improve user feedback across various components --- app/Filament/Pages/Auth/Login.php | 24 +- .../Information/CourseSchedule/Index.php | 6 +- .../Pages/Learning/StudyGroup/Index.php | 8 +- app/Filament/Pages/Profile.php | 40 +- .../Actions/CopyAssignmentLinkAction.php | 8 +- .../Assignments/Actions/PinAction.php | 16 +- .../Assignments/Pages/ListAssignments.php | 4 +- .../Pages/SubmitAssignmentPage.php | 40 +- .../Assignments/Schemas/AssignmentForm.php | 13 +- .../Attendances/Pages/ManageAttendances.php | 36 +- .../Actions/CopyAttendanceLinkAction.php | 8 +- .../Actions/GenerateSessionsAction.php | 19 +- .../Students/Actions/ChangePasswordAction.php | 8 +- .../Master/Students/Schemas/StudentForm.php | 16 +- .../Master/Students/Tables/StudentsTable.php | 8 +- app/Filament/Support/SystemNotification.php | 308 +++++-------- app/Filament/Widgets/SupportWidget.php | 2 +- lang/id/notif.php | 414 ++++++++++++++++++ 18 files changed, 597 insertions(+), 381 deletions(-) mode change 100644 => 100755 app/Filament/Support/SystemNotification.php create mode 100644 lang/id/notif.php diff --git a/app/Filament/Pages/Auth/Login.php b/app/Filament/Pages/Auth/Login.php index 8a72211..135dd92 100644 --- a/app/Filament/Pages/Auth/Login.php +++ b/app/Filament/Pages/Auth/Login.php @@ -93,12 +93,8 @@ public function authenticate(): ?LoginResponse } if ($user->is_active === IsActive::Inactive) { - SystemNotification::danger( - 'Akses Ditangguhkan โ›”', - 'Maaf, Anda tidak dapat masuk karena status akun saat ini sedang tidak aktif. Silakan hubungi Administrator untuk informasi lebih lanjut. ๐Ÿ˜ด', - 'Akses Akun Terbatas', - 'Akun Anda saat ini dalam status tidak aktif. Mohon hubungi pihak Administrator untuk klarifikasi lebih lanjut.' - )->send(); + SystemNotification::send('access_suspended', type: 'danger') + ->send(); throw ValidationException::withMessages([ 'login' => 'Akun Anda sedang dinonaktifkan.', @@ -145,24 +141,16 @@ public function authenticate(): ?LoginResponse session()->regenerate(); - SystemNotification::success( - 'Berhasil Masuk โœจ', - 'Selamat datang kembali, '.$user->name.'. Sesi Anda telah berhasil diaktifkan dengan aman. ๐Ÿ‘‹', - 'Otentikasi Berhasil', - 'Selamat datang, '.$user->name.'. Sesi autentikasi Anda telah berhasil dikonfirmasi oleh sistem.' - )->send(); + SystemNotification::send('login_success', ['name' => $user->name]) + ->send(); return app(LoginResponse::class); } protected function throwFailureValidationException(): never { - SystemNotification::danger( - 'Gagal Masuk ๐Ÿšซ', - 'Terjadi kendala saat proses masuk. Mohon periksa kembali alamat surel atau kata sandi Anda. ๐Ÿ˜Ÿ', - 'Otentikasi Gagal', - 'Upaya masuk gagal dilakukan. Mohon lakukan verifikasi kembali pada kredensial yang Anda masukkan.' - )->send(); + SystemNotification::send('login_failed', type: 'danger') + ->send(); throw ValidationException::withMessages([]); } diff --git a/app/Filament/Pages/Information/CourseSchedule/Index.php b/app/Filament/Pages/Information/CourseSchedule/Index.php index c5e0a45..e960f59 100644 --- a/app/Filament/Pages/Information/CourseSchedule/Index.php +++ b/app/Filament/Pages/Information/CourseSchedule/Index.php @@ -49,19 +49,19 @@ class Index extends Page implements HasActions, HasForms #[Computed] public function instructions(): string { - return SystemNotification::getMessage('Geser ke samping buat intip hari lainnya ya! ๐Ÿ“…โœจ', 'Geser ke samping untuk melihat hari lainnya.'); + return SystemNotification::getByKey('labels.course_schedule_hint'); } #[Computed] public function emptyHeading(): string { - return SystemNotification::getMessage('Yah, Belum Ada Jadwal Nih! ๐Ÿ“„๐Ÿ’ค', 'Tidak ada data yang ditemukan'); + return SystemNotification::getByKey('labels.empty_course_schedule.title'); } #[Computed] public function emptyDescription(): string { - return SystemNotification::getMessage('Belum ada jadwal perkuliahan yang terdaftar. Mungkin hari ini kamu bisa istirahat dulu? ๐Ÿ˜‰๐Ÿ’ค', 'Belum ada jadwal perkuliahan yang terdaftar untuk kriteria ini. Hubungi administrator jika jadwal Anda belum muncul.'); + return SystemNotification::getByKey('labels.empty_course_schedule.description'); } public ?string $search = ''; diff --git a/app/Filament/Pages/Learning/StudyGroup/Index.php b/app/Filament/Pages/Learning/StudyGroup/Index.php index 67a4122..08cd7e2 100644 --- a/app/Filament/Pages/Learning/StudyGroup/Index.php +++ b/app/Filament/Pages/Learning/StudyGroup/Index.php @@ -56,25 +56,25 @@ public static function getPagePermission(): string #[Computed] public function heading(): string { - return SystemNotification::getMessage('Daftar Grup Seru! ๐Ÿ’ƒ๐Ÿ•บ', 'Kelompok Belajar'); + return SystemNotification::getByKey('labels.study_group_list.title'); } #[Computed] public function description(): string { - return SystemNotification::getMessage('Lihat semua kelompok belajarmu di sini. Makin kompak makin asik! ๐Ÿค๐Ÿ“š', 'Daftar kelompok belajar Anda dan teman-teman sekelas.'); + return SystemNotification::getByKey('labels.study_group_list.description'); } #[Computed] public function emptyHeading(): string { - return SystemNotification::getMessage('Wah, Belum Ada Grup! ๐Ÿ‘ฏโ€โ™‚๏ธ๐ŸŒ€', 'Tidak ada data yang ditemukan'); + return SystemNotification::getByKey('labels.empty_study_group.title'); } #[Computed] public function emptyDescription(): string { - return SystemNotification::getMessage('Belum ada kelompok belajar yang terdaftar. Ayo ajak teman-temanmu bikin kelompok biar makin seru belajarnya! ๐Ÿค๐Ÿ“„', 'Belum ada kelompok belajar yang terdaftar untuk kriteria ini. Klik tombol tambah untuk memulai pembuatan kelompok.'); + return SystemNotification::getByKey('labels.empty_study_group.description'); } public ?int $course_id = null; diff --git a/app/Filament/Pages/Profile.php b/app/Filament/Pages/Profile.php index df6aacb..0c3b524 100644 --- a/app/Filament/Pages/Profile.php +++ b/app/Filament/Pages/Profile.php @@ -37,9 +37,9 @@ public function form(Schema $schema): Schema { return $schema ->components([ - Section::make(SystemNotification::getMessage('Akun Pengguna ๐Ÿ‘คโœจ', 'Akun')) - ->description(SystemNotification::getMessage('Kelola informasi detail akun Anda di sini ya biar nggak kudet! ๐Ÿ˜‰๐Ÿš€', 'Kelola informasi detail akun Anda agar selalu terkini.')) - ->icon(SystemNotification::getNotifStyle() === NotifStyle::Cheerful ? 'heroicon-o-face-smile' : 'heroicon-o-user') + Section::make(SystemNotification::getByKey('labels.user_account.title')) + ->description(SystemNotification::getByKey('labels.user_account.description')) + ->icon(SystemNotification::getByKey('icons.user_account')) ->schema([ Grid::make(2) ->schema([ @@ -67,9 +67,9 @@ public function form(Schema $schema): Schema ]), ]), - Section::make(SystemNotification::getMessage('Data Mahasiswa ๐ŸŽ“๐Ÿ“š', 'Informasi Mahasiswa')) - ->description(SystemNotification::getMessage('Pastikan data akademikmu sesuai dengan yang di sistem, jangan sampai salah loh! ๐Ÿค“๐Ÿ“', 'Pastikan data akademik Anda sesuai dengan record sistem.')) - ->icon(SystemNotification::getNotifStyle() === NotifStyle::Cheerful ? 'heroicon-o-academic-cap' : 'heroicon-o-identification') + Section::make(SystemNotification::getByKey('labels.student_data.title')) + ->description(SystemNotification::getByKey('labels.student_data.description_profile')) + ->icon(SystemNotification::getByKey('icons.student_data')) ->statePath('student') ->schema([ TextInput::make('full_name') @@ -135,9 +135,9 @@ public function form(Schema $schema): Schema ->columns(2) ->visible(fn () => auth()->user()?->student()->exists()), - Section::make(SystemNotification::getMessage('Keamanan Akun ๐Ÿ”โšก', 'Keamanan Akun')) - ->description(SystemNotification::getMessage('Rajin-rajin ganti password ya, biar akunmu aman dan nggak dibobol orang! ๐Ÿ•ต๏ธโ€โ™‚๏ธ๐Ÿ›ก๏ธ', 'Perbarui kata sandi Anda secara berkala untuk menjaga keamanan akun.')) - ->icon(SystemNotification::getNotifStyle() === NotifStyle::Cheerful ? 'heroicon-o-shield-check' : 'heroicon-o-lock-closed') + Section::make(SystemNotification::getByKey('labels.account_security.title')) + ->description(SystemNotification::getByKey('labels.account_security.description')) + ->icon(SystemNotification::getByKey('icons.account_security')) ->schema([ Grid::make(2) ->schema([ @@ -164,9 +164,9 @@ public function form(Schema $schema): Schema ]), ]), - Section::make(SystemNotification::getMessage('Pengaturan Tampilan & UX ๐ŸŽจโœจ', 'Preferensi Tampilan')) - ->description(SystemNotification::getMessage('Personalisasi pengalaman aplikasi Anda agar lebih nyaman dan sesuai selera! ๐ŸŒˆ๐Ÿš€', 'Sesuaikan gaya bahasa, warna tema, dan jenis huruf aplikasi Anda.')) - ->icon(SystemNotification::getNotifStyle() === NotifStyle::Cheerful ? 'heroicon-o-swatch' : 'heroicon-o-paint-brush') + Section::make(SystemNotification::getByKey('labels.appearance_settings.title')) + ->description(SystemNotification::getByKey('labels.appearance_settings.description')) + ->icon(SystemNotification::getByKey('icons.appearance_settings')) ->schema([ Grid::make(2) ->schema([ @@ -327,24 +327,16 @@ protected function handleRecordUpdate(Model $record, array $data): Model protected function afterSave(): void { - SystemNotification::success( - 'Profil Berhasil Diperbarui โœ…โœจ', - 'Data profil Anda telah berhasil disimpan dan diperbarui. Makin keren deh! ๐Ÿ˜Ž๐ŸŒˆ', - 'Pembaharuan Profil Berhasil', - 'Seluruh data profil Anda telah berhasil sinkronisasi dan disimpan dalam database.' - )->send(); + SystemNotification::send('profile_updated') + ->send(); if (filled($this->form->getState()['password'] ?? null)) { filament()->auth()->logout(); session()->invalidate(); session()->regenerateToken(); - SystemNotification::info( - 'Keamanan Akun Diperbarui ๐Ÿ”', - 'Anda telah mengubah kata sandi. Demi keamanan, silakan masuk kembali ya! ๐Ÿšช๐Ÿ”‘', - 'Pembaruan Kredensial', - 'Kata sandi Anda telah berhasil diubah. Harap lakukan otentikasi ulang untuk melanjutkan sesi.' - )->send(); + SystemNotification::send('account_security_updated', type: 'info') + ->send(); $this->redirect(filament()->getLoginUrl()); } else { diff --git a/app/Filament/Resources/Learning/Assignments/Actions/CopyAssignmentLinkAction.php b/app/Filament/Resources/Learning/Assignments/Actions/CopyAssignmentLinkAction.php index 32202cd..a5115be 100644 --- a/app/Filament/Resources/Learning/Assignments/Actions/CopyAssignmentLinkAction.php +++ b/app/Filament/Resources/Learning/Assignments/Actions/CopyAssignmentLinkAction.php @@ -36,12 +36,8 @@ protected function setUp(): void $livewire->js("if (navigator.clipboard) { navigator.clipboard.writeText('{$url}').catch(() => {}); }"); - SystemNotification::success( - 'Tautan Berhasil Disalin โœจ๐Ÿš€', - 'Tautan telah disalin ke clipboard dan siap untuk dibagikan. ๐Ÿ“‹', - 'Penyalinan Tautan Berhasil', - 'Tautan URL telah berhasil disalin ke papan klip sistem.' - )->send(); + SystemNotification::send('link_copied') + ->send(); }); } } diff --git a/app/Filament/Resources/Learning/Assignments/Actions/PinAction.php b/app/Filament/Resources/Learning/Assignments/Actions/PinAction.php index 6b77b09..d3f185a 100644 --- a/app/Filament/Resources/Learning/Assignments/Actions/PinAction.php +++ b/app/Filament/Resources/Learning/Assignments/Actions/PinAction.php @@ -41,24 +41,16 @@ protected function setUp(): void if ($existing) { $existing->delete(); - SystemNotification::success( - 'Pin Dilepas! Bye ๐Ÿ“Œ', - 'Pin pada tugas ini sukses dilepas dari daftar prioritas kamu. Semangat! ๐Ÿ‘‹', - 'Pembatalan Prioritas Berhasil', - 'Penanda prioritas pada tugas ini telah berhasil dihapus dari daftar akun Anda.' - )->send(); + SystemNotification::send('assignment_unpinned') + ->send(); } else { AssignmentPin::create([ 'student_id' => $studentProfile->id, 'assignment_id' => $assignmentId, ]); - SystemNotification::success( - 'Keren! Tugas Jadi Utama ๐Ÿ“', - 'Tugas ini sekarang nangkring di posisi teratas daftar prioritas kamu. Sikat! ๐Ÿš€', - 'Penandaan Prioritas Berhasil', - 'Tugas ini telah berhasil ditandai sebagai prioritas utama dalam daftar tugas Anda.' - )->send(); + SystemNotification::send('assignment_pinned') + ->send(); } unset($livewire->assignments, $livewire->pinnedIds); diff --git a/app/Filament/Resources/Learning/Assignments/Pages/ListAssignments.php b/app/Filament/Resources/Learning/Assignments/Pages/ListAssignments.php index f9955d6..0366ed7 100644 --- a/app/Filament/Resources/Learning/Assignments/Pages/ListAssignments.php +++ b/app/Filament/Resources/Learning/Assignments/Pages/ListAssignments.php @@ -93,13 +93,13 @@ protected function getHeaderActions(): array #[Computed] public function heading(): string { - return SystemNotification::getMessage('Daftar Tugas Bikin Lemes! ๐Ÿคฃ๐Ÿ“’', 'Tugas Saya'); + return SystemNotification::getByKey('labels.assignment_list.title'); } #[Computed] public function description(): string { - return SystemNotification::getMessage('Yuk, cek dan kumpulin tugasmu biar tenang hidupnya! Klik aja di tugasnya ya. ๐Ÿš€๐Ÿ‘จโ€๐Ÿ’ป', 'Klik pada tugas untuk melihat detail dan mengumpulkan file.'); + return SystemNotification::getByKey('labels.assignment_list.description'); } public function pinAction(): Action diff --git a/app/Filament/Resources/Learning/Assignments/Pages/SubmitAssignmentPage.php b/app/Filament/Resources/Learning/Assignments/Pages/SubmitAssignmentPage.php index 9c4b248..ea0947a 100644 --- a/app/Filament/Resources/Learning/Assignments/Pages/SubmitAssignmentPage.php +++ b/app/Filament/Resources/Learning/Assignments/Pages/SubmitAssignmentPage.php @@ -157,23 +157,15 @@ public function submit(): void $assignment = $this->record; if ($assignment->type === AssignmentType::Group && ! $this->currentGroup) { - SystemNotification::danger( - 'Gagal Mengumpulkan ๐Ÿšซ', - 'Anda tidak terdaftar dalam kelompok manapun yang ditugaskan untuk tugas ini. ๐Ÿ˜Ÿ', - 'Kesalahan Pengumpulan Tugas', - 'Data akun Anda tidak ditemukan dalam daftar kelompok yang ditugaskan untuk tugas ini.' - )->send(); + SystemNotification::send('submission_no_group', type: 'danger') + ->send(); return; } if (! $this->canSubmit) { - SystemNotification::danger( - 'Akses Ditolak ๐Ÿšซ', - 'Hanya ketua kelompok yang diizinkan untuk mengumpulkan atau memperbarui tugas kelompok. ๐Ÿ‘‘', - 'Batasan Otoritas Pengumpulan', - 'Hanya ketua kelompok yang memiliki otoritas untuk memperbarui atau mengumpulkan tugas kelompok.' - )->send(); + SystemNotification::send('submission_not_leader', type: 'danger') + ->send(); return; } @@ -181,12 +173,8 @@ public function submit(): void $existingSubmission = $this->existingSubmission; if (! $existingSubmission && ! $this->file) { - SystemNotification::warning( - 'Pilih File Dulu Dong! ๐Ÿ“', - 'Silakan pilih file untuk dikumpulkan agar sistem bisa menyimpannya ya! ๐Ÿ˜Š', - 'Kelengkapan Berkas Diperlukan', - 'Mohon sertakan lampiran berkas sebelum melanjutkan proses pengumpulan tugas.' - )->send(); + SystemNotification::send('submission_file_missing', type: 'warning') + ->send(); return; } @@ -216,12 +204,8 @@ public function submit(): void 'submitted_at' => now(), ]); - SystemNotification::success( - 'Keren! Tugas Sudah Update โœจ', - 'File tugas Anda telah berhasil diunggah ulang dan diperbarui di sistem. ๐Ÿ“ค', - 'Pembaruan Berkas Berhasil', - 'Berkas tugas telah berhasil diunggah ulang dan divalidasi oleh sistem.' - )->send(); + SystemNotification::send('submission_updated') + ->send(); } else { $submission = AssignmentSubmission::create([ 'assignment_id' => $assignment->id, @@ -235,12 +219,8 @@ public function submit(): void ->usingFileName($this->file->getClientOriginalName()) ->toMediaCollection('submission'); - SystemNotification::success( - 'Yeay! Tugas Terkumpul! ๐ŸŽ‰', - 'Berhasil! Tugas Anda telah tercatat dengan aman di sistem. Semangat! ๐ŸŽˆ', - 'Konfirmasi Pengumpulan Berhasil', - 'Seluruh berkas tugas Anda telah berhasil diverifikasi dan disimpan oleh sistem.' - )->send(); + SystemNotification::send('submission_success') + ->send(); } $this->file = null; diff --git a/app/Filament/Resources/Learning/Assignments/Schemas/AssignmentForm.php b/app/Filament/Resources/Learning/Assignments/Schemas/AssignmentForm.php index 5bee893..943a7d7 100644 --- a/app/Filament/Resources/Learning/Assignments/Schemas/AssignmentForm.php +++ b/app/Filament/Resources/Learning/Assignments/Schemas/AssignmentForm.php @@ -3,7 +3,6 @@ namespace App\Filament\Resources\Learning\Assignments\Schemas; use App\Enums\AssignmentType; -use App\Enums\NotifStyle; use App\Filament\Resources\Learning\Assignments\Actions\SelectAllStudentsAction; use App\Filament\Support\SystemNotification; use App\Models\Assignment; @@ -30,9 +29,9 @@ public static function configure(Schema $schema): Schema { return $schema ->components([ - Section::make(SystemNotification::getMessage('Informasi Tugas ๐Ÿ“โœจ', 'Informasi Tugas')) - ->description(SystemNotification::getMessage('Jelaskan tugasnya apa, kapan deadline-nya, dan buat sesi berapa. Semangat! ๐Ÿ’ช', 'Lengkapi informasi detail penugasan.')) - ->icon(SystemNotification::getNotifStyle() === NotifStyle::Cheerful ? 'heroicon-o-document-text' : 'heroicon-o-information-circle') + Section::make(SystemNotification::getByKey('labels.assignment_info.title')) + ->description(SystemNotification::getByKey('labels.assignment_info.description')) + ->icon(SystemNotification::getByKey('icons.assignment_info')) ->schema([ TextInput::make('title') @@ -128,9 +127,9 @@ public static function configure(Schema $schema): Schema ]) ->columns(2), - Section::make(SystemNotification::getMessage('Target Penugasan ๐ŸŽฏ๐Ÿง‘โ€๐ŸŽ“', 'Target Penugasan')) - ->description(SystemNotification::getMessage('Pilih siapa saja yang bakal ngerjain tugas ini. Jangan sampai salah sasaran ya! ๐Ÿน', 'Tentukan sasaran penerima penugasan ini.')) - ->icon(SystemNotification::getNotifStyle() === NotifStyle::Cheerful ? 'heroicon-o-users' : 'heroicon-o-user-group') + Section::make(SystemNotification::getByKey('labels.assignment_target.title')) + ->description(SystemNotification::getByKey('labels.assignment_target.description')) + ->icon(SystemNotification::getByKey('icons.assignment_target')) ->schema([ Select::make('student_ids') ->label('Mahasiswa') diff --git a/app/Filament/Resources/Learning/Attendances/Pages/ManageAttendances.php b/app/Filament/Resources/Learning/Attendances/Pages/ManageAttendances.php index 82ff0bd..872a342 100644 --- a/app/Filament/Resources/Learning/Attendances/Pages/ManageAttendances.php +++ b/app/Filament/Resources/Learning/Attendances/Pages/ManageAttendances.php @@ -38,37 +38,37 @@ class ManageAttendances extends Page implements HasForms, HasTable #[Computed] public function heading(): string { - return SystemNotification::getMessage('Ayo Presensi Dulu! ๐Ÿ™‹โ€โ™‚๏ธโœจ', 'Sesi Kuliah'); + return SystemNotification::getByKey('labels.attendance_section.title'); } #[Computed] public function description(): string { - return SystemNotification::getMessage('Jangan lupa absen ya kalau kelasnya udah mulai! Biar tercatat hadir. ๐Ÿ’ช', 'Silakan melakukan presensi sesuai dengan waktu kelas.'); + return SystemNotification::getByKey('labels.attendance_section.description'); } #[Computed] public function historyHeading(): string { - return SystemNotification::getMessage('Jejak Presensimu ๐Ÿ•ฐ๏ธ๐Ÿ“œ', 'Riwayat Presensi'); + return SystemNotification::getByKey('labels.attendance_history.title'); } #[Computed] public function historyDescription(): string { - return SystemNotification::getMessage('Di sini kamu bisa ngecek semua histori kehadiranmu sebelumnya. Rajin-rajin ya! ๐ŸŽ“', 'Berikut adalah riwayat kehadiran Anda pada sesi perkuliahan.'); + return SystemNotification::getByKey('labels.attendance_history.description'); } #[Computed] public function emptyHeading(): string { - return SystemNotification::getMessage('Yah, Absensi Belum Muncul! ๐Ÿ’โ€โ™‚๏ธ๐ŸŒ€', 'Tidak ada data yang ditemukan'); + return SystemNotification::getByKey('labels.empty_attendance.title'); } #[Computed] public function emptyDescription(): string { - return SystemNotification::getMessage('Sabar ya, setelah jadwal perkuliahan kamu muncul baru bisa diabsen di sini. Pantau terus jam kuliahnya! ๐Ÿ•’๐Ÿ’ช', 'Setelah jadwal Anda muncul, Anda dapat melakukan presensi di sini. Pastikan Anda mengecek kembali pada jam perkuliahan.'); + return SystemNotification::getByKey('labels.empty_attendance.description'); } public function getSchedules() @@ -187,12 +187,8 @@ public function attend(int $sessionId): void ->first(); if ($existing) { - SystemNotification::warning( - 'Presensi Sudah Tercatat โš ๏ธ', - 'Anda telah melakukan presensi untuk sesi perkuliahan ini. Jangan lupa belajar yang rajin ya! ๐Ÿ“šโœจ', - 'Pemberitahuan Presensi', - 'Status kehadiran Anda untuk sesi perkuliahan ini telah tercatat sebelumnya dalam sistem.' - )->send(); + SystemNotification::send('attendance_already_recorded', type: 'warning') + ->send(); return; } @@ -200,12 +196,8 @@ public function attend(int $sessionId): void // Check time $startTime = $session->start_time; if (now()->lessThan($startTime)) { - SystemNotification::warning( - 'Sabar Yaa! Belum Dibuka โณ', - 'Waktu presensi untuk sesi perkuliahan ini belum dimulai nih. Tunggu sebentar lagi, ya! โ˜•๐Ÿ˜Š', - 'Sesi Presensi Belum Dimulai', - 'Akses pengisian presensi untuk sesi ini belum diaktifkan sesuai dengan jadwal yang ditentukan.' - )->send(); + SystemNotification::send('attendance_not_started', type: 'warning') + ->send(); return; } @@ -223,12 +215,8 @@ public function attend(int $sessionId): void 'attended_at' => now(), ]); - SystemNotification::success( - 'Mantap! Presensi Berhasil โœจ๐Ÿš€', - 'Kehadiran Anda telah berhasil direkam. Semangat belajarnya hari ini! ๐Ÿ’ชโœ…', - 'Konfirmasi Presensi Berhasil', - 'Informasi kehadiran Anda telah berhasil diverifikasi dan disimpan secara resmi ke dalam sistem.' - )->send(); + SystemNotification::send('attendance_success') + ->send(); } public function table(Table $table): Table diff --git a/app/Filament/Resources/Learning/ClassSessions/Actions/CopyAttendanceLinkAction.php b/app/Filament/Resources/Learning/ClassSessions/Actions/CopyAttendanceLinkAction.php index 8b05678..2a451e1 100644 --- a/app/Filament/Resources/Learning/ClassSessions/Actions/CopyAttendanceLinkAction.php +++ b/app/Filament/Resources/Learning/ClassSessions/Actions/CopyAttendanceLinkAction.php @@ -30,12 +30,8 @@ protected function setUp(): void $livewire->js("if (navigator.clipboard) { navigator.clipboard.writeText('{$url}').catch(() => {}); }"); - SystemNotification::success( - 'Tautan Berhasil Disalin โœจ๐Ÿš€', - 'Tautan telah disalin ke clipboard dan siap untuk dibagikan. ๐Ÿ“‹', - 'Penyalinan Tautan Berhasil', - 'Tautan URL telah berhasil disalin ke papan klip sistem.' - )->send(); + SystemNotification::send('link_copied') + ->send(); }); } } diff --git a/app/Filament/Resources/Learning/ClassSessions/Actions/GenerateSessionsAction.php b/app/Filament/Resources/Learning/ClassSessions/Actions/GenerateSessionsAction.php index 2d7df20..3506a66 100644 --- a/app/Filament/Resources/Learning/ClassSessions/Actions/GenerateSessionsAction.php +++ b/app/Filament/Resources/Learning/ClassSessions/Actions/GenerateSessionsAction.php @@ -67,12 +67,8 @@ protected function setUp(): void $totalNewSessions = (int) ($data['total_sessions'] ?? 1); if (! $schedule) { - SystemNotification::danger( - 'Oops! Gagal Generate ๐Ÿšซ', - 'Jadwal belum ditentukan untuk mata kuliah ini, jadi sistem bingung mau buat sesi kapan. ๐Ÿ˜Ÿ', - 'Eksekusi Dibatalkan', - 'Penjadwalan resmi belum dikonfigurasi untuk mata kuliah ini. Proses pembuatan sesi otomatis tidak dapat dilanjutkan.' - )->send(); + SystemNotification::send('sessions_generated_failed', type: 'danger') + ->send(); return; } @@ -98,12 +94,11 @@ protected function setUp(): void ); } - SystemNotification::success( - 'Hore! Sesi Siap โœจ๐Ÿš€', - $totalNewSessions.' Sesi baru (No. '.$nextNumber.' sampai '.$maxNumber.') berhasil digenerate. ๐ŸŽ‰', - 'Verifikasi Sesi Berhasil', - 'Seluruh '.$totalNewSessions.' sesi pembelajaran tambahan telah berhasil dikonfigurasi secara otomatis.' - )->send(); + SystemNotification::send('sessions_generated_success', [ + 'count' => $totalNewSessions, + 'start' => $nextNumber, + 'end' => $maxNumber, + ])->send(); }); } } diff --git a/app/Filament/Resources/Master/Students/Actions/ChangePasswordAction.php b/app/Filament/Resources/Master/Students/Actions/ChangePasswordAction.php index 7c165e2..184cf98 100644 --- a/app/Filament/Resources/Master/Students/Actions/ChangePasswordAction.php +++ b/app/Filament/Resources/Master/Students/Actions/ChangePasswordAction.php @@ -33,12 +33,8 @@ protected function setUp(): void 'password' => Hash::make($data['password']), ]); - SystemNotification::success( - 'Aha! Kata Sandi Baru Berhasil ๐Ÿ”‘โœจ', - "Kata sandi untuk {$record->full_name} sudah update nih. Jangan lupa ingatkan mereka ya! ๐Ÿ˜‰", - 'Perubahan Kata Sandi Berhasil', - "Kredensial keamanan untuk mahasiswa {$record->full_name} telah diperbarui sesuai dengan entri sistem." - )->send(); + SystemNotification::send('password_changed', ['name' => $record->full_name]) + ->send(); }); } } diff --git a/app/Filament/Resources/Master/Students/Schemas/StudentForm.php b/app/Filament/Resources/Master/Students/Schemas/StudentForm.php index bd17c54..aead067 100644 --- a/app/Filament/Resources/Master/Students/Schemas/StudentForm.php +++ b/app/Filament/Resources/Master/Students/Schemas/StudentForm.php @@ -2,7 +2,6 @@ namespace App\Filament\Resources\Master\Students\Schemas; -use App\Enums\NotifStyle; use App\Enums\Sex; use App\Filament\Support\SystemNotification; use Carbon\Carbon; @@ -21,12 +20,9 @@ public static function configure(Schema $schema): Schema { return $schema ->components([ - Section::make(SystemNotification::getMessage('Kredensial Akun ๐Ÿ”‘โœจ', 'Akun')) - ->description(new HtmlString(SystemNotification::getMessage( - 'Pake email dan username ini buat login ya. Oh iya, password awalnya Minimal8@ ๐Ÿฅณ', - 'Alamat Surel dan Nama Pengguna akan digunakan untuk masuk ke dalam sistem. Kata sandi bawaan adalah Minimal8@' - ))) - ->icon(SystemNotification::getNotifStyle() === NotifStyle::Cheerful ? 'heroicon-o-key' : 'heroicon-o-user') + Section::make(SystemNotification::getByKey('labels.account_credentials.title')) + ->description(new HtmlString(SystemNotification::getByKey('labels.account_credentials.description'))) + ->icon(SystemNotification::getByKey('icons.account_credentials')) ->schema([ TextInput::make('email') ->label('Alamat Surel') @@ -50,9 +46,9 @@ public static function configure(Schema $schema): Schema ->columns(2) ->hiddenOn('edit'), - Section::make(SystemNotification::getMessage('Data Mahasiswa ๐ŸŽ“๐Ÿ“š', 'Informasi Mahasiswa')) - ->description(SystemNotification::getMessage('Lengkapi data mahasiswa di bawah ini dengan benar ya! ๐Ÿค“๐Ÿ“', 'Masukkan seluruh informasi akademik dan personal mahasiswa dengan benar.')) - ->icon(SystemNotification::getNotifStyle() === NotifStyle::Cheerful ? 'heroicon-o-academic-cap' : 'heroicon-o-identification') + Section::make(SystemNotification::getByKey('labels.student_data.title')) + ->description(SystemNotification::getByKey('labels.student_data.description')) + ->icon(SystemNotification::getByKey('icons.student_data')) ->schema([ TextInput::make('full_name') ->label('Nama Lengkap') diff --git a/app/Filament/Resources/Master/Students/Tables/StudentsTable.php b/app/Filament/Resources/Master/Students/Tables/StudentsTable.php index 2ac50d7..a671fb1 100644 --- a/app/Filament/Resources/Master/Students/Tables/StudentsTable.php +++ b/app/Filament/Resources/Master/Students/Tables/StudentsTable.php @@ -104,12 +104,8 @@ public static function configure(Table $table): Table ->delete(); } - SystemNotification::success( - $state ? 'Pengguna Diaktifkan! โœ…โœจ' : 'Pengguna Dinonaktifkan โ›”๐Ÿ‘‹', - $state ? 'Status akun pengguna berhasil diaktifkan kembali. Siap beraksi! ๐Ÿš€' : 'Status akun pengguna telah berhasil dinonaktifkan. Istirahat dulu ya... ๐Ÿ˜ด', - $state ? 'Aktivasi Akun Berhasil' : 'Penonaktifan Akun Berhasil', - $state ? 'Status akun pengguna terpilih telah diubah menjadi aktif.' : 'Status akun pengguna terpilih telah diubah menjadi tidak aktif.' - )->send(); + SystemNotification::send($state ? 'user_activated' : 'user_deactivated') + ->send(); }) ->visible(fn () => auth()->user()->hasRole([RoleEnum::Kosma, RoleEnum::Developer])), diff --git a/app/Filament/Support/SystemNotification.php b/app/Filament/Support/SystemNotification.php old mode 100644 new mode 100755 index b61a1be..ea1d1e5 --- a/app/Filament/Support/SystemNotification.php +++ b/app/Filament/Support/SystemNotification.php @@ -3,9 +3,7 @@ namespace App\Filament\Support; use App\Enums\NotifStyle; -use App\Models\User; use Filament\Notifications\Notification; -use Illuminate\Support\Facades\Auth; class SystemNotification { @@ -18,215 +16,110 @@ public static function make(): Notification } /** - * Notification for successful record creation. - */ - public static function create(): Notification - { - return self::success( - self::getMessage('Hore! Data Tersimpan ๐ŸŽ‰โœจ', 'Data Berhasil Disimpan'), - self::getMessage('Data baru berhasil ditambahkan! Sistem sudah menyimpannya dengan aman. ๐Ÿš€๐Ÿ’ช', 'Data baru telah berhasil ditambahkan ke dalam sistem.') - ); - } - - /** - * Notification for successful record update. - */ - public static function update(): Notification - { - return self::success( - self::getMessage('Mantap! Data Diperbarui โœ…๐Ÿ”ฅ', 'Perubahan Tersimpan'), - self::getMessage('Perubahan berhasil disimpan! Data sekarang sudah up-to-date dan segar lagi. โœจ๐Ÿ‘Œ', 'Perubahan pada data telah berhasil diperbarui dan disimpan.') - ); - } - - /** - * Notification for successful record deletion (soft delete). - */ - public static function delete(): Notification - { - return self::success( - self::getMessage('Oke, Data Dihapus ๐Ÿ—‘๏ธ๐Ÿ‘‹', 'Data Dihapus'), - self::getMessage('Data tersebut sudah berhasil dihapus dari sistem. Semuanya bersih dan rapi sekarang! ๐Ÿ˜Š๐Ÿšฎ', 'Data tersebut telah berhasil dihapus dari sistem aplikasi.') - ); - } - - /** - * Notification for successful permanent deletion. - */ - public static function forceDelete(): Notification - { - return self::success( - self::getMessage('Selamat Tinggal Selamanya ๐Ÿ‘‹๐Ÿ˜ข', 'Data Dihapus Permanen'), - self::getMessage('Data telah dihapus permanen dan tidak bisa kembali. Semoga ini keputusan yang tepat! ๐Ÿšฎ๐Ÿ’จ', 'Data tersebut telah dihapus secara permanen dari sistem.') - ); - } - - /** - * Notification for successful record restoration. - */ - public static function restore(): Notification - { - return self::success( - self::getMessage('Welcome Back! Data Pulih โ™ป๏ธโœจ', 'Data Berhasil Dipulihkan'), - self::getMessage('Data berhasil dikembalikan! Hati-hati ya, jangan sampai terhapus lagi. ๐Ÿ˜‰๐Ÿ‘', 'Data yang dihapus sebelumnya telah berhasil dipulihkan ke dalam sistem.') - ); - } - - /** - * Notification for successful status change/toggle. - */ - public static function statusUpdated(?string $title = null, ?string $body = null): Notification - { - return self::success( - $title ?? self::getMessage('Status Berubah! ๐Ÿ”„โœจ', 'Status Diperbarui'), - $body ?? self::getMessage('Status data berhasil diperbarui. Perubahan langsung aktif ya! ๐Ÿ‘', 'Status data telah berhasil diperbarui dan telah diterapkan.') - ); - } - - /** - * Notification for successful bulk deletion. - */ - public static function bulkDelete(): Notification - { - return self::success( - self::getMessage('Oke, Banyak Data Dihapus ๐Ÿ—‘๏ธ๐Ÿ‘‹', 'Data Berhasil Dihapus'), - self::getMessage('Semua data yang dipilih berhasil dihapus. Sistem makin lega deh! ๐Ÿ˜Š', 'Seluruh data yang dipilih telah berhasil dihapus dari sistem.') - ); - } - - /** - * Notification for successful bulk permanent deletion. - */ - public static function bulkForceDelete(): Notification - { - return self::success( - self::getMessage('Bye Bye Semua! ๐Ÿ‘‹๐Ÿ”ฅ', 'Data Dihapus Permanen'), - self::getMessage('Data yang dipilih sudah dihapus permanen. Bersih total! ๐Ÿงน๐Ÿ’จ', 'Data yang dipilih telah berhasil dihapus secara permanen.') - ); - } - - /** - * Notification for successful bulk restoration. - */ - public static function bulkRestore(): Notification - { - return self::success( - self::getMessage('Hore! Banyak Data Pulih โ™ป๏ธ๐ŸŽ‰', 'Data Berhasil Dipulihkan'), - self::getMessage('Data-data tersebut sudah kembali aktif. Selamat bekerja kembali! ๐Ÿ’ชโœจ', 'Seluruh data yang dipilih telah berhasil dikembalikan ke posisi semula.') - ); - } - - /** - * Success notification wrapper. - */ - public static function success(string $title, string $body, ?string $formalTitle = null, ?string $formalBody = null): Notification - { - $finalTitle = self::getMessage($title, $formalTitle ?? $title); - $finalBody = self::getMessage($body, $formalBody ?? $body); - - return self::applyStyle( - self::make() - ->title(self::clean($finalTitle)) - ->body(self::clean($finalBody)) - ->success(), - 'success' - ); - } - - /** - * Custom info notification. - */ - public static function info(string $title, string $body, ?string $formalTitle = null, ?string $formalBody = null): Notification - { - $finalTitle = self::getMessage($title, $formalTitle ?? $title); - $finalBody = self::getMessage($body, $formalBody ?? $body); - - return self::applyStyle( - self::make() - ->title(self::clean($finalTitle)) - ->body(self::clean($finalBody)) - ->info(), - 'info' - ); - } - - /** - * Custom warning notification. - */ - public static function warning(string $title, string $body, ?string $formalTitle = null, ?string $formalBody = null): Notification - { - $finalTitle = self::getMessage($title, $formalTitle ?? $title); - $finalBody = self::getMessage($body, $formalBody ?? $body); - - return self::applyStyle( - self::make() - ->title(self::clean($finalTitle)) - ->body(self::clean($finalBody)) - ->warning(), - 'warning' - ); - } - - /** - * Custom danger notification. - */ - public static function danger(string $title, string $body, ?string $formalTitle = null, ?string $formalBody = null): Notification - { - $finalTitle = self::getMessage($title, $formalTitle ?? $title); - $finalBody = self::getMessage($body, $formalBody ?? $body); - - return self::applyStyle( - self::make() - ->title(self::clean($finalTitle)) - ->body(self::clean($finalBody)) - ->danger(), - 'danger' - ); - } - - /** - * Apply the user's selected style to the notification. - */ - protected static function applyStyle(Notification $notification, string $status): Notification - { - $isCheerful = self::getNotifStyle() === NotifStyle::Cheerful; - - if ($isCheerful) { - $notification - ->duration(6000) - ->icon(match ($status) { - 'success' => 'heroicon-o-sparkles', - 'danger' => 'heroicon-o-fire', - 'warning' => 'heroicon-o-bolt', - 'info' => 'heroicon-o-megaphone', - default => null, - }); - } else { - $notification - ->icon(null) - ->duration(4000); - } - - return $notification; - } - - /** - * Get the current user's notification style preference. + * Get the current user's Notification style preference. */ public static function getNotifStyle(): NotifStyle { try { - /** @var User|null $user */ - $user = Auth::user(); - - return $user?->settings?->notif_style ?? NotifStyle::Cheerful; + return auth()->user()?->settings?->notif_style ?? NotifStyle::Cheerful; } catch (\Throwable $e) { return NotifStyle::Cheerful; } } + public static function create(): Notification + { + return self::make() + ->title(self::getByKey('create.title')) + ->body(self::getByKey('create.body')) + ->success(); + } + + public static function update(): Notification + { + return self::make() + ->title(self::getByKey('update.title')) + ->body(self::getByKey('update.body')) + ->success(); + } + + public static function delete(): Notification + { + return self::make() + ->title(self::getByKey('delete.title')) + ->body(self::getByKey('delete.body')) + ->success(); + } + + public static function forceDelete(): Notification + { + return self::make() + ->title(self::getByKey('force_delete.title')) + ->body(self::getByKey('force_delete.body')) + ->success(); + } + + public static function restore(): Notification + { + return self::make() + ->title(self::getByKey('restore.title')) + ->body(self::getByKey('restore.body')) + ->success(); + } + + public static function statusUpdated(?string $title = null, ?string $body = null): Notification + { + return self::make() + ->title($title ?? self::getByKey('status_updated.title')) + ->body($body ?? self::getByKey('status_updated.body')) + ->success(); + } + + public static function bulkDelete(): Notification + { + return self::make() + ->title(self::getByKey('bulk_delete.title')) + ->body(self::getByKey('bulk_delete.body')) + ->success(); + } + + public static function bulkForceDelete(): Notification + { + return self::make() + ->title(self::getByKey('bulk_force_delete.title')) + ->body(self::getByKey('bulk_force_delete.body')) + ->success(); + } + + public static function bulkRestore(): Notification + { + return self::make() + ->title(self::getByKey('bulk_restore.title')) + ->body(self::getByKey('bulk_restore.body')) + ->success(); + } + /** - * Get message based on the user's notification style preference. + * Send a notification by key. + */ + public static function send(string $key, array $replace = [], string $type = 'success'): Notification + { + $notification = self::make() + ->title(self::getByKey("$key.title", $replace)) + ->body(self::getByKey("$key.body", $replace)); + + return match ($type) { + 'info' => $notification->info(), + 'warning' => $notification->warning(), + 'danger' => $notification->danger(), + default => $notification->success(), + }; + } + + /** + * Get dynamic message based on UX style. + * + * @deprecated Use getByKey('key') for centralized messages. */ public static function getMessage(string $cheerful, string $formal): string { @@ -234,17 +127,12 @@ public static function getMessage(string $cheerful, string $formal): string } /** - * Strip emojis if the notification style is formal. + * Get translation by key and current user notification style. */ - public static function clean(string $text): string + public static function getByKey(string $key, array $replace = []): string { - if (self::getNotifStyle() === NotifStyle::Formal) { - // Comprehensive regex to remove emojis and symbols - $regex = '/[\x{1F600}-\x{1F64F}\x{1F300}-\x{1F5FF}\x{1F680}-\x{1F6FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{1F900}-\x{1F9FF}\x{1F1E0}-\x{1F1FF}]/u'; + $style = self::getNotifStyle()->value; - return trim(preg_replace($regex, '', $text)); - } - - return $text; + return __("notif.{$style}.{$key}", $replace); } } diff --git a/app/Filament/Widgets/SupportWidget.php b/app/Filament/Widgets/SupportWidget.php index b6510a1..322767e 100644 --- a/app/Filament/Widgets/SupportWidget.php +++ b/app/Filament/Widgets/SupportWidget.php @@ -15,6 +15,6 @@ class SupportWidget extends Widget public function getHeading(): string { - return SystemNotification::getMessage('Butuh Bantuan? Tanya Saja! ๐Ÿ’ฌโœจ', 'Informasi & Bantuan'); + return SystemNotification::getByKey('labels.help_center.title'); } } diff --git a/lang/id/notif.php b/lang/id/notif.php new file mode 100644 index 0000000..82fd635 --- /dev/null +++ b/lang/id/notif.php @@ -0,0 +1,414 @@ + [ + // Standard Actions + 'create' => [ + 'title' => 'Hore! Data Tersimpan ๐ŸŽ‰โœจ', + 'body' => 'Data baru berhasil ditambahkan! Sistem sudah menyimpannya dengan aman. ๐Ÿš€๐Ÿ’ช', + ], + 'update' => [ + 'title' => 'Mantap! Data Diperbarui โœ…๐Ÿ”ฅ', + 'body' => 'Perubahan berhasil disimpan! Data sekarang sudah up-to-date dan segar lagi. โœจ๐Ÿ‘Œ', + ], + 'delete' => [ + 'title' => 'Oke, Data Dihapus ๐Ÿ—‘๏ธ๐Ÿ‘‹', + 'body' => 'Data tersebut sudah berhasil dihapus dari sistem. Semuanya bersih dan rapi sekarang! ๐Ÿ˜Š๐Ÿšฎ', + ], + 'force_delete' => [ + 'title' => 'Selamat Tinggal Selamanya ๐Ÿ‘‹๐Ÿ˜ข', + 'body' => 'Data telah dihapus permanen dan tidak bisa kembali. Semoga ini keputusan yang tepat! ๐Ÿšฎ๐Ÿ’จ', + ], + 'restore' => [ + 'title' => 'Welcome Back! Data Pulih โ™ป๏ธโœจ', + 'body' => 'Data berhasil dikembalikan! Hati-hati ya, jangan sampai terhapus lagi. ๐Ÿ˜‰๐Ÿ‘', + ], + 'status_updated' => [ + 'title' => 'Status Berubah! ๐Ÿ”„โœจ', + 'body' => 'Status data berhasil diperbarui. Perubahan langsung aktif ya! ๐Ÿ‘', + ], + 'bulk_delete' => [ + 'title' => 'Oke, Banyak Data Dihapus ๐Ÿ—‘๏ธ๐Ÿ‘‹', + 'body' => 'Semua data yang dipilih berhasil dihapus. Sistem makin lega deh! ๐Ÿ˜Š', + ], + 'bulk_force_delete' => [ + 'title' => 'Bye Bye Semua! ๐Ÿ‘‹๐Ÿ”ฅ', + 'body' => 'Data yang dipilih sudah dihapus permanen. Bersih total! ๐Ÿงน๐Ÿ’จ', + ], + 'bulk_restore' => [ + 'title' => 'Hore! Banyak Data Pulih โ™ป๏ธ๐ŸŽ‰', + 'body' => 'Data-data tersebut sudah kembali aktif. Selamat bekerja kembali! ๐Ÿ’ชโœจ', + ], + + // Custom Messages + 'password_changed' => [ + 'title' => 'Password Berhasil Diganti ๐Ÿ”‘โœจ', + 'body' => 'Password untuk :name sudah diperbarui. Jangan sampai lupa lagi ya! ๐Ÿ˜‰๐Ÿ”', + ], + 'profile_updated' => [ + 'title' => 'Profil Kece Diperbarui! ๐Ÿ‘ค๐ŸŒˆ', + 'body' => 'Data profil kamu sudah berhasil disimpan. Tampil makin oke deh! ๐Ÿš€โœจ', + ], + 'account_security_updated' => [ + 'title' => 'Keamanan Akun Diperbarui ๐Ÿ”', + 'body' => 'Anda telah mengubah kata sandi. Demi keamanan, silakan masuk kembali ya! ๐Ÿšช๐Ÿ”‘', + ], + 'login_success' => [ + 'title' => 'Selamat Datang Kembali! ๐Ÿ‘‹โœจ', + 'body' => 'Senang melihatmu lagi, :name! Ayo lanjut belajar dan berkarya hari ini. ๐Ÿ’ช๐Ÿš€', + ], + 'login_failed' => [ + 'title' => 'Ups! Ada yang Salah ๐Ÿ™…โ€โ™‚๏ธโŒ', + 'body' => 'Email atau password kamu nggak pas nih. Coba dicek lagi ya, pelan-pelan saja! ๐Ÿ˜‰๐Ÿ”', + ], + 'access_suspended' => [ + 'title' => 'Akses Ditangguhkan โ›”', + 'body' => 'Maaf, Anda tidak dapat masuk karena status akun saat ini sedang tidak aktif. Silakan hubungi Administrator ya! ๐Ÿ˜ด', + ], + 'login_invalid' => [ + 'title' => 'Waduh! Gagal Masuk ๐Ÿ›‘โš ๏ธ', + 'body' => 'Ada masalah saat memproses login kamu. Coba lagi sebentar lagi ya! ๐Ÿ™๐ŸŒ€', + ], + 'assignment_pinned' => [ + 'title' => 'Tugas Disematkan! ๐Ÿ“Œโœจ', + 'body' => 'Tugas ini sekarang ada di paling atas biar gampang kamu pantau! ๐Ÿš€', + ], + 'assignment_unpinned' => [ + 'title' => 'Sematkan Dilepas ๐Ÿ“๐Ÿ‘‹', + 'body' => 'Tugas sudah kembali ke posisi semula di daftar. ๐Ÿ‘Œ', + ], + 'link_copied' => [ + 'title' => 'Link Berhasil Disalin! ๐Ÿ”—โœจ', + 'body' => 'Link tugas sudah tersimpan di clipboard kamu. Tinggal share deh! ๐Ÿš€๐Ÿ‘Œ', + ], + 'attendance_already_recorded' => [ + 'title' => 'Presensi Sudah Tercatat โš ๏ธ', + 'body' => 'Anda telah melakukan presensi untuk sesi perkuliahan ini. Jangan lupa belajar yang rajin ya! ๐Ÿ“šโœจ', + ], + 'attendance_not_started' => [ + 'title' => 'Sabar Yaa! Belum Dibuka โณ', + 'body' => 'Waktu presensi untuk sesi perkuliahan ini belum dimulai nih. Tunggu sebentar lagi, ya! โ˜•๐Ÿ˜Š', + ], + 'attendance_success' => [ + 'title' => 'Mantap! Presensi Berhasil โœจ๐Ÿš€', + 'body' => 'Kehadiran Anda telah berhasil direkam. Semangat belajarnya hari ini! ๐Ÿ’ชโœ…', + ], + 'sessions_generated_failed' => [ + 'title' => 'Oops! Gagal Generate ๐Ÿšซ', + 'body' => 'Jadwal belum ditentukan untuk mata kuliah ini, jadi sistem bingung mau buat sesi kapan. ๐Ÿ˜Ÿ', + ], + 'sessions_generated_success' => [ + 'title' => 'Hore! Sesi Siap โœจ๐Ÿš€', + 'body' => ':count Sesi baru (No. :start sampai :end) berhasil dibuat otomatis. ๐ŸŽ‰', + ], + 'submission_no_group' => [ + 'title' => 'Gagal Mengumpulkan ๐Ÿšซ', + 'body' => 'Anda tidak terdaftar dalam kelompok manapun yang ditugaskan untuk tugas ini. ๐Ÿ˜Ÿ', + ], + 'submission_not_leader' => [ + 'title' => 'Akses Ditolak ๐Ÿšซ', + 'body' => 'Hanya ketua kelompok yang diizinkan untuk mengumpulkan atau memperbarui tugas kelompok. ๐Ÿ‘‘', + ], + 'submission_file_missing' => [ + 'title' => 'Pilih File Dulu Dong! ๐Ÿ“', + 'body' => 'Silakan pilih file untuk dikumpulkan agar sistem bisa menyimpannya ya! ๐Ÿ˜Š', + ], + 'submission_updated' => [ + 'title' => 'Keren! Tugas Sudah Update โœจ', + 'body' => 'File tugas Anda telah berhasil diunggah ulang dan diperbarui di sistem. ๐Ÿ“ค', + ], + 'submission_success' => [ + 'title' => 'Yeay! Tugas Terkumpul! ๐ŸŽ‰', + 'body' => 'Berhasil! Tugas Anda telah tercatat dengan aman di sistem. Semangat! ๐ŸŽˆ', + ], + 'user_activated' => [ + 'title' => 'Pengguna Diaktifkan! โœ…โœจ', + 'body' => 'Status akun pengguna berhasil diaktifkan kembali. Siap beraksi! ๐Ÿš€', + ], + 'user_deactivated' => [ + 'title' => 'Pengguna Dinonaktifkan โ›”๐Ÿ‘‹', + 'body' => 'Status akun pengguna telah berhasil dinonaktifkan. Istirahat dulu ya... ๐Ÿ˜ด', + ], + + // UI Labels & Descriptions + 'labels' => [ + 'assignment_info' => [ + 'title' => 'Informasi Tugas ๐Ÿ“โœจ', + 'description' => 'Jelaskan tugasnya apa, kapan deadline-nya, dan buat sesi berapa. Semangat! ๐Ÿ’ช', + ], + 'assignment_target' => [ + 'title' => 'Target Penugasan ๐ŸŽฏ๐Ÿง‘โ€๐ŸŽ“', + 'description' => 'Pilih siapa saja yang bakal ngerjain tugas ini. Jangan sampai salah sasaran ya! ๐Ÿน', + ], + 'account_credentials' => [ + 'title' => 'Kredensial Akun ๐Ÿ”‘โœจ', + 'description' => 'Pake email dan username ini buat login ya. Oh iya, password awalnya Minimal8@ ๐Ÿฅณ', + ], + 'student_data' => [ + 'title' => 'Data Mahasiswa ๐ŸŽ“๐Ÿ“š', + 'description' => 'Lengkapi data mahasiswa di bawah ini dengan benar ya! ๐Ÿค“๐Ÿ“', + 'description_profile' => 'Pastikan data akademikmu sesuai dengan yang di sistem, jangan sampai salah loh! ๐Ÿค“๐Ÿ“', + ], + 'user_account' => [ + 'title' => 'Akun Pengguna ๐Ÿ‘คโœจ', + 'description' => 'Kelola informasi detail akun Anda di sini ya biar nggak kudet! ๐Ÿ˜‰๐Ÿš€', + ], + 'account_security' => [ + 'title' => 'Keamanan Akun ๐Ÿ”โšก', + 'description' => 'Rajin-rajin ganti password ya, biar akunmu aman dan nggak dibobol orang! ๐Ÿ•ต๏ธโ€โ™‚๏ธ๐Ÿ›ก๏ธ', + ], + 'appearance_settings' => [ + 'title' => 'Pengaturan Tampilan & UX ๐ŸŽจโœจ', + 'description' => 'Personalisasi pengalaman aplikasi Anda agar lebih nyaman dan sesuai selera! ๐ŸŒˆ๐Ÿš€', + ], + 'help_center' => [ + 'title' => 'Butuh Bantuan? Tanya Saja! ๐Ÿ’ฌโœจ', + ], + 'study_group_list' => [ + 'title' => 'Daftar Grup Seru! ๐Ÿ’ƒ๐Ÿ•บ', + 'description' => 'Lihat semua kelompok belajarmu di sini. Makin kompak makin asik! ๐Ÿค๐Ÿ“š', + ], + 'empty_study_group' => [ + 'title' => 'Wah, Belum Ada Grup! ๐Ÿ‘ฏโ€โ™‚๏ธ๐ŸŒ€', + 'description' => 'Belum ada kelompok belajar yang terdaftar. Ayo ajak teman-temanmu bikin kelompok biar makin seru belajarnya! ๐Ÿค๐Ÿ“„', + ], + 'course_schedule_hint' => 'Geser ke samping buat intip hari lainnya ya! ๐Ÿ“…โœจ', + 'empty_course_schedule' => [ + 'title' => 'Yah, Belum Ada Jadwal Nih! ๐Ÿ“„๐Ÿ’ค', + 'description' => 'Belum ada jadwal perkuliahan yang terdaftar. Mungkin hari ini kamu bisa istirahat dulu? ๐Ÿ˜‰๐Ÿ’ค', + ], + 'attendance_section' => [ + 'title' => 'Ayo Presensi Dulu! ๐Ÿ™‹โ€โ™‚๏ธโœจ', + 'description' => 'Jangan lupa absen ya kalau kelasnya udah mulai! Biar tercatat hadir. ๐Ÿ’ช', + ], + 'attendance_history' => [ + 'title' => 'Jejak Presensimu ๐Ÿ•ฐ๏ธ๐Ÿ“œ', + 'description' => 'Di sini kamu bisa ngecek semua histori kehadiranmu sebelumnya. Rajin-rajin ya! ๐ŸŽ“', + ], + 'empty_attendance' => [ + 'title' => 'Yah, Absensi Belum Muncul! ๐Ÿ’โ€โ™‚๏ธ๐ŸŒ€', + 'description' => 'Sabar ya, setelah jadwal perkuliahan kamu muncul baru bisa diabsen di sini. Pantau terus jam kuliahnya! ๐Ÿ•’๐Ÿ’ช', + ], + 'assignment_list' => [ + 'title' => 'Daftar Tugas Bikin Lemes! ๐Ÿคฃ๐Ÿ“’', + 'description' => 'Yuk, cek dan kumpulin tugasmu biar tenang hidupnya! Klik aja di tugasnya ya. ๐Ÿš€๐Ÿ‘จโ€๐Ÿ’ป', + ], + ], + + // Icons + 'icons' => [ + 'assignment_info' => 'heroicon-o-document-text', + 'assignment_target' => 'heroicon-o-users', + 'account_credentials' => 'heroicon-o-key', + 'student_data' => 'heroicon-o-academic-cap', + 'user_account' => 'heroicon-o-face-smile', + 'account_security' => 'heroicon-o-shield-check', + 'appearance_settings' => 'heroicon-o-swatch', + ], + ], + 'formal' => [ + // Standard Actions + 'create' => [ + 'title' => 'Data Berhasil Disimpan', + 'body' => 'Data baru telah berhasil ditambahkan ke dalam sistem.', + ], + 'update' => [ + 'title' => 'Perubahan Tersimpan', + 'body' => 'Perubahan pada data telah berhasil diperbarui dan disimpan.', + ], + 'delete' => [ + 'title' => 'Data Dihapus', + 'body' => 'Data tersebut telah berhasil dihapus dari sistem aplikasi.', + ], + 'force_delete' => [ + 'title' => 'Data Dihapus Permanen', + 'body' => 'Data tersebut telah dihapus secara permanen dari sistem.', + ], + 'restore' => [ + 'title' => 'Data Berhasil Dipulihkan', + 'body' => 'Data yang dihapus sebelumnya telah berhasil dipulihkan ke dalam sistem.', + ], + 'status_updated' => [ + 'title' => 'Status Diperbarui', + 'body' => 'Status data telah berhasil diperbarui dan telah diterapkan.', + ], + 'bulk_delete' => [ + 'title' => 'Data Berhasil Dihapus', + 'body' => 'Seluruh data yang dipilih telah berhasil dihapus dari sistem.', + ], + 'bulk_force_delete' => [ + 'title' => 'Data Dihapus Permanen', + 'body' => 'Data yang dipilih telah berhasil dihapus secara permanen.', + ], + 'bulk_restore' => [ + 'title' => 'Data Berhasil Dipulihkan', + 'body' => 'Seluruh data yang dipilih telah berhasil dikembalikan ke posisi semula.', + ], + + // Custom Messages + 'password_changed' => [ + 'title' => 'Kata Sandi Berhasil Diperbarui', + 'body' => 'Kata sandi untuk :name telah berhasil diperbarui di dalam sistem.', + ], + 'profile_updated' => [ + 'title' => 'Profil Berhasil Diperbarui', + 'body' => 'Perubahan pada informasi profil Anda telah berhasil disimpan.', + ], + 'account_security_updated' => [ + 'title' => 'Pembaruan Kredensial', + 'body' => 'Kata sandi Anda telah berhasil diubah. Harap lakukan otentikasi ulang untuk melanjutkan sesi.', + ], + 'login_success' => [ + 'title' => 'Otentikasi Berhasil', + 'body' => 'Selamat datang kembali, :name. Anda telah berhasil masuk ke dalam sistem.', + ], + 'login_failed' => [ + 'title' => 'Otentikasi Gagal', + 'body' => 'Email atau kata sandi yang Anda masukkan tidak sesuai dengan record kami.', + ], + 'access_suspended' => [ + 'title' => 'Akses Akun Terbatas', + 'body' => 'Akun Anda saat ini dalam status tidak aktif. Mohon hubungi pihak Administrator untuk klarifikasi lebih lanjut.', + ], + 'login_invalid' => [ + 'title' => 'Kesalahan Sistem', + 'body' => 'Terjadi kesalahan saat memproses permintaan masuk Anda. Silakan coba lagi.', + ], + 'assignment_pinned' => [ + 'title' => 'Tugas Disematkan', + 'body' => 'Tugas telah berhasil disematkan ke bagian atas daftar penugasan.', + ], + 'assignment_unpinned' => [ + 'title' => 'Sematkan Dilepas', + 'body' => 'Status sematan pada tugas ini telah berhasil dilepaskan.', + ], + 'link_copied' => [ + 'title' => 'Tautan Berhasil Disalin', + 'body' => 'Tautan tugas telah disalin ke papan klip perangkat Anda.', + ], + 'attendance_already_recorded' => [ + 'title' => 'Pemberitahuan Presensi', + 'body' => 'Status kehadiran Anda untuk sesi perkuliahan ini telah tercatat sebelumnya dalam sistem.', + ], + 'attendance_not_started' => [ + 'title' => 'Sesi Presensi Belum Dimulai', + 'body' => 'Akses pengisian presensi untuk sesi ini belum diaktifkan sesuai dengan jadwal yang ditentukan.', + ], + 'attendance_success' => [ + 'title' => 'Konfirmasi Presensi Berhasil', + 'body' => 'Informasi kehadiran Anda telah berhasil diverifikasi dan disimpan secara resmi ke dalam sistem.', + ], + 'sessions_generated_failed' => [ + 'title' => 'Eksekusi Dibatalkan', + 'body' => 'Penjadwalan resmi belum dikonfigurasi untuk mata kuliah ini. Proses pembuatan sesi otomatis tidak dapat dilanjutkan.', + ], + 'sessions_generated_success' => [ + 'title' => 'Verifikasi Sesi Berhasil', + 'body' => 'Seluruh :count sesi pembelajaran tambahan (No. :start sampai :end) telah berhasil dikonfigurasi secara otomatis.', + ], + 'submission_no_group' => [ + 'title' => 'Kesalahan Pengumpulan Tugas', + 'body' => 'Data akun Anda tidak ditemukan dalam daftar kelompok yang ditugaskan untuk tugas ini.', + ], + 'submission_not_leader' => [ + 'title' => 'Batasan Otoritas Pengumpulan', + 'body' => 'Hanya ketua kelompok yang memiliki otoritas untuk memperbarui atau mengumpulkan tugas kelompok.', + ], + 'submission_file_missing' => [ + 'title' => 'Kelengkapan Berkas Diperlukan', + 'body' => 'Mohon sertakan lampiran berkas sebelum melanjutkan proses pengumpulan tugas.', + ], + 'submission_updated' => [ + 'title' => 'Pembaruan Berkas Berhasil', + 'body' => 'Berkas tugas telah berhasil diunggah ulang dan divalidasi oleh sistem.', + ], + 'submission_success' => [ + 'title' => 'Konfirmasi Pengumpulan Berhasil', + 'body' => 'Seluruh berkas tugas Anda telah berhasil diverifikasi dan disimpan oleh sistem.', + ], + 'user_activated' => [ + 'title' => 'Aktivasi Akun Berhasil', + 'body' => 'Status akun pengguna terpilih telah diubah menjadi aktif.', + ], + 'user_deactivated' => [ + 'title' => 'Penonaktifan Akun Berhasil', + 'body' => 'Status akun pengguna terpilih telah diubah menjadi tidak aktif.', + ], + + // UI Labels & Descriptions + 'labels' => [ + 'assignment_info' => [ + 'title' => 'Informasi Tugas', + 'description' => 'Lengkapi informasi detail penugasan.', + ], + 'assignment_target' => [ + 'title' => 'Target Penugasan', + 'description' => 'Tentukan sasaran penerima penugasan ini.', + ], + 'account_credentials' => [ + 'title' => 'Akun', + 'description' => 'Alamat Surel dan Nama Pengguna akan digunakan untuk masuk ke dalam sistem. Kata sandi bawaan adalah Minimal8@', + ], + 'student_data' => [ + 'title' => 'Informasi Mahasiswa', + 'description' => 'Masukkan seluruh informasi akademik dan personal mahasiswa dengan benar.', + 'description_profile' => 'Pastikan data akademik Anda sesuai dengan record sistem.', + ], + 'user_account' => [ + 'title' => 'Akun', + 'description' => 'Kelola informasi detail akun Anda agar selalu terkini.', + ], + 'account_security' => [ + 'title' => 'Keamanan Akun', + 'description' => 'Perbarui kata sandi Anda secara berkala untuk menjaga keamanan akun.', + ], + 'appearance_settings' => [ + 'title' => 'Preferensi Tampilan', + 'description' => 'Sesuaikan gaya bahasa, warna tema, dan jenis huruf aplikasi Anda.', + ], + 'help_center' => [ + 'title' => 'Informasi & Bantuan', + ], + 'study_group_list' => [ + 'title' => 'Kelompok Belajar', + 'description' => 'Daftar kelompok belajar Anda dan teman-teman sekelas.', + ], + 'empty_study_group' => [ + 'title' => 'Tidak ada data yang ditemukan', + 'description' => 'Belum ada kelompok belajar yang terdaftar untuk kriteria ini. Klik tombol tambah untuk memulai pembuatan kelompok.', + ], + 'course_schedule_hint' => 'Geser ke samping untuk melihat hari lainnya.', + 'empty_course_schedule' => [ + 'title' => 'Tidak ada data yang ditemukan', + 'description' => 'Belum ada jadwal perkuliahan yang terdaftar untuk kriteria ini. Hubungi administrator jika jadwal Anda belum muncul.', + ], + 'attendance_section' => [ + 'title' => 'Sesi Kuliah', + 'description' => 'Silakan melakukan presensi sesuai dengan waktu kelas.', + ], + 'attendance_history' => [ + 'title' => 'Riwayat Presensi', + 'description' => 'Berikut adalah riwayat kehadiran Anda pada sesi perkuliahan.', + ], + 'empty_attendance' => [ + 'title' => 'Tidak ada data yang ditemukan', + 'description' => 'Setelah jadwal Anda muncul, Anda dapat melakukan presensi di sini. Pastikan Anda mengecek kembali pada jam perkuliahan.', + ], + 'assignment_list' => [ + 'title' => 'Tugas Saya', + 'description' => 'Klik pada tugas untuk melihat detail dan mengumpulkan file.', + ], + ], + + // Icons + 'icons' => [ + 'assignment_info' => 'heroicon-o-information-circle', + 'assignment_target' => 'heroicon-o-user-group', + 'account_credentials' => 'heroicon-o-user', + 'student_data' => 'heroicon-o-identification', + 'user_account' => 'heroicon-o-user', + 'account_security' => 'heroicon-o-lock-closed', + 'appearance_settings' => 'heroicon-o-paint-brush', + ], + ], +];