diff --git a/.gitignore b/.gitignore index c73ec7a..6e19222 100644 --- a/.gitignore +++ b/.gitignore @@ -86,7 +86,10 @@ phpunit vendor/ # uploads -public/uploads +public/uploads/* +!public/uploads/index.html +!public/uploads/logo/index.html +!public/uploads/tmp/index.html #------------------------- # IDE / Development Files diff --git a/README.md b/README.md index d6a047b..e9ead2f 100644 --- a/README.md +++ b/README.md @@ -130,19 +130,9 @@ Aplikasi Web Sistem Absensi Sekolah Berbasis QR Code adalah sebuah proyek yang b > > - Konfigurasi file `.env` untuk mengatur base url(terutama jika melakukan hosting), koneksi database dan pengaturan lainnya sesuai dengan lingkungan pengembangan Anda. > -> - Untuk mengubah konfigurasi nama sekolah, tahun ajaran dll, buka file konfigurasi `app/Config/AbsensiSekolah.php` dan ubah pada: -> -> ```php -> // NAMA SEKOLAH -> const SCHOOL_NAME = 'SMK 1 Indonesia'; -> -> // TAHUN AJARAN -> const SCHOOL_YEAR = '2024/2025'; -> -> // ... -> ``` +> - Untuk mengubah konfigurasi nama sekolah, tahun ajaran logo sekolah dll sudah disediakan pengaturan di admin panel. > -> - Ganti/replace logo sekolah di `public/assets/img/logo_sekolah.jpg`. +> - Logo Sekolah Rekomendasi 100x100px atau 1:1 dan berformat PNG/JPG. > > - Jika ingin mengubah email, username & password dari superadmin, buka file `app\Database\Migrations\2023-08-18-000004_AddSuperadmin.php` lalu ubah & sesuaikan kode berikut: > @@ -157,7 +147,7 @@ Aplikasi Web Sistem Absensi Sekolah Berbasis QR Code adalah sebuah proyek yang b Dengan aplikasi web sistem absensi sekolah berbasis QR code ini, diharapkan proses absensi di sekolah menjadi lebih efisien dan terotomatisasi. Proyek ini dapat diadaptasi dan dikembangkan lebih lanjut sesuai dengan kebutuhan dan persyaratan sekolah Anda. -Jangan lupa beri star ya...⭐ +Jangan lupa beri star ya...⭐⭐⭐ ## Contributing diff --git a/app/Common.php b/app/Common.php index 23e3e61..e1fbe6c 100644 --- a/app/Common.php +++ b/app/Common.php @@ -13,3 +13,251 @@ * * @see: https://codeigniter4.github.io/CodeIgniter4/ */ + + +//clean string +if (!function_exists('cleanStr')) { + function cleanStr($str) + { + $str = strTrim($str); + $str = removeSpecialCharacters($str); + return esc($str); + } +} + +//clean number +if (!function_exists('cleanNumber')) { + function cleanNumber($num) + { + $num = strTrim($num); + $num = esc($num); + if (empty($num)) { + return 0; + } + return intval($num); + } +} + +//clean number +if (!function_exists('clrQuotes')) { + function clrQuotes($str) + { + $str = strReplace('"', '', $str); + $str = strReplace("'", '', $str); + return $str; + } +} + +/** + * Get validation rules + * + * @return Rules + */ +if (!function_exists('getValRules')) { + function getValRules($val) + { + $rules = $val->getRules(); + $newRules = array(); + if (!empty($rules)) { + foreach ($rules as $key => $rule) { + $newRules[$key] = [ + 'label' => $rule['label'], + 'rules' => $rule['rules'], + 'errors' => [ + 'required' => lang("Validation.form_validation_required"), + 'min_length' => lang("Validation.form_validation_min_length"), + 'max_length' => lang("Validation.form_validation_max_length"), + 'matches' => lang("Validation.form_validation_matches"), + 'is_unique' => lang("Validation.form_validation_is_unique") + ] + ]; + } + } + return $newRules; + } +} + +/** + * STR TRIM + * + * TRIM string + * + * @return string + */ +if (!function_exists('strTrim')) { + function strTrim($str) + { + if (!empty($str)) { + return trim($str); + } + } +} + +/** + * STR Replace + * + * Replace string + * + * @return string + */ +if (!function_exists('strReplace')) { + function strReplace($search, $replace, $str) + { + if (!empty($str)) { + return str_replace($search, $replace, $str); + } + } +} + +/** + * POST Request + * + * Sanitaze Input Post + * + * @return string + */ +if (!function_exists('inputPost')) { + function inputPost($input_name, $removeForbidden = false) + { + $input = \Config\Services::request()->getPost($input_name); + if (!is_array($input)) { + $input = strTrim($input); + } + if ($removeForbidden) { + $input = removeForbiddenCharacters($input); + } + return $input; + } +} + +/** + * GET Request + * + * Sanitaze Input GET + * + * @return string + */ +if (!function_exists('inputGet')) { + function inputGet($input_name, $removeForbidden = false) + { + $input = \Config\Services::request()->getGet($input_name); + if (!is_array($input)) { + $input = strTrim($input); + } + if ($removeForbidden) { + $input = removeForbiddenCharacters($input); + } + return $input; + } +} + +/** + * remove forbidden characters + * + * + * @return string + */ +if (!function_exists('removeForbiddenCharacters')) { + function removeForbiddenCharacters($str) + { + $str = strTrim($str); + $str = strReplace(';', '', $str); + $str = strReplace('"', '', $str); + $str = strReplace('$', '', $str); + $str = strReplace('%', '', $str); + $str = strReplace('*', '', $str); + $str = strReplace('/', '', $str); + $str = strReplace('\'', '', $str); + $str = strReplace('<', '', $str); + $str = strReplace('>', '', $str); + $str = strReplace('=', '', $str); + $str = strReplace('?', '', $str); + $str = strReplace('[', '', $str); + $str = strReplace(']', '', $str); + $str = strReplace('\\', '', $str); + $str = strReplace('^', '', $str); + $str = strReplace('`', '', $str); + $str = strReplace('{', '', $str); + $str = strReplace('}', '', $str); + $str = strReplace('|', '', $str); + $str = strReplace('~', '', $str); + $str = strReplace('+', '', $str); + return $str; + } +} + +/** + * remove special characters + * + * + * @return string + */ +if (!function_exists('removeSpecialCharacters')) { + function removeSpecialCharacters($str, $removeQuotes = false) + { + $str = removeForbiddenCharacters($str); + $str = strReplace('#', '', $str); + $str = strReplace('!', '', $str); + $str = strReplace('(', '', $str); + $str = strReplace(')', '', $str); + if ($removeQuotes) { + $str = clrQuotes($str); + } + return $str; + } +} + +/** + * Get Logo + * + * @return string + */ +if (!function_exists('getLogo')) { + function getLogo() + { + $schoolConfigurations = new \Config\School(); + $generalSettings = $schoolConfigurations::$generalSettings; + if (!empty($generalSettings)) { + if (!empty($generalSettings->logo) && file_exists(FCPATH . $generalSettings->logo)) { + return base_url($generalSettings->logo); + } + return base_url("assets/img/logo_sekolah.jpg"); + } + return base_url("assets/img/logo_sekolah.jpg"); + } +} + +/** + * Invalid Feedback + * + * @return + */ +if (!function_exists('invalidFeedback')) { + function invalidFeedback($input) + { + $session = session(); + if ($session->getFlashdata('errors')) { + $errors = $session->getFlashdata('errors'); + if (!empty($errors[$input])) { + return esc($errors[$input]); + } + + return null; + } + + return null; + } +} + +//generate unique id +if (!function_exists('generateToken')) { + function generateToken($short = false) + { + $token = uniqid('', true); + $token = strReplace('.', '-', $token); + if ($short == false) { + $token = $token . '-' . rand(10000000, 99999999); + } + return $token; + } +} diff --git a/app/Config/AbsensiSekolah.php b/app/Config/AbsensiSekolah.php deleted file mode 100644 index 3084245..0000000 --- a/app/Config/AbsensiSekolah.php +++ /dev/null @@ -1,26 +0,0 @@ - */ - public $classmap = []; + public $classmap = [ + 'School' => APPPATH . 'Config/School.php' + ]; /** * ------------------------------------------------------------------- diff --git a/app/Config/Routes.php b/app/Config/Routes.php index ab7ad67..79a4920 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -120,6 +120,12 @@ $routes->post('petugas/edit', 'Admin\DataPetugas::updatePetugas'); // superadmin hapus data petugas $routes->delete('petugas/delete/(:any)', 'Admin\DataPetugas::delete/$1'); + + // Settings + $routes->group('general-settings', ['namespace' => 'App\Controllers\Admin'], function ($routes) { + $routes->get('/', 'GeneralSettings::index'); + $routes->post('update', 'GeneralSettings::generalSettingsPost'); + }); }); diff --git a/app/Config/School.php b/app/Config/School.php new file mode 100644 index 0000000..f24670d --- /dev/null +++ b/app/Config/School.php @@ -0,0 +1,26 @@ +db = \Config\Database::connect(); + $this->setGlobalConfigurations(); + } + + private function setGlobalConfigurations() + { + // Get General Settings + self::$generalSettings = $this->db->table('general_settings')->where('id', 1)->get()->getRow(); + } +} diff --git a/app/Controllers/Admin/Dashboard.php b/app/Controllers/Admin/Dashboard.php index fce3f89..ac6d938 100644 --- a/app/Controllers/Admin/Dashboard.php +++ b/app/Controllers/Admin/Dashboard.php @@ -25,8 +25,6 @@ class Dashboard extends BaseController protected PetugasModel $petugasModel; - protected string $namaSekolah; - public function __construct() { $this->siswaModel = new SiswaModel(); @@ -35,7 +33,6 @@ public function __construct() $this->presensiSiswaModel = new PresensiSiswaModel(); $this->presensiGuruModel = new PresensiGuruModel(); $this->petugasModel = new PetugasModel(); - $this->namaSekolah = ConfigAbsensiSekolah::SCHOOL_NAME; } public function index() @@ -101,8 +98,6 @@ public function index() ], 'petugas' => $this->petugasModel->getAllPetugas(), - - 'namaSekolah' => $this->namaSekolah, ]; return view('admin/dashboard', $data); diff --git a/app/Controllers/Admin/GeneralSettings.php b/app/Controllers/Admin/GeneralSettings.php new file mode 100644 index 0000000..f4d3d02 --- /dev/null +++ b/app/Controllers/Admin/GeneralSettings.php @@ -0,0 +1,45 @@ +generalSettingsModel = new GeneralSettingsModel(); + } + + public function index() + { + $data['title'] = 'Pengaturan Utama'; + $data['ctx'] = 'general_settings'; + + return view('admin/general-settings/index', $data); + } + + public function generalSettingsPost() + { + $val = \Config\Services::validation(); + $val->setRule('school_name', 'Nama Sekolah', 'required|max_length[200]'); + $val->setRule('school_year', 'Tahun Ajaran', 'required|max_length[200]'); + $val->setRule('copyright', 'copyright', 'max_length[200]'); + + if (!$this->validate(getValRules($val))) { + $this->session->setFlashdata('errors', $val->getErrors()); + return redirect()->to('admin/general-settings')->withInput(); + } else { + if ($this->generalSettingsModel->updateSettings()) { + $this->session->setFlashdata('success', 'Data berhasil diubah'); + } else { + $this->session->setFlashdata('error', 'Error data!'); + } + } + return redirect()->to('admin/general-settings'); + } +} diff --git a/app/Controllers/Admin/GenerateLaporan.php b/app/Controllers/Admin/GenerateLaporan.php index 3e32fd8..e7e0395 100644 --- a/app/Controllers/Admin/GenerateLaporan.php +++ b/app/Controllers/Admin/GenerateLaporan.php @@ -13,7 +13,6 @@ use App\Models\PresensiGuruModel; use App\Models\SiswaModel; use App\Models\PresensiSiswaModel; -use Config\AbsensiSekolah as ConfigAbsensiSekolah; class GenerateLaporan extends BaseController { @@ -25,9 +24,6 @@ class GenerateLaporan extends BaseController protected PresensiSiswaModel $presensiSiswaModel; protected PresensiGuruModel $presensiGuruModel; - protected string $namaSekolah; - protected string $tahunAjaran; - public function __construct() { $this->siswaModel = new SiswaModel(); @@ -37,9 +33,6 @@ public function __construct() $this->presensiSiswaModel = new PresensiSiswaModel(); $this->presensiGuruModel = new PresensiGuruModel(); - - $this->namaSekolah = ConfigAbsensiSekolah::SCHOOL_NAME; - $this->tahunAjaran = ConfigAbsensiSekolah::SCHOOL_YEAR; } public function index() @@ -130,8 +123,6 @@ public function generateLaporanSiswa() ], 'kelas' => $kelas, 'grup' => "kelas " . $kelas['kelas'] . " " . $kelas['jurusan'], - 'namaSekolah' => $this->namaSekolah, - 'tahunAjaran' => $this->tahunAjaran ]; if ($type == 'doc') { @@ -207,8 +198,6 @@ public function generateLaporanGuru() 'perempuan' => count($guru) - $laki ], 'grup' => 'guru', - 'namaSekolah' => $this->namaSekolah, - 'tahunAjaran' => $this->tahunAjaran ]; if ($type == 'doc') { diff --git a/app/Controllers/Admin/JurusanController.php b/app/Controllers/Admin/JurusanController.php index 4bdedc8..286c024 100644 --- a/app/Controllers/Admin/JurusanController.php +++ b/app/Controllers/Admin/JurusanController.php @@ -5,8 +5,9 @@ use App\Models\JurusanModel; use CodeIgniter\Exceptions\PageNotFoundException; use CodeIgniter\RESTful\ResourceController; +use App\Controllers\BaseController; -class JurusanController extends ResourceController +class JurusanController extends BaseController { protected JurusanModel $jurusanModel; diff --git a/app/Controllers/Admin/KelasController.php b/app/Controllers/Admin/KelasController.php index 52740dd..4d8096c 100644 --- a/app/Controllers/Admin/KelasController.php +++ b/app/Controllers/Admin/KelasController.php @@ -5,14 +5,16 @@ use App\Models\JurusanModel; use App\Models\KelasModel; use CodeIgniter\Exceptions\PageNotFoundException; -use CodeIgniter\RESTful\ResourceController; +use App\Controllers\BaseController; -class KelasController extends ResourceController +class KelasController extends BaseController { protected KelasModel $kelasModel; protected JurusanModel $jurusanModel; + protected $generalSettings; + public function __construct() { $this->kelasModel = new KelasModel(); diff --git a/app/Controllers/Admin/QRGenerator.php b/app/Controllers/Admin/QRGenerator.php index 6685ac8..c649a52 100644 --- a/app/Controllers/Admin/QRGenerator.php +++ b/app/Controllers/Admin/QRGenerator.php @@ -15,12 +15,14 @@ use Endroid\QrCode\Logo\Logo; use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeMargin; use Endroid\QrCode\Writer\PngWriter; +use Endroid\QrCode\Writer\SvgWriter; +use Endroid\QrCode\Writer\WriterInterface; class QRGenerator extends BaseController { protected QrCode $qrCode; - protected PngWriter $writer; - protected ?Logo $logo; + protected WriterInterface $writer; + protected ?Logo $logo = null; protected Label $label; protected Font $labelFont; protected Color $foregroundColor; @@ -29,8 +31,7 @@ class QRGenerator extends BaseController protected string $qrCodeFilePath; - const PUBLIC_PATH = ROOTPATH . 'public' . DIRECTORY_SEPARATOR; - const UPLOADS_PATH = self::PUBLIC_PATH . 'uploads' . DIRECTORY_SEPARATOR; + const UPLOADS_PATH = FCPATH . 'uploads' . DIRECTORY_SEPARATOR; public function __construct() { @@ -38,16 +39,31 @@ public function __construct() $this->writer = new PngWriter(); - $this->labelFont = new Font(self::PUBLIC_PATH . 'assets/fonts/Roboto-Medium.ttf', 14); + $this->labelFont = new Font(FCPATH . 'assets/fonts/Roboto-Medium.ttf', 14); $this->foregroundColor = new Color(44, 73, 162); $this->foregroundColor2 = new Color(28, 101, 90); $this->backgroundColor = new Color(255, 255, 255); - // Create logo - $this->logo = boolval(env('QR_LOGO')) - ? Logo::create(self::PUBLIC_PATH . 'assets/img/logo_sekolah.jpg')->setResizeToWidth(75) - : null; + if (boolval(env('QR_LOGO'))) { + // Create logo + $logo = (new \Config\School)::$generalSettings->logo; + if (empty($logo) || !file_exists(FCPATH . $logo)) { + $logo = 'assets/img/logo_sekolah.jpg'; + } + if (file_exists(FCPATH . $logo)) { + $fileExtension = pathinfo(FCPATH . $logo, PATHINFO_EXTENSION); + if ($fileExtension === 'svg') { + $this->writer = new SvgWriter(); + $this->logo = Logo::create(FCPATH . $logo) + ->setResizeToWidth(75) + ->setResizeToHeight(75); + } else { + $this->logo = Logo::create(FCPATH . $logo) + ->setResizeToWidth(75); + } + } + } $this->label = Label::create('') ->setFont($this->labelFont) @@ -114,7 +130,8 @@ public function generateQrGuru() public function generate($nama, $nomor, $unique_code) { - $filename = url_title($nama, lowercase: true) . "_" . url_title($nomor, lowercase: true) . '.png'; + $fileExt = $this->writer instanceof SvgWriter ? 'svg' : 'png'; + $filename = url_title($nama, lowercase: true) . "_" . url_title($nomor, lowercase: true) . ".$fileExt"; // set qr code data $this->qrCode->setData($unique_code); diff --git a/app/Controllers/BaseController.php b/app/Controllers/BaseController.php index 314a21b..8d1cb82 100644 --- a/app/Controllers/BaseController.php +++ b/app/Controllers/BaseController.php @@ -41,7 +41,10 @@ abstract class BaseController extends Controller * Be sure to declare properties for any property fetch you initialized. * The creation of dynamic property is deprecated in PHP 8.2. */ - // protected $session; + + protected $session; + + protected $generalSettings; /** * Constructor. @@ -53,6 +56,13 @@ public function initController(RequestInterface $request, ResponseInterface $res // Preload any models, libraries, etc, here. - // E.g.: $this->session = \Config\Services::session(); + $this->session = \Config\Services::session(); + $schoolConfigurations = new \Config\School(); + $this->generalSettings = $schoolConfigurations::$generalSettings; + + + // Passing global variable to views + $view = \Config\Services::renderer(); + $view->setData(['generalSettings' => $this->generalSettings]); } } diff --git a/app/Database/Migrations/2024-07-24-083011_GeneralSettings.php b/app/Database/Migrations/2024-07-24-083011_GeneralSettings.php new file mode 100644 index 0000000..3403478 --- /dev/null +++ b/app/Database/Migrations/2024-07-24-083011_GeneralSettings.php @@ -0,0 +1,59 @@ +forge->addField([ + 'id' => [ + 'type' => 'INT', + 'constraint' => 11, + 'unsigned' => true, + 'auto_increment' => true + ], + 'logo' => [ + 'type' => 'VARCHAR', + 'constraint' => 225, + 'null' => true + ], + 'school_name' => [ + 'type' => 'VARCHAR', + 'constraint' => 225, + 'null' => true, + 'default' => 'SMK 1 Indonesia', + ], + 'school_year' => [ + 'type' => 'VARCHAR', + 'constraint' => 225, + 'null' => true, + 'default' => '2024/2025', + ], + 'copyright' => [ + 'type' => 'VARCHAR', + 'constraint' => 225, + 'null' => true, + 'default' => '© 2023 All rights reserved.', + ], + ]); + + // primary key + $this->forge->addKey('id', primary: TRUE); + + + $this->forge->createTable('general_settings', TRUE); + + // Insert Default Data + $default['school_name'] = 'SMK 1 Indonesia'; + $default['school_year'] = '2024/2025'; + $this->db->table('general_settings')->insert($default); + } + + public function down() + { + $this->forge->dropTable('general_settings'); + } +} diff --git a/app/Language/en/Validation.php b/app/Language/en/Validation.php index 54d1e7a..0bad0a5 100644 --- a/app/Language/en/Validation.php +++ b/app/Language/en/Validation.php @@ -1,4 +1,10 @@ 'Kolom {field} wajib di isi.', + 'form_validation_min_length' => 'Panjang {field} minimal {param} karakter.', + 'form_validation_max_length' => 'Panjang {field} maksimal {param} karakter.', + 'form_validation_matches' => 'Kolom {field} tidak sama dengan kolom {param}.', + 'form_validation_is_unique' => 'Data {field} Harus Unik.', +]; diff --git a/app/Models/BaseModel.php b/app/Models/BaseModel.php new file mode 100644 index 0000000..0afb58e --- /dev/null +++ b/app/Models/BaseModel.php @@ -0,0 +1,19 @@ +request = \Config\Services::request(); + $this->session = \Config\Services::session(); + $this->generalSettings = School::$generalSettings; + } +} \ No newline at end of file diff --git a/app/Models/GeneralSettingsModel.php b/app/Models/GeneralSettingsModel.php new file mode 100644 index 0000000..73dd9d6 --- /dev/null +++ b/app/Models/GeneralSettingsModel.php @@ -0,0 +1,44 @@ +builder = $this->db->table('general_settings'); + } + + //input values + public function inputValues() + { + return [ + 'school_name' => inputPost('school_name'), + 'school_year' => inputPost('school_year'), + 'copyright' => inputPost('copyright'), + ]; + } + + public function updateSettings() + { + $data = $this->inputValues(); + + $uploadModel = new UploadModel(); + $logoPath = $uploadModel->uploadLogo('logo'); + + if (!empty($logoPath) && !empty($logoPath['path'])) { + $oldLogo = $this->generalSettings->logo; + $data['logo'] = $logoPath['path']; + if (file_exists($oldLogo)) { + @unlink($oldLogo); + } + } + + return $this->builder->where('id', 1)->update($data); + } +} diff --git a/app/Models/UploadModel.php b/app/Models/UploadModel.php new file mode 100644 index 0000000..dc847be --- /dev/null +++ b/app/Models/UploadModel.php @@ -0,0 +1,89 @@ +jpgQuality = 85; + $this->webpQuality = 80; + $this->imgExt = '.jpg'; + } + + //upload file + private function upload($inputName, $directory, $namePrefix, $allowedExtensions = null) + { + if ($allowedExtensions != null && is_array($allowedExtensions) && !empty($allowedExtensions[0])) { + if (!$this->checkAllowedFileTypes($inputName, $allowedExtensions)) { + return null; + } + } + $file = $this->request->getFile($inputName); + if (!empty($file) && !empty($file->getName())) { + $orjName = $file->getName(); + $name = pathinfo($orjName, PATHINFO_FILENAME); + $ext = pathinfo($orjName, PATHINFO_EXTENSION); + $uniqueName = $namePrefix . generateToken(true) . '.' . $ext; + if (!$file->hasMoved()) { + if ($file->move(FCPATH . $directory, $uniqueName)) { + return ['name' => $uniqueName, 'orjName' => $orjName, 'path' => $directory . $uniqueName, 'ext' => $ext]; + } + } + } + return null; + } + + //upload temp file + public function uploadTempFile($inputName, $isImage = false) + { + $allowedExtensions = array(); + if ($isImage) { + $allowedExtensions = ['jpg', 'jpeg', 'webp', 'png', 'gif']; + } + return $this->upload($inputName, 'uploads/tmp/', 'temp_', $allowedExtensions); + } + + //logo upload + public function uploadLogo($inputName) + { + return $this->upload($inputName, "uploads/logo/", "logo_", ['jpg', 'jpeg', 'png', 'gif', 'svg']); + } + + //check allowed file types + public function checkAllowedFileTypes($fileName, $allowedTypes) + { + if (!isset($_FILES[$fileName])) { + return false; + } + if (empty($_FILES[$fileName]['name'])) { + return false; + } + + $ext = pathinfo($_FILES[$fileName]['name'], PATHINFO_EXTENSION); + if (!empty($ext)) { + $ext = strtolower($ext); + } + $extArray = array(); + if (!empty($allowedTypes) && is_array($allowedTypes)) { + foreach ($allowedTypes as $item) { + if (!empty($item)) { + $item = trim($item, '"'); + } + if (!empty($item)) { + $item = trim($item, "'"); + } + array_push($extArray, $item); + } + } + if (!empty($extArray) && in_array($ext, $extArray)) { + return true; + } + return false; + } +} diff --git a/app/Views/admin/_messages.php b/app/Views/admin/_messages.php new file mode 100644 index 0000000..baaf0af --- /dev/null +++ b/app/Views/admin/_messages.php @@ -0,0 +1,22 @@ +getFlashdata('error')) : ?> +
+
+ + getFlashdata('error'); ?> +
+
+ +getFlashdata('success')) : ?> +
+
+ + getFlashdata('success'); ?> +
+
+ \ No newline at end of file diff --git a/app/Views/admin/dashboard.php b/app/Views/admin/dashboard.php index e18cc31..2b5866a 100644 --- a/app/Views/admin/dashboard.php +++ b/app/Views/admin/dashboard.php @@ -56,7 +56,7 @@ diff --git a/app/Views/admin/data/data-guru.php b/app/Views/admin/data/data-guru.php index 414cb82..6c05569 100644 --- a/app/Views/admin/data/data-guru.php +++ b/app/Views/admin/data/data-guru.php @@ -20,7 +20,7 @@

Daftar Guru

-

Angkatan

+

Angkatan school_year; ?>