├── .editorconfig ├── .env.example ├── .gitattributes ├── .gitignore ├── .htaccess ├── .styleci.yml ├── LICENSE ├── Procfile ├── README.md ├── app ├── Console │ ├── Commands │ │ ├── AppSetup.php │ │ └── Database │ │ │ ├── Create.php │ │ │ ├── Delete.php │ │ │ ├── MigrateFresh.php │ │ │ ├── RoleSeed.php │ │ │ └── UserSeed.php │ └── Kernel.php ├── Exceptions │ └── Handler.php ├── Http │ ├── Controllers │ │ ├── ActionLogController.php │ │ ├── Auth │ │ │ ├── ForgotPasswordController.php │ │ │ ├── LoginController.php │ │ │ └── ResetPasswordController.php │ │ ├── Controller.php │ │ ├── FeedController.php │ │ ├── HomeController.php │ │ ├── NotificationController.php │ │ ├── ProfileController.php │ │ ├── RoleController.php │ │ ├── StudentClassController.php │ │ └── UserController.php │ ├── Kernel.php │ ├── Middleware │ │ ├── Authenticate.php │ │ ├── CheckForMaintenanceMode.php │ │ ├── EncryptCookies.php │ │ ├── RedirectIfAuthenticated.php │ │ ├── TrimStrings.php │ │ ├── TrustProxies.php │ │ └── VerifyCsrfToken.php │ ├── Requests │ │ ├── ActionLog │ │ │ └── StoreActionLogRequest.php │ │ ├── Assessment │ │ │ └── AssessmentRequest.php │ │ ├── Notification │ │ │ └── StoreNotificationRequest.php │ │ ├── Profile │ │ │ ├── PasswordRequest.php │ │ │ └── ProfileRequest.php │ │ ├── Role │ │ │ ├── StoreRoleRequest.php │ │ │ └── UpdateRoleRequest.php │ │ ├── StudentClass │ │ │ ├── FeedRequest.php │ │ │ ├── ListStudentClassRequest.php │ │ │ ├── StoreStudentClassRequest.php │ │ │ ├── UpdateStudentClassRequest.php │ │ │ └── UpdateTugasRequest.php │ │ └── User │ │ │ ├── PasswordRequest.php │ │ │ ├── StoreUserRequest.php │ │ │ └── UpdateUserRequest.php │ └── Resources │ │ ├── ActionLog │ │ ├── ActionLogCollection.php │ │ └── ActionLogResource.php │ │ ├── Notification │ │ └── NotificationResource.php │ │ ├── StudentClass │ │ ├── StudentClassCollection.php │ │ └── StudentClassResource.php │ │ └── User │ │ ├── UserCollection.php │ │ └── UserResource.php ├── Model │ ├── ActionLog │ │ └── ActionLog.php │ ├── AssessmentLog │ │ └── AssessmentLog.php │ ├── Helper │ │ ├── Permission.php │ │ └── Role.php │ ├── Notification │ │ └── Notification.php │ ├── RoleHasPermission │ │ └── RoleHasPermission.php │ ├── StudentClass │ │ ├── Feed.php │ │ ├── StudentClass.php │ │ └── Tugas.php │ ├── User │ │ ├── User.php │ │ ├── UserLoginHistory.php │ │ └── UserToken.php │ └── UserNotification │ │ └── UserNotification.php ├── Notifications │ └── ResetPasswordNotification.php └── Providers │ ├── AppServiceProvider.php │ ├── AuthServiceProvider.php │ ├── BroadcastServiceProvider.php │ ├── EventServiceProvider.php │ └── RouteServiceProvider.php ├── artisan ├── bootstrap ├── app.php └── cache │ └── .gitignore ├── composer.json ├── config ├── app.php ├── auth.php ├── breadcrumbs.php ├── broadcasting.php ├── cache.php ├── database.php ├── dompdf.php ├── filesystems.php ├── hashing.php ├── logging.php ├── mail.php ├── permission.php ├── queue.php ├── services.php ├── session.php └── view.php ├── database ├── .gitignore ├── factories │ └── UserFactory.php ├── migrations │ ├── 2019_07_03_041141_create_user_table.php │ ├── 2019_07_03_042750_create_class_table.php │ ├── 2019_07_03_043613_create_user_token_table.php │ ├── 2019_07_03_044924_create_sytem_log_table.php │ ├── 2019_07_03_074842_create_global_setting_table.php │ ├── 2019_08_12_083949_create_permission_tables.php │ ├── 2019_09_05_011908_create_action_log.php │ ├── 2020_01_31_213915_create_notification.php │ ├── 2020_02_02_005836_create_user_notification.php │ ├── 2020_02_02_005837_create_password_resets_table.php │ ├── 2020_02_13_130004_create_user_login_history.php │ ├── 2020_06_25_060711_create_feed_table.php │ ├── 2020_06_25_060752_create_tugas_table.php │ └── 2020_06_26_060712_create_class_user_table.php └── seeds │ ├── DatabaseSeeder.php │ ├── RoleTableSeeder.php │ └── UsersTableSeeder.php ├── keybindings.json ├── makefile ├── package.json ├── phpunit.xml ├── public ├── .htaccess ├── asset │ ├── auth.jpeg │ ├── file_thumb.png │ └── ouroom.png ├── asset_user │ └── Creator │ │ └── Super Admin │ │ └── WhatsApp Image 2020-07-23 at 06.23.07.jpeg ├── favicon.ico ├── index.php ├── layout │ └── assets │ │ ├── css │ │ ├── additional_css.css │ │ ├── animate.min.css │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap.min.css │ │ ├── bootstrap4.min.css │ │ ├── datatables.min.css │ │ ├── daterangepicker.css │ │ ├── font-awesome.min.css │ │ ├── icon.min.css │ │ ├── jquery.dataTables.css │ │ ├── light-bootstrap-dashboard.css │ │ ├── main.css │ │ ├── pe-icon-7-stroke.css │ │ ├── robotofont.css │ │ ├── select2.min.css │ │ └── semantic.min.css │ │ ├── fonts │ │ ├── Pe-icon-7-stroke.eot │ │ ├── Pe-icon-7-stroke.svg │ │ ├── Pe-icon-7-stroke.ttf │ │ ├── Pe-icon-7-stroke.woff │ │ ├── fontawesome-webfont.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ │ ├── images │ │ ├── sort_asc.png │ │ ├── sort_asc_disabled.png │ │ ├── sort_both.png │ │ ├── sort_desc.png │ │ └── sort_desc_disabled.png │ │ ├── js │ │ ├── bootstrap-notify.js │ │ ├── bootstrap-select.js │ │ ├── bootstrap.min.js │ │ ├── chartist.min.js │ │ ├── clipboard.min.js │ │ ├── datatables.min.js │ │ ├── daterangepicker.min.js │ │ ├── demo.js │ │ ├── jquery.3.2.1.min.js │ │ ├── jquery.dataTables.js │ │ ├── light-bootstrap-dashboard.js │ │ ├── moment.min.js │ │ ├── select2.min.js │ │ ├── semantic.min.js │ │ └── sweetalert.min.js │ │ ├── modules │ │ └── datatables │ │ │ ├── DataTables-1.10.16 │ │ │ ├── css │ │ │ │ ├── dataTables.bootstrap.css │ │ │ │ ├── dataTables.bootstrap.min.css │ │ │ │ ├── dataTables.bootstrap4.css │ │ │ │ ├── dataTables.bootstrap4.min.css │ │ │ │ ├── dataTables.foundation.css │ │ │ │ ├── dataTables.foundation.min.css │ │ │ │ ├── dataTables.jqueryui.css │ │ │ │ ├── dataTables.jqueryui.min.css │ │ │ │ ├── dataTables.semanticui.css │ │ │ │ ├── dataTables.semanticui.min.css │ │ │ │ ├── jquery.dataTables.css │ │ │ │ └── jquery.dataTables.min.css │ │ │ ├── images │ │ │ │ ├── sort_asc.png │ │ │ │ ├── sort_asc_disabled.png │ │ │ │ ├── sort_both.png │ │ │ │ ├── sort_desc.png │ │ │ │ └── sort_desc_disabled.png │ │ │ └── js │ │ │ │ ├── dataTables.bootstrap.js │ │ │ │ ├── dataTables.bootstrap.min.js │ │ │ │ ├── dataTables.bootstrap4.js │ │ │ │ ├── dataTables.bootstrap4.min.js │ │ │ │ ├── dataTables.foundation.js │ │ │ │ ├── dataTables.foundation.min.js │ │ │ │ ├── dataTables.jqueryui.js │ │ │ │ ├── dataTables.jqueryui.min.js │ │ │ │ ├── dataTables.semanticui.js │ │ │ │ ├── dataTables.semanticui.min.js │ │ │ │ ├── jquery.dataTables.js │ │ │ │ └── jquery.dataTables.min.js │ │ │ ├── Responsive-2.2.1 │ │ │ ├── css │ │ │ │ ├── responsive.bootstrap.css │ │ │ │ ├── responsive.bootstrap.min.css │ │ │ │ ├── responsive.bootstrap4.css │ │ │ │ ├── responsive.bootstrap4.min.css │ │ │ │ ├── responsive.dataTables.css │ │ │ │ ├── responsive.dataTables.min.css │ │ │ │ ├── responsive.foundation.css │ │ │ │ ├── responsive.foundation.min.css │ │ │ │ ├── responsive.jqueryui.css │ │ │ │ ├── responsive.jqueryui.min.css │ │ │ │ ├── responsive.semanticui.css │ │ │ │ └── responsive.semanticui.min.css │ │ │ └── js │ │ │ │ ├── dataTables.responsive.js │ │ │ │ ├── dataTables.responsive.min.js │ │ │ │ ├── responsive.bootstrap.js │ │ │ │ ├── responsive.bootstrap.min.js │ │ │ │ ├── responsive.bootstrap4.js │ │ │ │ ├── responsive.bootstrap4.min.js │ │ │ │ ├── responsive.foundation.js │ │ │ │ ├── responsive.foundation.min.js │ │ │ │ ├── responsive.jqueryui.js │ │ │ │ ├── responsive.jqueryui.min.js │ │ │ │ ├── responsive.semanticui.js │ │ │ │ └── responsive.semanticui.min.js │ │ │ ├── Select-1.2.4 │ │ │ ├── css │ │ │ │ ├── select.bootstrap.css │ │ │ │ ├── select.bootstrap.min.css │ │ │ │ ├── select.bootstrap4.css │ │ │ │ ├── select.bootstrap4.min.css │ │ │ │ ├── select.dataTables.css │ │ │ │ ├── select.dataTables.min.css │ │ │ │ ├── select.foundation.css │ │ │ │ ├── select.foundation.min.css │ │ │ │ ├── select.jqueryui.css │ │ │ │ ├── select.jqueryui.min.css │ │ │ │ ├── select.semanticui.css │ │ │ │ └── select.semanticui.min.css │ │ │ └── js │ │ │ │ ├── dataTables.select.js │ │ │ │ └── dataTables.select.min.js │ │ │ ├── datatables.css │ │ │ ├── datatables.js │ │ │ ├── datatables.min.css │ │ │ └── datatables.min.js │ │ └── sass │ │ ├── lbd │ │ ├── _alerts.scss │ │ ├── _buttons.scss │ │ ├── _cards.scss │ │ ├── _chartist.scss │ │ ├── _checkbox-radio-switch.scss │ │ ├── _dropdown.scss │ │ ├── _footers.scss │ │ ├── _inputs.scss │ │ ├── _misc.scss │ │ ├── _mixins.scss │ │ ├── _navbars.scss │ │ ├── _responsive.scss │ │ ├── _sidebar-and-main-panel.scss │ │ ├── _tables.scss │ │ ├── _typography.scss │ │ ├── _variables.scss │ │ └── mixins │ │ │ ├── _buttons.scss │ │ │ ├── _cards.scss │ │ │ ├── _chartist.scss │ │ │ ├── _icons.scss │ │ │ ├── _inputs.scss │ │ │ ├── _labels.scss │ │ │ ├── _morphing-buttons.scss │ │ │ ├── _navbars.scss │ │ │ ├── _social-buttons.scss │ │ │ ├── _tabs.scss │ │ │ ├── _transparency.scss │ │ │ └── _vendor-prefixes.scss │ │ └── light-bootstrap-dashboard.scss ├── layout_login │ ├── css │ │ ├── main.css │ │ └── util.css │ ├── fonts │ │ ├── font-awesome-4.7.0 │ │ │ ├── HELP-US-OUT.txt │ │ │ ├── css │ │ │ │ ├── font-awesome.css │ │ │ │ └── font-awesome.min.css │ │ │ ├── fonts │ │ │ │ ├── FontAwesome.otf │ │ │ │ ├── fontawesome-webfont.eot │ │ │ │ ├── fontawesome-webfont.svg │ │ │ │ ├── fontawesome-webfont.ttf │ │ │ │ ├── fontawesome-webfont.woff │ │ │ │ └── fontawesome-webfont.woff2 │ │ │ ├── less │ │ │ │ ├── animated.less │ │ │ │ ├── bordered-pulled.less │ │ │ │ ├── core.less │ │ │ │ ├── fixed-width.less │ │ │ │ ├── font-awesome.less │ │ │ │ ├── icons.less │ │ │ │ ├── larger.less │ │ │ │ ├── list.less │ │ │ │ ├── mixins.less │ │ │ │ ├── path.less │ │ │ │ ├── rotated-flipped.less │ │ │ │ ├── screen-reader.less │ │ │ │ ├── stacked.less │ │ │ │ └── variables.less │ │ │ └── scss │ │ │ │ ├── _animated.scss │ │ │ │ ├── _bordered-pulled.scss │ │ │ │ ├── _core.scss │ │ │ │ ├── _fixed-width.scss │ │ │ │ ├── _icons.scss │ │ │ │ ├── _larger.scss │ │ │ │ ├── _list.scss │ │ │ │ ├── _mixins.scss │ │ │ │ ├── _path.scss │ │ │ │ ├── _rotated-flipped.scss │ │ │ │ ├── _screen-reader.scss │ │ │ │ ├── _stacked.scss │ │ │ │ ├── _variables.scss │ │ │ │ └── font-awesome.scss │ │ ├── montserrat │ │ │ ├── Montserrat-Black.ttf │ │ │ ├── Montserrat-BlackItalic.ttf │ │ │ ├── Montserrat-Bold.ttf │ │ │ ├── Montserrat-BoldItalic.ttf │ │ │ ├── Montserrat-ExtraBold.ttf │ │ │ ├── Montserrat-ExtraBoldItalic.ttf │ │ │ ├── Montserrat-ExtraLight.ttf │ │ │ ├── Montserrat-ExtraLightItalic.ttf │ │ │ ├── Montserrat-Italic.ttf │ │ │ ├── Montserrat-Light.ttf │ │ │ ├── Montserrat-LightItalic.ttf │ │ │ ├── Montserrat-Medium.ttf │ │ │ ├── Montserrat-MediumItalic.ttf │ │ │ ├── Montserrat-Regular.ttf │ │ │ ├── Montserrat-SemiBold.ttf │ │ │ ├── Montserrat-SemiBoldItalic.ttf │ │ │ ├── Montserrat-Thin.ttf │ │ │ ├── Montserrat-ThinItalic.ttf │ │ │ └── OFL.txt │ │ └── poppins │ │ │ ├── Poppins-Black.ttf │ │ │ ├── Poppins-BlackItalic.ttf │ │ │ ├── Poppins-Bold.ttf │ │ │ ├── Poppins-BoldItalic.ttf │ │ │ ├── Poppins-ExtraBold.ttf │ │ │ ├── Poppins-ExtraBoldItalic.ttf │ │ │ ├── Poppins-ExtraLight.ttf │ │ │ ├── Poppins-ExtraLightItalic.ttf │ │ │ ├── Poppins-Italic.ttf │ │ │ ├── Poppins-Light.ttf │ │ │ ├── Poppins-LightItalic.ttf │ │ │ ├── Poppins-Medium.ttf │ │ │ ├── Poppins-MediumItalic.ttf │ │ │ ├── Poppins-Regular.ttf │ │ │ ├── Poppins-SemiBold.ttf │ │ │ ├── Poppins-SemiBoldItalic.ttf │ │ │ ├── Poppins-Thin.ttf │ │ │ └── Poppins-ThinItalic.ttf │ ├── images │ │ ├── icons │ │ │ └── favicon.ico │ │ └── undraw.png │ ├── js │ │ └── main.js │ └── vendor │ │ ├── animate │ │ └── animate.css │ │ ├── bootstrap │ │ ├── css │ │ │ ├── bootstrap-grid.css │ │ │ ├── bootstrap-grid.css.map │ │ │ ├── bootstrap-grid.min.css │ │ │ ├── bootstrap-grid.min.css.map │ │ │ ├── bootstrap-reboot.css │ │ │ ├── bootstrap-reboot.css.map │ │ │ ├── bootstrap-reboot.min.css │ │ │ ├── bootstrap-reboot.min.css.map │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ └── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ ├── popper.js │ │ │ ├── popper.min.js │ │ │ └── tooltip.js │ │ ├── css-hamburgers │ │ ├── hamburgers.css │ │ └── hamburgers.min.css │ │ ├── jquery │ │ └── jquery-3.2.1.min.js │ │ ├── select2 │ │ ├── select2.css │ │ ├── select2.js │ │ ├── select2.min.css │ │ └── select2.min.js │ │ └── tilt │ │ └── tilt.jquery.min.js ├── robots.txt └── web.config ├── resources └── views │ ├── action-log │ └── index.blade.php │ ├── auth │ ├── login.blade.php │ ├── passwords │ │ ├── email.blade.php │ │ └── reset.blade.php │ └── register.blade.php │ ├── components │ └── alert.blade.php │ ├── content_master.blade.php │ ├── content_profile.blade.php │ ├── error │ └── unauthorized.blade.php │ ├── home │ └── index.blade.php │ ├── include │ ├── footer.blade.php │ ├── head.blade.php │ └── navbar.blade.php │ ├── login │ └── indexlogin.blade.php │ ├── master.blade.php │ ├── master_reset_password.blade.php │ ├── notification │ └── index.blade.php │ ├── profile │ └── index.blade.php │ ├── role │ ├── index.blade.php │ ├── store.blade.php │ └── update.blade.php │ ├── siswa │ ├── index.blade.php │ └── store.blade.php │ ├── student_class │ ├── assessment.blade.php │ ├── data_class.blade.php │ ├── feed.blade.php │ ├── index.blade.php │ ├── list.blade.php │ ├── rekap_tugas.blade.php │ ├── siswa_class.blade.php │ ├── store.blade.php │ └── tugas_siswa.blade.php │ ├── user │ ├── index.blade.php │ └── store.blade.php │ └── vendor │ ├── mail │ ├── html │ │ ├── button.blade.php │ │ ├── footer.blade.php │ │ ├── header.blade.php │ │ ├── layout.blade.php │ │ ├── message.blade.php │ │ ├── panel.blade.php │ │ ├── promotion.blade.php │ │ ├── promotion │ │ │ └── button.blade.php │ │ ├── subcopy.blade.php │ │ ├── table.blade.php │ │ └── themes │ │ │ └── default.css │ └── text │ │ ├── button.blade.php │ │ ├── footer.blade.php │ │ ├── header.blade.php │ │ ├── layout.blade.php │ │ ├── message.blade.php │ │ ├── panel.blade.php │ │ ├── promotion.blade.php │ │ ├── promotion │ │ └── button.blade.php │ │ ├── subcopy.blade.php │ │ └── table.blade.php │ └── notifications │ └── email.blade.php ├── routes ├── api.php ├── breadcrumbs.php ├── channels.php ├── console.php └── web.php ├── server.php ├── storage ├── app │ ├── .gitignore │ └── public │ │ └── .gitignore ├── framework │ ├── .gitignore │ ├── cache │ │ ├── .gitignore │ │ └── data │ │ │ └── .gitignore │ ├── sessions │ │ └── .gitignore │ ├── testing │ │ └── .gitignore │ └── views │ │ └── .gitignore └── logs │ └── .gitignore ├── tests ├── CreatesApplication.php ├── Feature │ └── ExampleTest.php ├── TestCase.php └── Unit │ └── ExampleTest.php └── webpack.mix.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 4 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [*.yml] 15 | indent_size = 2 16 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | APP_NAME=Laravel 2 | APP_ENV=local 3 | APP_KEY= 4 | APP_DEBUG=true 5 | APP_URL=http://localhost 6 | 7 | LOG_CHANNEL=stack 8 | 9 | DB_CONNECTION=mysql 10 | DB_HOST=127.0.0.1 11 | DB_PORT=3306 12 | DB_DATABASE=homestead 13 | DB_USERNAME=homestead 14 | DB_PASSWORD=secret 15 | 16 | BROADCAST_DRIVER=log 17 | CACHE_DRIVER=file 18 | QUEUE_CONNECTION=sync 19 | SESSION_DRIVER=file 20 | SESSION_LIFETIME=120 21 | 22 | REDIS_HOST=127.0.0.1 23 | REDIS_PASSWORD=null 24 | REDIS_PORT=6379 25 | 26 | MAIL_DRIVER=smtp 27 | MAIL_HOST=smtp.mailtrap.io 28 | MAIL_PORT=2525 29 | MAIL_USERNAME=null 30 | MAIL_PASSWORD=null 31 | MAIL_ENCRYPTION=null 32 | 33 | AWS_ACCESS_KEY_ID= 34 | AWS_SECRET_ACCESS_KEY= 35 | AWS_DEFAULT_REGION=us-east-1 36 | AWS_BUCKET= 37 | 38 | PUSHER_APP_ID= 39 | PUSHER_APP_KEY= 40 | PUSHER_APP_SECRET= 41 | PUSHER_APP_CLUSTER=mt1 42 | 43 | MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 44 | MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" 45 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.css linguist-vendored 3 | *.scss linguist-vendored 4 | *.js linguist-vendored 5 | CHANGELOG.md export-ignore 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /public/hot 3 | /public/storage 4 | /storage/*.key 5 | /vendor 6 | .env 7 | .phpunit.result.cache 8 | Homestead.json 9 | Homestead.yaml 10 | npm-debug.log 11 | yarn-error.log 12 | composer.lock 13 | README.md -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | Options +FollowSymLinks -Indexes 2 | RewriteEngine On 3 | 4 | RewriteCond %{HTTP:Authorization} . 5 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 6 | 7 | RewriteCond %{REQUEST_FILENAME} !-d 8 | RewriteCond %{REQUEST_FILENAME} !-f 9 | RewriteRule ^ index.php [L] -------------------------------------------------------------------------------- /.styleci.yml: -------------------------------------------------------------------------------- 1 | php: 2 | preset: laravel 3 | disabled: 4 | - unused_use 5 | finder: 6 | not-name: 7 | - index.php 8 | - server.php 9 | js: 10 | finder: 11 | not-name: 12 | - webpack.mix.js 13 | css: true 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Yayang Kurnia 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: vendor/bin/heroku-php-apache2 public/ 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Ourooom

