├── public ├── favicon.ico ├── robots.txt ├── .DS_Store ├── sekitarkita.apk ├── images │ ├── sekitar.png │ ├── sikm │ │ ├── ttd.png │ │ └── kop-sikm.png │ ├── markers │ │ ├── m1.png │ │ ├── m2.png │ │ ├── m3.png │ │ ├── m4.png │ │ ├── m5.png │ │ ├── odp.png │ │ ├── pdp.png │ │ ├── confirmed.png │ │ ├── healthy.png │ │ ├── odp-online.gif │ │ ├── pdp-online.gif │ │ ├── healthy-online.gif │ │ └── confirmed-online.gif │ ├── sekitarkitalogo.png │ ├── vendor │ │ └── leaflet │ │ │ └── dist │ │ │ ├── layers.png │ │ │ ├── layers-2x.png │ │ │ ├── marker-icon.png │ │ │ ├── marker-icon-2x.png │ │ │ └── marker-shadow.png │ └── icons │ │ └── smartphone.svg ├── sekitarkitalogo.png ├── fonts │ ├── feather-webfont.eot │ ├── feather-webfont.ttf │ └── feather-webfont.woff ├── mix-manifest.json ├── vendor │ └── nova │ │ ├── mix-manifest.json │ │ └── manifest.js ├── .htaccess └── index.php ├── resources ├── sass │ └── tabler │ │ ├── _infobox.scss │ │ ├── _functions.scss │ │ ├── _product.scss │ │ ├── _badge.scss │ │ ├── fonts │ │ └── feather │ │ │ ├── feather-webfont.eot │ │ │ ├── feather-webfont.ttf │ │ │ └── feather-webfont.woff │ │ ├── _carousel.scss │ │ ├── _close.scss │ │ ├── _media.scss │ │ ├── _popover.scss │ │ ├── _image.scss │ │ ├── _social.scss │ │ ├── _footer.scss │ │ ├── _breadcrumb.scss │ │ ├── _stamp.scss │ │ ├── _list-group.scss │ │ ├── _alert.scss │ │ ├── _sparkline.scss │ │ ├── _link.scss │ │ ├── _colors.scss │ │ ├── _statuses.scss │ │ ├── _pagination.scss │ │ ├── _list.scss │ │ ├── _icon.scss │ │ ├── _utilities.scss │ │ ├── _text.scss │ │ ├── _aside.scss │ │ ├── _grid.scss │ │ ├── _core.scss │ │ ├── _chips.scss │ │ ├── _charts.scss │ │ ├── _maps.scss │ │ ├── forms │ │ ├── _custom-colorinput.scss │ │ ├── _custom-selectgroup.scss │ │ ├── _custom-switch.scss │ │ └── _custom-imagecheck.scss │ │ ├── _timeline.scss │ │ ├── tabler.scss │ │ ├── _dropdown.scss │ │ ├── _layout.scss │ │ ├── _chat.scss │ │ ├── _tag.scss │ │ ├── _syntax.scss │ │ ├── _type.scss │ │ ├── _nav.scss │ │ ├── _avatar.scss │ │ ├── _tables.scss │ │ ├── _button.scss │ │ └── _header.scss ├── js │ ├── app.js │ └── bootstrap.js ├── views │ ├── vendor │ │ └── nova │ │ │ └── partials │ │ │ ├── meta.blade.php │ │ │ ├── footer.blade.php │ │ │ └── user.blade.php │ ├── mapping │ │ ├── member.blade.php │ │ ├── device.blade.php │ │ ├── mapping-for-puppeteer.blade.php │ │ └── base.blade.php │ ├── errors │ │ └── 503.blade.php │ └── layouts │ │ └── app.blade.php └── lang │ ├── en │ ├── pagination.php │ ├── auth.php │ └── passwords.php │ └── vendor │ └── nova │ └── en │ └── validation.php ├── bootstrap ├── cache │ └── .gitignore └── app.php ├── storage ├── logs │ └── .gitignore ├── app │ ├── public │ │ └── .gitignore │ └── .gitignore └── framework │ ├── testing │ └── .gitignore │ ├── views │ └── .gitignore │ ├── cache │ ├── data │ │ └── .gitignore │ └── .gitignore │ ├── sessions │ └── .gitignore │ └── .gitignore ├── database ├── .gitignore ├── seeds │ ├── DatabaseSeeder.php │ └── NovaUserSeeder.php ├── migrations │ ├── 2020_04_18_021333_create_sequences_table.php │ ├── 2020_05_20_112154_create_zones_table.php │ ├── 2020_04_13_215843_create_partners_table.php │ ├── 2020_03_29_160931_create_call_centers_table.php │ ├── 2020_06_03_114029_alter_devices_table.php │ ├── 2020_06_03_114029_alter_self_checks_table.php │ ├── 2019_08_19_000000_create_failed_jobs_table.php │ ├── 2020_04_02_172703_alter_action_event_user_id.php │ ├── 2020_06_29_195420_alter_sikm_add_estimate.php │ ├── 2020_03_29_161421_create_hospitals_table.php │ ├── 2014_10_12_000000_create_users_table.php │ ├── 2020_03_21_120707_create_nearby_table.php │ ├── 2020_04_13_124152_create_device_logs_table.php │ ├── 2020_04_13_125858_create_change_requests_table.php │ ├── 2020_06_12_213131_create_sikm_table.php │ ├── 2020_05_26_155648_create_self_checks_table.php │ └── 2020_03_21_120110_create_devices_table.php └── factories │ └── UserFactory.php ├── .DS_Store ├── .gitattributes ├── app ├── Models │ ├── Partner.php │ ├── Zone.php │ ├── Hospital.php │ ├── CallCenter.php │ ├── ChangeRequest.php │ ├── SelfCheck.php │ ├── Kelurahan.php │ ├── Sequence.php │ ├── Provinsi.php │ ├── Kabupaten.php │ ├── Kecamatan.php │ ├── Nearby.php │ ├── User.php │ ├── DeviceLog.php │ ├── SIKM.php │ └── Device.php ├── Policies │ ├── HandlessPolicy.php │ ├── PartnerPolicy.php │ └── UserPolicy.php ├── Http │ ├── Middleware │ │ ├── EncryptCookies.php │ │ ├── VerifyCsrfToken.php │ │ ├── CheckForMaintenanceMode.php │ │ ├── TrimStrings.php │ │ ├── PartnerMiddleware.php │ │ ├── TrustProxies.php │ │ ├── Authenticate.php │ │ └── RedirectIfAuthenticated.php │ ├── Controllers │ │ ├── Controller.php │ │ ├── NovaLoginController.php │ │ └── Api │ │ │ └── AreaController.php │ └── Resources │ │ ├── NearbyCollection.php │ │ ├── CustomPaginatedResourceResponse.php │ │ ├── CallCenterResource.php │ │ └── HospitalResource.php ├── Providers │ ├── BroadcastServiceProvider.php │ ├── AppServiceProvider.php │ ├── AuthServiceProvider.php │ ├── EventServiceProvider.php │ └── RouteServiceProvider.php ├── Traits │ └── UuidIndex.php ├── Enums │ ├── SIKMCategory.php │ ├── Transportation.php │ ├── ZoneLevel.php │ ├── ChangeRequestStatus.php │ └── HealthStatus.php ├── Console │ └── Kernel.php ├── Nova │ ├── Actions │ │ ├── PendingSIKM.php │ │ ├── RejectSIKM.php │ │ └── ApproveSIKM.php │ ├── Filters │ │ ├── AreaFilter.php │ │ └── ChangeRequestFilter.php │ ├── Metrics │ │ ├── OnlineDevice.php │ │ ├── NewDevice.php │ │ ├── NewInteraction.php │ │ ├── DevicePerDay.php │ │ ├── HealthyUser.php │ │ ├── PDPUser.php │ │ ├── InteractionPerHour.php │ │ ├── InteractionPerMinutes.php │ │ ├── Devices.php │ │ ├── ODPUser.php │ │ ├── InteractionPerDay.php │ │ └── NearbyDevices.php │ ├── Resource.php │ ├── Kelurahan.php │ ├── Zone.php │ ├── Partner.php │ └── Provinsi.php ├── Exceptions │ └── Handler.php └── Observers │ └── ChangeRequestObserver.php ├── tests ├── TestCase.php ├── Unit │ └── ExampleTest.php ├── Feature │ └── ExampleTest.php └── CreatesApplication.php ├── .styleci.yml ├── .editorconfig ├── .gitignore ├── routes ├── channels.php ├── console.php ├── web.php └── api.php ├── server.php ├── webpack.mix.js ├── serverless.yml ├── config ├── cors.php ├── services.php ├── view.php ├── hashing.php └── broadcasting.php ├── .env.example ├── .github └── workflows │ └── sekitar-cicd.yml ├── phpunit.xml ├── package.json ├── artisan ├── composer.json └── README.md /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/sass/tabler/_infobox.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite 2 | *.sqlite-journal 3 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/cache/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !data/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/.DS_Store -------------------------------------------------------------------------------- /resources/js/app.js: -------------------------------------------------------------------------------- 1 | require('./bootstrap'); 2 | require('./utils'); 3 | 4 | 5 | -------------------------------------------------------------------------------- /public/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/.DS_Store -------------------------------------------------------------------------------- /resources/sass/tabler/_functions.scss: -------------------------------------------------------------------------------- 1 | @function px2rem($value) { 2 | @return $value/16px * 1rem; 3 | } -------------------------------------------------------------------------------- /public/sekitarkita.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/sekitarkita.apk -------------------------------------------------------------------------------- /public/images/sekitar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/sekitar.png -------------------------------------------------------------------------------- /public/images/sikm/ttd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/sikm/ttd.png -------------------------------------------------------------------------------- /public/sekitarkitalogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/sekitarkitalogo.png -------------------------------------------------------------------------------- /public/images/markers/m1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/markers/m1.png -------------------------------------------------------------------------------- /public/images/markers/m2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/markers/m2.png -------------------------------------------------------------------------------- /public/images/markers/m3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/markers/m3.png -------------------------------------------------------------------------------- /public/images/markers/m4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/markers/m4.png -------------------------------------------------------------------------------- /public/images/markers/m5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/markers/m5.png -------------------------------------------------------------------------------- /public/images/markers/odp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/markers/odp.png -------------------------------------------------------------------------------- /public/images/markers/pdp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/markers/pdp.png -------------------------------------------------------------------------------- /public/fonts/feather-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/fonts/feather-webfont.eot -------------------------------------------------------------------------------- /public/fonts/feather-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/fonts/feather-webfont.ttf -------------------------------------------------------------------------------- /public/images/sikm/kop-sikm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/sikm/kop-sikm.png -------------------------------------------------------------------------------- /public/fonts/feather-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/fonts/feather-webfont.woff -------------------------------------------------------------------------------- /public/images/markers/confirmed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/markers/confirmed.png -------------------------------------------------------------------------------- /public/images/markers/healthy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/markers/healthy.png -------------------------------------------------------------------------------- /public/images/sekitarkitalogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/sekitarkitalogo.png -------------------------------------------------------------------------------- /resources/sass/tabler/_product.scss: -------------------------------------------------------------------------------- 1 | .product-price { 2 | font-size: 1rem; 3 | 4 | strong { 5 | font-size: 1.5rem; 6 | } 7 | } -------------------------------------------------------------------------------- /public/images/markers/odp-online.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/markers/odp-online.gif -------------------------------------------------------------------------------- /public/images/markers/pdp-online.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/markers/pdp-online.gif -------------------------------------------------------------------------------- /public/images/markers/healthy-online.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/markers/healthy-online.gif -------------------------------------------------------------------------------- /resources/views/vendor/nova/partials/meta.blade.php: -------------------------------------------------------------------------------- 1 | {{-- --}} 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.css linguist-vendored 3 | *.scss linguist-vendored 4 | *.js linguist-vendored 5 | CHANGELOG.md export-ignore 6 | -------------------------------------------------------------------------------- /public/images/markers/confirmed-online.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/markers/confirmed-online.gif -------------------------------------------------------------------------------- /resources/sass/tabler/_badge.scss: -------------------------------------------------------------------------------- 1 | .badge { 2 | color: #fff; 3 | } 4 | 5 | .badge-default { 6 | background: $gray-200; 7 | color: $gray-600; 8 | } -------------------------------------------------------------------------------- /public/images/vendor/leaflet/dist/layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/vendor/leaflet/dist/layers.png -------------------------------------------------------------------------------- /public/images/vendor/leaflet/dist/layers-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/vendor/leaflet/dist/layers-2x.png -------------------------------------------------------------------------------- /public/images/vendor/leaflet/dist/marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/vendor/leaflet/dist/marker-icon.png -------------------------------------------------------------------------------- /public/mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/js/app.js": "/js/app.js?id=79d62ecf12587ab784b7", 3 | "/css/app.css": "/css/app.css?id=8f9e92b23f6642f2c392" 4 | } 5 | -------------------------------------------------------------------------------- /storage/framework/.gitignore: -------------------------------------------------------------------------------- 1 | config.php 2 | routes.php 3 | schedule-* 4 | compiled.php 5 | services.json 6 | events.scanned.php 7 | routes.scanned.php 8 | down 9 | -------------------------------------------------------------------------------- /public/images/vendor/leaflet/dist/marker-icon-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/vendor/leaflet/dist/marker-icon-2x.png -------------------------------------------------------------------------------- /public/images/vendor/leaflet/dist/marker-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/public/images/vendor/leaflet/dist/marker-shadow.png -------------------------------------------------------------------------------- /resources/sass/tabler/fonts/feather/feather-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/resources/sass/tabler/fonts/feather/feather-webfont.eot -------------------------------------------------------------------------------- /resources/sass/tabler/fonts/feather/feather-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/resources/sass/tabler/fonts/feather/feather-webfont.ttf -------------------------------------------------------------------------------- /resources/sass/tabler/fonts/feather/feather-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghuniyu/sekitarkita-backend/HEAD/resources/sass/tabler/fonts/feather/feather-webfont.woff -------------------------------------------------------------------------------- /app/Models/Partner.php: -------------------------------------------------------------------------------- 1 | morphTo(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /resources/sass/tabler/_media.scss: -------------------------------------------------------------------------------- 1 | .media-icon { 2 | width: 2rem; 3 | height: 2rem; 4 | line-height: 2rem; 5 | text-align: center; 6 | border-radius: 100%; 7 | } 8 | 9 | .media-list { 10 | margin: 0; 11 | padding: 0; 12 | list-style: none; 13 | } -------------------------------------------------------------------------------- /app/Models/Hospital.php: -------------------------------------------------------------------------------- 1 | morphTo(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/Models/CallCenter.php: -------------------------------------------------------------------------------- 1 | morphTo(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/Policies/HandlessPolicy.php: -------------------------------------------------------------------------------- 1 | .col, 7 | > [class*="col-"] { 8 | padding-left: .25rem; 9 | padding-right: .25rem; 10 | padding-bottom: .5rem; 11 | } 12 | } -------------------------------------------------------------------------------- /.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,yaml}] 15 | indent_size = 2 16 | -------------------------------------------------------------------------------- /resources/sass/tabler/_social.scss: -------------------------------------------------------------------------------- 1 | .social-links { 2 | li { 3 | a { 4 | background: #f8f8f8; 5 | border-radius: 50%; 6 | color: $text-muted; 7 | display: inline-block; 8 | height: 1.75rem; 9 | width: 1.75rem; 10 | line-height: 1.75rem; 11 | text-align: center; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /public/hot 3 | /public/storage 4 | /public/landing 5 | /storage/*.key 6 | /vendor 7 | /.idea/** 8 | /public/web.config 9 | *.apk 10 | .env 11 | .env.save 12 | .env.backup 13 | .phpunit.result.cache 14 | Homestead.json 15 | Homestead.yaml 16 | npm-debug.log 17 | yarn-error.log 18 | .serverless 19 | -------------------------------------------------------------------------------- /resources/sass/tabler/_footer.scss: -------------------------------------------------------------------------------- 1 | .footer { 2 | background: $footer-bg; 3 | border-top: $border-width solid $border-color; 4 | font-size: px2rem(14px); 5 | padding: 1.25rem 0; 6 | color: $text-muted; 7 | 8 | a:not(.btn) { 9 | color: $text-muted-dark; 10 | } 11 | 12 | @media print { 13 | display: none; 14 | } 15 | } -------------------------------------------------------------------------------- /resources/views/vendor/nova/partials/footer.blade.php: -------------------------------------------------------------------------------- 1 |

2 | SekitarKita 3 | · 4 | © {{ date('Y') }} Sekitar Kita - By Ghuniyu. 5 |

6 | -------------------------------------------------------------------------------- /database/seeds/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | call(NovaUserSeeder::class); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/Unit/ExampleTest.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /resources/sass/tabler/_breadcrumb.scss: -------------------------------------------------------------------------------- 1 | .page-breadcrumb { 2 | background: none; 3 | padding: 0; 4 | margin: 1rem 0 0; 5 | font-size: px2rem(14px); 6 | 7 | @include media-breakpoint-up(md) { 8 | margin: -.5rem 0 0; 9 | } 10 | 11 | .breadcrumb-item { 12 | color: $text-muted; 13 | 14 | &.active { 15 | color: $text-muted-dark; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /app/Models/ChangeRequest.php: -------------------------------------------------------------------------------- 1 | belongsTo(Device::class); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /resources/sass/tabler/_stamp.scss: -------------------------------------------------------------------------------- 1 | .stamp { 2 | color: #fff; 3 | background: $gray-600; 4 | display: inline-block; 5 | min-width: 2rem; 6 | height: 2rem; 7 | padding: 0 .25rem; 8 | line-height: 2rem; 9 | text-align: center; 10 | border-radius: 3px; 11 | font-weight: 600; 12 | } 13 | 14 | .stamp-md { 15 | min-width: 2.5rem; 16 | height: 2.5rem; 17 | line-height: 2.5rem; 18 | } -------------------------------------------------------------------------------- /app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | i { 9 | color: inherit !important; 10 | font-size: 1rem; 11 | position: absolute; 12 | top: 1rem; 13 | left: 1rem; 14 | } 15 | } 16 | 17 | .alert-avatar { 18 | padding-left: 3.75rem; 19 | 20 | .avatar { 21 | position: absolute; 22 | top: .5rem; 23 | left: .75rem; 24 | } 25 | } -------------------------------------------------------------------------------- /resources/views/mapping/member.blade.php: -------------------------------------------------------------------------------- 1 | @extends('mapping.base') 2 | @section('title', 'Mapping Member -') 3 | @push('js') 4 | 11 | @endpush 12 | -------------------------------------------------------------------------------- /app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | get('/'); 18 | 19 | $response->assertStatus(200); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /resources/sass/tabler/_sparkline.scss: -------------------------------------------------------------------------------- 1 | .sparkline { 2 | display: inline-block; 3 | height: 2rem; 4 | } 5 | 6 | .jqstooltip { 7 | box-sizing: content-box; 8 | font-family: inherit !important; 9 | background: #333 !important; 10 | border: none !important; 11 | border-radius: 3px; 12 | font-size: 11px !important; 13 | font-weight: 700 !important; 14 | line-height: 1 !important; 15 | padding: 6px !important; 16 | 17 | .jqsfield { 18 | font: inherit !important; 19 | } 20 | } -------------------------------------------------------------------------------- /resources/sass/tabler/_link.scss: -------------------------------------------------------------------------------- 1 | .link-overlay { 2 | position: relative; 3 | 4 | &:hover { 5 | .link-overlay-bg { 6 | opacity: 1; 7 | } 8 | } 9 | } 10 | 11 | .link-overlay-bg { 12 | position: absolute; 13 | top: 0; 14 | left: 0; 15 | right: 0; 16 | bottom: 0; 17 | background: rgba($blue, .8); 18 | display: flex; 19 | color: #fff; 20 | align-items: center; 21 | justify-content: center; 22 | font-size: px2rem(20px); 23 | opacity: 0; 24 | transition: .3s opacity; 25 | } -------------------------------------------------------------------------------- /resources/sass/tabler/_colors.scss: -------------------------------------------------------------------------------- 1 | @each $color, $value in $colors { 2 | @include bg-variant(".bg-#{$color}-lightest", mix($value, #fff, 10%)); 3 | @include bg-variant(".bg-#{$color}-lighter", mix($value, #fff, 30%)); 4 | @include bg-variant(".bg-#{$color}-light", mix($value, #fff, 70%)); 5 | @include bg-variant(".bg-#{$color}-dark", mix($value, #000, 80%)); 6 | @include bg-variant(".bg-#{$color}-darker", mix($value, #000, 40%)); 7 | @include bg-variant(".bg-#{$color}-darkest", mix($value, #000, 20%)); 8 | } -------------------------------------------------------------------------------- /tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 19 | 20 | return $app; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | belongsTo(Device::class); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/Traits/UuidIndex.php: -------------------------------------------------------------------------------- 1 | getKeyName()] = $uuid->getHex(); 16 | }); 17 | } 18 | 19 | public function getIncrementing() 20 | { 21 | return false; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Http/Middleware/PartnerMiddleware.php: -------------------------------------------------------------------------------- 1 | getHost() !== env('APP_DOMAIN','sekitarkita.id') && $request->getHost() !== 'localhost') { 13 | return parent::handle($request, $next, ...$guards); 14 | } 15 | 16 | return $next($request); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /resources/sass/tabler/_list.scss: -------------------------------------------------------------------------------- 1 | .list-inline-dots { 2 | .list-inline-item { 3 | 4 | + .list-inline-item { 5 | &:before { 6 | content: '· '; 7 | margin-left: -2px; 8 | margin-right: 3px; 9 | } 10 | } 11 | } 12 | } 13 | 14 | 15 | .list-separated { 16 | 17 | } 18 | 19 | .list-separated-item { 20 | padding: 1rem 0; 21 | 22 | &:first-child { 23 | padding-top: 0; 24 | } 25 | 26 | &:last-child { 27 | padding-bottom: 0; 28 | } 29 | 30 | & + & { 31 | border-top: 1px solid $border-color; 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /resources/sass/tabler/_icon.scss: -------------------------------------------------------------------------------- 1 | .icons-list { 2 | list-style: none; 3 | margin: 0 -1px -1px 0; 4 | padding: 0; 5 | display: flex; 6 | flex-wrap: wrap; 7 | 8 | >li { 9 | flex: 1 0 4rem; 10 | } 11 | } 12 | 13 | .icons-list-wrap { 14 | overflow: hidden; 15 | } 16 | 17 | .icons-list-item { 18 | text-align: center; 19 | height: 4rem; 20 | display: flex; 21 | align-items: center; 22 | justify-content: center; 23 | border-right: 1px solid $border-color; 24 | border-bottom: 1px solid $border-color; 25 | 26 | i { 27 | font-size: 1.25rem; 28 | } 29 | } -------------------------------------------------------------------------------- /app/Http/Middleware/TrustProxies.php: -------------------------------------------------------------------------------- 1 | expectsJson()) { 18 | return route('login'); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Models/Kelurahan.php: -------------------------------------------------------------------------------- 1 | belongsTo(Kecamatan::class, 'district_id'); 14 | } 15 | 16 | public function hospitals() 17 | { 18 | return $this->morphMany(Hospital::class, 'area'); 19 | } 20 | 21 | public function call_centers() 22 | { 23 | return $this->morphMany(CallCenter::class, 'area'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Enums/SIKMCategory.php: -------------------------------------------------------------------------------- 1 | where('name', $name)->latest('number')->first(); 16 | if (!$sequence) { 17 | $newSequence = Sequence::create(['name' => $name, 'number' => 1]); 18 | return $newSequence['number']; 19 | } 20 | 21 | return $sequence->increment('number'); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /resources/lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | '« Previous', 17 | 'next' => 'Next »', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /routes/channels.php: -------------------------------------------------------------------------------- 1 | id === (int) $id; 18 | }); 19 | -------------------------------------------------------------------------------- /server.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | $uri = urldecode( 11 | parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) 12 | ); 13 | 14 | // This file allows us to emulate Apache's "mod_rewrite" functionality from the 15 | // built-in PHP web server. This provides a convenient way to test a Laravel 16 | // application without having installed a "real" web server software here. 17 | if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) { 18 | return false; 19 | } 20 | 21 | require_once __DIR__.'/public/index.php'; 22 | -------------------------------------------------------------------------------- /webpack.mix.js: -------------------------------------------------------------------------------- 1 | const mix = require('laravel-mix'); 2 | 3 | /* 4 | |-------------------------------------------------------------------------- 5 | | Mix Asset Management 6 | |-------------------------------------------------------------------------- 7 | | 8 | | Mix provides a clean, fluent API for defining some Webpack build steps 9 | | for your Laravel application. By default, we are compiling the Sass 10 | | file for the application as well as bundling up all the JS files. 11 | | 12 | */ 13 | 14 | mix.js('resources/js/app.js', 'public/js') 15 | .sass('resources/sass/app.scss', 'public/css'); 16 | 17 | if (mix.inProduction()) { 18 | mix.version(); 19 | } 20 | -------------------------------------------------------------------------------- /app/Providers/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 19 | })->describe('Display an inspiring quote'); 20 | -------------------------------------------------------------------------------- /app/Models/Provinsi.php: -------------------------------------------------------------------------------- 1 | hasMany(Kabupaten::class, 'province_id'); 18 | } 19 | 20 | public function hospitals() 21 | { 22 | return $this->morphMany(Hospital::class, 'area'); 23 | } 24 | 25 | public function call_centers() 26 | { 27 | return $this->morphMany(CallCenter::class, 'area'); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /resources/sass/tabler/_utilities.scss: -------------------------------------------------------------------------------- 1 | @each $color, $value in $colors { 2 | @include bg-variant(".bg-#{$color}", $value); 3 | 4 | .text-#{$color} { 5 | color: $value !important; 6 | } 7 | } 8 | 9 | 10 | .icon { 11 | color: $text-muted !important; 12 | 13 | i { 14 | vertical-align: -1px; 15 | } 16 | 17 | @at-root a#{&} { 18 | text-decoration: none; 19 | cursor: pointer; 20 | 21 | &:hover { 22 | color: $body-color !important; 23 | } 24 | } 25 | } 26 | 27 | .o-auto { overflow: auto !important; } 28 | .o-hidden { overflow: hidden !important; } 29 | 30 | .shadow { box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05) !important; } 31 | .shadow-none { box-shadow: none !important; } -------------------------------------------------------------------------------- /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 | # Send Requests To Front Controller... 18 | RewriteCond %{REQUEST_FILENAME} !-d 19 | RewriteCond %{REQUEST_FILENAME} !-f 20 | RewriteRule ^ index.php [L] 21 | 22 | -------------------------------------------------------------------------------- /app/Enums/Transportation.php: -------------------------------------------------------------------------------- 1 | 'These credentials do not match our records.', 17 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /resources/lang/vendor/nova/en/validation.php: -------------------------------------------------------------------------------- 1 | 'This :attribute is already attached.', 17 | 'relatable' => 'This :attribute may not be associated with this resource.', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /app/Enums/ZoneLevel.php: -------------------------------------------------------------------------------- 1 | check()) { 22 | return redirect(RouteServiceProvider::HOME); 23 | } 24 | 25 | return $next($request); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /resources/sass/tabler/_text.scss: -------------------------------------------------------------------------------- 1 | .display-1, 2 | .display-2, 3 | .display-3, 4 | .display-4 { 5 | i { 6 | vertical-align: baseline; 7 | font-size: 0.815em; 8 | } 9 | } 10 | 11 | .text-inherit { color: inherit !important; } 12 | .text-default { color: $body-color !important; } 13 | .text-muted-dark { color: $text-muted-dark !important; } 14 | 15 | .tracking-tight { letter-spacing: -0.05em !important; } 16 | .tracking-normal { letter-spacing: 0 !important; } 17 | .tracking-wide { letter-spacing: 0.05em !important; } 18 | 19 | .leading-none { line-height: 1 !important; } 20 | .leading-tight { line-height: 1.25 !important; } 21 | .leading-normal { line-height: $line-height-base !important; } 22 | .leading-loose { line-height: 2 !important; } -------------------------------------------------------------------------------- /resources/sass/tabler/_aside.scss: -------------------------------------------------------------------------------- 1 | .aside { 2 | position: fixed; 3 | top: 0; 4 | right: 0; 5 | bottom: 0; 6 | width: $aside-width; 7 | background: #ffffff; 8 | border-left: 1px solid $border-color; 9 | display: flex; 10 | flex-direction: column; 11 | z-index: 100; 12 | visibility: hidden; 13 | box-shadow: 0 0 5px 2px rgba(#000, .05); 14 | 15 | body.aside-opened & { 16 | @media (min-width: 1600px) { 17 | visibility: visible; 18 | } 19 | } 20 | } 21 | 22 | .aside-body { 23 | padding: 1.5rem; 24 | flex: 1 1 auto; 25 | overflow: auto; 26 | } 27 | 28 | .aside-footer { 29 | padding: 1rem 1.5rem; 30 | border-top: 1px solid $border-color; 31 | } 32 | 33 | .aside-header { 34 | padding: 1rem 1.5rem; 35 | border-bottom: 1px solid $border-color; 36 | } -------------------------------------------------------------------------------- /serverless.yml: -------------------------------------------------------------------------------- 1 | service: api-sekitarkita 2 | 3 | provider: 4 | name: aws 5 | region: ap-southeast-1 6 | runtime: provided 7 | 8 | plugins: 9 | - ./vendor/bref/bref 10 | 11 | package: 12 | exclude: 13 | - node_modules/** 14 | - public/storage 15 | - storage/** 16 | - tests/** 17 | 18 | functions: 19 | website: 20 | handler: public/index.php 21 | timeout: 28 # in seconds (API Gateway has a timeout of 29 seconds) 22 | layers: 23 | - ${bref:layer.php-73-fpm} 24 | events: 25 | - http: 'ANY /' 26 | - http: 'ANY /{proxy+}' 27 | artisan: 28 | handler: artisan 29 | timeout: 120 # in seconds 30 | layers: 31 | - ${bref:layer.php-73} # PHP 32 | - ${bref:layer.console} # The "console" layer 33 | -------------------------------------------------------------------------------- /app/Enums/ChangeRequestStatus.php: -------------------------------------------------------------------------------- 1 | belongsTo(Provinsi::class, 'province_id'); 18 | } 19 | 20 | public function kecamatans() 21 | { 22 | return $this->hasMany(Kecamatan::class, 'city_id'); 23 | } 24 | 25 | public function hospitals() 26 | { 27 | return $this->morphMany(Hospital::class, 'area'); 28 | } 29 | 30 | public function call_centers() 31 | { 32 | return $this->morphMany(CallCenter::class, 'area'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/Models/Kecamatan.php: -------------------------------------------------------------------------------- 1 | belongsTo(Kabupaten::class, 'city_id'); 18 | } 19 | 20 | public function kelurahans() 21 | { 22 | return $this->hasMany(Kelurahan::class, 'district_id'); 23 | } 24 | 25 | public function hospitals() 26 | { 27 | return $this->morphMany(Hospital::class, 'area'); 28 | } 29 | 30 | public function call_centers() 31 | { 32 | return $this->morphMany(CallCenter::class, 'area'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/Policies/PartnerPolicy.php: -------------------------------------------------------------------------------- 1 | onlySuperadmin($user); 15 | } 16 | 17 | public function view(User $user) 18 | { 19 | return $this->onlySuperadmin($user); 20 | } 21 | 22 | public function create(User $user) 23 | { 24 | return $this->onlySuperadmin($user); 25 | } 26 | 27 | public function update(User $user) 28 | { 29 | return $this->onlySuperadmin($user); 30 | } 31 | 32 | public function delete(User $user) 33 | { 34 | return $this->onlySuperadmin($user); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /resources/lang/en/passwords.php: -------------------------------------------------------------------------------- 1 | 'Your password has been reset!', 17 | 'sent' => 'We have emailed your password reset link!', 18 | 'throttled' => 'Please wait before retrying.', 19 | 'token' => 'This password reset token is invalid.', 20 | 'user' => "We can't find a user with that email address.", 21 | 22 | ]; 23 | -------------------------------------------------------------------------------- /app/Policies/UserPolicy.php: -------------------------------------------------------------------------------- 1 | onlySuperadmin($user); 15 | } 16 | 17 | public function view(User $user, User $model) 18 | { 19 | return $this->onlySuperadmin($user); 20 | } 21 | 22 | public function create(User $user) 23 | { 24 | return $this->onlySuperadmin($user); 25 | } 26 | 27 | public function update(User $user, User $model) 28 | { 29 | return $this->onlySuperadmin($user); 30 | } 31 | 32 | public function delete(User $user) 33 | { 34 | return $this->onlySuperadmin($user); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /resources/sass/tabler/_grid.scss: -------------------------------------------------------------------------------- 1 | .container { 2 | @media print { 3 | max-width: none; 4 | } 5 | } 6 | 7 | .row-cards { 8 | > .col, 9 | > [class*='col-'] { 10 | display: flex; 11 | flex-direction: column; 12 | } 13 | } 14 | 15 | .row-deck { 16 | > .col, 17 | > [class*='col-'] { 18 | display: flex; 19 | align-items: stretch; 20 | 21 | .card { 22 | flex: 1 1 auto; 23 | } 24 | } 25 | } 26 | 27 | .col-text { 28 | max-width: 48rem; 29 | } 30 | 31 | .col-login { 32 | max-width: 24rem; 33 | } 34 | 35 | @each $name, $value in (0: 0, xs: .25rem, sm: .5rem, lg: 1rem, xl: 1.5rem) { 36 | .gutters-#{$name} { 37 | margin-right: (-$value); 38 | margin-left: -($value); 39 | 40 | > .col, 41 | > [class*="col-"] { 42 | padding-right: $value; 43 | padding-left: $value; 44 | } 45 | 46 | .card { 47 | margin-bottom: 2*$value; 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /resources/sass/tabler/_core.scss: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: 16px; 3 | height: 100%; 4 | direction: ltr; 5 | } 6 | 7 | body { 8 | direction: ltr; 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | -webkit-tap-highlight-color: transparent; 12 | -webkit-text-size-adjust: none; 13 | -ms-touch-action: manipulation; 14 | touch-action: manipulation; 15 | -webkit-font-feature-settings: "liga" 0; 16 | font-feature-settings: "liga" 0; 17 | height: 100%; 18 | overflow-y: scroll; 19 | position: relative; 20 | 21 | @media print { 22 | background: none; 23 | } 24 | } 25 | 26 | body *::-webkit-scrollbar { 27 | width: 6px; 28 | height: 6px; 29 | transition: .3s background; 30 | } 31 | 32 | body *::-webkit-scrollbar-thumb { 33 | background: $gray-400; 34 | } 35 | body *:hover::-webkit-scrollbar-thumb { 36 | background: $gray-500; 37 | } 38 | -------------------------------------------------------------------------------- /resources/views/mapping/device.blade.php: -------------------------------------------------------------------------------- 1 | @extends('mapping.base') 2 | @section('title', 'Mapping Device - ') 3 | @push('js') 4 | 25 | @endpush 26 | -------------------------------------------------------------------------------- /database/migrations/2020_04_18_021333_create_sequences_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('name')->index(); 19 | $table->unsignedBigInteger('number'); 20 | $table->timestamps(); 21 | }); 22 | } 23 | 24 | /** 25 | * Reverse the migrations. 26 | * 27 | * @return void 28 | */ 29 | public function down() 30 | { 31 | Schema::dropIfExists('sequences'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Providers/AuthServiceProvider.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 | Gate::guessPolicyNamesUsing(function ($modelClass) { 29 | return 'App\\Policies\\' . class_basename($modelClass) . 'Policy'; 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/Http/Resources/NearbyCollection.php: -------------------------------------------------------------------------------- 1 | resource instanceof AbstractPaginator 27 | ? (new CustomPaginatedResourceResponse($this))->toResponse($request) 28 | : parent::toResponse($request); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /app/Providers/EventServiceProvider.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 | -------------------------------------------------------------------------------- /database/migrations/2020_05_20_112154_create_zones_table.php: -------------------------------------------------------------------------------- 1 | id(); 19 | $table->morphs('area'); 20 | $table->enum('status', ZoneLevel::getValues()); 21 | $table->timestamps(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | * 28 | * @return void 29 | */ 30 | public function down() 31 | { 32 | Schema::dropIfExists('zones'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /resources/views/mapping/mapping-for-puppeteer.blade.php: -------------------------------------------------------------------------------- 1 | @extends('mapping.base') 2 | @section('title', 'Mapping Device - ') 3 | @push('js') 4 | 25 | @endpush 26 | -------------------------------------------------------------------------------- /database/seeds/NovaUserSeeder.php: -------------------------------------------------------------------------------- 1 | 'Admin', 17 | 'email' => 'admin@sekitarkita.id', 18 | 'password' => '$2y$10$KoGXJOk4Q.ry5O55MJ4wU.g1sXYfBZt4rD3jHevB20ip.GRbG00cO' 19 | ]); 20 | 21 | User::create([ 22 | 'name' => 'Admin Gorontalo', 23 | 'email' => 'gorontalo@sekitarkita.id', 24 | 'area' => 'gorontalo', 25 | 'domain_access' => 'gorontalo.sekitarkita.id', 26 | 'prefix' => 'GTO', 27 | 'password' => '$2y$10$DSAxGdMDZ7m5HNtNixJJYO8nIDDLbYkOC.xsQnF29pYwP9.m4Wxsi' 28 | ]); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /database/migrations/2020_04_13_215843_create_partners_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('name'); 19 | $table->string('logo'); 20 | $table->string('description')->nullable(); 21 | $table->timestamps(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | * 28 | * @return void 29 | */ 30 | public function down() 31 | { 32 | Schema::dropIfExists('partners'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /resources/sass/tabler/_chips.scss: -------------------------------------------------------------------------------- 1 | .chips { 2 | margin: 0 0 -.5rem; 3 | 4 | .chip { 5 | margin: 0 .5rem .5rem 0; 6 | } 7 | } 8 | 9 | .chip { 10 | display: inline-block; 11 | height: 2rem; 12 | line-height: 2rem; 13 | font-size: px2rem(14px); 14 | font-weight: 500; 15 | color: $text-muted-dark; 16 | padding: 0 .75rem; 17 | border-radius: 1rem; 18 | background-color: $gray-100; 19 | transition: .3s background; 20 | 21 | .avatar { 22 | float: left; 23 | margin: 0 .5rem 0 -.75rem; 24 | height: 2rem; 25 | width: 2rem; 26 | border-radius: 50%; 27 | } 28 | 29 | //.close { 30 | // cursor: pointer; 31 | // float: right; 32 | // font-size: 1.3rem; 33 | // padding-left: .5rem; 34 | // line-height: inherit; 35 | // margin-left: .25rem; 36 | //} 37 | 38 | @at-root a#{&} { 39 | &:hover { 40 | color: inherit; 41 | text-decoration: none; 42 | background-color: $gray-200; 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /app/Models/Nearby.php: -------------------------------------------------------------------------------- 1 | belongsTo(Device::class); 23 | } 24 | 25 | public function scopeWithAppUser($query) 26 | { 27 | return $query->addSelect(['app_user' => Device::select('app_user') 28 | ->whereColumn('another_device', 'devices.id') 29 | ])->withCasts(['app_user' => 'boolean'])->addSelect(['user_status' => Device::select('user_status') 30 | ->whereColumn('another_device', 'devices.id') 31 | ]); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Models/User.php: -------------------------------------------------------------------------------- 1 | 'datetime', 38 | ]; 39 | } 40 | -------------------------------------------------------------------------------- /database/migrations/2020_03_29_160931_create_call_centers_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('phone'); 19 | $table->string('mobile'); 20 | $table->string('website'); 21 | $table->morphs('area'); 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('call_centers'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2020_06_03_114029_alter_devices_table.php: -------------------------------------------------------------------------------- 1 | string('age')->nullable()->after('phone'); 18 | $table->string('address')->nullable()->after('age'); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | * 25 | * @return void 26 | */ 27 | public function down() 28 | { 29 | Schema::table('devices', function (Blueprint $table) { 30 | $table->dropColumn('age'); 31 | $table->dropColumn('address'); 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /resources/sass/tabler/_charts.scss: -------------------------------------------------------------------------------- 1 | $sizes: ( 2 | 'xs': 2.5rem, 3 | 'sm': 4rem, 4 | 'lg': 10rem 5 | ); 6 | 7 | .chart-circle { 8 | display: block; 9 | height: 8rem; 10 | width: 8rem; 11 | position: relative; 12 | 13 | canvas { 14 | margin: 0 auto; 15 | display: block; 16 | max-width: 100%; 17 | max-height: 100%; 18 | } 19 | } 20 | 21 | @each $size, $value in $sizes { 22 | .chart-circle-#{$size} { 23 | height: $value; 24 | width: $value; 25 | font-size: .8rem; 26 | } 27 | } 28 | 29 | .chart-circle-value { 30 | position: absolute; 31 | top: 0; 32 | left: 0; 33 | right: 0; 34 | margin-left: auto; 35 | margin-right: auto; 36 | bottom: 0; 37 | display: flex; 38 | justify-content: center; 39 | align-items: center; 40 | flex-direction: column; 41 | 42 | //font-size: px2rem(24px); 43 | //font-weight: 600; 44 | line-height: 1; 45 | 46 | small { 47 | display: block; 48 | color: $text-muted; 49 | font-size: px2rem(15px); 50 | } 51 | } -------------------------------------------------------------------------------- /database/migrations/2020_06_03_114029_alter_self_checks_table.php: -------------------------------------------------------------------------------- 1 | string('age')->nullable()->after('phone'); 18 | $table->string('address')->nullable()->after('age'); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | * 25 | * @return void 26 | */ 27 | public function down() 28 | { 29 | Schema::table('self_checks', function (Blueprint $table) { 30 | $table->dropColumn('age'); 31 | $table->dropColumn('address'); 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /config/cors.php: -------------------------------------------------------------------------------- 1 | ['api/*'], 19 | 20 | 'allowed_methods' => ['*'], 21 | 22 | 'allowed_origins' => ['*'], 23 | 24 | 'allowed_origins_patterns' => [], 25 | 26 | 'allowed_headers' => ['*'], 27 | 28 | 'exposed_headers' => false, 29 | 30 | 'max_age' => false, 31 | 32 | 'supports_credentials' => false, 33 | 34 | ]; 35 | -------------------------------------------------------------------------------- /database/migrations/2019_08_19_000000_create_failed_jobs_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->text('connection'); 19 | $table->text('queue'); 20 | $table->longText('payload'); 21 | $table->longText('exception'); 22 | $table->timestamp('failed_at')->useCurrent(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('failed_jobs'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /resources/sass/tabler/_maps.scss: -------------------------------------------------------------------------------- 1 | .map, 2 | .chart { 3 | position: relative; 4 | padding-top: (9/16)*100%; 5 | } 6 | 7 | .map-square, 8 | .chart-square { 9 | padding-top: 100%; 10 | } 11 | 12 | .map-content, 13 | .chart-content { 14 | position: absolute; 15 | top: 0; 16 | left: 0; 17 | right: 0; 18 | bottom: 0; 19 | } 20 | 21 | .map-header { 22 | margin-top: -1.5rem; 23 | margin-bottom: 1.5rem; 24 | height: 15rem; 25 | position: relative; 26 | 27 | //todo 28 | margin-bottom: -1.5rem; 29 | 30 | &:before { 31 | content: ''; 32 | position: absolute; 33 | bottom: 0; 34 | left: 0; 35 | right: 0; 36 | height: 10rem; 37 | background: linear-gradient(to bottom, rgba($body-bg, 0) 5%, $body-bg 95%); 38 | pointer-events: none; 39 | } 40 | } 41 | 42 | .map-header-layer { 43 | height: 100%; 44 | } 45 | 46 | .map-static { 47 | height: 120px; 48 | width: 100%; 49 | max-width: 640px; 50 | background-position: center center; 51 | background-size: 640px 120px; 52 | } -------------------------------------------------------------------------------- /.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=laravel 13 | DB_USERNAME=root 14 | DB_PASSWORD= 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_MAILER=smtp 27 | MAIL_HOST=smtp.mailtrap.io 28 | MAIL_PORT=2525 29 | MAIL_USERNAME=null 30 | MAIL_PASSWORD=null 31 | MAIL_ENCRYPTION=null 32 | MAIL_FROM_ADDRESS=null 33 | MAIL_FROM_NAME="${APP_NAME}" 34 | 35 | AWS_ACCESS_KEY_ID= 36 | AWS_SECRET_ACCESS_KEY= 37 | AWS_DEFAULT_REGION=us-east-1 38 | AWS_BUCKET= 39 | 40 | PUSHER_APP_ID= 41 | PUSHER_APP_KEY= 42 | PUSHER_APP_SECRET= 43 | PUSHER_APP_CLUSTER=mt1 44 | 45 | MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 46 | MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" 47 | -------------------------------------------------------------------------------- /database/migrations/2020_04_02_172703_alter_action_event_user_id.php: -------------------------------------------------------------------------------- 1 | string('user_id')->change(); 18 | $table->string('actionable_id')->change(); 19 | $table->string('target_id')->change(); 20 | $table->string('model_id')->change(); 21 | }); 22 | } 23 | 24 | /** 25 | * Reverse the migrations. 26 | * 27 | * @return void 28 | */ 29 | public function down() 30 | { 31 | Schema::table('action_events', function (Blueprint $table) { 32 | 33 | }); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/Http/Controllers/NovaLoginController.php: -------------------------------------------------------------------------------- 1 | authorizeable($request)) 16 | return false; 17 | 18 | return $this->guard()->attempt( 19 | $this->credentials($request), $request->filled('remember') 20 | ); 21 | } 22 | 23 | private function authorizeable(Request $request) 24 | { 25 | $user = User::where('email', $request->email)->first(); 26 | 27 | if (!$user) 28 | return false; 29 | 30 | if ($user['area'] !== null) { 31 | return Str::contains($request->root(), $user['domain_access']); 32 | } 33 | 34 | return true; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('inspire')->hourly(); 28 | } 29 | 30 | /** 31 | * Register the commands for the application. 32 | * 33 | * @return void 34 | */ 35 | protected function commands() 36 | { 37 | $this->load(__DIR__.'/Commands'); 38 | 39 | require base_path('routes/console.php'); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /database/factories/UserFactory.php: -------------------------------------------------------------------------------- 1 | define(User::class, function (Faker $faker) { 21 | return [ 22 | 'name' => $faker->name, 23 | 'email' => $faker->unique()->safeEmail, 24 | 'email_verified_at' => now(), 25 | 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password 26 | 'remember_token' => Str::random(10), 27 | ]; 28 | }); 29 | -------------------------------------------------------------------------------- /database/migrations/2020_06_29_195420_alter_sikm_add_estimate.php: -------------------------------------------------------------------------------- 1 | dateTime('arrival_estimation')->nullable(); /* remove nullable after apps updated */ 19 | $table->enum('transportation', Transportation::getValues())->nullable(); /* remove nullable after apps updated */ 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::table('sikm', function (Blueprint $table) { 31 | // 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/Models/DeviceLog.php: -------------------------------------------------------------------------------- 1 | belongsTo(Device::class); 18 | } 19 | 20 | public function nearby() 21 | { 22 | return $this->belongsTo(Device::class, 'nearby_device', 'id'); 23 | } 24 | 25 | public function getAnotherDeviceAttribute() 26 | { 27 | return $this->attributes['nearby_device']; 28 | } 29 | 30 | public function scopeWithAppUser($query) 31 | { 32 | return $query->whereNotNull('nearby_device')->addSelect(['app_user' => Device::select('app_user') 33 | ->whereColumn('nearby_device', 'devices.id') 34 | ])->withCasts(['app_user' => 'boolean']); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /database/migrations/2020_03_29_161421_create_hospitals_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('name'); 19 | $table->string('address'); 20 | $table->morphs('area'); 21 | $table->string('phone'); 22 | $table->decimal('latitude', 10, 7)->nullable(); 23 | $table->decimal('longitude', 10, 7)->nullable(); 24 | $table->timestamps(); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down() 34 | { 35 | Schema::dropIfExists('hospitals'); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /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 | ]; 34 | -------------------------------------------------------------------------------- /resources/sass/tabler/forms/_custom-colorinput.scss: -------------------------------------------------------------------------------- 1 | //.colorinput-stacked { 2 | // display: flex; 3 | // flex-wrap: wrap; 4 | // 5 | // .colorinput { 6 | // margin-right: .25rem; 7 | // } 8 | //} 9 | 10 | .colorinput { 11 | margin: 0; 12 | position: relative; 13 | cursor: pointer; 14 | } 15 | 16 | .colorinput-input { 17 | position: absolute; 18 | z-index: -1; 19 | opacity: 0; 20 | } 21 | 22 | .colorinput-color { 23 | display: inline-block; 24 | width: 1.75rem; 25 | height: 1.75rem; 26 | border-radius: 3px; 27 | border: 1px solid $border-color; 28 | color: #fff; 29 | box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); 30 | 31 | &:before { 32 | content: ''; 33 | opacity: 0; 34 | position: absolute; 35 | top: .25rem; 36 | left: .25rem; 37 | height: 1.25rem; 38 | width: 1.25rem; 39 | transition: .3s opacity; 40 | background: $custom-checkbox-indicator-icon-checked no-repeat center center/50% 50%; 41 | 42 | .colorinput-input:checked ~ & { 43 | opacity: 1; 44 | } 45 | } 46 | 47 | .colorinput-input:focus ~ & { 48 | border-color: $primary; 49 | box-shadow: $input-btn-focus-box-shadow; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/Nova/Actions/PendingSIKM.php: -------------------------------------------------------------------------------- 1 | pending(); 28 | } 29 | return Action::message('Berhasil Pending SIKM'); 30 | } 31 | 32 | /** 33 | * Get the fields available on the action. 34 | * 35 | * @return array 36 | */ 37 | public function fields() 38 | { 39 | return []; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/Nova/Actions/RejectSIKM.php: -------------------------------------------------------------------------------- 1 | reject(); 29 | } 30 | return Action::message('Berhasil Menolak SIKM'); 31 | } 32 | 33 | /** 34 | * Get the fields available on the action. 35 | * 36 | * @return array 37 | */ 38 | public function fields() 39 | { 40 | return []; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/Nova/Actions/ApproveSIKM.php: -------------------------------------------------------------------------------- 1 | approve(); 29 | } 30 | return Action::message('Berhasil Menyetujui SIKM'); 31 | } 32 | 33 | /** 34 | * Get the fields available on the action. 35 | * 36 | * @return array 37 | */ 38 | public function fields() 39 | { 40 | return []; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/Http/Resources/CustomPaginatedResourceResponse.php: -------------------------------------------------------------------------------- 1 | resource->resource->toArray(); 21 | 22 | return [ 23 | 'pagination' => $this->pagination($paginated), 24 | ]; 25 | } 26 | 27 | /** 28 | * Meta Pagination 29 | * 30 | * @param array $paginated 31 | * @return array 32 | */ 33 | protected function pagination($paginated) 34 | { 35 | $paginated['next_page'] = $paginated['current_page'] != $paginated['last_page'] ? ($paginated['current_page']+1) : null; 36 | 37 | return Arr::except($paginated, [ 38 | 'data', 39 | ]); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('name'); 19 | $table->string('email')->unique(); 20 | $table->timestamp('email_verified_at')->nullable(); 21 | $table->string('password'); 22 | $table->string('area')->nullable(); 23 | $table->string('domain_access')->nullable(); 24 | $table->string('prefix')->nullable(); 25 | $table->rememberToken(); 26 | $table->timestamps(); 27 | }); 28 | } 29 | 30 | /** 31 | * Reverse the migrations. 32 | * 33 | * @return void 34 | */ 35 | public function down() 36 | { 37 | Schema::dropIfExists('users'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/Enums/HealthStatus.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /resources/views/vendor/nova/partials/user.blade.php: -------------------------------------------------------------------------------- 1 | 2 | @isset($user->email) 3 | 7 | @endisset 8 | 9 | 10 | {{ $user->name ?? $user->email ?? __('Nova User') }} 11 | 12 | 13 | 14 | 15 | 33 | 34 | -------------------------------------------------------------------------------- /database/migrations/2020_03_21_120707_create_nearby_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('device_id'); 19 | $table->foreign('device_id')->references('id')->on('devices'); 20 | $table->string('device_name')->nullable(); 21 | $table->string('another_device'); 22 | $table->unique(['device_id', 'another_device']); 23 | $table->decimal('latitude', 10, 7)->nullable(); 24 | $table->decimal('longitude', 10, 7)->nullable(); 25 | $table->double('speed')->nullable(); 26 | $table->timestamps(); 27 | }); 28 | } 29 | 30 | /** 31 | * Reverse the migrations. 32 | * 33 | * @return void 34 | */ 35 | public function down() 36 | { 37 | Schema::dropIfExists('nearby'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /database/migrations/2020_04_13_124152_create_device_logs_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('device_id'); 19 | $table->foreign('device_id')->references('id')->on('devices'); 20 | $table->string('nearby_device')->nullable(); 21 | $table->string('area')->nullable(); 22 | $table->double('speed')->nullable(); 23 | $table->string('device_name')->nullable(); 24 | $table->decimal('latitude', 10, 7)->nullable(); 25 | $table->decimal('longitude', 10, 7)->nullable(); 26 | $table->timestamps(); 27 | }); 28 | } 29 | 30 | /** 31 | * Reverse the migrations. 32 | * 33 | * @return void 34 | */ 35 | public function down() 36 | { 37 | Schema::dropIfExists('device_logs'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | ./tests/Unit 9 | 10 | 11 | 12 | ./tests/Feature 13 | 14 | 15 | 16 | 17 | ./app 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /database/migrations/2020_04_13_125858_create_change_requests_table.php: -------------------------------------------------------------------------------- 1 | id(); 20 | $table->string('device_id'); 21 | $table->foreign('device_id')->references('id')->on('devices'); 22 | $table->enum('user_status', HealthStatus::getValues()); 23 | $table->string('nik')->nullable(); 24 | $table->string('name')->nullable(); 25 | $table->string('phone')->nullable(); 26 | $table->enum('status', ChangeRequestStatus::getValues()); 27 | $table->timestamps(); 28 | }); 29 | } 30 | 31 | /** 32 | * Reverse the migrations. 33 | * 34 | * @return void 35 | */ 36 | public function down() 37 | { 38 | Schema::dropIfExists('change_requests'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /resources/sass/tabler/_timeline.scss: -------------------------------------------------------------------------------- 1 | .timeline { 2 | position: relative; 3 | margin: 0 0 2rem; 4 | padding: 0; 5 | list-style: none; 6 | 7 | &:before { 8 | background-color: $gray-200; 9 | position: absolute; 10 | display: block; 11 | content: ''; 12 | width: 1px; 13 | height: 100%; 14 | top: 0; 15 | bottom: 0; 16 | left: 4px; 17 | } 18 | } 19 | 20 | .timeline-item { 21 | position: relative; 22 | display: flex; 23 | padding-left: 2rem; 24 | margin: .5rem 0; 25 | 26 | &:first-child:before, 27 | &:last-child:before { 28 | content: ''; 29 | position: absolute; 30 | background: #fff; 31 | width: 1px; 32 | left: .25rem; 33 | } 34 | 35 | &:first-child { 36 | margin-top: 0; 37 | 38 | &:before { 39 | top: 0; 40 | height: .5rem; 41 | } 42 | } 43 | 44 | &:last-child { 45 | margin-bottom: 0; 46 | 47 | &:before { 48 | top: .5rem; 49 | bottom: 0; 50 | } 51 | } 52 | } 53 | 54 | .timeline-badge { 55 | position: absolute; 56 | display: block; 57 | width: px2rem(7px); 58 | height: px2rem(7px); 59 | left: 1px; 60 | top: .5rem; 61 | border-radius: 100%; 62 | border: 1px solid #fff; 63 | background: $gray-500; 64 | } 65 | 66 | .timeline-time { 67 | white-space: nowrap; 68 | margin-left: auto; 69 | color: $text-muted; 70 | font-size: $small-font-size; 71 | } -------------------------------------------------------------------------------- /resources/sass/tabler/tabler.scss: -------------------------------------------------------------------------------- 1 | @import "functions"; 2 | 3 | @import "core"; 4 | @import "type"; 5 | @import "grid"; 6 | 7 | @import "layout"; 8 | @import "aside"; 9 | @import "header"; 10 | @import "footer"; 11 | @import "colors"; 12 | @import "text"; 13 | @import "utilities"; 14 | 15 | @import "nav"; 16 | @import "button"; 17 | @import "alert"; 18 | @import "close"; 19 | @import "badge"; 20 | @import "tables"; 21 | @import "breadcrumb"; 22 | @import "pagination"; 23 | @import "cards"; 24 | @import "popover"; 25 | @import "dropdown"; 26 | @import "list"; 27 | @import "list-group"; 28 | @import "avatar"; 29 | @import "product"; 30 | @import "progress"; 31 | @import "icon"; 32 | @import "image"; 33 | @import "link"; 34 | @import "media"; 35 | @import "form"; 36 | @import "sparkline"; 37 | @import "social"; 38 | @import "maps"; 39 | @import "statuses"; 40 | @import "charts"; 41 | @import "chips"; 42 | @import "stamp"; 43 | @import "chat"; 44 | @import "tag"; 45 | @import "syntax"; 46 | @import "infobox"; 47 | @import "carousel"; 48 | @import "selectize"; 49 | 50 | @import "forms/custom-range"; 51 | @import "forms/custom-selectgroup"; 52 | @import "forms/custom-switch"; 53 | @import "forms/custom-imagecheck"; 54 | @import "forms/custom-colorinput"; 55 | 56 | @import "timeline"; 57 | 58 | @import "fonts/feather"; 59 | -------------------------------------------------------------------------------- /resources/views/mapping/base.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | @section('content') 3 |
4 |
5 |
6 |
7 | 8 |
9 |
10 |
0%
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
Legend
19 |
20 | Sehat 21 | ODP 22 | PDP 23 | Positif 24 |
25 |
26 |
27 | @endsection 28 | -------------------------------------------------------------------------------- /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 | "bootstrap": "^4.1.0", 14 | "cross-env": "^7.0", 15 | "jquery": "^3.5", 16 | "popper.js": "^1.14.3", 17 | "laravel-mix": "^4.0.7", 18 | "resolve-url-loader": "^3.1.0", 19 | "sass": "^1.15.2", 20 | "sass-loader": "^7.1.0", 21 | "vue-template-compiler": "^2.6.11" 22 | }, 23 | "dependencies": { 24 | "lodash": "^4.17.15", 25 | "socket.io-client": "^2.3.0", 26 | "sweetalert2": "^9.10.12", 27 | "vis-network": "^7.4.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /resources/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | window._ = require('lodash'); 2 | 3 | /** 4 | * We'll load the axios HTTP library which allows us to easily issue requests 5 | * to our Laravel back-end. This library automatically handles sending the 6 | * CSRF token as a header based on the value of the "XSRF" token cookie. 7 | */ 8 | 9 | // window.axios = require('axios'); 10 | // 11 | // window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 12 | 13 | 14 | try { 15 | window.Popper = require('popper.js').default; 16 | window.$ = window.jQuery = require('jquery'); 17 | require('bootstrap'); 18 | window.vis = require('vis-network/standalone/umd/vis-network'); 19 | window.Swal = require('sweetalert2'); 20 | window.io = require('socket.io-client'); 21 | } catch (e) { 22 | 23 | } 24 | 25 | /** 26 | * Echo exposes an expressive API for subscribing to channels and listening 27 | * for events that are broadcast by Laravel. Echo and event broadcasting 28 | * allows your team to easily build robust real-time web applications. 29 | */ 30 | 31 | // import Echo from 'laravel-echo'; 32 | 33 | // window.Pusher = require('pusher-js'); 34 | 35 | // window.Echo = new Echo({ 36 | // broadcaster: 'pusher', 37 | // key: process.env.MIX_PUSHER_APP_KEY, 38 | // cluster: process.env.MIX_PUSHER_APP_CLUSTER, 39 | // forceTLS: true 40 | // }); 41 | -------------------------------------------------------------------------------- /resources/sass/tabler/_dropdown.scss: -------------------------------------------------------------------------------- 1 | .dropdown { 2 | display: inline-block; 3 | } 4 | 5 | .dropdown-menu { 6 | box-shadow: $dropdown-box-shadow; 7 | min-width: 12rem; 8 | } 9 | 10 | .dropdown-item { 11 | color: $text-muted-dark; 12 | } 13 | 14 | .dropdown-menu-arrow { 15 | &:before { 16 | position: absolute; 17 | top: -6px; 18 | left: 12px; 19 | display: inline-block; 20 | border-right: 5px solid transparent; 21 | border-bottom: 5px solid $border-color; 22 | border-left: 5px solid transparent; 23 | border-bottom-color: rgba(0, 0, 0, 0.2); 24 | content: ''; 25 | } 26 | 27 | &:after { 28 | position: absolute; 29 | top: -5px; 30 | left: 12px; 31 | display: inline-block; 32 | border-right: 5px solid transparent; 33 | border-bottom: 5px solid #fff; 34 | border-left: 5px solid transparent; 35 | content: ''; 36 | } 37 | 38 | &.dropdown-menu-right { 39 | &:before, 40 | &:after { 41 | left: auto; 42 | right: 12px; 43 | } 44 | } 45 | } 46 | 47 | .dropdown-toggle { 48 | user-select: none; 49 | cursor: pointer; 50 | 51 | &:after { 52 | vertical-align: 0.155em; 53 | } 54 | 55 | &:empty:after { 56 | margin-left: 0; 57 | } 58 | } 59 | 60 | .dropdown-icon { 61 | color: $text-muted; 62 | margin-right: .5rem; 63 | margin-left: -.5rem; 64 | width: 1em; 65 | display: inline-block; 66 | text-align: center; 67 | vertical-align: -1px; 68 | } -------------------------------------------------------------------------------- /app/Exceptions/Handler.php: -------------------------------------------------------------------------------- 1 | 'date', 19 | 'arrival_estimation' => 'datetime', 20 | ]; 21 | 22 | public function originable() 23 | { 24 | return $this->morphTo(); 25 | } 26 | 27 | public function destinationable() 28 | { 29 | return $this->morphTo(); 30 | } 31 | 32 | public function device() 33 | { 34 | return $this->belongsTo(Device::class); 35 | } 36 | 37 | public function approve() 38 | { 39 | $this['status'] = ChangeRequestStatus::APPROVE; 40 | $this->save(); 41 | } 42 | 43 | public function pending() 44 | { 45 | $this['status'] = ChangeRequestStatus::PENDING; 46 | $this->save(); 47 | } 48 | 49 | public function reject() 50 | { 51 | $this['status'] = ChangeRequestStatus::REJECT; 52 | $this->save(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/Nova/Filters/AreaFilter.php: -------------------------------------------------------------------------------- 1 | where('area', $value)->latest()->get(['id', 'device_id'])->unique('device_id')->pluck('id'); 29 | return $query->whereIn('id', $ids); 30 | } 31 | 32 | /** 33 | * Get the filter's available options. 34 | * 35 | * @param \Illuminate\Http\Request $request 36 | * @return array 37 | */ 38 | public function options(Request $request) 39 | { 40 | return DeviceLog::whereNotNull('area')->get('area')->pluck('area')->unique()->map(function ($v) { 41 | return [ 42 | 'id' => $v, 43 | 'name' => $v, 44 | 'value' => $v, 45 | ]; 46 | }); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/Http/Resources/CallCenterResource.php: -------------------------------------------------------------------------------- 1 | $this['phone'], 30 | 'mobile' => $this['mobile'], 31 | 'website' => $this['website'], 32 | 'area' => $this['area']['name'], 33 | 'area_detail' => $area, 34 | ]; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/Nova/Filters/ChangeRequestFilter.php: -------------------------------------------------------------------------------- 1 | columnName = $columnName; 18 | $this->options = $options; 19 | $this->name = $customName; 20 | } 21 | 22 | /** 23 | * The filter's component. 24 | * 25 | * @var string 26 | */ 27 | public $component = 'select-filter'; 28 | 29 | public function key() 30 | { 31 | return 'filter-' . $this->columnName; 32 | } 33 | 34 | /** 35 | * Apply the filter to the given query. 36 | * 37 | * @param Request $request 38 | * @param Builder $query 39 | * @param mixed $value 40 | * @return Builder 41 | */ 42 | public function apply(Request $request, $query, $value) 43 | { 44 | return $query->where($this->columnName, $value); 45 | } 46 | 47 | /** 48 | * Get the filter's available options. 49 | * 50 | * @param Request $request 51 | * @return array 52 | */ 53 | public function options(Request $request) 54 | { 55 | return $this->options; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/Nova/Metrics/OnlineDevice.php: -------------------------------------------------------------------------------- 1 | user()['area']) { 22 | $device->where('last_known_area', 'like', "%$area%"); 23 | } 24 | 25 | 26 | return $this->result($device->online()->count()); 27 | } 28 | 29 | /** 30 | * Get the ranges available for the metric. 31 | * 32 | * @return array 33 | */ 34 | public function ranges() 35 | { 36 | return [ 37 | 38 | ]; 39 | } 40 | 41 | /** 42 | * Determine for how many minutes the metric should be cached. 43 | * 44 | * @return \DateTimeInterface|\DateInterval|float|int 45 | */ 46 | public function cacheFor() 47 | { 48 | // return now()->addMinutes(5); 49 | } 50 | 51 | /** 52 | * Get the URI key for the metric. 53 | * 54 | * @return string 55 | */ 56 | public function uriKey() 57 | { 58 | return 'online-device'; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /database/migrations/2020_06_12_213131_create_sikm_table.php: -------------------------------------------------------------------------------- 1 | id(); 20 | $table->string('device_id'); 21 | $table->foreign('device_id')->references('id')->on('devices'); 22 | $table->string('nik'); 23 | $table->string('name'); 24 | $table->string('phone'); 25 | $table->morphs('originable'); 26 | $table->morphs('destinationable'); 27 | $table->enum('category', SIKMCategory::getValues()); 28 | $table->string('ktp_file'); 29 | $table->string('medical_file'); 30 | $table->date('medical_issued'); 31 | $table->enum('status', ChangeRequestStatus::getValues())->default(ChangeRequestStatus::APPROVE); 32 | $table->timestamps(); 33 | }); 34 | } 35 | 36 | /** 37 | * Reverse the migrations. 38 | * 39 | * @return void 40 | */ 41 | public function down() 42 | { 43 | Schema::dropIfExists('sikm'); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/Observers/ChangeRequestObserver.php: -------------------------------------------------------------------------------- 1 | isDirty('status') && $changeRequest['status'] === 'approve') { 22 | $user = auth()->user(); 23 | $localNumbering = null; 24 | $globalNumbering = null; 25 | 26 | if ($changeRequest['user_status'] !== HealthStatus::HEALTHY) { 27 | $localPrefix = $user['prefix']; 28 | $localNumbering = $localPrefix ? $localPrefix . '-' . Sequence::getNextNumber($localPrefix) : null; 29 | $globalPrefix = "sekitar"; 30 | $globalNumbering = $globalPrefix . '-' . Sequence::getNextNumber($globalPrefix); 31 | } 32 | $changeRequest->device->update([ 33 | 'user_status' => $changeRequest['user_status'], 34 | 'name' => $changeRequest['name'], 35 | 'nik' => $changeRequest['nik'], 36 | 'local_numbering' => $localNumbering, 37 | 'global_numbering' => $globalNumbering 38 | ]); 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /app/Nova/Metrics/NewDevice.php: -------------------------------------------------------------------------------- 1 | user()['area']) { 24 | $device->where('last_known_area', 'like', "%$area%"); 25 | } 26 | 27 | return $this->count($request, $device); 28 | } 29 | 30 | /** 31 | * Get the ranges available for the metric. 32 | * 33 | * @return array 34 | */ 35 | public function ranges() 36 | { 37 | return [ 38 | 'TODAY' => 'Hari Ini', 39 | 7 => 'Minggu Ini' 40 | ]; 41 | } 42 | 43 | /** 44 | * Determine for how many minutes the metric should be cached. 45 | * 46 | * @return \DateTimeInterface|\DateInterval|float|int 47 | */ 48 | public function cacheFor() 49 | { 50 | // return now()->addMinutes(5); 51 | } 52 | 53 | /** 54 | * Get the URI key for the metric. 55 | * 56 | * @return string 57 | */ 58 | public function uriKey() 59 | { 60 | return 'new-device'; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/Http/Resources/HospitalResource.php: -------------------------------------------------------------------------------- 1 | $this['name'], 30 | 'address' => $this['address'], 31 | 'phone' => $this['phone'], 32 | 'area_detail' => $area, 33 | 'area' => $this['area']['nama'], 34 | 'latitude' => $this['latitude'], 35 | 'longitude' => $this['longitude'], 36 | ]; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /database/migrations/2020_05_26_155648_create_self_checks_table.php: -------------------------------------------------------------------------------- 1 | id(); 19 | $table->string('device_id'); 20 | $table->foreign('device_id')->references('id')->on('devices'); 21 | $table->string('name')->nullable(); 22 | $table->string('phone')->nullable(); 23 | $table->boolean('has_direct_contact'); 24 | $table->boolean('has_fever'); 25 | $table->boolean('has_flu'); 26 | $table->boolean('has_cough'); 27 | $table->boolean('has_breath_problem'); 28 | $table->boolean('has_sore_throat'); 29 | $table->boolean('has_in_infected_country'); 30 | $table->boolean('has_in_infected_city'); 31 | $table->enum('result', HealthStatus::getValues()); 32 | $table->timestamps(); 33 | }); 34 | } 35 | 36 | /** 37 | * Reverse the migrations. 38 | * 39 | * @return void 40 | */ 41 | public function down() 42 | { 43 | Schema::dropIfExists('self_checks'); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/Nova/Metrics/NewInteraction.php: -------------------------------------------------------------------------------- 1 | user()['area']) { 22 | $nearby->whereHas('device', function ($q) use ($area) { 23 | return $q->where('last_known_area', 'like', "%$area%"); 24 | }); 25 | } 26 | 27 | return $this->count($request, $nearby); 28 | } 29 | 30 | /** 31 | * Get the ranges available for the metric. 32 | * 33 | * @return array 34 | */ 35 | public function ranges() 36 | { 37 | return [ 38 | 'TODAY' => 'Hari Ini', 39 | 7 => 'Minggu Ini' 40 | ]; 41 | } 42 | 43 | /** 44 | * Determine for how many minutes the metric should be cached. 45 | * 46 | * @return \DateTimeInterface|\DateInterval|float|int 47 | */ 48 | public function cacheFor() 49 | { 50 | // return now()->addMinutes(5); 51 | } 52 | 53 | /** 54 | * Get the URI key for the metric. 55 | * 56 | * @return string 57 | */ 58 | public function uriKey() 59 | { 60 | return 'new-interaction'; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/Nova/Metrics/DevicePerDay.php: -------------------------------------------------------------------------------- 1 | user()['area']) { 23 | $device->where('last_known_area', 'like', "%$area%"); 24 | } 25 | 26 | return $this->countByDays($request, $device); 27 | } 28 | 29 | /** 30 | * Get the ranges available for the metric. 31 | * 32 | * @return array 33 | */ 34 | public function ranges() 35 | { 36 | return [ 37 | 7 => '1 Minggu', 38 | 14 => '2 Minggu', 39 | 30 => '1 Bulan', 40 | 60 => '2 Bulan', 41 | ]; 42 | } 43 | 44 | /** 45 | * Determine for how many minutes the metric should be cached. 46 | * 47 | * @return \DateTimeInterface|\DateInterval|float|int 48 | */ 49 | public function cacheFor() 50 | { 51 | // return now()->addMinutes(5); 52 | } 53 | 54 | /** 55 | * Get the URI key for the metric. 56 | * 57 | * @return string 58 | */ 59 | public function uriKey() 60 | { 61 | return 'device-per-day'; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /resources/sass/tabler/_layout.scss: -------------------------------------------------------------------------------- 1 | .page { 2 | display: flex; 3 | flex-direction: column; 4 | justify-content: center; 5 | min-height: 100%; 6 | 7 | body.fixed-header & { 8 | padding-top: $header-height; 9 | } 10 | 11 | body.aside-opened & { 12 | @media (min-width: 1600px) { 13 | margin-right: $aside-width; 14 | } 15 | } 16 | } 17 | 18 | .page-main { 19 | flex: 1 1 auto; 20 | } 21 | 22 | .page-content { 23 | margin: .75rem 0; 24 | 25 | @include media-breakpoint-up(md) { 26 | margin: 1.5rem 0; 27 | } 28 | } 29 | 30 | .page-header { 31 | display: flex; 32 | align-items: center; 33 | margin: 1.5rem 0 1.5rem; 34 | flex-wrap: wrap; 35 | } 36 | 37 | .page-title { 38 | margin: 0; 39 | font-size: $h3-font-size; 40 | font-weight: 400; 41 | line-height: 2.5rem; 42 | } 43 | 44 | .page-title-icon { 45 | color: $text-muted; 46 | font-size: 1.25rem; 47 | } 48 | 49 | .page-subtitle { 50 | font-size: px2rem(13px); 51 | color: $text-muted-dark; 52 | margin-left: 2rem; 53 | 54 | a { 55 | color: inherit; 56 | } 57 | } 58 | 59 | .page-options { 60 | margin-left: auto; 61 | } 62 | 63 | .page-breadcrumb { 64 | flex-basis: 100%; 65 | } 66 | 67 | .page-description { 68 | margin: .25rem 0 0; 69 | color: $text-muted-dark; 70 | 71 | a { 72 | color: inherit; 73 | } 74 | } 75 | 76 | .page-single { 77 | flex: 1 1 auto; 78 | display: flex; 79 | align-items: center; 80 | justify-content: center; 81 | padding: 1rem 0; 82 | } 83 | 84 | 85 | 86 | .content-heading { 87 | font-weight: 400; 88 | margin: 2rem 0 1.5rem; 89 | font-size: px2rem(20px); 90 | line-height: 1.25; 91 | 92 | &:first-child { 93 | margin-top: 0; 94 | } 95 | } -------------------------------------------------------------------------------- /app/Nova/Metrics/HealthyUser.php: -------------------------------------------------------------------------------- 1 | user()['area']) { 22 | $device->where('last_known_area', 'like', "%$area%"); 23 | } 24 | return $this->count($request, $device->healthy()); 25 | } 26 | 27 | /** 28 | * Get the ranges available for the metric. 29 | * 30 | * @return array 31 | */ 32 | public function ranges() 33 | { 34 | return [ 35 | 30 => '30 Days', 36 | 60 => '60 Days', 37 | 365 => '365 Days', 38 | 'TODAY' => 'Today', 39 | 'MTD' => 'Month To Date', 40 | 'QTD' => 'Quarter To Date', 41 | 'YTD' => 'Year To Date', 42 | ]; 43 | } 44 | 45 | /** 46 | * Determine for how many minutes the metric should be cached. 47 | * 48 | * @return \DateTimeInterface|\DateInterval|float|int 49 | */ 50 | public function cacheFor() 51 | { 52 | // return now()->addMinutes(5); 53 | } 54 | 55 | /** 56 | * Get the URI key for the metric. 57 | * 58 | * @return string 59 | */ 60 | public function uriKey() 61 | { 62 | return 'healthy-user'; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/Nova/Metrics/PDPUser.php: -------------------------------------------------------------------------------- 1 | user()['area']) { 25 | $device->where('last_known_area', 'like', "%$area%"); 26 | } 27 | return $this->count($request, $device->pdp()); 28 | } 29 | 30 | /** 31 | * Get the ranges available for the metric. 32 | * 33 | * @return array 34 | */ 35 | public function ranges() 36 | { 37 | return [ 38 | 30 => '30 Days', 39 | 60 => '60 Days', 40 | 365 => '365 Days', 41 | 'TODAY' => 'Today', 42 | 'MTD' => 'Month To Date', 43 | 'QTD' => 'Quarter To Date', 44 | 'YTD' => 'Year To Date', 45 | ]; 46 | } 47 | 48 | /** 49 | * Determine for how many minutes the metric should be cached. 50 | * 51 | * @return \DateTimeInterface|\DateInterval|float|int 52 | */ 53 | public function cacheFor() 54 | { 55 | // return now()->addMinutes(5); 56 | } 57 | 58 | /** 59 | * Get the URI key for the metric. 60 | * 61 | * @return string 62 | */ 63 | public function uriKey() 64 | { 65 | return 'p-d-p-user'; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /resources/sass/tabler/_chat.scss: -------------------------------------------------------------------------------- 1 | .chat { 2 | outline: 0; 3 | margin: 0; 4 | padding: 0; 5 | list-style-type: none; 6 | display: flex; 7 | flex-direction: column; 8 | justify-content: flex-end; 9 | min-height: 100%; 10 | } 11 | 12 | .chat-line { 13 | padding: 0; 14 | text-align: right; 15 | position: relative; 16 | display: flex; 17 | flex-direction: row-reverse; 18 | 19 | & + & { 20 | padding-top: 1rem; 21 | } 22 | } 23 | 24 | .chat-message { 25 | position: relative; 26 | display: inline-block; 27 | background-color: $primary; 28 | color: #fff; 29 | font-size: px2rem(14px); 30 | padding: .375rem .5rem; 31 | border-radius: 3px; 32 | white-space: normal; 33 | text-align: left; 34 | margin: 0 .5rem 0 2.5rem; 35 | line-height: 1.4; 36 | 37 | >:last-child { 38 | margin-bottom: 0 !important; 39 | } 40 | 41 | &:after { 42 | content: ""; 43 | position: absolute; 44 | right: -5px; 45 | top: 7px; 46 | border-bottom: 6px solid transparent; 47 | border-left: 6px solid $primary; 48 | border-top: 6px solid transparent; 49 | } 50 | 51 | img { 52 | max-width: 100%; 53 | } 54 | 55 | p { 56 | margin-bottom: 1em; 57 | } 58 | } 59 | 60 | .chat-line-friend { 61 | flex-direction: row; 62 | 63 | & + & { 64 | margin-top: -.5rem; 65 | 66 | .chat-author { 67 | visibility: hidden; 68 | } 69 | 70 | .chat-message:after { 71 | display: none; 72 | } 73 | } 74 | 75 | .chat-message { 76 | background-color: #f3f3f3; 77 | color: $body-color; 78 | margin-left: .5rem; 79 | margin-right: 2.5rem; 80 | 81 | &:after { 82 | right: auto; 83 | left: -5px; 84 | border-left-width: 0; 85 | border-right: 5px solid #f3f3f3; 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /app/Nova/Metrics/InteractionPerHour.php: -------------------------------------------------------------------------------- 1 | user()['area']) { 23 | $nearby->whereHas('device', function ($q) use ($area) { 24 | return $q->where('last_known_area', 'like', "%$area%"); 25 | }); 26 | } 27 | return $this->countByHours($request, $nearby); 28 | } 29 | 30 | /** 31 | * Get the ranges available for the metric. 32 | * 33 | * @return array 34 | */ 35 | public function ranges() 36 | { 37 | return [ 38 | 12 => '12 Jam', 39 | 24 => '24 Jam', 40 | 48 => '48 Jam', 41 | 96 => '96 Jam', 42 | ]; 43 | } 44 | 45 | /** 46 | * Determine for how many minutes the metric should be cached. 47 | * 48 | * @return \DateTimeInterface|\DateInterval|float|int 49 | */ 50 | public function cacheFor() 51 | { 52 | // return now()->addMinutes(5); 53 | } 54 | 55 | /** 56 | * Get the URI key for the metric. 57 | * 58 | * @return string 59 | */ 60 | public function uriKey() 61 | { 62 | return 'interaction-per-hour'; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/Nova/Metrics/InteractionPerMinutes.php: -------------------------------------------------------------------------------- 1 | user()['area']) { 23 | $nearby->whereHas('device', function ($q) use ($area) { 24 | return $q->where('last_known_area', 'like', "%$area%"); 25 | }); 26 | } 27 | 28 | return $this->countByMinutes($request, $nearby); 29 | } 30 | 31 | /** 32 | * Get the ranges available for the metric. 33 | * 34 | * @return array 35 | */ 36 | public function ranges() 37 | { 38 | return [ 39 | 10 => '10 Menit', 40 | 30 => 'Setengah Jam', 41 | 60 => '1 Jam', 42 | ]; 43 | } 44 | 45 | /** 46 | * Determine for how many minutes the metric should be cached. 47 | * 48 | * @return \DateTimeInterface|\DateInterval|float|int 49 | */ 50 | public function cacheFor() 51 | { 52 | // return now()->addMinutes(5); 53 | } 54 | 55 | /** 56 | * Get the URI key for the metric. 57 | * 58 | * @return string 59 | */ 60 | public function uriKey() 61 | { 62 | return 'interaction-per-minutes'; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/Nova/Metrics/Devices.php: -------------------------------------------------------------------------------- 1 | user()['area']) { 23 | $device->where('last_known_area', 'like', "%$area%"); 24 | } 25 | 26 | 27 | return $this->count($request, $device); 28 | } 29 | 30 | /** 31 | * Get the ranges available for the metric. 32 | * 33 | * @return array 34 | */ 35 | public function ranges() 36 | { 37 | return [ 38 | 30 => '30 Days', 39 | 60 => '60 Days', 40 | 365 => '365 Days', 41 | 'TODAY' => 'Today', 42 | 'MTD' => 'Month To Date', 43 | 'QTD' => 'Quarter To Date', 44 | 'YTD' => 'Year To Date', 45 | ]; 46 | } 47 | 48 | /** 49 | * Determine for how many minutes the metric should be cached. 50 | * 51 | * @return \DateTimeInterface|\DateInterval|float|int 52 | */ 53 | public function cacheFor() 54 | { 55 | // return now()->addMinutes(5); 56 | } 57 | 58 | /** 59 | * Get the URI key for the metric. 60 | * 61 | * @return string 62 | */ 63 | public function uriKey() 64 | { 65 | return 'devices'; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/Nova/Metrics/ODPUser.php: -------------------------------------------------------------------------------- 1 | odp(); 22 | 23 | if ($area = $request->user()['area']) { 24 | $device->where('last_known_area', 'like', "%$area%"); 25 | } 26 | 27 | return $this->count($request, $device); 28 | } 29 | 30 | /** 31 | * Get the ranges available for the metric. 32 | * 33 | * @return array 34 | */ 35 | public function ranges() 36 | { 37 | return [ 38 | 30 => '30 Days', 39 | 60 => '60 Days', 40 | 365 => '365 Days', 41 | 'TODAY' => 'Today', 42 | 'MTD' => 'Month To Date', 43 | 'QTD' => 'Quarter To Date', 44 | 'YTD' => 'Year To Date', 45 | ]; 46 | } 47 | 48 | /** 49 | * Determine for how many minutes the metric should be cached. 50 | * 51 | * @return \DateTimeInterface|\DateInterval|float|int 52 | */ 53 | public function cacheFor() 54 | { 55 | // return now()->addMinutes(5); 56 | } 57 | 58 | /** 59 | * Get the URI key for the metric. 60 | * 61 | * @return string 62 | */ 63 | public function uriKey() 64 | { 65 | return 'o-d-p-user'; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /resources/sass/tabler/forms/_custom-selectgroup.scss: -------------------------------------------------------------------------------- 1 | .selectgroup { 2 | display: inline-flex; 3 | } 4 | 5 | .selectgroup-item { 6 | flex-grow: 1; 7 | position: relative; 8 | 9 | & + & { 10 | margin-left: -1px; 11 | } 12 | 13 | &:not(:first-child) .selectgroup-button { 14 | border-top-left-radius: 0; 15 | border-bottom-left-radius: 0; 16 | } 17 | 18 | &:not(:last-child) .selectgroup-button { 19 | border-top-right-radius: 0; 20 | border-bottom-right-radius: 0; 21 | } 22 | } 23 | 24 | .selectgroup-input { 25 | opacity: 0; 26 | position: absolute; 27 | z-index: -1; 28 | top: 0; 29 | left: 0; 30 | } 31 | 32 | .selectgroup-button { 33 | display: block; 34 | border: 1px solid $input-border-color; 35 | text-align: center; 36 | padding: $input-btn-padding-y 1rem; 37 | position: relative; 38 | cursor: pointer; 39 | border-radius: 3px; 40 | color: $text-muted; 41 | user-select: none; 42 | font-size: $font-size-base; 43 | line-height: 1.5rem; 44 | min-width: $input-height; 45 | } 46 | 47 | .selectgroup-button-icon { 48 | padding-left: .5rem; 49 | padding-right: .5rem; 50 | font-size: 1rem; 51 | } 52 | 53 | .selectgroup-input:checked + .selectgroup-button { 54 | border-color: $primary; 55 | z-index: 1; 56 | color: $primary; 57 | background: mix(#fff, $primary, 90%) 58 | } 59 | 60 | .selectgroup-input:focus + .selectgroup-button { 61 | border-color: $primary; 62 | z-index: 2; 63 | color: $primary; 64 | box-shadow: $input-btn-focus-box-shadow; 65 | } 66 | 67 | .selectgroup-pills { 68 | flex-wrap: wrap; 69 | align-items: flex-start; 70 | 71 | .selectgroup-item { 72 | margin-right: .5rem; 73 | flex-grow: 0; 74 | } 75 | 76 | .selectgroup-button { 77 | border-radius: 50px !important; 78 | } 79 | } -------------------------------------------------------------------------------- /app/Nova/Metrics/InteractionPerDay.php: -------------------------------------------------------------------------------- 1 | user()['area']) { 25 | $nearby->whereHas('device', function ($q) use ($area) { 26 | return $q->where('last_known_area', 'like', "%$area%"); 27 | }); 28 | } 29 | 30 | return $this->countByDays($request, $nearby); 31 | } 32 | 33 | /** 34 | * Get the ranges available for the metric. 35 | * 36 | * @return array 37 | */ 38 | public function ranges() 39 | { 40 | return [ 41 | 7 => '1 Minggu', 42 | 14 => '2 Minggu', 43 | 30 => '1 Bulan', 44 | 60 => '2 Bulan', 45 | ]; 46 | } 47 | 48 | /** 49 | * Determine for how many minutes the metric should be cached. 50 | * 51 | * @return \DateTimeInterface|\DateInterval|float|int 52 | */ 53 | public function cacheFor() 54 | { 55 | // return now()->addMinutes(5); 56 | } 57 | 58 | /** 59 | * Get the URI key for the metric. 60 | * 61 | * @return string 62 | */ 63 | public function uriKey() 64 | { 65 | return 'interaction-per-day'; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /database/migrations/2020_03_21_120110_create_devices_table.php: -------------------------------------------------------------------------------- 1 | string('id')->primary(); 19 | $table->string('label')->nullable(); 20 | $table->string('name')->nullable(); 21 | $table->string('nik',16)->nullable(); 22 | $table->string('phone')->nullable(); 23 | $table->string('global_numbering')->unique()->nullable(); 24 | $table->string('local_numbering')->unique()->nullable(); 25 | $table->enum('user_status', HealthStatus::getValues()); 26 | $table->string('device_name')->nullable(); 27 | $table->decimal('last_known_latitude', 10, 7)->nullable(); 28 | $table->decimal('last_known_longitude', 10, 7)->nullable(); 29 | $table->string('last_known_area')->nullable(); 30 | $table->text('last_known_address')->nullable(); 31 | $table->boolean('app_user')->default(false); 32 | $table->boolean('banned')->default(false); 33 | $table->string('firebase_token')->nullable(); 34 | $table->timestamps(); 35 | }); 36 | } 37 | 38 | /** 39 | * Reverse the migrations. 40 | * 41 | * @return void 42 | */ 43 | public function down() 44 | { 45 | Schema::dropIfExists('devices'); 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 | |-------------------------------------------------------------------------- 38 | | Blade View Modification Checking 39 | |-------------------------------------------------------------------------- 40 | | 41 | | On every request the framework will check to see if a view has expired 42 | | to determine if it needs to be recompiled. If you are in production 43 | | and precompiling views this feature may be disabled to save time. 44 | | 45 | */ 46 | 47 | 'expires' => env('VIEW_CHECK_EXPIRATION', true), 48 | 49 | ]; 50 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/Nova/Metrics/NearbyDevices.php: -------------------------------------------------------------------------------- 1 | user()['area']) { 23 | $nearby->whereHas('device', function ($q) use ($area) { 24 | return $q->where('last_known_area', 'like', "%$area%"); 25 | }); 26 | } 27 | 28 | return $this->count($request, $nearby); 29 | } 30 | 31 | /** 32 | * Get the ranges available for the metric. 33 | * 34 | * @return array 35 | */ 36 | public function ranges() 37 | { 38 | return [ 39 | 30 => '30 Days', 40 | 60 => '60 Days', 41 | 365 => '365 Days', 42 | 'TODAY' => 'Today', 43 | 'MTD' => 'Month To Date', 44 | 'QTD' => 'Quarter To Date', 45 | 'YTD' => 'Year To Date', 46 | ]; 47 | } 48 | 49 | /** 50 | * Determine for how many minutes the metric should be cached. 51 | * 52 | * @return \DateTimeInterface|\DateInterval|float|int 53 | */ 54 | public function cacheFor() 55 | { 56 | // return now()->addMinutes(5); 57 | } 58 | 59 | /** 60 | * Get the URI key for the metric. 61 | * 62 | * @return string 63 | */ 64 | public function uriKey() 65 | { 66 | return 'nearby-devices'; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | 'useTLS' => 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 | -------------------------------------------------------------------------------- /resources/sass/tabler/forms/_custom-switch.scss: -------------------------------------------------------------------------------- 1 | $custom-switch-width: 2.25rem; 2 | $custom-switch-height: 1.25rem; 3 | $custom-switch-padding: 1px; 4 | 5 | .custom-switch { 6 | user-select: none; 7 | cursor: default; 8 | display: inline-flex; 9 | align-items: center; 10 | margin: 0; 11 | } 12 | 13 | .custom-switch-input { 14 | position: absolute; 15 | z-index: -1; 16 | opacity: 0; 17 | } 18 | 19 | .custom-switches-stacked { 20 | display: flex; 21 | flex-direction: column; 22 | 23 | .custom-switch { 24 | margin-bottom: .5rem; 25 | } 26 | } 27 | 28 | .custom-switch-indicator { 29 | display: inline-block; 30 | height: $custom-switch-height; 31 | width: $custom-switch-width; 32 | background: $gray-200; 33 | border-radius: 50px; 34 | position: relative; 35 | vertical-align: bottom; 36 | border: 1px solid $border-color; 37 | transition: .3s border-color, .3s background-color; 38 | 39 | &:before { 40 | content: ''; 41 | position: absolute; 42 | height: calc(#{$custom-switch-height} - #{$custom-switch-padding * 2 + 2px}); 43 | width: calc(#{$custom-switch-height} - #{$custom-switch-padding * 2 + 2px}); 44 | top: $custom-switch-padding; 45 | left: $custom-switch-padding; 46 | background: #fff; 47 | border-radius: 50%; 48 | transition: .3s left; 49 | box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.4); 50 | } 51 | 52 | .custom-switch-input:checked ~ & { 53 | background: $primary; 54 | 55 | &:before { 56 | left: calc(#{$custom-switch-width - $custom-switch-height} + #{$custom-switch-padding}) 57 | } 58 | } 59 | 60 | .custom-switch-input:focus ~ & { 61 | box-shadow: $input-btn-focus-box-shadow; 62 | border-color: $primary; 63 | } 64 | } 65 | 66 | .custom-switch-description { 67 | margin-left: .5rem; 68 | color: $text-muted-dark; 69 | transition: .3s color; 70 | 71 | .custom-switch-input:checked ~ & { 72 | color: $body-color; 73 | } 74 | } -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /resources/sass/tabler/_tag.scss: -------------------------------------------------------------------------------- 1 | .tag { 2 | font-size: px2rem(12px); 3 | color: $text-muted-dark; 4 | background-color: $gray-200; 5 | border-radius: 3px; 6 | padding: 0 .5rem; 7 | line-height: 2em; 8 | display: inline-flex; 9 | cursor: default; 10 | font-weight: 400; 11 | user-select: none; 12 | 13 | @at-root a#{&} { 14 | text-decoration: none; 15 | cursor: pointer; 16 | transition: .3s color, .3s background; 17 | 18 | &:hover { 19 | background-color: rgba($text-muted-dark, .20); 20 | color: inherit; 21 | } 22 | } 23 | } 24 | 25 | .tag-addon { 26 | display: inline-block; 27 | padding: 0 .5rem; 28 | color: inherit; 29 | text-decoration: none; 30 | background: rgba(#000, .06); 31 | margin: 0 -.5rem 0 .5rem; 32 | text-align: center; 33 | min-width: 1.5rem; 34 | 35 | &:last-child { 36 | border-top-right-radius: 3px; 37 | border-bottom-right-radius: 3px; 38 | } 39 | 40 | i { 41 | vertical-align: middle; 42 | margin: 0 -.25rem; 43 | } 44 | 45 | @at-root a#{&} { 46 | text-decoration: none; 47 | cursor: pointer; 48 | transition: .3s color, .3s background; 49 | 50 | &:hover { 51 | background: rgba(#000, .16); 52 | color: inherit; 53 | } 54 | } 55 | } 56 | 57 | .tag-avatar { 58 | width: 1.5rem; 59 | height: 1.5rem; 60 | border-radius: 3px 0 0 3px; 61 | margin: 0 .5rem 0 -.5rem; 62 | } 63 | 64 | @each $vendor, $color in $colors { 65 | .tag-#{$vendor} { 66 | background-color: $color; 67 | color: #fff; 68 | } 69 | } 70 | 71 | @each $vendor, $color in $theme-colors { 72 | .tag-#{$vendor} { 73 | background-color: $color; 74 | color: #fff; 75 | } 76 | } 77 | 78 | .tag-rounded { 79 | border-radius: 50px; 80 | 81 | .tag-avatar { 82 | border-radius: 50px; 83 | } 84 | } 85 | 86 | .tags { 87 | margin-bottom: -.5rem; 88 | font-size: 0; 89 | 90 | >.tag { 91 | margin-bottom: .5rem; 92 | 93 | &:not(:last-child) { 94 | margin-right: .5rem; 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /resources/sass/tabler/forms/_custom-imagecheck.scss: -------------------------------------------------------------------------------- 1 | .imagecheck { 2 | margin: 0; 3 | position: relative; 4 | cursor: pointer; 5 | } 6 | 7 | .imagecheck-input { 8 | position: absolute; 9 | z-index: -1; 10 | opacity: 0; 11 | } 12 | 13 | .imagecheck-figure { 14 | border: 1px solid $border-color; 15 | border-radius: 3px; 16 | margin: 0; 17 | position: relative; 18 | 19 | .imagecheck-input:focus ~ & { 20 | border-color: $primary; 21 | box-shadow: $input-btn-focus-box-shadow; 22 | } 23 | 24 | .imagecheck-input:checked ~ & { 25 | border-color: $border-color-dark; 26 | } 27 | 28 | &:before { 29 | content: ''; 30 | position: absolute; 31 | top: .25rem; 32 | left: .25rem; 33 | display: block; 34 | width: 1rem; 35 | height: 1rem; 36 | pointer-events: none; 37 | user-select: none; 38 | background: $primary $custom-checkbox-indicator-icon-checked no-repeat center center/50% 50%; 39 | color: #fff; 40 | z-index: 1; 41 | border-radius: 3px; 42 | opacity: 0; 43 | transition: .3s opacity; 44 | 45 | .imagecheck-input:checked ~ & { 46 | opacity: 1; 47 | } 48 | } 49 | } 50 | 51 | .imagecheck-image { 52 | max-width: 100%; 53 | opacity: .64; 54 | transition: .3s opacity; 55 | 56 | &:first-child { 57 | border-top-left-radius: 2px; 58 | border-top-right-radius: 2px; 59 | } 60 | 61 | &:last-child { 62 | border-bottom-left-radius: 2px; 63 | border-bottom-right-radius: 2px; 64 | } 65 | 66 | .imagecheck:hover &, 67 | .imagecheck-input:focus ~ .imagecheck-figure &, 68 | .imagecheck-input:checked ~ .imagecheck-figure & { 69 | opacity: 1; 70 | } 71 | } 72 | 73 | .imagecheck-caption { 74 | text-align: center; 75 | padding: .25rem .25rem; 76 | color: $text-muted; 77 | font-size: $font-size-sm; 78 | transition: .3s color; 79 | 80 | .imagecheck:hover &, 81 | .imagecheck-input:focus ~ .imagecheck-figure &, 82 | .imagecheck-input:checked ~ .imagecheck-figure & { 83 | color: $body-color; 84 | } 85 | } -------------------------------------------------------------------------------- /app/Nova/Resource.php: -------------------------------------------------------------------------------- 1 | "; 76 | user-select: none; 77 | } 78 | } -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/Models/Device.php: -------------------------------------------------------------------------------- 1 | hasMany(Nearby::class); 37 | } 38 | 39 | function scannedDevice() 40 | { 41 | return $this->hasMany(Nearby::class, 'another_device'); 42 | } 43 | 44 | function scannedNearbyDevice() 45 | { 46 | return $this->nearbies->merge($this->scannedDevice)->unique(function ($item) { 47 | return $item['another_device'] . $item['device_id']; 48 | }); 49 | } 50 | 51 | public function scopeHealthy($query) 52 | { 53 | return $query->where('user_status', HealthStatus::HEALTHY); 54 | } 55 | 56 | public function scopePdp($query) 57 | { 58 | return $query->where('user_status', HealthStatus::PDP); 59 | } 60 | 61 | public function scopeOdp($query) 62 | { 63 | return $query->where('user_status', HealthStatus::ODP); 64 | } 65 | 66 | public function scopeOnline($query) 67 | { 68 | return $query->where('updated_at', '>', Carbon::now('Asia/Jakarta')->addMinutes(-60)); 69 | } 70 | 71 | public function getOnlineAttribute() 72 | { 73 | return $this['updated_at'] > Carbon::now('Asia/Jakarta')->addMinutes(-60); 74 | } 75 | 76 | public function selfChecks() 77 | { 78 | return $this->hasMany(SelfCheck::class); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /resources/sass/tabler/_type.scss: -------------------------------------------------------------------------------- 1 | .lead { 2 | line-height: 1.4; 3 | } 4 | 5 | a { 6 | text-decoration-skip: ink; 7 | } 8 | 9 | h1, h2, h3, h4, h5, h6, 10 | .h1, .h2, .h3, .h4, .h5, .h6 { 11 | a { 12 | color: inherit; 13 | } 14 | } 15 | 16 | strong, 17 | b { 18 | font-weight: 600; 19 | } 20 | 21 | p, 22 | ul, 23 | ol, 24 | blockquote { 25 | margin-bottom: 1em; 26 | } 27 | 28 | blockquote { 29 | font-style: italic; 30 | color: $text-muted-dark; 31 | padding-left: 2rem; 32 | border-left: 2px solid $border-color; 33 | 34 | p { 35 | margin-bottom: 1rem; 36 | } 37 | 38 | cite { 39 | display: block; 40 | text-align: right; 41 | 42 | &:before { 43 | content: '— '; 44 | } 45 | } 46 | } 47 | 48 | code { 49 | background: rgba(0, 0, 0, 0.025); 50 | border: 1px solid rgba(#000, .05); 51 | border-radius: 3px; 52 | padding: 3px; 53 | 54 | pre & { 55 | padding: 0; 56 | border-radius: 0; 57 | border: none; 58 | background: none; 59 | } 60 | } 61 | 62 | hr { 63 | margin-top: 2rem; 64 | margin-bottom: 2rem; 65 | } 66 | 67 | pre { 68 | color: $gray-800; 69 | padding: 1rem; 70 | overflow: auto; 71 | font-size: 85%; 72 | line-height: 1.45; 73 | background-color: #f8fafc; 74 | border-radius: 3px; 75 | tab-size: 4; 76 | text-shadow: 0 1px white; 77 | hyphens: none; 78 | } 79 | 80 | img { 81 | max-width: 100%; 82 | } 83 | 84 | .text-wrap { 85 | font-size: 1rem; 86 | line-height: 1.66; 87 | 88 | > :first-child { 89 | margin-top: 0; 90 | } 91 | 92 | > :last-child { 93 | margin-bottom: 0; 94 | } 95 | 96 | > { 97 | h1, h2, h3, h4, h5, h6 { 98 | margin-top: 1em; 99 | } 100 | } 101 | 102 | table { 103 | @extend .table, .table-bordered; 104 | } 105 | } 106 | 107 | .section-nav { 108 | background-color: $gray-100; 109 | margin: 1rem 0; 110 | padding: .5rem 1rem; 111 | border: 1px solid $border-color; 112 | border-radius: 3px; 113 | list-style: none; 114 | 115 | &:before { 116 | content: 'Table of contents:'; 117 | display: block; 118 | font-weight: 600; 119 | } 120 | } -------------------------------------------------------------------------------- /routes/web.php: -------------------------------------------------------------------------------- 1 | name('mapping.device'); 26 | Route::view('/mapping-member', 'mapping.member')->name('mapping.member') 27 | ->middleware('partner'); 28 | Route::view('/mapping-puppeteer', 'mapping.mapping-for-puppeteer'); 29 | 30 | Route::view('/tracking', 'tracking.index')->name('tracking.view') 31 | ->middleware(config('nova.middleware', [])); 32 | Route::view('/filteredTrack', 'tracking.filtered')->name('tracking.filtered') 33 | ->middleware(config('nova.middleware', [])); 34 | 35 | Route::get('api/track/{device}', 'Api\DeviceController@track') 36 | ->middleware(config('nova.middleware', [])); 37 | Route::get('api/member-interaction', 'Api\MappingController@associatedInteraction') 38 | ->middleware('partner'); 39 | Route::get('api/device-interaction', 'Api\MappingController@recordedInteraction') 40 | ->middleware('partner'); 41 | Route::get('api/filteredTrack/', 'Api\DeviceController@filteredTracking') 42 | ->middleware(config('nova.middleware', [])); 43 | 44 | Route::get('sikm/{info}', function ($info) { 45 | $sikm = SIKM::with('originable', 'destinationable') 46 | ->where('device_id', $info) 47 | ->orWhere('nik', $info) 48 | ->orWhere('id', $info) 49 | ->orderByDesc('created_at') 50 | ->firstOrFail(); 51 | 52 | return view('sikm.index', compact('sikm')); 53 | }); 54 | -------------------------------------------------------------------------------- /resources/views/errors/503.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Sekitar 8 | 9 | 10 | 11 | 12 | 13 | 67 | 68 | 69 |
70 |
71 |
72 | Mohon Maaf.. Server Sedang Dalam Peningkatan 73 |
74 | 75 |
76 | 77 |
78 |
79 |
80 | 81 | 82 | -------------------------------------------------------------------------------- /resources/views/layouts/app.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | @yield('title') SekitarKita.id 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 |
20 |
21 | 22 | tabler logo 26 | 27 | 40 |
41 |
42 |
43 |
44 | @yield('content') 45 |
46 |
47 | 48 | 49 | @stack('js') 50 | 51 | 52 | -------------------------------------------------------------------------------- /routes/api.php: -------------------------------------------------------------------------------- 1 | middleware('throttle:4,1'); 19 | 20 | Route::post('me', 'Api\DeviceController@getMe'); 21 | Route::post('store-firebase-token', 'Api\DeviceController@storeFirebaseToken'); 22 | Route::post('store-selfcheck', 'Api\DeviceController@storeSelfCheck'); 23 | Route::post('v2/store-selfcheck', 'Api\DeviceController@storeSelfCheck'); 24 | Route::post('device-history', 'Api\DeviceController@getNearby'); 25 | Route::post('change-status', 'Api\DeviceController@changeRequest'); 26 | 27 | Route::get('/', function () { 28 | return response()->json([ 29 | 'message' => 'Hello Developer' 30 | ]); 31 | }); 32 | 33 | Route::get('/call-centers', 'Api\InfoController@getCallCenters'); 34 | Route::get('/hospitals', 'Api\InfoController@getHospitals'); 35 | Route::get('/indonesia-statistics', 'Api\InfoController@getIndonesiaStatistics'); 36 | Route::get('/province-statistics', 'Api\InfoController@getProvinceStatistics'); 37 | Route::get('/gorontalo-statistics', 'Api\InfoController@getGorontaloStatistics'); 38 | Route::get('/partners', 'Api\InfoController@getPartners'); 39 | Route::post('/partners', 'Api\InfoController@reportPartners')->middleware('throttle:4,1');; 40 | Route::post('/partners/sikm', 'Api\InfoController@sikm'); 41 | 42 | Route::get('/area/provinces', 'Api\AreaController@getProvinces'); 43 | Route::get('/area/{province}/cities', 'Api\AreaController@getCities'); 44 | Route::get('/area/{city}/districts', 'Api\AreaController@getDistricts'); 45 | Route::get('/area/{district}/villages', 'Api\AreaController@getVillages'); 46 | Route::get('/area/gorontalo', 'Api\AreaController@getGorontalo'); 47 | Route::get('/area/origin-cities', 'Api\AreaController@getOriginCities'); 48 | -------------------------------------------------------------------------------- /app/Providers/RouteServiceProvider.php: -------------------------------------------------------------------------------- 1 | mapApiRoutes(); 47 | 48 | $this->mapWebRoutes(); 49 | 50 | // 51 | } 52 | 53 | /** 54 | * Define the "web" routes for the application. 55 | * 56 | * These routes all receive session state, CSRF protection, etc. 57 | * 58 | * @return void 59 | */ 60 | protected function mapWebRoutes() 61 | { 62 | Route::domain('{subdomain}.' . env('APP_DOMAIN', 'sekitarkita.id')) 63 | ->get('/', function () { 64 | return Redirect::to('/free-corona'); 65 | }); 66 | 67 | Route::middleware('web') 68 | ->namespace($this->namespace) 69 | ->group(base_path('routes/web.php')); 70 | } 71 | 72 | /** 73 | * Define the "api" routes for the application. 74 | * 75 | * These routes are typically stateless. 76 | * 77 | * @return void 78 | */ 79 | protected function mapApiRoutes() 80 | { 81 | Route::prefix('api') 82 | ->middleware('api') 83 | ->namespace($this->namespace) 84 | ->group(base_path('routes/api.php')); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /resources/sass/tabler/_nav.scss: -------------------------------------------------------------------------------- 1 | .nav-link, 2 | .nav-item { 3 | padding: 0 .75rem; 4 | min-width: 2rem; 5 | transition: .3s color; 6 | user-select: none; 7 | cursor: pointer; 8 | display: flex; 9 | align-items: center; 10 | 11 | .badge { 12 | position: absolute; 13 | top: 0; 14 | right: 0; 15 | padding: .2rem .25rem; 16 | min-width: 1rem 17 | } 18 | } 19 | 20 | .nav-tabs { 21 | user-select: none; 22 | color: $text-muted; 23 | margin: 0 -.75rem; 24 | 25 | .nav-link { 26 | border: 0; 27 | color: inherit; 28 | border-bottom: 1px solid transparent; 29 | margin-bottom: -1px; 30 | transition: .3s border-color; 31 | font-weight: 400; 32 | padding: 1rem 0; 33 | 34 | &:hover:not(.disabled) { 35 | border-color: $text-muted-dark; 36 | color: $text-muted-dark; 37 | } 38 | 39 | &.active { 40 | border-color: $blue; 41 | color: $blue; 42 | background: transparent; 43 | } 44 | 45 | &.disabled { 46 | opacity: .4; 47 | cursor: default; 48 | pointer-events: none; 49 | } 50 | } 51 | 52 | .nav-item { 53 | margin-bottom: 0; 54 | position: relative; 55 | 56 | i { 57 | margin-right: .25rem; 58 | line-height: 1; 59 | font-size: px2rem(14px); 60 | width: px2rem(14px); 61 | vertical-align: baseline; 62 | display: inline-block; 63 | } 64 | 65 | &:hover { 66 | .nav-submenu { 67 | display: block; 68 | } 69 | } 70 | } 71 | 72 | .nav-submenu { 73 | display: none; 74 | position: absolute; 75 | background: #fff; 76 | border: 1px solid $border-color; 77 | border-top: none; 78 | z-index: 10; 79 | box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); 80 | min-width: 10rem; 81 | border-radius: 0 0 3px 3px; 82 | 83 | .nav-item { 84 | display: block; 85 | padding: .5rem 1rem; 86 | color: $text-muted; 87 | margin: 0 !important; 88 | cursor: pointer; 89 | transition: .3s background; 90 | 91 | &.active { 92 | color: $link-color; 93 | } 94 | 95 | &:hover { 96 | color: $text-muted-dark; 97 | text-decoration: none; 98 | background: rgba(0, 0, 0, .024); 99 | } 100 | } 101 | } 102 | } 103 | 104 | .nav-link { 105 | //display: block; 106 | //padding: 0.25rem 0.75rem; 107 | } 108 | -------------------------------------------------------------------------------- /app/Nova/Kelurahan.php: -------------------------------------------------------------------------------- 1 | sortable(), 48 | BelongsTo::make('Kecamatan', 'kecamatan', Kecamatan::class) 49 | ->searchable() 50 | ->sortable(), 51 | ]; 52 | } 53 | 54 | /** 55 | * Get the cards available for the request. 56 | * 57 | * @param \Illuminate\Http\Request $request 58 | * @return array 59 | */ 60 | public function cards(Request $request) 61 | { 62 | return []; 63 | } 64 | 65 | /** 66 | * Get the filters available for the resource. 67 | * 68 | * @param \Illuminate\Http\Request $request 69 | * @return array 70 | */ 71 | public function filters(Request $request) 72 | { 73 | return []; 74 | } 75 | 76 | /** 77 | * Get the lenses available for the resource. 78 | * 79 | * @param \Illuminate\Http\Request $request 80 | * @return array 81 | */ 82 | public function lenses(Request $request) 83 | { 84 | return []; 85 | } 86 | 87 | /** 88 | * Get the actions available for the resource. 89 | * 90 | * @param \Illuminate\Http\Request $request 91 | * @return array 92 | */ 93 | public function actions(Request $request) 94 | { 95 | return []; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /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 | "repositories": [ 11 | { 12 | "type": "composer", 13 | "url": "https://nova.laravel.com" 14 | } 15 | ], 16 | "require": { 17 | "php": "^7.2.5", 18 | "ext-json": "*", 19 | "bensampo/laravel-enum": "^1.37", 20 | "dillingham/nova-button": "^1.0", 21 | "ericlagarda/nova-text-card": "^1.1", 22 | "fideloper/proxy": "^4.2", 23 | "fruitcake/laravel-cors": "^1.0", 24 | "genealabs/nova-map-marker-field": "^0.1.15", 25 | "guzzlehttp/guzzle": "^6.5", 26 | "laravel/framework": "^7.0", 27 | "laravel/nova": "~3.0", 28 | "laravel/tinker": "^2.0", 29 | "laravolt/indonesia": "^0.26.0", 30 | "league/csv": "^9.6", 31 | "predis/predis": "^1.1", 32 | "propaganistas/laravel-phone": "^4.2", 33 | "saumini/count": "^1.0" 34 | }, 35 | "require-dev": { 36 | "facade/ignition": "^2.0", 37 | "fzaninotto/faker": "^1.9.1", 38 | "mockery/mockery": "^1.3.1", 39 | "nunomaduro/collision": "^4.1", 40 | "phpunit/phpunit": "^8.5" 41 | }, 42 | "config": { 43 | "optimize-autoloader": true, 44 | "preferred-install": "dist", 45 | "sort-packages": true 46 | }, 47 | "extra": { 48 | "laravel": { 49 | "dont-discover": [] 50 | } 51 | }, 52 | "autoload": { 53 | "psr-4": { 54 | "App\\": "app/" 55 | }, 56 | "classmap": [ 57 | "database/seeds", 58 | "database/factories" 59 | ] 60 | }, 61 | "autoload-dev": { 62 | "psr-4": { 63 | "Tests\\": "tests/" 64 | } 65 | }, 66 | "minimum-stability": "dev", 67 | "prefer-stable": true, 68 | "scripts": { 69 | "post-autoload-dump": [ 70 | "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", 71 | "@php artisan package:discover --ansi" 72 | ], 73 | "post-root-package-install": [ 74 | "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" 75 | ], 76 | "post-create-project-cmd": [ 77 | "@php artisan key:generate --ansi" 78 | ] 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | Build Status 5 | Deploy Status 6 | License 7 |

8 | 9 | ## Tentang SekitarKita.id 10 | 11 | SekitarKita adalah aplikasi Berbasis Mobile yang membantu anda melakukan Tracking terhadap Titik Singgung anda dengan Orang-Orang terdekat dengan menggunakan Nearby Device Bluetooth. Aplikasi ini sangat berguna untuk melakukan pemetaan dalam pandemi COVID-19. 12 | backend aplikasi dibangun Menggunakan [Laravel 7](https://laravel.com/) dan [Laravel Nova](https://nova.laravel.com/) 13 | 14 | 15 | ## Contributing 16 | Proyek ini adalah Proyek Terbuka, siapapun dapat berkontribusi 17 | 18 | ## License 19 | SekitarKita adalah open-sourced software yang berlisensi dibawah [MIT license](https://opensource.org/licenses/MIT). 20 | 21 | # Dokumentasi API 22 | 23 | ### POST /store-device 24 | 25 | ### validation 26 | ``` 27 | 'device_id' => 'required|string|regex:/^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/', 28 | 'nearby_device' => 'required|string|regex:/^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/', 29 | 'latitude' => 'nullable|numeric', 30 | 'longitude' => 'nullable|numeric', 31 | 'speed' => 'sometimes|nullable|numeric|min:0|max:100', 32 | 'device_name' => 'sometimes|nullable|string|max:100', 33 | ``` 34 | 35 | ## POST /me 36 | 37 | ### validation 38 | ``` 39 | device_id' => 'required|string|regex:/^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/', 40 | ``` 41 | 42 | ## POST /store-firebase-token 43 | 44 | ### validation 45 | ``` 46 | 'device_id' => 'required|string|regex:/^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/', 47 | 'firebase_token' => 'required|string|min:32|max:256' 48 | ``` 49 | 50 | ## POST /device-history 51 | 52 | ### validation 53 | ``` 54 | 'device_id' => 'required|string|regex:/^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/' 55 | ``` 56 | 57 | ## POST set-health 58 | 59 | ### validation 60 | ``` 61 | 'device_id' => 'required|string|regex:/^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/', 62 | 'health' => 'required|in:healthy,pdp,odp' 63 | ``` 64 | -------------------------------------------------------------------------------- /resources/sass/tabler/_avatar.scss: -------------------------------------------------------------------------------- 1 | .avatar { 2 | width: 2rem; 3 | height: 2rem; 4 | line-height: 2rem; 5 | border-radius: 50%; 6 | display: inline-block; 7 | background: $gray-400 no-repeat center/cover; 8 | position: relative; 9 | text-align: center; 10 | color: $gray-600; 11 | font-weight: 600; 12 | vertical-align: bottom; 13 | font-size: .875rem; 14 | user-select: none; 15 | 16 | i { 17 | font-size: 125%; 18 | vertical-align: sub; 19 | } 20 | } 21 | 22 | .avatar-status { 23 | position: absolute; 24 | right: -2px; 25 | bottom: -2px; 26 | width: .75rem; 27 | height: .75rem; 28 | border: 2px solid #fff; 29 | background: $gray-600; 30 | border-radius: 50%; 31 | } 32 | 33 | .avatar-sm { 34 | width: 1.5rem; 35 | height: 1.5rem; 36 | line-height: 1.5rem; 37 | font-size: .75rem; 38 | } 39 | 40 | .avatar-md { 41 | width: 2.5rem; 42 | height: 2.5rem; 43 | line-height: 2.5rem; 44 | font-size: 1rem; 45 | } 46 | 47 | .avatar-lg { 48 | width: 3rem; 49 | height: 3rem; 50 | line-height: 3rem; 51 | font-size: 1.25rem; 52 | } 53 | 54 | .avatar-xl { 55 | width: 4rem; 56 | height: 4rem; 57 | line-height: 4rem; 58 | font-size: 1.75rem; 59 | } 60 | 61 | .avatar-xxl { 62 | width: 5rem; 63 | height: 5rem; 64 | line-height: 5rem; 65 | font-size: 2rem; 66 | } 67 | 68 | .avatar-placeholder { 69 | background: $gray-400 url('data:image/svg+xml;charset=utf8,') no-repeat center/80%; 70 | } 71 | 72 | .avatar-list { 73 | margin: 0 0 -.5rem; 74 | padding: 0; 75 | font-size: 0; 76 | 77 | .avatar { 78 | margin-bottom: .5rem; 79 | 80 | &:not(:last-child) { 81 | margin-right: .5rem; 82 | } 83 | } 84 | } 85 | 86 | .avatar-list-stacked { 87 | .avatar { 88 | margin-right: -.8em !important; 89 | } 90 | 91 | .avatar { 92 | box-shadow: 0 0 0 2px #fff; 93 | } 94 | } 95 | 96 | @each $vendor, $color in $colors { 97 | .avatar-#{$vendor} { 98 | background-color: mix($color, #fff, 30%); 99 | color: $color; 100 | } 101 | } -------------------------------------------------------------------------------- /resources/sass/tabler/_tables.scss: -------------------------------------------------------------------------------- 1 | .table { 2 | thead { 3 | //background: $table-accent-bg; 4 | 5 | th { 6 | border-top: 0; 7 | border-bottom-width: 1px; 8 | padding-top: .5rem; 9 | padding-bottom: .5rem; 10 | } 11 | } 12 | 13 | th { 14 | color: $text-muted; 15 | text-transform: uppercase; 16 | font-size: $h6-font-size; 17 | font-weight: 400; 18 | } 19 | } 20 | 21 | .table-md { 22 | th, 23 | td { 24 | padding: .5rem; 25 | } 26 | } 27 | 28 | .table-vcenter { 29 | td, 30 | th { 31 | vertical-align: middle; 32 | } 33 | } 34 | 35 | .table-center { 36 | td, 37 | th { 38 | text-align: center; 39 | } 40 | } 41 | 42 | .table-striped { 43 | tbody tr:nth-of-type(odd) { 44 | background: transparent; 45 | } 46 | 47 | tbody tr:nth-of-type(even) { 48 | background-color: $table-accent-bg; 49 | } 50 | } 51 | 52 | .table-calendar { 53 | margin: 0 0 .75rem; 54 | 55 | td, 56 | th { 57 | border: 0; 58 | text-align: center; 59 | padding: 0 !important; 60 | width: (100%/7); 61 | line-height: 2.5rem; 62 | } 63 | 64 | td { 65 | border-top: 0; 66 | } 67 | } 68 | 69 | .table-calendar-link { 70 | line-height: 2rem; 71 | min-width: calc(2rem + 2px); 72 | display: inline-block; 73 | border-radius: 3px; 74 | background: $gray-100; 75 | color: $body-color; 76 | font-weight: 600; 77 | transition: .3s background, .3s color; 78 | position: relative; 79 | 80 | &:before { 81 | content: ''; 82 | width: 4px; 83 | height: 4px; 84 | position: absolute; 85 | left: .25rem; 86 | top: .25rem; 87 | border-radius: 50px; 88 | background: $primary; 89 | } 90 | 91 | &:hover { 92 | color: #fff; 93 | text-decoration: none; 94 | background: $primary; 95 | transition: .3s background; 96 | 97 | &:before { 98 | background: #fff; 99 | } 100 | } 101 | } 102 | 103 | 104 | .table-header { 105 | cursor: pointer; 106 | transition: .3s color; 107 | 108 | &:hover { 109 | color: $body-color !important; 110 | } 111 | 112 | &:after { 113 | content: '\f0dc'; 114 | font-family: FontAwesome; 115 | display: inline-block; 116 | margin-left: .5rem; 117 | font-size: .75rem; 118 | } 119 | } 120 | 121 | .table-header-asc { 122 | color: $body-color !important; 123 | 124 | &:after { 125 | content: '\f0de'; 126 | } 127 | } 128 | 129 | .table-header-desc { 130 | color: $body-color !important; 131 | 132 | &:after { 133 | content: '\f0dd'; 134 | } 135 | } -------------------------------------------------------------------------------- /app/Http/Controllers/Api/AreaController.php: -------------------------------------------------------------------------------- 1 | kabupatens->values(); 21 | } 22 | 23 | function getDistricts(Kabupaten $city) 24 | { 25 | return $city->kecamatans->values(); 26 | } 27 | 28 | function getVillages(Kecamatan $district) 29 | { 30 | return $district->kelurahans->values(); 31 | } 32 | 33 | function getGorontalo() 34 | { 35 | $result = cache()->remember('get-area-gorontalo', now()->addHours(12), function () { 36 | $data = Provinsi::with('kabupatens.kecamatans.kelurahans')->find(75); 37 | return [ 38 | 'data' => $data['kabupatens']->map(function ($kab) { 39 | return $kab['kecamatans']->map(function ($kec) use ($kab) { 40 | return $kec['kelurahans']->map(function ($des) use ($kab, $kec) { 41 | return [ 42 | 'id' => $des['id'], 43 | 'name' => sprintf('%s, %s, %s', $kab['name'], $kec['name'], $des['name']) 44 | ]; 45 | }); 46 | }); 47 | })->flatten(2), 48 | 'success' => true 49 | ]; 50 | }); 51 | 52 | return response()->json($result); 53 | } 54 | 55 | function getOriginCities() 56 | { 57 | $result = cache()->remember('get-all-area', now()->addHours(12), function () { 58 | $data = Provinsi::with('kabupatens')->get(); 59 | return [ 60 | 'data' => $data->map(function ($prov) { 61 | return $prov['kabupatens']->map(function ($kab) use ($prov) { 62 | return [ 63 | 'id' => $kab['id'], 64 | 'name' => sprintf('%s, %s', $prov['name'], $kab['name']) 65 | ]; 66 | }); 67 | })->flatten(1), 68 | 'success' => true 69 | ]; 70 | }); 71 | 72 | return response()->json($result); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /resources/sass/tabler/_button.scss: -------------------------------------------------------------------------------- 1 | .btn { 2 | cursor: pointer; 3 | font-weight: 600; 4 | letter-spacing: .03em; 5 | font-size: px2rem(13px); 6 | min-width: px2rem(38px); 7 | 8 | i { 9 | font-size: 1rem; 10 | vertical-align: -2px; 11 | } 12 | } 13 | 14 | .btn-icon { 15 | padding-left: .5rem; 16 | padding-right: .5rem; 17 | text-align: center; 18 | } 19 | 20 | .btn-secondary { 21 | @include button-variant(#fff, $input-border-color, #f6f6f6); 22 | box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.05); 23 | } 24 | 25 | .btn-pill { 26 | border-radius: 10rem; 27 | padding-left: 1.5em; 28 | padding-right: 1.5em; 29 | } 30 | 31 | .btn-square { 32 | border-radius: 0; 33 | } 34 | 35 | @each $vendor, $color in $social-colors { 36 | .btn-#{$vendor} { 37 | @include button-variant($color, $color); 38 | } 39 | } 40 | 41 | @each $vendor, $color in $colors { 42 | .btn-#{$vendor} { 43 | @include button-variant($color, $color); 44 | } 45 | } 46 | 47 | .btn-option { 48 | background: transparent; 49 | color: $text-muted; 50 | 51 | &:hover { 52 | color: $text-muted-dark; 53 | } 54 | 55 | &:focus { 56 | box-shadow: none; 57 | color: $text-muted-dark; 58 | } 59 | } 60 | 61 | .btn-sm { 62 | font-size: px2rem(12px); 63 | min-width: px2rem(26px); 64 | } 65 | 66 | .btn-lg { 67 | font-size: px2rem(16px); 68 | min-width: px2rem(44px); 69 | font-weight: 400; 70 | } 71 | 72 | .btn-list { 73 | margin-bottom: -.5rem; 74 | font-size: 0; 75 | 76 | >.btn, 77 | >.dropdown { 78 | margin-bottom: .5rem; 79 | 80 | &:not(:last-child) { 81 | margin-right: .5rem; 82 | } 83 | } 84 | } 85 | 86 | .btn-loading { 87 | color: transparent !important; 88 | pointer-events: none; 89 | position: relative; 90 | 91 | &:after { 92 | content: ''; 93 | animation: loader 500ms infinite linear; 94 | border: 2px solid #fff; 95 | border-radius: 50%; 96 | border-right-color: transparent !important; 97 | border-top-color: transparent !important; 98 | display: block; 99 | height: 1.4em; 100 | width: 1.4em; 101 | position: absolute; 102 | left: calc(50% - (1.4em / 2)); 103 | top: calc(50% - (1.4em / 2)); 104 | transform-origin: center; 105 | position: absolute !important; 106 | } 107 | 108 | &.btn-sm:after{ 109 | height: 1em; 110 | width: 1em; 111 | left: calc(50% - (1em / 2)); 112 | top: calc(50% - (1em / 2)); 113 | } 114 | 115 | &.btn-secondary:after { 116 | border-color: $yiq-text-dark; 117 | } 118 | } -------------------------------------------------------------------------------- /app/Nova/Zone.php: -------------------------------------------------------------------------------- 1 | types([Kecamatan::class, Kabupaten::class, Provinsi::class, Kelurahan::class]) 48 | ->searchable(), 49 | Select::make('Zona', 'status') 50 | ->displayUsingLabels() 51 | ->options(ZoneLevel::toSelectArray()), 52 | ]; 53 | } 54 | 55 | /** 56 | * Get the cards available for the request. 57 | * 58 | * @param \Illuminate\Http\Request $request 59 | * @return array 60 | */ 61 | public function cards(Request $request) 62 | { 63 | return []; 64 | } 65 | 66 | /** 67 | * Get the filters available for the resource. 68 | * 69 | * @param \Illuminate\Http\Request $request 70 | * @return array 71 | */ 72 | public function filters(Request $request) 73 | { 74 | return []; 75 | } 76 | 77 | /** 78 | * Get the lenses available for the resource. 79 | * 80 | * @param \Illuminate\Http\Request $request 81 | * @return array 82 | */ 83 | public function lenses(Request $request) 84 | { 85 | return []; 86 | } 87 | 88 | /** 89 | * Get the actions available for the resource. 90 | * 91 | * @param \Illuminate\Http\Request $request 92 | * @return array 93 | */ 94 | public function actions(Request $request) 95 | { 96 | return []; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /resources/sass/tabler/_header.scss: -------------------------------------------------------------------------------- 1 | .header { 2 | padding-top: .75rem; 3 | padding-bottom: .75rem; 4 | background: #fff; 5 | border-bottom: 1px solid $border-color; 6 | 7 | body.fixed-header & { 8 | position: fixed; 9 | top: 0; 10 | left: 0; 11 | right: 0; 12 | z-index: $zindex-fixed; 13 | } 14 | 15 | @media print { 16 | display: none; 17 | } 18 | 19 | .dropdown-menu { 20 | margin-top: .75rem; 21 | } 22 | } 23 | 24 | .nav-unread { 25 | position: absolute; 26 | top: .25rem; 27 | right: .25rem; 28 | background: $red; 29 | width: .5rem; 30 | height: .5rem; 31 | border-radius: 50%; 32 | } 33 | 34 | .header-brand { 35 | color: inherit; 36 | margin-right: 1rem; 37 | font-size: 1.25rem; 38 | white-space: nowrap; 39 | font-weight: 600; 40 | padding: 0; 41 | transition: .3s opacity; 42 | line-height: 2rem; 43 | 44 | &:hover { 45 | opacity: .8; 46 | color: inherit; 47 | text-decoration: none; 48 | } 49 | } 50 | 51 | .header-brand-img { 52 | height: 2rem; 53 | line-height: 2rem; 54 | vertical-align: bottom; 55 | margin-right: .5rem; 56 | width: auto; 57 | } 58 | 59 | .header-avatar { 60 | width: 2rem; 61 | height: 2rem; 62 | display: inline-block; 63 | vertical-align: bottom; 64 | border-radius: 50%; 65 | } 66 | 67 | //.header-nav { 68 | // background: #fff; 69 | // border-bottom: 1px solid $border-color; 70 | // color: $text-muted; 71 | // align-items: center; 72 | // 73 | // @media print { 74 | // display: none; 75 | // } 76 | // 77 | // .nav-tabs { 78 | // border: 0; 79 | // } 80 | //} 81 | 82 | .header-btn { 83 | display: inline-block; 84 | width: 2rem; 85 | height: 2rem; 86 | line-height: 2rem; 87 | text-align: center; 88 | font-size: 1rem; 89 | 90 | &.has-new { 91 | position: relative; 92 | 93 | &:before { 94 | content: ''; 95 | width: 6px; 96 | height: 6px; 97 | background: $red; 98 | position: absolute; 99 | top: 4px; 100 | right: 4px; 101 | border-radius: 50%; 102 | } 103 | } 104 | } 105 | 106 | .header-toggler { 107 | width: 2rem; 108 | height: 2rem; 109 | position: relative; 110 | color: $text-muted; 111 | 112 | &:hover { 113 | color: $text-muted-dark; 114 | } 115 | } 116 | 117 | .header-toggler-icon { 118 | position: absolute; 119 | width: 1rem; 120 | height: 2px; 121 | color: inherit; 122 | background: currentColor; 123 | border-radius: 3px; 124 | top: 50%; 125 | left: 50%; 126 | margin: -2px 0 0 -.5rem; 127 | box-shadow: 0 5px currentColor, 0 -5px currentColor; 128 | } -------------------------------------------------------------------------------- /app/Nova/Partner.php: -------------------------------------------------------------------------------- 1 | sortable() 48 | ->required(), 49 | Image::make(__('Logo Partner'), 'logo') 50 | ->required() 51 | ->disk('public'), 52 | Textarea::make(__('Deskripsi'), 'description') 53 | ]; 54 | } 55 | 56 | /** 57 | * Get the cards available for the request. 58 | * 59 | * @param \Illuminate\Http\Request $request 60 | * @return array 61 | */ 62 | public function cards(Request $request) 63 | { 64 | return []; 65 | } 66 | 67 | /** 68 | * Get the filters available for the resource. 69 | * 70 | * @param \Illuminate\Http\Request $request 71 | * @return array 72 | */ 73 | public function filters(Request $request) 74 | { 75 | return []; 76 | } 77 | 78 | /** 79 | * Get the lenses available for the resource. 80 | * 81 | * @param \Illuminate\Http\Request $request 82 | * @return array 83 | */ 84 | public function lenses(Request $request) 85 | { 86 | return []; 87 | } 88 | 89 | /** 90 | * Get the actions available for the resource. 91 | * 92 | * @param \Illuminate\Http\Request $request 93 | * @return array 94 | */ 95 | public function actions(Request $request) 96 | { 97 | return []; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /app/Nova/Provinsi.php: -------------------------------------------------------------------------------- 1 | orderBy('name'); 48 | } 49 | 50 | public function fields(Request $request) 51 | { 52 | return [ 53 | Text::make('name') 54 | ->sortable(), 55 | HasMany::make('Kabupaten', 'kabupatens', Kabupaten::class) 56 | ]; 57 | } 58 | 59 | /** 60 | * Get the cards available for the request. 61 | * 62 | * @param \Illuminate\Http\Request $request 63 | * @return array 64 | */ 65 | public function cards(Request $request) 66 | { 67 | return []; 68 | } 69 | 70 | /** 71 | * Get the filters available for the resource. 72 | * 73 | * @param \Illuminate\Http\Request $request 74 | * @return array 75 | */ 76 | public function filters(Request $request) 77 | { 78 | return []; 79 | } 80 | 81 | /** 82 | * Get the lenses available for the resource. 83 | * 84 | * @param \Illuminate\Http\Request $request 85 | * @return array 86 | */ 87 | public function lenses(Request $request) 88 | { 89 | return []; 90 | } 91 | 92 | /** 93 | * Get the actions available for the resource. 94 | * 95 | * @param \Illuminate\Http\Request $request 96 | * @return array 97 | */ 98 | public function actions(Request $request) 99 | { 100 | return []; 101 | } 102 | } 103 | --------------------------------------------------------------------------------