2 |

Google Classroom Wannabe

3 | 4 | 5 | ![Ouroom](https://github.com/kurnyaannn/ouroom-project/blob/master/public/asset/ouroom.png?raw=true) 6 |
Illustration by Undraw
7 | 8 | ## Requirements 9 | * PHP 7+ 10 | * NodeJS 11 | * Composer 12 | * Laravel 13 | 14 | ## Installation 15 | * Edit .env file according to your needs 16 | * Run : 17 | ```bash 18 | $ composer update 19 | $ php artisan classroom:setup 20 | ``` 21 | 22 | ## Usage 23 | * Creator Level (check UserSeeds for credentials) 24 | * Can access all feature available 25 | * Administrator Level 26 | * Can access all feature except update role and notifying Creator 27 | * Guru Level 28 | * Class feature 29 | * Assessment 30 | * Siswa Level 31 | * Class feature 32 | 33 | ## Demo 34 | Demo link: ( http://atm-classroom.herokuapp.com ) 35 | Username | Password 36 | -------- | --------- 37 | admin | adminatm 38 | 39 | *ps: In order to join a Class. The student needs to have same `Jurusan`, `Angkatan`, & `Class Token` with the chosen Class. 40 | 41 | ## Contributing 42 | - Fork it ( https://github.com/kurnyaannn/ouroom-project/fork ) 43 | - Create your feature branch (`git checkout -b my-new-feature`) 44 | - Commit your changes (`git commit -am 'Add some feature'`) 45 | - Push to the branch (`git push origin my-new-feature`) 46 | - Create a new Pull Request 47 | 48 | ## License 49 | As you can see Ouroom is under MIT License 50 | 51 | ## About the Author 52 | Yayang Kurnia. 53 | -------------------------------------------------------------------------------- /app/Console/Commands/AppSetup.php: -------------------------------------------------------------------------------- 1 | line('--------------- Instalasi Classroom ----------------'); 39 | 40 | $this->line('Deleting old Database.'); 41 | Artisan::call('database:delete', ['db_name' => env('DB_DATABASE')]); 42 | 43 | $this->line('Creating new Database.'); 44 | Artisan::call('database:create', ['db_name' => env('DB_DATABASE')]); 45 | 46 | $this->line('Running Migration:fresh.'); 47 | Artisan::call('database:migrate:fresh'); 48 | 49 | $this->line('Injecting User to Database.'); 50 | Artisan::call('database:user:seed'); 51 | 52 | $this->line('Injecting Role to Database.'); 53 | Artisan::call('database:role:seed'); 54 | 55 | $this->line('Making Laravel Key.'); 56 | Artisan::call('key:generate'); 57 | 58 | $path = public_path() . '/storage'; 59 | 60 | $this->line('Checking Storage Link'); 61 | 62 | if (!file_exists($path)) { 63 | Artisan::call('storage:link'); 64 | $this->line('Making Storage Succes.'); 65 | } else { 66 | $this->line('Storage Ready.'); 67 | } 68 | 69 | $this->line('Installation Complete.'); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /app/Console/Commands/Database/Create.php: -------------------------------------------------------------------------------- 1 | argument('db_name'); 40 | if ($dbName) { 41 | $this->line('Membuat DB : ' . $dbName . '.'); 42 | // create a new database 43 | if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { 44 | $process = new Process('C:\XAMPP\MYSQL\Bin\mysql -u ' . env('DB_USERNAME') . 45 | ' -p' . env('DB_PASSWORD') . 46 | ' -e "create database ' . $dbName . '"'); 47 | $process->run(); 48 | } else { 49 | $process = new Process('mysql -u ' . env('DB_USERNAME') . 50 | ' -p' . env('DB_PASSWORD') . 51 | ' -e "create database ' . $dbName . '"'); 52 | $process->run(); 53 | } 54 | // executes after the command finishes 55 | if (!$process->isSuccessful()) { 56 | $this->line($process->getOutput()); 57 | throw new ProcessFailedException($process); 58 | } 59 | } else { 60 | $this->line('Invalid DB given.'); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/Console/Commands/Database/MigrateFresh.php: -------------------------------------------------------------------------------- 1 | line('Fresh Migrating DB.'); 43 | 44 | // Update the Tenant DB Name in Configuration 45 | config()->set('database.connections.mysql.database', env('DB_DATABASE')); 46 | DB::connection('mysql')->reconnect(); 47 | 48 | Artisan::call('migrate:fresh', [ 49 | '--path' => 'database/migrations', 50 | '--force' => true 51 | ]); 52 | 53 | info('Fresh Migration Successful.'); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/Console/Commands/Database/RoleSeed.php: -------------------------------------------------------------------------------- 1 | line('Menyuntikkan Role Ke Database'); 44 | 45 | // Command Artisan [Parameter] 46 | Artisan::call('db:seed', [ 47 | '--class' => 'RoleTableSeeder' 48 | ]); 49 | 50 | info('Berhasil Disuntikkan.'); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/Console/Commands/Database/UserSeed.php: -------------------------------------------------------------------------------- 1 | line('Injecting User to Database'); 44 | 45 | // Command Artisan [Parameter] 46 | Artisan::call('db:seed', [ 47 | '--class' => 'UsersTableSeeder' 48 | ]); 49 | 50 | info('Succesfully injected.'); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('inspire') 28 | // ->hourly(); 29 | } 30 | 31 | /** 32 | * Register the commands for the application. 33 | * 34 | * @return void 35 | */ 36 | protected function commands() 37 | { 38 | $this->load(__DIR__.'/Commands'); 39 | 40 | require base_path('routes/console.php'); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/Exceptions/Handler.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 15 | } 16 | 17 | public function index(Request $request) 18 | { 19 | if ($request->ajax()) { 20 | $data = ActionLog::all(); 21 | return Datatables::of($data) 22 | ->addColumn('user', function ($row) { 23 | return $row->getUser->full_name; 24 | }) 25 | ->addIndexColumn() 26 | ->make(true); 27 | } 28 | if ($this->getUserPermission('index role')) { 29 | $this->systemLog(false, 'Mengakses halaman action log'); 30 | return view('action-log.index', ['active' => 'action-log']); 31 | } else { 32 | $this->systemLog(true, 'Gagal Mengakses halaman action log'); 33 | return view('error.unauthorized', ['active' => 'action-log']); 34 | } 35 | } 36 | 37 | public function destroy(Request $request) 38 | { 39 | if ($request->ajax()) { 40 | if (ActionLog::truncate()) { 41 | return $this->getResponse(true, 200, '', 'Semua data log berhasil terhapus'); 42 | } else { 43 | return $this->getResponse(false, 400, '', 'Terjadi kesalahan, Data gagal dihapus'); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/ForgotPasswordController.php: -------------------------------------------------------------------------------- 1 | $email]; 23 | $response = Password::sendResetLink($credentials, function (Message $message) { 24 | $message->subject($this->getEmailSubject()); 25 | }); 26 | switch ($response) { 27 | case Password::RESET_LINK_SENT: 28 | return redirect()->back()->with('status', trans($response)); 29 | case Password::INVALID_USER: 30 | return redirect()->back()->withErrors(['email' => trans($response)]); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | json(['status' => $status, 'status_code' => $status_code, 'data' => $data, 'message' => $message]); 26 | } else { 27 | return response()->json(['status' => $status, 'status_code' => $status_code, 'data' => $data, 'message' => $message]); 28 | } 29 | } 30 | 31 | public function getUserPermission($permission_name) 32 | { 33 | $user = Auth::user(); 34 | if (!$user->hasPermissionTo($permission_name)) { 35 | return false; 36 | } 37 | return true; 38 | } 39 | 40 | public function systemLog($is_error = false, $action_message = '') 41 | { 42 | $user = Auth::user(); 43 | DB::beginTransaction(); 44 | $action_log = new ActionLog(); 45 | $action_log->action_type = ActionLog::TYPE_GENERAL; 46 | $action_log->is_error = $is_error; 47 | $action_log->action_message = $action_message; 48 | $action_log->user_id = $user->id; 49 | $action_log->date = date('Y-m-d H:i:s'); 50 | if (!$action_log->save()) { 51 | DB::rollBack(); 52 | return false; 53 | } 54 | DB::commit(); 55 | return true; 56 | } 57 | 58 | public function printLog() 59 | { 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/Http/Middleware/Authenticate.php: -------------------------------------------------------------------------------- 1 | expectsJson()) { 18 | return route('login'); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Middleware/CheckForMaintenanceMode.php: -------------------------------------------------------------------------------- 1 | check()) { 21 | return redirect('/home'); 22 | } 23 | 24 | return $next($request); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | 'required|integer', 28 | 'user_id' => 'required|integer', 29 | 'is_error' => 'required|integer', 30 | 'action_message' => 'required|string', 31 | 'date' => 'required|date', 32 | ]; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/Http/Requests/Assessment/AssessmentRequest.php: -------------------------------------------------------------------------------- 1 | request->get('id_siswa'))->memorization_type; 30 | 31 | if($memorization_type != Siswa::TYPE_IQRO) 32 | { 33 | return [ 34 | 'id_siswa' => 'integer', 35 | 'surah_id' => 'integer', 36 | 'ayat' => 'integer', 37 | 'note' => 'string | nullable', 38 | 'begin' => 'integer', 39 | 'end' => 'integer', 40 | ]; 41 | } 42 | else 43 | { 44 | return [ 45 | 'id_siswa' => 'integer', 46 | 'iqro_id' => 'integer', 47 | 'page' => 'integer', 48 | 'note' => 'string | nullable', 49 | 'begin' => 'integer', 50 | 'end' => 'integer', 51 | ]; 52 | } 53 | } 54 | 55 | /** 56 | * Get the validation messages that apply to the request. 57 | * 58 | * @return array 59 | */ 60 | public function messages() 61 | { 62 | return [ 63 | 64 | ]; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/Http/Requests/Notification/StoreNotificationRequest.php: -------------------------------------------------------------------------------- 1 | 'required|string', 28 | 'notification_message' => 'required|string', 29 | ]; 30 | } 31 | 32 | /** 33 | * Get the validation messages that apply to the request. 34 | * 35 | * @return array 36 | */ 37 | public function messages() 38 | { 39 | return [ 40 | 'notification_title.required' => 'Judul diperlukan', 41 | 'notification_title.string' => 'Tipe tidak sesuai', 42 | 'notification_message.string' => 'Tipe tidak sesuai', 43 | 'notification_message.required' => 'Pesan tidak boleh kosong', 44 | ]; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/Http/Requests/Profile/PasswordRequest.php: -------------------------------------------------------------------------------- 1 | password; 29 | 30 | return [ 31 | 'old_password' => 'required', 32 | 'password' => 'required|confirmed|min:6|different:old_password', 33 | ]; 34 | } 35 | 36 | /** 37 | * Get the validation messages that apply to the request. 38 | * 39 | * @return array 40 | */ 41 | public function messages() 42 | { 43 | return [ 44 | 'password.required' => 'Anda belum melengkapi pengisisan Password', 45 | 'password.confirmed' => 'Password tidak sesuai', 46 | 'password.min' => 'Password minimal terdiri dari 6 Karakter', 47 | 'password.different' => 'Password baru harus berbeda dengan password lama', 48 | 'old_password.required' => 'Anda belum melengkapi pengisisan Password Lama', 49 | ]; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/Http/Requests/Profile/ProfileRequest.php: -------------------------------------------------------------------------------- 1 | 'required|email|unique:tbl_user,email,'. $request->get('iduser'), 30 | 'full_name' => 'required|string|min:2', 31 | 'address' => 'string|nullable', 32 | 'file' => 'nullable|max:2000', 33 | 'profile_picture' => 'string|nullable', 34 | ]; 35 | } 36 | 37 | /** 38 | * Get the validation messages that apply to the request. 39 | * 40 | * @return array 41 | */ 42 | public function messages() 43 | { 44 | return [ 45 | 'full_name.required' => 'Nama tidak boleh dikosongkan', 46 | 'full_name.string' => 'Gunakan huruf untuk nama lengkap anda', 47 | 'full_name.min' => 'Gunakan setidaknya 2 karakter', 48 | 49 | 'email.required' => 'Email tidak boleh dikosongkan', 50 | 'email.email' => 'Format email tidak disetujui', 51 | 'email.unique' => 'Email telah digunakan sebelumnya', 52 | 53 | 'file.max' => 'Maksimum file 100 KB', 54 | 55 | 'address.string' => 'Gunakan huruf untuk nama lengkap anda', 56 | ]; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/Http/Requests/Role/StoreRoleRequest.php: -------------------------------------------------------------------------------- 1 | 'required|min:2', 28 | ]; 29 | } 30 | 31 | /** 32 | * Get the validation messages that apply to the request. 33 | * 34 | * @return array 35 | */ 36 | public function messages() 37 | { 38 | return [ 39 | 'name.required' => 'Role tidak boleh dikosongkan', 40 | 'name.min' => 'Minimal 2 Karakter untuk Role', 41 | ]; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/Http/Requests/Role/UpdateRoleRequest.php: -------------------------------------------------------------------------------- 1 | 'required|min:2', 28 | ]; 29 | } 30 | 31 | /** 32 | * Get the validation messages that apply to the request. 33 | * 34 | * @return array 35 | */ 36 | public function messages() 37 | { 38 | return [ 39 | 'name.required' => 'Role tidak boleh dikosongkan', 40 | 'name.min' => 'Minimal 2 Karakter untuk Role', 41 | ]; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/Http/Requests/StudentClass/FeedRequest.php: -------------------------------------------------------------------------------- 1 | 'required|min:2', 23 | 'kategori' => 'required', 24 | 'detail' => 'string', 25 | 'file' => 'string', 26 | 'deadline' => 'date', 27 | ]; 28 | } 29 | 30 | public function messages() 31 | { 32 | return [ 33 | 'judul.required' => 'Judul tidak boleh dikosongkan', 34 | 'kategori.required' => 'Kategori tidak boleh dikosongkan', 35 | 'detail.required' => 'Detail tidak boleh dikosongkan', 36 | ]; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/Http/Requests/StudentClass/ListStudentClassRequest.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/app/Http/Requests/StudentClass/ListStudentClassRequest.php -------------------------------------------------------------------------------- /app/Http/Requests/StudentClass/StoreStudentClassRequest.php: -------------------------------------------------------------------------------- 1 | 'required|min:2', 28 | 'class_name' => 'required', 29 | 'teacher_id' => 'integer' 30 | ]; 31 | } 32 | 33 | /** 34 | * Get the validation messages that apply to the request. 35 | * 36 | * @return array 37 | */ 38 | public function messages() 39 | { 40 | return [ 41 | 'angkatan.required' => 'Tahun Angkatan tidak boleh dikosongkan', 42 | 'angkatan.min' => 'Angkatan tidak memenuhi kereteria', 43 | 'class_name.required' => 'Kelas tidak boleh dikosongkan', 44 | 'teacher_id.integer' => 'Format guru tidak diterima oleh sistem' 45 | ]; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/Http/Requests/StudentClass/UpdateStudentClassRequest.php: -------------------------------------------------------------------------------- 1 | 'required|min:2', 28 | 'class_name' => 'required', 29 | 'teacher_id' => 'integer' 30 | ]; 31 | } 32 | 33 | /** 34 | * Get the validation messages that apply to the request. 35 | * 36 | * @return array 37 | */ 38 | public function messages() 39 | { 40 | return [ 41 | 'angkatan.required' => 'Tahun Angkatan tidak boleh dikosongkan', 42 | 'angkatan.min' => 'Angkatan tidak memenuhi kereteria', 43 | 'class_name.required' => 'Kelas tidak boleh dikosongkan', 44 | 'teacher_id.integer' => 'Format guru tidak diterima oleh sistem' 45 | ]; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/Http/Requests/StudentClass/UpdateTugasRequest.php: -------------------------------------------------------------------------------- 1 | 'integer', 23 | ]; 24 | } 25 | 26 | public function messages() 27 | { 28 | return [ 29 | 'nilai.integer' => 'Input nilai salah', 30 | ]; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/Http/Requests/User/PasswordRequest.php: -------------------------------------------------------------------------------- 1 | 'required|confirmed|min:6', 28 | ]; 29 | } 30 | 31 | /** 32 | * Get the validation messages that apply to the request. 33 | * 34 | * @return array 35 | */ 36 | public function messages() 37 | { 38 | return [ 39 | 'password.required' => 'Anda belum melengkapi pengisisan Password', 40 | 'password.confirmed' => 'Password tidak sesuai', 41 | 'password.min' => 'Password minimal terdiri dari 6 Karakter', 42 | ]; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/Http/Requests/User/StoreUserRequest.php: -------------------------------------------------------------------------------- 1 | 'required|string|max:255', 25 | 'email' => 'required|email|unique:tbl_user', 26 | 'kelas' => 'nullable|string', 27 | 'username' => 'required|min:5|unique:tbl_user', 28 | 'address' => 'nullable|string', 29 | 'profile_picture' => 'nullable|string', 30 | 'password' => 'required|confirmed|min:6', 31 | ]; 32 | } 33 | 34 | /** 35 | * Get the validation messages that apply to the request. 36 | * 37 | * @return array 38 | */ 39 | public function messages(){ 40 | return [ 41 | 'username.required' => 'Username tidak boleh dikosongkan', 42 | 'username.min' => 'Username setidaknya 5 karakter', 43 | 'username.unique' => 'Username telah digunakan', 44 | 45 | 'email.required' => 'Username tidak boleh dikosongkan', 46 | 'email.email' => 'Format email tidak disetujui', 47 | 'email.unique' => 'Email telah digunakan', 48 | 49 | 'full_name.string' => 'Gunakan huruf untuk nama lengkap anda', 50 | 'full_name.min' => 'Gunakan setidaknya 2 karakter', 51 | 52 | 'address.string' => 'Gunakan huruf untuk nama lengkap anda', 53 | 54 | 'password.required' => 'Password tidak boleh dikosongkan', 55 | 'password.confirmed' => 'Password tidak sesuai', 56 | 'password.min' => 'Password minimal terdiri dari 6 Karakter', 57 | ]; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /app/Http/Requests/User/UpdateUserRequest.php: -------------------------------------------------------------------------------- 1 | 'required|min:2|unique:tbl_user,username,'.$request->get('iduser'), 30 | 'email' => 'required|email|unique:tbl_user,email,'. $request->get('iduser'), 31 | 'profile_picture' => 'string|nullable', 32 | 'full_name' => 'string|nullable', 33 | 'address' => 'string|nullable', 34 | ]; 35 | } 36 | 37 | /** 38 | * Get the validation messages that apply to the request. 39 | * 40 | * @return array 41 | */ 42 | public function messages() 43 | { 44 | return [ 45 | 'username.required' => 'Username tidak boleh dikosongkan', 46 | 'username.min' => 'Username setidaknya 2 karakter', 47 | 'username.unique' => 'Username telah ada sebelumnya', 48 | 49 | 'email.required' => 'Username tidak boleh dikosongkan', 50 | 'email.email' => 'Format email tidak disetujui', 51 | 'email.unique' => 'Email telah digunakan sebelumnya', 52 | 53 | 'full_name.string' => 'Gunakan huruf untuk nama lengkap anda', 54 | 'full_name.min' => 'Gunakan setidaknya 2 karakter', 55 | ]; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/Http/Resources/ActionLog/ActionLogCollection.php: -------------------------------------------------------------------------------- 1 | collection->transform(function (ActionLog $action_log) { 20 | return new ActionLogResource($action_log); 21 | }); 22 | 23 | return parent::toArray($request); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Http/Resources/ActionLog/ActionLogResource.php: -------------------------------------------------------------------------------- 1 | $this->getUser, 19 | 'action_type' => $this->action_type, 20 | 'is_error' => $this->is_error, 21 | 'action_message' => $this->action_message, 22 | 'date' => $this->date, 23 | 'created_at' => $this->created_at, 24 | 'updated_at' => $this->updated_at 25 | ]; 26 | } 27 | } -------------------------------------------------------------------------------- /app/Http/Resources/Notification/NotificationResource.php: -------------------------------------------------------------------------------- 1 | $this->notification_type, 19 | 'notification_title' => $this->notification_title, 20 | 'notification_message' => $this->notification_message, 21 | 'date' => $this->date, 22 | 'created_at' => $this->created_at, 23 | 'updated_at' => $this->updated_at 24 | ]; 25 | } 26 | } -------------------------------------------------------------------------------- /app/Http/Resources/StudentClass/StudentClassCollection.php: -------------------------------------------------------------------------------- 1 | collection->transform(function (StudentClass $studentClass) { 20 | return new StudentClassResource($studentClass); 21 | }); 22 | 23 | return parent::toArray($request); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Http/Resources/StudentClass/StudentClassResource.php: -------------------------------------------------------------------------------- 1 | $this->class_name, 19 | 'note' => $this->note, 20 | 'teacher' => $this->getTeacher, 21 | 'angkatan' => $this->angkatan, 22 | 'created_at' => $this->created_at, 23 | 'updated_at' => $this->updated_at 24 | ]; 25 | } 26 | } -------------------------------------------------------------------------------- /app/Http/Resources/User/UserCollection.php: -------------------------------------------------------------------------------- 1 | collection->transform(function (User $user) { 20 | return new UserResource($user); 21 | }); 22 | 23 | return parent::toArray($request); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Http/Resources/User/UserResource.php: -------------------------------------------------------------------------------- 1 | $this->id, 19 | 'username' => $this->username, 20 | 'address' => $this->address, 21 | 'email' => $this->email, 22 | 'full_name' => $this->full_name, 23 | 'account_type' => $this->account_type, 24 | 'has_parent' => $this->hasParent, 25 | 'status' => $this->status, 26 | 'created_at' => $this->created_at, 27 | 'updated_at' => $this->updated_at 28 | ]; 29 | } 30 | } -------------------------------------------------------------------------------- /app/Model/ActionLog/ActionLog.php: -------------------------------------------------------------------------------- 1 | 'nullable | interger', 23 | 'action_type' => 'required | interger', 24 | 'date' => 'required | date', 25 | 'is_error' => 'required | interger', 26 | ]; 27 | 28 | protected $hidden = []; 29 | 30 | public function getUser() 31 | { 32 | return $this->hasOne('App\Model\User\User', 'id', 'user_id'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/Model/AssessmentLog/AssessmentLog.php: -------------------------------------------------------------------------------- 1 | 'required | interger', 22 | 'range' => 'required | string', 23 | 'date' => 'required | date', 24 | 'assessment' => 'required | string', 25 | ]; 26 | 27 | protected $hidden = []; 28 | 29 | public function getSiswa() 30 | { 31 | return $this->belongsTo('App\Model\Siswa\Siswa', 'siswa_id', 'id'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Model/Helper/Permission.php: -------------------------------------------------------------------------------- 1 | where('guard_name', $guard_name)->first()) { 14 | return false; 15 | } 16 | return true; 17 | } 18 | 19 | public static function createIfNotExists($name, $guard_name) 20 | { 21 | if (!self::isExists($name, $guard_name)) { 22 | self::create(['name' => $name, 'guard_name' => $guard_name]); 23 | } 24 | return self::where('name', $name)->where('guard_name', $guard_name)->first(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Model/Helper/Role.php: -------------------------------------------------------------------------------- 1 | where('guard_name', $guard_name)->first()) { 14 | return false; 15 | } 16 | return true; 17 | } 18 | 19 | public static function createIfNotExists($name, $guard_name) 20 | { 21 | if (!self::isExists($name, $guard_name)) { 22 | self::create(['name' => $name, 'guard_name' => $guard_name]); 23 | } 24 | return self::where('name', $name)->where('guard_name', $guard_name)->first(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Model/Notification/Notification.php: -------------------------------------------------------------------------------- 1 | 'required | interger', 25 | 'notification_title' => 'required | string', 26 | 'date' => 'required | date', 27 | ]; 28 | 29 | protected $hidden = []; 30 | 31 | public static function getTypeMeaning($notification_type) 32 | { 33 | switch ($notification_type) { 34 | case static::NOTIFICATION_TYPE_TEACHER: 35 | return 'Untuk Guru'; 36 | case static::NOTIFICATION_TYPE_SISWA: 37 | return 'Untuk Siswa'; 38 | default: 39 | return ''; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/Model/RoleHasPermission/RoleHasPermission.php: -------------------------------------------------------------------------------- 1 | 'required | interger', 20 | 'role_id' => 'required | interger' 21 | ]; 22 | 23 | protected $hidden = []; 24 | 25 | public static function getHasPermission($role_id) 26 | { 27 | return self::all()->where('role_id', $role_id); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/Model/StudentClass/Feed.php: -------------------------------------------------------------------------------- 1 | 'required', 21 | 'kategori' => 'required', 22 | 'detail' => 'string', 23 | 'file' => 'string', 24 | 'deadline' => 'date' 25 | ]; 26 | } 27 | -------------------------------------------------------------------------------- /app/Model/StudentClass/StudentClass.php: -------------------------------------------------------------------------------- 1 | 'required', 26 | 'angkatan' => 'string', 27 | 'kelas' => 'string', 28 | 'note' => 'string', 29 | 'teacher_id' => 'required | interger', 30 | 'teacher_name' => 'string' 31 | ]; 32 | 33 | protected $hidden = []; 34 | 35 | public static function validateClass($angkatan, $class_name, $guru) 36 | { 37 | $data = self::where('angkatan', $angkatan)->where('class_name', $class_name)->where('teacher_id', $guru)->first(); 38 | if ($data != null) { 39 | return true; 40 | } 41 | return false; 42 | } 43 | 44 | public static function getClass($search = null) 45 | { 46 | $user = Auth::user(); 47 | if ($user->account_type == User::ACCOUNT_TYPE_TEACHER) { 48 | return self::where('class_name', 'like', '%' . $search . '%')->where('teacher_id', $user->id)->get(); 49 | } 50 | return self::where('class_name', 'like', '%' . $search . '%')->get(); 51 | } 52 | 53 | public function getTeacher() 54 | { 55 | return $this->hasOne('App\Model\User\User', 'id', 'teacher_id'); 56 | } 57 | 58 | public function getSiswa() 59 | { 60 | return $this->belongsTo('App\Model\Siswa\Siswa'); 61 | } 62 | 63 | public function hasUser() 64 | { 65 | return $this->belongsToMany(User::class, 'tbl_class_user', 'class_id', 'user_id'); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/Model/StudentClass/Tugas.php: -------------------------------------------------------------------------------- 1 | 'string', 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /app/Model/User/UserLoginHistory.php: -------------------------------------------------------------------------------- 1 | 'required | integer', 21 | 'last_login_ip' => 'required | string', 22 | 'date' => 'required | date', 23 | ]; 24 | 25 | protected $hidden = []; 26 | 27 | public static function findLastlogin() 28 | { 29 | return self::orderBy('created_at', 'desc')->first(); 30 | } 31 | 32 | public function getUser() 33 | { 34 | return $this->hasOne('App\Model\User\User', 'id', 'user_id'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/Model/User/UserToken.php: -------------------------------------------------------------------------------- 1 | 'required | unique', 19 | 'token' => 'string | unique', 20 | 'date_expired' => 'required | integer' 21 | ]; 22 | 23 | protected $hidden = []; 24 | } 25 | -------------------------------------------------------------------------------- /app/Model/UserNotification/UserNotification.php: -------------------------------------------------------------------------------- 1 | 'required | interger', 31 | 'notification_id' => 'required | interger', 32 | 'status' => 'required | interger' 33 | ]; 34 | 35 | /** 36 | * The attributes excluded from the model's JSON form. 37 | * 38 | * @var array 39 | */ 40 | protected $hidden = []; 41 | 42 | /** 43 | * 44 | */ 45 | public function getUser() 46 | { 47 | return $this->hasOne('App\Model\User\User','id','user_id'); 48 | } 49 | 50 | /** 51 | * 52 | */ 53 | public function getNotification() 54 | { 55 | return $this->hasOne('App\Model\Notification\Notification','id','notification_id'); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /app/Notifications/ResetPasswordNotification.php: -------------------------------------------------------------------------------- 1 | token); 18 | } 19 | return (new MailMessage) 20 | ->line('Kami telah menerima permintaan reset password dari akun anda.') 21 | ->action('Reset Password', route('password.reset.token', ['token' => $this->token])) 22 | ->line('Abaikan pesan ini apabila anda tidak melakukan permintaan ini.') 23 | ->subject('Permintaan perubahan Password'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Providers/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | 'App\Policies\ModelPolicy', 17 | ]; 18 | 19 | /** 20 | * Register any authentication / authorization services. 21 | * 22 | * @return void 23 | */ 24 | public function boot() 25 | { 26 | $this->registerPolicies(); 27 | 28 | // 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | [ 19 | SendEmailVerificationNotification::class, 20 | ], 21 | ]; 22 | 23 | /** 24 | * Register any events for your application. 25 | * 26 | * @return void 27 | */ 28 | public function boot() 29 | { 30 | parent::boot(); 31 | 32 | // 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/Providers/RouteServiceProvider.php: -------------------------------------------------------------------------------- 1 | mapApiRoutes(); 46 | 47 | $this->mapWebRoutes(); 48 | 49 | // 50 | } 51 | 52 | /** 53 | * Define the "web" routes for the application. 54 | * 55 | * These routes all receive session state, CSRF protection, etc. 56 | * 57 | * @return void 58 | */ 59 | protected function mapWebRoutes() 60 | { 61 | Route::middleware('web') 62 | ->namespace($this->namespace) 63 | ->group(base_path('routes/web.php')); 64 | } 65 | 66 | /** 67 | * Define the "api" routes for the application. 68 | * 69 | * These routes are typically stateless. 70 | * 71 | * @return void 72 | */ 73 | protected function mapApiRoutes() 74 | { 75 | Route::prefix('api') 76 | ->middleware('api') 77 | ->namespace($this->namespace) 78 | ->group(base_path('routes/api.php')); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /artisan: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | make(Illuminate\Contracts\Console\Kernel::class); 34 | 35 | $status = $kernel->handle( 36 | $input = new Symfony\Component\Console\Input\ArgvInput, 37 | new Symfony\Component\Console\Output\ConsoleOutput 38 | ); 39 | 40 | /* 41 | |-------------------------------------------------------------------------- 42 | | Shutdown The Application 43 | |-------------------------------------------------------------------------- 44 | | 45 | | Once Artisan has finished running, we will fire off the shutdown events 46 | | so that any final work may be done by the application before we shut 47 | | down the process. This is the last thing to happen to the request. 48 | | 49 | */ 50 | 51 | $kernel->terminate($input, $status); 52 | 53 | exit($status); 54 | -------------------------------------------------------------------------------- /bootstrap/app.php: -------------------------------------------------------------------------------- 1 | singleton( 30 | Illuminate\Contracts\Http\Kernel::class, 31 | App\Http\Kernel::class 32 | ); 33 | 34 | $app->singleton( 35 | Illuminate\Contracts\Console\Kernel::class, 36 | App\Console\Kernel::class 37 | ); 38 | 39 | $app->singleton( 40 | Illuminate\Contracts\Debug\ExceptionHandler::class, 41 | App\Exceptions\Handler::class 42 | ); 43 | 44 | /* 45 | |-------------------------------------------------------------------------- 46 | | Return The Application 47 | |-------------------------------------------------------------------------- 48 | | 49 | | This script returns the application instance. The instance is given to 50 | | the calling script so we can separate the building of the instances 51 | | from the actual running of the application and sending responses. 52 | | 53 | */ 54 | 55 | return $app; 56 | -------------------------------------------------------------------------------- /bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laravel/laravel", 3 | "type": "project", 4 | "description": "The Laravel Framework.", 5 | "keywords": [ 6 | "framework", 7 | "laravel" 8 | ], 9 | "license": "MIT", 10 | "require": { 11 | "php": "^7.1.3", 12 | "barryvdh/laravel-dompdf": "^0.8.4", 13 | "davejamesmiller/laravel-breadcrumbs": "5.x", 14 | "fideloper/proxy": "^4.0", 15 | "intervention/image": "^2.5", 16 | "laravel/framework": "5.8.*", 17 | "laravel/tinker": "^1.0", 18 | "spatie/laravel-permission": "^2.37", 19 | "tucker-eric/eloquentfilter": "^1.4", 20 | "yajra/laravel-datatables-oracle": "~9.0", 21 | "nesbot/carbon": "2.29.1 as 1.39.0", 22 | "kylekatarnls/laravel-carbon-2": "^1.0.0" 23 | }, 24 | "require-dev": { 25 | "beyondcode/laravel-dump-server": "^1.0", 26 | "filp/whoops": "^2.0", 27 | "fzaninotto/faker": "^1.4", 28 | "mockery/mockery": "^1.0", 29 | "nunomaduro/collision": "^3.0", 30 | "phpunit/phpunit": "^7.5" 31 | }, 32 | "config": { 33 | "optimize-autoloader": true, 34 | "preferred-install": "dist", 35 | "sort-packages": true 36 | }, 37 | "extra": { 38 | "laravel": { 39 | "dont-discover": [] 40 | } 41 | }, 42 | "autoload": { 43 | "psr-4": { 44 | "App\\": "app/" 45 | }, 46 | "classmap": [ 47 | "database/seeds", 48 | "database/factories" 49 | ] 50 | }, 51 | "autoload-dev": { 52 | "psr-4": { 53 | "Tests\\": "tests/" 54 | } 55 | }, 56 | "minimum-stability": "dev", 57 | "prefer-stable": true, 58 | "scripts": { 59 | "post-autoload-dump": [ 60 | "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", 61 | "@php artisan package:discover --ansi" 62 | ], 63 | "post-root-package-install": [ 64 | "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" 65 | ], 66 | "post-create-project-cmd": [ 67 | "@php artisan key:generate --ansi" 68 | ] 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /config/broadcasting.php: -------------------------------------------------------------------------------- 1 | env('BROADCAST_DRIVER', 'null'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Broadcast Connections 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may define all of the broadcast connections that will be used 26 | | to broadcast events to other systems or over websockets. Samples of 27 | | each available type of connection are provided inside this array. 28 | | 29 | */ 30 | 31 | 'connections' => [ 32 | 33 | 'pusher' => [ 34 | 'driver' => 'pusher', 35 | 'key' => env('PUSHER_APP_KEY'), 36 | 'secret' => env('PUSHER_APP_SECRET'), 37 | 'app_id' => env('PUSHER_APP_ID'), 38 | 'options' => [ 39 | 'cluster' => env('PUSHER_APP_CLUSTER'), 40 | 'encrypted' => true, 41 | ], 42 | ], 43 | 44 | 'redis' => [ 45 | 'driver' => 'redis', 46 | 'connection' => 'default', 47 | ], 48 | 49 | 'log' => [ 50 | 'driver' => 'log', 51 | ], 52 | 53 | 'null' => [ 54 | 'driver' => 'null', 55 | ], 56 | 57 | ], 58 | 59 | ]; 60 | -------------------------------------------------------------------------------- /config/hashing.php: -------------------------------------------------------------------------------- 1 | 'bcrypt', 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Bcrypt Options 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may specify the configuration options that should be used when 26 | | passwords are hashed using the Bcrypt algorithm. This will allow you 27 | | to control the amount of time it takes to hash the given password. 28 | | 29 | */ 30 | 31 | 'bcrypt' => [ 32 | 'rounds' => env('BCRYPT_ROUNDS', 10), 33 | ], 34 | 35 | /* 36 | |-------------------------------------------------------------------------- 37 | | Argon Options 38 | |-------------------------------------------------------------------------- 39 | | 40 | | Here you may specify the configuration options that should be used when 41 | | passwords are hashed using the Argon algorithm. These will allow you 42 | | to control the amount of time it takes to hash the given password. 43 | | 44 | */ 45 | 46 | 'argon' => [ 47 | 'memory' => 1024, 48 | 'threads' => 2, 49 | 'time' => 2, 50 | ], 51 | 52 | ]; 53 | -------------------------------------------------------------------------------- /config/services.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => env('MAILGUN_DOMAIN'), 19 | 'secret' => env('MAILGUN_SECRET'), 20 | 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), 21 | ], 22 | 23 | 'postmark' => [ 24 | 'token' => env('POSTMARK_TOKEN'), 25 | ], 26 | 27 | 'ses' => [ 28 | 'key' => env('AWS_ACCESS_KEY_ID'), 29 | 'secret' => env('AWS_SECRET_ACCESS_KEY'), 30 | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 31 | ], 32 | 33 | 'sparkpost' => [ 34 | 'secret' => env('SPARKPOST_SECRET'), 35 | ], 36 | 37 | 'stripe' => [ 38 | 'model' => App\User::class, 39 | 'key' => env('STRIPE_KEY'), 40 | 'secret' => env('STRIPE_SECRET'), 41 | 'webhook' => [ 42 | 'secret' => env('STRIPE_WEBHOOK_SECRET'), 43 | 'tolerance' => env('STRIPE_WEBHOOK_TOLERANCE', 300), 44 | ], 45 | ], 46 | 47 | ]; 48 | -------------------------------------------------------------------------------- /config/view.php: -------------------------------------------------------------------------------- 1 | [ 17 | resource_path('views'), 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled View Path 23 | |-------------------------------------------------------------------------- 24 | | 25 | | This option determines where all the compiled Blade templates will be 26 | | stored for your application. Typically, this is within the storage 27 | | directory. However, as usual, you are free to change this value. 28 | | 29 | */ 30 | 31 | 'compiled' => env( 32 | 'VIEW_COMPILED_PATH', 33 | realpath(storage_path('framework/views')) 34 | ), 35 | 36 | ]; 37 | -------------------------------------------------------------------------------- /database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite 2 | *.sqlite-journal 3 | -------------------------------------------------------------------------------- /database/factories/UserFactory.php: -------------------------------------------------------------------------------- 1 | define(User::class, function (Faker $faker) { 20 | return [ 21 | 'name' => $faker->name, 22 | 'email' => $faker->unique()->safeEmail, 23 | 'email_verified_at' => now(), 24 | 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password 25 | 'remember_token' => Str::random(10), 26 | ]; 27 | }); 28 | -------------------------------------------------------------------------------- /database/migrations/2019_07_03_041141_create_user_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id', 20); 16 | $table->string('username'); 17 | $table->string('password'); 18 | $table->string('account_type')->default('Creator'); 19 | $table->string('full_name')->nullable(); 20 | $table->string('email')->nullable()->unique(); 21 | $table->string('jenis_kelamin')->nullable(); 22 | $table->unsignedBigInteger('angkatan')->nullable(); 23 | $table->string('kelas')->nullable(); 24 | $table->string('profile_picture')->nullable(); 25 | $table->timestamp('email_verified_at')->nullable(); 26 | $table->rememberToken(); 27 | $table->datetime('last_login_at')->nullable(); 28 | $table->string('last_login_ip')->nullable(); 29 | $table->timestamp('created_at')->default(\DB::raw('CURRENT_TIMESTAMP')); 30 | $table->timestamp('updated_at')->default(\DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP')); 31 | }); 32 | } 33 | 34 | /** 35 | * Reverse the migrations. 36 | * 37 | * @return void 38 | */ 39 | public function down() { 40 | Schema::dropIfExists('tbl_user'); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /database/migrations/2019_07_03_042750_create_class_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id', 20); 16 | $table->string('class_name'); 17 | $table->string('angkatan'); 18 | $table->string('kelas'); 19 | $table->string('note')->nullable(); 20 | $table->unsignedBigInteger('teacher_id'); 21 | $table->string('token')->unique(); 22 | $table->timestamp('created_at')->default(\DB::raw('CURRENT_TIMESTAMP')); 23 | $table->timestamp('updated_at')->default(\DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP')); 24 | 25 | $table->foreign('teacher_id') 26 | ->references('id') 27 | ->on('tbl_user') 28 | ->onDelete('cascade'); 29 | }); 30 | } 31 | 32 | /** 33 | * Reverse the migrations. 34 | * 35 | * @return void 36 | */ 37 | public function down() { 38 | Schema::dropIfExists('tbl_class'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /database/migrations/2019_07_03_043613_create_user_token_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id', 20); 18 | $table->unsignedBigInteger('user_id'); 19 | $table->longText('token'); 20 | $table->integer('date_expired'); 21 | $table->timestamp('created_at')->default(\DB::raw('CURRENT_TIMESTAMP')); 22 | $table->timestamp('updated_at')->default(\DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP')); 23 | 24 | $table->foreign('user_id') 25 | ->references('id') 26 | ->on('tbl_user') 27 | ->onDelete('cascade'); 28 | 29 | }); 30 | 31 | } 32 | 33 | /** 34 | * Reverse the migrations. 35 | * 36 | * @return void 37 | */ 38 | public function down() 39 | { 40 | Schema::dropIfExists('tbl_user_token'); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /database/migrations/2019_07_03_044924_create_sytem_log_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id', 20); 18 | $table->text('action'); 19 | $table->dateTime('date'); 20 | $table->unsignedBigInteger('user_id')->unique(); 21 | $table->timestamp('created_at')->default(\DB::raw('CURRENT_TIMESTAMP')); 22 | $table->timestamp('updated_at')->default(\DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP')); 23 | 24 | $table->foreign('user_id') 25 | ->references('id') 26 | ->on('tbl_user') 27 | ->onDelete('cascade'); 28 | }); 29 | 30 | } 31 | 32 | /** 33 | * Reverse the migrations. 34 | * 35 | * @return void 36 | */ 37 | public function down() 38 | { 39 | Schema::dropIfExists('tbl_system_log'); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /database/migrations/2019_07_03_074842_create_global_setting_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id', 20); 18 | $table->tinyInteger('use_log_setting')->default(10); 19 | $table->tinyInteger('use_log_print')->default(10); 20 | $table->timestamp('created_at')->default(\DB::raw('CURRENT_TIMESTAMP')); 21 | $table->timestamp('updated_at')->default(\DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP')); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | * 28 | * @return void 29 | */ 30 | public function down() 31 | { 32 | Schema::dropIfExists('tbl_global_setting'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /database/migrations/2019_09_05_011908_create_action_log.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id'); 19 | $table->unsignedBigInteger('user_id')->nullable(); 20 | $table->integer('action_type'); 21 | $table->integer('is_error'); 22 | $table->string('action_message'); 23 | $table->dateTime('date'); 24 | $table->timestamp('created_at')->default(\DB::raw('CURRENT_TIMESTAMP')); 25 | $table->timestamp('updated_at')->default(\DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP')); 26 | 27 | $table->foreign('user_id') 28 | ->references('id') 29 | ->on('tbl_user') 30 | ->onDelete('set null'); 31 | 32 | }); 33 | } 34 | 35 | /** 36 | * Reverse the migrations. 37 | * 38 | * @return void 39 | */ 40 | public function down() 41 | { 42 | Schema::dropIfExists('tbl_action_log'); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /database/migrations/2020_01_31_213915_create_notification.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id'); 21 | $table->integer('notification_type'); 22 | $table->string('notification_title'); 23 | $table->string('notification_message'); 24 | $table->dateTime('date'); 25 | $table->timestamp('created_at')->default(\DB::raw('CURRENT_TIMESTAMP')); 26 | $table->timestamp('updated_at')->default(\DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP')); 27 | }); 28 | } 29 | 30 | /** 31 | * Reverse the migrations. 32 | * 33 | * @return void 34 | */ 35 | public function down() 36 | { 37 | Schema::dropIfExists('tbl_notification'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /database/migrations/2020_02_02_005836_create_user_notification.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id'); 18 | $table->unsignedBigInteger('user_id')->nullable(); 19 | $table->unsignedBigInteger('notification_id')->nullable(); 20 | $table->integer('status'); 21 | $table->timestamp('created_at')->default(\DB::raw('CURRENT_TIMESTAMP')); 22 | $table->timestamp('updated_at')->default(\DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP')); 23 | 24 | $table->foreign('user_id') 25 | ->references('id') 26 | ->on('tbl_user') 27 | ->onDelete('set null'); 28 | $table->foreign('notification_id') 29 | ->references('id') 30 | ->on('tbl_notification') 31 | ->onDelete('set null'); 32 | }); 33 | } 34 | 35 | /** 36 | * Reverse the migrations. 37 | * 38 | * @return void 39 | */ 40 | public function down() 41 | { 42 | Schema::dropIfExists('tbl_user_notification'); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /database/migrations/2020_02_02_005837_create_password_resets_table.php: -------------------------------------------------------------------------------- 1 | string('email')->index(); 18 | $table->string('token'); 19 | $table->timestamp('created_at')->nullable(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('password_resets'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2020_02_13_130004_create_user_login_history.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id', 20); 19 | $table->unsignedBigInteger('user_id'); 20 | $table->string('last_login_ip')->nullable(); 21 | $table->dateTime('date')->nullable(); 22 | $table->timestamp('created_at')->default(\DB::raw('CURRENT_TIMESTAMP')); 23 | $table->timestamp('updated_at')->default(\DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP')); 24 | 25 | $table->foreign('user_id') 26 | ->references('id') 27 | ->on('tbl_user') 28 | ->onDelete('cascade'); 29 | }); 30 | 31 | } 32 | 33 | /** 34 | * Reverse the migrations. 35 | * 36 | * @return void 37 | */ 38 | public function down() 39 | { 40 | Schema::dropIfExists('tbl_user_login_history'); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /database/migrations/2020_06_25_060711_create_feed_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id', 20); 18 | $table->string('judul'); 19 | $table->string('kategori'); 20 | $table->text('detail'); 21 | $table->string('file')->nullable(); 22 | $table->date('deadline')->nullable(); 23 | $table->unsignedBigInteger('class_id'); 24 | $table->timestamp('created_at')->default(\DB::raw('CURRENT_TIMESTAMP')); 25 | $table->timestamp('updated_at')->default(\DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP')); 26 | 27 | $table->foreign('class_id') 28 | ->references('id') 29 | ->on('tbl_class') 30 | ->onDelete('cascade'); 31 | }); 32 | } 33 | 34 | /** 35 | * Reverse the migrations. 36 | * 37 | * @return void 38 | */ 39 | public function down() 40 | { 41 | Schema::dropIfExists('tbl_feed'); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /database/migrations/2020_06_25_060752_create_tugas_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id', 20); 16 | $table->string('file')->nullable(); 17 | $table->integer('nilai')->nullable(); 18 | $table->unsignedBigInteger('siswa_id'); 19 | $table->unsignedBigInteger('class_id'); 20 | $table->unsignedBigInteger('feed_id'); 21 | $table->timestamp('created_at')->default(\DB::raw('CURRENT_TIMESTAMP')); 22 | $table->timestamp('updated_at')->default(\DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP')); 23 | 24 | $table->foreign('siswa_id') 25 | ->references('id') 26 | ->on('tbl_user') 27 | ->onDelete('cascade'); 28 | $table->foreign('class_id') 29 | ->references('id') 30 | ->on('tbl_class') 31 | ->onDelete('cascade'); 32 | $table->foreign('feed_id') 33 | ->references('id') 34 | ->on('tbl_feed') 35 | ->onDelete('cascade'); 36 | }); 37 | } 38 | 39 | /** 40 | * Reverse the migrations. 41 | * 42 | * @return void 43 | */ 44 | public function down() { 45 | Schema::dropIfExists('tbl_class'); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /database/migrations/2020_06_26_060712_create_class_user_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id', 20); 18 | $table->unsignedBigInteger('class_id'); 19 | $table->unsignedBigInteger('user_id'); 20 | $table->timestamp('created_at')->default(\DB::raw('CURRENT_TIMESTAMP')); 21 | $table->timestamp('updated_at')->default(\DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP')); 22 | 23 | $table->foreign('class_id') 24 | ->references('id') 25 | ->on('tbl_class') 26 | ->onDelete('cascade'); 27 | $table->foreign('user_id') 28 | ->references('id') 29 | ->on('tbl_user') 30 | ->onDelete('cascade'); 31 | }); 32 | } 33 | 34 | /** 35 | * Reverse the migrations. 36 | * 37 | * @return void 38 | */ 39 | public function down() 40 | { 41 | Schema::dropIfExists('tbl_class_user'); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /database/seeds/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | call([ 17 | UsersTableSeeder::class, 18 | ]); 19 | } 20 | } -------------------------------------------------------------------------------- /database/seeds/UsersTableSeeder.php: -------------------------------------------------------------------------------- 1 | insert([ 19 | 'username' => 'creator', 20 | 'email' => 'creator@ouroom.com', 21 | 'password' => Hash::make('creatoratm'), 22 | 'full_name' => 'Super Admin', 23 | 'account_type' => 'Creator' 24 | ]); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /keybindings.json: -------------------------------------------------------------------------------- 1 | { 2 | "key": "cmd+b", 3 | "command": "HookyQR.beautify", 4 | "when": "editorFocus" 5 | } -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | git: 2 | git add . 3 | git commit -m "$m" 4 | git push -u origin master -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "npm run development", 5 | "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 6 | "watch": "npm run development -- --watch", 7 | "watch-poll": "npm run watch -- --watch-poll", 8 | "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", 9 | "prod": "npm run production", 10 | "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" 11 | }, 12 | "devDependencies": { 13 | "axios": "^0.18", 14 | "bootstrap": "^4.1.0", 15 | "cross-env": "^5.1", 16 | "jquery": "^3.2", 17 | "laravel-mix": "^4.0.7", 18 | "lodash": "^4.17.5", 19 | "popper.js": "^1.12", 20 | "resolve-url-loader": "^2.3.1", 21 | "sass": "^1.15.2", 22 | "sass-loader": "^7.1.0", 23 | "vue": "^2.5.17" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | ./tests/Unit 14 | 15 | 16 | 17 | ./tests/Feature 18 | 19 | 20 | 21 | 22 | ./app 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews -Indexes 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Handle Authorization Header 9 | RewriteCond %{HTTP:Authorization} . 10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 11 | 12 | # Redirect Trailing Slashes If Not A Folder... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_URI} (.+)/$ 15 | RewriteRule ^ %1 [L,R=301] 16 | 17 | # Handle Front Controller... 18 | RewriteCond %{REQUEST_FILENAME} !-d 19 | RewriteCond %{REQUEST_FILENAME} !-f 20 | RewriteRule ^ index.php [L] 21 | 22 | -------------------------------------------------------------------------------- /public/asset/auth.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/asset/auth.jpeg -------------------------------------------------------------------------------- /public/asset/file_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/asset/file_thumb.png -------------------------------------------------------------------------------- /public/asset/ouroom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/asset/ouroom.png -------------------------------------------------------------------------------- /public/asset_user/Creator/Super Admin/WhatsApp Image 2020-07-23 at 06.23.07.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/asset_user/Creator/Super Admin/WhatsApp Image 2020-07-23 at 06.23.07.jpeg -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/favicon.ico -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | define('LARAVEL_START', microtime(true)); 11 | 12 | /* 13 | |-------------------------------------------------------------------------- 14 | | Register The Auto Loader 15 | |-------------------------------------------------------------------------- 16 | | 17 | | Composer provides a convenient, automatically generated class loader for 18 | | our application. We just need to utilize it! We'll simply require it 19 | | into the script here so that we don't have to worry about manual 20 | | loading any of our classes later on. It feels great to relax. 21 | | 22 | */ 23 | 24 | require __DIR__.'/../vendor/autoload.php'; 25 | 26 | /* 27 | |-------------------------------------------------------------------------- 28 | | Turn On The Lights 29 | |-------------------------------------------------------------------------- 30 | | 31 | | We need to illuminate PHP development, so let us turn on the lights. 32 | | This bootstraps the framework and gets it ready for use, then it 33 | | will load up this application so that we can run it and send 34 | | the responses back to the browser and delight our users. 35 | | 36 | */ 37 | 38 | $app = require_once __DIR__.'/../bootstrap/app.php'; 39 | 40 | /* 41 | |-------------------------------------------------------------------------- 42 | | Run The Application 43 | |-------------------------------------------------------------------------- 44 | | 45 | | Once we have the application, we can handle the incoming request 46 | | through the kernel, and send the associated response back to 47 | | the client's browser allowing them to enjoy the creative 48 | | and wonderful application we have prepared for them. 49 | | 50 | */ 51 | 52 | $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); 53 | 54 | $response = $kernel->handle( 55 | $request = Illuminate\Http\Request::capture() 56 | ); 57 | 58 | $response->send(); 59 | 60 | $kernel->terminate($request, $response); 61 | -------------------------------------------------------------------------------- /public/layout/assets/css/additional_css.css: -------------------------------------------------------------------------------- 1 | .form-gap { 2 | padding-top: 70px; 3 | } 4 | 5 | .logoreset { 6 | background-color:#2F4F4F; 7 | } 8 | 9 | fieldset 10 | { 11 | border: 1px solid #ddd !important; 12 | margin: 0; 13 | xmin-width: 0; 14 | padding: 10px; 15 | position: relative; 16 | border-radius:4px; 17 | background-color:#f5f5f5; 18 | padding-left:10px!important; 19 | } 20 | 21 | legend 22 | { 23 | font-size:14px; 24 | font-weight:bold; 25 | margin-bottom: 0px; 26 | min-width: 35%; 27 | width: auto; 28 | border: 1px solid #ddd; 29 | border-radius: 4px; 30 | padding: 5px 5px 5px 10px; 31 | background-color: #ffffff; 32 | } 33 | 34 | 35 | /*Profile PP*/ 36 | 37 | .inputfile { 38 | width: 0.1px; 39 | height: 0.1px; 40 | opacity: 0; 41 | overflow: hidden; 42 | position: absolute; 43 | z-index: -1; 44 | } 45 | 46 | .inputfile + label { 47 | font-size: 1.25em; 48 | font-weight: 700; 49 | color: #9a9a9a; 50 | border: 2px solid #286cd2; 51 | border-radius: 5px; 52 | display: inline-block; 53 | padding: 0 10px; 54 | } 55 | 56 | .inputfile:focus + label, 57 | .inputfile + label:hover { 58 | background-color: #2185d0; 59 | color: white; 60 | } 61 | 62 | .inputfile + label { 63 | cursor: pointer; /* "hand" cursor */ 64 | } 65 | 66 | .inputfile:focus + label { 67 | outline: 1px dotted #000; 68 | outline: -webkit-focus-ring-color auto 5px; 69 | } 70 | 71 | .center-cropped { 72 | width: 100px; 73 | height: 100px; 74 | background-position: center center; 75 | background-repeat: no-repeat; 76 | } 77 | 78 | .content h3{ 79 | margin: 0px 0px 10px !important; 80 | } 81 | 82 | .card{ 83 | margin-bottom: 5px !important; 84 | } -------------------------------------------------------------------------------- /public/layout/assets/fonts/Pe-icon-7-stroke.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/layout/assets/fonts/Pe-icon-7-stroke.eot -------------------------------------------------------------------------------- /public/layout/assets/fonts/Pe-icon-7-stroke.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/layout/assets/fonts/Pe-icon-7-stroke.ttf -------------------------------------------------------------------------------- /public/layout/assets/fonts/Pe-icon-7-stroke.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/layout/assets/fonts/Pe-icon-7-stroke.woff -------------------------------------------------------------------------------- /public/layout/assets/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/layout/assets/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /public/layout/assets/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/layout/assets/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /public/layout/assets/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/layout/assets/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /public/layout/assets/images/sort_asc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/layout/assets/images/sort_asc.png -------------------------------------------------------------------------------- /public/layout/assets/images/sort_asc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/layout/assets/images/sort_asc_disabled.png -------------------------------------------------------------------------------- /public/layout/assets/images/sort_both.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/layout/assets/images/sort_both.png -------------------------------------------------------------------------------- /public/layout/assets/images/sort_desc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/layout/assets/images/sort_desc.png -------------------------------------------------------------------------------- /public/layout/assets/images/sort_desc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/layout/assets/images/sort_desc_disabled.png -------------------------------------------------------------------------------- /public/layout/assets/modules/datatables/DataTables-1.10.16/images/sort_asc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/layout/assets/modules/datatables/DataTables-1.10.16/images/sort_asc.png -------------------------------------------------------------------------------- /public/layout/assets/modules/datatables/DataTables-1.10.16/images/sort_asc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/layout/assets/modules/datatables/DataTables-1.10.16/images/sort_asc_disabled.png -------------------------------------------------------------------------------- /public/layout/assets/modules/datatables/DataTables-1.10.16/images/sort_both.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/layout/assets/modules/datatables/DataTables-1.10.16/images/sort_both.png -------------------------------------------------------------------------------- /public/layout/assets/modules/datatables/DataTables-1.10.16/images/sort_desc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/layout/assets/modules/datatables/DataTables-1.10.16/images/sort_desc.png -------------------------------------------------------------------------------- /public/layout/assets/modules/datatables/DataTables-1.10.16/images/sort_desc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kurnyaannn/ouroom-project/ffd7df598ee81e8d9a920cedc8ae36ff6b2ec60f/public/layout/assets/modules/datatables/DataTables-1.10.16/images/sort_desc_disabled.png -------------------------------------------------------------------------------- /public/layout/assets/modules/datatables/DataTables-1.10.16/js/dataTables.bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | DataTables Bootstrap 3 integration 3 | ©2011-2015 SpryMedia Ltd - datatables.net/license 4 | */ 5 | (function(b){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(a){return b(a,window,document)}):"object"===typeof exports?module.exports=function(a,d){a||(a=window);if(!d||!d.fn.dataTable)d=require("datatables.net")(a,d).$;return b(d,a,a.document)}:b(jQuery,window,document)})(function(b,a,d,m){var f=b.fn.dataTable;b.extend(!0,f.defaults,{dom:"<'row'<'col-sm-6'l><'col-sm-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-5'i><'col-sm-7'p>>",renderer:"bootstrap"});b.extend(f.ext.classes, 6 | {sWrapper:"dataTables_wrapper form-inline dt-bootstrap",sFilterInput:"form-control input-sm",sLengthSelect:"form-control input-sm",sProcessing:"dataTables_processing panel panel-default"});f.ext.renderer.pageButton.bootstrap=function(a,h,r,s,j,n){var o=new f.Api(a),t=a.oClasses,k=a.oLanguage.oPaginate,u=a.oLanguage.oAria.paginate||{},e,g,p=0,q=function(d,f){var l,h,i,c,m=function(a){a.preventDefault();!b(a.currentTarget).hasClass("disabled")&&o.page()!=a.data.action&&o.page(a.data.action).draw("page")}; 7 | l=0;for(h=f.length;l",{"class":t.sPageButton+" "+g,id:0===r&&"string"===typeof c?a.sTableId+"_"+c:null}).append(b("",{href:"#", 8 | "aria-controls":a.sTableId,"aria-label":u[c],"data-dt-idx":p,tabindex:a.iTabIndex}).html(e)).appendTo(d),a.oApi._fnBindAction(i,{action:c},m),p++)}},i;try{i=b(h).find(d.activeElement).data("dt-idx")}catch(v){}q(b(h).empty().html('